@monkey-mini-app/panel 0.1.1 → 0.1.4
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/dist/{chunk-X3QW77RD.js → chunk-JAWSEXOV.js} +36 -5
- package/dist/index.cjs +1916 -595
- package/dist/index.d.cts +127 -3
- package/dist/index.d.ts +127 -3
- package/dist/index.js +1451 -169
- package/dist/themes.cjs +41 -4
- package/dist/themes.d.cts +22 -1
- package/dist/themes.d.ts +22 -1
- package/dist/themes.js +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { __publicField, applyThemeTo, clampPalette, PALETTES } from './chunk-
|
|
2
|
-
export { PALETTES, applyThemeTo, clampMode, clampPalette, cssVars, parseThemeCss, runnerThemeCss, themeLabelFromCss, tokensOf } from './chunk-
|
|
3
|
-
import * as
|
|
1
|
+
import { __publicField, applyThemeTo, clampPalette, resolveMode, PALETTES, selectedPalette, GLOBAL_PALETTE_ID, LOCAL_PALETTE_ID, effectivePalette, themeCssVars, parseThemeCss, themeLabelFromCss, tokensOf } from './chunk-JAWSEXOV.js';
|
|
2
|
+
export { GLOBAL_PALETTE_ID, LOCAL_PALETTE_ID, PALETTES, applyThemeTo, clampMode, clampPalette, cssVars, effectivePalette, parseThemeCss, resolveMode, runnerThemeCss, selectedPalette, themeCssVars, themeLabelFromCss, tokensOf } from './chunk-JAWSEXOV.js';
|
|
3
|
+
import * as React4 from 'react';
|
|
4
4
|
import { useSyncExternalStore } from 'react';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
import { RefreshCw, LayoutGrid, Clock, Database, Settings as Settings$1, PanelRight, X } from 'lucide-react';
|
|
@@ -48,7 +48,113 @@ function isHostUnreachable(e) {
|
|
|
48
48
|
return e instanceof HostUnreachableError;
|
|
49
49
|
}
|
|
50
50
|
function appFrameUrl(origin, appId, query) {
|
|
51
|
-
|
|
51
|
+
const params = new URLSearchParams();
|
|
52
|
+
for (const key of ["theme", "palette", "dock"]) {
|
|
53
|
+
const value = query[key];
|
|
54
|
+
if (value) params.set(key, value);
|
|
55
|
+
}
|
|
56
|
+
return `${origin}/app/${encodeURIComponent(appId)}?${params.toString()}`;
|
|
57
|
+
}
|
|
58
|
+
function relayViewEval(origin, frames, query) {
|
|
59
|
+
if (!query.requestId || !query.appId) return;
|
|
60
|
+
if (frames.postViewEval(query)) return;
|
|
61
|
+
const body = { appId: query.appId, requestId: query.requestId, view: "not-open" };
|
|
62
|
+
fetch(`${origin.replace(/\/$/, "")}/api/app/${encodeURIComponent(query.appId)}/view/eval`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { "content-type": "application/json" },
|
|
65
|
+
body: JSON.stringify(body)
|
|
66
|
+
}).catch(() => {
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function subscribeHostEvents(origin, handlers) {
|
|
70
|
+
if (typeof EventSource === "undefined") return () => {
|
|
71
|
+
};
|
|
72
|
+
let es = null;
|
|
73
|
+
const listen = (fn) => {
|
|
74
|
+
return (raw) => {
|
|
75
|
+
const e = raw;
|
|
76
|
+
let data;
|
|
77
|
+
try {
|
|
78
|
+
data = JSON.parse(e.data || "{}");
|
|
79
|
+
} catch {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!data || typeof data !== "object") return;
|
|
83
|
+
fn(data);
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
es = new EventSource(`${origin.replace(/\/$/, "")}/api/events`);
|
|
88
|
+
es.addEventListener(
|
|
89
|
+
"app:open",
|
|
90
|
+
listen((d) => {
|
|
91
|
+
if (typeof d.appId === "string") handlers.onOpen?.(d.appId, typeof d.title === "string" ? d.title : void 0);
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
es.addEventListener(
|
|
95
|
+
"app:reload",
|
|
96
|
+
listen((d) => {
|
|
97
|
+
if (typeof d.appId === "string") handlers.onReload?.(d.appId);
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
es.addEventListener(
|
|
101
|
+
"app:eval",
|
|
102
|
+
listen((d) => {
|
|
103
|
+
if (typeof d.requestId !== "string" || typeof d.appId !== "string") return;
|
|
104
|
+
handlers.onEval?.({
|
|
105
|
+
requestId: d.requestId,
|
|
106
|
+
appId: d.appId,
|
|
107
|
+
code: typeof d.code === "string" ? d.code : "",
|
|
108
|
+
maxBytes: typeof d.maxBytes === "number" ? d.maxBytes : 0
|
|
109
|
+
});
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
es.addEventListener(
|
|
113
|
+
"app:storage-notice",
|
|
114
|
+
listen((d) => {
|
|
115
|
+
if (typeof d.appId !== "string" || typeof d.table !== "string" || typeof d.prompt !== "string") return;
|
|
116
|
+
const heavyRaw = Array.isArray(d.heavy) ? d.heavy : [];
|
|
117
|
+
const heavy = heavyRaw.flatMap((h) => {
|
|
118
|
+
if (!isRecord(h) || typeof h.key !== "string" || typeof h.bytes !== "number") return [];
|
|
119
|
+
const kind = h.kind === "list" || h.kind === "map" || h.kind === "value" ? h.kind : "value";
|
|
120
|
+
return [{
|
|
121
|
+
key: h.key,
|
|
122
|
+
bytes: h.bytes,
|
|
123
|
+
kind,
|
|
124
|
+
entries: typeof h.entries === "number" ? h.entries : void 0
|
|
125
|
+
}];
|
|
126
|
+
});
|
|
127
|
+
handlers.onStorageNotice?.({
|
|
128
|
+
appId: d.appId,
|
|
129
|
+
table: d.table,
|
|
130
|
+
bytes: typeof d.bytes === "number" ? d.bytes : 0,
|
|
131
|
+
keys: typeof d.keys === "number" ? d.keys : 0,
|
|
132
|
+
heavy,
|
|
133
|
+
prompt: d.prompt
|
|
134
|
+
});
|
|
135
|
+
})
|
|
136
|
+
);
|
|
137
|
+
} catch {
|
|
138
|
+
return () => {
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return () => {
|
|
142
|
+
try {
|
|
143
|
+
es?.close();
|
|
144
|
+
} catch {
|
|
145
|
+
}
|
|
146
|
+
es = null;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function parseLocalPalette(css) {
|
|
150
|
+
if (typeof css !== "string" || !css.trim()) return null;
|
|
151
|
+
const tokens = parseThemeCss(css, LOCAL_PALETTE_ID);
|
|
152
|
+
if (!tokens) return null;
|
|
153
|
+
return {
|
|
154
|
+
label: themeLabelFromCss(css, LOCAL_PALETTE_ID),
|
|
155
|
+
swatch: tokens.dark.primary || tokens.light.primary,
|
|
156
|
+
tokens
|
|
157
|
+
};
|
|
52
158
|
}
|
|
53
159
|
function parseAppTheme(raw) {
|
|
54
160
|
if (raw === null) return null;
|
|
@@ -58,6 +164,31 @@ function parseAppTheme(raw) {
|
|
|
58
164
|
if (!theme && !palette) return null;
|
|
59
165
|
return { theme, palette };
|
|
60
166
|
}
|
|
167
|
+
function parseAbout(raw) {
|
|
168
|
+
const rec = isRecord(raw) ? raw : {};
|
|
169
|
+
const packages = [];
|
|
170
|
+
if (Array.isArray(rec.packages)) {
|
|
171
|
+
for (const p of rec.packages) {
|
|
172
|
+
if (!isRecord(p) || typeof p.name !== "string" || typeof p.version !== "string") continue;
|
|
173
|
+
packages.push({ name: p.name, version: p.version });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
adapter: typeof rec.adapter === "string" ? rec.adapter : "host",
|
|
178
|
+
env: typeof rec.env === "string" ? rec.env : "unknown",
|
|
179
|
+
packages
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function parseUpdateCheck(raw) {
|
|
183
|
+
const rec = isRecord(raw) ? raw : {};
|
|
184
|
+
return {
|
|
185
|
+
name: typeof rec.name === "string" ? rec.name : "",
|
|
186
|
+
current: typeof rec.current === "string" ? rec.current : "",
|
|
187
|
+
latest: typeof rec.latest === "string" ? rec.latest : null,
|
|
188
|
+
updateAvailable: rec.updateAvailable === true,
|
|
189
|
+
error: typeof rec.error === "string" ? rec.error : void 0
|
|
190
|
+
};
|
|
191
|
+
}
|
|
61
192
|
function parseAppsResponse(raw) {
|
|
62
193
|
if (!isRecord(raw) || !Array.isArray(raw.apps)) return [];
|
|
63
194
|
const out = [];
|
|
@@ -70,7 +201,8 @@ function parseAppsResponse(raw) {
|
|
|
70
201
|
acronym: typeof item.acronym === "string" ? item.acronym : void 0,
|
|
71
202
|
commits: typeof item.commits === "number" ? item.commits : void 0,
|
|
72
203
|
version: typeof item.version === "string" ? item.version : void 0,
|
|
73
|
-
theme: parseAppTheme(item.theme)
|
|
204
|
+
theme: parseAppTheme(item.theme),
|
|
205
|
+
localPalette: parseLocalPalette(item.localThemeCss)
|
|
74
206
|
});
|
|
75
207
|
}
|
|
76
208
|
return out;
|
|
@@ -129,7 +261,36 @@ function parseStorageTables(raw) {
|
|
|
129
261
|
out.push({
|
|
130
262
|
name: row.name,
|
|
131
263
|
size: typeof row.size === "number" ? row.size : void 0,
|
|
132
|
-
updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : void 0
|
|
264
|
+
updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : void 0,
|
|
265
|
+
keys: typeof row.keys === "number" ? row.keys : void 0
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
function parseStorageNotices(raw, appId) {
|
|
271
|
+
const rec = isRecord(raw) ? raw : {};
|
|
272
|
+
const list = Array.isArray(rec.notices) ? rec.notices : [];
|
|
273
|
+
const out = [];
|
|
274
|
+
for (const row of list) {
|
|
275
|
+
if (!isRecord(row) || typeof row.table !== "string" || typeof row.prompt !== "string") continue;
|
|
276
|
+
const heavyRaw = Array.isArray(row.heavy) ? row.heavy : [];
|
|
277
|
+
const heavy = heavyRaw.flatMap((h) => {
|
|
278
|
+
if (!isRecord(h) || typeof h.key !== "string" || typeof h.bytes !== "number") return [];
|
|
279
|
+
const kind = h.kind === "list" || h.kind === "map" || h.kind === "value" ? h.kind : "value";
|
|
280
|
+
return [{
|
|
281
|
+
key: h.key,
|
|
282
|
+
bytes: h.bytes,
|
|
283
|
+
kind,
|
|
284
|
+
entries: typeof h.entries === "number" ? h.entries : void 0
|
|
285
|
+
}];
|
|
286
|
+
});
|
|
287
|
+
out.push({
|
|
288
|
+
appId: typeof row.appId === "string" ? row.appId : appId,
|
|
289
|
+
table: row.table,
|
|
290
|
+
bytes: typeof row.bytes === "number" ? row.bytes : 0,
|
|
291
|
+
keys: typeof row.keys === "number" ? row.keys : 0,
|
|
292
|
+
heavy,
|
|
293
|
+
prompt: row.prompt
|
|
133
294
|
});
|
|
134
295
|
}
|
|
135
296
|
return out;
|
|
@@ -204,12 +365,22 @@ function createRestPanelHost(opts) {
|
|
|
204
365
|
opts.onConfigSaved?.(cfg);
|
|
205
366
|
}
|
|
206
367
|
},
|
|
368
|
+
about: {
|
|
369
|
+
load: async () => parseAbout(await readJson(`${origin()}/api/about`)),
|
|
370
|
+
checkUpdates: async () => parseUpdateCheck(await readJson(`${origin()}/api/updates`))
|
|
371
|
+
},
|
|
207
372
|
history: {
|
|
208
373
|
list: async (appId) => parseCommitList(await readJson(`${origin()}/api/apps/${encodeURIComponent(appId)}/history?limit=50`)),
|
|
209
374
|
detail: async (appId, id) => parseCommitDetail(await readJson(`${origin()}/api/apps/${encodeURIComponent(appId)}/history/${encodeURIComponent(id)}`), id)
|
|
210
375
|
},
|
|
211
376
|
storage: {
|
|
212
|
-
listTables: async (appId) =>
|
|
377
|
+
listTables: async (appId) => {
|
|
378
|
+
const raw = await readJson(`${origin()}/api/apps/${encodeURIComponent(appId)}/storage`);
|
|
379
|
+
return {
|
|
380
|
+
tables: parseStorageTables(raw),
|
|
381
|
+
notices: parseStorageNotices(raw, appId)
|
|
382
|
+
};
|
|
383
|
+
},
|
|
213
384
|
readTable: async (appId, name) => {
|
|
214
385
|
const raw = await readJson(`${origin()}/api/apps/${encodeURIComponent(appId)}/storage/${encodeURIComponent(name)}`);
|
|
215
386
|
return isRecord(raw) && "value" in raw ? raw.value : raw;
|
|
@@ -257,6 +428,8 @@ var initial = {
|
|
|
257
428
|
cfgMsg: "",
|
|
258
429
|
cfgVersion: 0,
|
|
259
430
|
cfg: {},
|
|
431
|
+
about: null,
|
|
432
|
+
updateCheck: null,
|
|
260
433
|
emptyText: void 0,
|
|
261
434
|
capabilities: none,
|
|
262
435
|
locale: "zh-CN",
|
|
@@ -270,7 +443,8 @@ var initial = {
|
|
|
270
443
|
browseDetail: null,
|
|
271
444
|
browseTable: null,
|
|
272
445
|
browseTableValue: null,
|
|
273
|
-
browseOpenFile: null
|
|
446
|
+
browseOpenFile: null,
|
|
447
|
+
storageNotice: null
|
|
274
448
|
};
|
|
275
449
|
var state = { ...initial, capabilities: { ...none } };
|
|
276
450
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -306,7 +480,7 @@ function usePanelState() {
|
|
|
306
480
|
|
|
307
481
|
// src/actions.ts
|
|
308
482
|
function activeAppFrom(state2) {
|
|
309
|
-
const tab = state2.tabs.find((t) => t.kind === "app" && t.id === state2.active)
|
|
483
|
+
const tab = state2.tabs.find((t) => t.kind === "app" && t.id === state2.active);
|
|
310
484
|
return tab?.app ?? null;
|
|
311
485
|
}
|
|
312
486
|
function errorMessage(err) {
|
|
@@ -323,6 +497,17 @@ function pushAppTab(app) {
|
|
|
323
497
|
function asCustomPalettes(value) {
|
|
324
498
|
return value;
|
|
325
499
|
}
|
|
500
|
+
function loadCustomPalettes(host) {
|
|
501
|
+
if (!host.palettes) return;
|
|
502
|
+
host.palettes().then((list) => {
|
|
503
|
+
const custom = {};
|
|
504
|
+
for (const p of list) {
|
|
505
|
+
custom[p.id] = { label: p.label, swatch: p.swatch, tokens: p.tokens };
|
|
506
|
+
}
|
|
507
|
+
setPanelState({ customPalettes: custom });
|
|
508
|
+
}).catch(() => {
|
|
509
|
+
});
|
|
510
|
+
}
|
|
326
511
|
function createPanelActions(host, getRootEl, i18n) {
|
|
327
512
|
setPanelState({ capabilities: capabilitiesOf(host), locale: i18n.locale, emptyText: host.emptyText });
|
|
328
513
|
return {
|
|
@@ -337,14 +522,18 @@ function createPanelActions(host, getRootEl, i18n) {
|
|
|
337
522
|
const tab = s.tabs.find((t) => t.id === id);
|
|
338
523
|
setPanelState({
|
|
339
524
|
tabs: s.tabs.filter((t) => t.id !== id),
|
|
340
|
-
active: s.active === id ? "all" : s.active
|
|
525
|
+
active: s.active === id ? "all" : s.active,
|
|
526
|
+
...s.active === id ? { themeScope: "global" } : {}
|
|
341
527
|
});
|
|
342
528
|
if (tab?.app) host.frame.unmount(tab.app.id);
|
|
343
529
|
},
|
|
344
530
|
switchTab: (id) => {
|
|
345
|
-
setPanelState({ active: id });
|
|
346
531
|
const s = getPanelState();
|
|
347
532
|
const tab = s.tabs.find((t) => t.id === id && t.kind === "app");
|
|
533
|
+
setPanelState({
|
|
534
|
+
active: id,
|
|
535
|
+
...!tab?.app ? { themeScope: "global" } : {}
|
|
536
|
+
});
|
|
348
537
|
if (tab?.app) host.frame.mount(tab.app.id);
|
|
349
538
|
},
|
|
350
539
|
setDock: (next) => {
|
|
@@ -355,31 +544,38 @@ function createPanelActions(host, getRootEl, i18n) {
|
|
|
355
544
|
}
|
|
356
545
|
},
|
|
357
546
|
setQuery: (q) => setPanelState({ query: q }),
|
|
358
|
-
toggleThemePop: () =>
|
|
547
|
+
toggleThemePop: () => {
|
|
548
|
+
const next = !getPanelState().themePopOpen;
|
|
549
|
+
setPanelState({ themePopOpen: next });
|
|
550
|
+
if (next) loadCustomPalettes(host);
|
|
551
|
+
},
|
|
359
552
|
setAppearance: (next, scope) => {
|
|
360
553
|
const s = getPanelState();
|
|
361
|
-
const theme = next.theme ? String(next.theme) : s.theme;
|
|
362
|
-
const palette = next.palette ? String(next.palette) : s.palette;
|
|
363
|
-
setPanelState({ theme, palette });
|
|
364
|
-
const root = getRootEl();
|
|
365
|
-
if (root) {
|
|
366
|
-
applyThemeTo(root, theme, palette, asCustomPalettes(s.customPalettes));
|
|
367
|
-
}
|
|
368
554
|
if (scope === "app") {
|
|
369
|
-
const app = activeAppFrom(
|
|
555
|
+
const app = activeAppFrom(s);
|
|
370
556
|
if (app && host.appTheme) {
|
|
371
|
-
const
|
|
557
|
+
const base = app.theme ?? { theme: s.theme, palette: s.palette };
|
|
558
|
+
const nextTheme = {
|
|
559
|
+
theme: next.theme ? String(next.theme) : base.theme,
|
|
560
|
+
palette: next.palette ? String(next.palette) : base.palette
|
|
561
|
+
};
|
|
372
562
|
host.appTheme.save(app.id, nextTheme).catch(() => {
|
|
373
563
|
});
|
|
374
564
|
const cur = getPanelState();
|
|
565
|
+
const patchApp = (a) => a.id === app.id ? { ...a, theme: nextTheme } : a;
|
|
375
566
|
setPanelState({
|
|
376
|
-
apps: cur.apps.some((a) => a.id === app.id) ? cur.apps.map(
|
|
377
|
-
tabs: cur.tabs.map(
|
|
378
|
-
(t) => t.app?.id === app.id ? { ...t, app: { ...t.app, theme: nextTheme } } : t
|
|
379
|
-
)
|
|
567
|
+
apps: cur.apps.some((a) => a.id === app.id) ? cur.apps.map(patchApp) : [...cur.apps, { ...app, theme: nextTheme }],
|
|
568
|
+
tabs: cur.tabs.map((t) => t.app?.id === app.id ? { ...t, app: { ...t.app, theme: nextTheme } } : t)
|
|
380
569
|
});
|
|
381
570
|
}
|
|
382
571
|
} else {
|
|
572
|
+
const theme = next.theme ? String(next.theme) : s.theme;
|
|
573
|
+
const palette = next.palette ? String(next.palette) : s.palette;
|
|
574
|
+
setPanelState({ theme, palette });
|
|
575
|
+
const root = getRootEl();
|
|
576
|
+
if (root) {
|
|
577
|
+
applyThemeTo(root, theme, palette, asCustomPalettes(s.customPalettes));
|
|
578
|
+
}
|
|
383
579
|
host.persistTheme?.(theme, palette);
|
|
384
580
|
}
|
|
385
581
|
host.frame.syncEnv?.();
|
|
@@ -402,23 +598,71 @@ function createPanelActions(host, getRootEl, i18n) {
|
|
|
402
598
|
},
|
|
403
599
|
getActiveApp: () => activeAppFrom(getPanelState()),
|
|
404
600
|
toggleSettings: (open) => {
|
|
405
|
-
setPanelState({
|
|
601
|
+
setPanelState({
|
|
602
|
+
settingsOpen: open,
|
|
603
|
+
cfgMsg: open ? "" : getPanelState().cfgMsg,
|
|
604
|
+
updateCheck: open ? null : getPanelState().updateCheck
|
|
605
|
+
});
|
|
406
606
|
if (open && host.config) {
|
|
407
607
|
host.config.load().then((cfg) => {
|
|
408
608
|
setPanelState({ cfg, cfgVersion: getPanelState().cfgVersion + 1 });
|
|
409
609
|
}).catch(() => {
|
|
410
610
|
});
|
|
411
611
|
}
|
|
612
|
+
if (open && host.about) {
|
|
613
|
+
host.about.load().then((about) => setPanelState({ about })).catch(() => setPanelState({ about: null }));
|
|
614
|
+
}
|
|
412
615
|
},
|
|
413
616
|
getCfg: () => getPanelState().cfg,
|
|
617
|
+
checkUpdates: () => {
|
|
618
|
+
if (!host.about) return;
|
|
619
|
+
setPanelState({
|
|
620
|
+
updateCheck: {
|
|
621
|
+
name: "",
|
|
622
|
+
current: "",
|
|
623
|
+
latest: null,
|
|
624
|
+
updateAvailable: false,
|
|
625
|
+
status: "loading"
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
host.about.checkUpdates().then((check) => setPanelState({ updateCheck: { ...check, status: "done" } })).catch(
|
|
629
|
+
(err) => setPanelState({
|
|
630
|
+
updateCheck: {
|
|
631
|
+
name: "",
|
|
632
|
+
current: "",
|
|
633
|
+
latest: null,
|
|
634
|
+
updateAvailable: false,
|
|
635
|
+
status: "done",
|
|
636
|
+
error: errorMessage(err)
|
|
637
|
+
}
|
|
638
|
+
})
|
|
639
|
+
);
|
|
640
|
+
},
|
|
414
641
|
saveHostConfig: (form) => {
|
|
415
642
|
if (!host.config) return;
|
|
416
643
|
host.config.save(form).then(() => {
|
|
644
|
+
const style = form.cardStyle || getPanelState().cardStyle;
|
|
645
|
+
const theme = form.theme || getPanelState().theme;
|
|
646
|
+
const palette = form.palette || getPanelState().palette;
|
|
417
647
|
setPanelState({
|
|
418
648
|
cfg: { ...form },
|
|
419
649
|
cfgMsg: i18n.t("config.saved"),
|
|
420
|
-
cfgVersion: getPanelState().cfgVersion + 1
|
|
650
|
+
cfgVersion: getPanelState().cfgVersion + 1,
|
|
651
|
+
cardStyle: style,
|
|
652
|
+
theme,
|
|
653
|
+
palette
|
|
421
654
|
});
|
|
655
|
+
const root = getRootEl();
|
|
656
|
+
if (root) {
|
|
657
|
+
applyThemeTo(root, theme, palette, asCustomPalettes(getPanelState().customPalettes));
|
|
658
|
+
root.setAttribute("data-cardstyle", style);
|
|
659
|
+
}
|
|
660
|
+
host.persistTheme?.(theme, palette);
|
|
661
|
+
host.frame.syncEnv?.();
|
|
662
|
+
try {
|
|
663
|
+
localStorage.setItem("mma-card-style", style);
|
|
664
|
+
} catch {
|
|
665
|
+
}
|
|
422
666
|
}).catch((e) => {
|
|
423
667
|
setPanelState({ cfgMsg: i18n.t("config.error", { message: errorMessage(e) }) });
|
|
424
668
|
});
|
|
@@ -452,11 +696,22 @@ function createPanelActions(host, getRootEl, i18n) {
|
|
|
452
696
|
setPanelState({ browseList: list, browseLoading: false });
|
|
453
697
|
}).catch((e) => setPanelState({ browseError: errorMessage(e), browseLoading: false }));
|
|
454
698
|
} else if (host.storage) {
|
|
455
|
-
host.storage.listTables(app.id).then((
|
|
456
|
-
|
|
699
|
+
host.storage.listTables(app.id).then(({ tables, notices }) => {
|
|
700
|
+
const notice = notices[0] ?? null;
|
|
701
|
+
setPanelState({
|
|
702
|
+
browseList: tables,
|
|
703
|
+
browseLoading: false,
|
|
704
|
+
...notice ? { storageNotice: notice } : {}
|
|
705
|
+
});
|
|
457
706
|
}).catch((e) => setPanelState({ browseError: errorMessage(e), browseLoading: false }));
|
|
458
707
|
}
|
|
459
708
|
},
|
|
709
|
+
dismissStorageNotice: () => {
|
|
710
|
+
setPanelState({ storageNotice: null });
|
|
711
|
+
},
|
|
712
|
+
applyStorageNotice: (notice) => {
|
|
713
|
+
setPanelState({ storageNotice: notice });
|
|
714
|
+
},
|
|
460
715
|
loadCommitDetail: (id) => {
|
|
461
716
|
const s = getPanelState();
|
|
462
717
|
if (!host.history || !s.browseAppId) return;
|
|
@@ -515,7 +770,14 @@ function createPanelActions(host, getRootEl, i18n) {
|
|
|
515
770
|
});
|
|
516
771
|
});
|
|
517
772
|
},
|
|
518
|
-
setCardStyle: (v) =>
|
|
773
|
+
setCardStyle: (v) => {
|
|
774
|
+
setPanelState({ cardStyle: v });
|
|
775
|
+
getRootEl()?.setAttribute("data-cardstyle", v);
|
|
776
|
+
try {
|
|
777
|
+
localStorage.setItem("mma-card-style", v);
|
|
778
|
+
} catch {
|
|
779
|
+
}
|
|
780
|
+
}
|
|
519
781
|
};
|
|
520
782
|
}
|
|
521
783
|
function defaultHideThemePop() {
|
|
@@ -526,8 +788,8 @@ function defaultHideThemePop() {
|
|
|
526
788
|
function clampPaletteId(v) {
|
|
527
789
|
return clampPalette(v);
|
|
528
790
|
}
|
|
529
|
-
var PanelActionsContext =
|
|
530
|
-
var PanelI18nContext =
|
|
791
|
+
var PanelActionsContext = React4.createContext(null);
|
|
792
|
+
var PanelI18nContext = React4.createContext(null);
|
|
531
793
|
function PanelProvider({
|
|
532
794
|
actions,
|
|
533
795
|
i18n,
|
|
@@ -536,12 +798,12 @@ function PanelProvider({
|
|
|
536
798
|
return /* @__PURE__ */ jsx(PanelI18nContext.Provider, { value: i18n, children: /* @__PURE__ */ jsx(PanelActionsContext.Provider, { value: actions, children }) });
|
|
537
799
|
}
|
|
538
800
|
function usePanelActions() {
|
|
539
|
-
const ctx =
|
|
801
|
+
const ctx = React4.useContext(PanelActionsContext);
|
|
540
802
|
if (!ctx) throw new Error("usePanelActions must be used inside <PanelProvider>");
|
|
541
803
|
return ctx;
|
|
542
804
|
}
|
|
543
805
|
function usePanelI18n() {
|
|
544
|
-
const ctx =
|
|
806
|
+
const ctx = React4.useContext(PanelI18nContext);
|
|
545
807
|
if (!ctx) throw new Error("usePanelI18n must be used inside <PanelProvider>");
|
|
546
808
|
return ctx;
|
|
547
809
|
}
|
|
@@ -601,6 +863,7 @@ function AppCard({ app }) {
|
|
|
601
863
|
{
|
|
602
864
|
type: "button",
|
|
603
865
|
className: "mma-card",
|
|
866
|
+
"data-app-id": app.id,
|
|
604
867
|
style: { "--h": hue(app.id) },
|
|
605
868
|
onClick: () => actions.openAppTab(app),
|
|
606
869
|
children: [
|
|
@@ -629,6 +892,7 @@ function AppRow({ app }) {
|
|
|
629
892
|
{
|
|
630
893
|
type: "button",
|
|
631
894
|
className: "mma-row",
|
|
895
|
+
"data-app-id": app.id,
|
|
632
896
|
style: { "--h": hue(app.id) },
|
|
633
897
|
onClick: () => actions.openAppTab(app),
|
|
634
898
|
children: [
|
|
@@ -736,26 +1000,60 @@ function CommitItem({ c }) {
|
|
|
736
1000
|
] })
|
|
737
1001
|
] });
|
|
738
1002
|
}
|
|
1003
|
+
function humanBytes(n, t) {
|
|
1004
|
+
if (n < 1024) return `${n} B`;
|
|
1005
|
+
if (n < 1024 * 1024) return t("browse.sizeKb", { value: (n / 1024).toFixed(1) });
|
|
1006
|
+
return t("browse.sizeMb", { value: (n / (1024 * 1024)).toFixed(1) });
|
|
1007
|
+
}
|
|
739
1008
|
function StorageItem({ table }) {
|
|
740
1009
|
const actions = usePanelActions();
|
|
1010
|
+
const { t } = usePanelI18n();
|
|
741
1011
|
return /* @__PURE__ */ jsxs("button", { type: "button", className: "mma-bitem", onClick: () => actions.loadTable(table.name), children: [
|
|
742
1012
|
/* @__PURE__ */ jsx("b", { children: table.name }),
|
|
743
1013
|
/* @__PURE__ */ jsxs("span", { className: "meta", children: [
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
|
|
746
|
-
" B"
|
|
747
|
-
] }),
|
|
1014
|
+
typeof table.keys === "number" ? /* @__PURE__ */ jsx("span", { children: t("browse.entries", { count: table.keys }) }) : null,
|
|
1015
|
+
/* @__PURE__ */ jsx("span", { children: humanBytes(table.size || 0, t) }),
|
|
748
1016
|
/* @__PURE__ */ jsx("span", { children: table.updatedAt || "" })
|
|
749
1017
|
] })
|
|
750
1018
|
] });
|
|
751
1019
|
}
|
|
1020
|
+
function StorageNoticeBanner() {
|
|
1021
|
+
const s = usePanelState();
|
|
1022
|
+
const actions = usePanelActions();
|
|
1023
|
+
const { t } = usePanelI18n();
|
|
1024
|
+
const notice = s.storageNotice;
|
|
1025
|
+
const [copied, setCopied] = React4.useState(false);
|
|
1026
|
+
if (!notice) return null;
|
|
1027
|
+
if (s.browseAppId && notice.appId !== s.browseAppId) return null;
|
|
1028
|
+
const top = notice.heavy[0];
|
|
1029
|
+
const summary = top ? t("browse.noticeTop", { key: top.key, size: humanBytes(top.bytes, t) }) : "";
|
|
1030
|
+
const copyPrompt = async () => {
|
|
1031
|
+
try {
|
|
1032
|
+
await navigator.clipboard.writeText(notice.prompt);
|
|
1033
|
+
setCopied(true);
|
|
1034
|
+
window.setTimeout(() => setCopied(false), 1500);
|
|
1035
|
+
} catch {
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
return /* @__PURE__ */ jsxs("div", { className: "mma-storage-notice", role: "status", children: [
|
|
1039
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-storage-notice-body", children: [
|
|
1040
|
+
/* @__PURE__ */ jsx("b", { children: t("browse.noticeTitle", { table: notice.table, size: humanBytes(notice.bytes, t) }) }),
|
|
1041
|
+
/* @__PURE__ */ jsx("p", { children: t("browse.noticeBody") }),
|
|
1042
|
+
summary ? /* @__PURE__ */ jsx("p", { className: "mma-storage-notice-top", children: summary }) : null
|
|
1043
|
+
] }),
|
|
1044
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-storage-notice-actions", children: [
|
|
1045
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "mma-storage-notice-copy", onClick: () => void copyPrompt(), children: copied ? t("browse.noticeCopied") : t("browse.noticeCopy") }),
|
|
1046
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => actions.dismissStorageNotice(), children: t("browse.noticeDismiss") })
|
|
1047
|
+
] })
|
|
1048
|
+
] });
|
|
1049
|
+
}
|
|
752
1050
|
function CommitDetail() {
|
|
753
1051
|
const s = usePanelState();
|
|
754
1052
|
const actions = usePanelActions();
|
|
755
1053
|
const { t } = usePanelI18n();
|
|
756
|
-
const [msgExpanded, setMsgExpanded] =
|
|
1054
|
+
const [msgExpanded, setMsgExpanded] = React4.useState(false);
|
|
757
1055
|
const d = s.browseDetail;
|
|
758
|
-
|
|
1056
|
+
React4.useEffect(() => {
|
|
759
1057
|
setMsgExpanded(false);
|
|
760
1058
|
}, [d?.id]);
|
|
761
1059
|
if (!d) return null;
|
|
@@ -843,7 +1141,10 @@ function Browse() {
|
|
|
843
1141
|
) })
|
|
844
1142
|
] });
|
|
845
1143
|
}
|
|
846
|
-
return /* @__PURE__ */ jsx("div", { className: "mma-browse", id: "mma-browse", "data-open": "1", children: /* @__PURE__ */
|
|
1144
|
+
return /* @__PURE__ */ jsx("div", { className: "mma-browse", id: "mma-browse", "data-open": "1", children: /* @__PURE__ */ jsxs("div", { className: "mma-browse-body", id: "mma-browse-body", children: [
|
|
1145
|
+
s.browseKind === "storage" ? /* @__PURE__ */ jsx(StorageNoticeBanner, {}) : null,
|
|
1146
|
+
content
|
|
1147
|
+
] }) });
|
|
847
1148
|
}
|
|
848
1149
|
function Modal() {
|
|
849
1150
|
const s = usePanelState();
|
|
@@ -860,66 +1161,676 @@ function Modal() {
|
|
|
860
1161
|
] })
|
|
861
1162
|
] }) });
|
|
862
1163
|
}
|
|
1164
|
+
function OptionCardGrid({
|
|
1165
|
+
options,
|
|
1166
|
+
value,
|
|
1167
|
+
onChange,
|
|
1168
|
+
columns = 3,
|
|
1169
|
+
"aria-label": ariaLabel,
|
|
1170
|
+
className,
|
|
1171
|
+
trailing
|
|
1172
|
+
}) {
|
|
1173
|
+
const refs = React4.useRef([]);
|
|
1174
|
+
const values = options.map((o) => o.value);
|
|
1175
|
+
const focusAt = (index) => {
|
|
1176
|
+
const el = refs.current[index];
|
|
1177
|
+
el?.focus();
|
|
1178
|
+
};
|
|
1179
|
+
const onKeyDown = (e, index) => {
|
|
1180
|
+
const enabled = options.map((o, i) => ({ o, i })).filter((x) => !x.o.disabled);
|
|
1181
|
+
if (!enabled.length) return;
|
|
1182
|
+
const pos = enabled.findIndex((x) => x.i === index);
|
|
1183
|
+
if (pos < 0) return;
|
|
1184
|
+
let nextPos = pos;
|
|
1185
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
1186
|
+
e.preventDefault();
|
|
1187
|
+
nextPos = (pos + 1) % enabled.length;
|
|
1188
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
1189
|
+
e.preventDefault();
|
|
1190
|
+
nextPos = (pos - 1 + enabled.length) % enabled.length;
|
|
1191
|
+
} else if (e.key === "Home") {
|
|
1192
|
+
e.preventDefault();
|
|
1193
|
+
nextPos = 0;
|
|
1194
|
+
} else if (e.key === "End") {
|
|
1195
|
+
e.preventDefault();
|
|
1196
|
+
nextPos = enabled.length - 1;
|
|
1197
|
+
} else {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
const next = enabled[nextPos];
|
|
1201
|
+
if (!next) return;
|
|
1202
|
+
focusAt(next.i);
|
|
1203
|
+
if (!next.o.disabled) onChange(next.o.value);
|
|
1204
|
+
};
|
|
1205
|
+
return /* @__PURE__ */ jsxs(
|
|
1206
|
+
"div",
|
|
1207
|
+
{
|
|
1208
|
+
className: `mma-optgrid mma-optgrid--${columns}${className ? ` ${className}` : ""}`,
|
|
1209
|
+
role: "radiogroup",
|
|
1210
|
+
"aria-label": ariaLabel,
|
|
1211
|
+
children: [
|
|
1212
|
+
options.map((opt, index) => {
|
|
1213
|
+
const checked = value === opt.value;
|
|
1214
|
+
return /* @__PURE__ */ jsxs(
|
|
1215
|
+
"button",
|
|
1216
|
+
{
|
|
1217
|
+
type: "button",
|
|
1218
|
+
role: "radio",
|
|
1219
|
+
"aria-checked": checked,
|
|
1220
|
+
"aria-label": opt.hint ? `${opt.label}. ${opt.hint}` : opt.label,
|
|
1221
|
+
disabled: opt.disabled,
|
|
1222
|
+
tabIndex: checked || !value && index === 0 ? 0 : -1,
|
|
1223
|
+
className: "mma-optcard",
|
|
1224
|
+
"data-on": checked ? "1" : "0",
|
|
1225
|
+
ref: (el) => {
|
|
1226
|
+
refs.current[index] = el;
|
|
1227
|
+
},
|
|
1228
|
+
onClick: () => {
|
|
1229
|
+
if (!opt.disabled) onChange(opt.value);
|
|
1230
|
+
},
|
|
1231
|
+
onKeyDown: (e) => onKeyDown(e, index),
|
|
1232
|
+
children: [
|
|
1233
|
+
/* @__PURE__ */ jsx("span", { className: "mma-optcard-preview", "aria-hidden": "true", children: opt.preview }),
|
|
1234
|
+
/* @__PURE__ */ jsx("span", { className: "mma-optcard-label", children: opt.label }),
|
|
1235
|
+
checked ? /* @__PURE__ */ jsx("span", { className: "mma-optcard-check", "aria-hidden": "true", children: "\u2713" }) : null
|
|
1236
|
+
]
|
|
1237
|
+
},
|
|
1238
|
+
opt.value
|
|
1239
|
+
);
|
|
1240
|
+
}),
|
|
1241
|
+
trailing ? /* @__PURE__ */ jsxs(
|
|
1242
|
+
"button",
|
|
1243
|
+
{
|
|
1244
|
+
type: "button",
|
|
1245
|
+
className: "mma-optcard mma-optcard--ghost",
|
|
1246
|
+
disabled: trailing.disabled !== false,
|
|
1247
|
+
title: trailing.hint,
|
|
1248
|
+
onClick: () => trailing.onClick?.(),
|
|
1249
|
+
children: [
|
|
1250
|
+
/* @__PURE__ */ jsx("span", { className: "mma-optcard-preview mma-optcard-preview--plus", "aria-hidden": "true", children: "+" }),
|
|
1251
|
+
/* @__PURE__ */ jsx("span", { className: "mma-optcard-label", children: trailing.label })
|
|
1252
|
+
]
|
|
1253
|
+
}
|
|
1254
|
+
) : null,
|
|
1255
|
+
/* @__PURE__ */ jsx("span", { hidden: true, children: values.join(",") })
|
|
1256
|
+
]
|
|
1257
|
+
}
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
var SECTIONS = ["appearance", "network", "model", "about"];
|
|
1261
|
+
var DEFAULTS = {
|
|
1262
|
+
hostPort: "17880",
|
|
1263
|
+
provider: "",
|
|
1264
|
+
model: "",
|
|
1265
|
+
locale: "zh-CN",
|
|
1266
|
+
theme: "light",
|
|
1267
|
+
palette: "default",
|
|
1268
|
+
cardStyle: "stamp"
|
|
1269
|
+
};
|
|
1270
|
+
function shortPkg(name) {
|
|
1271
|
+
return name.replace(/^@monkey-mini-app\//, "");
|
|
1272
|
+
}
|
|
1273
|
+
function validatePort(raw) {
|
|
1274
|
+
const trimmed = raw.trim();
|
|
1275
|
+
if (!trimmed) return "empty";
|
|
1276
|
+
if (!/^\d+$/.test(trimmed)) return "nan";
|
|
1277
|
+
const n = Number(trimmed);
|
|
1278
|
+
if (!Number.isInteger(n) || n < 1024 || n > 65535) return "range";
|
|
1279
|
+
return null;
|
|
1280
|
+
}
|
|
1281
|
+
function ThemePreview({ mode }) {
|
|
1282
|
+
if (mode === "system") {
|
|
1283
|
+
return /* @__PURE__ */ jsxs("span", { className: "mma-preview-theme mma-preview-theme--system", children: [
|
|
1284
|
+
/* @__PURE__ */ jsx("span", { className: "mma-preview-theme-half mma-preview-theme-half--light" }),
|
|
1285
|
+
/* @__PURE__ */ jsx("span", { className: "mma-preview-theme-half mma-preview-theme-half--dark" })
|
|
1286
|
+
] });
|
|
1287
|
+
}
|
|
1288
|
+
return /* @__PURE__ */ jsxs("span", { className: `mma-preview-theme mma-preview-theme--${mode}`, children: [
|
|
1289
|
+
/* @__PURE__ */ jsx("span", { className: "mma-preview-bar" }),
|
|
1290
|
+
/* @__PURE__ */ jsx("span", { className: "mma-preview-bar" })
|
|
1291
|
+
] });
|
|
1292
|
+
}
|
|
1293
|
+
function PalettePreview({ id, mode }) {
|
|
1294
|
+
const t = tokensOf(id, mode);
|
|
1295
|
+
return /* @__PURE__ */ jsxs("span", { className: "mma-preview-swatches", children: [
|
|
1296
|
+
/* @__PURE__ */ jsx("span", { style: { background: t.primary } }),
|
|
1297
|
+
/* @__PURE__ */ jsx("span", { style: { background: t.secondary } }),
|
|
1298
|
+
/* @__PURE__ */ jsx("span", { style: { background: t.bg } })
|
|
1299
|
+
] });
|
|
1300
|
+
}
|
|
1301
|
+
function CardStylePreview({ style }) {
|
|
1302
|
+
return /* @__PURE__ */ jsx("span", { className: `mma-preview-cardstyle mma-preview-cardstyle--${style}` });
|
|
1303
|
+
}
|
|
863
1304
|
function Settings() {
|
|
864
1305
|
const s = usePanelState();
|
|
865
1306
|
const actions = usePanelActions();
|
|
866
1307
|
const { t } = usePanelI18n();
|
|
867
|
-
const [form, setForm] =
|
|
868
|
-
|
|
1308
|
+
const [form, setForm] = React4.useState({});
|
|
1309
|
+
const [snapshot, setSnapshot] = React4.useState(null);
|
|
1310
|
+
const [section, setSection] = React4.useState("appearance");
|
|
1311
|
+
const [portTouched, setPortTouched] = React4.useState(false);
|
|
1312
|
+
const [confirm, setConfirm] = React4.useState(null);
|
|
1313
|
+
const [lastSavedAt, setLastSavedAt] = React4.useState(null);
|
|
1314
|
+
const rootRef = React4.useRef(null);
|
|
1315
|
+
const contentRef = React4.useRef(null);
|
|
1316
|
+
const sectionRefs = React4.useRef({});
|
|
1317
|
+
const dirtyCountRef = React4.useRef(0);
|
|
1318
|
+
const confirmRef = React4.useRef(confirm);
|
|
1319
|
+
confirmRef.current = confirm;
|
|
1320
|
+
const [wide, setWide] = React4.useState(false);
|
|
1321
|
+
React4.useEffect(() => {
|
|
1322
|
+
if (!s.settingsOpen) return;
|
|
1323
|
+
const next = s.cfg && Object.keys(s.cfg).length ? { ...s.cfg } : { ...actions.getCfg() };
|
|
1324
|
+
const snap = {
|
|
1325
|
+
hostPort: next.hostPort || "",
|
|
1326
|
+
provider: next.provider || "",
|
|
1327
|
+
model: next.model || "",
|
|
1328
|
+
theme: next.theme || s.theme || "light",
|
|
1329
|
+
palette: next.palette || s.palette || "default",
|
|
1330
|
+
cardStyle: next.cardStyle || s.cardStyle || "stamp",
|
|
1331
|
+
locale: next.locale || next.chatLanguage || "zh-CN"
|
|
1332
|
+
};
|
|
1333
|
+
setForm({ ...next, ...snap, chatLanguage: snap.locale });
|
|
1334
|
+
setSnapshot(snap);
|
|
1335
|
+
setPortTouched(false);
|
|
1336
|
+
setConfirm(null);
|
|
1337
|
+
setSection("appearance");
|
|
1338
|
+
}, [s.settingsOpen, s.cfgVersion, s.cfg, actions, s.theme, s.palette, s.cardStyle]);
|
|
1339
|
+
React4.useEffect(() => {
|
|
1340
|
+
if (!s.settingsOpen) return;
|
|
1341
|
+
const host = rootRef.current?.closest("#mma-host") ?? rootRef.current;
|
|
1342
|
+
if (!host || typeof ResizeObserver === "undefined") return;
|
|
1343
|
+
const ro = new ResizeObserver((entries) => {
|
|
1344
|
+
const w = entries[0]?.contentRect.width ?? 0;
|
|
1345
|
+
setWide(w >= 720);
|
|
1346
|
+
});
|
|
1347
|
+
ro.observe(host);
|
|
1348
|
+
return () => ro.disconnect();
|
|
1349
|
+
}, [s.settingsOpen]);
|
|
1350
|
+
React4.useEffect(() => {
|
|
869
1351
|
if (!s.settingsOpen) return;
|
|
870
|
-
|
|
871
|
-
|
|
1352
|
+
const root = contentRef.current;
|
|
1353
|
+
if (!root) return;
|
|
1354
|
+
const nodes = SECTIONS.map((id) => sectionRefs.current[id]).filter(Boolean);
|
|
1355
|
+
if (!nodes.length) return;
|
|
1356
|
+
const obs = new IntersectionObserver(
|
|
1357
|
+
(entries) => {
|
|
1358
|
+
const visible = entries.filter((e) => e.isIntersecting).sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0];
|
|
1359
|
+
const id = visible?.target.getAttribute("data-section");
|
|
1360
|
+
if (id) setSection(id);
|
|
1361
|
+
},
|
|
1362
|
+
{ root, threshold: [0.25, 0.5, 0.75], rootMargin: "-20% 0px -55% 0px" }
|
|
1363
|
+
);
|
|
1364
|
+
for (const n of nodes) obs.observe(n);
|
|
1365
|
+
return () => obs.disconnect();
|
|
1366
|
+
}, [s.settingsOpen, form]);
|
|
1367
|
+
React4.useEffect(() => {
|
|
1368
|
+
if (!s.settingsOpen) return;
|
|
1369
|
+
const onKey = (e) => {
|
|
1370
|
+
if (e.key !== "Escape") return;
|
|
1371
|
+
e.preventDefault();
|
|
1372
|
+
if (confirmRef.current) {
|
|
1373
|
+
setConfirm(null);
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (dirtyCountRef.current > 0) setConfirm("close");
|
|
1377
|
+
else actions.toggleSettings(false);
|
|
1378
|
+
};
|
|
1379
|
+
window.addEventListener("keydown", onKey);
|
|
1380
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1381
|
+
}, [s.settingsOpen, actions]);
|
|
872
1382
|
if (!s.capabilities.config) return null;
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
] })
|
|
922
|
-
|
|
1383
|
+
const themeMode = form.theme === "system" || form.theme === "dark" || form.theme === "light" ? form.theme : s.theme === "system" || s.theme === "dark" || s.theme === "light" ? s.theme : "light";
|
|
1384
|
+
const resolvedMode = resolveMode(themeMode === "system" ? "system" : themeMode);
|
|
1385
|
+
const palette = form.palette || s.palette || "default";
|
|
1386
|
+
const cardStyle = form.cardStyle || s.cardStyle || "stamp";
|
|
1387
|
+
const locale = form.locale || form.chatLanguage || "zh-CN";
|
|
1388
|
+
const dirty = {
|
|
1389
|
+
hostPort: form.hostPort || "",
|
|
1390
|
+
provider: form.provider || "",
|
|
1391
|
+
model: form.model || "",
|
|
1392
|
+
theme: themeMode,
|
|
1393
|
+
palette,
|
|
1394
|
+
cardStyle,
|
|
1395
|
+
locale
|
|
1396
|
+
};
|
|
1397
|
+
const dirtyKeys = ["hostPort", "provider", "model", "theme", "palette", "cardStyle", "locale"].filter((k) => snapshot != null && dirty[k] !== snapshot[k]);
|
|
1398
|
+
const dirtyCount = dirtyKeys.length;
|
|
1399
|
+
dirtyCountRef.current = dirtyCount;
|
|
1400
|
+
const portDirty = snapshot != null && dirty.hostPort !== snapshot.hostPort;
|
|
1401
|
+
const portErrorKey = portTouched || portDirty ? validatePort(form.hostPort || "") : null;
|
|
1402
|
+
const portError = portErrorKey === "empty" ? t("settings.portEmpty") : portErrorKey === "nan" ? t("settings.portNan") : portErrorKey === "range" ? t("settings.portRange") : null;
|
|
1403
|
+
const canSave = dirtyCount > 0 && !portError;
|
|
1404
|
+
const hostUrl = `http://127.0.0.1:${(form.hostPort || "").trim() || "\u2014"}`;
|
|
1405
|
+
const paletteLabel = t(`palette.${clampPalette(palette)}`);
|
|
1406
|
+
const versionLabel = s.about?.packages?.[0]?.version ?? s.about?.packages?.find((p) => p.name.includes("dsh"))?.version ?? "\u2014";
|
|
1407
|
+
const patch = (partial) => setForm((prev) => ({ ...prev, ...partial }));
|
|
1408
|
+
const paintPreview = (next) => {
|
|
1409
|
+
const host = document.getElementById("mma-host");
|
|
1410
|
+
if (!host) return;
|
|
1411
|
+
const theme = next.theme ?? themeMode;
|
|
1412
|
+
const pal = next.palette ?? palette;
|
|
1413
|
+
const style = next.cardStyle ?? cardStyle;
|
|
1414
|
+
applyThemeTo(host, theme, pal, s.customPalettes);
|
|
1415
|
+
host.setAttribute("data-cardstyle", style);
|
|
1416
|
+
};
|
|
1417
|
+
const previewAppearance = (partial) => {
|
|
1418
|
+
const nextTheme = partial.theme ?? themeMode;
|
|
1419
|
+
const nextPalette = partial.palette ?? palette;
|
|
1420
|
+
const nextCard = partial.cardStyle ?? cardStyle;
|
|
1421
|
+
paintPreview({ theme: nextTheme, palette: nextPalette, cardStyle: nextCard });
|
|
1422
|
+
patch({
|
|
1423
|
+
...partial.theme != null ? { theme: partial.theme } : {},
|
|
1424
|
+
...partial.palette != null ? { palette: partial.palette } : {},
|
|
1425
|
+
...partial.cardStyle != null ? { cardStyle: partial.cardStyle } : {},
|
|
1426
|
+
...partial.locale != null ? { locale: partial.locale, chatLanguage: partial.locale } : {}
|
|
1427
|
+
});
|
|
1428
|
+
};
|
|
1429
|
+
const scrollTo = (id) => {
|
|
1430
|
+
setSection(id);
|
|
1431
|
+
sectionRefs.current[id]?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
1432
|
+
};
|
|
1433
|
+
const discard = () => {
|
|
1434
|
+
if (!snapshot) return;
|
|
1435
|
+
patch({ ...snapshot, chatLanguage: snapshot.locale });
|
|
1436
|
+
paintPreview({
|
|
1437
|
+
theme: snapshot.theme,
|
|
1438
|
+
palette: snapshot.palette,
|
|
1439
|
+
cardStyle: snapshot.cardStyle
|
|
1440
|
+
});
|
|
1441
|
+
setPortTouched(false);
|
|
1442
|
+
};
|
|
1443
|
+
const requestClose = () => {
|
|
1444
|
+
if (dirtyCount > 0) setConfirm("close");
|
|
1445
|
+
else actions.toggleSettings(false);
|
|
1446
|
+
};
|
|
1447
|
+
const restoreDefaults = () => {
|
|
1448
|
+
previewAppearance({
|
|
1449
|
+
theme: DEFAULTS.theme,
|
|
1450
|
+
palette: DEFAULTS.palette,
|
|
1451
|
+
cardStyle: DEFAULTS.cardStyle,
|
|
1452
|
+
locale: DEFAULTS.locale
|
|
1453
|
+
});
|
|
1454
|
+
patch({
|
|
1455
|
+
hostPort: DEFAULTS.hostPort,
|
|
1456
|
+
provider: DEFAULTS.provider,
|
|
1457
|
+
model: DEFAULTS.model,
|
|
1458
|
+
locale: DEFAULTS.locale,
|
|
1459
|
+
chatLanguage: DEFAULTS.locale,
|
|
1460
|
+
theme: DEFAULTS.theme,
|
|
1461
|
+
palette: DEFAULTS.palette,
|
|
1462
|
+
cardStyle: DEFAULTS.cardStyle
|
|
1463
|
+
});
|
|
1464
|
+
setPortTouched(true);
|
|
1465
|
+
setConfirm(null);
|
|
1466
|
+
};
|
|
1467
|
+
const save = () => {
|
|
1468
|
+
if (!canSave) return;
|
|
1469
|
+
const committed = { ...dirty };
|
|
1470
|
+
actions.saveHostConfig({
|
|
1471
|
+
...form,
|
|
1472
|
+
theme: committed.theme,
|
|
1473
|
+
palette: committed.palette,
|
|
1474
|
+
cardStyle: committed.cardStyle,
|
|
1475
|
+
locale: committed.locale,
|
|
1476
|
+
chatLanguage: committed.locale
|
|
1477
|
+
});
|
|
1478
|
+
actions.setAppearance(
|
|
1479
|
+
{ theme: committed.theme, palette: committed.palette },
|
|
1480
|
+
"global"
|
|
1481
|
+
);
|
|
1482
|
+
actions.setCardStyle(committed.cardStyle);
|
|
1483
|
+
setSnapshot(committed);
|
|
1484
|
+
const now = /* @__PURE__ */ new Date();
|
|
1485
|
+
setLastSavedAt(
|
|
1486
|
+
`${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`
|
|
1487
|
+
);
|
|
1488
|
+
};
|
|
1489
|
+
const copyUrl = async () => {
|
|
1490
|
+
try {
|
|
1491
|
+
await navigator.clipboard.writeText(hostUrl);
|
|
1492
|
+
} catch {
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
const sectionLabel = (id) => id === "appearance" ? t("settings.sectionAppearance") : id === "network" ? t("settings.sectionNetwork") : id === "model" ? t("settings.sectionModel") : t("settings.sectionAbout");
|
|
1496
|
+
return /* @__PURE__ */ jsxs(
|
|
1497
|
+
"div",
|
|
1498
|
+
{
|
|
1499
|
+
ref: rootRef,
|
|
1500
|
+
className: "mma-settings",
|
|
1501
|
+
id: "mma-settings",
|
|
1502
|
+
"data-open": s.settingsOpen ? "1" : "0",
|
|
1503
|
+
"data-wide": wide ? "1" : "0",
|
|
1504
|
+
children: [
|
|
1505
|
+
/* @__PURE__ */ jsxs("header", { className: "mma-settings-head", children: [
|
|
1506
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-head-left", children: [
|
|
1507
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-head-icon", "aria-hidden": "true", children: "\u2699" }),
|
|
1508
|
+
/* @__PURE__ */ jsx("h3", { children: t("settings.title") })
|
|
1509
|
+
] }),
|
|
1510
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-head-right", children: [
|
|
1511
|
+
/* @__PURE__ */ jsxs("span", { className: "mma-settings-meta", children: [
|
|
1512
|
+
versionLabel,
|
|
1513
|
+
" \xB7 ",
|
|
1514
|
+
paletteLabel
|
|
1515
|
+
] }),
|
|
1516
|
+
/* @__PURE__ */ jsx(
|
|
1517
|
+
"button",
|
|
1518
|
+
{
|
|
1519
|
+
type: "button",
|
|
1520
|
+
className: "mma-iconbtn",
|
|
1521
|
+
id: "mma-cfg-close",
|
|
1522
|
+
"aria-label": t("settings.close"),
|
|
1523
|
+
onClick: requestClose,
|
|
1524
|
+
children: "\u2715"
|
|
1525
|
+
}
|
|
1526
|
+
)
|
|
1527
|
+
] })
|
|
1528
|
+
] }),
|
|
1529
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-body", children: [
|
|
1530
|
+
/* @__PURE__ */ jsxs("nav", { className: "mma-settings-rail", role: "tablist", "aria-label": t("settings.sectionsAria"), children: [
|
|
1531
|
+
/* @__PURE__ */ jsx("div", { className: "mma-settings-rail-title", children: t("settings.sectionNav") }),
|
|
1532
|
+
SECTIONS.map((id) => /* @__PURE__ */ jsx(
|
|
1533
|
+
"button",
|
|
1534
|
+
{
|
|
1535
|
+
type: "button",
|
|
1536
|
+
role: "tab",
|
|
1537
|
+
"aria-current": section === id ? "page" : void 0,
|
|
1538
|
+
"data-on": section === id ? "1" : "0",
|
|
1539
|
+
className: "mma-settings-rail-item",
|
|
1540
|
+
onClick: () => scrollTo(id),
|
|
1541
|
+
children: sectionLabel(id)
|
|
1542
|
+
},
|
|
1543
|
+
id
|
|
1544
|
+
))
|
|
1545
|
+
] }),
|
|
1546
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-content", ref: contentRef, children: [
|
|
1547
|
+
/* @__PURE__ */ jsxs(
|
|
1548
|
+
"section",
|
|
1549
|
+
{
|
|
1550
|
+
className: "mma-settings-section",
|
|
1551
|
+
"data-section": "appearance",
|
|
1552
|
+
ref: (el) => {
|
|
1553
|
+
sectionRefs.current.appearance = el;
|
|
1554
|
+
},
|
|
1555
|
+
children: [
|
|
1556
|
+
/* @__PURE__ */ jsx("h4", { children: t("settings.sectionAppearance") }),
|
|
1557
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field", children: [
|
|
1558
|
+
/* @__PURE__ */ jsx("label", { className: "mma-settings-label", htmlFor: "mma-cfg-lang-seg", children: t("settings.language") }),
|
|
1559
|
+
/* @__PURE__ */ jsx("div", { className: "mma-seg", id: "mma-cfg-lang-seg", role: "group", "aria-label": t("settings.language"), children: [
|
|
1560
|
+
["zh-CN", t("settings.langZh")],
|
|
1561
|
+
["en", t("settings.langEn")]
|
|
1562
|
+
].map(([id, label]) => /* @__PURE__ */ jsx(
|
|
1563
|
+
"button",
|
|
1564
|
+
{
|
|
1565
|
+
type: "button",
|
|
1566
|
+
"data-on": locale === id ? "1" : "0",
|
|
1567
|
+
onClick: () => previewAppearance({ locale: id }),
|
|
1568
|
+
children: label
|
|
1569
|
+
},
|
|
1570
|
+
id
|
|
1571
|
+
)) })
|
|
1572
|
+
] }),
|
|
1573
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field", children: [
|
|
1574
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-label", children: t("settings.theme") }),
|
|
1575
|
+
/* @__PURE__ */ jsx(
|
|
1576
|
+
OptionCardGrid,
|
|
1577
|
+
{
|
|
1578
|
+
"aria-label": t("settings.theme"),
|
|
1579
|
+
columns: 3,
|
|
1580
|
+
value: themeMode,
|
|
1581
|
+
onChange: (v) => previewAppearance({ theme: v }),
|
|
1582
|
+
options: ["system", "light", "dark"].map((mode) => ({
|
|
1583
|
+
value: mode,
|
|
1584
|
+
label: t(`theme.${mode}`),
|
|
1585
|
+
preview: /* @__PURE__ */ jsx(ThemePreview, { mode })
|
|
1586
|
+
}))
|
|
1587
|
+
}
|
|
1588
|
+
)
|
|
1589
|
+
] }),
|
|
1590
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field", children: [
|
|
1591
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-label", children: t("settings.palette") }),
|
|
1592
|
+
/* @__PURE__ */ jsx(
|
|
1593
|
+
OptionCardGrid,
|
|
1594
|
+
{
|
|
1595
|
+
"aria-label": t("settings.palette"),
|
|
1596
|
+
columns: 4,
|
|
1597
|
+
value: palette,
|
|
1598
|
+
onChange: (v) => previewAppearance({ palette: v }),
|
|
1599
|
+
options: PALETTES.map((p) => ({
|
|
1600
|
+
value: p.id,
|
|
1601
|
+
label: t(`palette.${p.id}`),
|
|
1602
|
+
preview: /* @__PURE__ */ jsx(PalettePreview, { id: p.id, mode: resolvedMode })
|
|
1603
|
+
}))
|
|
1604
|
+
}
|
|
1605
|
+
)
|
|
1606
|
+
] }),
|
|
1607
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field", children: [
|
|
1608
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-label", children: t("settings.cardStyle") }),
|
|
1609
|
+
/* @__PURE__ */ jsx(
|
|
1610
|
+
OptionCardGrid,
|
|
1611
|
+
{
|
|
1612
|
+
"aria-label": t("settings.cardStyle"),
|
|
1613
|
+
columns: 3,
|
|
1614
|
+
value: cardStyle,
|
|
1615
|
+
onChange: (v) => previewAppearance({ cardStyle: v }),
|
|
1616
|
+
options: [
|
|
1617
|
+
["stamp", t("settings.cardStamp")],
|
|
1618
|
+
["etch", t("settings.cardEtch")],
|
|
1619
|
+
["hero", t("settings.cardHero")],
|
|
1620
|
+
["list", t("settings.cardList")]
|
|
1621
|
+
].map(([value, label]) => ({
|
|
1622
|
+
value,
|
|
1623
|
+
label,
|
|
1624
|
+
preview: /* @__PURE__ */ jsx(CardStylePreview, { style: value })
|
|
1625
|
+
}))
|
|
1626
|
+
}
|
|
1627
|
+
)
|
|
1628
|
+
] }),
|
|
1629
|
+
/* @__PURE__ */ jsx("p", { className: "mma-settings-hint", children: t("settings.appearanceHint") })
|
|
1630
|
+
]
|
|
1631
|
+
}
|
|
1632
|
+
),
|
|
1633
|
+
/* @__PURE__ */ jsx("hr", { className: "mma-settings-rule" }),
|
|
1634
|
+
/* @__PURE__ */ jsxs(
|
|
1635
|
+
"section",
|
|
1636
|
+
{
|
|
1637
|
+
className: "mma-settings-section",
|
|
1638
|
+
"data-section": "network",
|
|
1639
|
+
ref: (el) => {
|
|
1640
|
+
sectionRefs.current.network = el;
|
|
1641
|
+
},
|
|
1642
|
+
children: [
|
|
1643
|
+
/* @__PURE__ */ jsx("h4", { children: t("settings.sectionNetwork") }),
|
|
1644
|
+
/* @__PURE__ */ jsxs("div", { className: `mma-settings-field mma-settings-field--row${portError ? " is-error" : ""}`, children: [
|
|
1645
|
+
/* @__PURE__ */ jsx("label", { className: "mma-settings-label", htmlFor: "mma-cfg-port", children: t("settings.hostPort") }),
|
|
1646
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-control", children: [
|
|
1647
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-port-row", children: [
|
|
1648
|
+
/* @__PURE__ */ jsx("span", { className: "mma-port-addon", "aria-hidden": "true", children: ":" }),
|
|
1649
|
+
/* @__PURE__ */ jsx(
|
|
1650
|
+
"input",
|
|
1651
|
+
{
|
|
1652
|
+
id: "mma-cfg-port",
|
|
1653
|
+
type: "text",
|
|
1654
|
+
inputMode: "numeric",
|
|
1655
|
+
autoComplete: "off",
|
|
1656
|
+
value: form.hostPort || "",
|
|
1657
|
+
"aria-invalid": !!portError,
|
|
1658
|
+
"aria-describedby": "mma-cfg-port-hint",
|
|
1659
|
+
onChange: (e) => {
|
|
1660
|
+
setPortTouched(true);
|
|
1661
|
+
patch({ hostPort: e.target.value });
|
|
1662
|
+
},
|
|
1663
|
+
onBlur: () => setPortTouched(true)
|
|
1664
|
+
}
|
|
1665
|
+
),
|
|
1666
|
+
/* @__PURE__ */ jsx("code", { className: "mma-port-url", children: hostUrl }),
|
|
1667
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "mma-ghostbtn", onClick: () => void copyUrl(), children: t("settings.copyUrl") }),
|
|
1668
|
+
/* @__PURE__ */ jsx("a", { className: "mma-ghostbtn", href: hostUrl, target: "_blank", rel: "noreferrer", children: t("settings.openUrl") })
|
|
1669
|
+
] }),
|
|
1670
|
+
/* @__PURE__ */ jsx("p", { className: "mma-settings-hint", id: "mma-cfg-port-hint", role: portError ? "alert" : void 0, children: portError ?? t("settings.portHint") })
|
|
1671
|
+
] })
|
|
1672
|
+
] })
|
|
1673
|
+
]
|
|
1674
|
+
}
|
|
1675
|
+
),
|
|
1676
|
+
/* @__PURE__ */ jsx("hr", { className: "mma-settings-rule" }),
|
|
1677
|
+
/* @__PURE__ */ jsxs(
|
|
1678
|
+
"section",
|
|
1679
|
+
{
|
|
1680
|
+
className: "mma-settings-section",
|
|
1681
|
+
"data-section": "model",
|
|
1682
|
+
ref: (el) => {
|
|
1683
|
+
sectionRefs.current.model = el;
|
|
1684
|
+
},
|
|
1685
|
+
children: [
|
|
1686
|
+
/* @__PURE__ */ jsx("h4", { children: t("settings.sectionModel") }),
|
|
1687
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field mma-settings-field--row", children: [
|
|
1688
|
+
/* @__PURE__ */ jsx("label", { className: "mma-settings-label", htmlFor: "mma-cfg-provider", children: t("settings.llmProvider") }),
|
|
1689
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-control mma-settings-control--model", children: [
|
|
1690
|
+
/* @__PURE__ */ jsx(
|
|
1691
|
+
"input",
|
|
1692
|
+
{
|
|
1693
|
+
id: "mma-cfg-provider",
|
|
1694
|
+
list: "mma-cfg-provider-list",
|
|
1695
|
+
placeholder: t("settings.providerPlaceholder"),
|
|
1696
|
+
value: form.provider || "",
|
|
1697
|
+
onChange: (e) => patch({ provider: e.target.value, model: "" })
|
|
1698
|
+
}
|
|
1699
|
+
),
|
|
1700
|
+
/* @__PURE__ */ jsxs("datalist", { id: "mma-cfg-provider-list", children: [
|
|
1701
|
+
/* @__PURE__ */ jsx("option", { value: "openai" }),
|
|
1702
|
+
/* @__PURE__ */ jsx("option", { value: "anthropic" }),
|
|
1703
|
+
/* @__PURE__ */ jsx("option", { value: "deepseek" })
|
|
1704
|
+
] })
|
|
1705
|
+
] })
|
|
1706
|
+
] }),
|
|
1707
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-field mma-settings-field--row", children: [
|
|
1708
|
+
/* @__PURE__ */ jsx("label", { className: "mma-settings-label", htmlFor: "mma-cfg-model", children: t("settings.llmModel") }),
|
|
1709
|
+
/* @__PURE__ */ jsx("div", { className: "mma-settings-control mma-settings-control--model", children: /* @__PURE__ */ jsxs("div", { className: "mma-model-row", children: [
|
|
1710
|
+
/* @__PURE__ */ jsx(
|
|
1711
|
+
"input",
|
|
1712
|
+
{
|
|
1713
|
+
id: "mma-cfg-model",
|
|
1714
|
+
placeholder: form.provider ? t("settings.modelPlaceholder") : t("settings.modelNeedsProvider"),
|
|
1715
|
+
value: form.model || "",
|
|
1716
|
+
disabled: !form.provider,
|
|
1717
|
+
onChange: (e) => patch({ model: e.target.value })
|
|
1718
|
+
}
|
|
1719
|
+
),
|
|
1720
|
+
/* @__PURE__ */ jsx("span", { className: "mma-status-pill", "data-state": "idle", children: t("settings.llmProbeIdle") })
|
|
1721
|
+
] }) })
|
|
1722
|
+
] })
|
|
1723
|
+
]
|
|
1724
|
+
}
|
|
1725
|
+
),
|
|
1726
|
+
/* @__PURE__ */ jsx("hr", { className: "mma-settings-rule" }),
|
|
1727
|
+
/* @__PURE__ */ jsxs(
|
|
1728
|
+
"section",
|
|
1729
|
+
{
|
|
1730
|
+
className: "mma-settings-section",
|
|
1731
|
+
"data-section": "about",
|
|
1732
|
+
ref: (el) => {
|
|
1733
|
+
sectionRefs.current.about = el;
|
|
1734
|
+
},
|
|
1735
|
+
children: [
|
|
1736
|
+
/* @__PURE__ */ jsx("h4", { children: t("settings.sectionAbout") }),
|
|
1737
|
+
s.about ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1738
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-about-meta", children: [
|
|
1739
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-label", children: t("settings.env") }),
|
|
1740
|
+
/* @__PURE__ */ jsxs("code", { children: [
|
|
1741
|
+
s.about.adapter,
|
|
1742
|
+
" \xB7 ",
|
|
1743
|
+
s.about.env
|
|
1744
|
+
] })
|
|
1745
|
+
] }),
|
|
1746
|
+
/* @__PURE__ */ jsx("ul", { className: "mma-about-pkgs", children: s.about.packages.map((pkg) => /* @__PURE__ */ jsxs("li", { children: [
|
|
1747
|
+
/* @__PURE__ */ jsx("span", { title: pkg.name, children: shortPkg(pkg.name) }),
|
|
1748
|
+
/* @__PURE__ */ jsx("code", { children: pkg.version })
|
|
1749
|
+
] }, pkg.name)) }),
|
|
1750
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-about-actions", children: [
|
|
1751
|
+
/* @__PURE__ */ jsx(
|
|
1752
|
+
"button",
|
|
1753
|
+
{
|
|
1754
|
+
type: "button",
|
|
1755
|
+
className: "mma-ghostbtn",
|
|
1756
|
+
id: "mma-cfg-check-update",
|
|
1757
|
+
disabled: s.updateCheck?.status === "loading",
|
|
1758
|
+
onClick: () => actions.checkUpdates(),
|
|
1759
|
+
children: s.updateCheck?.status === "loading" ? t("settings.checkingUpdate") : t("settings.checkUpdate")
|
|
1760
|
+
}
|
|
1761
|
+
),
|
|
1762
|
+
s.updateCheck?.status === "done" ? /* @__PURE__ */ jsx("span", { className: "mma-settings-hint", children: s.updateCheck.error ? t("settings.updateError", { message: s.updateCheck.error }) : s.updateCheck.updateAvailable ? t("settings.updateAvailable", {
|
|
1763
|
+
latest: s.updateCheck.latest ?? "",
|
|
1764
|
+
current: s.updateCheck.current
|
|
1765
|
+
}) : t("settings.upToDate", {
|
|
1766
|
+
version: s.updateCheck.latest ?? s.updateCheck.current
|
|
1767
|
+
}) }) : null
|
|
1768
|
+
] })
|
|
1769
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "mma-settings-hint", children: t("settings.aboutLoading") })
|
|
1770
|
+
]
|
|
1771
|
+
}
|
|
1772
|
+
)
|
|
1773
|
+
] })
|
|
1774
|
+
] }),
|
|
1775
|
+
/* @__PURE__ */ jsxs("footer", { className: "mma-settings-foot", children: [
|
|
1776
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-foot-left", "aria-live": "polite", children: [
|
|
1777
|
+
lastSavedAt ? /* @__PURE__ */ jsxs("span", { className: "mma-settings-hint", children: [
|
|
1778
|
+
t("settings.lastSaved", { time: lastSavedAt }),
|
|
1779
|
+
dirtyCount > 0 ? " \xB7 " : ""
|
|
1780
|
+
] }) : null,
|
|
1781
|
+
dirtyCount > 0 ? /* @__PURE__ */ jsx("span", { className: "mma-settings-dirty", children: t("settings.dirtyCount", { count: dirtyCount }) }) : null
|
|
1782
|
+
] }),
|
|
1783
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-settings-foot-right", children: [
|
|
1784
|
+
dirtyCount > 0 ? /* @__PURE__ */ jsx("button", { type: "button", className: "mma-ghostbtn", onClick: discard, children: t("settings.discard") }) : null,
|
|
1785
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "mma-ghostbtn", onClick: () => setConfirm("restore"), children: t("settings.restore") }),
|
|
1786
|
+
/* @__PURE__ */ jsx(
|
|
1787
|
+
"button",
|
|
1788
|
+
{
|
|
1789
|
+
type: "button",
|
|
1790
|
+
className: "mma-primarybtn",
|
|
1791
|
+
id: "mma-cfg-save",
|
|
1792
|
+
disabled: !canSave,
|
|
1793
|
+
onClick: save,
|
|
1794
|
+
children: t("settings.save")
|
|
1795
|
+
}
|
|
1796
|
+
)
|
|
1797
|
+
] }),
|
|
1798
|
+
/* @__PURE__ */ jsx("span", { className: "mma-settings-msg", id: "mma-cfg-msg", children: s.cfgMsg })
|
|
1799
|
+
] }),
|
|
1800
|
+
confirm ? /* @__PURE__ */ jsx("div", { className: "mma-settings-confirm", role: "presentation", children: /* @__PURE__ */ jsxs(
|
|
1801
|
+
"div",
|
|
1802
|
+
{
|
|
1803
|
+
className: "mma-dialog",
|
|
1804
|
+
role: "dialog",
|
|
1805
|
+
"aria-modal": "true",
|
|
1806
|
+
"aria-labelledby": "mma-settings-confirm-title",
|
|
1807
|
+
children: [
|
|
1808
|
+
/* @__PURE__ */ jsx("h3", { id: "mma-settings-confirm-title", children: confirm === "close" ? t("settings.confirmCloseTitle") : t("settings.confirmRestoreTitle") }),
|
|
1809
|
+
/* @__PURE__ */ jsx("p", { children: confirm === "close" ? t("settings.confirmCloseBody") : t("settings.confirmRestoreBody") }),
|
|
1810
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-dialog-actions", children: [
|
|
1811
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setConfirm(null), children: t("modal.cancel") }),
|
|
1812
|
+
/* @__PURE__ */ jsx(
|
|
1813
|
+
"button",
|
|
1814
|
+
{
|
|
1815
|
+
type: "button",
|
|
1816
|
+
className: "go",
|
|
1817
|
+
onClick: () => {
|
|
1818
|
+
if (confirm === "close") {
|
|
1819
|
+
discard();
|
|
1820
|
+
actions.toggleSettings(false);
|
|
1821
|
+
} else restoreDefaults();
|
|
1822
|
+
setConfirm(null);
|
|
1823
|
+
},
|
|
1824
|
+
children: confirm === "close" ? t("settings.confirmDiscard") : t("settings.confirmRestoreAction")
|
|
1825
|
+
}
|
|
1826
|
+
)
|
|
1827
|
+
] })
|
|
1828
|
+
]
|
|
1829
|
+
}
|
|
1830
|
+
) }) : null
|
|
1831
|
+
]
|
|
1832
|
+
}
|
|
1833
|
+
);
|
|
923
1834
|
}
|
|
924
1835
|
function Tabs() {
|
|
925
1836
|
const s = usePanelState();
|
|
@@ -962,8 +1873,11 @@ function ThemePop() {
|
|
|
962
1873
|
const actions = usePanelActions();
|
|
963
1874
|
const { t } = usePanelI18n();
|
|
964
1875
|
const app = actions.getActiveApp();
|
|
965
|
-
const
|
|
1876
|
+
const appScope = Boolean(app) && s.themeScope === "app";
|
|
1877
|
+
const viewTheme = appScope ? app?.theme?.theme ?? s.theme : s.theme;
|
|
1878
|
+
const viewPalette = appScope ? selectedPalette(app?.theme?.palette, Boolean(app?.localPalette)) : s.palette;
|
|
966
1879
|
const customs = s.customPalettes || {};
|
|
1880
|
+
const canApp = Boolean(app && s.capabilities.appTheme);
|
|
967
1881
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
968
1882
|
s.themePopOpen ? /* @__PURE__ */ jsx(
|
|
969
1883
|
"div",
|
|
@@ -987,18 +1901,61 @@ function ThemePop() {
|
|
|
987
1901
|
onClick: (e) => e.stopPropagation(),
|
|
988
1902
|
onPointerDown: (e) => e.stopPropagation(),
|
|
989
1903
|
children: [
|
|
990
|
-
/* @__PURE__ */ jsx("div", { className: "mma-pop-
|
|
1904
|
+
/* @__PURE__ */ jsx("div", { className: "mma-pop-lab", children: t("theme.apply") }),
|
|
1905
|
+
/* @__PURE__ */ jsxs("div", { className: "mma-pop-seg", children: [
|
|
1906
|
+
/* @__PURE__ */ jsx(
|
|
1907
|
+
"button",
|
|
1908
|
+
{
|
|
1909
|
+
type: "button",
|
|
1910
|
+
"data-scope": "global",
|
|
1911
|
+
"data-on": s.themeScope === "global" ? "1" : "0",
|
|
1912
|
+
onClick: () => actions.setThemeScope("global"),
|
|
1913
|
+
children: t("theme.global")
|
|
1914
|
+
}
|
|
1915
|
+
),
|
|
1916
|
+
/* @__PURE__ */ jsx(
|
|
1917
|
+
"button",
|
|
1918
|
+
{
|
|
1919
|
+
type: "button",
|
|
1920
|
+
"data-scope": "app",
|
|
1921
|
+
id: "mma-scope-app",
|
|
1922
|
+
title: app ? t("theme.saveTo", { name: app.name }) : t("theme.openAppFirst"),
|
|
1923
|
+
"data-on": appScope ? "1" : "0",
|
|
1924
|
+
disabled: !canApp,
|
|
1925
|
+
onClick: () => actions.setThemeScope("app"),
|
|
1926
|
+
children: app ? app.name : t("theme.currentApp")
|
|
1927
|
+
}
|
|
1928
|
+
)
|
|
1929
|
+
] }),
|
|
1930
|
+
/* @__PURE__ */ jsx("div", { className: "mma-pop-lab", children: t("theme.appearance") }),
|
|
1931
|
+
/* @__PURE__ */ jsx("div", { className: "mma-pop-seg", children: ["system", "light", "dark"].map((mode) => /* @__PURE__ */ jsx(
|
|
991
1932
|
"button",
|
|
992
1933
|
{
|
|
993
1934
|
type: "button",
|
|
994
1935
|
"data-mode": mode,
|
|
995
|
-
"data-on":
|
|
1936
|
+
"data-on": viewTheme === mode ? "1" : "0",
|
|
996
1937
|
onClick: () => actions.setAppearance({ theme: mode }, s.themeScope),
|
|
997
1938
|
children: t(`theme.${mode}`)
|
|
998
1939
|
},
|
|
999
1940
|
mode
|
|
1000
1941
|
)) }),
|
|
1942
|
+
/* @__PURE__ */ jsx("div", { className: "mma-pop-lab", children: t("theme.palettes") }),
|
|
1001
1943
|
/* @__PURE__ */ jsxs("div", { className: "mma-pop-list", children: [
|
|
1944
|
+
appScope ? /* @__PURE__ */ jsxs(
|
|
1945
|
+
"button",
|
|
1946
|
+
{
|
|
1947
|
+
type: "button",
|
|
1948
|
+
className: "mma-swatch",
|
|
1949
|
+
id: "mma-follow-global",
|
|
1950
|
+
"data-on": viewPalette === GLOBAL_PALETTE_ID ? "1" : "0",
|
|
1951
|
+
role: "menuitem",
|
|
1952
|
+
onClick: () => actions.setAppearance({ palette: GLOBAL_PALETTE_ID }, "app"),
|
|
1953
|
+
children: [
|
|
1954
|
+
/* @__PURE__ */ jsx("i", { className: "mma-dot", style: { background: "linear-gradient(135deg,#888,#ddd)" } }),
|
|
1955
|
+
/* @__PURE__ */ jsx("span", { children: t("theme.followGlobal") })
|
|
1956
|
+
]
|
|
1957
|
+
}
|
|
1958
|
+
) : null,
|
|
1002
1959
|
PALETTES.map((p) => /* @__PURE__ */ jsxs(
|
|
1003
1960
|
"button",
|
|
1004
1961
|
{
|
|
@@ -1006,11 +1963,12 @@ function ThemePop() {
|
|
|
1006
1963
|
className: "mma-swatch",
|
|
1007
1964
|
"data-palette": p.id,
|
|
1008
1965
|
role: "menuitem",
|
|
1009
|
-
"data-on":
|
|
1966
|
+
"data-on": viewPalette === p.id ? "1" : "0",
|
|
1010
1967
|
onClick: () => actions.setAppearance({ palette: p.id }, s.themeScope),
|
|
1011
1968
|
children: [
|
|
1012
1969
|
/* @__PURE__ */ jsx("i", { className: "mma-dot", style: { background: p.swatch } }),
|
|
1013
|
-
/* @__PURE__ */ jsx("span", { children: t(`palette.${p.id}`) })
|
|
1970
|
+
/* @__PURE__ */ jsx("span", { children: t(`palette.${p.id}`) }),
|
|
1971
|
+
/* @__PURE__ */ jsx("i", { className: "mma-custom-badge", children: t("theme.chipSystem") })
|
|
1014
1972
|
]
|
|
1015
1973
|
},
|
|
1016
1974
|
p.id
|
|
@@ -1023,7 +1981,7 @@ function ThemePop() {
|
|
|
1023
1981
|
"data-palette": id,
|
|
1024
1982
|
"data-custom": "1",
|
|
1025
1983
|
role: "menuitem",
|
|
1026
|
-
"data-on":
|
|
1984
|
+
"data-on": viewPalette === id ? "1" : "0",
|
|
1027
1985
|
onClick: () => actions.setAppearance({ palette: id }, s.themeScope),
|
|
1028
1986
|
children: [
|
|
1029
1987
|
/* @__PURE__ */ jsx("i", { className: "mma-dot", style: { background: customs[id].swatch || "#888" } }),
|
|
@@ -1032,34 +1990,34 @@ function ThemePop() {
|
|
|
1032
1990
|
]
|
|
1033
1991
|
},
|
|
1034
1992
|
id
|
|
1035
|
-
))
|
|
1036
|
-
|
|
1037
|
-
/* @__PURE__ */ jsxs("div", { className: "mma-pop-seg mma-scope-seg", children: [
|
|
1038
|
-
/* @__PURE__ */ jsx(
|
|
1039
|
-
"button",
|
|
1040
|
-
{
|
|
1041
|
-
type: "button",
|
|
1042
|
-
"data-scope": "global",
|
|
1043
|
-
"data-on": s.themeScope === "global" ? "1" : "0",
|
|
1044
|
-
onClick: () => actions.setThemeScope("global"),
|
|
1045
|
-
children: t("theme.global")
|
|
1046
|
-
}
|
|
1047
|
-
),
|
|
1048
|
-
/* @__PURE__ */ jsx(
|
|
1993
|
+
)),
|
|
1994
|
+
appScope && app?.localPalette ? /* @__PURE__ */ jsxs(
|
|
1049
1995
|
"button",
|
|
1050
1996
|
{
|
|
1051
1997
|
type: "button",
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
"data-on":
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1998
|
+
className: "mma-swatch",
|
|
1999
|
+
"data-palette": LOCAL_PALETTE_ID,
|
|
2000
|
+
role: "menuitem",
|
|
2001
|
+
"data-on": viewPalette === LOCAL_PALETTE_ID ? "1" : "0",
|
|
2002
|
+
onClick: () => actions.setAppearance({ palette: LOCAL_PALETTE_ID }, "app"),
|
|
2003
|
+
children: [
|
|
2004
|
+
/* @__PURE__ */ jsx("i", { className: "mma-dot", style: { background: app.localPalette.swatch } }),
|
|
2005
|
+
/* @__PURE__ */ jsx("span", { children: app.localPalette.label }),
|
|
2006
|
+
/* @__PURE__ */ jsx("i", { className: "mma-custom-badge", children: t("theme.chipApp") })
|
|
2007
|
+
]
|
|
1059
2008
|
}
|
|
1060
|
-
)
|
|
2009
|
+
) : null
|
|
1061
2010
|
] }),
|
|
1062
|
-
|
|
2011
|
+
appScope && app?.theme ? /* @__PURE__ */ jsx(
|
|
2012
|
+
"button",
|
|
2013
|
+
{
|
|
2014
|
+
type: "button",
|
|
2015
|
+
className: "mma-textbtn",
|
|
2016
|
+
id: "mma-reset-app-theme",
|
|
2017
|
+
onClick: () => actions.clearAppTheme(),
|
|
2018
|
+
children: t("theme.resetApp")
|
|
2019
|
+
}
|
|
2020
|
+
) : null
|
|
1063
2021
|
]
|
|
1064
2022
|
}
|
|
1065
2023
|
)
|
|
@@ -1242,6 +2200,13 @@ function createFrameController(opts) {
|
|
|
1242
2200
|
const { container: initial2, urlOf, envOf } = opts;
|
|
1243
2201
|
let container = initial2 ?? null;
|
|
1244
2202
|
const map = /* @__PURE__ */ new Map();
|
|
2203
|
+
function targetOrigin(appId, rec) {
|
|
2204
|
+
try {
|
|
2205
|
+
return new URL(rec?.iframe.src || urlOf(appId)).origin;
|
|
2206
|
+
} catch {
|
|
2207
|
+
return "";
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
1245
2210
|
return {
|
|
1246
2211
|
map,
|
|
1247
2212
|
url: (appId) => urlOf(appId),
|
|
@@ -1253,8 +2218,13 @@ function createFrameController(opts) {
|
|
|
1253
2218
|
const w = rec?.iframe.contentWindow;
|
|
1254
2219
|
if (!w) return;
|
|
1255
2220
|
const env = envOf(appId);
|
|
2221
|
+
const target = targetOrigin(appId, rec);
|
|
2222
|
+
if (!target) return;
|
|
1256
2223
|
try {
|
|
1257
|
-
w.postMessage(
|
|
2224
|
+
w.postMessage(
|
|
2225
|
+
{ type: "mma-set-env", theme: env.theme, palette: env.palette, dock: env.dock, vars: env.vars },
|
|
2226
|
+
target
|
|
2227
|
+
);
|
|
1258
2228
|
} catch {
|
|
1259
2229
|
}
|
|
1260
2230
|
},
|
|
@@ -1268,7 +2238,7 @@ function createFrameController(opts) {
|
|
|
1268
2238
|
const wrap = document.createElement("div");
|
|
1269
2239
|
wrap.className = "mma-frame";
|
|
1270
2240
|
wrap.setAttribute("data-app", appId);
|
|
1271
|
-
wrap.innerHTML = `${loadingMarkup()}<iframe title="${escapeHtml(title || appId)}"></iframe>`;
|
|
2241
|
+
wrap.innerHTML = `${loadingMarkup()}<iframe title="${escapeHtml(title || appId)}" allow="clipboard-write"></iframe>`;
|
|
1272
2242
|
if (!container) return;
|
|
1273
2243
|
container.appendChild(wrap);
|
|
1274
2244
|
const iframe = wrap.querySelector("iframe");
|
|
@@ -1298,6 +2268,27 @@ function createFrameController(opts) {
|
|
|
1298
2268
|
if (!rec) return;
|
|
1299
2269
|
if (!rec.wrap.querySelector(".mma-load")) rec.wrap.insertAdjacentHTML("afterbegin", loadingMarkup());
|
|
1300
2270
|
rec.iframe.src = `${urlOf(appId)}&_=${Date.now()}`;
|
|
2271
|
+
},
|
|
2272
|
+
postViewEval(query) {
|
|
2273
|
+
const rec = map.get(query.appId);
|
|
2274
|
+
const w = rec?.iframe.contentWindow;
|
|
2275
|
+
const target = rec ? targetOrigin(query.appId, rec) : "";
|
|
2276
|
+
if (!w || !target) return false;
|
|
2277
|
+
try {
|
|
2278
|
+
w.postMessage(
|
|
2279
|
+
{
|
|
2280
|
+
type: "mma-view-eval",
|
|
2281
|
+
requestId: query.requestId,
|
|
2282
|
+
appId: query.appId,
|
|
2283
|
+
code: query.code ?? "",
|
|
2284
|
+
maxBytes: query.maxBytes ?? 0
|
|
2285
|
+
},
|
|
2286
|
+
target
|
|
2287
|
+
);
|
|
2288
|
+
return true;
|
|
2289
|
+
} catch {
|
|
2290
|
+
return false;
|
|
2291
|
+
}
|
|
1301
2292
|
}
|
|
1302
2293
|
};
|
|
1303
2294
|
}
|
|
@@ -1321,6 +2312,7 @@ var en_default = {
|
|
|
1321
2312
|
close: "Close"
|
|
1322
2313
|
},
|
|
1323
2314
|
theme: {
|
|
2315
|
+
system: "System",
|
|
1324
2316
|
light: "Light",
|
|
1325
2317
|
dark: "Dark",
|
|
1326
2318
|
custom: "Custom",
|
|
@@ -1328,7 +2320,13 @@ var en_default = {
|
|
|
1328
2320
|
currentApp: "Current app",
|
|
1329
2321
|
openAppFirst: "Open an app first",
|
|
1330
2322
|
saveTo: 'Save to "{{name}}"',
|
|
1331
|
-
followGlobal: "Follow global
|
|
2323
|
+
followGlobal: "Follow global",
|
|
2324
|
+
apply: "Apply to",
|
|
2325
|
+
appearance: "Appearance",
|
|
2326
|
+
palettes: "Palette",
|
|
2327
|
+
chipSystem: "System",
|
|
2328
|
+
chipApp: "This app",
|
|
2329
|
+
resetApp: "Restore this app default"
|
|
1332
2330
|
},
|
|
1333
2331
|
palette: {
|
|
1334
2332
|
default: "Default",
|
|
@@ -1354,20 +2352,59 @@ var en_default = {
|
|
|
1354
2352
|
},
|
|
1355
2353
|
settings: {
|
|
1356
2354
|
title: "Settings",
|
|
2355
|
+
close: "Close settings",
|
|
2356
|
+
sectionNav: "Sections",
|
|
2357
|
+
sectionsAria: "Settings sections",
|
|
2358
|
+
sectionAppearance: "Appearance",
|
|
2359
|
+
sectionNetwork: "Network",
|
|
2360
|
+
sectionModel: "Model",
|
|
2361
|
+
sectionAbout: "About",
|
|
2362
|
+
sectionHost: "Host",
|
|
1357
2363
|
hostPort: "Host port",
|
|
1358
2364
|
language: "Language",
|
|
1359
2365
|
langZh: "Chinese",
|
|
1360
2366
|
langEn: "English",
|
|
1361
2367
|
theme: "Theme",
|
|
1362
2368
|
palette: "Palette",
|
|
2369
|
+
dock: "Dock",
|
|
2370
|
+
dockFill: "Fill",
|
|
2371
|
+
dockSide: "Side",
|
|
1363
2372
|
cardStyle: "Card style",
|
|
1364
2373
|
cardStamp: "Stamp",
|
|
1365
2374
|
cardEtch: "Etch",
|
|
1366
2375
|
cardHero: "Hero",
|
|
1367
2376
|
cardList: "List",
|
|
2377
|
+
appearanceHint: "Preview only. Click Save to persist; closing discards unsaved changes.",
|
|
2378
|
+
portHint: "Range 1024\u201365535. Restart the app after changing.",
|
|
2379
|
+
portEmpty: "Enter a port.",
|
|
2380
|
+
portNan: "Port must be a number.",
|
|
2381
|
+
portRange: "Port must be between 1024 and 65535.",
|
|
2382
|
+
copyUrl: "Copy",
|
|
2383
|
+
openUrl: "Open",
|
|
1368
2384
|
llmProvider: "LLM Provider",
|
|
1369
2385
|
llmModel: "LLM model",
|
|
1370
|
-
|
|
2386
|
+
providerPlaceholder: "Select a provider",
|
|
2387
|
+
modelPlaceholder: "Enter a model",
|
|
2388
|
+
modelNeedsProvider: "Select a provider first",
|
|
2389
|
+
llmProbeIdle: "Probe not wired",
|
|
2390
|
+
save: "Save",
|
|
2391
|
+
discard: "Discard",
|
|
2392
|
+
restore: "Restore defaults",
|
|
2393
|
+
lastSaved: "Saved {{time}}",
|
|
2394
|
+
dirtyCount: "{{count}} unsaved",
|
|
2395
|
+
confirmCloseTitle: "Discard unsaved changes?",
|
|
2396
|
+
confirmCloseBody: "Unsaved appearance, network, and model changes will be discarded and restored.",
|
|
2397
|
+
confirmDiscard: "Discard",
|
|
2398
|
+
confirmRestoreTitle: "Restore defaults?",
|
|
2399
|
+
confirmRestoreBody: "Resets appearance, port, and model fields (port/model still need Save).",
|
|
2400
|
+
confirmRestoreAction: "Restore",
|
|
2401
|
+
env: "Environment",
|
|
2402
|
+
aboutLoading: "Loading version info\u2026",
|
|
2403
|
+
checkUpdate: "Check for updates",
|
|
2404
|
+
checkingUpdate: "Checking\u2026",
|
|
2405
|
+
upToDate: "Up to date ({{version}})",
|
|
2406
|
+
updateAvailable: "Update available: {{latest}} (current {{current}})",
|
|
2407
|
+
updateError: "Check failed: {{message}}"
|
|
1371
2408
|
},
|
|
1372
2409
|
modal: {
|
|
1373
2410
|
title: "Delete mini app",
|
|
@@ -1386,7 +2423,16 @@ var en_default = {
|
|
|
1386
2423
|
noCommits: "No commits yet",
|
|
1387
2424
|
noStorage: "No storage files",
|
|
1388
2425
|
expandMsg: "Show more",
|
|
1389
|
-
collapseMsg: "Show less"
|
|
2426
|
+
collapseMsg: "Show less",
|
|
2427
|
+
entries: "{{count}} entries",
|
|
2428
|
+
sizeKb: "{{value}} KB",
|
|
2429
|
+
sizeMb: "{{value}} MB",
|
|
2430
|
+
noticeTitle: '"{{table}}" is already {{size}}',
|
|
2431
|
+
noticeBody: "The bigger this file gets, the slower every save becomes. Move anything that keeps growing into its own table \u2014 copy the prompt below and paste it to an AI to do the split for you.",
|
|
2432
|
+
noticeTop: 'The heaviest piece right now is "{{key}}" (about {{size}}).',
|
|
2433
|
+
noticeCopy: "Copy split prompt",
|
|
2434
|
+
noticeCopied: "Copied",
|
|
2435
|
+
noticeDismiss: "Got it"
|
|
1390
2436
|
},
|
|
1391
2437
|
load: {
|
|
1392
2438
|
label: "Loading"
|
|
@@ -1416,6 +2462,7 @@ var zh_CN_default = {
|
|
|
1416
2462
|
close: "\u5173\u95ED"
|
|
1417
2463
|
},
|
|
1418
2464
|
theme: {
|
|
2465
|
+
system: "\u8DDF\u968F\u7CFB\u7EDF",
|
|
1419
2466
|
light: "\u6D45\u8272",
|
|
1420
2467
|
dark: "\u6DF1\u8272",
|
|
1421
2468
|
custom: "\u81EA\u5B9A\u4E49",
|
|
@@ -1423,7 +2470,13 @@ var zh_CN_default = {
|
|
|
1423
2470
|
currentApp: "\u5F53\u524D\u5C0F\u7A0B\u5E8F",
|
|
1424
2471
|
openAppFirst: "\u6253\u5F00\u5C0F\u7A0B\u5E8F\u540E\u53EF\u7528",
|
|
1425
2472
|
saveTo: "\u4FDD\u5B58\u5230\u300C{{name}}\u300D",
|
|
1426
|
-
followGlobal: "\u8DDF\u968F\u5168\u5C40
|
|
2473
|
+
followGlobal: "\u8DDF\u968F\u5168\u5C40",
|
|
2474
|
+
apply: "\u5E94\u7528\u5230",
|
|
2475
|
+
appearance: "\u5916\u89C2",
|
|
2476
|
+
palettes: "\u8272\u677F",
|
|
2477
|
+
chipSystem: "\u7CFB\u7EDF",
|
|
2478
|
+
chipApp: "\u672C\u5E94\u7528",
|
|
2479
|
+
resetApp: "\u6062\u590D\u8BE5\u5E94\u7528\u9ED8\u8BA4"
|
|
1427
2480
|
},
|
|
1428
2481
|
palette: {
|
|
1429
2482
|
default: "\u9ED8\u8BA4",
|
|
@@ -1449,20 +2502,59 @@ var zh_CN_default = {
|
|
|
1449
2502
|
},
|
|
1450
2503
|
settings: {
|
|
1451
2504
|
title: "\u8BBE\u7F6E",
|
|
2505
|
+
close: "\u5173\u95ED\u8BBE\u7F6E",
|
|
2506
|
+
sectionNav: "\u5206\u7EC4",
|
|
2507
|
+
sectionsAria: "\u8BBE\u7F6E\u5206\u7EC4",
|
|
2508
|
+
sectionAppearance: "\u5916\u89C2",
|
|
2509
|
+
sectionNetwork: "\u7F51\u7EDC",
|
|
2510
|
+
sectionModel: "\u6A21\u578B",
|
|
2511
|
+
sectionAbout: "\u5173\u4E8E",
|
|
2512
|
+
sectionHost: "\u5BBF\u4E3B",
|
|
1452
2513
|
hostPort: "Host \u7AEF\u53E3",
|
|
1453
2514
|
language: "\u754C\u9762\u8BED\u8A00",
|
|
1454
2515
|
langZh: "\u4E2D\u6587",
|
|
1455
2516
|
langEn: "English",
|
|
1456
2517
|
theme: "\u4E3B\u9898",
|
|
1457
2518
|
palette: "\u8C03\u8272\u677F",
|
|
2519
|
+
dock: "\u505C\u9760",
|
|
2520
|
+
dockFill: "\u94FA\u6EE1",
|
|
2521
|
+
dockSide: "\u4FA7\u680F",
|
|
1458
2522
|
cardStyle: "\u5361\u7247\u6837\u5F0F",
|
|
1459
2523
|
cardStamp: "\u5370\u7AE0",
|
|
1460
2524
|
cardEtch: "\u8680\u523B",
|
|
1461
2525
|
cardHero: "\u6D77\u62A5",
|
|
1462
2526
|
cardList: "\u5217\u8868",
|
|
2527
|
+
appearanceHint: "\u4EC5\u9884\u89C8\uFF0C\u70B9\u4FDD\u5B58\u540E\u624D\u4F1A\u5199\u5165\uFF1B\u5173\u95ED\u672A\u4FDD\u5B58\u5C06\u6062\u590D\u539F\u6837\u3002",
|
|
2528
|
+
portHint: "\u8303\u56F4 1024\u201365535\uFF0C\u4FEE\u6539\u540E\u9700\u91CD\u542F\u5E94\u7528\u3002",
|
|
2529
|
+
portEmpty: "\u8BF7\u8F93\u5165\u7AEF\u53E3\u3002",
|
|
2530
|
+
portNan: "\u7AEF\u53E3\u5FC5\u987B\u662F\u6570\u5B57\u3002",
|
|
2531
|
+
portRange: "\u7AEF\u53E3\u9700\u5728 1024\u201365535 \u4E4B\u95F4\u3002",
|
|
2532
|
+
copyUrl: "\u590D\u5236",
|
|
2533
|
+
openUrl: "\u6253\u5F00",
|
|
1463
2534
|
llmProvider: "LLM Provider",
|
|
1464
2535
|
llmModel: "LLM \u6A21\u578B",
|
|
1465
|
-
|
|
2536
|
+
providerPlaceholder: "\u9009\u62E9 Provider",
|
|
2537
|
+
modelPlaceholder: "\u8F93\u5165\u6A21\u578B\u540D",
|
|
2538
|
+
modelNeedsProvider: "\u5148\u9009\u62E9 Provider",
|
|
2539
|
+
llmProbeIdle: "\u672A\u63A5\u5165\u68C0\u6D4B",
|
|
2540
|
+
save: "\u4FDD\u5B58",
|
|
2541
|
+
discard: "\u653E\u5F03\u4FEE\u6539",
|
|
2542
|
+
restore: "\u6062\u590D\u9ED8\u8BA4",
|
|
2543
|
+
lastSaved: "\u4E0A\u6B21\u4FDD\u5B58 {{time}}",
|
|
2544
|
+
dirtyCount: "{{count}} \u9879\u672A\u4FDD\u5B58",
|
|
2545
|
+
confirmCloseTitle: "\u653E\u5F03\u672A\u4FDD\u5B58\u7684\u4FEE\u6539\uFF1F",
|
|
2546
|
+
confirmCloseBody: "\u5173\u95ED\u540E\uFF0C\u672A\u4FDD\u5B58\u7684\u5916\u89C2 / \u7F51\u7EDC / \u6A21\u578B\u6539\u52A8\u90FD\u4F1A\u4E22\u5F03\u5E76\u6062\u590D\u539F\u6837\u3002",
|
|
2547
|
+
confirmDiscard: "\u653E\u5F03",
|
|
2548
|
+
confirmRestoreTitle: "\u6062\u590D\u9ED8\u8BA4\u8BBE\u7F6E\uFF1F",
|
|
2549
|
+
confirmRestoreBody: "\u5C06\u91CD\u7F6E\u5916\u89C2\u3001\u7AEF\u53E3\u4E0E\u6A21\u578B\u5B57\u6BB5\u4E3A\u9ED8\u8BA4\u503C\uFF08\u4ECD\u9700\u4FDD\u5B58\u7AEF\u53E3/\u6A21\u578B\uFF09\u3002",
|
|
2550
|
+
confirmRestoreAction: "\u6062\u590D",
|
|
2551
|
+
env: "\u73AF\u5883",
|
|
2552
|
+
aboutLoading: "\u6B63\u5728\u8BFB\u53D6\u7248\u672C\u4FE1\u606F\u2026",
|
|
2553
|
+
checkUpdate: "\u68C0\u67E5\u66F4\u65B0",
|
|
2554
|
+
checkingUpdate: "\u68C0\u67E5\u4E2D\u2026",
|
|
2555
|
+
upToDate: "\u5DF2\u662F\u6700\u65B0\uFF08{{version}}\uFF09",
|
|
2556
|
+
updateAvailable: "\u6709\u65B0\u7248\u672C {{latest}}\uFF08\u5F53\u524D {{current}}\uFF09",
|
|
2557
|
+
updateError: "\u68C0\u67E5\u5931\u8D25\uFF1A{{message}}"
|
|
1466
2558
|
},
|
|
1467
2559
|
modal: {
|
|
1468
2560
|
title: "\u5220\u9664\u5C0F\u7A0B\u5E8F",
|
|
@@ -1481,7 +2573,16 @@ var zh_CN_default = {
|
|
|
1481
2573
|
noCommits: "\u6682\u65E0\u63D0\u4EA4\u8BB0\u5F55",
|
|
1482
2574
|
noStorage: "\u6682\u65E0\u5B58\u50A8\u6587\u4EF6",
|
|
1483
2575
|
expandMsg: "\u5C55\u5F00\u5168\u6587",
|
|
1484
|
-
collapseMsg: "\u6536\u8D77"
|
|
2576
|
+
collapseMsg: "\u6536\u8D77",
|
|
2577
|
+
entries: "{{count}} \u6761",
|
|
2578
|
+
sizeKb: "{{value}} KB",
|
|
2579
|
+
sizeMb: "{{value}} MB",
|
|
2580
|
+
noticeTitle: "\u300C{{table}}\u300D\u5DF2\u7ECF\u6709 {{size}} \u4E86",
|
|
2581
|
+
noticeBody: "\u8FD9\u4E2A\u6587\u4EF6\u8D8A\u5927\uFF0C\u6BCF\u6B21\u4FDD\u5B58\u90FD\u4F1A\u8D8A\u6162\u3002\u5EFA\u8BAE\u628A\u4F1A\u4E0D\u65AD\u53D8\u591A\u7684\u6570\u636E\u62C6\u5230\u5355\u72EC\u7684\u8868\u91CC\u2014\u2014\u4F60\u53EF\u4EE5\u628A\u4E0B\u9762\u7684\u63D0\u793A\u8BCD\u590D\u5236\u7ED9 AI\uFF0C\u8BA9\u5B83\u5E2E\u4F60\u6539\u3002",
|
|
2582
|
+
noticeTop: "\u773C\u4E0B\u6700\u5927\u7684\u4E00\u5757\u662F\u300C{{key}}\u300D\uFF08\u7EA6 {{size}}\uFF09\u3002",
|
|
2583
|
+
noticeCopy: "\u590D\u5236\u62C6\u5206\u63D0\u793A\u8BCD",
|
|
2584
|
+
noticeCopied: "\u5DF2\u590D\u5236",
|
|
2585
|
+
noticeDismiss: "\u77E5\u9053\u4E86"
|
|
1485
2586
|
},
|
|
1486
2587
|
load: {
|
|
1487
2588
|
label: "\u52A0\u8F7D\u4E2D"
|
|
@@ -1561,7 +2662,7 @@ function resolvePanelLocale(value) {
|
|
|
1561
2662
|
// src/styles.ts
|
|
1562
2663
|
var PANEL_CSS_TAG = "panel";
|
|
1563
2664
|
var CSS = [
|
|
1564
|
-
"#mma-host{color:var(--dsw-alias-fg,#111);background:var(--dsw-alias-bg,#f7f7f8);overflow:hidden;}",
|
|
2665
|
+
"#mma-host{color:var(--dsw-alias-fg,#111);background:var(--dsw-alias-bg,#f7f7f8);overflow:hidden;container-type:inline-size;container-name:mma-host;}",
|
|
1565
2666
|
"#mma-host button,#mma-host input,#mma-host select{color:inherit;font:inherit;}",
|
|
1566
2667
|
"#mma-host .mma-chrome{display:flex;align-items:center;gap:8px;height:46px;padding:0 10px;border-bottom:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);flex:0 0 auto;}",
|
|
1567
2668
|
"#mma-host .mma-tabs{display:flex;align-items:center;gap:2px;flex:1;min-width:0;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:thin;}",
|
|
@@ -1577,12 +2678,18 @@ var CSS = [
|
|
|
1577
2678
|
"#mma-host .mma-toolbar .mma-ico{display:block;}",
|
|
1578
2679
|
"#mma-host .mma-theme-wrap{position:relative;flex:0 0 auto;}",
|
|
1579
2680
|
"#mma-host .mma-pop-scrim{position:fixed;inset:0;z-index:7;background:transparent;}",
|
|
1580
|
-
"#mma-host .mma-pop{display:none;position:absolute;right:0;top:40px;z-index:8;width:
|
|
2681
|
+
"#mma-host .mma-pop{display:none;position:absolute;right:0;top:40px;z-index:8;width:260px;padding:12px 14px 14px;border-radius:12px;border:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);box-shadow:0 12px 32px var(--dsw-alias-shadow,rgba(0,0,0,.14));}",
|
|
1581
2682
|
"#mma-host .mma-pop[data-open='1']{display:block;}",
|
|
1582
2683
|
"#mma-host .mma-pop-seg{display:flex;gap:4px;margin:0 0 12px;padding:3px;border-radius:9px;background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
1583
2684
|
"#mma-host .mma-pop-seg button{flex:1;height:28px;padding:0;line-height:1;border:0;border-radius:7px;background:transparent;cursor:pointer;font-size:12px;color:inherit;display:flex;align-items:center;justify-content:center;}",
|
|
1584
2685
|
"#mma-host .mma-pop-seg button[data-on='1']{background:var(--dsw-alias-surface,#fff);font-weight:600;box-shadow:0 1px 2px var(--dsw-alias-shadow,rgba(0,0,0,.06));color:var(--dsw-alias-primary,#2563eb);}",
|
|
1585
|
-
"#mma-host .mma-pop-
|
|
2686
|
+
"#mma-host .mma-pop-seg button:disabled{opacity:.45;cursor:not-allowed;}",
|
|
2687
|
+
"#mma-host .mma-pop-lab{font-size:10px;letter-spacing:.12em;text-transform:uppercase;opacity:.55;margin:10px 2px 6px;}",
|
|
2688
|
+
"#mma-host .mma-pop-lab:first-child{margin-top:0;}",
|
|
2689
|
+
"#mma-host .mma-pop-list{margin:0;display:flex;flex-direction:column;gap:6px!important;max-height:280px;overflow-y:auto;padding:4px 0;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--dsw-alias-fg,#111) 35%,transparent) transparent;}",
|
|
2690
|
+
"#mma-host .mma-pop-list::-webkit-scrollbar{width:8px;}",
|
|
2691
|
+
"#mma-host .mma-pop-list::-webkit-scrollbar-track{background:transparent;}",
|
|
2692
|
+
"#mma-host .mma-pop-list::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--dsw-alias-fg,#111) 35%,transparent);border-radius:99px;}",
|
|
1586
2693
|
"#mma-host .mma-swatch{display:flex;align-items:center;gap:10px;width:100%;min-height:34px;padding:0 10px;border:0;border-radius:8px;background:transparent;cursor:pointer;color:inherit;font-size:13px;text-align:left;white-space:nowrap;overflow:hidden;}",
|
|
1587
2694
|
"#mma-host .mma-swatch:hover{background:var(--dsw-alias-accent,var(--dsw-alias-muted,#f3f4f6));}",
|
|
1588
2695
|
"#mma-host .mma-swatch[data-on='1']{background:var(--dsw-alias-accent,var(--dsw-alias-muted,#f3f4f6));font-weight:600;}",
|
|
@@ -1661,17 +2768,106 @@ var CSS = [
|
|
|
1661
2768
|
"#mma-host .mma-dialog-actions{display:flex;justify-content:flex-end;gap:8px;}",
|
|
1662
2769
|
"#mma-host .mma-dialog-actions button{height:32px;padding:0 12px;border-radius:8px;border:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);cursor:pointer;}",
|
|
1663
2770
|
"#mma-host .mma-dialog-actions .go{background:#dc2626;color:#fff;border-color:#dc2626;}",
|
|
1664
|
-
"#mma-host .mma-settings{position:absolute;inset:0;background:var(--dsw-alias-bg,#f7f7f8);
|
|
1665
|
-
"#mma-host .mma-settings[data-open='1']{display:
|
|
1666
|
-
"#mma-host .mma-settings
|
|
1667
|
-
"#mma-host .mma-settings-head{display:flex;align-items:center;
|
|
1668
|
-
"#mma-host .mma-settings
|
|
1669
|
-
"#mma-host .mma-settings
|
|
1670
|
-
"#mma-host .mma-settings-
|
|
1671
|
-
"#mma-host .mma-settings-
|
|
1672
|
-
"#mma-host .mma-settings-
|
|
1673
|
-
"#mma-host
|
|
1674
|
-
"#mma-host
|
|
2771
|
+
"#mma-host .mma-settings{position:absolute;inset:0;z-index:4;display:none;flex-direction:column;background:var(--dsw-alias-bg,#f7f7f8);color:inherit;overflow:hidden;}",
|
|
2772
|
+
"#mma-host .mma-settings[data-open='1']{display:flex;}",
|
|
2773
|
+
"#mma-host .mma-settings-head{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);}",
|
|
2774
|
+
"#mma-host .mma-settings-head-left{display:flex;align-items:center;gap:8px;min-width:0;}",
|
|
2775
|
+
"#mma-host .mma-settings-head-icon{opacity:.7;font-size:14px;}",
|
|
2776
|
+
"#mma-host .mma-settings-head h3{margin:0;font-size:15px;font-weight:650;letter-spacing:-.01em;}",
|
|
2777
|
+
"#mma-host .mma-settings-head-right{display:flex;align-items:center;gap:8px;}",
|
|
2778
|
+
"#mma-host .mma-settings-meta{font-size:11px;opacity:.55;white-space:nowrap;}",
|
|
2779
|
+
"#mma-host .mma-settings-body{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;}",
|
|
2780
|
+
"#mma-host .mma-settings-rail{flex:0 0 auto;display:flex;gap:4px;padding:8px 10px;border-bottom:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);overflow-x:auto;}",
|
|
2781
|
+
"#mma-host .mma-settings-rail-title{display:none;}",
|
|
2782
|
+
"#mma-host .mma-settings-rail-item{flex:0 0 auto;height:30px;padding:0 10px;border:0;border-radius:8px;background:transparent;color:inherit;opacity:.7;font-size:12.5px;cursor:pointer;}",
|
|
2783
|
+
"#mma-host .mma-settings-rail-item:hover{background:var(--dsw-alias-muted,#f3f4f6);opacity:1;}",
|
|
2784
|
+
"#mma-host .mma-settings-rail-item[data-on='1']{background:var(--dsw-alias-muted,#f3f4f6);opacity:1;font-weight:600;color:var(--dsw-alias-primary,#2563eb);box-shadow:inset 0 -2px 0 var(--dsw-alias-primary,#2563eb);}",
|
|
2785
|
+
"#mma-host .mma-settings-content{flex:1 1 auto;min-height:0;overflow:auto;padding:18px 16px 24px;scroll-behavior:smooth;}",
|
|
2786
|
+
"#mma-host .mma-settings-section{scroll-margin-top:12px;}",
|
|
2787
|
+
"#mma-host .mma-settings-section h4{margin:0 0 14px;font-size:12.5px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;opacity:.55;}",
|
|
2788
|
+
"#mma-host .mma-settings-field{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;}",
|
|
2789
|
+
"#mma-host .mma-settings-label{font-size:12.5px;opacity:.75;}",
|
|
2790
|
+
"#mma-host .mma-settings-control{min-width:0;}",
|
|
2791
|
+
"#mma-host .mma-settings-control--model{max-width:520px;}",
|
|
2792
|
+
"#mma-host .mma-settings input{display:block;width:100%;height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border,#e5e7eb);border-radius:9px;background:var(--dsw-alias-surface,#fff);color:inherit;font-size:13px;box-sizing:border-box;}",
|
|
2793
|
+
"#mma-host .mma-settings input:focus{outline:none;border-color:var(--dsw-alias-primary,#2563eb);box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-primary,#2563eb) 20%, transparent);}",
|
|
2794
|
+
"#mma-host .mma-settings input:disabled{opacity:.55;}",
|
|
2795
|
+
"#mma-host .mma-settings-field.is-error input{border-color:var(--dsw-alias-destructive,#dc2626);}",
|
|
2796
|
+
"#mma-host .mma-seg{display:flex;gap:4px;padding:3px;border-radius:10px;background:var(--dsw-alias-muted,#f3f4f6);max-width:280px;}",
|
|
2797
|
+
"#mma-host .mma-seg button{flex:1;height:30px;padding:0 8px;border:0;border-radius:8px;background:transparent;cursor:pointer;font-size:12.5px;color:inherit;}",
|
|
2798
|
+
"#mma-host .mma-seg button[data-on='1']{background:var(--dsw-alias-surface,#fff);font-weight:600;box-shadow:0 1px 2px var(--dsw-alias-shadow,rgba(0,0,0,.06));color:var(--dsw-alias-primary,#2563eb);}",
|
|
2799
|
+
"#mma-host .mma-optgrid{display:grid;gap:10px;}",
|
|
2800
|
+
"#mma-host .mma-optgrid--2{grid-template-columns:repeat(2,minmax(0,1fr));}",
|
|
2801
|
+
"#mma-host .mma-optgrid--3{grid-template-columns:repeat(2,minmax(0,1fr));}",
|
|
2802
|
+
"#mma-host .mma-optgrid--4{grid-template-columns:repeat(2,minmax(0,1fr));}",
|
|
2803
|
+
"#mma-host .mma-optcard{position:relative;display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid var(--dsw-alias-border,#e5e7eb);border-radius:10px;background:var(--dsw-alias-surface,#fff);color:inherit;cursor:pointer;text-align:left;}",
|
|
2804
|
+
"#mma-host .mma-optcard:hover{border-color:color-mix(in srgb, var(--dsw-alias-fg,#111) 28%, var(--dsw-alias-border,#e5e7eb));}",
|
|
2805
|
+
"#mma-host .mma-optcard:focus-visible{outline:2px solid var(--dsw-alias-primary,#2563eb);outline-offset:2px;}",
|
|
2806
|
+
"#mma-host .mma-optcard[data-on='1']{border-color:var(--dsw-alias-primary,#2563eb);background:color-mix(in srgb, var(--dsw-alias-primary,#2563eb) 8%, var(--dsw-alias-surface,#fff));}",
|
|
2807
|
+
"#mma-host .mma-optcard:disabled,.mma-optcard--ghost{opacity:.55;cursor:default;border-style:dashed;}",
|
|
2808
|
+
"#mma-host .mma-optcard-preview{display:block;height:42px;border-radius:8px;overflow:hidden;background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
2809
|
+
"#mma-host .mma-optcard-preview--plus{display:flex;align-items:center;justify-content:center;font-size:20px;opacity:.7;}",
|
|
2810
|
+
"#mma-host .mma-optcard-label{font-size:12px;line-height:1.2;}",
|
|
2811
|
+
"#mma-host .mma-optcard-check{position:absolute;top:8px;right:8px;width:18px;height:18px;border-radius:999px;background:var(--dsw-alias-primary,#2563eb);color:var(--dsw-alias-primary-fg,#fff);font-size:11px;display:flex;align-items:center;justify-content:center;}",
|
|
2812
|
+
"#mma-host .mma-preview-theme{display:flex;flex-direction:column;justify-content:center;gap:6px;height:100%;padding:8px;box-sizing:border-box;}",
|
|
2813
|
+
"#mma-host .mma-preview-theme--light{background:var(--dsw-alias-bg,#f7f7f8);}",
|
|
2814
|
+
"#mma-host .mma-preview-theme--dark{background:color-mix(in srgb, var(--dsw-alias-fg,#111) 88%, transparent);}",
|
|
2815
|
+
"#mma-host .mma-preview-theme--system{display:flex;flex-direction:row;padding:0;}",
|
|
2816
|
+
"#mma-host .mma-preview-theme-half{flex:1;height:100%;display:flex;flex-direction:column;justify-content:center;gap:6px;padding:8px;box-sizing:border-box;}",
|
|
2817
|
+
"#mma-host .mma-preview-theme-half--light{background:var(--dsw-alias-bg,#f7f7f8);}",
|
|
2818
|
+
"#mma-host .mma-preview-theme-half--dark{background:color-mix(in srgb, var(--dsw-alias-fg,#111) 88%, transparent);}",
|
|
2819
|
+
"#mma-host .mma-preview-bar{display:block;height:4px;border-radius:999px;background:color-mix(in srgb, var(--dsw-alias-fg,#111) 25%, transparent);}",
|
|
2820
|
+
"#mma-host .mma-preview-theme--dark .mma-preview-bar,#mma-host .mma-preview-theme-half--dark .mma-preview-bar{background:color-mix(in srgb, #fff 45%, transparent);}",
|
|
2821
|
+
"#mma-host .mma-preview-swatches{display:flex;align-items:center;justify-content:center;gap:8px;height:100%;}",
|
|
2822
|
+
"#mma-host .mma-preview-swatches > span{width:14px;height:14px;border-radius:999px;border:1px solid color-mix(in srgb, var(--dsw-alias-fg,#111) 12%, transparent);}",
|
|
2823
|
+
"#mma-host .mma-preview-cardstyle{display:block;height:100%;margin:8px;border-radius:6px;border:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);box-sizing:border-box;}",
|
|
2824
|
+
"#mma-host .mma-preview-cardstyle--stamp{box-shadow:inset 0 0 0 1px var(--dsw-alias-border,#e5e7eb);position:relative;}",
|
|
2825
|
+
"#mma-host .mma-preview-cardstyle--stamp::after{content:'';position:absolute;top:4px;right:4px;width:18px;height:8px;border-radius:3px;background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
2826
|
+
"#mma-host .mma-preview-cardstyle--etch{background:transparent;}",
|
|
2827
|
+
"#mma-host .mma-preview-cardstyle--hero{box-shadow:3px 3px 0 var(--dsw-alias-border,#e5e7eb);}",
|
|
2828
|
+
"#mma-host .mma-preview-cardstyle--list{border:0;border-bottom:1px solid var(--dsw-alias-border,#e5e7eb);border-radius:0;margin:14px 8px;}",
|
|
2829
|
+
"#mma-host .mma-port-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;}",
|
|
2830
|
+
"#mma-host .mma-port-addon{display:inline-flex;align-items:center;justify-content:center;height:34px;padding:0 8px;border:1px solid var(--dsw-alias-border,#e5e7eb);border-right:0;border-radius:9px 0 0 9px;background:var(--dsw-alias-muted,#f3f4f6);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;}",
|
|
2831
|
+
"#mma-host .mma-port-row input{width:120px;border-radius:0 9px 9px 0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}",
|
|
2832
|
+
"#mma-host .mma-port-url{font-size:11px;opacity:.65;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;}",
|
|
2833
|
+
"#mma-host .mma-model-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;}",
|
|
2834
|
+
"#mma-host .mma-model-row input{flex:1 1 180px;min-width:0;}",
|
|
2835
|
+
"#mma-host .mma-status-pill{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 10px;border-radius:20px;border:1px solid var(--dsw-alias-border,#e5e7eb);font-size:11px;opacity:.75;white-space:nowrap;}",
|
|
2836
|
+
"#mma-host .mma-ghostbtn{height:30px;padding:0 10px;border:1px solid var(--dsw-alias-border,#e5e7eb);border-radius:8px;background:var(--dsw-alias-surface,#fff);color:inherit;font-size:12px;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;}",
|
|
2837
|
+
"#mma-host .mma-ghostbtn:hover{background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
2838
|
+
"#mma-host .mma-ghostbtn:disabled{opacity:.55;cursor:default;}",
|
|
2839
|
+
"#mma-host .mma-primarybtn{height:34px;padding:0 16px;border:0;border-radius:8px;background:var(--dsw-alias-primary,#2563eb);color:var(--dsw-alias-primary-fg,#fff);font-size:13px;font-weight:600;cursor:pointer;}",
|
|
2840
|
+
"#mma-host .mma-primarybtn:disabled{opacity:.45;cursor:default;}",
|
|
2841
|
+
"#mma-host .mma-settings-hint{margin:0;font-size:11.5px;opacity:.6;line-height:1.45;}",
|
|
2842
|
+
"#mma-host .mma-settings-field.is-error .mma-settings-hint{color:var(--dsw-alias-destructive,#dc2626);opacity:1;}",
|
|
2843
|
+
"#mma-host .mma-settings-rule{border:0;border-top:1px solid var(--dsw-alias-border,#e5e7eb);margin:20px 0;}",
|
|
2844
|
+
"#mma-host .mma-about-meta{margin-bottom:10px;display:flex;flex-direction:column;gap:6px;}",
|
|
2845
|
+
"#mma-host .mma-about-meta code{display:inline-block;width:fit-content;font-size:12px;padding:3px 8px;border-radius:6px;background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
2846
|
+
"#mma-host .mma-about-pkgs{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:6px;}",
|
|
2847
|
+
"#mma-host .mma-about-pkgs li{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:12px;padding:8px 10px;border-radius:9px;background:var(--dsw-alias-surface,#fff);border:1px solid var(--dsw-alias-border,#e5e7eb);}",
|
|
2848
|
+
"#mma-host .mma-about-pkgs li span{opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
|
|
2849
|
+
"#mma-host .mma-about-pkgs li code{font-size:11px;font-variant-numeric:tabular-nums;opacity:.9;}",
|
|
2850
|
+
"#mma-host .mma-about-actions{display:flex;flex-direction:column;align-items:flex-start;gap:8px;}",
|
|
2851
|
+
"#mma-host .mma-settings-foot{flex:0 0 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px;padding:10px 14px;border-top:1px solid var(--dsw-alias-border,#e5e7eb);background:var(--dsw-alias-surface,#fff);}",
|
|
2852
|
+
"#mma-host .mma-settings-foot-left{display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-width:0;}",
|
|
2853
|
+
"#mma-host .mma-settings-foot-right{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-left:auto;}",
|
|
2854
|
+
"#mma-host .mma-settings-dirty{font-size:11.5px;color:var(--dsw-alias-primary,#2563eb);}",
|
|
2855
|
+
"#mma-host .mma-settings-msg{flex-basis:100%;font-size:12px;opacity:.75;line-height:1.4;}",
|
|
2856
|
+
"#mma-host .mma-settings-msg.err{color:var(--dsw-alias-destructive,#dc2626);}",
|
|
2857
|
+
"#mma-host .mma-settings-confirm{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;padding:16px;background:color-mix(in srgb, var(--dsw-alias-fg,#111) 35%, transparent);}",
|
|
2858
|
+
/* Wide layout: data-wide from ResizeObserver (reliable on fixed #mma-host) + container query fallback. */
|
|
2859
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-body{flex-direction:row;}",
|
|
2860
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-rail{flex:0 0 148px;flex-direction:column;align-items:stretch;gap:2px;border-bottom:0;border-right:1px solid var(--dsw-alias-border,#e5e7eb);padding:14px 10px;overflow:visible;}",
|
|
2861
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-rail-title{display:block;font-size:10px;letter-spacing:.08em;text-transform:uppercase;opacity:.45;margin:0 8px 8px;}",
|
|
2862
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-rail-item{width:100%;justify-content:flex-start;text-align:left;box-shadow:none;border-radius:8px;position:relative;}",
|
|
2863
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-rail-item[data-on='1']{box-shadow:none;background:var(--dsw-alias-muted,#f3f4f6);}",
|
|
2864
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-rail-item[data-on='1']::before{content:'';position:absolute;left:0;top:6px;bottom:6px;width:2px;border-radius:2px;background:var(--dsw-alias-primary,#2563eb);}",
|
|
2865
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-content{padding:22px 26px 28px;}",
|
|
2866
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-optgrid--3{grid-template-columns:repeat(3,minmax(0,1fr));}",
|
|
2867
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-optgrid--4{grid-template-columns:repeat(4,minmax(0,1fr));}",
|
|
2868
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-field--row{flex-direction:row;align-items:flex-start;gap:16px;}",
|
|
2869
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-field--row > .mma-settings-label{flex:0 0 112px;padding-top:8px;}",
|
|
2870
|
+
"#mma-host .mma-settings[data-wide='1'] .mma-settings-field--row > .mma-settings-control{flex:1 1 auto;}",
|
|
1675
2871
|
"#mma-host .mma-browse{position:absolute;inset:0;background:var(--dsw-alias-bg,#f7f7f8);z-index:3;overflow:auto;padding:16px 18px;display:none;}",
|
|
1676
2872
|
"#mma-host .mma-browse[data-open='1']{display:block;}",
|
|
1677
2873
|
"#mma-host .mma-browse-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;}",
|
|
@@ -1708,7 +2904,15 @@ var CSS = [
|
|
|
1708
2904
|
"#mma-host .mma-diff-line--del{color:#991b1b;background:rgba(220,38,38,.10);}",
|
|
1709
2905
|
"#mma-host .mma-diff-line--ctx{color:inherit;opacity:.85;}",
|
|
1710
2906
|
"#mma-host .mma-bempty{padding:20px;opacity:.6;text-align:center;font-size:13px;}",
|
|
1711
|
-
"#mma-host .mma-berr{padding:16px;color:#b91c1c;font-size:13px;}"
|
|
2907
|
+
"#mma-host .mma-berr{padding:16px;color:#b91c1c;font-size:13px;}",
|
|
2908
|
+
"#mma-host .mma-storage-notice{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;padding:12px 14px;margin:0 0 12px;border-radius:10px;background:color-mix(in srgb, var(--dsw-alias-warning, #f59e0b) 14%, var(--dsw-alias-bg, #f7f7f8));border:1px solid color-mix(in srgb, var(--dsw-alias-warning, #f59e0b) 35%, transparent);}",
|
|
2909
|
+
"#mma-host .mma-storage-notice-body{min-width:0;flex:1;}",
|
|
2910
|
+
"#mma-host .mma-storage-notice-body b{display:block;font-size:13px;margin:0 0 4px;}",
|
|
2911
|
+
"#mma-host .mma-storage-notice-body p{margin:0;font-size:12px;line-height:1.45;opacity:.85;}",
|
|
2912
|
+
"#mma-host .mma-storage-notice-top{margin-top:6px !important;}",
|
|
2913
|
+
"#mma-host .mma-storage-notice-actions{display:flex;flex-direction:column;gap:6px;flex-shrink:0;}",
|
|
2914
|
+
"#mma-host .mma-storage-notice-actions button{font-size:12px;padding:6px 10px;border-radius:8px;border:1px solid color-mix(in srgb, currentColor 18%, transparent);background:var(--dsw-alias-bg, #fff);cursor:pointer;}",
|
|
2915
|
+
"#mma-host .mma-storage-notice-copy{font-weight:600;}"
|
|
1712
2916
|
];
|
|
1713
2917
|
function injectPanelCss() {
|
|
1714
2918
|
if (typeof document === "undefined") return;
|
|
@@ -1721,25 +2925,20 @@ function injectPanelCss() {
|
|
|
1721
2925
|
}
|
|
1722
2926
|
tag.textContent = CSS.join("\n");
|
|
1723
2927
|
}
|
|
1724
|
-
function loadCustomPalettes(host) {
|
|
1725
|
-
if (!host.palettes) return;
|
|
1726
|
-
host.palettes().then((list) => {
|
|
1727
|
-
const custom = {};
|
|
1728
|
-
for (const p of list) {
|
|
1729
|
-
custom[p.id] = { label: p.label, swatch: p.swatch, tokens: p.tokens };
|
|
1730
|
-
}
|
|
1731
|
-
setPanelState({ customPalettes: custom });
|
|
1732
|
-
}).catch(() => {
|
|
1733
|
-
});
|
|
1734
|
-
}
|
|
1735
2928
|
function createMiniAppPanel(host, options) {
|
|
1736
2929
|
const locale = resolvePanelLocale(options?.locale ?? host.locale);
|
|
1737
2930
|
const i18n = createPanelI18n(locale);
|
|
2931
|
+
const prev = getPanelState();
|
|
1738
2932
|
resetPanelState({
|
|
1739
2933
|
tabs: [{ id: "all", title: i18n.t("tabs.all"), kind: "all" }],
|
|
1740
2934
|
capabilities: capabilitiesOf(host),
|
|
1741
2935
|
locale,
|
|
1742
|
-
emptyText: host.emptyText
|
|
2936
|
+
emptyText: host.emptyText,
|
|
2937
|
+
theme: prev.theme,
|
|
2938
|
+
palette: prev.palette,
|
|
2939
|
+
dock: prev.dock,
|
|
2940
|
+
cardStyle: prev.cardStyle,
|
|
2941
|
+
visible: prev.visible
|
|
1743
2942
|
});
|
|
1744
2943
|
let rootEl = null;
|
|
1745
2944
|
let root = null;
|
|
@@ -1786,29 +2985,98 @@ function readThemePrefs(storage) {
|
|
|
1786
2985
|
return null;
|
|
1787
2986
|
}
|
|
1788
2987
|
};
|
|
1789
|
-
return {
|
|
2988
|
+
return {
|
|
2989
|
+
theme: (() => {
|
|
2990
|
+
const m = get("mma-theme-mode");
|
|
2991
|
+
return m === "system" || m === "dark" || m === "light" ? m : "light";
|
|
2992
|
+
})(),
|
|
2993
|
+
palette: get("mma-palette") || "default",
|
|
2994
|
+
cardStyle: get("mma-card-style") || "stamp"
|
|
2995
|
+
};
|
|
1790
2996
|
}
|
|
1791
2997
|
function createHostShell(opts) {
|
|
1792
2998
|
const storage = safeStorage(opts.storage);
|
|
1793
2999
|
const themePrefs = readThemePrefs(storage);
|
|
3000
|
+
let currentOrigin = opts.hostUrl.replace(/\/$/, "");
|
|
1794
3001
|
const frame = createFrameController({
|
|
1795
|
-
urlOf: (appId) => appFrameUrl(
|
|
3002
|
+
urlOf: (appId) => appFrameUrl(currentOrigin, appId, envFor(appId)),
|
|
1796
3003
|
envOf: (appId) => envFor(appId)
|
|
1797
3004
|
});
|
|
3005
|
+
let unsubEvents = null;
|
|
3006
|
+
function bindHostEvents() {
|
|
3007
|
+
unsubEvents?.();
|
|
3008
|
+
unsubEvents = subscribeHostEvents(currentOrigin, {
|
|
3009
|
+
// `mini_app_open` asked to show an app. Without this the panel opens on the list and
|
|
3010
|
+
// the agent's follow-up (`mini_app_errors`, `mini_app_view_eval`) waits on a view that
|
|
3011
|
+
// was never mounted — the dsh client already does this in its own stream handler.
|
|
3012
|
+
onOpen: (appId, title) => {
|
|
3013
|
+
optOnOpen();
|
|
3014
|
+
void host.fetchApps().then((apps) => {
|
|
3015
|
+
const app = apps.find((a) => a.id === appId);
|
|
3016
|
+
if (app) panelRef()?.actions.openAppTab(app);
|
|
3017
|
+
else if (title) console.warn(`[mma] opened app ${appId} is not registered on this host`);
|
|
3018
|
+
});
|
|
3019
|
+
},
|
|
3020
|
+
onReload: (appId) => {
|
|
3021
|
+
if (frame.map.has(appId)) frame.reload(appId);
|
|
3022
|
+
},
|
|
3023
|
+
onEval: (query) => relayViewEval(currentOrigin, frame, query),
|
|
3024
|
+
onStorageNotice: (notice) => {
|
|
3025
|
+
setPanelState({ storageNotice: notice });
|
|
3026
|
+
}
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
1798
3029
|
function envFor(appId) {
|
|
1799
3030
|
const s = getPanelState();
|
|
1800
3031
|
const app = s.apps.find((a) => a.id === appId);
|
|
1801
|
-
|
|
3032
|
+
const theme = app?.theme?.theme || s.theme;
|
|
3033
|
+
const palette = effectivePalette(app?.theme?.palette, Boolean(app?.localPalette), s.palette);
|
|
3034
|
+
const custom = { ...s.customPalettes };
|
|
3035
|
+
if (app?.localPalette) {
|
|
3036
|
+
custom[LOCAL_PALETTE_ID] = {
|
|
3037
|
+
label: app.localPalette.label,
|
|
3038
|
+
swatch: app.localPalette.swatch,
|
|
3039
|
+
tokens: app.localPalette.tokens
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
return {
|
|
3043
|
+
theme,
|
|
3044
|
+
palette,
|
|
3045
|
+
dock: s.dock,
|
|
3046
|
+
vars: themeCssVars(resolveMode(theme), palette, custom)
|
|
3047
|
+
};
|
|
3048
|
+
}
|
|
3049
|
+
async function migrateOrigin(next) {
|
|
3050
|
+
const origin = next.replace(/\/$/, "");
|
|
3051
|
+
for (let i = 0; i < 30; i++) {
|
|
3052
|
+
try {
|
|
3053
|
+
const res = await fetch(`${origin}/health`);
|
|
3054
|
+
if (res.ok) break;
|
|
3055
|
+
} catch {
|
|
3056
|
+
}
|
|
3057
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
3058
|
+
}
|
|
3059
|
+
currentOrigin = origin;
|
|
3060
|
+
try {
|
|
3061
|
+
storage?.setItem("mma-host-url", origin);
|
|
3062
|
+
} catch {
|
|
3063
|
+
}
|
|
3064
|
+
opts.onHostChange?.(origin);
|
|
3065
|
+
bindHostEvents();
|
|
3066
|
+
for (const id of [...frame.map.keys()]) frame.reload(id);
|
|
1802
3067
|
}
|
|
1803
3068
|
const host = createRestPanelHost({
|
|
1804
3069
|
hostUrl: opts.hostUrl,
|
|
3070
|
+
getHostUrl: () => currentOrigin,
|
|
1805
3071
|
storage,
|
|
1806
3072
|
cardStyle: opts.cardStyle,
|
|
1807
3073
|
locale: opts.locale ?? void 0,
|
|
1808
3074
|
emptyText: opts.emptyText,
|
|
1809
3075
|
onOpen: () => optOnOpen(),
|
|
1810
3076
|
onClose: () => optOnClose(),
|
|
1811
|
-
onHostChange: (next) =>
|
|
3077
|
+
onHostChange: (next) => {
|
|
3078
|
+
void migrateOrigin(next);
|
|
3079
|
+
},
|
|
1812
3080
|
frameController: {
|
|
1813
3081
|
url: (appId) => frame.url(appId),
|
|
1814
3082
|
// Lazy-bind the frames container (React may not have rendered #mma-frames yet).
|
|
@@ -1835,6 +3103,10 @@ function createHostShell(opts) {
|
|
|
1835
3103
|
}
|
|
1836
3104
|
let panel = null;
|
|
1837
3105
|
let containerEl = null;
|
|
3106
|
+
function panelRef() {
|
|
3107
|
+
if (!panel) panel = createMiniAppPanel(host);
|
|
3108
|
+
return panel;
|
|
3109
|
+
}
|
|
1838
3110
|
function optOnOpen() {
|
|
1839
3111
|
setPanelState({ visible: true });
|
|
1840
3112
|
opts.onOpen?.();
|
|
@@ -1857,15 +3129,15 @@ function createHostShell(opts) {
|
|
|
1857
3129
|
host,
|
|
1858
3130
|
frames: frame,
|
|
1859
3131
|
get panel() {
|
|
1860
|
-
|
|
1861
|
-
return panel;
|
|
3132
|
+
return panelRef();
|
|
1862
3133
|
},
|
|
1863
3134
|
mount(el) {
|
|
1864
3135
|
containerEl = document.createElement("div");
|
|
1865
3136
|
containerEl.id = "mma-host";
|
|
1866
3137
|
containerEl.setAttribute("data-ready", "1");
|
|
1867
3138
|
containerEl.setAttribute("data-dock", getPanelState().dock);
|
|
1868
|
-
containerEl.setAttribute("data-cardstyle",
|
|
3139
|
+
containerEl.setAttribute("data-cardstyle", themePrefs.cardStyle);
|
|
3140
|
+
bindHostEvents();
|
|
1869
3141
|
Object.assign(containerEl.style, {
|
|
1870
3142
|
position: "fixed",
|
|
1871
3143
|
top: "0",
|
|
@@ -1881,14 +3153,24 @@ function createHostShell(opts) {
|
|
|
1881
3153
|
});
|
|
1882
3154
|
const target = el ?? document.body;
|
|
1883
3155
|
target.appendChild(containerEl);
|
|
1884
|
-
|
|
1885
|
-
|
|
3156
|
+
const cardStyle = themePrefs.cardStyle;
|
|
3157
|
+
setPanelState({
|
|
3158
|
+
theme: themePrefs.theme,
|
|
3159
|
+
palette: themePrefs.palette,
|
|
3160
|
+
cardStyle,
|
|
3161
|
+
visible: true
|
|
3162
|
+
});
|
|
1886
3163
|
this.panel.mount(containerEl);
|
|
3164
|
+
applyThemeTo(containerEl, themePrefs.theme, themePrefs.palette);
|
|
3165
|
+
setPanelState({ theme: themePrefs.theme, palette: themePrefs.palette, cardStyle });
|
|
3166
|
+
containerEl.setAttribute("data-cardstyle", cardStyle);
|
|
1887
3167
|
const framesEl = containerEl.querySelector("#mma-frames");
|
|
1888
3168
|
if (framesEl) frame.setContainer(framesEl);
|
|
1889
3169
|
void this.panel.actions.fetchApps();
|
|
1890
3170
|
},
|
|
1891
3171
|
unmount() {
|
|
3172
|
+
unsubEvents?.();
|
|
3173
|
+
unsubEvents = null;
|
|
1892
3174
|
panel?.unmount();
|
|
1893
3175
|
panel = null;
|
|
1894
3176
|
frame.unmountAll();
|
|
@@ -1920,4 +3202,4 @@ function createHostShell(opts) {
|
|
|
1920
3202
|
// src/index.ts
|
|
1921
3203
|
var packageName = "@monkey-mini-app/panel";
|
|
1922
3204
|
|
|
1923
|
-
export { AppList, Browse, HostUnreachableError, LOCALE_IDS, ListRegion, Loading, MiniAppPanel, Modal, PANEL_CSS_TAG, PanelError, PanelProvider, Settings, Tabs, ThemePop, Toolbar, activeAppFrom, appBlurb, appFrameUrl, capabilitiesOf, clampPaletteId, createFrameController, createHostShell, createMiniAppPanel, createPanelActions, createPanelI18n, createRestPanelHost, defaultHideThemePop, formToHostConfigBody, getPanelState, hostConfigToForm, hue, injectPanelCss, isHostUnreachable, monoOf, packageName, parseAppsResponse, parseCommitDetail, parseCommitList, parsePalettes, parseStorageTables, readJson, resetPanelState, resolvePanelLocale, setPanelState, subscribePanel, usePanelActions, usePanelI18n, usePanelState };
|
|
3205
|
+
export { AppList, Browse, HostUnreachableError, LOCALE_IDS, ListRegion, Loading, MiniAppPanel, Modal, PANEL_CSS_TAG, PanelError, PanelProvider, Settings, Tabs, ThemePop, Toolbar, activeAppFrom, appBlurb, appFrameUrl, capabilitiesOf, clampPaletteId, createFrameController, createHostShell, createMiniAppPanel, createPanelActions, createPanelI18n, createRestPanelHost, defaultHideThemePop, formToHostConfigBody, getPanelState, hostConfigToForm, hue, injectPanelCss, isHostUnreachable, monoOf, packageName, parseAppsResponse, parseCommitDetail, parseCommitList, parsePalettes, parseStorageTables, readJson, relayViewEval, resetPanelState, resolvePanelLocale, setPanelState, subscribeHostEvents, subscribePanel, usePanelActions, usePanelI18n, usePanelState };
|