App.razor 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. @inherits ViewBase
  2. @code {
  3. public static App Instance { get; private set; }
  4. [Inject]
  5. private FnzDataSetHelper DataSetHelper { get; set; }
  6. private bool isLoading = true;
  7. private string loadingErrorMessage;
  8. private ProgressBar progressBar1;
  9. private ProgressBar progressBar2;
  10. private ProgressBar progressBar3;
  11. private ProgressBar progressBar4;
  12. private SettingDialog dlgSetting;
  13. private PlaylistAddDialog dlgPlaylistAdd;
  14. private enum ViewNames { Browse, Search, Playlists }
  15. private ViewNames CurrentView { get => LocalStorage.Get<ViewNames>(); set => LocalStorage.Set(value); }
  16. protected override async Task OnInitializedAsync()
  17. {
  18. Instance = this;
  19. if (CurrentView == 0) CurrentView = ViewNames.Browse;
  20. await base.OnInitializedAsync();
  21. await LoadData();
  22. }
  23. }
  24. <SettingDialog @ref="dlgSetting" ReloadData="async ()=>await LoadData()" />
  25. <div class="container" style="margin-bottom: @(BottomBarHeight)px">
  26. <a style="float: right" href="/classic-index">Back OLD Home Page</a>
  27. <h3>Blazor WASM UI</h3>
  28. <ul class="nav nav-tabs justify-content-center nav-fill" id="MainNavBar">
  29. @foreach (ViewNames item in Enum.GetValues(typeof(ViewNames)))
  30. {
  31. <li class="nav-item">
  32. <button class="nav-link @(item == CurrentView ? "active" : "")" type="button" @onclick="() => CurrentView = item">
  33. @item
  34. </button>
  35. </li>
  36. }
  37. <li class="nav-item" role="presentation">
  38. <button class="nav-link" type="button" role="tab" @onclick="() => dlgSetting.Show()">
  39. <i class="bi bi-gear"></i>
  40. </button>
  41. </li>
  42. </ul>
  43. @if (isLoading)
  44. {
  45. @if (loadingErrorMessage != null)
  46. {
  47. <div class="p-3">
  48. <span class="bi bi-x-circle text-danger" role="status" />
  49. <span>@loadingErrorMessage</span>
  50. </div>
  51. }
  52. else
  53. {
  54. <div class="p-3">
  55. <ProgressBar @ref="progressBar1" Throttle="500"></ProgressBar>
  56. </div>
  57. <div class="p-3">
  58. <ProgressBar @ref="progressBar2" Throttle="500"></ProgressBar>
  59. </div>
  60. <div class="p-3">
  61. <ProgressBar @ref="progressBar3" Throttle="500"></ProgressBar>
  62. </div>
  63. <div class="p-3">
  64. <ProgressBar @ref="progressBar4" Throttle="500"></ProgressBar>
  65. </div>
  66. }
  67. }
  68. @if (!isLoading)
  69. {
  70. switch (CurrentView)
  71. {
  72. case ViewNames.Browse:
  73. <BrowseView></BrowseView>
  74. break;
  75. case ViewNames.Search:
  76. <SearchView></SearchView>
  77. break;
  78. case ViewNames.Playlists:
  79. <PlaylistView></PlaylistView>
  80. break;
  81. }
  82. }
  83. <PlaylistAddDialog @ref="dlgPlaylistAdd"></PlaylistAddDialog>
  84. </div>
  85. @code {
  86. private async Task LoadData()
  87. {
  88. isLoading = true;
  89. StateHasChanged();
  90. await Task.Delay(10);
  91. await progressBar1.SetProgress(0, "Waiting server ready...", true);
  92. await progressBar2.SetProgress(0, "Pending load fileset...", true);
  93. await progressBar3.SetProgress(0, "Pending load tags...", true);
  94. await progressBar4.SetProgress(0, "Pending parse models...", true);
  95. StateHasChanged();
  96. await Task.Delay(10);
  97. try
  98. {
  99. do
  100. {
  101. var r = await ApiClient.GetProgressAsync();
  102. await progressBar1.SetProgress((float)r.LoadedTags / r.TotalTrackCount, $"Waiting server ready {r.LoadedTags}/{r.TotalTrackCount}");
  103. if (r?.IsLoading == false)
  104. {
  105. await progressBar1.SetProgress(100, "Waiting server ready...OK", true);
  106. break;
  107. }
  108. await Task.Delay(1000);
  109. } while (true);
  110. StateHasChanged();
  111. await Task.Delay(10);
  112. await DataSetHelper.InitFeModulesAsync(new[] { progressBar2, progressBar3, progressBar4, });
  113. StateHasChanged();
  114. await Task.Delay(500);
  115. isLoading = false;
  116. }
  117. catch (Exception ex)
  118. {
  119. loadingErrorMessage = ex.Message;
  120. }
  121. }
  122. public void ShowAddTrackToPlaylistDialog(FeTrack track) => dlgPlaylistAdd.Show(track);
  123. }
  124. @if (requestedPlay)
  125. {
  126. <style>
  127. .bottom-bar {
  128. pointer-events: none;
  129. gap: 0;
  130. }
  131. .bottom-bar *:not(div) {
  132. pointer-events: auto;
  133. }
  134. .player-video {
  135. max-height: 25vh;
  136. }
  137. .player-audio {
  138. height: 60px;
  139. }
  140. </style>
  141. <FnzDiv @ref="bottomBar" class="bottom-bar fixed-bottom d-flex flex-wrap align-content-end flex-column-reverse" style="z-index: 4096;">
  142. <FnzVideo @ref="player" @onloadedmetadata="@PlayerLoaded" class="@PlayerCssClass" src="@currentPlayingUrl" autoplay controls playsinline></FnzVideo>
  143. <div class="text-end">
  144. <button class="btn btn-secondary text-nowrap" type="button" @onclick="@StopAndClose">
  145. <i class="bi bi-x-circle"></i> Stop and close
  146. </button>
  147. @*<div class="btn-group dropup">
  148. <button class="align-bottom btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
  149. <i class="bi bi-card-list"></i>
  150. </button>
  151. <div class="dropdown-menu">
  152. <div class="text-center"><a class="btn-link" @onclick="@StopAndClose">Stop and close</a></div>
  153. </div>
  154. </div>*@
  155. @*<button class="btn btn-secondary" type="button">
  156. <i class="bi bi-chevron-bar-left"></i>
  157. </button>
  158. <button class="btn btn-secondary" type="button">
  159. <i class="bi bi-chevron-bar-right"></i>
  160. </button>*@
  161. </div>
  162. </FnzDiv>
  163. }
  164. @code {
  165. public Task PlayTrack(FeTrack track) => PlayTrack(track.Path);
  166. private void StopAndClose()
  167. {
  168. currentPlayingUrl = null;
  169. StateHasChanged();
  170. requestedPlay = false;
  171. StateHasChanged();
  172. BottomBarHeight = 0;
  173. StateHasChanged();
  174. BottomBarHeightChanged?.Invoke();
  175. }
  176. }
  177. @code {
  178. private bool requestedPlay;
  179. private string currentPlayingUrl;
  180. private FnzDiv bottomBar;
  181. public Action BottomBarHeightChanged;
  182. public int BottomBarHeight { get; private set; }
  183. private FnzVideo player;
  184. private bool isPlayAudio;
  185. private string PlayerCssClass => "w-100" + (isPlayAudio ? " player-audio" : " player-video");
  186. private async Task PlayTrack(string path)
  187. {
  188. if (player != null) await player.Reset();
  189. currentPlayingUrl = path;
  190. requestedPlay = true;
  191. StateHasChanged();
  192. }
  193. private async Task PlayerLoaded(EventArgs args)
  194. {
  195. await player.Play();
  196. isPlayAudio = await player.CheckIsAudioOnly();
  197. BottomBarHeight = bottomBar == null ? 0 : await bottomBar.GetClientHeight();
  198. StateHasChanged();
  199. BottomBarHeightChanged?.Invoke();
  200. }
  201. }