MainPresenter.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using JetBrains.Annotations;
  2. using Unity.Cloud.Collaborate.Assets;
  3. using Unity.Cloud.Collaborate.Components;
  4. using Unity.Cloud.Collaborate.Models;
  5. using Unity.Cloud.Collaborate.Models.Structures;
  6. using Unity.Cloud.Collaborate.Views;
  7. using UnityEngine;
  8. using UnityEngine.Assertions;
  9. namespace Unity.Cloud.Collaborate.Presenters
  10. {
  11. internal class MainPresenter : IMainPresenter
  12. {
  13. [NotNull]
  14. readonly IMainView m_View;
  15. [NotNull]
  16. readonly IMainModel m_Model;
  17. bool m_IsStarted;
  18. const string k_ErrorOccuredId = "error_occured";
  19. const string k_ConflictsDetectedId = "conflicts_detected";
  20. const string k_RevisionsAvailableId = "revisions_available";
  21. public MainPresenter([NotNull] IMainView view, [NotNull] IMainModel model)
  22. {
  23. m_View = view;
  24. m_Model = model;
  25. }
  26. /// <inheritdoc />
  27. public void Start()
  28. {
  29. Assert.IsFalse(m_IsStarted, "The presenter has already been started.");
  30. m_IsStarted = true;
  31. // Setup listeners.
  32. m_Model.ConflictStatusChange += OnConflictStatusChange;
  33. m_Model.OperationStatusChange += OnOperationStatusChange;
  34. m_Model.OperationProgressChange += OnOperationProgressChange;
  35. m_Model.ErrorOccurred += OnErrorOccurred;
  36. m_Model.ErrorCleared += OnErrorCleared;
  37. m_Model.RemoteRevisionsAvailabilityChange += OnRemoteRevisionsAvailabilityChange;
  38. m_Model.BackButtonStateUpdated += OnBackButtonStateUpdated;
  39. m_Model.StateChanged += OnStateChanged;
  40. // Update progress info.
  41. var progressInfo = m_Model.ProgressInfo;
  42. if (progressInfo != null)
  43. {
  44. OnOperationStatusChange(true);
  45. OnOperationProgressChange(m_Model.ProgressInfo);
  46. }
  47. // Update error info.
  48. var errorInfo = m_Model.ErrorInfo;
  49. if (errorInfo != null)
  50. {
  51. OnErrorOccurred(errorInfo);
  52. }
  53. else
  54. {
  55. OnErrorCleared();
  56. }
  57. // Get initial values.
  58. OnConflictStatusChange(m_Model.Conflicted);
  59. OnRemoteRevisionsAvailabilityChange(m_Model.RemoteRevisionsAvailable);
  60. PopulateInitialData();
  61. }
  62. /// <inheritdoc />
  63. public void Stop()
  64. {
  65. Assert.IsTrue(m_IsStarted, "The presenter has already been stopped.");
  66. m_IsStarted = false;
  67. m_Model.ConflictStatusChange -= OnConflictStatusChange;
  68. m_Model.OperationStatusChange -= OnOperationStatusChange;
  69. m_Model.OperationProgressChange -= OnOperationProgressChange;
  70. m_Model.ErrorOccurred -= OnErrorOccurred;
  71. m_Model.ErrorCleared -= OnErrorCleared;
  72. m_Model.RemoteRevisionsAvailabilityChange -= OnRemoteRevisionsAvailabilityChange;
  73. m_Model.BackButtonStateUpdated -= OnBackButtonStateUpdated;
  74. m_Model.StateChanged -= OnStateChanged;
  75. }
  76. /// <summary>
  77. /// Refresh state from the model.
  78. /// </summary>
  79. void OnStateChanged()
  80. {
  81. PopulateInitialData();
  82. }
  83. /// <summary>
  84. /// Populate the view with the initial data from the model.
  85. /// </summary>
  86. void PopulateInitialData()
  87. {
  88. // Set tab.
  89. m_View.SetTab(m_Model.CurrentTabIndex);
  90. // Update back navigation
  91. OnBackButtonStateUpdated(m_Model.GetBackNavigation()?.text);
  92. }
  93. /// <inheritdoc />
  94. public IHistoryPresenter AssignHistoryPresenter(IHistoryView view)
  95. {
  96. var presenter = new HistoryPresenter(view, m_Model.ConstructHistoryModel(), m_Model);
  97. view.Presenter = presenter;
  98. return presenter;
  99. }
  100. /// <inheritdoc />
  101. public IChangesPresenter AssignChangesPresenter(IChangesView view)
  102. {
  103. var presenter = new ChangesPresenter(view, m_Model.ConstructChangesModel(), m_Model);
  104. view.Presenter = presenter;
  105. return presenter;
  106. }
  107. /// <inheritdoc />
  108. public void RequestCancelJob()
  109. {
  110. m_Model.RequestCancelJob();
  111. }
  112. /// <inheritdoc />
  113. public void UpdateTabIndex(int index)
  114. {
  115. m_Model.CurrentTabIndex = index;
  116. }
  117. /// <inheritdoc />
  118. public void NavigateBack()
  119. {
  120. // Grab back action from the model, clear it, then invoke it.
  121. var nav = m_Model.GetBackNavigation();
  122. if (nav == null) return;
  123. m_Model.UnregisterBackNavigation(nav.Value.id);
  124. nav.Value.backAction.Invoke();
  125. }
  126. /// <summary>
  127. /// Display an alert if there is conflicts detected.
  128. /// </summary>
  129. /// <param name="conflicts">True if conflicts exist.</param>
  130. void OnConflictStatusChange(bool conflicts)
  131. {
  132. if (conflicts)
  133. {
  134. m_View.AddAlert(k_ConflictsDetectedId, AlertBox.AlertLevel.Alert, StringAssets.conflictsDetected);
  135. }
  136. else
  137. {
  138. m_View.RemoveAlert(k_ConflictsDetectedId);
  139. }
  140. }
  141. /// <summary>
  142. /// Display a progress bar if an operation has started.
  143. /// </summary>
  144. /// <param name="inProgress"></param>
  145. void OnOperationStatusChange(bool inProgress)
  146. {
  147. if (inProgress)
  148. {
  149. m_View.AddOperationProgress();
  150. }
  151. else
  152. {
  153. m_View.RemoveOperationProgress();
  154. }
  155. }
  156. /// <summary>
  157. /// Update progress bar with incremental details.
  158. /// </summary>
  159. /// <param name="progressInfo"></param>
  160. void OnOperationProgressChange(IProgressInfo progressInfo)
  161. {
  162. m_View.SetOperationProgress(progressInfo.Title, progressInfo.Details,
  163. progressInfo.PercentageComplete, progressInfo.CurrentCount,
  164. progressInfo.TotalCount, progressInfo.PercentageProgressType, progressInfo.CanCancel);
  165. }
  166. /// <summary>
  167. /// Display an error.
  168. /// </summary>
  169. /// <param name="errorInfo"></param>
  170. void OnErrorOccurred(IErrorInfo errorInfo)
  171. {
  172. if (errorInfo.Behaviour == ErrorInfoBehavior.Alert)
  173. {
  174. m_View.AddAlert(k_ErrorOccuredId, AlertBox.AlertLevel.Alert, errorInfo.Message, (StringAssets.clear, m_Model.ClearError));
  175. }
  176. }
  177. /// <summary>
  178. /// Clear the error state.
  179. /// </summary>
  180. void OnErrorCleared()
  181. {
  182. m_View.RemoveAlert(k_ErrorOccuredId);
  183. }
  184. /// <summary>
  185. /// Show or clear the revisions to fetch alert based on whether or not they are available.
  186. /// </summary>
  187. /// <param name="remoteRevisionsAvailable">True if there are remote revisions to pull down.</param>
  188. void OnRemoteRevisionsAvailabilityChange(bool remoteRevisionsAvailable)
  189. {
  190. if (remoteRevisionsAvailable)
  191. {
  192. m_View.AddAlert(k_RevisionsAvailableId, AlertBox.AlertLevel.Info, StringAssets.syncRemoteRevisionsMessage, (StringAssets.sync, m_Model.RequestSync));
  193. }
  194. else
  195. {
  196. m_View.RemoveAlert(k_RevisionsAvailableId);
  197. }
  198. }
  199. /// <summary>
  200. /// Clear or show back navigation button.
  201. /// </summary>
  202. /// <param name="title">Text to display next to the back navigation. Null means no back navigation.</param>
  203. void OnBackButtonStateUpdated([CanBeNull] string title)
  204. {
  205. if (title == null)
  206. {
  207. m_View.ClearBackNavigation();
  208. }
  209. else
  210. {
  211. m_View.DisplayBackNavigation(title);
  212. }
  213. }
  214. }
  215. }