waybetter 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/bin/waybetter.mjs +2 -5
- package/cli/buildenv.mjs +1 -1
- package/cli/release.mjs +11 -18
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +4 -4
- package/cli/store.mjs +80 -28
- package/cli/strings.mjs +2 -0
- package/dist/runtime/stringPackHook.js +2 -2
- package/dist/runtime/stringPackHook.js.map +1 -1
- package/dist/runtime/stringPackTranslate.d.ts +3 -1
- package/dist/runtime/stringPackTranslate.js +6 -3
- package/dist/runtime/stringPackTranslate.js.map +1 -1
- package/dist/runtime/stringPacks.d.ts +53 -5
- package/dist/runtime/stringPacks.js +161 -25
- package/dist/runtime/stringPacks.js.map +1 -1
- package/dist/runtime/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.js.map +1 -0
- package/dist/runtime/themeComponents.js +16 -3
- package/dist/runtime/themeComponents.js.map +1 -1
- package/dist/runtime/themeDecor.js +3 -1
- package/dist/runtime/themeDecor.js.map +1 -1
- package/dist/runtime/themeDerive.d.ts +69 -0
- package/dist/runtime/themeDerive.js +117 -0
- package/dist/runtime/themeDerive.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +44 -3
- package/dist/runtime/themeDoctor.js +86 -25
- package/dist/runtime/themeDoctor.js.map +1 -1
- package/dist/runtime/themeGuards.d.ts +60 -0
- package/dist/runtime/themeGuards.js +235 -0
- package/dist/runtime/themeGuards.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +1 -1
- package/dist/runtime/themeIcons.js +13 -5
- package/dist/runtime/themeIcons.js.map +1 -1
- package/dist/runtime/themeInk.d.ts +37 -0
- package/dist/runtime/themeInk.js +111 -0
- package/dist/runtime/themeInk.js.map +1 -0
- package/dist/runtime/themeInvariants.d.ts +39 -0
- package/dist/runtime/themeInvariants.js +273 -0
- package/dist/runtime/themeInvariants.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +15 -1
- package/dist/runtime/themeRuntime.js +78 -5
- package/dist/runtime/themeRuntime.js.map +1 -1
- package/dist/runtime/themeSpec.d.ts +5 -1
- package/dist/runtime/themeSpec.js +9 -13
- package/dist/runtime/themeSpec.js.map +1 -1
- package/dist/shell/InstallDialog.js +14 -8
- package/dist/shell/InstallDialog.js.map +1 -1
- package/dist/shell/StoreView.d.ts +12 -0
- package/dist/shell/StoreView.js +9 -4
- package/dist/shell/StoreView.js.map +1 -1
- package/dist/shell/frame/AppMenu.d.ts +26 -3
- package/dist/shell/frame/AppMenu.js +106 -27
- package/dist/shell/frame/AppMenu.js.map +1 -1
- package/dist/shell/frame/FindBar.js +1 -1
- package/dist/shell/frame/FindBar.js.map +1 -1
- package/dist/shell/frame/Shell.d.ts +1 -0
- package/dist/shell/frame/Shell.js +10 -2
- package/dist/shell/frame/Shell.js.map +1 -1
- package/dist/shell/frame/Titlebar.d.ts +2 -1
- package/dist/shell/frame/Titlebar.js +5 -3
- package/dist/shell/frame/Titlebar.js.map +1 -1
- package/dist/shell/frame/WebPanel.js +4 -1
- package/dist/shell/frame/WebPanel.js.map +1 -1
- package/dist/shell/frame/accountSwitcher.css +10 -10
- package/dist/shell/frame/appMenu.css +19 -13
- package/dist/shell/frame/boot.js +2 -0
- package/dist/shell/frame/boot.js.map +1 -1
- package/dist/shell/frame/chromeTheme.d.ts +19 -1
- package/dist/shell/frame/chromeTheme.js +51 -14
- package/dist/shell/frame/chromeTheme.js.map +1 -1
- package/dist/shell/frame/deck.css +30 -30
- package/dist/shell/frame/edges.css +159 -0
- package/dist/shell/frame/index.d.ts +2 -2
- package/dist/shell/frame/index.js +1 -1
- package/dist/shell/frame/index.js.map +1 -1
- package/dist/shell/frame/mediaModel.d.ts +13 -0
- package/dist/shell/frame/mediaModel.js +14 -0
- package/dist/shell/frame/mediaModel.js.map +1 -1
- package/dist/shell/frame/menuMessages.en.json +43 -1
- package/dist/shell/frame/menuModel.d.ts +42 -0
- package/dist/shell/frame/menuModel.js +8 -0
- package/dist/shell/frame/menuModel.js.map +1 -1
- package/dist/shell/frame/nativeMenu.d.ts +5 -0
- package/dist/shell/frame/nativeMenu.js +178 -0
- package/dist/shell/frame/nativeMenu.js.map +1 -0
- package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
- package/dist/shell/frame/nativeMenuModel.js +186 -0
- package/dist/shell/frame/nativeMenuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.js +3 -1
- package/dist/shell/frame/paletteModel.js.map +1 -1
- package/dist/shell/frame/paneTheme.css +1 -1
- package/dist/shell/frame/reportModel.d.ts +1 -1
- package/dist/shell/frame/reportModel.js +1 -1
- package/dist/shell/frame/reportModel.js.map +1 -1
- package/dist/shell/frame/shell.css +56 -51
- package/dist/shell/frame/state.d.ts +2 -0
- package/dist/shell/frame/state.js +3 -1
- package/dist/shell/frame/state.js.map +1 -1
- package/dist/shell/frame/themeStore.js +21 -6
- package/dist/shell/frame/themeStore.js.map +1 -1
- package/dist/shell/frame/workspaces.css +12 -12
- package/dist/shell/installController.d.ts +16 -1
- package/dist/shell/installController.js +31 -5
- package/dist/shell/installController.js.map +1 -1
- package/dist/shell/panel/Appearance.js +12 -3
- package/dist/shell/panel/Appearance.js.map +1 -1
- package/dist/shell/panel/Settings.d.ts +1 -1
- package/dist/shell/panel/Settings.js +4 -3
- package/dist/shell/panel/Settings.js.map +1 -1
- package/dist/shell/panel/StoreSection.d.ts +2 -1
- package/dist/shell/panel/StoreSection.js +31 -1
- package/dist/shell/panel/StoreSection.js.map +1 -1
- package/dist/shell/panel/StringPacks.d.ts +12 -3
- package/dist/shell/panel/StringPacks.js +33 -8
- package/dist/shell/panel/StringPacks.js.map +1 -1
- package/dist/shell/panel/backup.css +1 -1
- package/dist/shell/panel/builder.css +48 -40
- package/dist/shell/panel/make.css +8 -7
- package/dist/shell/panel/panel.css +401 -401
- package/dist/shell/panel/panelMessages.d.ts +41 -1
- package/dist/shell/panel/panelMessages.js +13 -1
- package/dist/shell/panel/panelMessages.js.map +1 -1
- package/dist/shell/panel/plugins.css +5 -5
- package/dist/shell/panel/strings.css +1 -1
- package/dist/shell/store.css +34 -14
- package/dist/shell/storeMessages.d.ts +24 -0
- package/dist/shell/storeMessages.js +24 -0
- package/dist/shell/storeMessages.js.map +1 -1
- package/dist/shell/storeModel.d.ts +31 -7
- package/dist/shell/storeModel.js +15 -2
- package/dist/shell/storeModel.js.map +1 -1
- package/dist/shell/stringPacksModel.js +7 -2
- package/dist/shell/stringPacksModel.js.map +1 -1
- package/icons.schema.json +9 -0
- package/locales/ar.json +109 -2
- package/locales/bg.json +109 -2
- package/locales/bn.json +109 -2
- package/locales/ca.json +109 -2
- package/locales/cs.json +109 -2
- package/locales/da.json +109 -2
- package/locales/de.json +109 -2
- package/locales/el.json +109 -2
- package/locales/en.json +108 -2
- package/locales/es.json +109 -2
- package/locales/eu.json +109 -2
- package/locales/fa.json +109 -2
- package/locales/fi.json +109 -2
- package/locales/fil.json +109 -2
- package/locales/fr.json +109 -2
- package/locales/ga.json +109 -2
- package/locales/gl.json +109 -2
- package/locales/gu.json +109 -2
- package/locales/ha.json +109 -2
- package/locales/he.json +109 -2
- package/locales/hi.json +109 -2
- package/locales/hr.json +109 -2
- package/locales/hu.json +110 -2
- package/locales/id.json +109 -2
- package/locales/ig.json +109 -2
- package/locales/it.json +109 -2
- package/locales/ja.json +109 -2
- package/locales/kn.json +109 -2
- package/locales/ko.json +109 -2
- package/locales/mr.json +109 -2
- package/locales/ms.json +109 -2
- package/locales/nb.json +109 -2
- package/locales/nl.json +109 -2
- package/locales/pl.json +109 -2
- package/locales/pt.json +109 -2
- package/locales/ro.json +109 -2
- package/locales/ru.json +109 -2
- package/locales/sk.json +109 -2
- package/locales/sr.json +109 -2
- package/locales/sv.json +109 -2
- package/locales/ta.json +109 -2
- package/locales/th.json +109 -2
- package/locales/tr.json +109 -2
- package/locales/uk.json +109 -2
- package/locales/ur.json +109 -2
- package/locales/vi.json +109 -2
- package/locales/yo.json +109 -2
- package/locales/zh-Hans.json +109 -2
- package/locales/zh-Hant.json +109 -2
- package/package.json +2 -3
- package/store-catalog.schema.json +18 -5
- package/theme.schema.json +9 -0
- package/windows/installer.nsi +22 -2
- package/cli/privacy.mjs +0 -768
|
@@ -7,6 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
7
7
|
// its tab webviews while it is open (`setOverlay`). Styles: `store.css` (framework `--wb-*` tokens).
|
|
8
8
|
import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
10
|
+
import { GlyphPaths } from "./frame/iconPack.js";
|
|
10
11
|
import { formatBytes, permissionBadges, previewLines } from "./storeModel.js";
|
|
11
12
|
import { coveragePercent } from "./stringPacksModel.js";
|
|
12
13
|
/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */
|
|
@@ -30,6 +31,7 @@ const G = {
|
|
|
30
31
|
warn: 'M12 4l9 16H3zM12 10v4M12 17h.01',
|
|
31
32
|
copy: 'M9 9h10v10H9zM5 15V5h10',
|
|
32
33
|
close: 'M6 6l12 12M18 6L6 18',
|
|
34
|
+
icons: 'M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM17 14v6M14 17h6',
|
|
33
35
|
strings: 'M4 5h9M8.5 3v2M11 5c-.8 3.8-3.4 6.6-7 8M6.5 8.5c1.1 1.6 2.7 3 4.5 3.8M13 21l4-9 4 9M14.4 18h5.2',
|
|
34
36
|
};
|
|
35
37
|
function Fact({ label, children, wide }) {
|
|
@@ -67,24 +69,26 @@ function Ready({ request, props }) {
|
|
|
67
69
|
const [armed, setArmed] = useState(false);
|
|
68
70
|
// On by default only when it is from the signed store or declares its permissions and the code
|
|
69
71
|
// scan found nothing to point out; otherwise the owner turns it on deliberately.
|
|
70
|
-
const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));
|
|
72
|
+
const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || preview.kind === 'icons' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));
|
|
71
73
|
const [copied, setCopied] = useState(false);
|
|
72
74
|
useEffect(() => { const timer = setTimeout(() => setArmed(true), REVIEW_MS); return () => clearTimeout(timer); }, [preview.token]);
|
|
73
75
|
const strings = preview.kind === 'strings' ? preview.strings ?? null : null;
|
|
74
76
|
const summary = strings ? props.stringsSummary?.(preview.text) ?? null : null;
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
+
const pack = preview.kind === 'icons' ? request.pack ?? null : null;
|
|
78
|
+
const icons = preview.kind === 'icons' ? preview.icons ?? null : null;
|
|
79
|
+
const name = plugin?.name ?? facts?.name ?? preview.theme?.name ?? strings?.name ?? pack?.name ?? icons?.name ?? t('wb.install.untitled');
|
|
80
|
+
const author = plugin?.author || facts?.author || preview.theme?.author || strings?.authors.join(', ') || pack?.author || icons?.author || '';
|
|
77
81
|
const version = preview.version || preview.store?.version || '';
|
|
78
82
|
const updating = preview.existing && !preview.existing.same;
|
|
79
83
|
const verb = preview.existing?.same ? t('wb.install.reinstall') : updating || ready?.replaces ? t('wb.install.update') : t('wb.store.install');
|
|
80
84
|
const step = preview.existing?.same ? 'reinstall' : updating || ready?.replaces ? 'update' : 'install';
|
|
81
|
-
const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });
|
|
85
|
+
const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : preview.kind === 'icons' ? t(`wb.install.eyebrow.icons.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });
|
|
82
86
|
const badges = preview.kind === 'plugin' ? permissionBadges(plugin?.permissions, t, site) : [];
|
|
83
87
|
const installing = request.status === 'installing';
|
|
84
|
-
const description = plugin?.description || facts?.description || strings?.description;
|
|
85
|
-
return _jsxs(_Fragment, { children: [_jsxs("header", { className: "wbi-head", children: [_jsx("div", { className: `wbi-tile is-${preview.kind}`, style: facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined, children: _jsx(Glyph, { d: preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : G.theme, size: 22 }) }), _jsxs("div", { className: "wbi-title", children: [_jsx("span", { className: "wbi-eyebrow", children: eyebrow }), _jsx("h2", { id: "wbi-title", children: name }), _jsx("p", { children: [author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor') })] }), _jsx("button", { className: `${classes.icon} wbi-close`, "aria-label": t('wb.install.cancel'), onClick: () => void controller.cancel(), children: props.closeIcon ?? _jsx(Glyph, { d: G.close, size: 16 }) })] }), _jsxs("div", { className: "wbi-body", children: [_jsxs("div", { className: `wbi-source is-${preview.source.kind}`, children: [_jsx(Glyph, { d: sourceIcon(preview) }), _jsxs("div", { children: [_jsx("strong", { children: sourceLabel(preview.source, t) }), preview.source.url && _jsx("code", { title: preview.source.url, children: preview.source.url })] }), preview.source.signed && _jsxs("span", { className: "wbi-verified", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.verified')] })] }), description && _jsx("p", { className: "wbi-desc", children: description }), _jsxs("dl", { className: "wbi-facts", children: [preview.file && _jsx(Fact, { label: t('wb.install.file'), children: preview.file }), _jsx(Fact, { label: t('wb.install.size'), children: formatBytes(preview.size) }), preview.existing && _jsx(Fact, { label: t('wb.install.installedNow'), children: preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}` }), ready?.replaces && _jsx(Fact, { label: t('wb.install.replaces'), children: t('wb.install.replacesValue') }), preview.store?.license && _jsx(Fact, { label: t('wb.install.license'), children: preview.store.license }), preview.store?.credits && _jsx(Fact, { label: t('wb.install.credits'), wide: true, children: preview.store.credits }), _jsxs(Fact, { label: "SHA-256", wide: true, children: [_jsx("span", { className: "wbi-hash", children: preview.sha256 }), _jsx("button", { className: "wbi-copy", "aria-label": t('wb.install.copyHash'), onClick: () => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => { }), children: _jsx(Glyph, { d: copied ? G.check : G.copy, size: 14 }) })] })] }), preview.kind === 'plugin' && _jsxs("section", { className: "wbi-perms", "aria-label": t('wb.store.permissions'), children: [_jsx("h3", { children: t('wb.install.permissions') }), _jsx("ul", { children: badges.map(badge => _jsxs("li", { className: `is-${badge.tone}`, children: [_jsx("span", { className: "wbi-chip", children: badge.label }), _jsx("span", { children: badge.detail })] }, badge.id)) }), _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.pageAccess', { site })] }), preview.findings.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.theCode') }), preview.findings.map(finding => _jsx("span", { children: finding }, finding))] })] }), strings && _jsxs("section", { className: "wbi-perms wbi-strings", "aria-label": t('wb.store.stringsItem'), children: [_jsxs("p", { className: "wbi-note is-ok", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.strings.dataOnly', { site })] }), _jsxs("dl", { className: "wbi-facts", children: [_jsx(Fact, { label: t('wb.install.strings.language'), children: strings.language }), _jsx(Fact, { label: t('wb.install.strings.coverage'), wide: true, children: summary && !summary.otherCatalog
|
|
88
|
+
const description = plugin?.description || facts?.description || strings?.description || pack?.description;
|
|
89
|
+
return _jsxs(_Fragment, { children: [_jsxs("header", { className: "wbi-head", children: [_jsx("div", { className: `wbi-tile is-${preview.kind}`, style: facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined, children: _jsx(Glyph, { d: preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : preview.kind === 'icons' ? G.icons : G.theme, size: 22 }) }), _jsxs("div", { className: "wbi-title", children: [_jsx("span", { className: "wbi-eyebrow", children: eyebrow }), _jsx("h2", { id: "wbi-title", children: name }), _jsx("p", { children: [author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor') })] }), _jsx("button", { className: `${classes.icon} wbi-close`, "aria-label": t('wb.install.cancel'), onClick: () => void controller.cancel(), children: props.closeIcon ?? _jsx(Glyph, { d: G.close, size: 16 }) })] }), _jsxs("div", { className: "wbi-body", children: [_jsxs("div", { className: `wbi-source is-${preview.source.kind}`, children: [_jsx(Glyph, { d: sourceIcon(preview) }), _jsxs("div", { children: [_jsx("strong", { children: sourceLabel(preview.source, t) }), preview.source.url && _jsx("code", { title: preview.source.url, children: preview.source.url })] }), preview.source.signed && _jsxs("span", { className: "wbi-verified", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.verified')] })] }), description && _jsx("p", { className: "wbi-desc", children: description }), _jsxs("dl", { className: "wbi-facts", children: [preview.file && _jsx(Fact, { label: t('wb.install.file'), children: preview.file }), _jsx(Fact, { label: t('wb.install.size'), children: formatBytes(preview.size) }), preview.existing && _jsx(Fact, { label: t('wb.install.installedNow'), children: preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}` }), ready?.replaces && _jsx(Fact, { label: t('wb.install.replaces'), children: t('wb.install.replacesValue') }), preview.store?.license && _jsx(Fact, { label: t('wb.install.license'), children: preview.store.license }), preview.store?.credits && _jsx(Fact, { label: t('wb.install.credits'), wide: true, children: preview.store.credits }), _jsxs(Fact, { label: "SHA-256", wide: true, children: [_jsx("span", { className: "wbi-hash", children: preview.sha256 }), _jsx("button", { className: "wbi-copy", "aria-label": t('wb.install.copyHash'), onClick: () => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => { }), children: _jsx(Glyph, { d: copied ? G.check : G.copy, size: 14 }) })] })] }), preview.kind === 'plugin' && _jsxs("section", { className: "wbi-perms", "aria-label": t('wb.store.permissions'), children: [_jsx("h3", { children: t('wb.install.permissions') }), _jsx("ul", { children: badges.map(badge => _jsxs("li", { className: `is-${badge.tone}`, children: [_jsx("span", { className: "wbi-chip", children: badge.label }), _jsx("span", { children: badge.detail })] }, badge.id)) }), _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.pageAccess', { site })] }), preview.findings.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.theCode') }), preview.findings.map(finding => _jsx("span", { children: finding }, finding))] })] }), strings && _jsxs("section", { className: "wbi-perms wbi-strings", "aria-label": t('wb.store.stringsItem'), children: [_jsxs("p", { className: "wbi-note is-ok", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.strings.dataOnly', { site })] }), _jsxs("dl", { className: "wbi-facts", children: [_jsx(Fact, { label: t('wb.install.strings.language'), children: strings.language }), _jsx(Fact, { label: t('wb.install.strings.coverage'), wide: true, children: summary && !summary.otherCatalog
|
|
86
90
|
? t('wb.install.strings.coverageValue', { translated: String(summary.translated), translatable: String(summary.translatable), site, percent: coveragePercent(summary) })
|
|
87
|
-
: t('wb.install.strings.count', { count: strings.strings }) })] }), summary?.otherCatalog && _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.strings.otherCatalog', { site })] }), summary && !summary.otherCatalog && _jsxs("ul", { className: "wbi-strings-notes", children: [summary.closed > 0 && _jsx("li", { children: t('wb.install.strings.closed', { count: summary.closed, site }) }), summary.unknown > 0 && _jsx("li", { children: t('wb.install.strings.unknown', { count: summary.unknown, site }) }), summary.refused > 0 && _jsx("li", { children: t('wb.install.strings.refused', { count: summary.refused, site }) })] }), summary && summary.sample.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.strings.sample') }), summary.sample.map(text => _jsx("span", { children: text }, text))] })] }), theme !== null && _jsxs("section", { className: "wbi-theme", children: [props.renderThemePreview?.(theme), (ready?.warnings.length ?? 0) > 0 && _jsx("ul", { className: "wbi-warnings", children: ready.warnings.map(warning => _jsx("li", { children: warning }, warning)) })] }), facts?.css ? _jsx(CodePreview, { t: t, text: facts.css, label: t('wb.install.themeCss', { site }) }) : null, _jsx(CodePreview, { t: t, text: preview.text, label: preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : t('wb.install.themeFile') })] }), _jsxs("footer", { className: "wbi-foot", children: [_jsxs("label", { className: "wbi-check", children: [_jsx("input", { type: "checkbox", checked: enable, disabled: installing || Boolean(preview.existing?.enabled), onChange: event => setEnable(event.target.checked) }), _jsx("span", { children: preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow') })] }), _jsx("span", { className: "wbi-foot-end" }), _jsx("button", { className: classes.secondary, onClick: () => void controller.cancel(), disabled: installing, children: t('wb.install.cancel') }), _jsx("button", { className: `${classes.primary} wbi-install${armed ? '' : ' is-arming'}`, disabled: !armed || installing, onClick: () => void controller.confirm(enable), children: installing ? t('wb.install.installing') : verb })] })] });
|
|
91
|
+
: t('wb.install.strings.count', { count: strings.strings }) })] }), summary?.otherCatalog && _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.strings.otherCatalog', { site })] }), summary && !summary.otherCatalog && _jsxs("ul", { className: "wbi-strings-notes", children: [summary.closed > 0 && _jsx("li", { children: t('wb.install.strings.closed', { count: summary.closed, site }) }), summary.unknown > 0 && _jsx("li", { children: t('wb.install.strings.unknown', { count: summary.unknown, site }) }), summary.refused > 0 && _jsx("li", { children: t('wb.install.strings.refused', { count: summary.refused, site }) })] }), summary && summary.sample.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.strings.sample') }), summary.sample.map(text => _jsx("span", { children: text }, text))] })] }), pack && _jsxs("section", { className: "wbi-perms wbi-icons", "aria-label": t('wb.store.iconsItem'), children: [_jsxs("p", { className: "wbi-note is-ok", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.icons.dataOnly')] }), _jsxs("dl", { className: "wbi-facts", children: [_jsx(Fact, { label: t('wb.install.icons.license'), children: pack.license }), _jsx(Fact, { label: t('wb.install.icons.count'), children: t('wb.install.icons.countValue', { count: Object.keys(pack.glyphs).length }) }), pack.source && _jsx(Fact, { label: t('wb.install.icons.source'), wide: true, children: pack.source }), pack.credits && _jsx(Fact, { label: t('wb.install.credits'), wide: true, children: pack.credits })] }), _jsx("div", { className: "wbi-pack-grid", "aria-hidden": "true", children: Object.keys(pack.glyphs).map(glyph => _jsx("span", { title: glyph, children: _jsx("svg", { viewBox: "0 0 24 24", children: _jsx(GlyphPaths, { glyph: pack.glyphs[glyph], pack: pack }) }) }, glyph)) }), (ready?.warnings.length ?? 0) > 0 && _jsx("ul", { className: "wbi-warnings", children: ready.warnings.map(warning => _jsx("li", { children: warning }, warning)) })] }), theme !== null && _jsxs("section", { className: "wbi-theme", children: [props.renderThemePreview?.(theme), (ready?.warnings.length ?? 0) > 0 && _jsx("ul", { className: "wbi-warnings", children: ready.warnings.map(warning => _jsx("li", { children: warning }, warning)) })] }), facts?.css ? _jsx(CodePreview, { t: t, text: facts.css, label: t('wb.install.themeCss', { site }) }) : null, _jsx(CodePreview, { t: t, text: preview.text, label: preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : preview.kind === 'icons' ? t('wb.install.icons.file') : t('wb.install.themeFile') })] }), _jsxs("footer", { className: "wbi-foot", children: [_jsxs("label", { className: "wbi-check", children: [_jsx("input", { type: "checkbox", checked: enable, disabled: installing || Boolean(preview.existing?.enabled), onChange: event => setEnable(event.target.checked) }), _jsx("span", { children: preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow') })] }), _jsx("span", { className: "wbi-foot-end" }), _jsx("button", { className: classes.secondary, onClick: () => void controller.cancel(), disabled: installing, children: t('wb.install.cancel') }), _jsx("button", { className: `${classes.primary} wbi-install${armed ? '' : ' is-arming'}`, disabled: !armed || installing, onClick: () => void controller.confirm(enable), children: installing ? t('wb.install.installing') : verb })] })] });
|
|
88
92
|
}
|
|
89
93
|
function Done({ request, props }) {
|
|
90
94
|
const { t, site, controller, classes } = props;
|
|
@@ -92,7 +96,9 @@ function Done({ request, props }) {
|
|
|
92
96
|
? (request.enabled ? t('wb.install.done.pluginOn', { site }) : t('wb.install.done.pluginOff'))
|
|
93
97
|
: request.kind === 'strings'
|
|
94
98
|
? (request.enabled ? t('wb.install.done.stringsOn', { site }) : t('wb.install.done.stringsOff'))
|
|
95
|
-
:
|
|
99
|
+
: request.kind === 'icons'
|
|
100
|
+
? (request.enabled ? t('wb.install.done.iconsOn') : t('wb.install.done.iconsOff'))
|
|
101
|
+
: (request.enabled ? t('wb.install.done.themeOn') : t('wb.install.done.themeOff')) }), request.fonts.length > 0 && _jsx("p", { className: "wbi-muted", children: t('wb.install.done.fonts', { fonts: request.fonts.join(', ') }) }), _jsxs("div", { className: "wbi-state-actions", children: [_jsx("button", { className: classes.secondary, onClick: () => { controller.close(); props.openSection(request.kind); }, children: request.kind === 'plugin' ? t('wb.install.openPlugins') : request.kind === 'strings' ? t('wb.install.openStrings') : t('wb.install.openAppearance') }), _jsx("button", { className: classes.primary, autoFocus: true, onClick: controller.close, children: t('wb.install.doneButton') })] })] });
|
|
96
102
|
}
|
|
97
103
|
function Dialog({ request, props }) {
|
|
98
104
|
const { t, controller, classes, setOverlay } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallDialog.js","sourceRoot":"","sources":["../../../../../shell/src/InstallDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["// The install screen, shared by every wayBetter app: every theme or plugin that is not copied into\n// the plugins folder by hand (a waybetter:// link, a dropped file, the Store) is shown here first\n// with its name, author, version, where it came from, its sha256, the permissions a plugin declares\n// and the exact code or CSS that will be written. Nothing installs until Install is pressed (enabled\n// after a moment, so a stray click or Enter cannot confirm it). Lives in the shell; the app hides\n// its tab webviews while it is open (`setOverlay`). Styles: `store.css` (framework `--wb-*` tokens).\n\nimport { useEffect, useRef, useState, useSyncExternalStore, type KeyboardEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { InstallController, InstallRequest } from './installController.ts';\nimport type { StoreText } from './storeMessages.ts';\nimport { formatBytes, permissionBadges, previewLines, type InstallKind, type InstallPreview } from './storeModel.ts';\nimport { coveragePercent, type StringsSummary } from './stringPacksModel.ts';\n\n/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */\nexport const REVIEW_MS = 1000;\nconst PREVIEW_LINES = 160;\n\n/** Class names for the app's own buttons (defaults: the framework's `.wb-btn`). */\nexport type InstallClassNames = { primary: string; secondary: string; icon: string; pop: string };\nconst DEFAULT_CLASSES: InstallClassNames = { primary: 'wb-btn is-primary', secondary: 'wb-btn', icon: 'wb-icon-btn', pop: '' };\n\nexport type InstallHostProps<Theme> = {\n controller: InstallController<Theme>;\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n /** Shows or hides the app's tab webviews under the screen (+1 when it opens, -1 when it closes). */\n setOverlay(delta: 1 | -1): void;\n /** \"Open Plugins\" / \"Open Appearance\" after an install. */\n openSection(kind: InstallKind): void;\n /** A live preview of a staged theme (the app's theme preview). */\n renderThemePreview?(theme: Theme): ReactNode;\n /** A string pack's coverage against the site's inventory (the app has the inventory). */\n stringsSummary?(text: string): StringsSummary | null;\n /** Drops on elements matching this selector are handled by them (e.g. an import box). */\n ownDropTargets?: string;\n closeIcon?: ReactNode;\n classNames?: Partial<InstallClassNames>;\n};\n\n/** Re-renders with the controller's current request. */\nexport function useInstallRequest<Theme>(controller: InstallController<Theme>): InstallRequest<Theme> | null {\n return useSyncExternalStore(controller.subscribe, controller.current, controller.current);\n}\n\nfunction Glyph({ d, size = 18 }: { d: string; size?: number }) {\n return <svg width={size} height={size} viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d={d} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>;\n}\nconst G = {\n plugin: 'M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0zM12 17v4',\n theme: 'M12 3a9 9 0 1 0 0 18c1.5 0 2-1 2-1.8 0-1.2-.9-1.5-.9-2.5 0-1 .8-1.7 1.8-1.7h2A4.2 4.2 0 0 0 21 10.8 8.8 8.8 0 0 0 12 3zM7.5 11h.01M10.5 7.5h.01M15 8h.01',\n shield: 'M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6z',\n check: 'M5 12.5l4.2 4.2L19 7',\n link: 'M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1',\n file: 'M7 3h7l5 5v13H7zM14 3v5h5',\n warn: 'M12 4l9 16H3zM12 10v4M12 17h.01',\n copy: 'M9 9h10v10H9zM5 15V5h10',\n close: 'M6 6l12 12M18 6L6 18',\n strings: 'M4 5h9M8.5 3v2M11 5c-.8 3.8-3.4 6.6-7 8M6.5 8.5c1.1 1.6 2.7 3 4.5 3.8M13 21l4-9 4 9M14.4 18h5.2',\n};\n\nfunction Fact({ label, children, wide }: { label: string; children: ReactNode; wide?: boolean }) {\n return <div className={`wbi-fact${wide ? ' is-wide' : ''}`}><dt>{label}</dt><dd>{children}</dd></div>;\n}\n\nfunction CodePreview({ text, label, t }: { text: string; label: string; t: StoreText }) {\n const [all, setAll] = useState(false);\n const { lines, hidden } = previewLines(text, PREVIEW_LINES, all);\n return <section className=\"wbi-code\" aria-label={label}>\n <header><span>{label}</span><small>{t('wb.install.lines', { count: text.split('\\n').length })}</small></header>\n <pre tabIndex={0}><code>{lines.map((line, i) => <span key={i} className=\"wbi-line\"><i>{i + 1}</i>{line || ' '}</span>)}</code></pre>\n {hidden > 0 && <button className=\"wbi-more\" onClick={() => setAll(true)}>{t('wb.install.moreLines', { count: hidden })}</button>}\n </section>;\n}\n\nfunction sourceIcon(preview: InstallPreview) {\n return preview.source.kind === 'store' ? G.shield : preview.source.kind === 'link' ? G.link : G.file;\n}\n\n/** Where it comes from, in the owner's language (native code's `label` is English). */\nfunction sourceLabel(source: InstallPreview['source'], t: StoreText): string {\n if (source.kind === 'store') return t('wb.install.source.store');\n if (source.kind === 'link') {\n let host = '';\n try { host = new URL(source.url ?? '').hostname; } catch { /* no host */ }\n return t('wb.install.source.link', { host });\n }\n return t('wb.install.source.file');\n}\n\ntype Shared<Theme> = Omit<InstallHostProps<Theme>, 'classNames'> & { classes: InstallClassNames };\n\nfunction Ready<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'ready' | 'installing' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n const preview = request.preview;\n const ready = request.status === 'ready' ? request : null;\n const theme = ready ? ready.theme : null;\n const facts = theme !== null ? controller.facts(theme) : null;\n const plugin = preview.plugin;\n const [armed, setArmed] = useState(false);\n // On by default only when it is from the signed store or declares its permissions and the code\n // scan found nothing to point out; otherwise the owner turns it on deliberately.\n const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));\n const [copied, setCopied] = useState(false);\n useEffect(() => { const timer = setTimeout(() => setArmed(true), REVIEW_MS); return () => clearTimeout(timer); }, [preview.token]);\n const strings = preview.kind === 'strings' ? preview.strings ?? null : null;\n const summary = strings ? props.stringsSummary?.(preview.text) ?? null : null;\n const name = plugin?.name ?? facts?.name ?? preview.theme?.name ?? strings?.name ?? t('wb.install.untitled');\n const author = plugin?.author || facts?.author || preview.theme?.author || strings?.authors.join(', ') || '';\n const version = preview.version || preview.store?.version || '';\n const updating = preview.existing && !preview.existing.same;\n const verb = preview.existing?.same ? t('wb.install.reinstall') : updating || ready?.replaces ? t('wb.install.update') : t('wb.store.install');\n const step = preview.existing?.same ? 'reinstall' : updating || ready?.replaces ? 'update' : 'install';\n const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });\n const badges = preview.kind === 'plugin' ? permissionBadges(plugin?.permissions, t, site) : [];\n const installing = request.status === 'installing';\n const description = plugin?.description || facts?.description || strings?.description;\n return <>\n <header className=\"wbi-head\">\n <div className={`wbi-tile is-${preview.kind}`} style={facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined}>\n <Glyph d={preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : G.theme} size={22}/>\n </div>\n <div className=\"wbi-title\">\n <span className=\"wbi-eyebrow\">{eyebrow}</span>\n <h2 id=\"wbi-title\">{name}</h2>\n <p>{[author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor')}</p>\n </div>\n <button className={`${classes.icon} wbi-close`} aria-label={t('wb.install.cancel')} onClick={() => void controller.cancel()}>{props.closeIcon ?? <Glyph d={G.close} size={16}/>}</button>\n </header>\n\n <div className=\"wbi-body\">\n <div className={`wbi-source is-${preview.source.kind}`}>\n <Glyph d={sourceIcon(preview)}/>\n <div>\n <strong>{sourceLabel(preview.source, t)}</strong>\n {preview.source.url && <code title={preview.source.url}>{preview.source.url}</code>}\n </div>\n {preview.source.signed && <span className=\"wbi-verified\"><Glyph d={G.check} size={14}/>{t('wb.install.verified')}</span>}\n </div>\n\n {description && <p className=\"wbi-desc\">{description}</p>}\n\n <dl className=\"wbi-facts\">\n {preview.file && <Fact label={t('wb.install.file')}>{preview.file}</Fact>}\n <Fact label={t('wb.install.size')}>{formatBytes(preview.size)}</Fact>\n {preview.existing && <Fact label={t('wb.install.installedNow')}>{preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}`}</Fact>}\n {ready?.replaces && <Fact label={t('wb.install.replaces')}>{t('wb.install.replacesValue')}</Fact>}\n {preview.store?.license && <Fact label={t('wb.install.license')}>{preview.store.license}</Fact>}\n {preview.store?.credits && <Fact label={t('wb.install.credits')} wide>{preview.store.credits}</Fact>}\n <Fact label=\"SHA-256\" wide>\n <span className=\"wbi-hash\">{preview.sha256}</span>\n <button className=\"wbi-copy\" aria-label={t('wb.install.copyHash')} onClick={() => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => {})}>\n <Glyph d={copied ? G.check : G.copy} size={14}/>\n </button>\n </Fact>\n </dl>\n\n {preview.kind === 'plugin' && <section className=\"wbi-perms\" aria-label={t('wb.store.permissions')}>\n <h3>{t('wb.install.permissions')}</h3>\n <ul>\n {badges.map(badge => <li key={badge.id} className={`is-${badge.tone}`}><span className=\"wbi-chip\">{badge.label}</span><span>{badge.detail}</span></li>)}\n </ul>\n <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.pageAccess', { site })}</p>\n {preview.findings.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.theCode')}</strong>{preview.findings.map(finding => <span key={finding}>{finding}</span>)}</div>}\n </section>}\n\n {strings && <section className=\"wbi-perms wbi-strings\" aria-label={t('wb.store.stringsItem')}>\n <p className=\"wbi-note is-ok\"><Glyph d={G.check} size={14}/>{t('wb.install.strings.dataOnly', { site })}</p>\n <dl className=\"wbi-facts\">\n <Fact label={t('wb.install.strings.language')}>{strings.language}</Fact>\n <Fact label={t('wb.install.strings.coverage')} wide>\n {summary && !summary.otherCatalog\n ? t('wb.install.strings.coverageValue', { translated: String(summary.translated), translatable: String(summary.translatable), site, percent: coveragePercent(summary) })\n : t('wb.install.strings.count', { count: strings.strings })}\n </Fact>\n </dl>\n {summary?.otherCatalog && <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.strings.otherCatalog', { site })}</p>}\n {summary && !summary.otherCatalog && <ul className=\"wbi-strings-notes\">\n {summary.closed > 0 && <li>{t('wb.install.strings.closed', { count: summary.closed, site })}</li>}\n {summary.unknown > 0 && <li>{t('wb.install.strings.unknown', { count: summary.unknown, site })}</li>}\n {summary.refused > 0 && <li>{t('wb.install.strings.refused', { count: summary.refused, site })}</li>}\n </ul>}\n {summary && summary.sample.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.strings.sample')}</strong>{summary.sample.map(text => <span key={text}>{text}</span>)}</div>}\n </section>}\n\n {theme !== null && <section className=\"wbi-theme\">\n {props.renderThemePreview?.(theme)}\n {(ready?.warnings.length ?? 0) > 0 && <ul className=\"wbi-warnings\">{ready!.warnings.map(warning => <li key={warning}>{warning}</li>)}</ul>}\n </section>}\n\n {facts?.css ? <CodePreview t={t} text={facts.css} label={t('wb.install.themeCss', { site })}/> : null}\n <CodePreview t={t} text={preview.text} label={preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : t('wb.install.themeFile')}/>\n </div>\n\n <footer className=\"wbi-foot\">\n <label className=\"wbi-check\">\n <input type=\"checkbox\" checked={enable} disabled={installing || Boolean(preview.existing?.enabled)} onChange={event => setEnable(event.target.checked)}/>\n <span>{preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow')}</span>\n </label>\n <span className=\"wbi-foot-end\"/>\n <button className={classes.secondary} onClick={() => void controller.cancel()} disabled={installing}>{t('wb.install.cancel')}</button>\n <button className={`${classes.primary} wbi-install${armed ? '' : ' is-arming'}`} disabled={!armed || installing} onClick={() => void controller.confirm(enable)}>\n {installing ? t('wb.install.installing') : verb}\n </button>\n </footer>\n </>;\n}\n\nfunction Done<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'done' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n return <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-ok\"><Glyph d={G.check} size={26}/></div>\n <h2 id=\"wbi-title\">{t('wb.install.done', { name: request.name })}</h2>\n <p>{request.kind === 'plugin'\n ? (request.enabled ? t('wb.install.done.pluginOn', { site }) : t('wb.install.done.pluginOff'))\n : request.kind === 'strings'\n ? (request.enabled ? t('wb.install.done.stringsOn', { site }) : t('wb.install.done.stringsOff'))\n : (request.enabled ? t('wb.install.done.themeOn') : t('wb.install.done.themeOff'))}</p>\n {request.fonts.length > 0 && <p className=\"wbi-muted\">{t('wb.install.done.fonts', { fonts: request.fonts.join(', ') })}</p>}\n <div className=\"wbi-state-actions\">\n <button className={classes.secondary} onClick={() => { controller.close(); props.openSection(request.kind); }}>{request.kind === 'plugin' ? t('wb.install.openPlugins') : request.kind === 'strings' ? t('wb.install.openStrings') : t('wb.install.openAppearance')}</button>\n <button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.doneButton')}</button>\n </div>\n </div>;\n}\n\nfunction Dialog<Theme>({ request, props }: { request: InstallRequest<Theme>; props: Shared<Theme> }) {\n const { t, controller, classes, setOverlay } = props;\n const box = useRef<HTMLDivElement>(null);\n useEffect(() => {\n setOverlay(1);\n return () => setOverlay(-1);\n }, []);\n useEffect(() => { box.current?.querySelector<HTMLElement>('.wbi-close, [autofocus]')?.focus(); }, [request.status]);\n const dismiss = () => (request.status === 'ready' ? void controller.cancel() : request.status === 'installing' ? undefined : controller.close());\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') { event.preventDefault(); dismiss(); }\n // Enter never confirms an install; only a click on Install does.\n if (event.key === 'Enter' && (event.target as HTMLElement).classList.contains('wbi-install')) event.preventDefault();\n };\n return createPortal(<div className=\"wbi-backdrop\" onMouseDown={dismiss}>\n <div ref={box} className={`wbi ${classes.pop} is-${request.status}`.replace(/\\s+/g, ' ')} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"wbi-title\" onMouseDown={event => event.stopPropagation()} onKeyDown={onKey}>\n {request.status === 'loading' && <div className=\"wbi-state\">\n <div className=\"wbi-spinner\" aria-hidden=\"true\"/>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.detail}</p>\n <div className=\"wbi-state-actions\"><button className={classes.secondary} onClick={controller.close}>{t('wb.install.cancel')}</button></div>\n </div>}\n {(request.status === 'ready' || request.status === 'installing') && <Ready request={request} props={props}/>}\n {request.status === 'done' && <Done request={request} props={props}/>}\n {request.status === 'error' && <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-warn\"><Glyph d={G.warn} size={26}/></div>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.message}</p>\n <div className=\"wbi-state-actions\"><button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.close')}</button></div>\n </div>}\n </div>\n </div>, document.body);\n}\n\nconst hasFiles = (event: DragEvent) => Array.from(event.dataTransfer?.types ?? []).includes('Files');\n\n/**\n * Install links, the screen, and file drops on the window. A file dragged over the shell (tab\n * strip, titlebar, settings) shows a drop target over the whole window; files dragged straight into\n * a site tab stay the site's (e.g. images for a post).\n */\nexport function InstallHost<Theme>(props: InstallHostProps<Theme>) {\n const { t, controller, setOverlay, ownDropTargets } = props;\n const shared: Shared<Theme> = { ...props, classes: { ...DEFAULT_CLASSES, ...props.classNames } };\n const request = useInstallRequest(controller);\n const [dropping, setDropping] = useState(false);\n useEffect(() => controller.start(), [controller]);\n useEffect(() => {\n let last = 0;\n let timer: ReturnType<typeof setInterval> | undefined;\n const own = (event: DragEvent) => Boolean(ownDropTargets && (event.target as Element | null)?.closest?.(ownDropTargets));\n const stop = () => { clearInterval(timer); timer = undefined; setDropping(false); };\n const over = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n last = Date.now();\n if (!timer) {\n setDropping(true);\n // Esc or leaving the window ends a drag without an event here.\n timer = setInterval(() => { if (Date.now() - last > 900) stop(); }, 200);\n }\n };\n const drop = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n stop();\n const file = event.dataTransfer?.files[0];\n if (file) void controller.requestFile(file);\n };\n window.addEventListener('dragenter', over, true);\n window.addEventListener('dragover', over, true);\n window.addEventListener('drop', drop, true);\n return () => { stop(); window.removeEventListener('dragenter', over, true); window.removeEventListener('dragover', over, true); window.removeEventListener('drop', drop, true); };\n }, [controller, ownDropTargets]);\n useEffect(() => {\n if (!dropping) return;\n setOverlay(1);\n return () => setOverlay(-1);\n }, [dropping]);\n return <>\n {dropping && createPortal(<div className=\"wbi-drop\" aria-hidden=\"true\"><div>\n <Glyph d={G.file} size={30}/>\n <strong>{t('wb.install.drop')}</strong>\n <span>{t('wb.install.dropHint')}</span>\n </div></div>, document.body)}\n {request && <Dialog request={request} props={shared}/>}\n </>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"InstallDialog.js","sourceRoot":"","sources":["../../../../../shell/src/InstallDialog.tsx"],"names":[],"mappings":";AAAA,mGAAmG;AACnG,kGAAkG;AAClG,oGAAoG;AACpG,qGAAqG;AACrG,kGAAkG;AAClG,qGAAqG;AAErG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,EAAsC,MAAM,OAAO,CAAC;AAC9G,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAsB,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAyC,MAAM,iBAAiB,CAAC;AACrH,OAAO,EAAE,eAAe,EAAuB,MAAM,uBAAuB,CAAC;AAE7E,oGAAoG;AACpG,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAC9B,MAAM,aAAa,GAAG,GAAG,CAAC;AAI1B,MAAM,eAAe,GAAsB,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AAqB/H,wDAAwD;AACxD,MAAM,UAAU,iBAAiB,CAAQ,UAAoC;IAC3E,OAAO,oBAAoB,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,EAAgC;IAC3D,OAAO,cAAK,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,WAAW,iBAAa,MAAM,YAAC,eAAM,CAAC,EAAE,CAAC,EAAE,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,KAAK,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,GAAE,GAAM,CAAC;AACrM,CAAC;AACD,MAAM,CAAC,GAAG;IACR,MAAM,EAAE,gDAAgD;IACxD,KAAK,EAAE,0JAA0J;IACjK,MAAM,EAAE,kDAAkD;IAC1D,KAAK,EAAE,sBAAsB;IAC7B,IAAI,EAAE,oGAAoG;IAC1G,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,iCAAiC;IACvC,IAAI,EAAE,yBAAyB;IAC/B,KAAK,EAAE,sBAAsB;IAC7B,KAAK,EAAE,sDAAsD;IAC7D,OAAO,EAAE,iGAAiG;CAC3G,CAAC;AAEF,SAAS,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAA0D;IAC7F,OAAO,eAAK,SAAS,EAAE,WAAW,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,aAAE,uBAAK,KAAK,GAAM,EAAA,uBAAK,QAAQ,GAAM,IAAM,CAAC;AACxG,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAiD;IACpF,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;IACjE,OAAO,mBAAS,SAAS,EAAC,UAAU,gBAAa,KAAK,aACpD,6BAAQ,yBAAO,KAAK,GAAQ,EAAA,0BAAQ,CAAC,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,GAAS,IAAS,EAC/G,cAAK,QAAQ,EAAE,CAAC,YAAE,yBAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,gBAAc,SAAS,EAAC,UAAU,aAAC,sBAAI,CAAC,GAAG,CAAC,GAAK,EAAC,IAAI,IAAI,GAAG,KAAlD,CAAC,CAAyD,CAAC,GAAQ,GAAM,EACnI,MAAM,GAAG,CAAC,IAAI,iBAAQ,SAAS,EAAC,UAAU,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAG,CAAC,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAU,IACxH,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,OAAuB;IACzC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvG,CAAC;AAED,uFAAuF;AACvF,SAAS,WAAW,CAAC,MAAgC,EAAE,CAAY;IACjE,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,yBAAyB,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YAAC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,CAAC,wBAAwB,CAAC,CAAC;AACrC,CAAC;AAID,SAAS,KAAK,CAAQ,EAAE,OAAO,EAAE,KAAK,EAAyG;IAC7I,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,+FAA+F;IAC/F,iFAAiF;IACjF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrP,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,SAAS,CAAC,GAAG,EAAE,GAAG,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACnI,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACtE,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC;IAC1I,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,MAAM,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;IAC9I,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;IAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC/I,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAClN,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC;IACnD,MAAM,WAAW,GAAG,MAAM,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,OAAO,EAAE,WAAW,IAAI,IAAI,EAAE,WAAW,CAAC;IAC3G,OAAO,8BACL,kBAAQ,SAAS,EAAC,UAAU,aAC1B,cAAK,SAAS,EAAE,eAAe,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,mBAAmB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,YAC/L,KAAC,KAAK,IAAC,CAAC,EAAE,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,GAC/I,EACN,eAAK,SAAS,EAAC,WAAW,aACxB,eAAM,SAAS,EAAC,aAAa,YAAE,OAAO,GAAQ,EAC9C,aAAI,EAAE,EAAC,WAAW,YAAE,IAAI,GAAM,EAC9B,sBAAI,CAAC,MAAM,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,GAAK,IAC/H,EACN,iBAAQ,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,YAAY,gBAAc,CAAC,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,UAAU,CAAC,MAAM,EAAE,YAAG,KAAK,CAAC,SAAS,IAAI,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,GAAU,IAClL,EAET,eAAK,SAAS,EAAC,UAAU,aACvB,eAAK,SAAS,EAAE,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,aACpD,KAAC,KAAK,IAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,EAChC,0BACE,2BAAS,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAU,EAChD,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,eAAM,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,YAAG,OAAO,CAAC,MAAM,CAAC,GAAG,GAAQ,IAC/E,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,gBAAM,SAAS,EAAC,cAAc,aAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC,CAAC,CAAC,qBAAqB,CAAC,IAAQ,IACpH,EAEL,WAAW,IAAI,YAAG,SAAS,EAAC,UAAU,YAAE,WAAW,GAAK,EAEzD,cAAI,SAAS,EAAC,WAAW,aACtB,OAAO,CAAC,IAAI,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,iBAAiB,CAAC,YAAG,OAAO,CAAC,IAAI,GAAQ,EACzE,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,iBAAiB,CAAC,YAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,GAAQ,EACpE,OAAO,CAAC,QAAQ,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,YAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAQ,EAC5Q,KAAK,EAAE,QAAQ,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,qBAAqB,CAAC,YAAG,CAAC,CAAC,0BAA0B,CAAC,GAAQ,EAChG,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,YAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAQ,EAC9F,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,kBAAE,OAAO,CAAC,KAAK,CAAC,OAAO,GAAQ,EACpG,MAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,IAAI,mBACxB,eAAM,SAAS,EAAC,UAAU,YAAE,OAAO,CAAC,MAAM,GAAQ,EAClD,iBAAQ,SAAS,EAAC,UAAU,gBAAa,CAAC,CAAC,qBAAqB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,YAC9N,KAAC,KAAK,IAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,GACzC,IACJ,IACJ,EAEJ,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,mBAAS,SAAS,EAAC,WAAW,gBAAa,CAAC,CAAC,sBAAsB,CAAC,aAChG,uBAAK,CAAC,CAAC,wBAAwB,CAAC,GAAM,EACtC,uBACG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,cAAmB,SAAS,EAAE,MAAM,KAAK,CAAC,IAAI,EAAE,aAAE,eAAM,SAAS,EAAC,UAAU,YAAE,KAAK,CAAC,KAAK,GAAQ,EAAA,yBAAO,KAAK,CAAC,MAAM,GAAQ,KAAnH,KAAK,CAAC,EAAE,CAAgH,CAAC,GACpJ,EACL,aAAG,SAAS,EAAC,UAAU,aAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC,CAAC,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,CAAC,IAAK,EAC9F,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,eAAK,SAAS,EAAC,cAAc,aAAC,2BAAS,CAAC,CAAC,oBAAoB,CAAC,GAAU,EAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,yBAAqB,OAAO,IAAjB,OAAO,CAAkB,CAAC,IAAO,IAC7K,EAET,OAAO,IAAI,mBAAS,SAAS,EAAC,uBAAuB,gBAAa,CAAC,CAAC,sBAAsB,CAAC,aAC1F,aAAG,SAAS,EAAC,gBAAgB,aAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC,CAAC,CAAC,6BAA6B,EAAE,EAAE,IAAI,EAAE,CAAC,IAAK,EAC5G,cAAI,SAAS,EAAC,WAAW,aACvB,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,6BAA6B,CAAC,YAAG,OAAO,CAAC,QAAQ,GAAQ,EACxE,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,6BAA6B,CAAC,EAAE,IAAI,kBAChD,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY;4CAC/B,CAAC,CAAC,CAAC,CAAC,kCAAkC,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;4CACxK,CAAC,CAAC,CAAC,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,GACxD,IACJ,EACJ,OAAO,EAAE,YAAY,IAAI,aAAG,SAAS,EAAC,UAAU,aAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC,CAAC,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,CAAC,IAAK,EAClI,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,cAAI,SAAS,EAAC,mBAAmB,aACnE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAK,CAAC,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,GAAM,EAChG,OAAO,CAAC,OAAO,GAAG,CAAC,IAAI,uBAAK,CAAC,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAM,EACnG,OAAO,CAAC,OAAO,GAAG,CAAC,IAAI,uBAAK,CAAC,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAM,IACjG,EACJ,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,eAAK,SAAS,EAAC,cAAc,aAAC,2BAAS,CAAC,CAAC,2BAA2B,CAAC,GAAU,EAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,yBAAkB,IAAI,IAAX,IAAI,CAAe,CAAC,IAAO,IAClL,EAET,IAAI,IAAI,mBAAS,SAAS,EAAC,qBAAqB,gBAAa,CAAC,CAAC,oBAAoB,CAAC,aACnF,aAAG,SAAS,EAAC,gBAAgB,aAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAC,CAAC,CAAC,2BAA2B,CAAC,IAAK,EAChG,cAAI,SAAS,EAAC,WAAW,aACvB,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,0BAA0B,CAAC,YAAG,IAAI,CAAC,OAAO,GAAQ,EACjE,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,wBAAwB,CAAC,YAAG,CAAC,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,GAAQ,EAC9H,IAAI,CAAC,MAAM,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC,EAAE,IAAI,kBAAE,IAAI,CAAC,MAAM,GAAQ,EACnF,IAAI,CAAC,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,kBAAE,IAAI,CAAC,OAAO,GAAQ,IAC9E,EACL,cAAK,SAAS,EAAC,eAAe,iBAAa,MAAM,YAC7C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAqC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,eAAkB,KAAK,EAAE,KAAK,YAAE,cAAK,OAAO,EAAC,WAAW,YAAC,KAAC,UAAU,IAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAE,EAAE,IAAI,EAAE,IAAI,GAAG,GAAM,IAAzG,KAAK,CAA2G,CAAC,GACpM,EACL,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,aAAI,SAAS,EAAC,cAAc,YAAE,KAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,uBAAmB,OAAO,IAAjB,OAAO,CAAgB,CAAC,GAAM,IAClI,EAET,KAAK,KAAK,IAAI,IAAI,mBAAS,SAAS,EAAC,WAAW,aAC9C,KAAK,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,EACjC,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,aAAI,SAAS,EAAC,cAAc,YAAE,KAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,uBAAmB,OAAO,IAAjB,OAAO,CAAgB,CAAC,GAAM,IAClI,EAET,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,KAAC,WAAW,IAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EACrG,KAAC,WAAW,IAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,GAAG,IAC7O,EAEN,kBAAQ,SAAS,EAAC,UAAU,aAC1B,iBAAO,SAAS,EAAC,WAAW,aAC1B,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EACzJ,yBAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAQ,IAC5I,EACR,eAAM,SAAS,EAAC,cAAc,GAAE,EAChC,iBAAQ,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,UAAU,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,YAAG,CAAC,CAAC,mBAAmB,CAAC,GAAU,EACtI,iBAAQ,SAAS,EAAE,GAAG,OAAO,CAAC,OAAO,eAAe,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,IAAI,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,YAC5J,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,IAAI,GACxC,IACF,IACR,CAAC;AACN,CAAC;AAED,SAAS,IAAI,CAAQ,EAAE,OAAO,EAAE,KAAK,EAAyF;IAC5H,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC/C,OAAO,eAAK,SAAS,EAAC,WAAW,aAC/B,cAAK,SAAS,EAAC,sBAAsB,YAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,GAAM,EAC1E,aAAI,EAAE,EAAC,WAAW,YAAE,CAAC,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,GAAM,EACtE,sBAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;oBAC3B,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC;oBAC9F,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS;wBAC1B,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC;wBAChG,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO;4BACxB,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;4BACpF,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,GAAK,EAC1F,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,YAAG,SAAS,EAAC,WAAW,YAAE,CAAC,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAK,EAC3H,eAAK,SAAS,EAAC,mBAAmB,aAChC,iBAAQ,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAG,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,GAAU,EAC7Q,iBAAQ,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,QAAC,OAAO,EAAE,UAAU,CAAC,KAAK,YAAG,CAAC,CAAC,uBAAuB,CAAC,GAAU,IAC1G,IACF,CAAC;AACT,CAAC;AAED,SAAS,MAAM,CAAQ,EAAE,OAAO,EAAE,KAAK,EAA4D;IACjG,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACzC,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,aAAa,CAAc,yBAAyB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACpH,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IACjJ,MAAM,KAAK,GAAG,CAAC,KAAoB,EAAE,EAAE;QACrC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAAC,KAAK,CAAC,cAAc,EAAE,CAAC;YAAC,OAAO,EAAE,CAAC;QAAC,CAAC;QAClE,iEAAiE;QACjE,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,IAAK,KAAK,CAAC,MAAsB,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC;YAAE,KAAK,CAAC,cAAc,EAAE,CAAC;IACvH,CAAC,CAAC;IACF,OAAO,YAAY,CAAC,cAAK,SAAS,EAAC,cAAc,EAAC,WAAW,EAAE,OAAO,YACpE,eAAK,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAC,QAAQ,gBAAY,MAAM,qBAAiB,WAAW,EAAC,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,aAClN,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,eAAK,SAAS,EAAC,WAAW,aACzD,cAAK,SAAS,EAAC,aAAa,iBAAa,MAAM,GAAE,EACjD,aAAI,EAAE,EAAC,WAAW,YAAE,OAAO,CAAC,KAAK,GAAM,EACvC,sBAAI,OAAO,CAAC,MAAM,GAAK,EACvB,cAAK,SAAS,EAAC,mBAAmB,YAAC,iBAAQ,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,KAAK,YAAG,CAAC,CAAC,mBAAmB,CAAC,GAAU,GAAM,IACvI,EACL,CAAC,OAAO,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,IAAI,KAAC,KAAK,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,EAC3G,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,KAAC,IAAI,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,EACpE,OAAO,CAAC,MAAM,KAAK,OAAO,IAAI,eAAK,SAAS,EAAC,WAAW,aACvD,cAAK,SAAS,EAAC,wBAAwB,YAAC,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,GAAM,EAC3E,aAAI,EAAE,EAAC,WAAW,YAAE,OAAO,CAAC,KAAK,GAAM,EACvC,sBAAI,OAAO,CAAC,OAAO,GAAK,EACxB,cAAK,SAAS,EAAC,mBAAmB,YAAC,iBAAQ,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,QAAC,OAAO,EAAE,UAAU,CAAC,KAAK,YAAG,CAAC,CAAC,kBAAkB,CAAC,GAAU,GAAM,IAC9I,IACF,GACF,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErG;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAQ,KAA8B;IAC/D,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAC5D,MAAM,MAAM,GAAkB,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,eAAe,EAAE,GAAG,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;IACjG,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAClD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,KAAiD,CAAC;QACtD,MAAM,GAAG,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,IAAK,KAAK,CAAC,MAAyB,EAAE,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;QACzH,MAAM,IAAI,GAAG,GAAG,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAE,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO;YAC3C,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,KAAK,CAAC,YAAY;gBAAE,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;YAC/D,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,CAAC,CAAC;gBAClB,+DAA+D;gBAC/D,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG;oBAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAE,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;gBAAE,OAAO;YAC3C,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,EAAE,CAAC;YACP,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,IAAI;gBAAE,KAAK,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACpL,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;IACjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,UAAU,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACf,OAAO,8BACJ,QAAQ,IAAI,YAAY,CAAC,cAAK,SAAS,EAAC,UAAU,iBAAa,MAAM,YAAC,0BACrE,KAAC,KAAK,IAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAC7B,2BAAS,CAAC,CAAC,iBAAiB,CAAC,GAAU,EACvC,yBAAO,CAAC,CAAC,qBAAqB,CAAC,GAAQ,IACnC,GAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,EAC3B,OAAO,IAAI,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IACrD,CAAC;AACN,CAAC","sourcesContent":["// The install screen, shared by every wayBetter app: every theme or plugin that is not copied into\n// the plugins folder by hand (a waybetter:// link, a dropped file, the Store) is shown here first\n// with its name, author, version, where it came from, its sha256, the permissions a plugin declares\n// and the exact code or CSS that will be written. Nothing installs until Install is pressed (enabled\n// after a moment, so a stray click or Enter cannot confirm it). Lives in the shell; the app hides\n// its tab webviews while it is open (`setOverlay`). Styles: `store.css` (framework `--wb-*` tokens).\n\nimport { useEffect, useRef, useState, useSyncExternalStore, type KeyboardEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { GlyphPaths } from './frame/iconPack.tsx';\nimport type { InstallController, InstallRequest } from './installController.ts';\nimport type { StoreText } from './storeMessages.ts';\nimport { formatBytes, permissionBadges, previewLines, type InstallKind, type InstallPreview } from './storeModel.ts';\nimport { coveragePercent, type StringsSummary } from './stringPacksModel.ts';\n\n/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */\nexport const REVIEW_MS = 1000;\nconst PREVIEW_LINES = 160;\n\n/** Class names for the app's own buttons (defaults: the framework's `.wb-btn`). */\nexport type InstallClassNames = { primary: string; secondary: string; icon: string; pop: string };\nconst DEFAULT_CLASSES: InstallClassNames = { primary: 'wb-btn is-primary', secondary: 'wb-btn', icon: 'wb-icon-btn', pop: '' };\n\nexport type InstallHostProps<Theme> = {\n controller: InstallController<Theme>;\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n /** Shows or hides the app's tab webviews under the screen (+1 when it opens, -1 when it closes). */\n setOverlay(delta: 1 | -1): void;\n /** \"Open Plugins\" / \"Open Appearance\" after an install. */\n openSection(kind: InstallKind): void;\n /** A live preview of a staged theme (the app's theme preview). */\n renderThemePreview?(theme: Theme): ReactNode;\n /** A string pack's coverage against the site's inventory (the app has the inventory). */\n stringsSummary?(text: string): StringsSummary | null;\n /** Drops on elements matching this selector are handled by them (e.g. an import box). */\n ownDropTargets?: string;\n closeIcon?: ReactNode;\n classNames?: Partial<InstallClassNames>;\n};\n\n/** Re-renders with the controller's current request. */\nexport function useInstallRequest<Theme>(controller: InstallController<Theme>): InstallRequest<Theme> | null {\n return useSyncExternalStore(controller.subscribe, controller.current, controller.current);\n}\n\nfunction Glyph({ d, size = 18 }: { d: string; size?: number }) {\n return <svg width={size} height={size} viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d={d} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>;\n}\nconst G = {\n plugin: 'M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0zM12 17v4',\n theme: 'M12 3a9 9 0 1 0 0 18c1.5 0 2-1 2-1.8 0-1.2-.9-1.5-.9-2.5 0-1 .8-1.7 1.8-1.7h2A4.2 4.2 0 0 0 21 10.8 8.8 8.8 0 0 0 12 3zM7.5 11h.01M10.5 7.5h.01M15 8h.01',\n shield: 'M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6z',\n check: 'M5 12.5l4.2 4.2L19 7',\n link: 'M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1',\n file: 'M7 3h7l5 5v13H7zM14 3v5h5',\n warn: 'M12 4l9 16H3zM12 10v4M12 17h.01',\n copy: 'M9 9h10v10H9zM5 15V5h10',\n close: 'M6 6l12 12M18 6L6 18',\n icons: 'M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM17 14v6M14 17h6',\n strings: 'M4 5h9M8.5 3v2M11 5c-.8 3.8-3.4 6.6-7 8M6.5 8.5c1.1 1.6 2.7 3 4.5 3.8M13 21l4-9 4 9M14.4 18h5.2',\n};\n\nfunction Fact({ label, children, wide }: { label: string; children: ReactNode; wide?: boolean }) {\n return <div className={`wbi-fact${wide ? ' is-wide' : ''}`}><dt>{label}</dt><dd>{children}</dd></div>;\n}\n\nfunction CodePreview({ text, label, t }: { text: string; label: string; t: StoreText }) {\n const [all, setAll] = useState(false);\n const { lines, hidden } = previewLines(text, PREVIEW_LINES, all);\n return <section className=\"wbi-code\" aria-label={label}>\n <header><span>{label}</span><small>{t('wb.install.lines', { count: text.split('\\n').length })}</small></header>\n <pre tabIndex={0}><code>{lines.map((line, i) => <span key={i} className=\"wbi-line\"><i>{i + 1}</i>{line || ' '}</span>)}</code></pre>\n {hidden > 0 && <button className=\"wbi-more\" onClick={() => setAll(true)}>{t('wb.install.moreLines', { count: hidden })}</button>}\n </section>;\n}\n\nfunction sourceIcon(preview: InstallPreview) {\n return preview.source.kind === 'store' ? G.shield : preview.source.kind === 'link' ? G.link : G.file;\n}\n\n/** Where it comes from, in the owner's language (native code's `label` is English). */\nfunction sourceLabel(source: InstallPreview['source'], t: StoreText): string {\n if (source.kind === 'store') return t('wb.install.source.store');\n if (source.kind === 'link') {\n let host = '';\n try { host = new URL(source.url ?? '').hostname; } catch { /* no host */ }\n return t('wb.install.source.link', { host });\n }\n return t('wb.install.source.file');\n}\n\ntype Shared<Theme> = Omit<InstallHostProps<Theme>, 'classNames'> & { classes: InstallClassNames };\n\nfunction Ready<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'ready' | 'installing' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n const preview = request.preview;\n const ready = request.status === 'ready' ? request : null;\n const theme = ready ? ready.theme : null;\n const facts = theme !== null ? controller.facts(theme) : null;\n const plugin = preview.plugin;\n const [armed, setArmed] = useState(false);\n // On by default only when it is from the signed store or declares its permissions and the code\n // scan found nothing to point out; otherwise the owner turns it on deliberately.\n const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || preview.kind === 'icons' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));\n const [copied, setCopied] = useState(false);\n useEffect(() => { const timer = setTimeout(() => setArmed(true), REVIEW_MS); return () => clearTimeout(timer); }, [preview.token]);\n const strings = preview.kind === 'strings' ? preview.strings ?? null : null;\n const summary = strings ? props.stringsSummary?.(preview.text) ?? null : null;\n const pack = preview.kind === 'icons' ? request.pack ?? null : null;\n const icons = preview.kind === 'icons' ? preview.icons ?? null : null;\n const name = plugin?.name ?? facts?.name ?? preview.theme?.name ?? strings?.name ?? pack?.name ?? icons?.name ?? t('wb.install.untitled');\n const author = plugin?.author || facts?.author || preview.theme?.author || strings?.authors.join(', ') || pack?.author || icons?.author || '';\n const version = preview.version || preview.store?.version || '';\n const updating = preview.existing && !preview.existing.same;\n const verb = preview.existing?.same ? t('wb.install.reinstall') : updating || ready?.replaces ? t('wb.install.update') : t('wb.store.install');\n const step = preview.existing?.same ? 'reinstall' : updating || ready?.replaces ? 'update' : 'install';\n const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : preview.kind === 'icons' ? t(`wb.install.eyebrow.icons.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });\n const badges = preview.kind === 'plugin' ? permissionBadges(plugin?.permissions, t, site) : [];\n const installing = request.status === 'installing';\n const description = plugin?.description || facts?.description || strings?.description || pack?.description;\n return <>\n <header className=\"wbi-head\">\n <div className={`wbi-tile is-${preview.kind}`} style={facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined}>\n <Glyph d={preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : preview.kind === 'icons' ? G.icons : G.theme} size={22}/>\n </div>\n <div className=\"wbi-title\">\n <span className=\"wbi-eyebrow\">{eyebrow}</span>\n <h2 id=\"wbi-title\">{name}</h2>\n <p>{[author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor')}</p>\n </div>\n <button className={`${classes.icon} wbi-close`} aria-label={t('wb.install.cancel')} onClick={() => void controller.cancel()}>{props.closeIcon ?? <Glyph d={G.close} size={16}/>}</button>\n </header>\n\n <div className=\"wbi-body\">\n <div className={`wbi-source is-${preview.source.kind}`}>\n <Glyph d={sourceIcon(preview)}/>\n <div>\n <strong>{sourceLabel(preview.source, t)}</strong>\n {preview.source.url && <code title={preview.source.url}>{preview.source.url}</code>}\n </div>\n {preview.source.signed && <span className=\"wbi-verified\"><Glyph d={G.check} size={14}/>{t('wb.install.verified')}</span>}\n </div>\n\n {description && <p className=\"wbi-desc\">{description}</p>}\n\n <dl className=\"wbi-facts\">\n {preview.file && <Fact label={t('wb.install.file')}>{preview.file}</Fact>}\n <Fact label={t('wb.install.size')}>{formatBytes(preview.size)}</Fact>\n {preview.existing && <Fact label={t('wb.install.installedNow')}>{preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}`}</Fact>}\n {ready?.replaces && <Fact label={t('wb.install.replaces')}>{t('wb.install.replacesValue')}</Fact>}\n {preview.store?.license && <Fact label={t('wb.install.license')}>{preview.store.license}</Fact>}\n {preview.store?.credits && <Fact label={t('wb.install.credits')} wide>{preview.store.credits}</Fact>}\n <Fact label=\"SHA-256\" wide>\n <span className=\"wbi-hash\">{preview.sha256}</span>\n <button className=\"wbi-copy\" aria-label={t('wb.install.copyHash')} onClick={() => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => {})}>\n <Glyph d={copied ? G.check : G.copy} size={14}/>\n </button>\n </Fact>\n </dl>\n\n {preview.kind === 'plugin' && <section className=\"wbi-perms\" aria-label={t('wb.store.permissions')}>\n <h3>{t('wb.install.permissions')}</h3>\n <ul>\n {badges.map(badge => <li key={badge.id} className={`is-${badge.tone}`}><span className=\"wbi-chip\">{badge.label}</span><span>{badge.detail}</span></li>)}\n </ul>\n <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.pageAccess', { site })}</p>\n {preview.findings.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.theCode')}</strong>{preview.findings.map(finding => <span key={finding}>{finding}</span>)}</div>}\n </section>}\n\n {strings && <section className=\"wbi-perms wbi-strings\" aria-label={t('wb.store.stringsItem')}>\n <p className=\"wbi-note is-ok\"><Glyph d={G.check} size={14}/>{t('wb.install.strings.dataOnly', { site })}</p>\n <dl className=\"wbi-facts\">\n <Fact label={t('wb.install.strings.language')}>{strings.language}</Fact>\n <Fact label={t('wb.install.strings.coverage')} wide>\n {summary && !summary.otherCatalog\n ? t('wb.install.strings.coverageValue', { translated: String(summary.translated), translatable: String(summary.translatable), site, percent: coveragePercent(summary) })\n : t('wb.install.strings.count', { count: strings.strings })}\n </Fact>\n </dl>\n {summary?.otherCatalog && <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.strings.otherCatalog', { site })}</p>}\n {summary && !summary.otherCatalog && <ul className=\"wbi-strings-notes\">\n {summary.closed > 0 && <li>{t('wb.install.strings.closed', { count: summary.closed, site })}</li>}\n {summary.unknown > 0 && <li>{t('wb.install.strings.unknown', { count: summary.unknown, site })}</li>}\n {summary.refused > 0 && <li>{t('wb.install.strings.refused', { count: summary.refused, site })}</li>}\n </ul>}\n {summary && summary.sample.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.strings.sample')}</strong>{summary.sample.map(text => <span key={text}>{text}</span>)}</div>}\n </section>}\n\n {pack && <section className=\"wbi-perms wbi-icons\" aria-label={t('wb.store.iconsItem')}>\n <p className=\"wbi-note is-ok\"><Glyph d={G.check} size={14}/>{t('wb.install.icons.dataOnly')}</p>\n <dl className=\"wbi-facts\">\n <Fact label={t('wb.install.icons.license')}>{pack.license}</Fact>\n <Fact label={t('wb.install.icons.count')}>{t('wb.install.icons.countValue', { count: Object.keys(pack.glyphs).length })}</Fact>\n {pack.source && <Fact label={t('wb.install.icons.source')} wide>{pack.source}</Fact>}\n {pack.credits && <Fact label={t('wb.install.credits')} wide>{pack.credits}</Fact>}\n </dl>\n <div className=\"wbi-pack-grid\" aria-hidden=\"true\">\n {(Object.keys(pack.glyphs) as Array<keyof typeof pack.glyphs>).map(glyph => <span key={glyph} title={glyph}><svg viewBox=\"0 0 24 24\"><GlyphPaths glyph={pack.glyphs[glyph]!} pack={pack}/></svg></span>)}\n </div>\n {(ready?.warnings.length ?? 0) > 0 && <ul className=\"wbi-warnings\">{ready!.warnings.map(warning => <li key={warning}>{warning}</li>)}</ul>}\n </section>}\n\n {theme !== null && <section className=\"wbi-theme\">\n {props.renderThemePreview?.(theme)}\n {(ready?.warnings.length ?? 0) > 0 && <ul className=\"wbi-warnings\">{ready!.warnings.map(warning => <li key={warning}>{warning}</li>)}</ul>}\n </section>}\n\n {facts?.css ? <CodePreview t={t} text={facts.css} label={t('wb.install.themeCss', { site })}/> : null}\n <CodePreview t={t} text={preview.text} label={preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : preview.kind === 'icons' ? t('wb.install.icons.file') : t('wb.install.themeFile')}/>\n </div>\n\n <footer className=\"wbi-foot\">\n <label className=\"wbi-check\">\n <input type=\"checkbox\" checked={enable} disabled={installing || Boolean(preview.existing?.enabled)} onChange={event => setEnable(event.target.checked)}/>\n <span>{preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow')}</span>\n </label>\n <span className=\"wbi-foot-end\"/>\n <button className={classes.secondary} onClick={() => void controller.cancel()} disabled={installing}>{t('wb.install.cancel')}</button>\n <button className={`${classes.primary} wbi-install${armed ? '' : ' is-arming'}`} disabled={!armed || installing} onClick={() => void controller.confirm(enable)}>\n {installing ? t('wb.install.installing') : verb}\n </button>\n </footer>\n </>;\n}\n\nfunction Done<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'done' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n return <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-ok\"><Glyph d={G.check} size={26}/></div>\n <h2 id=\"wbi-title\">{t('wb.install.done', { name: request.name })}</h2>\n <p>{request.kind === 'plugin'\n ? (request.enabled ? t('wb.install.done.pluginOn', { site }) : t('wb.install.done.pluginOff'))\n : request.kind === 'strings'\n ? (request.enabled ? t('wb.install.done.stringsOn', { site }) : t('wb.install.done.stringsOff'))\n : request.kind === 'icons'\n ? (request.enabled ? t('wb.install.done.iconsOn') : t('wb.install.done.iconsOff'))\n : (request.enabled ? t('wb.install.done.themeOn') : t('wb.install.done.themeOff'))}</p>\n {request.fonts.length > 0 && <p className=\"wbi-muted\">{t('wb.install.done.fonts', { fonts: request.fonts.join(', ') })}</p>}\n <div className=\"wbi-state-actions\">\n <button className={classes.secondary} onClick={() => { controller.close(); props.openSection(request.kind); }}>{request.kind === 'plugin' ? t('wb.install.openPlugins') : request.kind === 'strings' ? t('wb.install.openStrings') : t('wb.install.openAppearance')}</button>\n <button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.doneButton')}</button>\n </div>\n </div>;\n}\n\nfunction Dialog<Theme>({ request, props }: { request: InstallRequest<Theme>; props: Shared<Theme> }) {\n const { t, controller, classes, setOverlay } = props;\n const box = useRef<HTMLDivElement>(null);\n useEffect(() => {\n setOverlay(1);\n return () => setOverlay(-1);\n }, []);\n useEffect(() => { box.current?.querySelector<HTMLElement>('.wbi-close, [autofocus]')?.focus(); }, [request.status]);\n const dismiss = () => (request.status === 'ready' ? void controller.cancel() : request.status === 'installing' ? undefined : controller.close());\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') { event.preventDefault(); dismiss(); }\n // Enter never confirms an install; only a click on Install does.\n if (event.key === 'Enter' && (event.target as HTMLElement).classList.contains('wbi-install')) event.preventDefault();\n };\n return createPortal(<div className=\"wbi-backdrop\" onMouseDown={dismiss}>\n <div ref={box} className={`wbi ${classes.pop} is-${request.status}`.replace(/\\s+/g, ' ')} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"wbi-title\" onMouseDown={event => event.stopPropagation()} onKeyDown={onKey}>\n {request.status === 'loading' && <div className=\"wbi-state\">\n <div className=\"wbi-spinner\" aria-hidden=\"true\"/>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.detail}</p>\n <div className=\"wbi-state-actions\"><button className={classes.secondary} onClick={controller.close}>{t('wb.install.cancel')}</button></div>\n </div>}\n {(request.status === 'ready' || request.status === 'installing') && <Ready request={request} props={props}/>}\n {request.status === 'done' && <Done request={request} props={props}/>}\n {request.status === 'error' && <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-warn\"><Glyph d={G.warn} size={26}/></div>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.message}</p>\n <div className=\"wbi-state-actions\"><button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.close')}</button></div>\n </div>}\n </div>\n </div>, document.body);\n}\n\nconst hasFiles = (event: DragEvent) => Array.from(event.dataTransfer?.types ?? []).includes('Files');\n\n/**\n * Install links, the screen, and file drops on the window. A file dragged over the shell (tab\n * strip, titlebar, settings) shows a drop target over the whole window; files dragged straight into\n * a site tab stay the site's (e.g. images for a post).\n */\nexport function InstallHost<Theme>(props: InstallHostProps<Theme>) {\n const { t, controller, setOverlay, ownDropTargets } = props;\n const shared: Shared<Theme> = { ...props, classes: { ...DEFAULT_CLASSES, ...props.classNames } };\n const request = useInstallRequest(controller);\n const [dropping, setDropping] = useState(false);\n useEffect(() => controller.start(), [controller]);\n useEffect(() => {\n let last = 0;\n let timer: ReturnType<typeof setInterval> | undefined;\n const own = (event: DragEvent) => Boolean(ownDropTargets && (event.target as Element | null)?.closest?.(ownDropTargets));\n const stop = () => { clearInterval(timer); timer = undefined; setDropping(false); };\n const over = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n last = Date.now();\n if (!timer) {\n setDropping(true);\n // Esc or leaving the window ends a drag without an event here.\n timer = setInterval(() => { if (Date.now() - last > 900) stop(); }, 200);\n }\n };\n const drop = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n stop();\n const file = event.dataTransfer?.files[0];\n if (file) void controller.requestFile(file);\n };\n window.addEventListener('dragenter', over, true);\n window.addEventListener('dragover', over, true);\n window.addEventListener('drop', drop, true);\n return () => { stop(); window.removeEventListener('dragenter', over, true); window.removeEventListener('dragover', over, true); window.removeEventListener('drop', drop, true); };\n }, [controller, ownDropTargets]);\n useEffect(() => {\n if (!dropping) return;\n setOverlay(1);\n return () => setOverlay(-1);\n }, [dropping]);\n return <>\n {dropping && createPortal(<div className=\"wbi-drop\" aria-hidden=\"true\"><div>\n <Glyph d={G.file} size={30}/>\n <strong>{t('wb.install.drop')}</strong>\n <span>{t('wb.install.dropHint')}</span>\n </div></div>, document.body)}\n {request && <Dialog request={request} props={shared}/>}\n </>;\n}\n"]}
|
|
@@ -51,6 +51,18 @@ export type StoreViewProps<Theme> = {
|
|
|
51
51
|
/** Theme ids that ship with the app, and the owner's own theme ids now. */
|
|
52
52
|
builtinThemes: readonly string[];
|
|
53
53
|
userThemes: readonly string[];
|
|
54
|
+
/** The owner's installed icon pack ids now (an icon pack the owner removed in Appearance shows as installable again). */
|
|
55
|
+
userIcons?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* The app's area plugins, for items of kind `builtin`: whether the app has one by this id, whether
|
|
58
|
+
* its switch is on, and turning it on or off. Without it (or for an id it does not have) a built-in
|
|
59
|
+
* item only says it is built in.
|
|
60
|
+
*/
|
|
61
|
+
areas?: {
|
|
62
|
+
has(id: string): boolean;
|
|
63
|
+
on(id: string): boolean;
|
|
64
|
+
set(id: string, on: boolean): Promise<void>;
|
|
65
|
+
};
|
|
54
66
|
/** Removes an installed item (plugin file, or the owner's copy of a store theme); false: nothing to remove. */
|
|
55
67
|
onRemove(item: StoreItem, view: StoreCatalogView): Promise<boolean>;
|
|
56
68
|
/** Makes a built-in theme the current one. */
|
package/dist/shell/StoreView.js
CHANGED
|
@@ -26,9 +26,14 @@ function Preview({ item }) {
|
|
|
26
26
|
// Offline or not published yet: swatches from the signed catalog (themes) or a plain tile.
|
|
27
27
|
return _jsx("div", { className: "wbs-img wbs-swatch", style: c ? { background: c.bg } : undefined, "aria-hidden": "true", children: c ? _jsxs(_Fragment, { children: [_jsx("span", { style: { background: c.surface ?? c.bg, borderColor: c.text } }), _jsx("i", { style: { background: c.text } }), _jsx("b", { style: { background: c.accent } })] }) : _jsx("strong", { children: item.name.slice(0, 1) }) });
|
|
28
28
|
}
|
|
29
|
-
function Action({ item, state, busy, t, ui, onInstall, onRemove, onUse }) {
|
|
29
|
+
function Action({ item, state, busy, t, ui, areas, onInstall, onRemove, onUse, onArea }) {
|
|
30
30
|
const { Button } = ui;
|
|
31
31
|
const [asking, setAsking] = useState(false);
|
|
32
|
+
if (state.state === 'area') {
|
|
33
|
+
const known = areas?.has(item.id) ?? false;
|
|
34
|
+
const on = known && areas.on(item.id);
|
|
35
|
+
return _jsxs("div", { className: "wbs-actions", children: [_jsxs("span", { className: "wbs-state", children: [t('wb.store.builtinItem'), known && ` · ${on ? t('wb.store.areaOn') : t('wb.store.areaOff')}`] }), known && _jsxs("label", { className: "wbs-switch", title: t('wb.store.areaSwitch', { name: item.name }), children: [_jsx("input", { type: "checkbox", role: "switch", checked: on, "aria-label": t('wb.store.areaSwitch', { name: item.name }), onChange: event => onArea(event.target.checked) }), _jsx("span", { "aria-hidden": "true" })] })] });
|
|
36
|
+
}
|
|
32
37
|
if (state.state === 'builtin')
|
|
33
38
|
return _jsxs("div", { className: "wbs-actions", children: [_jsx("span", { className: "wbs-state", children: t('wb.store.builtIn') }), _jsx(Button, { size: "sm", onClick: onUse, children: t('wb.store.use') })] });
|
|
34
39
|
if (state.state === 'install')
|
|
@@ -69,7 +74,7 @@ export function StoreView(props) {
|
|
|
69
74
|
useEffect(() => { if (request === null)
|
|
70
75
|
void load(false); }, [request === null]);
|
|
71
76
|
const items = view?.catalog?.items ?? [];
|
|
72
|
-
const context = { plugins: view?.plugins ?? {}, records: view?.records.items ?? {}, builtinThemes: props.builtinThemes, userThemes: props.userThemes };
|
|
77
|
+
const context = { plugins: view?.plugins ?? {}, records: view?.records.items ?? {}, builtinThemes: props.builtinThemes, userThemes: props.userThemes, userIcons: props.userIcons };
|
|
73
78
|
const categories = useMemo(() => [...new Set(items.filter(item => kind === 'all' || item.kind === kind).map(item => item.category))].sort(), [items, kind]);
|
|
74
79
|
const shown = filterItems(items, query, kind, category);
|
|
75
80
|
const updates = items.filter(item => itemState(item, context).state === 'update');
|
|
@@ -95,9 +100,9 @@ export function StoreView(props) {
|
|
|
95
100
|
const status = view?.error
|
|
96
101
|
? _jsx("span", { className: "wbs-status is-warn", role: "status", children: view.catalog ? t('wb.store.offline', { when: ago(view.fetchedAt), error: errorText(view.error) }) : t('wb.store.unreachableShort') })
|
|
97
102
|
: view?.catalog ? _jsxs("span", { className: "wbs-status is-ok", role: "status", children: [_jsx("svg", { width: "13", height: "13", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6zM8.5 12l2.5 2.5 4.5-5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }), t('wb.store.verified', { when: ago(view.fetchedAt) })] }) : null;
|
|
98
|
-
return _jsxs("div", { className: "wbs", children: [_jsx("p", { className: "wbs-intro", children: t('wb.store.intro') }), _jsxs("div", { className: "wbs-toolbar", children: [_jsx(SearchField, { label: t('wb.store.search'), placeholder: t('wb.store.searchPlaceholder'), value: query, onChange: setQuery }), _jsx(Segmented, { label: t('wb.store.kind'), size: "sm", value: kind, onChange: next => { setKind(next); setCategory('all'); }, options: [{ value: 'all', label: t('wb.store.all') }, { value: 'theme', label: t('wb.store.themes') }, { value: 'plugin', label: t('wb.store.pluginsTab') }, ...(items.some(item => item.kind === 'strings') ? [{ value: 'strings', label: t('wb.store.strings') }] : [])] }), _jsx(Button, { size: "sm", tone: "ghost", disabled: loading, onClick: () => void load(true), children: loading ? t('wb.store.checking') : t('wb.store.refresh') })] }), _jsxs("div", { className: "wbs-cats", role: "group", "aria-label": t('wb.store.categories'), children: [['all', ...categories].map(id => _jsx("button", { className: category === id ? 'is-on' : '', "aria-pressed": category === id, onClick: () => setCategory(id), children: id === 'all' ? t('wb.store.everything') : categoryLabel(id, t) }, id)), _jsx("span", { className: "wbs-cats-end" }), status] }), updates.length > 0 && _jsxs("div", { className: "wbs-updates", role: "status", children: [_jsx("strong", { children: t('wb.store.updates', { count: updates.length }) }), _jsx("span", { children: updates.map(item => item.name).join(', ') })] }), !view && loading && _jsx("div", { className: "wbs-grid", "aria-busy": "true", children: Array.from({ length: 6 }, (_, i) => _jsx("div", { className: "wbs-card is-skeleton" }, i)) }), view && !view.catalog && _jsxs(EmptyState, { icon: STORE_ICON, title: t('wb.store.unreachable'), action: _jsx(Button, { size: "sm", onClick: () => void load(true), children: t('wb.store.tryAgain') }), children: [view.error ? errorText(view.error).replace(/\.?$/, '.') : t('wb.store.noCatalog'), " ", t('wb.store.nothingChanged')] }), view?.catalog && shown.length === 0 && _jsx(EmptyState, { icon: STORE_ICON, title: t('wb.store.noMatch'), children: t('wb.store.noMatchHint') }), _jsx("div", { className: "wbs-grid", children: shown.map(item => {
|
|
103
|
+
return _jsxs("div", { className: "wbs", children: [_jsx("p", { className: "wbs-intro", children: t('wb.store.intro') }), _jsxs("div", { className: "wbs-toolbar", children: [_jsx(SearchField, { label: t('wb.store.search'), placeholder: t('wb.store.searchPlaceholder'), value: query, onChange: setQuery }), _jsx(Segmented, { label: t('wb.store.kind'), size: "sm", value: kind, onChange: next => { setKind(next); setCategory('all'); }, options: [{ value: 'all', label: t('wb.store.all') }, { value: 'theme', label: t('wb.store.themes') }, { value: 'plugin', label: t('wb.store.pluginsTab') }, ...(items.some(item => item.kind === 'icons') ? [{ value: 'icons', label: t('wb.store.icons') }] : []), ...(items.some(item => item.kind === 'strings') ? [{ value: 'strings', label: t('wb.store.strings') }] : []), ...(items.some(item => item.kind === 'builtin') ? [{ value: 'builtin', label: t('wb.store.builtinTab') }] : [])] }), _jsx(Button, { size: "sm", tone: "ghost", disabled: loading, onClick: () => void load(true), children: loading ? t('wb.store.checking') : t('wb.store.refresh') })] }), _jsxs("div", { className: "wbs-cats", role: "group", "aria-label": t('wb.store.categories'), children: [['all', ...categories].map(id => _jsx("button", { className: category === id ? 'is-on' : '', "aria-pressed": category === id, onClick: () => setCategory(id), children: id === 'all' ? t('wb.store.everything') : categoryLabel(id, t) }, id)), _jsx("span", { className: "wbs-cats-end" }), status] }), updates.length > 0 && _jsxs("div", { className: "wbs-updates", role: "status", children: [_jsx("strong", { children: t('wb.store.updates', { count: updates.length }) }), _jsx("span", { children: updates.map(item => item.name).join(', ') })] }), !view && loading && _jsx("div", { className: "wbs-grid", "aria-busy": "true", children: Array.from({ length: 6 }, (_, i) => _jsx("div", { className: "wbs-card is-skeleton" }, i)) }), view && !view.catalog && _jsxs(EmptyState, { icon: STORE_ICON, title: t('wb.store.unreachable'), action: _jsx(Button, { size: "sm", onClick: () => void load(true), children: t('wb.store.tryAgain') }), children: [view.error ? errorText(view.error).replace(/\.?$/, '.') : t('wb.store.noCatalog'), " ", t('wb.store.nothingChanged')] }), view?.catalog && shown.length === 0 && _jsx(EmptyState, { icon: STORE_ICON, title: t('wb.store.noMatch'), children: t('wb.store.noMatchHint') }), _jsx("div", { className: "wbs-grid", children: shown.map(item => {
|
|
99
104
|
const state = itemState(item, context);
|
|
100
|
-
return _jsxs("article", { className: `wbs-card is-${item.kind}`, children: [_jsx(Preview, { item: item }), _jsxs("div", { className: "wbs-card-body", children: [_jsxs("header", { children: [_jsx("h3", { children: item.name }), _jsx(Badge, { children: item.kind === 'theme' ? t('wb.store.theme') : item.kind === 'strings' ? t('wb.store.stringsItem') : t('wb.store.plugin') })] }), _jsxs("p", { className: "wbs-meta", children: [item.author && `${t('wb.store.by', { author: item.author })} · `, "v", item.version, " \u00B7 ", item.kind === 'strings' && item.language ? item.language : categoryLabel(item.category, t), item.license ? ` · ${item.license}` : ''] }), _jsx("p", { className: "wbs-desc", children: item.description }), item.kind === 'plugin' && _jsx("ul", { className: "wbs-perms", "aria-label": t('wb.store.permissions'), children: permissionBadges(item.permissions, t, site).map(badge => _jsx("li", { className: `is-${badge.tone}`, title: badge.detail, children: badge.label }, badge.id)) }), _jsx(Action, { item: item, state: state, busy: request !== null, t: t, ui: ui, onInstall: () => void controller.requestStoreItem(item), onRemove: () => void removeItem(item), onUse: () => void props.onUse(item).then(() => notify(t('wb.store.themeNow', { name: item.name }))).catch(error => notify(errorText(error), true)) })] })] }, `${item.kind}:${item.id}`);
|
|
105
|
+
return _jsxs("article", { className: `wbs-card is-${item.kind}`, children: [_jsx(Preview, { item: item }), _jsxs("div", { className: "wbs-card-body", children: [_jsxs("header", { children: [_jsx("h3", { children: item.name }), _jsx(Badge, { children: item.kind === 'theme' ? t('wb.store.theme') : item.kind === 'strings' ? t('wb.store.stringsItem') : item.kind === 'icons' ? t('wb.store.iconsItem') : item.kind === 'builtin' ? t('wb.store.builtinItem') : t('wb.store.plugin') })] }), _jsxs("p", { className: "wbs-meta", children: [item.author && `${t('wb.store.by', { author: item.author })} · `, "v", item.version, " \u00B7 ", item.kind === 'strings' && item.language ? item.language : categoryLabel(item.category, t), item.license ? ` · ${item.license}` : ''] }), _jsx("p", { className: "wbs-desc", children: item.description }), item.kind === 'plugin' && _jsx("ul", { className: "wbs-perms", "aria-label": t('wb.store.permissions'), children: permissionBadges(item.permissions, t, site).map(badge => _jsx("li", { className: `is-${badge.tone}`, title: badge.detail, children: badge.label }, badge.id)) }), _jsx(Action, { item: item, state: state, busy: request !== null, t: t, ui: ui, areas: props.areas, onArea: on => void props.areas?.set(item.id, on).catch(error => notify(errorText(error), true)), onInstall: () => void controller.requestStoreItem(item), onRemove: () => void removeItem(item), onUse: () => void props.onUse(item).then(() => notify(t('wb.store.themeNow', { name: item.name }))).catch(error => notify(errorText(error), true)) })] })] }, `${item.kind}:${item.id}`);
|
|
101
106
|
}) }), _jsx("p", { className: "wbs-foot", children: t('wb.store.foot') })] });
|
|
102
107
|
}
|
|
103
108
|
//# sourceMappingURL=StoreView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StoreView.js","sourceRoot":"","sources":["../../../../../shell/src/StoreView.tsx"],"names":[],"mappings":"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","sourcesContent":["// The wayBetter Store view, shared by every wayBetter app: themes and plugins from the signed\n// catalog (native code verifies its Ed25519 signature, keeps this app's items, then checks each\n// download's sha256). Search, kinds, categories, cards with previews and permission badges, and\n// Install / Update / Remove. Installing always goes through the install screen (InstallHost), never\n// straight from here. Styles: `store.css` (framework `--wb-*` tokens). The app may pass its own\n// controls (buttons, search field, segmented control) so the view matches its settings.\n\nimport { useEffect, useMemo, useState, useSyncExternalStore, type ReactNode } from 'react';\nimport type { InstallController } from './installController.ts';\nimport type { StoreText } from './storeMessages.ts';\nimport { categoryLabel, errorText, filterItems, itemState, permissionBadges, type ItemState, type StoreCatalogView, type StoreItem } from './storeModel.ts';\n\ntype ButtonProps = { children: ReactNode; onClick?(): void; tone?: 'plain' | 'primary' | 'ghost' | 'danger'; size?: 'sm' | 'md'; disabled?: boolean; title?: string };\ntype Option<T extends string> = { value: T; label: string };\nexport type StoreControls = {\n Button(props: ButtonProps): ReactNode;\n SearchField(props: { value: string; onChange(next: string): void; placeholder: string; label: string }): ReactNode;\n Segmented<T extends string>(props: { value: T; options: Array<Option<T>>; onChange(next: T): void; label: string; size?: 'sm' | 'md' }): ReactNode;\n EmptyState(props: { icon?: ReactNode; title: string; children?: ReactNode; action?: ReactNode }): ReactNode;\n Badge(props: { children: ReactNode }): ReactNode;\n};\n\nexport const DEFAULT_CONTROLS: StoreControls = {\n Button: ({ children, onClick, tone = 'plain', size = 'md', disabled, title }) =>\n <button type=\"button\" className={`wb-btn is-${tone} is-${size}`} disabled={disabled} title={title} onClick={onClick}>{children}</button>,\n SearchField: ({ value, onChange, placeholder, label }) =>\n <input className=\"wb-field\" type=\"search\" aria-label={label} placeholder={placeholder} value={value}\n onChange={event => onChange(event.target.value)} onKeyDown={event => { if (event.key === 'Escape' && value) { event.stopPropagation(); onChange(''); } }}/>,\n Segmented: ({ value, options, onChange, label }) =>\n <div className=\"wb-segmented\" role=\"radiogroup\" aria-label={label}>\n {options.map(option => <button key={option.value} type=\"button\" role=\"radio\" aria-checked={option.value === value} className={option.value === value ? 'is-on' : ''} onClick={() => onChange(option.value)}>{option.label}</button>)}\n </div>,\n EmptyState: ({ icon, title, children, action }) =>\n <div className=\"wb-empty\">{icon && <div aria-hidden=\"true\">{icon}</div>}<strong>{title}</strong>{children && <p>{children}</p>}{action}</div>,\n Badge: ({ children }) => <span className=\"wb-badge\">{children}</span>,\n};\n\nexport type StoreViewProps<Theme> = {\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n /** `store_catalog` (the app passes `refresh => invoke('store_catalog', { refresh })`). */\n load(refresh: boolean): Promise<StoreCatalogView>;\n /** The install screen's controller: Install opens it; the list refreshes when it closes. */\n controller: InstallController<Theme>;\n /** Theme ids that ship with the app, and the owner's own theme ids now. */\n builtinThemes: readonly string[];\n userThemes: readonly string[];\n /** Removes an installed item (plugin file, or the owner's copy of a store theme); false: nothing to remove. */\n onRemove(item: StoreItem, view: StoreCatalogView): Promise<boolean>;\n /** Makes a built-in theme the current one. */\n onUse(item: StoreItem): Promise<void>;\n notify(text: string, error?: boolean): void;\n /** \"3 minutes ago\" for a timestamp (the app's relative-time formatter). */\n relativeTime(at: number): string;\n /** Window events after which the list reloads (e.g. the app's \"plugins changed\"). */\n reloadOn?: readonly string[];\n controls?: Partial<StoreControls>;\n};\n\nconst STORE_ICON = <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4 9l1.5-5h13L20 9M4 9h16v11H4zM4 9a2.7 2.7 0 0 0 5.3 0 2.7 2.7 0 0 0 5.4 0 2.7 2.7 0 0 0 5.3 0M10 20v-5h4v5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinejoin=\"round\"/></svg>;\n\nfunction Preview({ item }: { item: StoreItem }) {\n const [broken, setBroken] = useState(false);\n const c = item.colors;\n if (item.preview && !broken) return <img className=\"wbs-img\" src={item.preview} alt=\"\" loading=\"lazy\" onError={() => setBroken(true)}/>;\n // Offline or not published yet: swatches from the signed catalog (themes) or a plain tile.\n return <div className=\"wbs-img wbs-swatch\" style={c ? { background: c.bg } : undefined} aria-hidden=\"true\">\n {c ? <><span style={{ background: c.surface ?? c.bg, borderColor: c.text }}/><i style={{ background: c.text }}/><b style={{ background: c.accent }}/></> : <strong>{item.name.slice(0, 1)}</strong>}\n </div>;\n}\n\nfunction Action({ item, state, busy, t, ui, onInstall, onRemove, onUse }: { item: StoreItem; state: ItemState; busy: boolean; t: StoreText; ui: StoreControls; onInstall(): void; onRemove(): void; onUse(): void }) {\n const { Button } = ui;\n const [asking, setAsking] = useState(false);\n if (state.state === 'builtin') return <div className=\"wbs-actions\"><span className=\"wbs-state\">{t('wb.store.builtIn')}</span><Button size=\"sm\" onClick={onUse}>{t('wb.store.use')}</Button></div>;\n if (state.state === 'install') return <div className=\"wbs-actions\"><Button size=\"sm\" tone=\"primary\" disabled={busy} onClick={onInstall}>{t('wb.store.install')}</Button></div>;\n const remove = asking\n ? <><Button size=\"sm\" tone=\"danger\" onClick={() => { setAsking(false); onRemove(); }}>{t('wb.store.remove')}</Button><Button size=\"sm\" tone=\"ghost\" onClick={() => setAsking(false)}>{t('wb.store.keep')}</Button></>\n : <Button size=\"sm\" tone=\"ghost\" onClick={() => setAsking(true)}>{t('wb.store.remove')}</Button>;\n if (state.state === 'update') return <div className=\"wbs-actions\"><Button size=\"sm\" tone=\"primary\" disabled={busy} onClick={onInstall}>{t('wb.store.updateTo', { version: item.version })}</Button>{remove}</div>;\n if (state.state === 'modified') return <div className=\"wbs-actions\"><span className=\"wbs-state\" title={t('wb.store.modifiedTitle')}>{t('wb.store.modified')}</span><Button size=\"sm\" disabled={busy} onClick={onInstall}>{t('wb.store.replace')}</Button>{remove}</div>;\n return <div className=\"wbs-actions\"><span className=\"wbs-state is-ok\">{state.version ? t('wb.store.installedVersion', { version: state.version }) : t('wb.store.installed')}</span>{remove}</div>;\n}\n\nexport function StoreView<Theme>(props: StoreViewProps<Theme>) {\n const { t, site, controller, notify } = props;\n const ui: StoreControls = { ...DEFAULT_CONTROLS, ...props.controls };\n const { Button, SearchField, Segmented, EmptyState, Badge } = ui;\n const [view, setView] = useState<StoreCatalogView | null>(null);\n const [loading, setLoading] = useState(false);\n const [query, setQuery] = useState('');\n const [kind, setKind] = useState<'all' | 'theme' | 'plugin' | 'strings'>('all');\n const [category, setCategory] = useState<string>('all');\n const request = useSyncExternalStore(controller.subscribe, controller.current, controller.current);\n\n const load = (refresh: boolean) => {\n setLoading(true);\n return props.load(refresh).then(setView).catch(error => notify(errorText(error), true)).finally(() => setLoading(false));\n };\n useEffect(() => { void load(false); }, []);\n // Installs finish in the install screen; refresh what is installed afterwards.\n useEffect(() => {\n const again = () => void load(false);\n const events = props.reloadOn ?? [];\n for (const name of events) window.addEventListener(name, again);\n return () => { for (const name of events) window.removeEventListener(name, again); };\n }, [(props.reloadOn ?? []).join(' ')]);\n useEffect(() => { if (request === null) void load(false); }, [request === null]);\n\n const items = view?.catalog?.items ?? [];\n const context = { plugins: view?.plugins ?? {}, records: view?.records.items ?? {}, builtinThemes: props.builtinThemes, userThemes: props.userThemes };\n const categories = useMemo(() => [...new Set(items.filter(item => kind === 'all' || item.kind === kind).map(item => item.category))].sort(), [items, kind]);\n const shown = filterItems(items, query, kind, category);\n const updates = items.filter(item => itemState(item, context).state === 'update');\n\n const ago = (iso: string | null) => {\n if (!iso) return '';\n const at = Date.parse(iso);\n return Number.isFinite(at) ? props.relativeTime(Math.min(at, Date.now())) : '';\n };\n\n async function removeItem(item: StoreItem) {\n if (!view) return;\n try {\n if (!(await props.onRemove(item, view))) return;\n notify(t('wb.store.removed', { name: item.name }));\n await load(false);\n } catch (error) { notify(errorText(error), true); }\n }\n\n const status = view?.error\n ? <span className=\"wbs-status is-warn\" role=\"status\">{view.catalog ? t('wb.store.offline', { when: ago(view.fetchedAt), error: errorText(view.error) }) : t('wb.store.unreachableShort')}</span>\n : view?.catalog ? <span className=\"wbs-status is-ok\" role=\"status\"><svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6zM8.5 12l2.5 2.5 4.5-5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>{t('wb.store.verified', { when: ago(view.fetchedAt) })}</span> : null;\n\n return <div className=\"wbs\">\n <p className=\"wbs-intro\">{t('wb.store.intro')}</p>\n <div className=\"wbs-toolbar\">\n <SearchField label={t('wb.store.search')} placeholder={t('wb.store.searchPlaceholder')} value={query} onChange={setQuery}/>\n <Segmented label={t('wb.store.kind')} size=\"sm\" value={kind} onChange={next => { setKind(next); setCategory('all'); }} options={[{ value: 'all', label: t('wb.store.all') }, { value: 'theme', label: t('wb.store.themes') }, { value: 'plugin', label: t('wb.store.pluginsTab') }, ...(items.some(item => item.kind === 'strings') ? [{ value: 'strings' as const, label: t('wb.store.strings') }] : [])]}/>\n <Button size=\"sm\" tone=\"ghost\" disabled={loading} onClick={() => void load(true)}>{loading ? t('wb.store.checking') : t('wb.store.refresh')}</Button>\n </div>\n <div className=\"wbs-cats\" role=\"group\" aria-label={t('wb.store.categories')}>\n {['all', ...categories].map(id => <button key={id} className={category === id ? 'is-on' : ''} aria-pressed={category === id} onClick={() => setCategory(id)}>{id === 'all' ? t('wb.store.everything') : categoryLabel(id, t)}</button>)}\n <span className=\"wbs-cats-end\"/>\n {status}\n </div>\n {updates.length > 0 && <div className=\"wbs-updates\" role=\"status\"><strong>{t('wb.store.updates', { count: updates.length })}</strong><span>{updates.map(item => item.name).join(', ')}</span></div>}\n {!view && loading && <div className=\"wbs-grid\" aria-busy=\"true\">{Array.from({ length: 6 }, (_, i) => <div key={i} className=\"wbs-card is-skeleton\"/>)}</div>}\n {view && !view.catalog && <EmptyState icon={STORE_ICON} title={t('wb.store.unreachable')} action={<Button size=\"sm\" onClick={() => void load(true)}>{t('wb.store.tryAgain')}</Button>}>\n {view.error ? errorText(view.error).replace(/\\.?$/, '.') : t('wb.store.noCatalog')} {t('wb.store.nothingChanged')}\n </EmptyState>}\n {view?.catalog && shown.length === 0 && <EmptyState icon={STORE_ICON} title={t('wb.store.noMatch')}>{t('wb.store.noMatchHint')}</EmptyState>}\n <div className=\"wbs-grid\">\n {shown.map(item => {\n const state = itemState(item, context);\n return <article key={`${item.kind}:${item.id}`} className={`wbs-card is-${item.kind}`}>\n <Preview item={item}/>\n <div className=\"wbs-card-body\">\n <header>\n <h3>{item.name}</h3>\n <Badge>{item.kind === 'theme' ? t('wb.store.theme') : item.kind === 'strings' ? t('wb.store.stringsItem') : t('wb.store.plugin')}</Badge>\n </header>\n <p className=\"wbs-meta\">{item.author && `${t('wb.store.by', { author: item.author })} · `}v{item.version} · {item.kind === 'strings' && item.language ? item.language : categoryLabel(item.category, t)}{item.license ? ` · ${item.license}` : ''}</p>\n <p className=\"wbs-desc\">{item.description}</p>\n {item.kind === 'plugin' && <ul className=\"wbs-perms\" aria-label={t('wb.store.permissions')}>\n {permissionBadges(item.permissions, t, site).map(badge => <li key={badge.id} className={`is-${badge.tone}`} title={badge.detail}>{badge.label}</li>)}\n </ul>}\n <Action item={item} state={state} busy={request !== null} t={t} ui={ui}\n onInstall={() => void controller.requestStoreItem(item)}\n onRemove={() => void removeItem(item)}\n onUse={() => void props.onUse(item).then(() => notify(t('wb.store.themeNow', { name: item.name }))).catch(error => notify(errorText(error), true))}/>\n </div>\n </article>;\n })}\n </div>\n <p className=\"wbs-foot\">{t('wb.store.foot')}</p>\n </div>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"StoreView.js","sourceRoot":"","sources":["../../../../../shell/src/StoreView.tsx"],"names":[],"mappings":"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","sourcesContent":["// The wayBetter Store view, shared by every wayBetter app: themes and plugins from the signed\n// catalog (native code verifies its Ed25519 signature, keeps this app's items, then checks each\n// download's sha256). Search, kinds, categories, cards with previews and permission badges, and\n// Install / Update / Remove. Installing always goes through the install screen (InstallHost), never\n// straight from here. Styles: `store.css` (framework `--wb-*` tokens). The app may pass its own\n// controls (buttons, search field, segmented control) so the view matches its settings.\n\nimport { useEffect, useMemo, useState, useSyncExternalStore, type ReactNode } from 'react';\nimport type { InstallController } from './installController.ts';\nimport type { StoreText } from './storeMessages.ts';\nimport { categoryLabel, errorText, filterItems, itemState, permissionBadges, type ItemState, type StoreCatalogView, type StoreItem, type StoreKind } from './storeModel.ts';\n\ntype ButtonProps = { children: ReactNode; onClick?(): void; tone?: 'plain' | 'primary' | 'ghost' | 'danger'; size?: 'sm' | 'md'; disabled?: boolean; title?: string };\ntype Option<T extends string> = { value: T; label: string };\nexport type StoreControls = {\n Button(props: ButtonProps): ReactNode;\n SearchField(props: { value: string; onChange(next: string): void; placeholder: string; label: string }): ReactNode;\n Segmented<T extends string>(props: { value: T; options: Array<Option<T>>; onChange(next: T): void; label: string; size?: 'sm' | 'md' }): ReactNode;\n EmptyState(props: { icon?: ReactNode; title: string; children?: ReactNode; action?: ReactNode }): ReactNode;\n Badge(props: { children: ReactNode }): ReactNode;\n};\n\nexport const DEFAULT_CONTROLS: StoreControls = {\n Button: ({ children, onClick, tone = 'plain', size = 'md', disabled, title }) =>\n <button type=\"button\" className={`wb-btn is-${tone} is-${size}`} disabled={disabled} title={title} onClick={onClick}>{children}</button>,\n SearchField: ({ value, onChange, placeholder, label }) =>\n <input className=\"wb-field\" type=\"search\" aria-label={label} placeholder={placeholder} value={value}\n onChange={event => onChange(event.target.value)} onKeyDown={event => { if (event.key === 'Escape' && value) { event.stopPropagation(); onChange(''); } }}/>,\n Segmented: ({ value, options, onChange, label }) =>\n <div className=\"wb-segmented\" role=\"radiogroup\" aria-label={label}>\n {options.map(option => <button key={option.value} type=\"button\" role=\"radio\" aria-checked={option.value === value} className={option.value === value ? 'is-on' : ''} onClick={() => onChange(option.value)}>{option.label}</button>)}\n </div>,\n EmptyState: ({ icon, title, children, action }) =>\n <div className=\"wb-empty\">{icon && <div aria-hidden=\"true\">{icon}</div>}<strong>{title}</strong>{children && <p>{children}</p>}{action}</div>,\n Badge: ({ children }) => <span className=\"wb-badge\">{children}</span>,\n};\n\nexport type StoreViewProps<Theme> = {\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n /** `store_catalog` (the app passes `refresh => invoke('store_catalog', { refresh })`). */\n load(refresh: boolean): Promise<StoreCatalogView>;\n /** The install screen's controller: Install opens it; the list refreshes when it closes. */\n controller: InstallController<Theme>;\n /** Theme ids that ship with the app, and the owner's own theme ids now. */\n builtinThemes: readonly string[];\n userThemes: readonly string[];\n /** The owner's installed icon pack ids now (an icon pack the owner removed in Appearance shows as installable again). */\n userIcons?: readonly string[];\n /**\n * The app's area plugins, for items of kind `builtin`: whether the app has one by this id, whether\n * its switch is on, and turning it on or off. Without it (or for an id it does not have) a built-in\n * item only says it is built in.\n */\n areas?: { has(id: string): boolean; on(id: string): boolean; set(id: string, on: boolean): Promise<void> };\n /** Removes an installed item (plugin file, or the owner's copy of a store theme); false: nothing to remove. */\n onRemove(item: StoreItem, view: StoreCatalogView): Promise<boolean>;\n /** Makes a built-in theme the current one. */\n onUse(item: StoreItem): Promise<void>;\n notify(text: string, error?: boolean): void;\n /** \"3 minutes ago\" for a timestamp (the app's relative-time formatter). */\n relativeTime(at: number): string;\n /** Window events after which the list reloads (e.g. the app's \"plugins changed\"). */\n reloadOn?: readonly string[];\n controls?: Partial<StoreControls>;\n};\n\nconst STORE_ICON = <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M4 9l1.5-5h13L20 9M4 9h16v11H4zM4 9a2.7 2.7 0 0 0 5.3 0 2.7 2.7 0 0 0 5.4 0 2.7 2.7 0 0 0 5.3 0M10 20v-5h4v5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinejoin=\"round\"/></svg>;\n\nfunction Preview({ item }: { item: StoreItem }) {\n const [broken, setBroken] = useState(false);\n const c = item.colors;\n if (item.preview && !broken) return <img className=\"wbs-img\" src={item.preview} alt=\"\" loading=\"lazy\" onError={() => setBroken(true)}/>;\n // Offline or not published yet: swatches from the signed catalog (themes) or a plain tile.\n return <div className=\"wbs-img wbs-swatch\" style={c ? { background: c.bg } : undefined} aria-hidden=\"true\">\n {c ? <><span style={{ background: c.surface ?? c.bg, borderColor: c.text }}/><i style={{ background: c.text }}/><b style={{ background: c.accent }}/></> : <strong>{item.name.slice(0, 1)}</strong>}\n </div>;\n}\n\nfunction Action({ item, state, busy, t, ui, areas, onInstall, onRemove, onUse, onArea }: { item: StoreItem; state: ItemState; busy: boolean; t: StoreText; ui: StoreControls; areas?: StoreViewProps<unknown>['areas']; onInstall(): void; onRemove(): void; onUse(): void; onArea(on: boolean): void }) {\n const { Button } = ui;\n const [asking, setAsking] = useState(false);\n if (state.state === 'area') {\n const known = areas?.has(item.id) ?? false;\n const on = known && areas!.on(item.id);\n return <div className=\"wbs-actions\"><span className=\"wbs-state\">{t('wb.store.builtinItem')}{known && ` · ${on ? t('wb.store.areaOn') : t('wb.store.areaOff')}`}</span>\n {known && <label className=\"wbs-switch\" title={t('wb.store.areaSwitch', { name: item.name })}>\n <input type=\"checkbox\" role=\"switch\" checked={on} aria-label={t('wb.store.areaSwitch', { name: item.name })} onChange={event => onArea(event.target.checked)}/><span aria-hidden=\"true\"/>\n </label>}\n </div>;\n }\n if (state.state === 'builtin') return <div className=\"wbs-actions\"><span className=\"wbs-state\">{t('wb.store.builtIn')}</span><Button size=\"sm\" onClick={onUse}>{t('wb.store.use')}</Button></div>;\n if (state.state === 'install') return <div className=\"wbs-actions\"><Button size=\"sm\" tone=\"primary\" disabled={busy} onClick={onInstall}>{t('wb.store.install')}</Button></div>;\n const remove = asking\n ? <><Button size=\"sm\" tone=\"danger\" onClick={() => { setAsking(false); onRemove(); }}>{t('wb.store.remove')}</Button><Button size=\"sm\" tone=\"ghost\" onClick={() => setAsking(false)}>{t('wb.store.keep')}</Button></>\n : <Button size=\"sm\" tone=\"ghost\" onClick={() => setAsking(true)}>{t('wb.store.remove')}</Button>;\n if (state.state === 'update') return <div className=\"wbs-actions\"><Button size=\"sm\" tone=\"primary\" disabled={busy} onClick={onInstall}>{t('wb.store.updateTo', { version: item.version })}</Button>{remove}</div>;\n if (state.state === 'modified') return <div className=\"wbs-actions\"><span className=\"wbs-state\" title={t('wb.store.modifiedTitle')}>{t('wb.store.modified')}</span><Button size=\"sm\" disabled={busy} onClick={onInstall}>{t('wb.store.replace')}</Button>{remove}</div>;\n return <div className=\"wbs-actions\"><span className=\"wbs-state is-ok\">{state.version ? t('wb.store.installedVersion', { version: state.version }) : t('wb.store.installed')}</span>{remove}</div>;\n}\n\nexport function StoreView<Theme>(props: StoreViewProps<Theme>) {\n const { t, site, controller, notify } = props;\n const ui: StoreControls = { ...DEFAULT_CONTROLS, ...props.controls };\n const { Button, SearchField, Segmented, EmptyState, Badge } = ui;\n const [view, setView] = useState<StoreCatalogView | null>(null);\n const [loading, setLoading] = useState(false);\n const [query, setQuery] = useState('');\n const [kind, setKind] = useState<StoreKind | 'all'>('all');\n const [category, setCategory] = useState<string>('all');\n const request = useSyncExternalStore(controller.subscribe, controller.current, controller.current);\n\n const load = (refresh: boolean) => {\n setLoading(true);\n return props.load(refresh).then(setView).catch(error => notify(errorText(error), true)).finally(() => setLoading(false));\n };\n useEffect(() => { void load(false); }, []);\n // Installs finish in the install screen; refresh what is installed afterwards.\n useEffect(() => {\n const again = () => void load(false);\n const events = props.reloadOn ?? [];\n for (const name of events) window.addEventListener(name, again);\n return () => { for (const name of events) window.removeEventListener(name, again); };\n }, [(props.reloadOn ?? []).join(' ')]);\n useEffect(() => { if (request === null) void load(false); }, [request === null]);\n\n const items = view?.catalog?.items ?? [];\n const context = { plugins: view?.plugins ?? {}, records: view?.records.items ?? {}, builtinThemes: props.builtinThemes, userThemes: props.userThemes, userIcons: props.userIcons };\n const categories = useMemo(() => [...new Set(items.filter(item => kind === 'all' || item.kind === kind).map(item => item.category))].sort(), [items, kind]);\n const shown = filterItems(items, query, kind, category);\n const updates = items.filter(item => itemState(item, context).state === 'update');\n\n const ago = (iso: string | null) => {\n if (!iso) return '';\n const at = Date.parse(iso);\n return Number.isFinite(at) ? props.relativeTime(Math.min(at, Date.now())) : '';\n };\n\n async function removeItem(item: StoreItem) {\n if (!view) return;\n try {\n if (!(await props.onRemove(item, view))) return;\n notify(t('wb.store.removed', { name: item.name }));\n await load(false);\n } catch (error) { notify(errorText(error), true); }\n }\n\n const status = view?.error\n ? <span className=\"wbs-status is-warn\" role=\"status\">{view.catalog ? t('wb.store.offline', { when: ago(view.fetchedAt), error: errorText(view.error) }) : t('wb.store.unreachableShort')}</span>\n : view?.catalog ? <span className=\"wbs-status is-ok\" role=\"status\"><svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6zM8.5 12l2.5 2.5 4.5-5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>{t('wb.store.verified', { when: ago(view.fetchedAt) })}</span> : null;\n\n return <div className=\"wbs\">\n <p className=\"wbs-intro\">{t('wb.store.intro')}</p>\n <div className=\"wbs-toolbar\">\n <SearchField label={t('wb.store.search')} placeholder={t('wb.store.searchPlaceholder')} value={query} onChange={setQuery}/>\n <Segmented label={t('wb.store.kind')} size=\"sm\" value={kind} onChange={next => { setKind(next); setCategory('all'); }} options={[{ value: 'all', label: t('wb.store.all') }, { value: 'theme', label: t('wb.store.themes') }, { value: 'plugin', label: t('wb.store.pluginsTab') }, ...(items.some(item => item.kind === 'icons') ? [{ value: 'icons' as const, label: t('wb.store.icons') }] : []), ...(items.some(item => item.kind === 'strings') ? [{ value: 'strings' as const, label: t('wb.store.strings') }] : []), ...(items.some(item => item.kind === 'builtin') ? [{ value: 'builtin' as const, label: t('wb.store.builtinTab') }] : [])]}/>\n <Button size=\"sm\" tone=\"ghost\" disabled={loading} onClick={() => void load(true)}>{loading ? t('wb.store.checking') : t('wb.store.refresh')}</Button>\n </div>\n <div className=\"wbs-cats\" role=\"group\" aria-label={t('wb.store.categories')}>\n {['all', ...categories].map(id => <button key={id} className={category === id ? 'is-on' : ''} aria-pressed={category === id} onClick={() => setCategory(id)}>{id === 'all' ? t('wb.store.everything') : categoryLabel(id, t)}</button>)}\n <span className=\"wbs-cats-end\"/>\n {status}\n </div>\n {updates.length > 0 && <div className=\"wbs-updates\" role=\"status\"><strong>{t('wb.store.updates', { count: updates.length })}</strong><span>{updates.map(item => item.name).join(', ')}</span></div>}\n {!view && loading && <div className=\"wbs-grid\" aria-busy=\"true\">{Array.from({ length: 6 }, (_, i) => <div key={i} className=\"wbs-card is-skeleton\"/>)}</div>}\n {view && !view.catalog && <EmptyState icon={STORE_ICON} title={t('wb.store.unreachable')} action={<Button size=\"sm\" onClick={() => void load(true)}>{t('wb.store.tryAgain')}</Button>}>\n {view.error ? errorText(view.error).replace(/\\.?$/, '.') : t('wb.store.noCatalog')} {t('wb.store.nothingChanged')}\n </EmptyState>}\n {view?.catalog && shown.length === 0 && <EmptyState icon={STORE_ICON} title={t('wb.store.noMatch')}>{t('wb.store.noMatchHint')}</EmptyState>}\n <div className=\"wbs-grid\">\n {shown.map(item => {\n const state = itemState(item, context);\n return <article key={`${item.kind}:${item.id}`} className={`wbs-card is-${item.kind}`}>\n <Preview item={item}/>\n <div className=\"wbs-card-body\">\n <header>\n <h3>{item.name}</h3>\n <Badge>{item.kind === 'theme' ? t('wb.store.theme') : item.kind === 'strings' ? t('wb.store.stringsItem') : item.kind === 'icons' ? t('wb.store.iconsItem') : item.kind === 'builtin' ? t('wb.store.builtinItem') : t('wb.store.plugin')}</Badge>\n </header>\n <p className=\"wbs-meta\">{item.author && `${t('wb.store.by', { author: item.author })} · `}v{item.version} · {item.kind === 'strings' && item.language ? item.language : categoryLabel(item.category, t)}{item.license ? ` · ${item.license}` : ''}</p>\n <p className=\"wbs-desc\">{item.description}</p>\n {item.kind === 'plugin' && <ul className=\"wbs-perms\" aria-label={t('wb.store.permissions')}>\n {permissionBadges(item.permissions, t, site).map(badge => <li key={badge.id} className={`is-${badge.tone}`} title={badge.detail}>{badge.label}</li>)}\n </ul>}\n <Action item={item} state={state} busy={request !== null} t={t} ui={ui} areas={props.areas}\n onArea={on => void props.areas?.set(item.id, on).catch(error => notify(errorText(error), true))}\n onInstall={() => void controller.requestStoreItem(item)}\n onRemove={() => void removeItem(item)}\n onUse={() => void props.onUse(item).then(() => notify(t('wb.store.themeNow', { name: item.name }))).catch(error => notify(errorText(error), true))}/>\n </div>\n </article>;\n })}\n </div>\n <p className=\"wbs-foot\">{t('wb.store.foot')}</p>\n </div>;\n}\n"]}
|
|
@@ -1,17 +1,30 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type AppMenuTrigger } from './menuModel.ts';
|
|
1
3
|
import './appMenu.css';
|
|
2
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* How the menu is asked to open: at a trigger other than the app's own (`anchor`), under one pane's
|
|
6
|
+
* button (`pane`, a dockview panel id), at a submenu, with the first row focused (keyboard), or
|
|
7
|
+
* closing if it is open at that place.
|
|
8
|
+
*/
|
|
3
9
|
export type AppMenuRequest = {
|
|
4
|
-
anchor?:
|
|
10
|
+
anchor?: AppMenuTrigger;
|
|
11
|
+
pane?: string;
|
|
5
12
|
submenu?: string;
|
|
6
13
|
keyboard?: boolean;
|
|
7
14
|
toggle?: boolean;
|
|
8
15
|
};
|
|
9
16
|
/** Opens the app menu (Alt+F / F10, the palette, the account menu's last row). */
|
|
10
17
|
export declare const openAppMenu: (request?: AppMenuRequest) => boolean;
|
|
18
|
+
/** Opens the "Report a problem" summary (the native menu bar's Help item). */
|
|
19
|
+
export declare const openReport: () => boolean;
|
|
11
20
|
/** The keys that open the menu, as the button's tooltip and the account menu write them. */
|
|
12
21
|
export declare const APP_MENU_KEYS: string;
|
|
22
|
+
/**
|
|
23
|
+
* The menu (mounted once, in the titlebar). `trigger`: where clicks and keys open it; default the
|
|
24
|
+
* app's `ShellMenu.trigger`, else `pane`. `true` / `false` are the older spellings of `button` / `logo`.
|
|
25
|
+
*/
|
|
13
26
|
export declare function AppMenu({ trigger }?: {
|
|
14
|
-
trigger?: boolean;
|
|
27
|
+
trigger?: AppMenuTrigger | boolean;
|
|
15
28
|
}): import("react").JSX.Element;
|
|
16
29
|
/**
|
|
17
30
|
* The app's logo at the start of the titlebar: a second trigger of the same menu, hung under the
|
|
@@ -19,3 +32,13 @@ export declare function AppMenu({ trigger }?: {
|
|
|
19
32
|
* it does; a right-click shows the window's system menu, where a titlebar icon has always had it.
|
|
20
33
|
*/
|
|
21
34
|
export declare function AppMenuLogo(): import("react").JSX.Element;
|
|
35
|
+
/** The app's menu trigger: `trigger` as `AppMenu` takes it, else `ShellMenu.trigger`, else `pane`. */
|
|
36
|
+
export declare const menuTrigger: (trigger?: AppMenuTrigger | boolean) => AppMenuTrigger;
|
|
37
|
+
/**
|
|
38
|
+
* One pane's menu button, at the end of its toolbar (the app's mark inside): opens the app menu
|
|
39
|
+
* under itself, or closes it when it is open there. Shown when the app's trigger is `pane`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function PaneMenuButton({ pane, children }: {
|
|
42
|
+
pane: string;
|
|
43
|
+
children: ReactNode;
|
|
44
|
+
}): import("react").JSX.Element;
|