Skip to content

Commit

Permalink
support set browser notification sound / frequency
Browse files Browse the repository at this point in the history
  • Loading branch information
mayswind committed Nov 6, 2022
1 parent 32adc3f commit 72dc516
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/langs/zh_Hans.txt
Expand Up @@ -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 地址
Expand Down
6 changes: 6 additions & 0 deletions src/langs/zh_Hant.txt
Expand Up @@ -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 位址
Expand Down
3 changes: 3 additions & 0 deletions src/scripts/config/constants.js
Expand Up @@ -5,6 +5,7 @@
title: 'AriaNg',
appPrefix: 'AriaNg',
optionStorageKey: 'Options',
browserNotificationHistoryStorageKey: 'Notifications',
languageStorageKeyPrefix: 'Language',
settingHistoryKeyPrefix: 'History',
languagePath: 'langs',
Expand All @@ -27,6 +28,8 @@
title: '${downspeed}, ${upspeed} - ${title}',
titleRefreshInterval: 5000,
browserNotification: false,
browserNotificationSound: true,
browserNotificationFrequency: 'unlimited',
rpcAlias: '',
rpcHost: '',
rpcPort: '6800',
Expand Down
6 changes: 6 additions & 0 deletions src/scripts/config/defaultLanguage.js
Expand Up @@ -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',
Expand Down
8 changes: 8 additions & 0 deletions src/scripts/controllers/settings-ariang.js
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/scripts/services/ariaNgCommonService.js
Expand Up @@ -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);
},
Expand Down
75 changes: 74 additions & 1 deletion 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) {
Expand Down Expand Up @@ -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;
Expand All @@ -40,10 +103,16 @@
return;
}

if (isReachBrowserNotificationFrequencyLimit()) {
return;
}

options = angular.extend({
icon: 'tileicon.png'
}, options);

recordBrowserNotificationHistory();

new $window.Notification(title, options);
};

Expand All @@ -54,6 +123,10 @@

options.body = content;

if (!ariaNgSettingService.getBrowserNotificationSound()) {
options.silent = true;
}

if (isSupportBrowserNotification && ariaNgSettingService.getBrowserNotification()) {
showBrowserNotifaction(title, options);
}
Expand Down
12 changes: 12 additions & 0 deletions src/scripts/services/ariaNgSettingService.js
Expand Up @@ -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');
},
Expand Down
26 changes: 26 additions & 0 deletions src/views/settings-ariang.html
Expand Up @@ -95,6 +95,32 @@
</select>
</div>
</div>
<div class="row" ng-if="isSupportNotification() && context.settings.browserNotification">
<div class="setting-key setting-key-without-desc col-sm-4">
<span translate>Browser Notification Sound</span>
</div>
<div class="setting-value col-sm-8">
<select class="form-control" style="width: 100%;"
ng-model="context.settings.browserNotificationSound"
ng-change="setBrowserNotificationSound(context.settings.browserNotificationSound)"
ng-options="option.value as (option.name | translate) for option in context.trueFalseOptions">
</select>
</div>
</div>
<div class="row" ng-if="isSupportNotification() && context.settings.browserNotification">
<div class="setting-key setting-key-without-desc col-sm-4">
<span translate>Browser Notification Frequency</span>
</div>
<div class="setting-value col-sm-8">
<select class="form-control" style="width: 100%;" ng-model="context.settings.browserNotificationFrequency"
ng-change="setBrowserNotificationFrequency(context.settings.browserNotificationFrequency)">
<option value="unlimited" translate>Unlimited</option>
<option value="high" translate>High (Up to 10 Notifications / 1 Minute)</option>
<option value="middle" translate>Middle (Up to 1 Notification / 1 Minute)</option>
<option value="low" translate>Low (Up to 1 Notification / 5 Minutes)</option>
</select>
</div>
</div>
<div class="row" ng-if="context.isSupportReconnect">
<div class="setting-key setting-key-without-desc col-sm-4">
<span translate>WebSocket Auto Reconnect Interval</span>
Expand Down

0 comments on commit 72dc516

Please sign in to comment.