@64mb/freelens-power 1.0.1 → 1.0.2
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/README.md +4 -4
- package/THIRD_PARTY_LICENSES +41 -0
- package/out/main/ai.js +9 -6
- package/out/main/ai.js.map +1 -1
- package/out/main/common/ai-extras.js +17 -0
- package/out/main/common/ai-extras.js.map +1 -1
- package/out/main/common/dashboard-readiness.js +88 -0
- package/out/main/common/dashboard-readiness.js.map +1 -0
- package/out/main/common/dashboard-selector.js +9 -1
- package/out/main/common/dashboard-selector.js.map +1 -1
- package/out/main/common/dashboard-views.js +2 -0
- package/out/main/common/dashboard-views.js.map +1 -1
- package/out/main/dashboard-network.js +104 -0
- package/out/main/dashboard-network.js.map +1 -0
- package/out/main/dashboard-views.js +98 -21
- package/out/main/dashboard-views.js.map +1 -1
- package/out/renderer/ai-extras.js +41 -12
- package/out/renderer/ai-extras.js.map +1 -1
- package/out/renderer/ai-message.js +1 -0
- package/out/renderer/ai-message.js.map +1 -1
- package/out/renderer/ai-provider-icon.js +44 -0
- package/out/renderer/ai-provider-icon.js.map +1 -0
- package/out/renderer/ai-shortcuts.js +1 -1
- package/out/renderer/ai-shortcuts.js.map +1 -1
- package/out/renderer/ai.js +53 -10
- package/out/renderer/ai.js.map +1 -1
- package/out/renderer/appearance.js +2 -1
- package/out/renderer/appearance.js.map +1 -1
- package/out/renderer/assets/claude.js +6 -0
- package/out/renderer/assets/claude.js.map +1 -0
- package/out/renderer/dashboard.js +39 -4
- package/out/renderer/dashboard.js.map +1 -1
- package/out/renderer/index.js +2 -0
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/menus/secure-node-shell-menu.js +1 -1
- package/out/renderer/menus/secure-node-shell-menu.js.map +1 -1
- package/out/renderer/monitoring.js +671 -91
- package/out/renderer/monitoring.js.map +1 -1
- package/out/renderer/pod-monitoring.js +214 -0
- package/out/renderer/pod-monitoring.js.map +1 -0
- package/out/renderer/preferences/ai-preferences.js +2 -2
- package/out/renderer/preferences/ai-preferences.js.map +1 -1
- package/out/renderer/preferences/dashboard-preferences.js +1 -8
- package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +1 -1
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/preferences/settings-icon-action.js +3 -1
- package/out/renderer/preferences/settings-icon-action.js.map +1 -1
- package/out/renderer/src/common/ai-extras.js +17 -0
- package/out/renderer/src/common/ai-extras.js.map +1 -1
- package/out/renderer/src/common/dashboard-selector.js.map +1 -1
- package/out/renderer/src/common/dashboard-views.js +2 -0
- package/out/renderer/src/common/dashboard-views.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
//#region src/main/dashboard-network.ts
|
|
2
|
+
function observeDashboardNetwork(contents) {
|
|
3
|
+
const protocol = contents.debugger;
|
|
4
|
+
const pending = /* @__PURE__ */ new Set();
|
|
5
|
+
let lastChange = Date.now();
|
|
6
|
+
let owned = false;
|
|
7
|
+
let active = false;
|
|
8
|
+
let disposed = false;
|
|
9
|
+
let ready;
|
|
10
|
+
let setupFinished = false;
|
|
11
|
+
let setupTimer;
|
|
12
|
+
let finishSetup;
|
|
13
|
+
const waits = /* @__PURE__ */ new Map();
|
|
14
|
+
const quiet = () => !active || pending.size === 0 && Date.now() - lastChange >= 350;
|
|
15
|
+
const release = () => {
|
|
16
|
+
for (const [timer, resolve] of waits) {
|
|
17
|
+
clearInterval(timer);
|
|
18
|
+
resolve();
|
|
19
|
+
}
|
|
20
|
+
waits.clear();
|
|
21
|
+
};
|
|
22
|
+
const detached = () => {
|
|
23
|
+
owned = false;
|
|
24
|
+
active = false;
|
|
25
|
+
pending.clear();
|
|
26
|
+
finishSetup?.();
|
|
27
|
+
release();
|
|
28
|
+
};
|
|
29
|
+
const message = (_event, method, params) => {
|
|
30
|
+
if (!active || typeof params?.requestId !== "string") return;
|
|
31
|
+
const id = params.requestId;
|
|
32
|
+
if (method === "Network.requestWillBeSent") {
|
|
33
|
+
if (params.type === "WebSocket" || params.type === "EventSource") return;
|
|
34
|
+
pending.add(id);
|
|
35
|
+
lastChange = Date.now();
|
|
36
|
+
} else if (method === "Network.responseReceived" && params.type === "EventSource") {
|
|
37
|
+
if (pending.delete(id)) lastChange = Date.now();
|
|
38
|
+
} else if (method === "Network.loadingFinished" || method === "Network.loadingFailed") {
|
|
39
|
+
if (pending.delete(id)) lastChange = Date.now();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const dispose = () => {
|
|
43
|
+
if (disposed) return;
|
|
44
|
+
disposed = true;
|
|
45
|
+
finishSetup?.();
|
|
46
|
+
active = false;
|
|
47
|
+
pending.clear();
|
|
48
|
+
release();
|
|
49
|
+
contents.removeListener("destroyed", dispose);
|
|
50
|
+
protocol?.removeListener("message", message);
|
|
51
|
+
protocol?.removeListener("detach", detached);
|
|
52
|
+
if (owned) {
|
|
53
|
+
owned = false;
|
|
54
|
+
try {
|
|
55
|
+
if (protocol.isAttached()) protocol.detach();
|
|
56
|
+
} catch {}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
try {
|
|
60
|
+
if (protocol && !protocol.isAttached()) {
|
|
61
|
+
protocol.attach("1.3");
|
|
62
|
+
owned = true;
|
|
63
|
+
active = true;
|
|
64
|
+
protocol.on("message", message);
|
|
65
|
+
protocol.on("detach", detached);
|
|
66
|
+
contents.on("destroyed", dispose);
|
|
67
|
+
ready = new Promise((resolve) => {
|
|
68
|
+
finishSetup = () => {
|
|
69
|
+
setupFinished = true;
|
|
70
|
+
clearTimeout(setupTimer);
|
|
71
|
+
resolve();
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
protocol.sendCommand("Network.enable").then(() => finishSetup?.(), dispose);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
dispose();
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
ready: () => {
|
|
81
|
+
if (ready && !setupFinished && !setupTimer) setupTimer = setTimeout(dispose, 500);
|
|
82
|
+
return ready ?? Promise.resolve();
|
|
83
|
+
},
|
|
84
|
+
quiet,
|
|
85
|
+
wait: () => new Promise((resolve) => {
|
|
86
|
+
if (quiet()) {
|
|
87
|
+
resolve();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const timer = setInterval(() => {
|
|
91
|
+
if (!quiet()) return;
|
|
92
|
+
clearInterval(timer);
|
|
93
|
+
waits.delete(timer);
|
|
94
|
+
resolve();
|
|
95
|
+
}, 50);
|
|
96
|
+
waits.set(timer, resolve);
|
|
97
|
+
}),
|
|
98
|
+
dispose
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
exports.observeDashboardNetwork = observeDashboardNetwork;
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=dashboard-network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-network.js","names":[],"sources":["../../src/main/dashboard-network.ts"],"sourcesContent":["import type { WebContents } from \"electron\";\n\nexport function observeDashboardNetwork(contents: WebContents) {\n const protocol = contents.debugger;\n const pending = new Set<string>();\n let lastChange = Date.now();\n let owned = false;\n let active = false;\n let disposed = false;\n let ready: Promise<void> | undefined;\n let setupFinished = false;\n let setupTimer: ReturnType<typeof setTimeout> | undefined;\n let finishSetup: (() => void) | undefined;\n const waits = new Map<ReturnType<typeof setInterval>, () => void>();\n const quiet = () => !active || (pending.size === 0 && Date.now() - lastChange >= 350);\n const release = () => {\n for (const [timer, resolve] of waits) {\n clearInterval(timer);\n resolve();\n }\n waits.clear();\n };\n const detached = () => {\n owned = false;\n active = false;\n pending.clear();\n finishSetup?.();\n release();\n };\n const message = (_event: unknown, method: string, params: { requestId?: unknown; type?: unknown }) => {\n if (!active || typeof params?.requestId !== \"string\") return;\n const id = params.requestId;\n if (method === \"Network.requestWillBeSent\") {\n if (params.type === \"WebSocket\" || params.type === \"EventSource\") return;\n pending.add(id);\n lastChange = Date.now();\n } else if (method === \"Network.responseReceived\" && params.type === \"EventSource\") {\n if (pending.delete(id)) lastChange = Date.now();\n } else if (method === \"Network.loadingFinished\" || method === \"Network.loadingFailed\") {\n if (pending.delete(id)) lastChange = Date.now();\n }\n };\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n finishSetup?.();\n active = false;\n pending.clear();\n release();\n contents.removeListener(\"destroyed\", dispose);\n protocol?.removeListener(\"message\", message);\n protocol?.removeListener(\"detach\", detached);\n if (owned) {\n owned = false;\n try {\n if (protocol.isAttached()) protocol.detach();\n } catch {}\n }\n };\n try {\n if (protocol && !protocol.isAttached()) {\n protocol.attach(\"1.3\");\n owned = true;\n active = true;\n protocol.on(\"message\", message);\n protocol.on(\"detach\", detached);\n contents.on(\"destroyed\", dispose);\n ready = new Promise<void>((resolve) => {\n finishSetup = () => {\n setupFinished = true;\n clearTimeout(setupTimer);\n resolve();\n };\n });\n void protocol.sendCommand(\"Network.enable\").then(() => finishSetup?.(), dispose);\n }\n } catch {\n dispose();\n }\n return {\n ready: () => {\n if (ready && !setupFinished && !setupTimer) setupTimer = setTimeout(dispose, 500);\n return ready ?? Promise.resolve();\n },\n quiet,\n wait: () =>\n new Promise<void>((resolve) => {\n if (quiet()) {\n resolve();\n return;\n }\n const timer = setInterval(() => {\n if (!quiet()) return;\n clearInterval(timer);\n waits.delete(timer);\n resolve();\n }, 50);\n waits.set(timer, resolve);\n }),\n dispose,\n };\n}\n"],"mappings":";AAEA,SAAgB,wBAAwB,UAAuB;CAC7D,MAAM,WAAW,SAAS;CAC1B,MAAM,0BAAU,IAAI,IAAY;CAChC,IAAI,aAAa,KAAK,IAAI;CAC1B,IAAI,QAAQ;CACZ,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI;CACJ,IAAI,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,MAAM,wBAAQ,IAAI,IAAgD;CAClE,MAAM,cAAc,CAAC,UAAW,QAAQ,SAAS,KAAK,KAAK,IAAI,IAAI,cAAc;CACjF,MAAM,gBAAgB;EACpB,KAAK,MAAM,CAAC,OAAO,YAAY,OAAO;GACpC,cAAc,KAAK;GACnB,QAAQ;EACV;EACA,MAAM,MAAM;CACd;CACA,MAAM,iBAAiB;EACrB,QAAQ;EACR,SAAS;EACT,QAAQ,MAAM;EACd,cAAc;EACd,QAAQ;CACV;CACA,MAAM,WAAW,QAAiB,QAAgB,WAAoD;EACpG,IAAI,CAAC,UAAU,OAAO,QAAQ,cAAc,UAAU;EACtD,MAAM,KAAK,OAAO;EAClB,IAAI,WAAW,6BAA6B;GAC1C,IAAI,OAAO,SAAS,eAAe,OAAO,SAAS,eAAe;GAClE,QAAQ,IAAI,EAAE;GACd,aAAa,KAAK,IAAI;EACxB,OAAO,IAAI,WAAW,8BAA8B,OAAO,SAAS;OAC9D,QAAQ,OAAO,EAAE,GAAG,aAAa,KAAK,IAAI;EAAA,OACzC,IAAI,WAAW,6BAA6B,WAAW;OACxD,QAAQ,OAAO,EAAE,GAAG,aAAa,KAAK,IAAI;EAAA;CAElD;CACA,MAAM,gBAAgB;EACpB,IAAI,UAAU;EACd,WAAW;EACX,cAAc;EACd,SAAS;EACT,QAAQ,MAAM;EACd,QAAQ;EACR,SAAS,eAAe,aAAa,OAAO;EAC5C,UAAU,eAAe,WAAW,OAAO;EAC3C,UAAU,eAAe,UAAU,QAAQ;EAC3C,IAAI,OAAO;GACT,QAAQ;GACR,IAAI;IACF,IAAI,SAAS,WAAW,GAAG,SAAS,OAAO;GAC7C,QAAQ,CAAC;EACX;CACF;CACA,IAAI;EACF,IAAI,YAAY,CAAC,SAAS,WAAW,GAAG;GACtC,SAAS,OAAO,KAAK;GACrB,QAAQ;GACR,SAAS;GACT,SAAS,GAAG,WAAW,OAAO;GAC9B,SAAS,GAAG,UAAU,QAAQ;GAC9B,SAAS,GAAG,aAAa,OAAO;GAChC,QAAQ,IAAI,SAAe,YAAY;IACrC,oBAAoB;KAClB,gBAAgB;KAChB,aAAa,UAAU;KACvB,QAAQ;IACV;GACF,CAAC;GACD,SAAc,YAAY,gBAAgB,CAAC,CAAC,WAAW,cAAc,GAAG,OAAO;EACjF;CACF,QAAQ;EACN,QAAQ;CACV;CACA,OAAO;EACL,aAAa;GACX,IAAI,SAAS,CAAC,iBAAiB,CAAC,YAAY,aAAa,WAAW,SAAS,GAAG;GAChF,OAAO,SAAS,QAAQ,QAAQ;EAClC;EACA;EACA,YACE,IAAI,SAAe,YAAY;GAC7B,IAAI,MAAM,GAAG;IACX,QAAQ;IACR;GACF;GACA,MAAM,QAAQ,kBAAkB;IAC9B,IAAI,CAAC,MAAM,GAAG;IACd,cAAc,KAAK;IACnB,MAAM,OAAO,KAAK;IAClB,QAAQ;GACV,GAAG,EAAE;GACL,MAAM,IAAI,OAAO,OAAO;EAC1B,CAAC;EACH;CACF;AACF"}
|
|
@@ -2,8 +2,10 @@ const require__global_external_mobx = require("./_virtual/_global-external_mobx.
|
|
|
2
2
|
const require_dashboard_selector = require("./common/dashboard-selector.js");
|
|
3
3
|
const require_dashboard = require("./common/dashboard.js");
|
|
4
4
|
const require_dashboard_preferences_store = require("./common/store/dashboard-preferences-store.js");
|
|
5
|
+
const require_dashboard_readiness = require("./common/dashboard-readiness.js");
|
|
5
6
|
const require_dashboard_views = require("./common/dashboard-views.js");
|
|
6
7
|
const require_dashboard_icon_cache = require("./dashboard-icon-cache.js");
|
|
8
|
+
const require_dashboard_network = require("./dashboard-network.js");
|
|
7
9
|
let electron = require("electron");
|
|
8
10
|
let node_path = require("node:path");
|
|
9
11
|
//#region src/main/dashboard-views.ts
|
|
@@ -56,6 +58,7 @@ function startDashboardViews() {
|
|
|
56
58
|
const card = owner.cards.get(id);
|
|
57
59
|
if (!card) return;
|
|
58
60
|
owner.cards.delete(id);
|
|
61
|
+
card.stopPreparation?.();
|
|
59
62
|
card.faviconRequest?.abort();
|
|
60
63
|
clearInterval(card.refreshTimer);
|
|
61
64
|
card.floating?.destroy();
|
|
@@ -71,7 +74,10 @@ function startDashboardViews() {
|
|
|
71
74
|
owner.cleanup();
|
|
72
75
|
};
|
|
73
76
|
const hide = (sender) => {
|
|
74
|
-
for (const card of owners.get(sender)?.cards.values() ?? [])
|
|
77
|
+
for (const card of owners.get(sender)?.cards.values() ?? []) {
|
|
78
|
+
card.visible = false;
|
|
79
|
+
card.container.setVisible(false);
|
|
80
|
+
}
|
|
75
81
|
};
|
|
76
82
|
const configuredCards = () => require_dashboard.sanitizeDashboardCards(require_dashboard_preferences_store.DashboardPreferencesStore.getInstanceOrCreate().cards);
|
|
77
83
|
const cachePath = (0, node_path.join)(electron.app.getPath("userData"), "freelens-power", "dashboard-icons.json");
|
|
@@ -90,21 +96,91 @@ function startDashboardViews() {
|
|
|
90
96
|
}).catch(() => {});
|
|
91
97
|
};
|
|
92
98
|
persistIcons();
|
|
93
|
-
const
|
|
99
|
+
const publishLoading = (card) => {
|
|
100
|
+
for (const [sender, owner] of owners) {
|
|
101
|
+
const id = [...owner.cards].find(([, candidate]) => candidate === card)?.[0];
|
|
102
|
+
if (!id || sender.isDestroyed() || !dashboardUrl(sender.mainFrame.url) || !dashboardUrl(sender.getURL()) || !configuredCards().some((configured) => configured.id === id && configured.url === card.url)) continue;
|
|
103
|
+
sender.send(require_dashboard_views.DASHBOARD_VIEWS_LOADING, {
|
|
104
|
+
id,
|
|
105
|
+
url: card.url,
|
|
106
|
+
loading: card.loading,
|
|
107
|
+
failed: card.failed
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const reload = (card, configuredUrl, initial = false) => {
|
|
94
112
|
const current = card.view.webContents.getURL();
|
|
95
|
-
const target = card.url === configuredUrl && webUrl(current) ? current : configuredUrl;
|
|
113
|
+
const target = !initial && card.url === configuredUrl && webUrl(current) ? current : configuredUrl;
|
|
96
114
|
card.faviconRequest?.abort();
|
|
97
115
|
card.url = configuredUrl;
|
|
98
116
|
card.failed = false;
|
|
99
|
-
card.
|
|
100
|
-
|
|
117
|
+
card.loading = true;
|
|
118
|
+
card.stopPreparation?.();
|
|
119
|
+
const contents = card.view.webContents;
|
|
120
|
+
const backgroundThrottling = contents.getBackgroundThrottling();
|
|
121
|
+
if (backgroundThrottling) contents.setBackgroundThrottling(false);
|
|
122
|
+
const network = require_dashboard_network.observeDashboardNetwork(card.view.webContents);
|
|
123
|
+
let stopped = false;
|
|
124
|
+
const stopPreparation = () => {
|
|
125
|
+
if (stopped) return;
|
|
126
|
+
stopped = true;
|
|
127
|
+
network.dispose();
|
|
128
|
+
contents.removeListener("destroyed", stopPreparation);
|
|
129
|
+
if (!contents.isDestroyed() && backgroundThrottling && !contents.getBackgroundThrottling()) contents.setBackgroundThrottling(backgroundThrottling);
|
|
130
|
+
if (card.stopPreparation === stopPreparation) card.stopPreparation = void 0;
|
|
131
|
+
};
|
|
132
|
+
card.stopPreparation = stopPreparation;
|
|
133
|
+
contents.once("destroyed", stopPreparation);
|
|
134
|
+
const generation = ++card.generation;
|
|
135
|
+
card.container.setVisible(false);
|
|
136
|
+
publishLoading(card);
|
|
137
|
+
const settled = (failed) => {
|
|
138
|
+
if (card.generation !== generation || card.view.webContents.isDestroyed()) return;
|
|
139
|
+
card.failed = failed;
|
|
140
|
+
card.loading = false;
|
|
141
|
+
for (const [sender, owner] of owners) {
|
|
142
|
+
if (![...owner.cards.values()].includes(card)) continue;
|
|
143
|
+
card.container.setVisible(card.visible && !card.floating && !failed && dashboardUrl(sender.getURL()));
|
|
144
|
+
}
|
|
145
|
+
publishLoading(card);
|
|
146
|
+
};
|
|
147
|
+
const load = () => {
|
|
148
|
+
if (card.generation !== generation || card.view.webContents.isDestroyed() || ![...owners.values()].some((owner) => [...owner.cards.values()].includes(card))) return Promise.resolve();
|
|
149
|
+
return card.view.webContents.loadURL(target);
|
|
150
|
+
};
|
|
151
|
+
card.pending = load().then(async () => {
|
|
152
|
+
let deadline;
|
|
153
|
+
let preparing = true;
|
|
154
|
+
const current = () => preparing && card.generation === generation && !card.view.webContents.isDestroyed() && [...owners.values()].some((owner) => [...owner.cards.values()].includes(card));
|
|
155
|
+
try {
|
|
156
|
+
await Promise.race([(async () => {
|
|
157
|
+
if (!current()) return;
|
|
158
|
+
await network.ready();
|
|
159
|
+
if (!current()) return;
|
|
160
|
+
await applySelector(card);
|
|
161
|
+
do {
|
|
162
|
+
await network.wait();
|
|
163
|
+
if (!current()) return;
|
|
164
|
+
await card.view.webContents.executeJavaScriptInIsolatedWorld(1004, [{ code: require_dashboard_readiness.dashboardReadinessScript(card.selector) }]);
|
|
165
|
+
} while (current() && !network.quiet());
|
|
166
|
+
})().catch(() => new Promise((resolve) => setTimeout(resolve, 200))), new Promise((resolve) => {
|
|
167
|
+
deadline = setTimeout(resolve, 8500);
|
|
168
|
+
})]);
|
|
169
|
+
} finally {
|
|
170
|
+
clearTimeout(deadline);
|
|
171
|
+
preparing = false;
|
|
172
|
+
stopPreparation();
|
|
173
|
+
}
|
|
174
|
+
settled(false);
|
|
101
175
|
}, () => {
|
|
102
|
-
|
|
176
|
+
stopPreparation();
|
|
177
|
+
settled(true);
|
|
103
178
|
});
|
|
104
179
|
return card.pending;
|
|
105
180
|
};
|
|
106
181
|
const applySelector = (card) => {
|
|
107
|
-
if (
|
|
182
|
+
if (card.view.webContents.isDestroyed()) return Promise.resolve();
|
|
183
|
+
return card.view.webContents.executeJavaScriptInIsolatedWorld(1004, [{ code: require_dashboard_selector.dashboardSelectorScript(card.selector) }]).catch(() => {});
|
|
108
184
|
};
|
|
109
185
|
const refreshTimers = () => {
|
|
110
186
|
const configured = configuredCards();
|
|
@@ -184,7 +260,7 @@ function startDashboardViews() {
|
|
|
184
260
|
owners.set(sender, owner);
|
|
185
261
|
}
|
|
186
262
|
if (payload && typeof payload === "object" && "hidden" in payload && payload.hidden === true) {
|
|
187
|
-
|
|
263
|
+
hide(event.sender);
|
|
188
264
|
return {
|
|
189
265
|
failed: [],
|
|
190
266
|
pinned: [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id)
|
|
@@ -200,6 +276,7 @@ function startDashboardViews() {
|
|
|
200
276
|
visible.add(item.id);
|
|
201
277
|
let card = owner.cards.get(item.id);
|
|
202
278
|
if (card?.floating) {
|
|
279
|
+
card.visible = false;
|
|
203
280
|
card.container.setVisible(false);
|
|
204
281
|
continue;
|
|
205
282
|
}
|
|
@@ -236,7 +313,10 @@ function startDashboardViews() {
|
|
|
236
313
|
container,
|
|
237
314
|
view,
|
|
238
315
|
url: "",
|
|
239
|
-
failed: false
|
|
316
|
+
failed: false,
|
|
317
|
+
loading: false,
|
|
318
|
+
visible: false,
|
|
319
|
+
generation: 0
|
|
240
320
|
};
|
|
241
321
|
owner.cards.set(item.id, card);
|
|
242
322
|
const created = card;
|
|
@@ -327,7 +407,8 @@ function startDashboardViews() {
|
|
|
327
407
|
})().catch(() => {}).finally(() => clearTimeout(timeout));
|
|
328
408
|
});
|
|
329
409
|
}
|
|
330
|
-
card.
|
|
410
|
+
card.visible = true;
|
|
411
|
+
card.container.setVisible(!card.loading && !card.failed && card.url === configured.url);
|
|
331
412
|
const zoom = event.sender.getZoomFactor();
|
|
332
413
|
card.container.setBorderRadius(Math.round(12 * zoom));
|
|
333
414
|
card.view.setBorderRadius(Math.round(12 * zoom));
|
|
@@ -345,24 +426,21 @@ function startDashboardViews() {
|
|
|
345
426
|
height: bounds.height
|
|
346
427
|
}));
|
|
347
428
|
if (card.url !== configured.url) {
|
|
348
|
-
card.url = configured.url;
|
|
349
429
|
card.favicon = void 0;
|
|
350
430
|
card.faviconRequest?.abort();
|
|
351
|
-
|
|
352
|
-
loading.failed = false;
|
|
353
|
-
loading.pending = loading.view.webContents.loadURL(configured.url).then(() => {
|
|
354
|
-
loading.failed = false;
|
|
355
|
-
}, () => {
|
|
356
|
-
loading.failed = true;
|
|
357
|
-
});
|
|
431
|
+
reload(card, configured.url, true);
|
|
358
432
|
}
|
|
433
|
+
publishLoading(card);
|
|
359
434
|
if (card.favicon) event.sender.send("freelens-power:dashboard-site-icon", {
|
|
360
435
|
id: item.id,
|
|
361
436
|
url: card.favicon
|
|
362
437
|
});
|
|
363
438
|
}
|
|
364
439
|
for (const [id, card] of owner.cards) if (!cards.some((configured) => configured.id === id)) remove(owner, id);
|
|
365
|
-
else if (!visible.has(id))
|
|
440
|
+
else if (!visible.has(id)) {
|
|
441
|
+
card.visible = false;
|
|
442
|
+
card.container.setVisible(false);
|
|
443
|
+
}
|
|
366
444
|
refreshTimers();
|
|
367
445
|
await Promise.all([...owner.cards.values()].map((card) => card.pending));
|
|
368
446
|
return {
|
|
@@ -455,8 +533,7 @@ function startDashboardViews() {
|
|
|
455
533
|
const current = floating?.getURL();
|
|
456
534
|
const floatingReload = floating && !floating.isDestroyed() ? floating.loadURL(current && webUrl(current) ? current : configured.url).then(() => false, () => !floating.isDestroyed()) : Promise.resolve(false);
|
|
457
535
|
const [, floatingFailed] = await Promise.all([reload(card, configured.url), floatingReload]);
|
|
458
|
-
card.failed
|
|
459
|
-
return { failed: card.failed ? [payload.id] : [] };
|
|
536
|
+
return { failed: card.failed || floatingFailed ? [payload.id] : [] };
|
|
460
537
|
});
|
|
461
538
|
return () => {
|
|
462
539
|
stopSettingsReaction();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-views.js","names":[],"sources":["../../src/main/dashboard-views.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { join } from \"node:path\";\nimport {\n app,\n BrowserWindow,\n type IpcMainInvokeEvent,\n ipcMain,\n type Rectangle,\n session,\n shell,\n View,\n type WebContents,\n WebContentsView,\n} from \"electron\";\nimport { reaction } from \"mobx\";\nimport { sanitizeDashboardCards } from \"../common/dashboard\";\nimport { dashboardSelectorScript } from \"../common/dashboard-selector\";\nimport {\n DASHBOARD_SITE_ICONS,\n DASHBOARD_VIEWS_PIN,\n DASHBOARD_VIEWS_PINNED,\n type DashboardSiteIcon,\n} from \"../common/dashboard-views\";\nimport { DashboardPreferencesStore } from \"../common/store/dashboard-preferences-store\";\nimport { boundedDashboardIcons, loadDashboardIcons, saveDashboardIcons } from \"./dashboard-icon-cache\";\n\nconst syncChannel = \"freelens-power:dashboard-views:sync\";\nconst reloadChannel = \"freelens-power:dashboard-views:reload\";\nconst clearChannel = \"freelens-power:dashboard-views:clear\";\nconst dashboardPath = \"/extension/freelens-power/dashboard\";\nconst websiteStyles =\n \"* { scrollbar-width: none !important; } *::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }\";\n\nfunction rendererUrl(value: string, dashboardOnly = false): boolean {\n try {\n const url = new URL(value);\n return (\n url.protocol === \"https:\" &&\n (url.hostname === \"renderer.freelens.app\" || url.hostname.endsWith(\".renderer.freelens.app\")) &&\n (!dashboardOnly || url.pathname === dashboardPath)\n );\n } catch {\n return false;\n }\n}\nfunction dashboardUrl(value: string): boolean {\n return rendererUrl(value, true);\n}\nfunction webUrl(value: string): boolean {\n try {\n return [\"https:\", \"http:\"].includes(new URL(value).protocol);\n } catch {\n return false;\n }\n}\nfunction rectangle(value: unknown): Rectangle | undefined {\n if (!value || typeof value !== \"object\") return;\n const rect = value as Rectangle;\n if (\n ![rect.x, rect.y, rect.width, rect.height].every(\n (n) => Number.isFinite(n) && Number.isInteger(n) && Math.abs(n) <= 32768,\n ) ||\n rect.width <= 0 ||\n rect.height <= 0\n )\n return;\n return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };\n}\n\ntype CardView = {\n container: View;\n view: WebContentsView;\n url: string;\n failed: boolean;\n selector?: string;\n pending?: Promise<void>;\n favicon?: string;\n faviconRequest?: AbortController;\n refreshTimer?: ReturnType<typeof setInterval>;\n floating?: BrowserWindow;\n};\ntype Owner = { window: BrowserWindow; cards: Map<string, CardView>; cleanup: () => void };\n\nexport function startDashboardViews(): () => void {\n const websiteSession = session.fromPartition(\"persist:freelens-power-websites\");\n websiteSession.setPermissionRequestHandler((_contents, _permission, callback) => callback(false));\n websiteSession.setPermissionCheckHandler(() => false);\n const owners = new Map<WebContents, Owner>();\n const icons = new Map<string, DashboardSiteIcon>();\n const remove = (owner: Owner, id: string) => {\n const card = owner.cards.get(id);\n if (!card) return;\n owner.cards.delete(id);\n card.faviconRequest?.abort();\n clearInterval(card.refreshTimer);\n card.floating?.destroy();\n card.floating = undefined;\n if (!owner.window.isDestroyed()) owner.window.contentView.removeChildView(card.container);\n if (!card.view.webContents.isDestroyed()) card.view.webContents.close();\n };\n const clear = (sender: WebContents) => {\n const owner = owners.get(sender);\n if (!owner) return;\n owners.delete(sender);\n for (const id of owner.cards.keys()) remove(owner, id);\n owner.cleanup();\n };\n const hide = (sender: WebContents) => {\n for (const card of owners.get(sender)?.cards.values() ?? []) card.container.setVisible(false);\n };\n const configuredCards = () =>\n sanitizeDashboardCards(DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards);\n const cachePath = join(app.getPath(\"userData\"), \"freelens-power\", \"dashboard-icons.json\");\n const ready = loadDashboardIcons(cachePath).then((saved) => {\n const configured = configuredCards();\n for (const icon of saved) {\n if (!icons.has(icon.id) && configured.some((card) => card.id === icon.id && card.url === icon.pageUrl))\n icons.set(icon.id, icon);\n }\n });\n let writes = ready;\n const persistIcons = () => {\n writes = writes\n .then(async () => {\n const configured = configuredCards();\n const bounded = boundedDashboardIcons(\n [...icons.values()].filter((icon) =>\n configured.some((card) => card.id === icon.id && card.url === icon.pageUrl),\n ),\n );\n icons.clear();\n for (const icon of bounded) icons.set(icon.id, icon);\n await saveDashboardIcons(cachePath, bounded);\n })\n .catch(() => {});\n };\n persistIcons();\n const reload = (card: CardView, configuredUrl: string) => {\n const current = card.view.webContents.getURL();\n const target = card.url === configuredUrl && webUrl(current) ? current : configuredUrl;\n card.faviconRequest?.abort();\n card.url = configuredUrl;\n card.failed = false;\n card.pending = card.view.webContents.loadURL(target).then(\n () => {\n card.failed = false;\n },\n () => {\n card.failed = true;\n },\n );\n return card.pending;\n };\n const applySelector = (card: { view: { webContents: WebContents }; selector?: string }) => {\n if (!card.view.webContents.isDestroyed())\n void card.view.webContents\n .executeJavaScriptInIsolatedWorld(1004, [{ code: dashboardSelectorScript(card.selector) }])\n .catch(() => {});\n };\n const refreshTimers = () => {\n const configured = configuredCards();\n for (const [id, icon] of icons) {\n if (!configured.some((card) => card.id === id && card.url === icon.pageUrl)) {\n icons.delete(id);\n persistIcons();\n }\n }\n for (const [sender, owner] of owners) {\n for (const [id, card] of owner.cards) {\n const setting = configured.find((item) => item.id === id);\n if (!setting || setting.url !== card.url) {\n remove(owner, id);\n continue;\n }\n if (card.selector !== setting.selector) {\n card.selector = setting.selector;\n applySelector(card);\n if (card.floating && !card.floating.isDestroyed())\n applySelector({ view: { webContents: card.floating.webContents }, selector: card.selector });\n }\n if (card.floating && !card.floating.isDestroyed()) card.floating.setTitle(setting.title);\n if (!setting.autoRefresh) {\n clearInterval(card.refreshTimer);\n card.refreshTimer = undefined;\n continue;\n }\n if (card.refreshTimer) continue;\n card.refreshTimer = setInterval(() => {\n const latest = configuredCards().find((item) => item.id === id);\n if (\n owners.get(sender) !== owner ||\n card.floating ||\n dashboardUrl(sender.getURL()) ||\n owner.cards.get(id) !== card ||\n !latest?.autoRefresh ||\n latest.url !== card.url ||\n card.view.webContents.isDestroyed() ||\n card.view.webContents.isLoading()\n )\n return;\n void reload(card, latest.url);\n }, 600000);\n }\n }\n };\n const stopSettingsReaction = reaction(\n () =>\n JSON.stringify(\n configuredCards().map(({ id, title, url, autoRefresh, selector }) => ({\n id,\n title,\n url,\n autoRefresh,\n selector,\n })),\n ),\n refreshTimers,\n );\n const trusted = (event: IpcMainInvokeEvent) =>\n event.senderFrame === event.sender.mainFrame &&\n dashboardUrl(event.senderFrame?.url ?? \"\") &&\n dashboardUrl(event.sender.getURL());\n ipcMain.handle(DASHBOARD_SITE_ICONS, async (event) => {\n if (\n event.senderFrame !== event.sender.mainFrame ||\n !rendererUrl(event.senderFrame?.url ?? \"\") ||\n !rendererUrl(event.sender.getURL()) ||\n !BrowserWindow.fromWebContents(event.sender)\n )\n return [];\n await ready;\n return configuredCards().flatMap((card) => {\n const icon = icons.get(card.id);\n return icon?.pageUrl === card.url ? [icon] : [];\n });\n });\n ipcMain.handle(syncChannel, async (event, payload: unknown) => {\n if (!trusted(event)) return;\n const window = BrowserWindow.fromWebContents(event.sender);\n if (!window || window.isDestroyed()) return;\n const requested =\n payload && typeof payload === \"object\" && \"cards\" in payload && Array.isArray(payload.cards) ? payload.cards : [];\n const cards = sanitizeDashboardCards(\n DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards,\n );\n let owner = owners.get(event.sender);\n if (!owner) {\n const sender = event.sender;\n const navigation = (_event: unknown, url: string) => {\n if (!dashboardUrl(url)) hide(sender);\n };\n const destroyed = () => clear(sender);\n sender.on(\"did-navigate\", navigation);\n sender.on(\"did-navigate-in-page\", navigation);\n sender.on(\"destroyed\", destroyed);\n owner = {\n window,\n cards: new Map(),\n cleanup: () => {\n sender.removeListener(\"did-navigate\", navigation);\n sender.removeListener(\"did-navigate-in-page\", navigation);\n sender.removeListener(\"destroyed\", destroyed);\n },\n };\n owners.set(sender, owner);\n }\n if (payload && typeof payload === \"object\" && \"hidden\" in payload && payload.hidden === true) {\n for (const card of owner.cards.values()) card.container.setVisible(false);\n return { failed: [], pinned: [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id) };\n }\n const visible = new Set<string>();\n for (const item of requested.slice(0, cards.length)) {\n if (!item || typeof item !== \"object\" || typeof item.id !== \"string\" || visible.has(item.id)) continue;\n const configured = cards.find((card) => card.id === item.id);\n const bounds = rectangle(item.bounds);\n const clip = rectangle(item.clip);\n if (\n !configured ||\n !bounds ||\n !clip ||\n clip.x < bounds.x ||\n clip.y < bounds.y ||\n clip.x + clip.width > bounds.x + bounds.width ||\n clip.y + clip.height > bounds.y + bounds.height\n )\n continue;\n visible.add(item.id);\n let card = owner.cards.get(item.id);\n if (card?.floating) {\n card.container.setVisible(false);\n continue;\n }\n if (!card) {\n const container = new View();\n container.setBackgroundColor(\"#00000000\");\n const view = new WebContentsView({\n webPreferences: {\n nodeIntegration: false,\n nodeIntegrationInSubFrames: false,\n contextIsolation: true,\n sandbox: true,\n webSecurity: true,\n partition: \"persist:freelens-power-websites\",\n },\n });\n view.setBackgroundColor(\"#00000000\");\n view.webContents.on(\"did-finish-load\", () => {\n if (!view.webContents.isDestroyed())\n void view.webContents.insertCSS(websiteStyles, { cssOrigin: \"user\" }).catch(() => {});\n });\n view.webContents.setWindowOpenHandler(({ url }) => {\n if (webUrl(url)) void shell.openExternal(url).catch(() => {});\n return { action: \"deny\" };\n });\n const navigation = (event: Electron.Event, url: string) => {\n if (!webUrl(url)) event.preventDefault();\n };\n view.webContents.on(\"will-navigate\", navigation);\n view.webContents.on(\"will-redirect\", navigation);\n view.webContents.on(\"will-frame-navigate\", (event) => {\n if (!webUrl(event.url)) event.preventDefault();\n });\n container.addChildView(view);\n window.contentView.addChildView(container);\n card = { container, view, url: \"\", failed: false };\n owner.cards.set(item.id, card);\n const created = card;\n view.webContents.on(\"before-input-event\", (_event, input: Electron.Input) => {\n if (\n input.type !== \"keyDown\" ||\n input.key !== \"Escape\" ||\n owners.get(event.sender) !== owner ||\n owner.cards.get(item.id) !== created ||\n !trusted(event)\n )\n return;\n event.sender.send(\"freelens-power:dashboard-escape\");\n });\n created.selector = configured.selector;\n view.webContents.on(\"did-finish-load\", () => applySelector(created));\n view.webContents.on(\"page-favicon-updated\", (_event, favicons: string[]) => {\n const favicon = favicons.find((value) => {\n if (!webUrl(value)) return false;\n const parsed = new URL(value);\n return !parsed.username && !parsed.password;\n });\n if (!favicon || owners.get(event.sender) !== owner || owner.cards.get(item.id) !== created) return;\n created.faviconRequest?.abort();\n const request = new AbortController();\n created.faviconRequest = request;\n created.favicon = favicon;\n const publish = (url: string) => {\n if (\n request.signal.aborted ||\n owners.get(event.sender) !== owner ||\n owner.cards.get(item.id) !== created ||\n event.senderFrame !== event.sender.mainFrame\n )\n return;\n created.favicon = url;\n if (\n url.startsWith(\"data:\") &&\n configuredCards().some((card) => card.id === item.id && card.url === created.url)\n ) {\n icons.set(item.id, { id: item.id, pageUrl: created.url, dataUrl: url });\n persistIcons();\n if (rendererUrl(event.senderFrame?.url ?? \"\") && rendererUrl(event.sender.getURL()))\n event.sender.send(DASHBOARD_SITE_ICONS);\n }\n if (!trusted(event)) return;\n event.sender.send(\"freelens-power:dashboard-site-icon\", { id: item.id, url });\n };\n publish(favicon);\n const timeout = setTimeout(() => request.abort(), 5000);\n void (async () => {\n let current = favicon;\n for (let redirects = 0; redirects <= 5; redirects++) {\n const response = await websiteSession.fetch(current, {\n signal: request.signal,\n redirect: \"manual\",\n credentials: \"include\",\n });\n if (response.status >= 300 && response.status < 400) {\n await response.body?.cancel();\n const location = response.headers.get(\"location\");\n if (!location) return;\n const next = new URL(location, current);\n if (!webUrl(next.href) || next.username || next.password) return;\n current = next.href;\n continue;\n }\n const mime = response.headers.get(\"content-type\")?.split(\";\")[0].trim().toLowerCase();\n if (\n !response.ok ||\n !mime ||\n ![\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/x-icon\",\n \"image/vnd.microsoft.icon\",\n \"image/svg+xml\",\n ].includes(mime) ||\n Number(response.headers.get(\"content-length\")) > 524288\n ) {\n await response.body?.cancel();\n return;\n }\n const reader = response.body?.getReader();\n if (!reader) return;\n const chunks: Uint8Array[] = [];\n let size = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.length;\n if (size > 524288) {\n await reader.cancel();\n return;\n }\n chunks.push(value);\n }\n if (size) publish(`data:${mime};base64,${Buffer.concat(chunks).toString(\"base64\")}`);\n return;\n }\n })()\n .catch(() => {})\n .finally(() => clearTimeout(timeout));\n });\n }\n card.container.setVisible(true);\n const zoom = event.sender.getZoomFactor();\n card.container.setBorderRadius(Math.round(12 * zoom));\n card.view.setBorderRadius(Math.round(12 * zoom));\n const scale = (rect: Rectangle): Rectangle => ({\n x: Math.round(rect.x * zoom),\n y: Math.round(rect.y * zoom),\n width: Math.round(rect.width * zoom),\n height: Math.round(rect.height * zoom),\n });\n card.container.setBounds(scale(clip));\n card.view.setBounds(\n scale({ x: bounds.x - clip.x, y: bounds.y - clip.y, width: bounds.width, height: bounds.height }),\n );\n if (card.url !== configured.url) {\n card.url = configured.url;\n card.favicon = undefined;\n card.faviconRequest?.abort();\n const loading = card;\n loading.failed = false;\n loading.pending = loading.view.webContents.loadURL(configured.url).then(\n () => {\n loading.failed = false;\n },\n () => {\n loading.failed = true;\n },\n );\n }\n if (card.favicon) event.sender.send(\"freelens-power:dashboard-site-icon\", { id: item.id, url: card.favicon });\n }\n for (const [id, card] of owner.cards) {\n if (!cards.some((configured) => configured.id === id)) remove(owner, id);\n else if (!visible.has(id)) card.container.setVisible(false);\n }\n refreshTimers();\n await Promise.all([...owner.cards.values()].map((card) => card.pending));\n return {\n failed: [...owner.cards.entries()].filter(([, card]) => card.failed).map(([id]) => id),\n pinned: [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id),\n };\n });\n const publishPinned = (sender: WebContents, owner: Owner) => {\n if (!sender.isDestroyed())\n sender.send(\n DASHBOARD_VIEWS_PINNED,\n [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id),\n );\n };\n ipcMain.handle(DASHBOARD_VIEWS_PIN, (event, payload: unknown) => {\n if (\n !trusted(event) ||\n !payload ||\n typeof payload !== \"object\" ||\n !(\"id\" in payload) ||\n typeof payload.id !== \"string\" ||\n !((\"pinned\" in payload && typeof payload.pinned === \"boolean\") || (\"focus\" in payload && payload.focus === true))\n )\n return;\n const id = payload.id;\n const owner = owners.get(event.sender);\n const card = owner?.cards.get(payload.id);\n const configured = configuredCards().find((item) => item.id === payload.id);\n if (\n !owner ||\n !card ||\n !configured ||\n card.url !== configured.url ||\n owner.window.isDestroyed() ||\n BrowserWindow.fromWebContents(event.sender) !== owner.window ||\n card.view.webContents.isDestroyed()\n )\n return;\n if (\"focus\" in payload && payload.focus === true) {\n card.floating?.show();\n card.floating?.focus();\n } else if (!(\"pinned\" in payload) || !payload.pinned) {\n card.floating?.close();\n } else if (!card.floating) {\n const floating = new BrowserWindow({\n title: configured.title,\n width: 800,\n height: 600,\n minWidth: 240,\n minHeight: 160,\n resizable: true,\n alwaysOnTop: true,\n autoHideMenuBar: true,\n show: false,\n webPreferences: {\n nodeIntegration: false,\n nodeIntegrationInSubFrames: false,\n contextIsolation: true,\n sandbox: true,\n webSecurity: true,\n partition: \"persist:freelens-power-websites\",\n },\n });\n floating.setMenu(null);\n floating.setAlwaysOnTop(true, \"floating\");\n floating.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });\n card.floating = floating;\n card.container.setVisible(false);\n const contents = floating.webContents;\n contents.setWindowOpenHandler(({ url }) => {\n if (webUrl(url)) void shell.openExternal(url).catch(() => {});\n return { action: \"deny\" };\n });\n const navigation = (event: Electron.Event, url: string) => {\n if (!webUrl(url)) event.preventDefault();\n };\n contents.on(\"will-navigate\", navigation);\n contents.on(\"will-redirect\", navigation);\n contents.on(\"will-frame-navigate\", (event) => {\n if (!webUrl(event.url)) event.preventDefault();\n });\n contents.on(\"page-title-updated\", (event) => event.preventDefault());\n contents.on(\"will-prevent-unload\", (event) => event.preventDefault());\n contents.on(\"did-finish-load\", () => {\n if (contents.isDestroyed()) return;\n void contents.insertCSS(websiteStyles, { cssOrigin: \"user\" }).catch(() => {});\n applySelector({ view: { webContents: contents }, selector: card.selector });\n });\n floating.on(\"closed\", () => {\n if (card.floating !== floating) return;\n card.floating = undefined;\n if (owner.cards.get(id) === card) publishPinned(event.sender, owner);\n });\n void contents.loadURL(configured.url).catch(() => {});\n floating.show();\n }\n publishPinned(event.sender, owner);\n return { pinned: [...owner.cards].filter(([, item]) => item.floating).map(([id]) => id) };\n });\n ipcMain.handle(clearChannel, (event) => {\n if (\n event.senderFrame === event.sender.mainFrame &&\n rendererUrl(event.senderFrame?.url ?? \"\") &&\n rendererUrl(event.sender.getURL())\n )\n hide(event.sender);\n });\n ipcMain.handle(reloadChannel, async (event, payload: unknown) => {\n if (\n !trusted(event) ||\n !payload ||\n typeof payload !== \"object\" ||\n !(\"id\" in payload) ||\n typeof payload.id !== \"string\"\n )\n return;\n const owner = owners.get(event.sender);\n const card = owner?.cards.get(payload.id);\n const configured = sanitizeDashboardCards(\n DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards,\n ).find((item) => item.id === payload.id);\n if (!card || !configured || card.view.webContents.isDestroyed()) return;\n const floating = card.floating?.webContents;\n const current = floating?.getURL();\n const floatingReload =\n floating && !floating.isDestroyed()\n ? floating.loadURL(current && webUrl(current) ? current : configured.url).then(\n () => false,\n () => !floating.isDestroyed(),\n )\n : Promise.resolve(false);\n const [, floatingFailed] = await Promise.all([reload(card, configured.url), floatingReload]);\n card.failed ||= floatingFailed;\n return { failed: card.failed ? [payload.id] : [] };\n });\n return () => {\n stopSettingsReaction();\n ipcMain.removeHandler(DASHBOARD_VIEWS_PIN);\n ipcMain.removeHandler(DASHBOARD_SITE_ICONS);\n ipcMain.removeHandler(syncChannel);\n ipcMain.removeHandler(clearChannel);\n ipcMain.removeHandler(reloadChannel);\n for (const sender of owners.keys()) clear(sender);\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dashboard-views.js","names":[],"sources":["../../src/main/dashboard-views.ts"],"sourcesContent":["// SPDX-License-Identifier: Apache-2.0\nimport { join } from \"node:path\";\nimport {\n app,\n BrowserWindow,\n type IpcMainInvokeEvent,\n ipcMain,\n type Rectangle,\n session,\n shell,\n View,\n type WebContents,\n WebContentsView,\n} from \"electron\";\nimport { reaction } from \"mobx\";\nimport { sanitizeDashboardCards } from \"../common/dashboard\";\nimport { dashboardReadinessScript } from \"../common/dashboard-readiness\";\nimport { dashboardSelectorScript } from \"../common/dashboard-selector\";\nimport {\n DASHBOARD_SITE_ICONS,\n DASHBOARD_VIEWS_LOADING,\n DASHBOARD_VIEWS_PIN,\n DASHBOARD_VIEWS_PINNED,\n type DashboardSiteIcon,\n} from \"../common/dashboard-views\";\nimport { DashboardPreferencesStore } from \"../common/store/dashboard-preferences-store\";\nimport { boundedDashboardIcons, loadDashboardIcons, saveDashboardIcons } from \"./dashboard-icon-cache\";\nimport { observeDashboardNetwork } from \"./dashboard-network\";\n\nconst syncChannel = \"freelens-power:dashboard-views:sync\";\nconst reloadChannel = \"freelens-power:dashboard-views:reload\";\nconst clearChannel = \"freelens-power:dashboard-views:clear\";\nconst dashboardPath = \"/extension/freelens-power/dashboard\";\nconst websiteStyles =\n \"* { scrollbar-width: none !important; } *::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }\";\n\nfunction rendererUrl(value: string, dashboardOnly = false): boolean {\n try {\n const url = new URL(value);\n return (\n url.protocol === \"https:\" &&\n (url.hostname === \"renderer.freelens.app\" || url.hostname.endsWith(\".renderer.freelens.app\")) &&\n (!dashboardOnly || url.pathname === dashboardPath)\n );\n } catch {\n return false;\n }\n}\nfunction dashboardUrl(value: string): boolean {\n return rendererUrl(value, true);\n}\nfunction webUrl(value: string): boolean {\n try {\n return [\"https:\", \"http:\"].includes(new URL(value).protocol);\n } catch {\n return false;\n }\n}\nfunction rectangle(value: unknown): Rectangle | undefined {\n if (!value || typeof value !== \"object\") return;\n const rect = value as Rectangle;\n if (\n ![rect.x, rect.y, rect.width, rect.height].every(\n (n) => Number.isFinite(n) && Number.isInteger(n) && Math.abs(n) <= 32768,\n ) ||\n rect.width <= 0 ||\n rect.height <= 0\n )\n return;\n return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };\n}\n\ntype CardView = {\n container: View;\n view: WebContentsView;\n url: string;\n failed: boolean;\n loading: boolean;\n visible: boolean;\n generation: number;\n stopPreparation?: () => void;\n selector?: string;\n pending?: Promise<void>;\n favicon?: string;\n faviconRequest?: AbortController;\n refreshTimer?: ReturnType<typeof setInterval>;\n floating?: BrowserWindow;\n};\ntype Owner = { window: BrowserWindow; cards: Map<string, CardView>; cleanup: () => void };\n\nexport function startDashboardViews(): () => void {\n const websiteSession = session.fromPartition(\"persist:freelens-power-websites\");\n websiteSession.setPermissionRequestHandler((_contents, _permission, callback) => callback(false));\n websiteSession.setPermissionCheckHandler(() => false);\n const owners = new Map<WebContents, Owner>();\n const icons = new Map<string, DashboardSiteIcon>();\n const remove = (owner: Owner, id: string) => {\n const card = owner.cards.get(id);\n if (!card) return;\n owner.cards.delete(id);\n card.stopPreparation?.();\n card.faviconRequest?.abort();\n clearInterval(card.refreshTimer);\n card.floating?.destroy();\n card.floating = undefined;\n if (!owner.window.isDestroyed()) owner.window.contentView.removeChildView(card.container);\n if (!card.view.webContents.isDestroyed()) card.view.webContents.close();\n };\n const clear = (sender: WebContents) => {\n const owner = owners.get(sender);\n if (!owner) return;\n owners.delete(sender);\n for (const id of owner.cards.keys()) remove(owner, id);\n owner.cleanup();\n };\n const hide = (sender: WebContents) => {\n for (const card of owners.get(sender)?.cards.values() ?? []) {\n card.visible = false;\n card.container.setVisible(false);\n }\n };\n const configuredCards = () =>\n sanitizeDashboardCards(DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards);\n const cachePath = join(app.getPath(\"userData\"), \"freelens-power\", \"dashboard-icons.json\");\n const ready = loadDashboardIcons(cachePath).then((saved) => {\n const configured = configuredCards();\n for (const icon of saved) {\n if (!icons.has(icon.id) && configured.some((card) => card.id === icon.id && card.url === icon.pageUrl))\n icons.set(icon.id, icon);\n }\n });\n let writes = ready;\n const persistIcons = () => {\n writes = writes\n .then(async () => {\n const configured = configuredCards();\n const bounded = boundedDashboardIcons(\n [...icons.values()].filter((icon) =>\n configured.some((card) => card.id === icon.id && card.url === icon.pageUrl),\n ),\n );\n icons.clear();\n for (const icon of bounded) icons.set(icon.id, icon);\n await saveDashboardIcons(cachePath, bounded);\n })\n .catch(() => {});\n };\n persistIcons();\n const publishLoading = (card: CardView) => {\n for (const [sender, owner] of owners) {\n const id = [...owner.cards].find(([, candidate]) => candidate === card)?.[0];\n if (\n !id ||\n sender.isDestroyed() ||\n !dashboardUrl(sender.mainFrame.url) ||\n !dashboardUrl(sender.getURL()) ||\n !configuredCards().some((configured) => configured.id === id && configured.url === card.url)\n )\n continue;\n sender.send(DASHBOARD_VIEWS_LOADING, { id, url: card.url, loading: card.loading, failed: card.failed });\n }\n };\n const reload = (card: CardView, configuredUrl: string, initial = false) => {\n const current = card.view.webContents.getURL();\n const target = !initial && card.url === configuredUrl && webUrl(current) ? current : configuredUrl;\n card.faviconRequest?.abort();\n card.url = configuredUrl;\n card.failed = false;\n card.loading = true;\n card.stopPreparation?.();\n const contents = card.view.webContents;\n const backgroundThrottling = contents.getBackgroundThrottling();\n if (backgroundThrottling) contents.setBackgroundThrottling(false);\n const network = observeDashboardNetwork(card.view.webContents);\n let stopped = false;\n const stopPreparation = () => {\n if (stopped) return;\n stopped = true;\n network.dispose();\n contents.removeListener(\"destroyed\", stopPreparation);\n if (!contents.isDestroyed() && backgroundThrottling && !contents.getBackgroundThrottling())\n contents.setBackgroundThrottling(backgroundThrottling);\n if (card.stopPreparation === stopPreparation) card.stopPreparation = undefined;\n };\n card.stopPreparation = stopPreparation;\n contents.once(\"destroyed\", stopPreparation);\n const generation = ++card.generation;\n card.container.setVisible(false);\n publishLoading(card);\n const settled = (failed: boolean) => {\n if (card.generation !== generation || card.view.webContents.isDestroyed()) return;\n card.failed = failed;\n card.loading = false;\n for (const [sender, owner] of owners) {\n if (![...owner.cards.values()].includes(card)) continue;\n card.container.setVisible(card.visible && !card.floating && !failed && dashboardUrl(sender.getURL()));\n }\n publishLoading(card);\n };\n const load = () => {\n if (\n card.generation !== generation ||\n card.view.webContents.isDestroyed() ||\n ![...owners.values()].some((owner) => [...owner.cards.values()].includes(card))\n )\n return Promise.resolve();\n return card.view.webContents.loadURL(target);\n };\n card.pending = load().then(\n async () => {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let preparing = true;\n const current = () =>\n preparing &&\n card.generation === generation &&\n !card.view.webContents.isDestroyed() &&\n [...owners.values()].some((owner) => [...owner.cards.values()].includes(card));\n try {\n await Promise.race([\n (async () => {\n if (!current()) return;\n await network.ready();\n if (!current()) return;\n await applySelector(card);\n do {\n await network.wait();\n if (!current()) return;\n await card.view.webContents.executeJavaScriptInIsolatedWorld(1004, [\n { code: dashboardReadinessScript(card.selector) },\n ]);\n } while (current() && !network.quiet());\n })().catch(() => new Promise<void>((resolve) => setTimeout(resolve, 200))),\n new Promise<void>((resolve) => {\n deadline = setTimeout(resolve, 8500);\n }),\n ]);\n } finally {\n clearTimeout(deadline);\n preparing = false;\n stopPreparation();\n }\n settled(false);\n },\n () => {\n stopPreparation();\n settled(true);\n },\n );\n return card.pending;\n };\n const applySelector = (card: { view: { webContents: WebContents }; selector?: string }) => {\n if (card.view.webContents.isDestroyed()) return Promise.resolve();\n return card.view.webContents\n .executeJavaScriptInIsolatedWorld(1004, [{ code: dashboardSelectorScript(card.selector) }])\n .catch(() => {});\n };\n const refreshTimers = () => {\n const configured = configuredCards();\n for (const [id, icon] of icons) {\n if (!configured.some((card) => card.id === id && card.url === icon.pageUrl)) {\n icons.delete(id);\n persistIcons();\n }\n }\n for (const [sender, owner] of owners) {\n for (const [id, card] of owner.cards) {\n const setting = configured.find((item) => item.id === id);\n if (!setting || setting.url !== card.url) {\n remove(owner, id);\n continue;\n }\n if (card.selector !== setting.selector) {\n card.selector = setting.selector;\n applySelector(card);\n if (card.floating && !card.floating.isDestroyed())\n applySelector({ view: { webContents: card.floating.webContents }, selector: card.selector });\n }\n if (card.floating && !card.floating.isDestroyed()) card.floating.setTitle(setting.title);\n if (!setting.autoRefresh) {\n clearInterval(card.refreshTimer);\n card.refreshTimer = undefined;\n continue;\n }\n if (card.refreshTimer) continue;\n card.refreshTimer = setInterval(() => {\n const latest = configuredCards().find((item) => item.id === id);\n if (\n owners.get(sender) !== owner ||\n card.floating ||\n dashboardUrl(sender.getURL()) ||\n owner.cards.get(id) !== card ||\n !latest?.autoRefresh ||\n latest.url !== card.url ||\n card.view.webContents.isDestroyed() ||\n card.view.webContents.isLoading()\n )\n return;\n void reload(card, latest.url);\n }, 600000);\n }\n }\n };\n const stopSettingsReaction = reaction(\n () =>\n JSON.stringify(\n configuredCards().map(({ id, title, url, autoRefresh, selector }) => ({\n id,\n title,\n url,\n autoRefresh,\n selector,\n })),\n ),\n refreshTimers,\n );\n const trusted = (event: IpcMainInvokeEvent) =>\n event.senderFrame === event.sender.mainFrame &&\n dashboardUrl(event.senderFrame?.url ?? \"\") &&\n dashboardUrl(event.sender.getURL());\n ipcMain.handle(DASHBOARD_SITE_ICONS, async (event) => {\n if (\n event.senderFrame !== event.sender.mainFrame ||\n !rendererUrl(event.senderFrame?.url ?? \"\") ||\n !rendererUrl(event.sender.getURL()) ||\n !BrowserWindow.fromWebContents(event.sender)\n )\n return [];\n await ready;\n return configuredCards().flatMap((card) => {\n const icon = icons.get(card.id);\n return icon?.pageUrl === card.url ? [icon] : [];\n });\n });\n ipcMain.handle(syncChannel, async (event, payload: unknown) => {\n if (!trusted(event)) return;\n const window = BrowserWindow.fromWebContents(event.sender);\n if (!window || window.isDestroyed()) return;\n const requested =\n payload && typeof payload === \"object\" && \"cards\" in payload && Array.isArray(payload.cards) ? payload.cards : [];\n const cards = sanitizeDashboardCards(\n DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards,\n );\n let owner = owners.get(event.sender);\n if (!owner) {\n const sender = event.sender;\n const navigation = (_event: unknown, url: string) => {\n if (!dashboardUrl(url)) hide(sender);\n };\n const destroyed = () => clear(sender);\n sender.on(\"did-navigate\", navigation);\n sender.on(\"did-navigate-in-page\", navigation);\n sender.on(\"destroyed\", destroyed);\n owner = {\n window,\n cards: new Map(),\n cleanup: () => {\n sender.removeListener(\"did-navigate\", navigation);\n sender.removeListener(\"did-navigate-in-page\", navigation);\n sender.removeListener(\"destroyed\", destroyed);\n },\n };\n owners.set(sender, owner);\n }\n if (payload && typeof payload === \"object\" && \"hidden\" in payload && payload.hidden === true) {\n hide(event.sender);\n return { failed: [], pinned: [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id) };\n }\n const visible = new Set<string>();\n for (const item of requested.slice(0, cards.length)) {\n if (!item || typeof item !== \"object\" || typeof item.id !== \"string\" || visible.has(item.id)) continue;\n const configured = cards.find((card) => card.id === item.id);\n const bounds = rectangle(item.bounds);\n const clip = rectangle(item.clip);\n if (\n !configured ||\n !bounds ||\n !clip ||\n clip.x < bounds.x ||\n clip.y < bounds.y ||\n clip.x + clip.width > bounds.x + bounds.width ||\n clip.y + clip.height > bounds.y + bounds.height\n )\n continue;\n visible.add(item.id);\n let card = owner.cards.get(item.id);\n if (card?.floating) {\n card.visible = false;\n card.container.setVisible(false);\n continue;\n }\n if (!card) {\n const container = new View();\n container.setBackgroundColor(\"#00000000\");\n const view = new WebContentsView({\n webPreferences: {\n nodeIntegration: false,\n nodeIntegrationInSubFrames: false,\n contextIsolation: true,\n sandbox: true,\n webSecurity: true,\n partition: \"persist:freelens-power-websites\",\n },\n });\n view.setBackgroundColor(\"#00000000\");\n view.webContents.on(\"did-finish-load\", () => {\n if (!view.webContents.isDestroyed())\n void view.webContents.insertCSS(websiteStyles, { cssOrigin: \"user\" }).catch(() => {});\n });\n view.webContents.setWindowOpenHandler(({ url }) => {\n if (webUrl(url)) void shell.openExternal(url).catch(() => {});\n return { action: \"deny\" };\n });\n const navigation = (event: Electron.Event, url: string) => {\n if (!webUrl(url)) event.preventDefault();\n };\n view.webContents.on(\"will-navigate\", navigation);\n view.webContents.on(\"will-redirect\", navigation);\n view.webContents.on(\"will-frame-navigate\", (event) => {\n if (!webUrl(event.url)) event.preventDefault();\n });\n container.addChildView(view);\n window.contentView.addChildView(container);\n card = { container, view, url: \"\", failed: false, loading: false, visible: false, generation: 0 };\n owner.cards.set(item.id, card);\n const created = card;\n view.webContents.on(\"before-input-event\", (_event, input: Electron.Input) => {\n if (\n input.type !== \"keyDown\" ||\n input.key !== \"Escape\" ||\n owners.get(event.sender) !== owner ||\n owner.cards.get(item.id) !== created ||\n !trusted(event)\n )\n return;\n event.sender.send(\"freelens-power:dashboard-escape\");\n });\n created.selector = configured.selector;\n view.webContents.on(\"did-finish-load\", () => applySelector(created));\n view.webContents.on(\"page-favicon-updated\", (_event, favicons: string[]) => {\n const favicon = favicons.find((value) => {\n if (!webUrl(value)) return false;\n const parsed = new URL(value);\n return !parsed.username && !parsed.password;\n });\n if (!favicon || owners.get(event.sender) !== owner || owner.cards.get(item.id) !== created) return;\n created.faviconRequest?.abort();\n const request = new AbortController();\n created.faviconRequest = request;\n created.favicon = favicon;\n const publish = (url: string) => {\n if (\n request.signal.aborted ||\n owners.get(event.sender) !== owner ||\n owner.cards.get(item.id) !== created ||\n event.senderFrame !== event.sender.mainFrame\n )\n return;\n created.favicon = url;\n if (\n url.startsWith(\"data:\") &&\n configuredCards().some((card) => card.id === item.id && card.url === created.url)\n ) {\n icons.set(item.id, { id: item.id, pageUrl: created.url, dataUrl: url });\n persistIcons();\n if (rendererUrl(event.senderFrame?.url ?? \"\") && rendererUrl(event.sender.getURL()))\n event.sender.send(DASHBOARD_SITE_ICONS);\n }\n if (!trusted(event)) return;\n event.sender.send(\"freelens-power:dashboard-site-icon\", { id: item.id, url });\n };\n publish(favicon);\n const timeout = setTimeout(() => request.abort(), 5000);\n void (async () => {\n let current = favicon;\n for (let redirects = 0; redirects <= 5; redirects++) {\n const response = await websiteSession.fetch(current, {\n signal: request.signal,\n redirect: \"manual\",\n credentials: \"include\",\n });\n if (response.status >= 300 && response.status < 400) {\n await response.body?.cancel();\n const location = response.headers.get(\"location\");\n if (!location) return;\n const next = new URL(location, current);\n if (!webUrl(next.href) || next.username || next.password) return;\n current = next.href;\n continue;\n }\n const mime = response.headers.get(\"content-type\")?.split(\";\")[0].trim().toLowerCase();\n if (\n !response.ok ||\n !mime ||\n ![\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n \"image/x-icon\",\n \"image/vnd.microsoft.icon\",\n \"image/svg+xml\",\n ].includes(mime) ||\n Number(response.headers.get(\"content-length\")) > 524288\n ) {\n await response.body?.cancel();\n return;\n }\n const reader = response.body?.getReader();\n if (!reader) return;\n const chunks: Uint8Array[] = [];\n let size = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.length;\n if (size > 524288) {\n await reader.cancel();\n return;\n }\n chunks.push(value);\n }\n if (size) publish(`data:${mime};base64,${Buffer.concat(chunks).toString(\"base64\")}`);\n return;\n }\n })()\n .catch(() => {})\n .finally(() => clearTimeout(timeout));\n });\n }\n card.visible = true;\n card.container.setVisible(!card.loading && !card.failed && card.url === configured.url);\n const zoom = event.sender.getZoomFactor();\n card.container.setBorderRadius(Math.round(12 * zoom));\n card.view.setBorderRadius(Math.round(12 * zoom));\n const scale = (rect: Rectangle): Rectangle => ({\n x: Math.round(rect.x * zoom),\n y: Math.round(rect.y * zoom),\n width: Math.round(rect.width * zoom),\n height: Math.round(rect.height * zoom),\n });\n card.container.setBounds(scale(clip));\n card.view.setBounds(\n scale({ x: bounds.x - clip.x, y: bounds.y - clip.y, width: bounds.width, height: bounds.height }),\n );\n if (card.url !== configured.url) {\n card.favicon = undefined;\n card.faviconRequest?.abort();\n void reload(card, configured.url, true);\n }\n publishLoading(card);\n if (card.favicon) event.sender.send(\"freelens-power:dashboard-site-icon\", { id: item.id, url: card.favicon });\n }\n for (const [id, card] of owner.cards) {\n if (!cards.some((configured) => configured.id === id)) remove(owner, id);\n else if (!visible.has(id)) {\n card.visible = false;\n card.container.setVisible(false);\n }\n }\n refreshTimers();\n await Promise.all([...owner.cards.values()].map((card) => card.pending));\n return {\n failed: [...owner.cards.entries()].filter(([, card]) => card.failed).map(([id]) => id),\n pinned: [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id),\n };\n });\n const publishPinned = (sender: WebContents, owner: Owner) => {\n if (!sender.isDestroyed())\n sender.send(\n DASHBOARD_VIEWS_PINNED,\n [...owner.cards].filter(([, card]) => card.floating).map(([id]) => id),\n );\n };\n ipcMain.handle(DASHBOARD_VIEWS_PIN, (event, payload: unknown) => {\n if (\n !trusted(event) ||\n !payload ||\n typeof payload !== \"object\" ||\n !(\"id\" in payload) ||\n typeof payload.id !== \"string\" ||\n !((\"pinned\" in payload && typeof payload.pinned === \"boolean\") || (\"focus\" in payload && payload.focus === true))\n )\n return;\n const id = payload.id;\n const owner = owners.get(event.sender);\n const card = owner?.cards.get(payload.id);\n const configured = configuredCards().find((item) => item.id === payload.id);\n if (\n !owner ||\n !card ||\n !configured ||\n card.url !== configured.url ||\n owner.window.isDestroyed() ||\n BrowserWindow.fromWebContents(event.sender) !== owner.window ||\n card.view.webContents.isDestroyed()\n )\n return;\n if (\"focus\" in payload && payload.focus === true) {\n card.floating?.show();\n card.floating?.focus();\n } else if (!(\"pinned\" in payload) || !payload.pinned) {\n card.floating?.close();\n } else if (!card.floating) {\n const floating = new BrowserWindow({\n title: configured.title,\n width: 800,\n height: 600,\n minWidth: 240,\n minHeight: 160,\n resizable: true,\n alwaysOnTop: true,\n autoHideMenuBar: true,\n show: false,\n webPreferences: {\n nodeIntegration: false,\n nodeIntegrationInSubFrames: false,\n contextIsolation: true,\n sandbox: true,\n webSecurity: true,\n partition: \"persist:freelens-power-websites\",\n },\n });\n floating.setMenu(null);\n floating.setAlwaysOnTop(true, \"floating\");\n floating.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });\n card.floating = floating;\n card.container.setVisible(false);\n const contents = floating.webContents;\n contents.setWindowOpenHandler(({ url }) => {\n if (webUrl(url)) void shell.openExternal(url).catch(() => {});\n return { action: \"deny\" };\n });\n const navigation = (event: Electron.Event, url: string) => {\n if (!webUrl(url)) event.preventDefault();\n };\n contents.on(\"will-navigate\", navigation);\n contents.on(\"will-redirect\", navigation);\n contents.on(\"will-frame-navigate\", (event) => {\n if (!webUrl(event.url)) event.preventDefault();\n });\n contents.on(\"page-title-updated\", (event) => event.preventDefault());\n contents.on(\"will-prevent-unload\", (event) => event.preventDefault());\n contents.on(\"did-finish-load\", () => {\n if (contents.isDestroyed()) return;\n void contents.insertCSS(websiteStyles, { cssOrigin: \"user\" }).catch(() => {});\n applySelector({ view: { webContents: contents }, selector: card.selector });\n });\n floating.on(\"closed\", () => {\n if (card.floating !== floating) return;\n card.floating = undefined;\n if (owner.cards.get(id) === card) publishPinned(event.sender, owner);\n });\n void contents.loadURL(configured.url).catch(() => {});\n floating.show();\n }\n publishPinned(event.sender, owner);\n return { pinned: [...owner.cards].filter(([, item]) => item.floating).map(([id]) => id) };\n });\n ipcMain.handle(clearChannel, (event) => {\n if (\n event.senderFrame === event.sender.mainFrame &&\n rendererUrl(event.senderFrame?.url ?? \"\") &&\n rendererUrl(event.sender.getURL())\n )\n hide(event.sender);\n });\n ipcMain.handle(reloadChannel, async (event, payload: unknown) => {\n if (\n !trusted(event) ||\n !payload ||\n typeof payload !== \"object\" ||\n !(\"id\" in payload) ||\n typeof payload.id !== \"string\"\n )\n return;\n const owner = owners.get(event.sender);\n const card = owner?.cards.get(payload.id);\n const configured = sanitizeDashboardCards(\n DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>().cards,\n ).find((item) => item.id === payload.id);\n if (!card || !configured || card.view.webContents.isDestroyed()) return;\n const floating = card.floating?.webContents;\n const current = floating?.getURL();\n const floatingReload =\n floating && !floating.isDestroyed()\n ? floating.loadURL(current && webUrl(current) ? current : configured.url).then(\n () => false,\n () => !floating.isDestroyed(),\n )\n : Promise.resolve(false);\n const [, floatingFailed] = await Promise.all([reload(card, configured.url), floatingReload]);\n return { failed: card.failed || floatingFailed ? [payload.id] : [] };\n });\n return () => {\n stopSettingsReaction();\n ipcMain.removeHandler(DASHBOARD_VIEWS_PIN);\n ipcMain.removeHandler(DASHBOARD_SITE_ICONS);\n ipcMain.removeHandler(syncChannel);\n ipcMain.removeHandler(clearChannel);\n ipcMain.removeHandler(reloadChannel);\n for (const sender of owners.keys()) clear(sender);\n };\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ const require_extensions = require("./_virtual/_global-external_@freelensapp/ext
|
|
|
2
2
|
const require_ai_extras = require("./src/common/ai-extras.js");
|
|
3
3
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
4
4
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
5
|
+
const require_ai_icon = require("./ai-icon.js");
|
|
5
6
|
//#region src/renderer/ai-extras.tsx
|
|
6
7
|
function AiContextPreview({ context }) {
|
|
7
8
|
return /* @__PURE__ */ require_jsx_runtime.jsxs("details", {
|
|
@@ -11,7 +12,10 @@ function AiContextPreview({ context }) {
|
|
|
11
12
|
fontSize: 11
|
|
12
13
|
},
|
|
13
14
|
children: [
|
|
14
|
-
/* @__PURE__ */ require_jsx_runtime.jsx("summary", {
|
|
15
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("summary", {
|
|
16
|
+
title: "Show the screen and resource metadata attached to your next message",
|
|
17
|
+
children: "Attached context"
|
|
18
|
+
}),
|
|
15
19
|
/* @__PURE__ */ require_jsx_runtime.jsx("pre", {
|
|
16
20
|
style: {
|
|
17
21
|
whiteSpace: "pre-wrap",
|
|
@@ -33,19 +37,20 @@ async function openAiResourceReference(clusterId, reference) {
|
|
|
33
37
|
name: reference.name,
|
|
34
38
|
namespace: reference.namespace
|
|
35
39
|
}) || require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) throw new Error("Resource details are unavailable");
|
|
36
|
-
require_extensions.Renderer.Navigation.showDetails(api.getUrl({
|
|
40
|
+
await require_extensions.Renderer.Navigation.showDetails(api.getUrl({
|
|
37
41
|
name: reference.name,
|
|
38
42
|
namespace: reference.namespace
|
|
39
43
|
}));
|
|
40
44
|
}
|
|
41
|
-
function AiResourceReferences({ clusterId, references }) {
|
|
45
|
+
function AiResourceReferences({ clusterId, references, text, onOpened }) {
|
|
42
46
|
const [error, setError] = require__global_external_react.useState("");
|
|
43
|
-
const items = require_ai_extras.
|
|
47
|
+
const items = require_ai_extras.referencedAiResources(text, references);
|
|
44
48
|
if (!items.length) return null;
|
|
45
49
|
return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
46
50
|
className: "power-ai-resource-references",
|
|
47
51
|
style: { marginTop: 12 },
|
|
48
52
|
children: [
|
|
53
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: `.power-ai-resource-references button.power-ai-resource-reference:hover { color: var(--primary); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, var(--contentColor)); } .power-ai-resource-references button.power-ai-resource-reference:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }` }),
|
|
49
54
|
/* @__PURE__ */ require_jsx_runtime.jsx("span", {
|
|
50
55
|
style: {
|
|
51
56
|
fontSize: 11,
|
|
@@ -62,17 +67,41 @@ function AiResourceReferences({ clusterId, references }) {
|
|
|
62
67
|
},
|
|
63
68
|
children: items.map((reference) => /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
|
|
64
69
|
type: "button",
|
|
65
|
-
|
|
70
|
+
className: "power-ai-resource-reference",
|
|
71
|
+
style: {
|
|
72
|
+
display: "inline-flex",
|
|
73
|
+
alignItems: "center",
|
|
74
|
+
gap: 6,
|
|
75
|
+
maxWidth: "100%",
|
|
76
|
+
minWidth: 0,
|
|
77
|
+
padding: "4px 8px",
|
|
78
|
+
fontSize: 12,
|
|
79
|
+
lineHeight: 1.4,
|
|
80
|
+
border: "1px solid var(--borderFaintColor)",
|
|
81
|
+
borderRadius: 6
|
|
82
|
+
},
|
|
83
|
+
title: `Open ${reference.kind}/${reference.name} details · ${reference.namespace ?? "cluster scoped"}`,
|
|
66
84
|
onClick: () => {
|
|
67
85
|
setError("");
|
|
68
|
-
openAiResourceReference(clusterId, reference).catch(() => setError("Unable to open this resource. Check the selected cluster and your access."));
|
|
86
|
+
openAiResourceReference(clusterId, reference).then(onOpened).catch(() => setError("Unable to open this resource. Check the selected cluster and your access."));
|
|
69
87
|
},
|
|
70
|
-
children: [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
89
|
+
style: {
|
|
90
|
+
minWidth: 0,
|
|
91
|
+
overflow: "hidden",
|
|
92
|
+
textOverflow: "ellipsis",
|
|
93
|
+
whiteSpace: "nowrap"
|
|
94
|
+
},
|
|
95
|
+
children: [
|
|
96
|
+
reference.kind,
|
|
97
|
+
"/",
|
|
98
|
+
reference.name,
|
|
99
|
+
reference.namespace ? ` · ${reference.namespace}` : ""
|
|
100
|
+
]
|
|
101
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
|
|
102
|
+
material: "arrow_forward",
|
|
103
|
+
size: 14
|
|
104
|
+
})]
|
|
76
105
|
}, JSON.stringify(reference)))
|
|
77
106
|
}),
|
|
78
107
|
error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
|