DownloadQueueViewController.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using CustomUI.BeatSaber;
  2. using CustomUI.Utilities;
  3. using HMUI;
  4. using SongBrowser.DataAccess.BeatSaverApi;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using TMPro;
  10. using UnityEngine;
  11. using UnityEngine.UI;
  12. using VRUI;
  13. using Logger = SongBrowser.Logging.Logger;
  14. // Modified From: https://github.com/andruzzzhka/BeatSaverDownloader
  15. // - Adding queue count
  16. namespace SongBrowser.UI.DownloadQueue
  17. {
  18. class DownloadQueueViewController : VRUIViewController, TableView.IDataSource
  19. {
  20. public event Action allSongsDownloaded;
  21. public List<Song> queuedSongs = new List<Song>();
  22. TextMeshProUGUI _titleText;
  23. Button _abortButton;
  24. TableView _queuedSongsTableView;
  25. LevelListTableCell _songListTableCellInstance;
  26. private Button _pageUpButton;
  27. private Button _pageDownButton;
  28. protected override void DidActivate(bool firstActivation, ActivationType type)
  29. {
  30. if (firstActivation && type == ActivationType.AddedToHierarchy)
  31. {
  32. SongDownloader.Instance.songDownloaded -= SongDownloaded;
  33. SongDownloader.Instance.songDownloaded += SongDownloaded;
  34. _songListTableCellInstance = Resources.FindObjectsOfTypeAll<LevelListTableCell>().First(x => (x.name == "LevelListTableCell"));
  35. _titleText = BeatSaberUI.CreateText(rectTransform, "DOWNLOAD QUEUE", new Vector2(0f, 35f));
  36. _titleText.alignment = TextAlignmentOptions.Top;
  37. _titleText.fontSize = 6f;
  38. _pageUpButton = Instantiate(Resources.FindObjectsOfTypeAll<Button>().Last(x => (x.name == "PageUpButton")), rectTransform, false);
  39. (_pageUpButton.transform as RectTransform).anchorMin = new Vector2(0.5f, 1f);
  40. (_pageUpButton.transform as RectTransform).anchorMax = new Vector2(0.5f, 1f);
  41. (_pageUpButton.transform as RectTransform).anchoredPosition = new Vector2(0f, -14f);
  42. (_pageUpButton.transform as RectTransform).sizeDelta = new Vector2(40f, 10f);
  43. _pageUpButton.interactable = true;
  44. _pageUpButton.onClick.AddListener(delegate ()
  45. {
  46. _queuedSongsTableView.GetPrivateField<TableViewScroller>("_scroller").PageScrollUp();
  47. });
  48. _pageDownButton = Instantiate(Resources.FindObjectsOfTypeAll<Button>().Last(x => (x.name == "PageDownButton")), rectTransform, false);
  49. (_pageDownButton.transform as RectTransform).anchorMin = new Vector2(0.5f, 0f);
  50. (_pageDownButton.transform as RectTransform).anchorMax = new Vector2(0.5f, 0f);
  51. (_pageDownButton.transform as RectTransform).anchoredPosition = new Vector2(0f, 8f);
  52. (_pageDownButton.transform as RectTransform).sizeDelta = new Vector2(40f, 10f);
  53. _pageDownButton.interactable = true;
  54. _pageDownButton.onClick.AddListener(delegate ()
  55. {
  56. _queuedSongsTableView.GetPrivateField<TableViewScroller>("_scroller").PageScrollDown();
  57. });
  58. var gameObject = new GameObject();
  59. gameObject.SetActive(false);
  60. _queuedSongsTableView = gameObject.AddComponent<TableView>();
  61. _queuedSongsTableView.transform.SetParent(rectTransform, false);
  62. _queuedSongsTableView.SetPrivateField("_isInitialized", false);
  63. _queuedSongsTableView.SetPrivateField("_preallocatedCells", new TableView.CellsGroup[0]);
  64. _queuedSongsTableView.Init();
  65. gameObject.SetActive(true);
  66. RectMask2D viewportMask = Instantiate(Resources.FindObjectsOfTypeAll<RectMask2D>().First(), _queuedSongsTableView.transform, false);
  67. viewportMask.transform.DetachChildren();
  68. _queuedSongsTableView.GetComponentsInChildren<RectTransform>().First(x => x.name == "Content").transform.SetParent(viewportMask.rectTransform, false);
  69. (_queuedSongsTableView.transform as RectTransform).anchorMin = new Vector2(0.3f, 0.5f);
  70. (_queuedSongsTableView.transform as RectTransform).anchorMax = new Vector2(0.7f, 0.5f);
  71. (_queuedSongsTableView.transform as RectTransform).sizeDelta = new Vector2(0f, 60f);
  72. (_queuedSongsTableView.transform as RectTransform).anchoredPosition = new Vector3(0f, -3f);
  73. ReflectionUtil.SetPrivateField(_queuedSongsTableView, "_pageUpButton", _pageUpButton);
  74. ReflectionUtil.SetPrivateField(_queuedSongsTableView, "_pageDownButton", _pageDownButton);
  75. _queuedSongsTableView.selectionType = TableViewSelectionType.None;
  76. _queuedSongsTableView.dataSource = this;
  77. _abortButton = BeatSaberUI.CreateUIButton(rectTransform, "PlayButton", new Vector2(36f, -30f), new Vector2(20f, 10f), AbortDownloads, "Abort All");
  78. _abortButton.ToggleWordWrapping(false);
  79. }
  80. }
  81. public void AbortDownloads()
  82. {
  83. Logger.Log("Cancelling downloads...");
  84. foreach (Song song in queuedSongs.Where(x => x.songQueueState == SongQueueState.Downloading || x.songQueueState == SongQueueState.Queued))
  85. {
  86. song.songQueueState = SongQueueState.Error;
  87. }
  88. Refresh();
  89. allSongsDownloaded?.Invoke();
  90. }
  91. protected override void DidDeactivate(DeactivationType type)
  92. {
  93. SongDownloader.Instance.songDownloaded -= SongDownloaded;
  94. }
  95. public void EnqueueSong(Song song, bool startDownload = true)
  96. {
  97. queuedSongs.Add(song);
  98. song.songQueueState = SongQueueState.Queued;
  99. if (startDownload && queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading) < PluginConfig.maxSimultaneousDownloads)
  100. {
  101. StartCoroutine(DownloadSong(song));
  102. Refresh();
  103. }
  104. }
  105. public void DownloadAllSongsFromQueue()
  106. {
  107. Logger.Log("Downloading all songs from queue...");
  108. for (int i = 0; i < Math.Min(PluginConfig.maxSimultaneousDownloads, queuedSongs.Count); i++)
  109. {
  110. StartCoroutine(DownloadSong(queuedSongs[i]));
  111. }
  112. Refresh();
  113. }
  114. IEnumerator DownloadSong(Song song)
  115. {
  116. yield return SongDownloader.Instance.DownloadSongCoroutine(song);
  117. Refresh();
  118. }
  119. private void SongDownloaded(Song obj)
  120. {
  121. Refresh();
  122. if (queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading) < PluginConfig.maxSimultaneousDownloads && queuedSongs.Any(x => x.songQueueState == SongQueueState.Queued))
  123. {
  124. StartCoroutine(DownloadSong(queuedSongs.First(x => x.songQueueState == SongQueueState.Queued)));
  125. }
  126. }
  127. public void Refresh()
  128. {
  129. int removed = queuedSongs.RemoveAll(x => x.songQueueState == SongQueueState.Downloaded || x.songQueueState == SongQueueState.Error);
  130. Logger.Log($"Removed {removed} songs from queue");
  131. _queuedSongsTableView.ReloadData();
  132. _queuedSongsTableView.ScrollToCellWithIdx(0, TableViewScroller.ScrollPositionType.Beginning, true);
  133. if (queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading || x.songQueueState == SongQueueState.Queued) == 0)
  134. {
  135. Logger.Log("All songs downloaded!");
  136. allSongsDownloaded?.Invoke();
  137. }
  138. if (queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading) < PluginConfig.maxSimultaneousDownloads && queuedSongs.Any(x => x.songQueueState == SongQueueState.Queued))
  139. StartCoroutine(DownloadSong(queuedSongs.First(x => x.songQueueState == SongQueueState.Queued)));
  140. }
  141. public float CellSize()
  142. {
  143. return 10f;
  144. }
  145. public int NumberOfCells()
  146. {
  147. return queuedSongs.Count;
  148. }
  149. public TableCell CellForIdx(TableView view, int row)
  150. {
  151. LevelListTableCell _tableCell = Instantiate(_songListTableCellInstance);
  152. DownloadQueueTableCell _queueCell = _tableCell.gameObject.AddComponent<DownloadQueueTableCell>();
  153. _queueCell.Init(queuedSongs[row]);
  154. return _queueCell;
  155. }
  156. }
  157. }