CollabHistoryWindow.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEditor.Collaboration;
  5. #if UNITY_2019_1_OR_NEWER
  6. using UnityEditor.UIElements;
  7. using UnityEngine.UIElements;
  8. #else
  9. using UnityEditor.Experimental.UIElements;
  10. using UnityEngine.Experimental.UIElements;
  11. using UnityEngine.Experimental.UIElements.StyleEnums;
  12. #endif
  13. using UnityEngine;
  14. using UnityEditor.Connect;
  15. namespace UnityEditor
  16. {
  17. internal class CollabHistoryWindow : EditorWindow, ICollabHistoryWindow
  18. {
  19. #if UNITY_2019_1_OR_NEWER
  20. private const string ResourcesPath = "Packages/com.unity.collab-proxy/Editor/Resources/Styles/";
  21. #else
  22. private const string ResourcesPath = "StyleSheets/";
  23. #endif
  24. const string kWindowTitle = "Collab History";
  25. const string kServiceUrl = "developer.cloud.unity3d.com";
  26. [MenuItem("Window/Asset Management/Collab History", false, 1)]
  27. public static void ShowHistoryWindow()
  28. {
  29. EditorWindow.GetWindow<CollabHistoryWindow>(kWindowTitle);
  30. }
  31. [MenuItem("Window/Asset Management/Collab History", true)]
  32. public static bool ValidateShowHistoryWindow()
  33. {
  34. return Collab.instance.IsCollabEnabledForCurrentProject();
  35. }
  36. CollabHistoryPresenter m_Presenter;
  37. Dictionary<HistoryState, VisualElement> m_Views;
  38. List<CollabHistoryItem> m_HistoryItems = new List<CollabHistoryItem>();
  39. HistoryState m_State;
  40. VisualElement m_Container;
  41. PagedListView m_Pager;
  42. ScrollView m_HistoryView;
  43. int m_ItemsPerPage = 5;
  44. string m_InProgressRev;
  45. bool m_RevisionActionsEnabled;
  46. public CollabHistoryWindow()
  47. {
  48. minSize = new Vector2(275, 50);
  49. }
  50. public void OnEnable()
  51. {
  52. SetupGUI();
  53. name = "CollabHistory";
  54. if (m_Presenter == null)
  55. {
  56. m_Presenter = new CollabHistoryPresenter(this, new CollabHistoryItemFactory(), new RevisionsService(Collab.instance, UnityConnect.instance));
  57. }
  58. m_Presenter.OnWindowEnabled();
  59. }
  60. public void OnDisable()
  61. {
  62. m_Presenter.OnWindowDisabled();
  63. }
  64. public bool revisionActionsEnabled
  65. {
  66. get { return m_RevisionActionsEnabled; }
  67. set
  68. {
  69. if (m_RevisionActionsEnabled == value)
  70. return;
  71. m_RevisionActionsEnabled = value;
  72. foreach (var historyItem in m_HistoryItems)
  73. {
  74. historyItem.RevisionActionsEnabled = value;
  75. }
  76. }
  77. }
  78. private void AddStyleSheetPath(VisualElement root, string path)
  79. {
  80. #if UNITY_2019_1_OR_NEWER
  81. root.styleSheets.Add(EditorGUIUtility.Load(path) as StyleSheet);
  82. #else
  83. root.AddStyleSheetPath(path);
  84. #endif
  85. }
  86. public void SetupGUI()
  87. {
  88. #if UNITY_2019_1_OR_NEWER
  89. var root = this.rootVisualElement;
  90. #else
  91. var root = this.GetRootVisualContainer();
  92. #endif
  93. AddStyleSheetPath(root, ResourcesPath + "CollabHistoryCommon.uss");
  94. if (EditorGUIUtility.isProSkin)
  95. {
  96. AddStyleSheetPath(root, ResourcesPath + "CollabHistoryDark.uss");
  97. }
  98. else
  99. {
  100. AddStyleSheetPath(root, ResourcesPath + "CollabHistoryLight.uss");
  101. }
  102. m_Container = new VisualElement();
  103. m_Container.StretchToParentSize();
  104. root.Add(m_Container);
  105. m_Pager = new PagedListView()
  106. {
  107. name = "PagedElement",
  108. pageSize = m_ItemsPerPage
  109. };
  110. var errorView = new StatusView()
  111. {
  112. message = "An Error Occurred",
  113. icon = EditorGUIUtility.LoadIconRequired("Collab.Warning") as Texture,
  114. };
  115. var noInternetView = new StatusView()
  116. {
  117. message = "No Internet Connection",
  118. icon = EditorGUIUtility.LoadIconRequired("Collab.NoInternet") as Texture,
  119. };
  120. var maintenanceView = new StatusView()
  121. {
  122. message = "Maintenance",
  123. };
  124. var loginView = new StatusView()
  125. {
  126. message = "Sign in to access Collaborate",
  127. buttonText = "Sign in...",
  128. callback = SignInClick,
  129. };
  130. var noSeatView = new StatusView()
  131. {
  132. message = "Ask your project owner for access to Unity Teams",
  133. buttonText = "Learn More",
  134. callback = NoSeatClick,
  135. };
  136. var waitingView = new StatusView()
  137. {
  138. message = "Updating...",
  139. };
  140. m_HistoryView = new ScrollView() { name = "HistoryContainer", showHorizontal = false};
  141. m_HistoryView.contentContainer.StretchToParentWidth();
  142. m_HistoryView.Add(m_Pager);
  143. m_Views = new Dictionary<HistoryState, VisualElement>()
  144. {
  145. {HistoryState.Error, errorView},
  146. {HistoryState.Offline, noInternetView},
  147. {HistoryState.Maintenance, maintenanceView},
  148. {HistoryState.LoggedOut, loginView},
  149. {HistoryState.NoSeat, noSeatView},
  150. {HistoryState.Waiting, waitingView},
  151. {HistoryState.Ready, m_HistoryView}
  152. };
  153. }
  154. public void UpdateState(HistoryState state, bool force)
  155. {
  156. if (state == m_State && !force)
  157. return;
  158. m_State = state;
  159. switch (state)
  160. {
  161. case HistoryState.Ready:
  162. UpdateHistoryView(m_Pager);
  163. break;
  164. case HistoryState.Disabled:
  165. Close();
  166. return;
  167. }
  168. m_Container.Clear();
  169. m_Container.Add(m_Views[m_State]);
  170. }
  171. public void UpdateRevisions(IEnumerable<RevisionData> datas, string tip, int totalRevisions, int currentPage)
  172. {
  173. var elements = new List<VisualElement>();
  174. var isFullDateObtained = false; // Has everything from this date been obtained?
  175. m_HistoryItems.Clear();
  176. if (datas != null)
  177. {
  178. DateTime currentDate = DateTime.MinValue;
  179. foreach (var data in datas)
  180. {
  181. if (data.timeStamp.Date != currentDate.Date)
  182. {
  183. elements.Add(new CollabHistoryRevisionLine(data.timeStamp, isFullDateObtained));
  184. currentDate = data.timeStamp;
  185. }
  186. var item = new CollabHistoryItem(data);
  187. m_HistoryItems.Add(item);
  188. var container = new VisualElement();
  189. container.style.flexDirection = FlexDirection.Row;
  190. if (data.current)
  191. {
  192. isFullDateObtained = true;
  193. container.AddToClassList("currentRevision");
  194. container.AddToClassList("obtainedRevision");
  195. }
  196. else if (data.obtained)
  197. {
  198. container.AddToClassList("obtainedRevision");
  199. }
  200. else
  201. {
  202. container.AddToClassList("absentRevision");
  203. }
  204. // If we use the index as-is, the latest commit will become #1, but we want it to be last
  205. container.Add(new CollabHistoryRevisionLine(data.index));
  206. container.Add(item);
  207. elements.Add(container);
  208. }
  209. }
  210. m_HistoryView.scrollOffset = new Vector2(0, 0);
  211. m_Pager.totalItems = totalRevisions;
  212. m_Pager.curPage = currentPage;
  213. m_Pager.items = elements;
  214. }
  215. public string inProgressRevision
  216. {
  217. get { return m_InProgressRev; }
  218. set
  219. {
  220. m_InProgressRev = value;
  221. foreach (var historyItem in m_HistoryItems)
  222. {
  223. historyItem.SetInProgressStatus(value);
  224. }
  225. }
  226. }
  227. public int itemsPerPage
  228. {
  229. set
  230. {
  231. if (m_ItemsPerPage == value)
  232. return;
  233. m_Pager.pageSize = m_ItemsPerPage;
  234. }
  235. }
  236. public PageChangeAction OnPageChangeAction
  237. {
  238. set { m_Pager.OnPageChanged = value; }
  239. }
  240. public RevisionAction OnGoBackAction
  241. {
  242. set { CollabHistoryItem.s_OnGoBack = value; }
  243. }
  244. public RevisionAction OnUpdateAction
  245. {
  246. set { CollabHistoryItem.s_OnUpdate = value; }
  247. }
  248. public RevisionAction OnRestoreAction
  249. {
  250. set { CollabHistoryItem.s_OnRestore = value; }
  251. }
  252. public ShowBuildAction OnShowBuildAction
  253. {
  254. set { CollabHistoryItem.s_OnShowBuild = value; }
  255. }
  256. public Action OnShowServicesAction
  257. {
  258. set { CollabHistoryItem.s_OnShowServices = value; }
  259. }
  260. void UpdateHistoryView(VisualElement history)
  261. {
  262. }
  263. void NoSeatClick()
  264. {
  265. var connection = UnityConnect.instance;
  266. var env = connection.GetEnvironment();
  267. // Map environment to url - prod is special
  268. if (env == "production")
  269. env = "";
  270. else
  271. env += "-";
  272. var url = "https://" + env + kServiceUrl
  273. + "/orgs/" + connection.GetOrganizationId()
  274. + "/projects/" + connection.GetProjectName()
  275. + "/unity-teams/";
  276. Application.OpenURL(url);
  277. }
  278. void SignInClick()
  279. {
  280. UnityConnect.instance.ShowLogin();
  281. }
  282. }
  283. }