App.razor 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <div class="container">
  2. <a style="float:right" href="/classic-index">Back OLD Home Page</a>
  3. <h3>Blazor WASM UI</h3>
  4. @if (Progress?.IsLoading != false)
  5. {
  6. <span>Waiting server ready...</span>
  7. <span>@(Progress?.LoadedTags ?? 0)</span>
  8. <span>/</span>
  9. <span>@(Progress?.TotalTrackCount ?? 0)</span>
  10. }
  11. else if (FnzDataSet.Libraries == null)
  12. {
  13. <span>Loading file set...</span>
  14. }
  15. else if (FnzDataSet.MediaTags == null)
  16. {
  17. <span>Loading tags...</span>
  18. }
  19. else
  20. {
  21. <ul class="nav nav-tabs justify-content-center nav-fill" id="RootTab" role="tablist">
  22. <li class="nav-item" role="presentation">
  23. <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">
  24. Browse
  25. </button>
  26. </li>
  27. <li class="nav-item" role="presentation">
  28. <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">
  29. Search
  30. </button>
  31. </li>
  32. <li class="nav-item" role="presentation">
  33. <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">
  34. Playlists
  35. </button>
  36. </li>
  37. </ul>
  38. <div class="tab-content" id="RootTabContent">
  39. <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
  40. <div class="row justify-content-evenly mt-2">
  41. <div class="d-flex flex-row">
  42. <span>Library (@FnzDataSet.Libraries.Count):&nbsp;</span>
  43. <LibSelector SelectedLibs="@SelectedLibs" OnValueChanged="SelectedLibraryChanged"></LibSelector>
  44. </div>
  45. </div>
  46. <div class="row mt-2">
  47. <div class="col-12">
  48. <ul class="nav justify-content-start align-items-center">
  49. <li class="nav-item mb-1">
  50. <span>Play all track (@FnzDataSet.Libraries[CurrentLibraryKey].Discs.Sum(p=>p.Value.MainTracks.Count))</span>
  51. </li>
  52. <li class="nav-item mb-1 mx-2">
  53. <a class="nav-link btn btn-secondary"
  54. href="@ApiClient.GetListUrl(CurrentLibraryKey)"
  55. target="@FnzConst.PlaylistPageTarget"
  56. onclick="return BlockDownloadAndOpenHtmlPage(this)">
  57. <small class="font-monospace text-muted">@FnzDataSet.GetDuration(CurrentLibraryKey).SecondToDur() @FnzDataSet.GetFileSize(CurrentLibraryKey).BytesToFileSize()</small>
  58. Main
  59. </a>
  60. </li>
  61. @foreach (var sub in CurrentLibrary.Discs.SelectMany(p => p.Value.SubTracks.Keys).Distinct())
  62. {
  63. <li class="nav-item mb-1 mx-2">
  64. <a class="nav-link btn btn-secondary"
  65. href="@ApiClient.GetListUrl(CurrentLibraryKey,null,sub)"
  66. target="@FnzConst.PlaylistPageTarget"
  67. onclick="return BlockDownloadAndOpenHtmlPage(this)">
  68. <small class="font-monospace text-muted">@FnzDataSet.GetDuration(CurrentLibraryKey,null,sub).SecondToDur() @FnzDataSet.GetFileSize(CurrentLibraryKey,null,sub).BytesToFileSize()</small>
  69. @sub.ToUpper()
  70. </a>
  71. </li>
  72. }
  73. </ul>
  74. </div>
  75. </div>
  76. <div class="row">
  77. <div class="col-12">
  78. @if (CurrentLibrary != null)
  79. {
  80. <div class="row">
  81. @foreach (var d in CurrentLibrary.Discs.OrderByDescending(p => p.Key).WithIndex())
  82. {
  83. <div class="col-md-3 d-flex align-items-stretch">
  84. @*TODO: Card Component*@
  85. <div class="card mb-3 shadow-sm" @onclick="()=>SelectDisc(d.item.Key)">
  86. <img class="card-img-top" src="@ApiClient.ImageUrl(CurrentLibraryKey,d.item.Key)" onerror="this.src='blazor-192.png'">
  87. <div class="card-body d-flex align-content-between flex-wrap p-2">
  88. <p class="card-text">@d.item.Value.Name</p>
  89. <div class="w-100">
  90. <div class="w-100 text-center">
  91. <small class="font-monospace text-muted">Track @FnzDataSet.Libraries[CurrentLibraryKey].Discs[d.item.Key].MainTracks.Count</small>
  92. </div>
  93. <div class="d-flex justify-content-between w-100">
  94. <span class="align-self-center">Main</span>
  95. <small class="text-nowrap font-monospace text-muted align-self-center">@FnzDataSet.GetDuration(CurrentLibraryKey,d.item.Key).SecondToDur() @FnzDataSet.GetFileSize(CurrentLibraryKey,d.item.Key).BytesToFileSize()</small>
  96. </div>
  97. @foreach (var subSet in d.item.Value.SubTracks.OrderBy(p => p.Key))
  98. {
  99. <div class="d-flex justify-content-between w-100">
  100. <span class="align-self-center">@(subSet.Value.Name.StartsWith("AAC_Q1.00") ? "Q1" + subSet.Value.Name.Substring(9) : subSet.Value.Name)</span>
  101. <small class="text-nowrap font-monospace text-muted align-self-center">@FnzDataSet.GetDuration(CurrentLibraryKey,d.item.Key,subSet.Key).SecondToDur() @FnzDataSet.GetFileSize(CurrentLibraryKey,d.item.Key,subSet.Key).BytesToFileSize()</small>
  102. </div>
  103. }
  104. </div>
  105. </div>
  106. </div>
  107. </div>
  108. }
  109. </div>
  110. }
  111. </div>
  112. </div>
  113. <div class="modal fade" id="ModalDisc" aria-hidden="true" aria-labelledby="ModalDiscLabel" tabindex="-1">
  114. <div class="modal-dialog modal-dialog-centered modal-xl">
  115. <div class="modal-content">
  116. <div class="modal-header">
  117. <h5 class="modal-title" id="ModalDiscLabel">@CurrentDisc?.Name</h5>
  118. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  119. </div>
  120. <div class="modal-body">
  121. @*TODO: Disc Modal*@
  122. <div class="container-fluid">
  123. <div class="row">
  124. @if (CurrentDisc != null)
  125. {
  126. <div class="col-md-4 mb-1"><img class="card-img-top" src="@ApiClient.ImageUrl(CurrentLibraryKey,CurrentDiscKey)" onerror="this.src='blazor-192.png'"></div>
  127. <div class="col-md-8">
  128. <ul class="nav nav-tabs justify-content-center nav-fill" id="ModalDiscTab" role="tablist">
  129. <li class="nav-item" role="presentation">
  130. <button class="nav-link active" id="main-tab" data-bs-toggle="tab" data-bs-target="#tracks-main" type="button" role="tab" aria-controls="home" aria-selected="true">
  131. Main
  132. </button>
  133. </li>
  134. @foreach (var subSet in CurrentDisc.SubTracks.OrderBy(p => p.Key).WithIndex())
  135. {
  136. <li class="nav-item" role="presentation">
  137. <button class="nav-link" id="main-tab" data-bs-toggle="tab" data-bs-target="#tracks-@subSet.index" type="button" role="tab" aria-controls="home" aria-selected="true">
  138. @subSet.item.Value.Name
  139. </button>
  140. </li>
  141. }
  142. </ul>
  143. <div class="tab-content" id="ModalDiscTabContent">
  144. <div class="tab-pane fade show active" id="tracks-main" role="tabpanel" aria-labelledby="home-tab">
  145. <TrackSetTable LibraryKey="@CurrentLibraryKey"
  146. DiscKey="@CurrentDiscKey"
  147. TrackSetKey="@null"
  148. Tracks="@CurrentDisc?.MainTracks"></TrackSetTable>
  149. </div>
  150. @foreach (var subSet in CurrentDisc.SubTracks.OrderBy(p => p.Key).WithIndex())
  151. {
  152. <div class="tab-pane fade show" id="tracks-@subSet.index" role="tabpanel" aria-labelledby="home-tab">
  153. <TrackSetTable LibraryKey="@CurrentLibraryKey"
  154. DiscKey="@CurrentDiscKey"
  155. TrackSetKey="@subSet.item.Key"
  156. Tracks="@subSet.item.Value.Tracks"></TrackSetTable>
  157. </div>
  158. }
  159. </div>
  160. </div>
  161. }
  162. </div>
  163. </div>
  164. </div>
  165. <div class="modal-footer">
  166. <button class="btn btn-primary" data-bs-dismiss="modal">Close</button>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. </div>
  172. <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
  173. <div class="container">
  174. <h1>此处应有搜索界面</h1>
  175. </div>
  176. </div>
  177. <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
  178. <div class="container">
  179. <h1>此处应有列表界面</h1>
  180. </div>
  181. </div>
  182. </div>
  183. }
  184. </div>