overmux 0.0.10 → 0.0.11
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 +10 -0
- package/dist/bin.js.map +1 -1
- package/dist/docs/400-reference/200-configuration.md +35 -0
- package/dist/docs/400-reference/500-server/400-notifications.md +4 -0
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +49 -7
- package/dist/exports/client.js.map +1 -1
- package/dist/internal/server/coordinator/server-child.js +25 -1
- package/dist/internal/server/coordinator/server-child.js.map +1 -1
- package/dist/push/THIRD_PARTY_NOTICES.md +30 -0
- package/dist/push/badge.png +0 -0
- package/dist/push/icon.png +0 -0
- package/dist/push/sw.js +88 -0
- package/dist/push/sw.js.map +1 -0
- package/docs/400-reference/200-configuration.md +35 -0
- package/docs/400-reference/500-server/400-notifications.md +4 -0
- package/package.json +2 -2
- package/src/internal/client/background-notifications.ts +3 -1
- package/src/internal/client/host/hosted-pages/browser-notification-settings.tsx +8 -3
- package/src/internal/client/push-assets/badge.png +0 -0
- package/src/internal/client/push-assets/icon.png +0 -0
- package/src/internal/client/push-service-worker.ts +118 -0
- package/src/internal/client/register-push-worker.ts +63 -0
- package/src/internal/server/http/routes.ts +47 -2
- package/src/internal/shared/routes.ts +2 -0
|
@@ -255,3 +255,38 @@ export default defineOvermuxDesktopConfig({
|
|
|
255
255
|
macosTrafficLights: "hidden",
|
|
256
256
|
});
|
|
257
257
|
```
|
|
258
|
+
|
|
259
|
+
### `onBeforeInputEvent`
|
|
260
|
+
|
|
261
|
+
The optional `onBeforeInputEvent` callback exposes Electron's [`before-input-event`](https://www.electronjs.org/docs/latest/api/web-contents#event-before-input-event), receiving the actual Electron `Event`, `Input`, and receiving [`WebContents`](https://www.electronjs.org/docs/latest/api/web-contents).
|
|
262
|
+
|
|
263
|
+
You can use this callback to intercept Electron key presses.
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
import { defineOvermuxDesktopConfig } from "@overmux/desktop";
|
|
268
|
+
|
|
269
|
+
export default defineOvermuxDesktopConfig({
|
|
270
|
+
onBeforeInputEvent: ({ event, input, webContents }) => {
|
|
271
|
+
const key = input.key.toLowerCase();
|
|
272
|
+
if (
|
|
273
|
+
process.platform !== "linux" ||
|
|
274
|
+
input.type !== "keyDown" ||
|
|
275
|
+
!input.meta ||
|
|
276
|
+
input.control ||
|
|
277
|
+
input.alt ||
|
|
278
|
+
input.shift ||
|
|
279
|
+
(key !== "c" && key !== "v")
|
|
280
|
+
) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
event.preventDefault();
|
|
285
|
+
if (key === "c") {
|
|
286
|
+
webContents.copy();
|
|
287
|
+
} else {
|
|
288
|
+
webContents.paste();
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
```
|
|
@@ -30,3 +30,7 @@ export const serverConfig = defineOvermuxServer({
|
|
|
30
30
|
- `open.link`: optional destination to open when the notification is activated. Use an app-relative path starting with `/` or an HTTP(S) URL without credentials.
|
|
31
31
|
|
|
32
32
|
Each text field and link has a maximum length of 4,096 characters. `send()` returns `Promise<void>`.
|
|
33
|
+
|
|
34
|
+
## PWA background notifications
|
|
35
|
+
|
|
36
|
+
Open `/_overmux/settings` on your Overmux server, and enable browser notifications. This requires HTTPS, or localhost for development. See [Hosted pages](../../500-hosted-pages.md) for adding a settings link to your application.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/internal/client/background-notifications.ts","../../src/internal/client/native-web-view.tsx","../../src/internal/client/host/desktop-host.ts","../../src/internal/client/clipboard.ts","../../src/internal/client/browser-api.ts","../../src/internal/client/theme-scope.tsx","../../src/internal/client/client-definition.ts","../../src/internal/client/commands.tsx","../../src/internal/client/overmux-react.ts","../../src/internal/client/host/overmux-host.tsx","../../src/internal/client/shortcuts.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/internal/client/background-notifications.ts","../../src/internal/client/native-web-view.tsx","../../src/internal/client/host/desktop-host.ts","../../src/internal/client/clipboard.ts","../../src/internal/client/browser-api.ts","../../src/internal/client/theme-scope.tsx","../../src/internal/client/client-definition.ts","../../src/internal/client/commands.tsx","../../src/internal/client/overmux-react.ts","../../src/internal/client/host/overmux-host.tsx","../../src/internal/client/shortcuts.tsx"],"mappings":"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"}
|
package/dist/exports/client.js
CHANGED
|
@@ -192,6 +192,42 @@ const decodeProtocolFrame = (frame) => {
|
|
|
192
192
|
return decodeBinaryValue(header, bytes.subarray(8 + headerLength));
|
|
193
193
|
};
|
|
194
194
|
//#endregion
|
|
195
|
+
//#region src/internal/client/register-push-worker.ts
|
|
196
|
+
const registerPushWorker = () => new Promise((resolve, reject) => {
|
|
197
|
+
let watched = null;
|
|
198
|
+
let settled = false;
|
|
199
|
+
const finish = (error, registration) => {
|
|
200
|
+
if (settled) return;
|
|
201
|
+
settled = true;
|
|
202
|
+
clearTimeout(timeout);
|
|
203
|
+
watched?.removeEventListener("statechange", onStateChange);
|
|
204
|
+
if (error) reject(error);
|
|
205
|
+
else resolve(registration);
|
|
206
|
+
};
|
|
207
|
+
let registered;
|
|
208
|
+
const onStateChange = () => {
|
|
209
|
+
if (watched?.state === "activated") finish(void 0, registered);
|
|
210
|
+
else if (watched?.state === "redundant") finish(/* @__PURE__ */ new Error("The background notification worker failed to activate"));
|
|
211
|
+
};
|
|
212
|
+
const timeout = setTimeout(() => {
|
|
213
|
+
finish(/* @__PURE__ */ new Error("Timed out starting the background notification worker"));
|
|
214
|
+
}, 1e4);
|
|
215
|
+
navigator.serviceWorker.register("/sw.js", {
|
|
216
|
+
scope: "/",
|
|
217
|
+
updateViaCache: "none"
|
|
218
|
+
}).then((registration) => {
|
|
219
|
+
if (settled) return;
|
|
220
|
+
registered = registration;
|
|
221
|
+
watched = registration.active ?? registration.installing ?? registration.waiting;
|
|
222
|
+
if (!watched) {
|
|
223
|
+
finish(/* @__PURE__ */ new Error("No background notification worker was installed"));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
watched.addEventListener("statechange", onStateChange);
|
|
227
|
+
onStateChange();
|
|
228
|
+
}, (error) => finish(error instanceof Error ? error : new Error(String(error))));
|
|
229
|
+
});
|
|
230
|
+
//#endregion
|
|
195
231
|
//#region src/internal/client/background-notifications.ts
|
|
196
232
|
const enabledStorageKey = "overmux.backgroundNotificationsEnabled";
|
|
197
233
|
const isIos = () => /iPad|iPhone|iPod/u.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
@@ -257,7 +293,7 @@ const removeCurrentSubscription = async () => {
|
|
|
257
293
|
if (!await subscription.unsubscribe()) throw new Error("The background subscription could not be removed");
|
|
258
294
|
};
|
|
259
295
|
const reconcileBackgroundNotifications = async () => {
|
|
260
|
-
const registration = await
|
|
296
|
+
const registration = await registerPushWorker();
|
|
261
297
|
const publicKey = await getPublicKey();
|
|
262
298
|
let subscription = await registration.pushManager.getSubscription();
|
|
263
299
|
const subscriptionKey = subscription ? encodeApplicationServerKey(subscription.options.applicationServerKey) : void 0;
|
|
@@ -1510,13 +1546,17 @@ const statusMessage = (status) => {
|
|
|
1510
1546
|
};
|
|
1511
1547
|
const BrowserNotificationSettings = () => {
|
|
1512
1548
|
const [status, setStatus] = useState("checking");
|
|
1549
|
+
const [error, setError] = useState();
|
|
1513
1550
|
useEffect(() => {
|
|
1514
1551
|
let active = true;
|
|
1515
1552
|
const reconcile = () => {
|
|
1516
1553
|
reconciledStatus().then((next) => {
|
|
1517
1554
|
if (active) setStatus(next);
|
|
1518
|
-
}).catch(() => {
|
|
1519
|
-
if (active)
|
|
1555
|
+
}).catch((cause) => {
|
|
1556
|
+
if (active) {
|
|
1557
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1558
|
+
setStatus("error");
|
|
1559
|
+
}
|
|
1520
1560
|
});
|
|
1521
1561
|
};
|
|
1522
1562
|
const onVisibilityChange = () => {
|
|
@@ -1536,7 +1576,8 @@ const BrowserNotificationSettings = () => {
|
|
|
1536
1576
|
setStatus("checking");
|
|
1537
1577
|
const enabled = await enableBackgroundNotifications();
|
|
1538
1578
|
setStatus(enabled ? "enabled" : Notification.permission === "denied" ? "denied" : "disabled");
|
|
1539
|
-
} catch {
|
|
1579
|
+
} catch (cause) {
|
|
1580
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1540
1581
|
setStatus("error");
|
|
1541
1582
|
}
|
|
1542
1583
|
}, []);
|
|
@@ -1545,7 +1586,8 @@ const BrowserNotificationSettings = () => {
|
|
|
1545
1586
|
setStatus("checking");
|
|
1546
1587
|
await disableBackgroundNotifications();
|
|
1547
1588
|
setStatus("disabled");
|
|
1548
|
-
} catch {
|
|
1589
|
+
} catch (cause) {
|
|
1590
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1549
1591
|
setStatus("error");
|
|
1550
1592
|
}
|
|
1551
1593
|
}, []);
|
|
@@ -1555,10 +1597,10 @@ const BrowserNotificationSettings = () => {
|
|
|
1555
1597
|
"data-om-browser-notifications": "",
|
|
1556
1598
|
children: [
|
|
1557
1599
|
/* @__PURE__ */ jsx("h3", { children: "Browser notifications" }),
|
|
1558
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsxs("p", {
|
|
1559
1601
|
"aria-live": "polite",
|
|
1560
1602
|
"data-om-background-notifications-status": "",
|
|
1561
|
-
children: statusMessage(status)
|
|
1603
|
+
children: [statusMessage(status), status === "error" && error ? ` ${error}` : null]
|
|
1562
1604
|
}),
|
|
1563
1605
|
/* @__PURE__ */ jsxs("div", {
|
|
1564
1606
|
"data-om-hosted-actions": "",
|