App.razor 13 KB

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