settings-ariang.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. (function () {
  2. 'use strict';
  3. angular.module('ariaNg').controller('AriaNgSettingsController', ['$rootScope', '$scope', '$routeParams', '$window', '$interval', '$timeout', '$filter', 'clipboard', 'ariaNgLanguages', 'ariaNgCommonService', 'ariaNgVersionService', 'ariaNgKeyboardService', 'ariaNgNotificationService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgFileService', 'ariaNgSettingService', 'ariaNgMonitorService', 'ariaNgTitleService', 'aria2SettingService', 'ariaNgNativeElectronService', function ($rootScope, $scope, $routeParams, $window, $interval, $timeout, $filter, clipboard, ariaNgLanguages, ariaNgCommonService, ariaNgVersionService, ariaNgKeyboardService, ariaNgNotificationService, ariaNgLocalizationService, ariaNgLogService, ariaNgFileService, ariaNgSettingService, ariaNgMonitorService, ariaNgTitleService, aria2SettingService, ariaNgNativeElectronService) {
  4. var extendType = $routeParams.extendType;
  5. var lastRefreshPageNotification = null;
  6. var getFinalTitle = function () {
  7. return ariaNgTitleService.getFinalTitleByGlobalStat({
  8. globalStat: ariaNgMonitorService.getCurrentGlobalStat(),
  9. currentRpcProfile: getCurrentRPCProfile()
  10. });
  11. };
  12. var getCurrentRPCProfile = function () {
  13. if (!$scope.context || !$scope.context.rpcSettings || $scope.context.rpcSettings.length < 1) {
  14. return null;
  15. }
  16. for (var i = 0; i < $scope.context.rpcSettings.length; i++) {
  17. var rpcSetting = $scope.context.rpcSettings[i];
  18. if (rpcSetting.isDefault) {
  19. return rpcSetting;
  20. }
  21. }
  22. return null;
  23. };
  24. var getNativeSettings = function () {
  25. var originalConfig = ariaNgNativeElectronService.getNativeConfig();
  26. var config = {};
  27. config.defaultPosition = originalConfig.defaultPosition || 'last-position';
  28. if (!originalConfig.minimizedToTray) {
  29. config.afterMainWindowClosed = 'exit-application';
  30. } else {
  31. config.afterMainWindowClosed = 'minimize-to-tray';
  32. }
  33. config.notificationSound = originalConfig.notificationSound;
  34. config.execCommandOnStartup = originalConfig.execCommandOnStartup;
  35. config.execCommandArgumentsOnStartup = originalConfig.execCommandArgumentsOnStartup;
  36. if (!originalConfig.execDetachedCommandOnStartup) {
  37. config.execCommandOptionsOnStartup = 'as-child-process';
  38. } else {
  39. config.execCommandOptionsOnStartup = 'as-detached-process';
  40. }
  41. return config;
  42. };
  43. var setNeedRefreshPage = function () {
  44. if (lastRefreshPageNotification) {
  45. return;
  46. }
  47. lastRefreshPageNotification = ariaNgNotificationService.notifyInPage('', 'Configuration has been modified, please reload the page for the changes to take effect.', {
  48. delay: false,
  49. type: 'info',
  50. templateUrl: 'views/notification-reloadable.html',
  51. onClose: function () {
  52. lastRefreshPageNotification = null;
  53. }
  54. });
  55. };
  56. $scope.context = {
  57. currentTab: 'global',
  58. ariaNgNativeVersion: ariaNgVersionService.getBuildVersion(),
  59. ariaNgVersion: ariaNgVersionService.getAriaNgVersion(),
  60. buildCommit: ariaNgVersionService.getBuildCommit(),
  61. isCurrentLatestVersion: false,
  62. runtimeEnvironment: ariaNgNativeElectronService.getRuntimeEnvironment(),
  63. runtimeEnvironmentCollapsed: true,
  64. languages: ariaNgLanguages,
  65. titlePreview: getFinalTitle(),
  66. availableTime: ariaNgCommonService.getTimeOptions([1000, 2000, 3000, 5000, 10000, 30000, 60000], true),
  67. trueFalseOptions: [{name: 'Enabled', value: true}, {name: 'Disabled', value: false}],
  68. showRpcSecret: false,
  69. isInsecureProtocolDisabled: ariaNgSettingService.isInsecureProtocolDisabled(),
  70. settings: ariaNgSettingService.getAllOptions(),
  71. nativeSettings: getNativeSettings(),
  72. sessionSettings: ariaNgSettingService.getAllSessionOptions(),
  73. rpcSettings: ariaNgSettingService.getAllRpcSettings(),
  74. isMacKeyboardLike: ariaNgKeyboardService.isMacKeyboardLike(),
  75. isSupportReconnect: aria2SettingService.canReconnect(),
  76. isSupportBlob: ariaNgFileService.isSupportBlob(),
  77. isSupportDarkMode: ariaNgSettingService.isBrowserSupportDarkMode(),
  78. importSettings: null,
  79. exportSettings: null,
  80. exportSettingsCopied: false,
  81. exportCommandApiOptions: null
  82. };
  83. $scope.context.titlePreview = getFinalTitle();
  84. $scope.context.showDebugMode = false; // AriaNg Native does not allow to disable debug mode when current is in debug mode
  85. $scope.changeGlobalTab = function () {
  86. $scope.context.currentTab = 'global';
  87. };
  88. $scope.isCurrentGlobalTab = function () {
  89. return $scope.context.currentTab === 'global';
  90. };
  91. $scope.changeRpcTab = function (rpcIndex) {
  92. $scope.context.currentTab = 'rpc' + rpcIndex;
  93. };
  94. $scope.isCurrentRpcTab = function (rpcIndex) {
  95. return $scope.context.currentTab === 'rpc' + rpcIndex;
  96. };
  97. $scope.getCurrentRpcTabIndex = function () {
  98. if ($scope.isCurrentGlobalTab()) {
  99. return -1;
  100. }
  101. return parseInt($scope.context.currentTab.substring(3));
  102. };
  103. $scope.checkUpdate = function () {
  104. return ariaNgVersionService.getTheLatestVersion()
  105. .then(function onSuccess(response) {
  106. ariaNgLogService.debug('[AriaNgSettingsController.checkUpdate] latest version info', response);
  107. if (!response || !response.data || !response.data.tag_name) {
  108. ariaNgLogService.warn('[AriaNgSettingsController.checkUpdate] data format of latest version is invalid', response);
  109. ariaNgCommonService.showError('Failed to get latest version!');
  110. return;
  111. }
  112. var latestVersion = response.data.tag_name;
  113. if (ariaNgVersionService.compareVersion($scope.context.ariaNgNativeVersion, latestVersion) >= 0) {
  114. ariaNgCommonService.showInfo('Check Update', 'You have installed the latest version!');
  115. $scope.context.isCurrentLatestVersion = true;
  116. } else {
  117. ariaNgNativeElectronService.openProjectReleaseLink();
  118. }
  119. }).catch(function onError(response) {
  120. ariaNgLogService.error('[AriaNgSettingsController.checkUpdate] failed to get latest version', response);
  121. ariaNgCommonService.showError('Failed to get latest version!');
  122. });
  123. };
  124. $scope.updateTitlePreview = function () {
  125. $scope.context.titlePreview = getFinalTitle();
  126. };
  127. $rootScope.swipeActions.extendLeftSwipe = function () {
  128. var tabIndex = -1;
  129. if (!$scope.isCurrentGlobalTab()) {
  130. tabIndex = parseInt($scope.getCurrentRpcTabIndex());
  131. }
  132. if (tabIndex < $scope.context.rpcSettings.length - 1) {
  133. $scope.changeRpcTab(tabIndex + 1);
  134. return true;
  135. } else {
  136. return false;
  137. }
  138. };
  139. $rootScope.swipeActions.extendRightSwipe = function () {
  140. var tabIndex = -1;
  141. if (!$scope.isCurrentGlobalTab()) {
  142. tabIndex = parseInt($scope.getCurrentRpcTabIndex());
  143. }
  144. if (tabIndex > 0) {
  145. $scope.changeRpcTab(tabIndex - 1);
  146. return true;
  147. } else if (tabIndex === 0) {
  148. $scope.changeGlobalTab();
  149. return true;
  150. } else {
  151. return false;
  152. }
  153. };
  154. $scope.isSupportNotification = function () {
  155. return ariaNgNotificationService.isSupportBrowserNotification() &&
  156. ariaNgSettingService.isCurrentRpcUseWebSocket($scope.context.settings.protocol);
  157. };
  158. $scope.setLanguage = function (value) {
  159. if (ariaNgSettingService.setLanguage(value)) {
  160. ariaNgLocalizationService.applyLanguage(value);
  161. }
  162. $scope.updateTitlePreview();
  163. };
  164. $scope.setAutoCheckUpdates = function (value) {
  165. ariaNgSettingService.setAutoCheckUpdates(value);
  166. };
  167. $scope.setTheme = function (value) {
  168. ariaNgSettingService.setTheme(value);
  169. $rootScope.setTheme(value);
  170. };
  171. $scope.setDebugMode = function (value) {
  172. ariaNgSettingService.setDebugMode(value);
  173. };
  174. $scope.setTitle = function (value) {
  175. ariaNgSettingService.setTitle(value);
  176. };
  177. $scope.setEnableBrowserNotification = function (value) {
  178. ariaNgSettingService.setBrowserNotification(value);
  179. if (value && !ariaNgNotificationService.hasBrowserPermission()) {
  180. ariaNgNotificationService.requestBrowserPermission(function (result) {
  181. if (!result.granted) {
  182. $scope.context.settings.browserNotification = false;
  183. ariaNgCommonService.showError('You have disabled notification in your browser. You should change your browser\'s settings before you enable this function.');
  184. }
  185. });
  186. }
  187. };
  188. $scope.setBrowserNotificationSound = function (value) {
  189. ariaNgSettingService.setBrowserNotificationSound(value);
  190. ariaNgNativeElectronService.setNotificationSound(value);
  191. };
  192. $scope.setBrowserNotificationFrequency = function (value) {
  193. ariaNgSettingService.setBrowserNotificationFrequency(value);
  194. };
  195. $scope.setWebSocketReconnectInterval = function (value) {
  196. setNeedRefreshPage();
  197. ariaNgSettingService.setWebSocketReconnectInterval(value);
  198. };
  199. $scope.setTitleRefreshInterval = function (value) {
  200. setNeedRefreshPage();
  201. ariaNgSettingService.setTitleRefreshInterval(value);
  202. };
  203. $scope.setGlobalStatRefreshInterval = function (value) {
  204. setNeedRefreshPage();
  205. ariaNgSettingService.setGlobalStatRefreshInterval(value);
  206. };
  207. $scope.setDownloadTaskRefreshInterval = function (value) {
  208. setNeedRefreshPage();
  209. ariaNgSettingService.setDownloadTaskRefreshInterval(value);
  210. };
  211. $scope.setRPCListDisplayOrder = function (value) {
  212. setNeedRefreshPage();
  213. ariaNgSettingService.setRPCListDisplayOrder(value);
  214. };
  215. $scope.setKeyboardShortcuts = function (value) {
  216. ariaNgSettingService.setKeyboardShortcuts(value);
  217. };
  218. $scope.setSwipeGesture = function (value) {
  219. ariaNgSettingService.setSwipeGesture(value);
  220. };
  221. $scope.setDragAndDropTasks = function (value) {
  222. ariaNgSettingService.setDragAndDropTasks(value);
  223. };
  224. $scope.setAfterCreatingNewTask = function (value) {
  225. ariaNgSettingService.setAfterCreatingNewTask(value);
  226. };
  227. $scope.setRemoveOldTaskAfterRetrying = function (value) {
  228. ariaNgSettingService.setRemoveOldTaskAfterRetrying(value);
  229. };
  230. $scope.setConfirmTaskRemoval = function (value) {
  231. ariaNgSettingService.setConfirmTaskRemoval(value);
  232. };
  233. $scope.setIncludePrefixWhenCopyingFromTaskDetails = function (value) {
  234. ariaNgSettingService.setIncludePrefixWhenCopyingFromTaskDetails(value);
  235. };
  236. $scope.setShowPiecesInfoInTaskDetailPage = function (value) {
  237. ariaNgSettingService.setShowPiecesInfoInTaskDetailPage(value);
  238. };
  239. $scope.setAfterRetryingTask = function (value) {
  240. ariaNgSettingService.setAfterRetryingTask(value);
  241. };
  242. $scope.setDefaultPosition = function (value) {
  243. ariaNgNativeElectronService.setDefaultPosition(value);
  244. }
  245. $scope.setExecCommandOnStartup = function (value) {
  246. ariaNgNativeElectronService.setExecCommandOnStartup(value);
  247. };
  248. $scope.setExecCommandArgumentsOnStartup = function (value) {
  249. ariaNgNativeElectronService.setExecCommandArgumentsOnStartup(value);
  250. };
  251. $scope.setExecCommandOptionsOnStartup = function (value) {
  252. if (value === 'as-child-process') {
  253. ariaNgNativeElectronService.setExecDetachedCommandOnStartup(false);
  254. } else if (value === 'as-detached-process') {
  255. ariaNgNativeElectronService.setExecDetachedCommandOnStartup(true);
  256. }
  257. };
  258. $scope.browseAndSetExecCommandOnStartup = function () {
  259. ariaNgNativeElectronService.showOpenFileDialogAsync([{
  260. name: ariaNgLocalizationService.getLocalizedText('All Files'),
  261. extensions: ['*']
  262. }], function (result) {
  263. if (result && !result.canceled && angular.isArray(result.filePaths) && result.filePaths.length) {
  264. var filePath = result.filePaths[0];
  265. $scope.$apply(function () {
  266. $scope.context.nativeSettings.execCommandOnStartup = filePath;
  267. $scope.setExecCommandOnStartup(filePath);
  268. });
  269. }
  270. });
  271. }
  272. $scope.setAfterMainWindowClosed = function (value) {
  273. if (value === 'minimize-to-tray') {
  274. ariaNgNativeElectronService.setMinimizedToTray(true);
  275. } else if (value === 'exit-application') {
  276. ariaNgNativeElectronService.setMinimizedToTray(false);
  277. }
  278. };
  279. $scope.showImportSettingsModal = function () {
  280. $scope.context.importSettings = null;
  281. angular.element('#import-settings-modal').modal();
  282. };
  283. $('#import-settings-modal').on('hide.bs.modal', function (e) {
  284. $scope.context.importSettings = null;
  285. });
  286. $scope.openAriaNgConfigFile = function () {
  287. ariaNgFileService.openFileContent({
  288. scope: $scope,
  289. fileFilter: '.json',
  290. fileType: 'text'
  291. }, function (result) {
  292. $scope.context.importSettings = result.content;
  293. }, function (error) {
  294. ariaNgCommonService.showError(error);
  295. }, angular.element('#import-file-holder'));
  296. };
  297. $scope.importSettings = function (settings) {
  298. var settingsObj = null;
  299. try {
  300. settingsObj = JSON.parse(settings);
  301. } catch (e) {
  302. ariaNgLogService.error('[AriaNgSettingsController.importSettings] parse settings json error', e);
  303. ariaNgCommonService.showError('Invalid settings data format!');
  304. return;
  305. }
  306. if (!angular.isObject(settingsObj) || angular.isArray(settingsObj)) {
  307. ariaNgLogService.error('[AriaNgSettingsController.importSettings] settings json is not object');
  308. ariaNgCommonService.showError('Invalid settings data format!');
  309. return;
  310. }
  311. if (settingsObj) {
  312. ariaNgCommonService.confirm('Confirm Import', 'Are you sure you want to import all settings?', 'warning', function () {
  313. ariaNgSettingService.importAllOptions(settingsObj);
  314. ariaNgNativeElectronService.setNotificationSound(!!settingsObj.browserNotificationSound);
  315. $window.location.reload();
  316. });
  317. }
  318. };
  319. $scope.showExportSettingsModal = function () {
  320. $scope.context.exportSettings = $filter('json')(ariaNgSettingService.exportAllOptions());
  321. $scope.context.exportSettingsCopied = false;
  322. angular.element('#export-settings-modal').modal();
  323. };
  324. $('#export-settings-modal').on('hide.bs.modal', function (e) {
  325. $scope.context.exportSettings = null;
  326. $scope.context.exportSettingsCopied = false;
  327. });
  328. $scope.copyExportSettings = function () {
  329. clipboard.copyText($scope.context.exportSettings, {
  330. container: angular.element('#export-settings-modal')[0]
  331. });
  332. $scope.context.exportSettingsCopied = true;
  333. };
  334. $scope.addNewRpcSetting = function () {
  335. setNeedRefreshPage();
  336. var newRpcSetting = ariaNgSettingService.addNewRpcSetting();
  337. $scope.context.rpcSettings.push(newRpcSetting);
  338. $scope.changeRpcTab($scope.context.rpcSettings.length - 1);
  339. };
  340. $scope.updateRpcSetting = function (setting, field) {
  341. setNeedRefreshPage();
  342. ariaNgSettingService.updateRpcSetting(setting, field);
  343. };
  344. $scope.removeRpcSetting = function (setting) {
  345. var rpcName = (setting.rpcAlias ? setting.rpcAlias : setting.rpcHost + ':' + setting.rpcPort);
  346. ariaNgCommonService.confirm('Confirm Remove', 'Are you sure you want to remove rpc setting "{rpcName}"?', 'warning', function () {
  347. setNeedRefreshPage();
  348. var currentIndex = $scope.getCurrentRpcTabIndex();
  349. var index = $scope.context.rpcSettings.indexOf(setting);
  350. ariaNgSettingService.removeRpcSetting(setting);
  351. $scope.context.rpcSettings.splice(index, 1);
  352. if (currentIndex >= $scope.context.rpcSettings.length) {
  353. $scope.changeRpcTab($scope.context.rpcSettings.length - 1);
  354. } else if (currentIndex <= 0 || currentIndex <= index) {
  355. ; // Do Nothing
  356. } else { // currentIndex > index
  357. $scope.changeRpcTab(currentIndex - 1);
  358. }
  359. }, false, {
  360. textParams: {
  361. rpcName: rpcName
  362. }
  363. });
  364. };
  365. $scope.showExportCommandAPIModal = function (setting) {
  366. $scope.context.exportCommandApiOptions = {
  367. type: 'setting',
  368. data: setting
  369. };
  370. };
  371. $scope.setDefaultRpcSetting = function (setting) {
  372. if (setting.isDefault) {
  373. return;
  374. }
  375. ariaNgSettingService.setDefaultRpcSetting(setting);
  376. $window.location.reload();
  377. };
  378. $scope.resetSettings = function () {
  379. ariaNgCommonService.confirm('Confirm Reset', 'Are you sure you want to reset all settings?', 'warning', function () {
  380. ariaNgSettingService.resetSettings();
  381. $window.location.reload();
  382. });
  383. };
  384. $scope.clearHistory = function () {
  385. ariaNgCommonService.confirm('Confirm Clear', 'Are you sure you want to clear all settings history?', 'warning', function () {
  386. aria2SettingService.clearSettingsHistorys();
  387. $window.location.reload();
  388. });
  389. };
  390. $scope.reloadApp = function () {
  391. ariaNgNativeElectronService.reload();
  392. };
  393. angular.element('[data-toggle="popover"]').popover();
  394. $rootScope.loadPromise = $timeout(function () {}, 100);
  395. }]);
  396. }());