From 72dc516a0ae871be09760bce1d9ac4d81df09f55 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 6 Nov 2022 23:33:55 +0800 Subject: [PATCH] support set browser notification sound / frequency --- src/langs/zh_Hans.txt | 6 ++ src/langs/zh_Hant.txt | 6 ++ src/scripts/config/constants.js | 3 + src/scripts/config/defaultLanguage.js | 6 ++ src/scripts/controllers/settings-ariang.js | 8 ++ src/scripts/services/ariaNgCommonService.js | 3 + .../services/ariaNgNotificationService.js | 75 ++++++++++++++++++- src/scripts/services/ariaNgSettingService.js | 12 +++ src/views/settings-ariang.html | 26 +++++++ 9 files changed, 144 insertions(+), 1 deletion(-) diff --git a/src/langs/zh_Hans.txt b/src/langs/zh_Hans.txt index d310c745..ca03d15e 100644 --- a/src/langs/zh_Hans.txt +++ b/src/langs/zh_Hans.txt @@ -172,6 +172,12 @@ Tips: You can use the "noprefix" tag to ignore the prefix, "nosuffix" tag to ign Example: ${downspeed:noprefix:nosuffix:scale\=1}=示例: ${downspeed:noprefix:nosuffix:scale\=1} Updating Page Title Interval=页面标题更新间隔 Enable Browser Notification=启用浏览器通知 +Browser Notification Sound=浏览器通知声音 +Browser Notification Frequency=浏览器通知频次 +Unlimited=无限制 +High (Up to 10 Notifications / 1 Minute)=高 (最多 10 条通知 / 每分钟) +Middle (Up to 1 Notification / 1 Minute)=中 (最多 1 条通知 / 每分钟) +Low (Up to 1 Notification / 5 Minutes)=低 (最多 1 条通知 / 每5分钟) WebSocket Auto Reconnect Interval=WebSocket 自动重连时间 Aria2 RPC Alias=Aria2 RPC 别名 Aria2 RPC Address=Aria2 RPC 地址 diff --git a/src/langs/zh_Hant.txt b/src/langs/zh_Hant.txt index 2d151577..4a8dcafc 100644 --- a/src/langs/zh_Hant.txt +++ b/src/langs/zh_Hant.txt @@ -172,6 +172,12 @@ Tips: You can use the "noprefix" tag to ignore the prefix, "nosuffix" tag to ign Example: ${downspeed:noprefix:nosuffix:scale\=1}=示例: ${downspeed:noprefix:nosuffix:scale\=1} Updating Page Title Interval=頁面標題更新間隔 Enable Browser Notification=啟用瀏覽器通知 +Browser Notification Sound=瀏覽器通知聲音 +Browser Notification Frequency=瀏覽器通知頻次 +Unlimited=無限制 +High (Up to 10 Notifications / 1 Minute)=高 (最多 10 條通知 / 每分鐘) +Middle (Up to 1 Notification / 1 Minute)=中 (最多 1 條通知 / 每分鐘) +Low (Up to 1 Notification / 5 Minutes)=低 (最多 1 條通知 / 每5分鐘) WebSocket Auto Reconnect Interval=WebSocket 自动重連線時間 Aria2 RPC Alias=Aria2 RPC 別名 Aria2 RPC Address=Aria2 RPC 位址 diff --git a/src/scripts/config/constants.js b/src/scripts/config/constants.js index 00c628e7..0d58cef1 100644 --- a/src/scripts/config/constants.js +++ b/src/scripts/config/constants.js @@ -5,6 +5,7 @@ title: 'AriaNg', appPrefix: 'AriaNg', optionStorageKey: 'Options', + browserNotificationHistoryStorageKey: 'Notifications', languageStorageKeyPrefix: 'Language', settingHistoryKeyPrefix: 'History', languagePath: 'langs', @@ -27,6 +28,8 @@ title: '${downspeed}, ${upspeed} - ${title}', titleRefreshInterval: 5000, browserNotification: false, + browserNotificationSound: true, + browserNotificationFrequency: 'unlimited', rpcAlias: '', rpcHost: '', rpcPort: '6800', diff --git a/src/scripts/config/defaultLanguage.js b/src/scripts/config/defaultLanguage.js index d8f3b9c0..94753f37 100644 --- a/src/scripts/config/defaultLanguage.js +++ b/src/scripts/config/defaultLanguage.js @@ -176,6 +176,12 @@ 'Example: ${downspeed:noprefix:nosuffix:scale=1}': 'Example: ${downspeed:noprefix:nosuffix:scale=1}', 'Updating Page Title Interval': 'Updating Page Title Interval', 'Enable Browser Notification': 'Enable Browser Notification', + 'Browser Notification Sound': 'Browser Notification Sound', + 'Browser Notification Frequency': 'Browser Notification Frequency', + 'Unlimited': 'Unlimited', + 'High (Up to 10 Notifications / 1 Minute)': 'High (Up to 10 Notifications / 1 Minute)', + 'Middle (Up to 1 Notification / 1 Minute)': 'Middle (Up to 1 Notification / 1 Minute)', + 'Low (Up to 1 Notification / 5 Minutes)': 'Low (Up to 1 Notification / 5 Minutes)', 'WebSocket Auto Reconnect Interval': 'WebSocket Auto Reconnect Interval', 'Aria2 RPC Alias': 'Aria2 RPC Alias', 'Aria2 RPC Address': 'Aria2 RPC Address', diff --git a/src/scripts/controllers/settings-ariang.js b/src/scripts/controllers/settings-ariang.js index 8b257cba..6aee63cb 100644 --- a/src/scripts/controllers/settings-ariang.js +++ b/src/scripts/controllers/settings-ariang.js @@ -168,6 +168,14 @@ } }; + $scope.setBrowserNotificationSound = function (value) { + ariaNgSettingService.setBrowserNotificationSound(value); + }; + + $scope.setBrowserNotificationFrequency = function (value) { + ariaNgSettingService.setBrowserNotificationFrequency(value); + }; + $scope.setWebSocketReconnectInterval = function (value) { setNeedRefreshPage(); ariaNgSettingService.setWebSocketReconnectInterval(value); diff --git a/src/scripts/services/ariaNgCommonService.js b/src/scripts/services/ariaNgCommonService.js index a7238749..15b3f352 100644 --- a/src/scripts/services/ariaNgCommonService.js +++ b/src/scripts/services/ariaNgCommonService.js @@ -304,6 +304,9 @@ getLongTimeFromUnixTime: function (unixTime) { return moment(unixTime, 'X').format('HH:mm:ss'); }, + isUnixTimeAfter: function (datetime, duration, unit) { + return moment(datetime, 'X').isAfter(moment().add(duration, unit)); + }, formatDateTime: function (datetime, format) { return moment(datetime).format(format); }, diff --git a/src/scripts/services/ariaNgNotificationService.js b/src/scripts/services/ariaNgNotificationService.js index 89eb0ed7..cd73da45 100644 --- a/src/scripts/services/ariaNgNotificationService.js +++ b/src/scripts/services/ariaNgNotificationService.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - angular.module('ariaNg').factory('ariaNgNotificationService', ['$window', 'Notification', 'ariaNgLocalizationService', 'ariaNgSettingService', function ($window, Notification, ariaNgLocalizationService, ariaNgSettingService) { + angular.module('ariaNg').factory('ariaNgNotificationService', ['$window', 'Notification', 'ariaNgConstants', 'ariaNgCommonService', 'ariaNgStorageService', 'ariaNgLocalizationService', 'ariaNgLogService', 'ariaNgSettingService', function ($window, Notification, ariaNgConstants, ariaNgCommonService, ariaNgStorageService, ariaNgLocalizationService, ariaNgLogService, ariaNgSettingService) { var isSupportBrowserNotification = !!$window.Notification; var isBrowserNotifactionGranted = function (permission) { @@ -31,6 +31,69 @@ }); }; + var isReachBrowserNotificationFrequencyLimit = function () { + if (!ariaNgSettingService.getBrowserNotificationFrequency() || ariaNgSettingService.getBrowserNotificationFrequency() === 'unlimited') { + return false; + } + + var lastNotifications = ariaNgStorageService.get(ariaNgConstants.browserNotificationHistoryStorageKey) || []; + + if (!angular.isArray(lastNotifications)) { + return false; + } + + if (lastNotifications.length < 1) { + return false; + } + + var oldestTime = null; + var isReachLimit = false; + + if (ariaNgSettingService.getBrowserNotificationFrequency() === 'high') { + if (lastNotifications.length < 10) { + return false; + } + + oldestTime = lastNotifications[lastNotifications.length - 10].time; + isReachLimit = ariaNgCommonService.isUnixTimeAfter(oldestTime, '-1', 'minute'); + } else if (ariaNgSettingService.getBrowserNotificationFrequency() === 'middle') { + oldestTime = lastNotifications[lastNotifications.length - 1].time; + isReachLimit = ariaNgCommonService.isUnixTimeAfter(oldestTime, '-1', 'minute'); + } else if (ariaNgSettingService.getBrowserNotificationFrequency() === 'low') { + oldestTime = lastNotifications[lastNotifications.length - 1].time; + isReachLimit = ariaNgCommonService.isUnixTimeAfter(oldestTime, '-5', 'minute'); + } + + if (isReachLimit) { + ariaNgLogService.debug('[ariaNgNotificationService.isReachBrowserNotificationFrequencyLimit] reach frequency limit' + + (oldestTime ? ', the oldest time is ' + oldestTime : '')); + } + + return isReachLimit; + }; + + var recordBrowserNotificationHistory = function () { + if (!ariaNgSettingService.getBrowserNotificationFrequency() || ariaNgSettingService.getBrowserNotificationFrequency() === 'unlimited') { + return; + } + + var lastNotifications = ariaNgStorageService.get(ariaNgConstants.browserNotificationHistoryStorageKey) || []; + + if (!angular.isArray(lastNotifications)) { + lastNotifications = []; + } + + lastNotifications.push({ + time: ariaNgCommonService.getCurrentUnixTime() + }); + + if (lastNotifications.length > 10) { + lastNotifications.splice(0, lastNotifications.length - 10); + } + + ariaNgStorageService.set(ariaNgConstants.browserNotificationHistoryStorageKey, lastNotifications); + }; + var showBrowserNotifaction = function (title, options) { if (!$window.Notification) { return; @@ -40,10 +103,16 @@ return; } + if (isReachBrowserNotificationFrequencyLimit()) { + return; + } + options = angular.extend({ icon: 'tileicon.png' }, options); + recordBrowserNotificationHistory(); + new $window.Notification(title, options); }; @@ -54,6 +123,10 @@ options.body = content; + if (!ariaNgSettingService.getBrowserNotificationSound()) { + options.silent = true; + } + if (isSupportBrowserNotification && ariaNgSettingService.getBrowserNotification()) { showBrowserNotifaction(title, options); } diff --git a/src/scripts/services/ariaNgSettingService.js b/src/scripts/services/ariaNgSettingService.js index 26681c21..bf45d997 100644 --- a/src/scripts/services/ariaNgSettingService.js +++ b/src/scripts/services/ariaNgSettingService.js @@ -365,6 +365,18 @@ setBrowserNotification: function (value) { setOption('browserNotification', value); }, + getBrowserNotificationSound: function () { + return getOption('browserNotificationSound'); + }, + setBrowserNotificationSound: function (value) { + setOption('browserNotificationSound', value); + }, + getBrowserNotificationFrequency: function () { + return getOption('browserNotificationFrequency'); + }, + setBrowserNotificationFrequency: function (value) { + setOption('browserNotificationFrequency', value); + }, getWebSocketReconnectInterval: function () { return getOption('webSocketReconnectInterval'); }, diff --git a/src/views/settings-ariang.html b/src/views/settings-ariang.html index 0bcc3532..def00d38 100644 --- a/src/views/settings-ariang.html +++ b/src/views/settings-ariang.html @@ -95,6 +95,32 @@ +
+
+ Browser Notification Sound +
+
+ +
+
+
+
+ Browser Notification Frequency +
+
+ +
+
WebSocket Auto Reconnect Interval