dsh-update-plugin 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -4
- package/README.md +11 -2
- package/README.zh-CN.md +9 -2
- package/assets/screenshots/plugin-cn.png +0 -0
- package/assets/screenshots/plugin-en.png +0 -0
- package/assets/screenshots/sidebar-cn.png +0 -0
- package/assets/screenshots/sidebar-en.png +0 -0
- package/lib/client.js +244 -26
- package/lib/update-core.js +7 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,15 +6,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.0] - 2026-09-16
|
|
10
|
+
|
|
11
|
+
Published to npm as `dsh-update-plugin@0.3.0`. This is the first release that
|
|
12
|
+
actually ships the automatic-check and browser-notification work listed under
|
|
13
|
+
`0.2.0` below — `0.2.0` itself was never published.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Automatic update checks: on startup, hourly, daily or off, persisted in the
|
|
18
|
+
plugin config and restarted when the setting is saved.
|
|
19
|
+
- Browser notification when a real update is available: sent once per target
|
|
20
|
+
version, with a notification-permission row and an enable button in the
|
|
21
|
+
settings page.
|
|
22
|
+
- The **Send test reminder / 测试更新提醒** button now requests notification
|
|
23
|
+
permission and uses its own test copy, so it can be told apart from real
|
|
24
|
+
notifications.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Screenshot references in `README.md` and `README.zh-CN.md`: three links pointed
|
|
29
|
+
at files that do not exist. They now use the current captures, and the
|
|
30
|
+
duplicate `plugin-zh.png` (byte-identical to `plugin-cn.png`) is gone.
|
|
31
|
+
|
|
32
|
+
## [0.2.0] - 2026-09-13
|
|
33
|
+
|
|
34
|
+
Not published to npm; its changes shipped in `0.3.0`.
|
|
35
|
+
|
|
9
36
|
### Added
|
|
10
37
|
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
38
|
+
- Automatic update checks: on startup, hourly, daily or off, persisted in the
|
|
39
|
+
plugin config and restarted when the setting is saved.
|
|
40
|
+
- Browser notification when a real update is available: sent once per target
|
|
41
|
+
version, with a notification-permission row and an enable button in the
|
|
42
|
+
settings page.
|
|
43
|
+
- The **Send test reminder / 测试更新提醒** button now requests notification
|
|
44
|
+
permission and uses its own test copy, so it can be told apart from real
|
|
45
|
+
notifications.
|
|
15
46
|
|
|
16
47
|
## [0.1.0] - 2026-09-12
|
|
17
48
|
|
|
49
|
+
Published to npm as `dsh-update-plugin@0.1.0`.
|
|
50
|
+
|
|
18
51
|
### Added
|
|
19
52
|
|
|
20
53
|
- **Settings → General** row titled **Check for Updates... / 检查更新**, registered
|
package/README.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-update-plugin)
|
|
6
|
+
[](https://github.com/topics/dsh-plugin)
|
|
7
|
+
|
|
5
8
|
A DSH Web plugin that adds **Check for Updates...** (「检查更新」in Chinese) to
|
|
6
9
|
**Settings → General**, right next to Permission, Language, Appearance and Font
|
|
7
10
|
Size.
|
|
@@ -15,14 +18,16 @@ The update logic is built into the plugin. It does **not** require Homebrew or a
|
|
|
15
18
|
separately installed `dsh-update-all` script.
|
|
16
19
|
|
|
17
20
|

|
|
21
|
+

|
|
22
|
+

|
|
18
23
|
|
|
19
24
|
## Install
|
|
20
25
|
|
|
21
26
|
```bash
|
|
22
|
-
# from npm
|
|
27
|
+
# from npm
|
|
23
28
|
dsh plugin --profile web add dsh-update-plugin
|
|
24
29
|
|
|
25
|
-
# from a local checkout
|
|
30
|
+
# from a local checkout (development)
|
|
26
31
|
dsh plugin --profile web add /path/to/dsh-update-all/plugin
|
|
27
32
|
```
|
|
28
33
|
|
|
@@ -55,6 +60,10 @@ Then restart DSH Web, open **Settings → General**, and look for the
|
|
|
55
60
|
sends a browser notification (permission required), and shows the update badge
|
|
56
61
|
for 10 seconds so you can verify the reminder without a real release.
|
|
57
62
|
- The row shows the current and newest versions plus the number of profiles.
|
|
63
|
+
- **Automatic update checks** can run on startup, hourly or daily, or be turned
|
|
64
|
+
off; pick the interval in the settings page.
|
|
65
|
+
- When a real update is available and browser notifications are allowed, the
|
|
66
|
+
plugin sends a notification once per new version.
|
|
58
67
|
- **Check for updates** refreshes the status (it also refreshes after
|
|
59
68
|
reconnecting).
|
|
60
69
|
- **Update now** updates the CLI and then every profile with dependencies.
|
package/README.zh-CN.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/dsh-update-plugin)
|
|
6
|
+
[](https://github.com/topics/dsh-plugin)
|
|
7
|
+
|
|
5
8
|
一个 DSH Web 插件,在 **设置 → 通用设置** 里加入一行「检查更新」,和权限、语言、
|
|
6
9
|
外观、字号大小同级。
|
|
7
10
|
|
|
@@ -14,14 +17,16 @@
|
|
|
14
17
|
`dsh-update-all` 脚本**。
|
|
15
18
|
|
|
16
19
|

|
|
20
|
+

|
|
21
|
+

|
|
17
22
|
|
|
18
23
|
## 安装
|
|
19
24
|
|
|
20
25
|
```bash
|
|
21
|
-
# 从 npm
|
|
26
|
+
# 从 npm 安装
|
|
22
27
|
dsh plugin --profile web add dsh-update-plugin
|
|
23
28
|
|
|
24
|
-
#
|
|
29
|
+
# 本地开发 / 从本仓库安装
|
|
25
30
|
dsh plugin --profile web add /path/to/dsh-update-all/plugin
|
|
26
31
|
```
|
|
27
32
|
|
|
@@ -49,6 +54,8 @@ dsh plugin --profile web add /path/to/dsh-update-all/plugin --config.minimum-rel
|
|
|
49
54
|
- 状态卡片里有 **测试更新提醒** 按钮:会打开侧边栏 tab、发送浏览器通知
|
|
50
55
|
(需要授权),并显示 10 秒的更新角标,方便验证提醒效果,不用等真实新版本。
|
|
51
56
|
- 行内显示当前版本、最新版本和 profile 数量。
|
|
57
|
+
- **自动检查**支持启动时 / 每小时 / 每天,也可以关闭;在设置页选择即可。
|
|
58
|
+
- 发现真实新版本且浏览器通知已授权时,每个新版本只通知一次。
|
|
52
59
|
- **检查更新**:刷新状态。
|
|
53
60
|
- **立即更新**:先更新 CLI,再更新每个有依赖的 profile;更新前会自动把
|
|
54
61
|
`package.json` / `pnpm-lock.yaml` 备份到 `~/.dsh/update-backups/`。
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/client.js
CHANGED
|
@@ -112,8 +112,23 @@ window.__ModuleLoader__.load({
|
|
|
112
112
|
testStop: "停止测试",
|
|
113
113
|
testReminder: "测试提醒:发现可用更新(仅测试,不会真的更新)",
|
|
114
114
|
testReminderMeta: "仅用于验证角标和提醒效果",
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
testNotificationTitle: "DSH 有可用更新",
|
|
116
|
+
testNotificationBody: "测试提醒:仅用于验证浏览器通知和角标(不会真的更新)",
|
|
117
|
+
updateNotificationTitle: "DSH 有可用更新",
|
|
118
|
+
updateNotificationBody: "最新版本 {version}。打开 设置 → 通用设置 查看。",
|
|
119
|
+
notifications: "浏览器通知",
|
|
120
|
+
notificationHint: "有新版本时发送浏览器通知",
|
|
121
|
+
notificationGranted: "已允许",
|
|
122
|
+
notificationDefault: "未授权",
|
|
123
|
+
notificationDenied: "已拒绝",
|
|
124
|
+
notificationUnsupported: "当前环境不支持",
|
|
125
|
+
enableNotifications: "启用通知",
|
|
126
|
+
checkInterval: "自动检查",
|
|
127
|
+
checkIntervalHint: "启动时 / 每小时 / 每天,或关闭",
|
|
128
|
+
intervalStartup: "启动时",
|
|
129
|
+
intervalHourly: "每小时",
|
|
130
|
+
intervalDaily: "每天",
|
|
131
|
+
intervalOff: "关闭",
|
|
117
132
|
};
|
|
118
133
|
|
|
119
134
|
var EN = {
|
|
@@ -171,8 +186,23 @@ window.__ModuleLoader__.load({
|
|
|
171
186
|
testStop: "Stop test",
|
|
172
187
|
testReminder: "Test reminder: update available (test only, nothing is updated)",
|
|
173
188
|
testReminderMeta: "Only used to verify the badge and reminder UI",
|
|
174
|
-
|
|
175
|
-
|
|
189
|
+
testNotificationTitle: "DSH update available",
|
|
190
|
+
testNotificationBody: "Test reminder: only verifying the browser notification and badge (nothing is updated)",
|
|
191
|
+
updateNotificationTitle: "DSH update available",
|
|
192
|
+
updateNotificationBody: "Version {version} is available. Open Settings → General to review.",
|
|
193
|
+
notifications: "Browser notifications",
|
|
194
|
+
notificationHint: "Notify me when a new version is available",
|
|
195
|
+
notificationGranted: "Allowed",
|
|
196
|
+
notificationDefault: "Not allowed yet",
|
|
197
|
+
notificationDenied: "Denied",
|
|
198
|
+
notificationUnsupported: "Not supported in this environment",
|
|
199
|
+
enableNotifications: "Enable notifications",
|
|
200
|
+
checkInterval: "Automatic check",
|
|
201
|
+
checkIntervalHint: "On startup / hourly / daily, or off",
|
|
202
|
+
intervalStartup: "On startup",
|
|
203
|
+
intervalHourly: "Hourly",
|
|
204
|
+
intervalDaily: "Daily",
|
|
205
|
+
intervalOff: "Off",
|
|
176
206
|
};
|
|
177
207
|
|
|
178
208
|
function injectStyle() {
|
|
@@ -233,24 +263,59 @@ window.__ModuleLoader__.load({
|
|
|
233
263
|
}).then(parseJson);
|
|
234
264
|
}
|
|
235
265
|
|
|
236
|
-
function
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
266
|
+
function notificationsSupported() {
|
|
267
|
+
return typeof Notification !== "undefined";
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function notificationPermission() {
|
|
271
|
+
if (notificationsSupported()) return Notification.permission;
|
|
272
|
+
return "unsupported";
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function requestNotificationPermission() {
|
|
276
|
+
if (notificationsSupported()) {
|
|
277
|
+
return Notification.requestPermission().catch(function () {
|
|
278
|
+
return notificationPermission();
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
return Promise.resolve("unsupported");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function sendBrowserNotification(title, body) {
|
|
285
|
+
if (notificationsSupported()) {
|
|
286
|
+
try {
|
|
287
|
+
if (Notification.permission === "granted") {
|
|
288
|
+
var notice = new Notification(title, { body: body, tag: "dsh-update-plugin" });
|
|
289
|
+
notice.onclick = function () {
|
|
290
|
+
try {
|
|
291
|
+
window.focus();
|
|
292
|
+
} catch (error) {}
|
|
293
|
+
};
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {}
|
|
297
|
+
}
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function useNotificationPermission() {
|
|
302
|
+
var pair = React.useState(notificationPermission());
|
|
303
|
+
var permission = pair[0];
|
|
304
|
+
var setPermission = pair[1];
|
|
305
|
+
var request = React.useCallback(function () {
|
|
306
|
+
return requestNotificationPermission().then(function (next) {
|
|
307
|
+
setPermission(next);
|
|
308
|
+
return next;
|
|
309
|
+
});
|
|
310
|
+
}, [setPermission]);
|
|
311
|
+
return { permission: permission, request: request };
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function notificationStatusText(t, permission) {
|
|
315
|
+
if (permission === "granted") return t("notificationGranted");
|
|
316
|
+
if (permission === "denied") return t("notificationDenied");
|
|
317
|
+
if (permission === "unsupported") return t("notificationUnsupported");
|
|
318
|
+
return t("notificationDefault");
|
|
254
319
|
}
|
|
255
320
|
|
|
256
321
|
function manualCommands(profileName) {
|
|
@@ -343,6 +408,69 @@ window.__ModuleLoader__.load({
|
|
|
343
408
|
return Object.assign({}, data || {}, { updateAvailable: true, testReminder: true });
|
|
344
409
|
}
|
|
345
410
|
|
|
411
|
+
var NOTIFIED_KEY = "dsh-update-plugin:notified-version";
|
|
412
|
+
var autoCheckTimer = null;
|
|
413
|
+
|
|
414
|
+
function readNotifiedVersion() {
|
|
415
|
+
if (typeof window === "undefined" || typeof window.localStorage === "undefined") return null;
|
|
416
|
+
try {
|
|
417
|
+
return window.localStorage.getItem(NOTIFIED_KEY);
|
|
418
|
+
} catch (error) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function writeNotifiedVersion(version) {
|
|
424
|
+
if (typeof window === "undefined" || typeof window.localStorage === "undefined") return;
|
|
425
|
+
try {
|
|
426
|
+
window.localStorage.setItem(NOTIFIED_KEY, version);
|
|
427
|
+
} catch (error) {}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function stopAutoCheck() {
|
|
431
|
+
if (autoCheckTimer) {
|
|
432
|
+
clearInterval(autoCheckTimer);
|
|
433
|
+
autoCheckTimer = null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function autoCheckDelay(config) {
|
|
438
|
+
if (config && config.checkInterval === "hourly") return 60 * 60 * 1000;
|
|
439
|
+
if (config && config.checkInterval === "daily") return 24 * 60 * 60 * 1000;
|
|
440
|
+
return 0;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function checkUpdatesAndNotify(t) {
|
|
444
|
+
if (testReminder.active) return;
|
|
445
|
+
getStatus(true)
|
|
446
|
+
.then(function (data) {
|
|
447
|
+
if (data && data.updateAvailable && data.targetVersion) {
|
|
448
|
+
if (testReminder.active) return;
|
|
449
|
+
var last = readNotifiedVersion();
|
|
450
|
+
if (last === data.targetVersion) return;
|
|
451
|
+
var sent = sendBrowserNotification(
|
|
452
|
+
t("updateNotificationTitle"),
|
|
453
|
+
t("updateNotificationBody", { version: data.targetVersion }),
|
|
454
|
+
);
|
|
455
|
+
if (sent) writeNotifiedVersion(data.targetVersion);
|
|
456
|
+
}
|
|
457
|
+
})
|
|
458
|
+
.catch(function () {});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function startAutoCheck(config, t) {
|
|
462
|
+
stopAutoCheck();
|
|
463
|
+
var current = config || {};
|
|
464
|
+
if (current.checkInterval === "off") return;
|
|
465
|
+
checkUpdatesAndNotify(t);
|
|
466
|
+
var delay = autoCheckDelay(current);
|
|
467
|
+
if (delay > 0) {
|
|
468
|
+
autoCheckTimer = setInterval(function () {
|
|
469
|
+
checkUpdatesAndNotify(t);
|
|
470
|
+
}, delay);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
346
474
|
function useUpdater(t) {
|
|
347
475
|
var pair = React.useState({ loading: true, data: null, error: null });
|
|
348
476
|
var state = pair[0];
|
|
@@ -578,7 +706,8 @@ window.__ModuleLoader__.load({
|
|
|
578
706
|
var test = useTestReminder();
|
|
579
707
|
var configState = useConfig(t);
|
|
580
708
|
var backupsState = useBackups(t);
|
|
581
|
-
var
|
|
709
|
+
var notification = useNotificationPermission();
|
|
710
|
+
var draftPair = React.useState({ channel: "auto", minAge: 0, checkInterval: "startup" });
|
|
582
711
|
var draft = draftPair[0];
|
|
583
712
|
var setDraft = draftPair[1];
|
|
584
713
|
|
|
@@ -588,6 +717,7 @@ window.__ModuleLoader__.load({
|
|
|
588
717
|
setDraft({
|
|
589
718
|
channel: configState.state.config.channel || "auto",
|
|
590
719
|
minAge: Number.isInteger(configState.state.config.minAge) ? configState.state.config.minAge : 0,
|
|
720
|
+
checkInterval: configState.state.config.checkInterval || "startup",
|
|
591
721
|
});
|
|
592
722
|
}
|
|
593
723
|
},
|
|
@@ -612,6 +742,9 @@ window.__ModuleLoader__.load({
|
|
|
612
742
|
configState.save({
|
|
613
743
|
channel: draft.channel,
|
|
614
744
|
minAge: Number(draft.minAge) || 0,
|
|
745
|
+
checkInterval: draft.checkInterval || "startup",
|
|
746
|
+
}).then(function (next) {
|
|
747
|
+
if (next) startAutoCheck(next, t);
|
|
615
748
|
});
|
|
616
749
|
}
|
|
617
750
|
|
|
@@ -681,7 +814,11 @@ window.__ModuleLoader__.load({
|
|
|
681
814
|
return;
|
|
682
815
|
}
|
|
683
816
|
if (typeof props.openSidebar === "function") props.openSidebar();
|
|
684
|
-
|
|
817
|
+
requestNotificationPermission().then(function (permission) {
|
|
818
|
+
if (permission === "granted") {
|
|
819
|
+
sendBrowserNotification(t("testNotificationTitle"), t("testNotificationBody"));
|
|
820
|
+
}
|
|
821
|
+
});
|
|
685
822
|
setTestReminder(true, 10000);
|
|
686
823
|
},
|
|
687
824
|
},
|
|
@@ -727,7 +864,7 @@ window.__ModuleLoader__.load({
|
|
|
727
864
|
className: "dsu-select",
|
|
728
865
|
value: draft.channel,
|
|
729
866
|
onChange: function (event) {
|
|
730
|
-
setDraft({ channel: event.target.value, minAge: draft.minAge });
|
|
867
|
+
setDraft({ channel: event.target.value, minAge: draft.minAge, checkInterval: draft.checkInterval });
|
|
731
868
|
},
|
|
732
869
|
},
|
|
733
870
|
[
|
|
@@ -756,13 +893,67 @@ window.__ModuleLoader__.load({
|
|
|
756
893
|
step: 60,
|
|
757
894
|
value: draft.minAge,
|
|
758
895
|
onChange: function (event) {
|
|
759
|
-
setDraft({ channel: draft.channel, minAge: Math.max(0, Number(event.target.value) || 0) });
|
|
896
|
+
setDraft({ channel: draft.channel, minAge: Math.max(0, Number(event.target.value) || 0), checkInterval: draft.checkInterval });
|
|
760
897
|
},
|
|
761
898
|
}),
|
|
762
899
|
h("span", { className: "dsu-desc", key: "unit" }, t("minAgeUnit")),
|
|
763
900
|
]),
|
|
764
901
|
],
|
|
765
902
|
),
|
|
903
|
+
h(
|
|
904
|
+
"div",
|
|
905
|
+
{ className: "dsu-field", key: "check-interval" },
|
|
906
|
+
[
|
|
907
|
+
h("div", { className: "dsu-field-label", key: "label" }, [
|
|
908
|
+
h("div", { className: "dsu-title", key: "t" }, t("checkInterval")),
|
|
909
|
+
h("div", { className: "dsu-desc", key: "d" }, t("checkIntervalHint")),
|
|
910
|
+
]),
|
|
911
|
+
h(
|
|
912
|
+
"select",
|
|
913
|
+
{
|
|
914
|
+
key: "select",
|
|
915
|
+
className: "dsu-select",
|
|
916
|
+
value: draft.checkInterval,
|
|
917
|
+
onChange: function (event) {
|
|
918
|
+
setDraft({ channel: draft.channel, minAge: draft.minAge, checkInterval: event.target.value });
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
[
|
|
922
|
+
h("option", { key: "startup", value: "startup" }, t("intervalStartup")),
|
|
923
|
+
h("option", { key: "hourly", value: "hourly" }, t("intervalHourly")),
|
|
924
|
+
h("option", { key: "daily", value: "daily" }, t("intervalDaily")),
|
|
925
|
+
h("option", { key: "off", value: "off" }, t("intervalOff")),
|
|
926
|
+
],
|
|
927
|
+
),
|
|
928
|
+
],
|
|
929
|
+
),
|
|
930
|
+
h(
|
|
931
|
+
"div",
|
|
932
|
+
{ className: "dsu-field", key: "notifications" },
|
|
933
|
+
[
|
|
934
|
+
h("div", { className: "dsu-field-label", key: "label" }, [
|
|
935
|
+
h("div", { className: "dsu-title", key: "t" }, t("notifications")),
|
|
936
|
+
h("div", { className: "dsu-desc", key: "d" }, t("notificationHint")),
|
|
937
|
+
]),
|
|
938
|
+
h("div", { className: "dsu-control", key: "control" }, [
|
|
939
|
+
h("span", { className: "dsu-desc", key: "status" }, notificationStatusText(t, notification.permission)),
|
|
940
|
+
notification.permission === "granted" || notification.permission === "unsupported"
|
|
941
|
+
? null
|
|
942
|
+
: h(
|
|
943
|
+
"button",
|
|
944
|
+
{
|
|
945
|
+
key: "enable",
|
|
946
|
+
type: "button",
|
|
947
|
+
className: "dsu-btn",
|
|
948
|
+
onClick: function () {
|
|
949
|
+
notification.request();
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
t("enableNotifications"),
|
|
953
|
+
),
|
|
954
|
+
]),
|
|
955
|
+
],
|
|
956
|
+
),
|
|
766
957
|
h(
|
|
767
958
|
"div",
|
|
768
959
|
{ className: "dsu-control", key: "actions" },
|
|
@@ -963,6 +1154,33 @@ window.__ModuleLoader__.load({
|
|
|
963
1154
|
"dsh-update-plugin: dictionaries",
|
|
964
1155
|
);
|
|
965
1156
|
|
|
1157
|
+
var autoCheckDisposed = false;
|
|
1158
|
+
ctx.effect(
|
|
1159
|
+
function () {
|
|
1160
|
+
var translate = function (key, params) {
|
|
1161
|
+
return ctx.locale.bind(NS)(key, params);
|
|
1162
|
+
};
|
|
1163
|
+
getConfig()
|
|
1164
|
+
.then(function (config) {
|
|
1165
|
+
if (autoCheckDisposed) return;
|
|
1166
|
+
if (config && config.checkInterval) {
|
|
1167
|
+
startAutoCheck(config, translate);
|
|
1168
|
+
} else {
|
|
1169
|
+
startAutoCheck({ checkInterval: "startup" }, translate);
|
|
1170
|
+
}
|
|
1171
|
+
})
|
|
1172
|
+
.catch(function () {
|
|
1173
|
+
if (autoCheckDisposed) return;
|
|
1174
|
+
startAutoCheck({ checkInterval: "startup" }, translate);
|
|
1175
|
+
});
|
|
1176
|
+
return function () {
|
|
1177
|
+
autoCheckDisposed = true;
|
|
1178
|
+
stopAutoCheck();
|
|
1179
|
+
};
|
|
1180
|
+
},
|
|
1181
|
+
"dsh-update-plugin: automatic update check",
|
|
1182
|
+
);
|
|
1183
|
+
|
|
966
1184
|
var sidebarRight = null;
|
|
967
1185
|
ctx.inject(["sidebarRightTabs", "sidebarRight"], function (sideCtx) {
|
|
968
1186
|
sidebarRight = sideCtx.sidebarRight;
|
package/lib/update-core.js
CHANGED
|
@@ -20,8 +20,9 @@ export const CLI_TIMEOUT_MS = 10 * 60 * 1000;
|
|
|
20
20
|
export const PROFILE_TIMEOUT_MS = 5 * 60 * 1000;
|
|
21
21
|
|
|
22
22
|
export const CONFIG_FILENAME = "dsh-update-plugin.json";
|
|
23
|
-
export const DEFAULT_CONFIG = { channel: "auto", minAge: 0 };
|
|
23
|
+
export const DEFAULT_CONFIG = { channel: "auto", minAge: 0, checkInterval: "startup" };
|
|
24
24
|
const CHANNELS = new Set(["auto", "stable", "next", "alpha"]);
|
|
25
|
+
const CHECK_INTERVALS = new Set(["startup", "hourly", "daily", "off"]);
|
|
25
26
|
|
|
26
27
|
export function normalizeConfig(raw) {
|
|
27
28
|
const source = raw && typeof raw === "object" ? raw : {};
|
|
@@ -29,6 +30,11 @@ export function normalizeConfig(raw) {
|
|
|
29
30
|
if (!CHANNELS.has(config.channel)) config.channel = DEFAULT_CONFIG.channel;
|
|
30
31
|
const minAge = Number(config.minAge);
|
|
31
32
|
config.minAge = Number.isInteger(minAge) && minAge >= 0 ? minAge : DEFAULT_CONFIG.minAge;
|
|
33
|
+
if (CHECK_INTERVALS.has(config.checkInterval)) {
|
|
34
|
+
// keep
|
|
35
|
+
} else {
|
|
36
|
+
config.checkInterval = DEFAULT_CONFIG.checkInterval;
|
|
37
|
+
}
|
|
32
38
|
return config;
|
|
33
39
|
}
|
|
34
40
|
|