App.razor 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <div class="container">
  2. <a style="float:right" href="/classic-index">Back OLD Home Page</a>
  3. <h3 style="float:left">Blazor WASM UI</h3>
  4. <h2 class="w-100 text-center">
  5. &nbsp;
  6. @if (Libraries != null && MediaTags == null)
  7. {
  8. <span>Loading tags...</span>
  9. }
  10. &nbsp;
  11. </h2>
  12. @if (Progress?.IsLoading != false)
  13. {
  14. <span>Waiting server ready...</span>
  15. <span>@(Progress?.LoadedTags ?? 0)</span>
  16. <span>/</span>
  17. <span>@(Progress?.TotalTrackCount ?? 0)</span>
  18. }
  19. else if (Libraries == null)
  20. {
  21. <span>Loading file set...</span>
  22. }
  23. else
  24. {
  25. <ul class="nav nav-tabs justify-content-center nav-fill" id="RootTab" role="tablist">
  26. <li class="nav-item" role="presentation">
  27. <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">
  28. Browse
  29. </button>
  30. </li>
  31. <li class="nav-item" role="presentation">
  32. <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">
  33. Search
  34. </button>
  35. </li>
  36. <li class="nav-item" role="presentation">
  37. <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">
  38. Playlists
  39. </button>
  40. </li>
  41. </ul>
  42. <div class="tab-content" id="RootTabContent">
  43. <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
  44. <div class="row justify-content-evenly mt-2">
  45. <div class="d-flex flex-row bd-highlight mt-2">
  46. <div>
  47. Libs(@Libraries.Count):
  48. </div>
  49. <Select2 class="flex-fill" TItem="KeyValuePair<string,Library>"
  50. TSource="IReadOnlyCollection<KeyValuePair<string,Library>>"
  51. IdSelector="c => c.Key"
  52. TextSelector="c =>c.Value.Name+' '+'('+c.Value.Discs.Count+')'"
  53. FilterFunction="FilterLibrary"
  54. GetElementById="async (items, id, token) => items.FirstOrDefault(q=>q.Key==id)"
  55. Datasource="Libraries.OrderBy(p=>p.Key).ToArray()"
  56. Value="@SelectedLibs"
  57. Multiselect="false"
  58. OnValueChanged="SelectedLibraryChanged" />
  59. </div>
  60. <div class="row mt-2">
  61. <div class="col-12">
  62. @if (CurrentLibrary != null)
  63. {
  64. <div class="row">
  65. @foreach (var d in CurrentLibrary.Discs.OrderByDescending(p => p.Key))
  66. {
  67. <div class="col-md-3">
  68. <div class="card mb-3 shadow-sm" @onclick="()=>SelectDisc(d.Key)">
  69. <img class="card-img-top" src="@ApiClient.ImageUrl(CurrentLibraryKey,d.Key)">
  70. <div class="card-body">
  71. <p class="card-text">@d.Value.Name</p>
  72. <div class="d-flex justify-content-between align-items-center">
  73. <div class="btn-group">
  74. <button type="button" class="btn btn-sm btn-outline-secondary">Track @d.Value.MainTracks.Count</button>
  75. <button type="button" class="btn btn-sm btn-outline-secondary">SubSet @d.Value.SubTracks.Count</button>
  76. </div>
  77. <small class="text-muted">@GetDiscDurationDisplay(CurrentLibraryKey,d.Key)</small>
  78. </div>
  79. </div>
  80. </div>
  81. </div>
  82. }
  83. </div>
  84. }
  85. </div>
  86. </div>
  87. </div>
  88. <div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1">
  89. <div class="modal-dialog modal-dialog-centered modal-xl">
  90. <div class="modal-content">
  91. <div class="modal-header">
  92. <h5 class="modal-title" id="exampleModalToggleLabel">@CurrentDisc?.Name</h5>
  93. <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  94. </div>
  95. <div class="modal-body">
  96. <div class="container-fluid">
  97. <div class="row">
  98. @if (CurrentDisc != null)
  99. {
  100. <div class="col-md-4"><img class="card-img-top" src="@ApiClient.ImageUrl(CurrentLibraryKey,CurrentDiscKey)"></div>
  101. <div class="col-md-8">
  102. <ul class="nav nav-tabs justify-content-center nav-fill" id="ModalDiscTab" role="tablist">
  103. <li class="nav-item" role="presentation">
  104. <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">
  105. Main
  106. </button>
  107. </li>
  108. @foreach (var subSet in CurrentDisc.SubTracks.OrderBy(p => p.Key).WithIndex())
  109. {
  110. <li class="nav-item" role="presentation">
  111. <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">
  112. @subSet.item.Value.Name
  113. </button>
  114. </li>
  115. }
  116. </ul>
  117. <div class="tab-content" id="ModalDiscTabContent">
  118. <div class="tab-pane fade show active" id="tracks-main" role="tabpanel" aria-labelledby="home-tab">
  119. <a href="@ApiClient.GetListPageUrl(CurrentLibraryKey,CurrentDiscKey)" target="_fnz_play">Playlist page</a>
  120. <table class="table">
  121. <thead>
  122. <tr>
  123. <th scope="col">Name</th>
  124. <th scope="col"></th>
  125. <th scope="col">Duration</th>
  126. <th scope="col">Size</th>
  127. </tr>
  128. </thead>
  129. <tbody>
  130. @foreach (var t in CurrentDisc.MainTracks.OrderBy(p => p.Key))
  131. {
  132. <tr>
  133. <th scope="row">
  134. <a href="@ApiClient.GetMediaUrl(CurrentLibraryKey,CurrentDiscKey,t.Key)" target="_fnz_play">@t.Value</a>
  135. </th>
  136. <td></td>
  137. <td>TODO</td>
  138. <td>TODO</td>
  139. </tr>
  140. }
  141. </tbody>
  142. </table>
  143. </div>
  144. @foreach (var subSet in CurrentDisc.SubTracks.OrderBy(p => p.Key).WithIndex())
  145. {
  146. <div class="tab-pane fade show" id="tracks-@subSet.index" role="tabpanel" aria-labelledby="home-tab">
  147. <a href="@ApiClient.GetListPageUrl(CurrentLibraryKey,CurrentDiscKey,subSet.item.Key)" target="_fnz_play">Playlist page</a>
  148. <table class="table">
  149. <thead>
  150. <tr>
  151. <th scope="col">Name</th>
  152. <th scope="col"></th>
  153. <th scope="col">Duration</th>
  154. <th scope="col">Size</th>
  155. </tr>
  156. </thead>
  157. <tbody>
  158. @foreach (var t in subSet.item.Value.Tracks.OrderBy(p => p.Key))
  159. {
  160. <tr>
  161. <th scope="row">
  162. <a href="@ApiClient.GetMediaUrl(CurrentLibraryKey,CurrentDiscKey,t.Key,subSet.item.Key)" target="_fnz_play">@t.Value</a>
  163. </th>
  164. <td></td>
  165. <td>TODO</td>
  166. <td>TODO</td>
  167. </tr>
  168. }
  169. </tbody>
  170. </table>
  171. </div>
  172. }
  173. </div>
  174. </div>
  175. }
  176. </div>
  177. </div>
  178. </div>
  179. <div class="modal-footer">
  180. <button class="btn btn-primary" data-bs-dismiss="modal">Close</button>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
  187. <div class="container">
  188. <h1>此处应有搜索界面</h1>
  189. </div>
  190. </div>
  191. <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
  192. <div class="container">
  193. <h1>此处应有列表界面</h1>
  194. </div>
  195. </div>
  196. </div>
  197. }
  198. </div>