tabminal 3.0.6 → 3.0.7
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/package.json +1 -1
- package/public/app.js +4 -1
- package/public/index.html +1 -1
- package/public/modules/notifications.js +59 -0
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -4994,7 +4994,10 @@ class Session {
|
|
|
4994
4994
|
this.runningExecutionId = '';
|
|
4995
4995
|
this.runningCommand = '';
|
|
4996
4996
|
|
|
4997
|
-
if (
|
|
4997
|
+
if (
|
|
4998
|
+
state.activeSessionKey !== this.key
|
|
4999
|
+
&& !isAgentManagedSession(this)
|
|
5000
|
+
) {
|
|
4998
5001
|
this.needsAttention = true;
|
|
4999
5002
|
if (this.lastNotifiedExecutionId !== executionId) {
|
|
5000
5003
|
this.lastNotifiedExecutionId = executionId;
|
package/public/index.html
CHANGED
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
previousCompactWorkspaceMode
|
|
86
86
|
);
|
|
87
87
|
const compactTerminalTabsMode =
|
|
88
|
-
width
|
|
88
|
+
width < COMPACT_TERMINAL_TAB_MAX_WIDTH;
|
|
89
89
|
window.__tabminalCompactWorkspaceMode = compactWorkspaceMode;
|
|
90
90
|
window.__tabminalCompactTerminalTabsMode =
|
|
91
91
|
compactTerminalTabsMode;
|
|
@@ -6,6 +6,62 @@ export class NotificationManager {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
// BEGIN temporary iOS web-app notification dedupe workaround
|
|
10
|
+
static RECENT_NOTIFICATION_KEY = 'tabminal_recent_notifications';
|
|
11
|
+
|
|
12
|
+
static RECENT_NOTIFICATION_LIMIT = 10;
|
|
13
|
+
|
|
14
|
+
static RECENT_NOTIFICATION_TTL_MS = 30_000;
|
|
15
|
+
|
|
16
|
+
_loadRecentNotifications() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = localStorage.getItem(
|
|
19
|
+
NotificationManager.RECENT_NOTIFICATION_KEY
|
|
20
|
+
);
|
|
21
|
+
if (!raw) return [];
|
|
22
|
+
const parsed = JSON.parse(raw);
|
|
23
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
24
|
+
} catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
_storeRecentNotifications(entries) {
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem(
|
|
32
|
+
NotificationManager.RECENT_NOTIFICATION_KEY,
|
|
33
|
+
JSON.stringify(entries)
|
|
34
|
+
);
|
|
35
|
+
} catch {
|
|
36
|
+
// Ignore localStorage failures.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_shouldSuppressRecentNotification(title, body) {
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
const fingerprint = `${title}\n${body}`;
|
|
43
|
+
const recent = this._loadRecentNotifications().filter((entry) => (
|
|
44
|
+
entry
|
|
45
|
+
&& typeof entry.fingerprint === 'string'
|
|
46
|
+
&& Number.isFinite(entry.at)
|
|
47
|
+
&& (now - entry.at) < NotificationManager.RECENT_NOTIFICATION_TTL_MS
|
|
48
|
+
));
|
|
49
|
+
|
|
50
|
+
if (recent.some((entry) => entry.fingerprint === fingerprint)) {
|
|
51
|
+
this._storeRecentNotifications(
|
|
52
|
+
recent.slice(-NotificationManager.RECENT_NOTIFICATION_LIMIT)
|
|
53
|
+
);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
recent.push({ fingerprint, at: now });
|
|
58
|
+
this._storeRecentNotifications(
|
|
59
|
+
recent.slice(-NotificationManager.RECENT_NOTIFICATION_LIMIT)
|
|
60
|
+
);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// END temporary iOS web-app notification dedupe workaround
|
|
64
|
+
|
|
9
65
|
requestPermission() {
|
|
10
66
|
if (!('Notification' in window)) return;
|
|
11
67
|
if (Notification.permission !== 'granted' && Notification.permission !== 'denied') {
|
|
@@ -20,6 +76,9 @@ export class NotificationManager {
|
|
|
20
76
|
|
|
21
77
|
// Check permission status directly
|
|
22
78
|
if (Notification.permission === 'granted') {
|
|
79
|
+
if (this._shouldSuppressRecentNotification(title, body)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
23
82
|
try {
|
|
24
83
|
new Notification(title, {
|
|
25
84
|
body: body,
|