waybetter 0.1.1 → 0.6.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 +140 -6
- package/bin/waybetter.mjs +46 -0
- package/build/runtime.mjs +105 -0
- package/cli/buildenv.mjs +130 -0
- package/cli/dev.mjs +97 -0
- package/cli/i18n.mjs +382 -0
- package/cli/manifests.mjs +383 -0
- package/cli/privacy.mjs +768 -0
- package/cli/release.mjs +444 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +326 -0
- package/cli/strings.mjs +121 -0
- package/dist/runtime/column.d.ts +93 -0
- package/dist/runtime/column.js +451 -0
- package/dist/runtime/column.js.map +1 -0
- package/dist/runtime/commandReport.d.ts +19 -0
- package/dist/runtime/commandReport.js +47 -0
- package/dist/runtime/commandReport.js.map +1 -0
- package/dist/runtime/commands.d.ts +72 -0
- package/dist/runtime/commands.js +214 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/devErrors.d.ts +16 -0
- package/dist/runtime/devErrors.js +30 -0
- package/dist/runtime/devErrors.js.map +1 -0
- package/dist/runtime/domHub.d.ts +21 -0
- package/dist/runtime/domHub.js +139 -4
- package/dist/runtime/domHub.js.map +1 -1
- package/dist/runtime/featureModules.d.ts +157 -0
- package/dist/runtime/featureModules.js +484 -0
- package/dist/runtime/featureModules.js.map +1 -0
- package/dist/runtime/featureTable.d.ts +144 -0
- package/dist/runtime/featureTable.js +223 -0
- package/dist/runtime/featureTable.js.map +1 -0
- package/dist/runtime/fonts.d.ts +22 -0
- package/dist/runtime/fonts.js +72 -0
- package/dist/runtime/fonts.js.map +1 -0
- package/dist/runtime/i18n.d.ts +138 -0
- package/dist/runtime/i18n.js +614 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/i18nCheck.d.ts +30 -0
- package/dist/runtime/i18nCheck.js +224 -0
- package/dist/runtime/i18nCheck.js.map +1 -0
- package/dist/runtime/pageLang.d.ts +8 -0
- package/dist/runtime/pageLang.js +64 -0
- package/dist/runtime/pageLang.js.map +1 -0
- package/dist/runtime/pageStrings.d.ts +35 -0
- package/dist/runtime/pageStrings.js +76 -0
- package/dist/runtime/pageStrings.js.map +1 -0
- package/dist/runtime/panelButton.d.ts +33 -0
- package/dist/runtime/panelButton.js +83 -0
- package/dist/runtime/panelButton.js.map +1 -0
- package/dist/runtime/permissions.d.ts +47 -0
- package/dist/runtime/permissions.js +141 -0
- package/dist/runtime/permissions.js.map +1 -0
- package/dist/runtime/pluginApi.d.ts +51 -2
- package/dist/runtime/pluginApi.js +137 -22
- package/dist/runtime/pluginApi.js.map +1 -1
- package/dist/runtime/pluginI18n.d.ts +29 -0
- package/dist/runtime/pluginI18n.js +119 -0
- package/dist/runtime/pluginI18n.js.map +1 -0
- package/dist/runtime/settingsForm.d.ts +66 -0
- package/dist/runtime/settingsForm.js +114 -0
- package/dist/runtime/settingsForm.js.map +1 -0
- package/dist/runtime/site.d.ts +5 -0
- package/dist/runtime/site.js +1 -1
- package/dist/runtime/site.js.map +1 -1
- package/dist/runtime/siteRuntime.d.ts +144 -0
- package/dist/runtime/siteRuntime.js +175 -0
- package/dist/runtime/siteRuntime.js.map +1 -0
- package/dist/runtime/stringPackHook.d.ts +84 -0
- package/dist/runtime/stringPackHook.js +220 -0
- package/dist/runtime/stringPackHook.js.map +1 -0
- package/dist/runtime/stringPackTranslate.d.ts +59 -0
- package/dist/runtime/stringPackTranslate.js +264 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +200 -0
- package/dist/runtime/stringPacks.js +474 -0
- package/dist/runtime/stringPacks.js.map +1 -0
- package/dist/runtime/styles.d.ts +15 -0
- package/dist/runtime/styles.js +81 -0
- package/dist/runtime/styles.js.map +1 -0
- package/dist/runtime/textNet.d.ts +15 -0
- package/dist/runtime/textNet.js +131 -0
- package/dist/runtime/textNet.js.map +1 -0
- package/dist/runtime/themeApi.d.ts +121 -0
- package/dist/runtime/themeApi.js +220 -0
- package/dist/runtime/themeApi.js.map +1 -0
- package/dist/runtime/themeChoice.d.ts +52 -0
- package/dist/runtime/themeChoice.js +69 -0
- package/dist/runtime/themeChoice.js.map +1 -0
- package/dist/runtime/themeComponents.d.ts +435 -0
- package/dist/runtime/themeComponents.js +463 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +131 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +11 -0
- package/dist/runtime/themeDoctor.js +51 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +130 -0
- package/dist/runtime/themeIcons.js +263 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +100 -0
- package/dist/runtime/themeRuntime.js +497 -0
- package/dist/runtime/themeRuntime.js.map +1 -0
- package/dist/runtime/themeSchema.d.ts +10 -0
- package/dist/runtime/themeSchema.js +150 -0
- package/dist/runtime/themeSchema.js.map +1 -0
- package/dist/runtime/themeSpec.d.ts +259 -0
- package/dist/runtime/themeSpec.js +439 -0
- package/dist/runtime/themeSpec.js.map +1 -0
- package/dist/runtime/themeTokens.d.ts +12 -0
- package/dist/runtime/themeTokens.js +14 -6
- package/dist/runtime/themeTokens.js.map +1 -1
- package/dist/runtime/themeVariants.d.ts +30 -0
- package/dist/runtime/themeVariants.js +53 -0
- package/dist/runtime/themeVariants.js.map +1 -0
- package/dist/runtime/ui.d.ts +192 -0
- package/dist/runtime/ui.js +926 -0
- package/dist/runtime/ui.js.map +1 -0
- package/dist/shell/InstallDialog.d.ts +40 -0
- package/dist/shell/InstallDialog.js +170 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +66 -0
- package/dist/shell/StoreView.js +103 -0
- package/dist/shell/StoreView.js.map +1 -0
- package/dist/shell/addressModel.js.map +1 -1
- package/dist/shell/chrome.js.map +1 -1
- package/dist/shell/deckModel.d.ts +117 -0
- package/dist/shell/deckModel.js +267 -0
- package/dist/shell/deckModel.js.map +1 -0
- package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
- package/dist/shell/frame/AccountSwitcher.js +243 -0
- package/dist/shell/frame/AccountSwitcher.js.map +1 -0
- package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
- package/dist/shell/frame/AddColumnDialog.js +81 -0
- package/dist/shell/frame/AddColumnDialog.js.map +1 -0
- package/dist/shell/frame/AppMenu.d.ts +21 -0
- package/dist/shell/frame/AppMenu.js +642 -0
- package/dist/shell/frame/AppMenu.js.map +1 -0
- package/dist/shell/frame/CommandPalette.d.ts +7 -0
- package/dist/shell/frame/CommandPalette.js +118 -0
- package/dist/shell/frame/CommandPalette.js.map +1 -0
- package/dist/shell/frame/DeckView.d.ts +13 -0
- package/dist/shell/frame/DeckView.js +287 -0
- package/dist/shell/frame/DeckView.js.map +1 -0
- package/dist/shell/frame/FindBar.d.ts +10 -0
- package/dist/shell/frame/FindBar.js +108 -0
- package/dist/shell/frame/FindBar.js.map +1 -0
- package/dist/shell/frame/MediaPanel.d.ts +8 -0
- package/dist/shell/frame/MediaPanel.js +76 -0
- package/dist/shell/frame/MediaPanel.js.map +1 -0
- package/dist/shell/frame/NewTabPage.d.ts +9 -0
- package/dist/shell/frame/NewTabPage.js +71 -0
- package/dist/shell/frame/NewTabPage.js.map +1 -0
- package/dist/shell/frame/PaneTheme.d.ts +16 -0
- package/dist/shell/frame/PaneTheme.js +67 -0
- package/dist/shell/frame/PaneTheme.js.map +1 -0
- package/dist/shell/frame/ReportDialog.d.ts +3 -0
- package/dist/shell/frame/ReportDialog.js +95 -0
- package/dist/shell/frame/ReportDialog.js.map +1 -0
- package/dist/shell/frame/Shell.d.ts +8 -0
- package/dist/shell/frame/Shell.js +1131 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +16 -0
- package/dist/shell/frame/Titlebar.js +77 -0
- package/dist/shell/frame/Titlebar.js.map +1 -0
- package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
- package/dist/shell/frame/TitlebarExtras.js +202 -0
- package/dist/shell/frame/TitlebarExtras.js.map +1 -0
- package/dist/shell/frame/WebPanel.d.ts +4 -0
- package/dist/shell/frame/WebPanel.js +182 -0
- package/dist/shell/frame/WebPanel.js.map +1 -0
- package/dist/shell/frame/accountModel.d.ts +49 -0
- package/dist/shell/frame/accountModel.js +67 -0
- package/dist/shell/frame/accountModel.js.map +1 -0
- package/dist/shell/frame/accountSwitcher.css +91 -0
- package/dist/shell/frame/appI18n.d.ts +44 -0
- package/dist/shell/frame/appI18n.js +64 -0
- package/dist/shell/frame/appI18n.js.map +1 -0
- package/dist/shell/frame/appMenu.css +121 -0
- package/dist/shell/frame/backupModel.d.ts +38 -0
- package/dist/shell/frame/backupModel.js +192 -0
- package/dist/shell/frame/backupModel.js.map +1 -0
- package/dist/shell/frame/boot.d.ts +8 -0
- package/dist/shell/frame/boot.js +35 -0
- package/dist/shell/frame/boot.js.map +1 -0
- package/dist/shell/frame/brand.d.ts +1 -0
- package/dist/shell/frame/brand.js +4 -0
- package/dist/shell/frame/brand.js.map +1 -0
- package/dist/shell/frame/bridge.d.ts +35 -0
- package/dist/shell/frame/bridge.js +70 -0
- package/dist/shell/frame/bridge.js.map +1 -0
- package/dist/shell/frame/chromeTheme.d.ts +29 -0
- package/dist/shell/frame/chromeTheme.js +81 -0
- package/dist/shell/frame/chromeTheme.js.map +1 -0
- package/dist/shell/frame/deck.css +209 -0
- package/dist/shell/frame/deckStore.d.ts +89 -0
- package/dist/shell/frame/deckStore.js +239 -0
- package/dist/shell/frame/deckStore.js.map +1 -0
- package/dist/shell/frame/devHost.d.ts +35 -0
- package/dist/shell/frame/devHost.js +80 -0
- package/dist/shell/frame/devHost.js.map +1 -0
- package/dist/shell/frame/devModel.d.ts +7 -0
- package/dist/shell/frame/devModel.js +17 -0
- package/dist/shell/frame/devModel.js.map +1 -0
- package/dist/shell/frame/diag.d.ts +7 -0
- package/dist/shell/frame/diag.js +39 -0
- package/dist/shell/frame/diag.js.map +1 -0
- package/dist/shell/frame/findBar.css +14 -0
- package/dist/shell/frame/frameMessages.d.ts +248 -0
- package/dist/shell/frame/frameMessages.js +252 -0
- package/dist/shell/frame/frameMessages.js.map +1 -0
- package/dist/shell/frame/hooks.d.ts +39 -0
- package/dist/shell/frame/hooks.js +97 -0
- package/dist/shell/frame/hooks.js.map +1 -0
- package/dist/shell/frame/i18n.d.ts +27 -0
- package/dist/shell/frame/i18n.js +66 -0
- package/dist/shell/frame/i18n.js.map +1 -0
- package/dist/shell/frame/iconPack.d.ts +11 -0
- package/dist/shell/frame/iconPack.js +45 -0
- package/dist/shell/frame/iconPack.js.map +1 -0
- package/dist/shell/frame/icons.d.ts +71 -0
- package/dist/shell/frame/icons.js +75 -0
- package/dist/shell/frame/icons.js.map +1 -0
- package/dist/shell/frame/index.d.ts +34 -0
- package/dist/shell/frame/index.js +43 -0
- package/dist/shell/frame/index.js.map +1 -0
- package/dist/shell/frame/language.d.ts +58 -0
- package/dist/shell/frame/language.js +165 -0
- package/dist/shell/frame/language.js.map +1 -0
- package/dist/shell/frame/mediaModel.d.ts +34 -0
- package/dist/shell/frame/mediaModel.js +53 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +54 -0
- package/dist/shell/frame/menuModel.d.ts +277 -0
- package/dist/shell/frame/menuModel.js +293 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +112 -0
- package/dist/shell/frame/paletteModel.js.map +1 -0
- package/dist/shell/frame/paneTheme.css +9 -0
- package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
- package/dist/shell/frame/pluginCommandStore.js +70 -0
- package/dist/shell/frame/pluginCommandStore.js.map +1 -0
- package/dist/shell/frame/reportModel.d.ts +52 -0
- package/dist/shell/frame/reportModel.js +105 -0
- package/dist/shell/frame/reportModel.js.map +1 -0
- package/dist/shell/frame/safeStore.d.ts +7 -0
- package/dist/shell/frame/safeStore.js +40 -0
- package/dist/shell/frame/safeStore.js.map +1 -0
- package/dist/shell/frame/searchInput.d.ts +2 -0
- package/dist/shell/frame/searchInput.js +11 -0
- package/dist/shell/frame/searchInput.js.map +1 -0
- package/dist/shell/frame/shell.css +629 -0
- package/dist/shell/frame/site.d.ts +206 -0
- package/dist/shell/frame/site.js +22 -0
- package/dist/shell/frame/site.js.map +1 -0
- package/dist/shell/frame/state.d.ts +99 -0
- package/dist/shell/frame/state.js +284 -0
- package/dist/shell/frame/state.js.map +1 -0
- package/dist/shell/frame/syncGate.d.ts +10 -0
- package/dist/shell/frame/syncGate.js +36 -0
- package/dist/shell/frame/syncGate.js.map +1 -0
- package/dist/shell/frame/syncHost.d.ts +35 -0
- package/dist/shell/frame/syncHost.js +85 -0
- package/dist/shell/frame/syncHost.js.map +1 -0
- package/dist/shell/frame/tabStill.d.ts +2 -0
- package/dist/shell/frame/tabStill.js +62 -0
- package/dist/shell/frame/tabStill.js.map +1 -0
- package/dist/shell/frame/themeScopes.d.ts +29 -0
- package/dist/shell/frame/themeScopes.js +61 -0
- package/dist/shell/frame/themeScopes.js.map +1 -0
- package/dist/shell/frame/themeStore.d.ts +99 -0
- package/dist/shell/frame/themeStore.js +252 -0
- package/dist/shell/frame/themeStore.js.map +1 -0
- package/dist/shell/frame/windowBinding.d.ts +2 -0
- package/dist/shell/frame/windowBinding.js +7 -0
- package/dist/shell/frame/windowBinding.js.map +1 -0
- package/dist/shell/frame/workspaceModel.d.ts +82 -0
- package/dist/shell/frame/workspaceModel.js +250 -0
- package/dist/shell/frame/workspaceModel.js.map +1 -0
- package/dist/shell/frame/workspaces.css +84 -0
- package/dist/shell/frame/workspaces.d.ts +22 -0
- package/dist/shell/frame/workspaces.js +125 -0
- package/dist/shell/frame/workspaces.js.map +1 -0
- package/dist/shell/frame/zoomStore.d.ts +10 -0
- package/dist/shell/frame/zoomStore.js +65 -0
- package/dist/shell/frame/zoomStore.js.map +1 -0
- package/dist/shell/installController.d.ts +122 -0
- package/dist/shell/installController.js +146 -0
- package/dist/shell/installController.js.map +1 -0
- package/dist/shell/installerMessages.d.ts +30 -0
- package/dist/shell/installerMessages.js +36 -0
- package/dist/shell/installerMessages.js.map +1 -0
- package/dist/shell/linkDrop.js.map +1 -1
- package/dist/shell/messages.d.ts +16 -0
- package/dist/shell/messages.js +27 -0
- package/dist/shell/messages.js.map +1 -0
- package/dist/shell/palette.js.map +1 -1
- package/dist/shell/paneModel.d.ts +22 -0
- package/dist/shell/paneModel.js +24 -1
- package/dist/shell/paneModel.js.map +1 -1
- package/dist/shell/panel/Appearance.d.ts +8 -0
- package/dist/shell/panel/Appearance.js +256 -0
- package/dist/shell/panel/Appearance.js.map +1 -0
- package/dist/shell/panel/BackupPanel.d.ts +5 -0
- package/dist/shell/panel/BackupPanel.js +198 -0
- package/dist/shell/panel/BackupPanel.js.map +1 -0
- package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
- package/dist/shell/panel/DeveloperPanel.js +51 -0
- package/dist/shell/panel/DeveloperPanel.js.map +1 -0
- package/dist/shell/panel/FeatureToggles.d.ts +13 -0
- package/dist/shell/panel/FeatureToggles.js +42 -0
- package/dist/shell/panel/FeatureToggles.js.map +1 -0
- package/dist/shell/panel/Home.d.ts +3 -0
- package/dist/shell/panel/Home.js +23 -0
- package/dist/shell/panel/Home.js.map +1 -0
- package/dist/shell/panel/IconPackInstall.d.ts +15 -0
- package/dist/shell/panel/IconPackInstall.js +41 -0
- package/dist/shell/panel/IconPackInstall.js.map +1 -0
- package/dist/shell/panel/LanguageSettings.d.ts +1 -0
- package/dist/shell/panel/LanguageSettings.js +54 -0
- package/dist/shell/panel/LanguageSettings.js.map +1 -0
- package/dist/shell/panel/MakePanel.d.ts +3 -0
- package/dist/shell/panel/MakePanel.js +237 -0
- package/dist/shell/panel/MakePanel.js.map +1 -0
- package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
- package/dist/shell/panel/MarkdownDoc.js +35 -0
- package/dist/shell/panel/MarkdownDoc.js.map +1 -0
- package/dist/shell/panel/Modes.d.ts +40 -0
- package/dist/shell/panel/Modes.js +270 -0
- package/dist/shell/panel/Modes.js.map +1 -0
- package/dist/shell/panel/NavIcon.d.ts +4 -0
- package/dist/shell/panel/NavIcon.js +6 -0
- package/dist/shell/panel/NavIcon.js.map +1 -0
- package/dist/shell/panel/Panel.d.ts +7 -0
- package/dist/shell/panel/Panel.js +139 -0
- package/dist/shell/panel/Panel.js.map +1 -0
- package/dist/shell/panel/PluginFeatures.d.ts +24 -0
- package/dist/shell/panel/PluginFeatures.js +165 -0
- package/dist/shell/panel/PluginFeatures.js.map +1 -0
- package/dist/shell/panel/Plugins.d.ts +33 -0
- package/dist/shell/panel/Plugins.js +112 -0
- package/dist/shell/panel/Plugins.js.map +1 -0
- package/dist/shell/panel/PowerSettings.d.ts +4 -0
- package/dist/shell/panel/PowerSettings.js +52 -0
- package/dist/shell/panel/PowerSettings.js.map +1 -0
- package/dist/shell/panel/Settings.d.ts +23 -0
- package/dist/shell/panel/Settings.js +116 -0
- package/dist/shell/panel/Settings.js.map +1 -0
- package/dist/shell/panel/ShareSetup.d.ts +8 -0
- package/dist/shell/panel/ShareSetup.js +130 -0
- package/dist/shell/panel/ShareSetup.js.map +1 -0
- package/dist/shell/panel/StoreSection.d.ts +6 -0
- package/dist/shell/panel/StoreSection.js +48 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +11 -0
- package/dist/shell/panel/StringPacks.js +106 -0
- package/dist/shell/panel/StringPacks.js.map +1 -0
- package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
- package/dist/shell/panel/ThemeBuilder.js +205 -0
- package/dist/shell/panel/ThemeBuilder.js.map +1 -0
- package/dist/shell/panel/backup.css +34 -0
- package/dist/shell/panel/builder.css +232 -0
- package/dist/shell/panel/builderModel.d.ts +55 -0
- package/dist/shell/panel/builderModel.js +95 -0
- package/dist/shell/panel/builderModel.js.map +1 -0
- package/dist/shell/panel/compare.d.ts +10 -0
- package/dist/shell/panel/compare.js +51 -0
- package/dist/shell/panel/compare.js.map +1 -0
- package/dist/shell/panel/controls.d.ts +135 -0
- package/dist/shell/panel/controls.js +213 -0
- package/dist/shell/panel/controls.js.map +1 -0
- package/dist/shell/panel/featureModel.d.ts +69 -0
- package/dist/shell/panel/featureModel.js +79 -0
- package/dist/shell/panel/featureModel.js.map +1 -0
- package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
- package/dist/shell/panel/fonts/FontBrowser.js +189 -0
- package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
- package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
- package/dist/shell/panel/fonts/FontRoles.js +77 -0
- package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
- package/dist/shell/panel/fonts/catalog.d.ts +37 -0
- package/dist/shell/panel/fonts/catalog.js +68 -0
- package/dist/shell/panel/fonts/catalog.js.map +1 -0
- package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
- package/dist/shell/panel/index.d.ts +20 -0
- package/dist/shell/panel/index.js +34 -0
- package/dist/shell/panel/index.js.map +1 -0
- package/dist/shell/panel/languageModel.d.ts +5 -0
- package/dist/shell/panel/languageModel.js +7 -0
- package/dist/shell/panel/languageModel.js.map +1 -0
- package/dist/shell/panel/make.css +72 -0
- package/dist/shell/panel/makeModel.d.ts +32 -0
- package/dist/shell/panel/makeModel.js +84 -0
- package/dist/shell/panel/makeModel.js.map +1 -0
- package/dist/shell/panel/markdown.d.ts +46 -0
- package/dist/shell/panel/markdown.js +100 -0
- package/dist/shell/panel/markdown.js.map +1 -0
- package/dist/shell/panel/nav.d.ts +12 -0
- package/dist/shell/panel/nav.js +50 -0
- package/dist/shell/panel/nav.js.map +1 -0
- package/dist/shell/panel/panel.css +401 -0
- package/dist/shell/panel/panelMessages.d.ts +763 -0
- package/dist/shell/panel/panelMessages.js +767 -0
- package/dist/shell/panel/panelMessages.js.map +1 -0
- package/dist/shell/panel/plugins.css +59 -0
- package/dist/shell/panel/setupModel.d.ts +87 -0
- package/dist/shell/panel/setupModel.js +152 -0
- package/dist/shell/panel/setupModel.js.map +1 -0
- package/dist/shell/panel/site.d.ts +259 -0
- package/dist/shell/panel/site.js +25 -0
- package/dist/shell/panel/site.js.map +1 -0
- package/dist/shell/panel/strings.css +7 -0
- package/dist/shell/panel/themes.d.ts +10 -0
- package/dist/shell/panel/themes.js +8 -0
- package/dist/shell/panel/themes.js.map +1 -0
- package/dist/shell/profileModel.d.ts +3 -2
- package/dist/shell/profileModel.js +7 -5
- package/dist/shell/profileModel.js.map +1 -1
- package/dist/shell/store.css +230 -0
- package/dist/shell/storeMessages.d.ts +169 -0
- package/dist/shell/storeMessages.js +172 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +181 -0
- package/dist/shell/storeModel.js +133 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +94 -0
- package/dist/shell/stringPacksModel.js.map +1 -0
- package/dist/shell/updateModel.d.ts +2 -1
- package/dist/shell/updateModel.js +5 -4
- package/dist/shell/updateModel.js.map +1 -1
- package/dist/shell/windowControls.d.ts +4 -0
- package/dist/shell/windowControls.js +5 -0
- package/dist/shell/windowControls.js.map +1 -1
- package/i18n-config.schema.json +29 -0
- package/i18n-meta.schema.json +26 -0
- package/i18n.schema.json +42 -0
- package/icons.schema.json +646 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1281 -0
- package/locales/bg.json +1280 -0
- package/locales/bn.json +1280 -0
- package/locales/ca.json +1280 -0
- package/locales/cs.json +1280 -0
- package/locales/da.json +1280 -0
- package/locales/de.json +1280 -0
- package/locales/el.json +1280 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1280 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1280 -0
- package/locales/eu.json +1280 -0
- package/locales/fa.json +1281 -0
- package/locales/fi.json +1280 -0
- package/locales/fil.json +1280 -0
- package/locales/fr.json +1280 -0
- package/locales/ga.json +1280 -0
- package/locales/gl.json +1280 -0
- package/locales/gu.json +1280 -0
- package/locales/ha.json +1280 -0
- package/locales/he.json +1281 -0
- package/locales/hi.json +1280 -0
- package/locales/hr.json +1280 -0
- package/locales/hu.json +1279 -0
- package/locales/id.json +1280 -0
- package/locales/ig.json +1280 -0
- package/locales/it.json +1280 -0
- package/locales/ja.json +1280 -0
- package/locales/kn.json +1280 -0
- package/locales/ko.json +1280 -0
- package/locales/mr.json +1280 -0
- package/locales/ms.json +1280 -0
- package/locales/nb.json +1280 -0
- package/locales/nl.json +1280 -0
- package/locales/pl.json +1280 -0
- package/locales/pt.json +1280 -0
- package/locales/ro.json +1280 -0
- package/locales/ru.json +1280 -0
- package/locales/sk.json +1280 -0
- package/locales/sr.json +1280 -0
- package/locales/sv.json +1280 -0
- package/locales/ta.json +1280 -0
- package/locales/th.json +1280 -0
- package/locales/tr.json +1280 -0
- package/locales/uk.json +1280 -0
- package/locales/ur.json +1281 -0
- package/locales/vi.json +1280 -0
- package/locales/yo.json +1280 -0
- package/locales/zh-Hans.json +1280 -0
- package/locales/zh-Hant.json +1280 -0
- package/package.json +139 -5
- package/store-catalog.schema.json +65 -0
- package/theme.schema.json +4659 -0
- package/windows/installer.nsi +926 -0
- package/windows/languages/Basque.nsh +28 -0
- package/windows/languages/Catalan.nsh +28 -0
- package/windows/languages/Croatian.nsh +28 -0
- package/windows/languages/Czech.nsh +28 -0
- package/windows/languages/Danish.nsh +28 -0
- package/windows/languages/Finnish.nsh +28 -0
- package/windows/languages/Galician.nsh +28 -0
- package/windows/languages/Greek.nsh +28 -0
- package/windows/languages/Hungarian.nsh +28 -0
- package/windows/languages/Indonesian.nsh +28 -0
- package/windows/languages/Irish.nsh +28 -0
- package/windows/languages/Malay.nsh +28 -0
- package/windows/languages/Polish.nsh +28 -0
- package/windows/languages/Romanian.nsh +28 -0
- package/windows/languages/Serbian.nsh +28 -0
- package/windows/languages/Slovak.nsh +28 -0
- package/windows/languages/Thai.nsh +28 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { invoke, listen } from "./bridge.js";
|
|
5
|
+
import { useT } from "./hooks.js";
|
|
6
|
+
import { attachTarget, clipPreview, folderLabel, relativeTime } from "./mediaModel.js";
|
|
7
|
+
import { site } from "./site.js";
|
|
8
|
+
import { isWeb, setOverlay, shell } from "./state.js";
|
|
9
|
+
const getError = (error) => error instanceof Error ? error.message : String(error);
|
|
10
|
+
function targetTab() {
|
|
11
|
+
const api = shell.api;
|
|
12
|
+
const media = site().media;
|
|
13
|
+
if (!api || !media)
|
|
14
|
+
return null;
|
|
15
|
+
const tabs = api.panels.filter(isWeb).map(panel => ({ id: panel.id, url: panel.params.url }));
|
|
16
|
+
return attachTarget(tabs, api.activePanel?.id, media.canAttach);
|
|
17
|
+
}
|
|
18
|
+
/** Lazily loads one preview (a data URL read natively, only from inside a gallery folder). */
|
|
19
|
+
function Thumb({ command, args, alt }) {
|
|
20
|
+
const [src, setSrc] = useState(null);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
let live = true;
|
|
23
|
+
invoke(command, args).then(url => { if (live)
|
|
24
|
+
setSrc(url); }).catch(() => { });
|
|
25
|
+
return () => { live = false; };
|
|
26
|
+
}, [command, JSON.stringify(args)]);
|
|
27
|
+
return src ? _jsx("img", { src: src, alt: alt, loading: "lazy", draggable: false }) : _jsx("span", { className: "bt-media-thumb-empty" });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Media side panel: recent images from the owner's gallery folders and the local clipboard
|
|
31
|
+
* history. Choosing an item attaches the image to (or inserts the text into) the composer of the
|
|
32
|
+
* active site tab (`site.media.canAttach`). Nothing is posted; the user reviews and sends it themselves.
|
|
33
|
+
*/
|
|
34
|
+
export function MediaPanel({ onClose }) {
|
|
35
|
+
const t = useT();
|
|
36
|
+
const siteName = site().name;
|
|
37
|
+
const [tab, setTab] = useState('gallery');
|
|
38
|
+
const [settings, setSettings] = useState(null);
|
|
39
|
+
const [images, setImages] = useState(null);
|
|
40
|
+
const [clips, setClips] = useState(null);
|
|
41
|
+
const [error, setError] = useState('');
|
|
42
|
+
const refresh = () => {
|
|
43
|
+
invoke('media_get').then(setSettings).catch(err => setError(getError(err)));
|
|
44
|
+
invoke('gallery_list', { limit: 60 }).then(setImages).catch(err => setError(getError(err)));
|
|
45
|
+
invoke('clip_list').then(setClips).catch(err => setError(getError(err)));
|
|
46
|
+
};
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
setOverlay(1);
|
|
49
|
+
invoke('shell_focus').catch(() => { });
|
|
50
|
+
refresh();
|
|
51
|
+
const unlisten = listen('clipboard-changed', () => { invoke('clip_list').then(setClips).catch(() => { }); });
|
|
52
|
+
const onKey = (event) => { if (event.key === 'Escape')
|
|
53
|
+
onClose(); };
|
|
54
|
+
window.addEventListener('keydown', onKey);
|
|
55
|
+
return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); unlisten.then(dispose => dispose()).catch(() => { }); };
|
|
56
|
+
}, []);
|
|
57
|
+
const deliver = (command, args) => {
|
|
58
|
+
const target = targetTab();
|
|
59
|
+
if (!target) {
|
|
60
|
+
setError(t('wb.media.noComposer', { site: siteName }));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
onClose();
|
|
64
|
+
shell.api?.getPanel(target.id)?.api.setActive();
|
|
65
|
+
// Wait until the tab webview is shown again (the overlay hid it), then attach. Never posts.
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
invoke(command, { id: target.id, ...args }).catch(err => console.warn('[shell] media attach failed', err));
|
|
68
|
+
}, 150);
|
|
69
|
+
};
|
|
70
|
+
const addFolder = () => invoke('gallery_add_folder').then(next => { setSettings(next); refresh(); }).catch(err => setError(getError(err)));
|
|
71
|
+
const removeClip = (id) => invoke('clip_remove', { id }).then(setClips).catch(err => setError(getError(err)));
|
|
72
|
+
return createPortal(_jsx("div", { className: "bt-palette-backdrop bt-media-backdrop", onMouseDown: onClose, children: _jsxs("aside", { className: "bt-media", role: "dialog", "aria-label": t('wb.media.title'), onMouseDown: event => event.stopPropagation(), children: [_jsxs("header", { className: "bt-media-head", children: [_jsxs("div", { className: "bt-media-tabs", role: "tablist", children: [_jsx("button", { role: "tab", "aria-selected": tab === 'gallery', className: tab === 'gallery' ? 'active' : '', onClick: () => setTab('gallery'), children: t('wb.media.gallery') }), _jsx("button", { role: "tab", "aria-selected": tab === 'clipboard', className: tab === 'clipboard' ? 'active' : '', onClick: () => setTab('clipboard'), children: t('wb.media.clipboard') })] }), _jsx("button", { className: "bt-icon bt-media-close", "aria-label": t('wb.common.close'), title: t('wb.media.closeTitle'), onClick: onClose, children: _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M6 6l12 12M18 6L6 18" }) }) })] }), error && _jsx("div", { className: "bt-media-error", role: "alert", children: error }), tab === 'gallery' && _jsxs("div", { className: "bt-media-body", children: [settings && settings.folders.length === 0 && _jsxs("div", { className: "bt-media-empty", children: [_jsx("p", { children: t('wb.media.pickFolders') }), _jsx("button", { className: "button small", onClick: () => void addFolder(), children: t('wb.media.addFolder') })] }), settings && settings.folders.length > 0 && _jsxs("div", { className: "bt-media-folders", children: [settings.folders.map(folder => _jsx("span", { className: "pill", title: folder, children: folderLabel(folder) }, folder)), _jsx("button", { className: "bt-media-link", onClick: () => void addFolder(), children: t('wb.media.add') })] }), images && images.length > 0 && _jsx("div", { className: "bt-media-grid", children: images.map(image => _jsxs("button", { className: "bt-media-tile", title: t('wb.media.attachTitle', { name: image.name }), onClick: () => deliver('tab_attach_image', { source: { kind: 'gallery', path: image.path } }), children: [_jsx(Thumb, { command: "gallery_thumb", args: { path: image.path }, alt: image.name }), _jsx("span", { className: "bt-media-caption", children: relativeTime(image.modifiedMs) })] }, image.path)) }), settings && settings.folders.length > 0 && images?.length === 0 && _jsx("div", { className: "bt-media-empty", children: _jsx("p", { children: t('wb.media.noImages') }) })] }), tab === 'clipboard' && _jsxs("div", { className: "bt-media-body", children: [settings && !settings.clipboardEnabled && _jsx("div", { className: "bt-media-empty", children: _jsx("p", { children: t('wb.media.clipOff', { count: settings.clipboardMax }) }) }), clips && clips.length === 0 && settings?.clipboardEnabled && _jsx("div", { className: "bt-media-empty", children: _jsx("p", { children: t('wb.media.clipEmpty') }) }), clips && clips.length > 0 && _jsx("ul", { className: "bt-media-clips", children: clips.map(item => _jsxs("li", { className: "bt-media-clip", children: [_jsxs("button", { className: "bt-media-clip-main", title: t('wb.media.putIn'), onClick: () => item.kind === 'image'
|
|
73
|
+
? deliver('tab_attach_image', { source: { kind: 'clip', id: item.id } })
|
|
74
|
+
: deliver('tab_insert_text', { text: item.text ?? '' }), children: [item.kind === 'image' ? _jsx("span", { className: "bt-media-clip-thumb", children: _jsx(Thumb, { command: "clip_thumb", args: { id: item.id }, alt: t('wb.media.copiedImage') }) }) : _jsx("span", { className: "bt-media-clip-text", children: clipPreview(item) }), _jsx("small", { children: relativeTime(item.at) })] }), _jsx("button", { className: "bt-icon", "aria-label": t('wb.media.removeFromHistory'), title: t('wb.common.remove'), onClick: () => void removeClip(item.id), children: _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M6 6l12 12M18 6L6 18" }) }) })] }, item.id)) })] }), _jsxs("footer", { className: "bt-palette-foot", children: [_jsx("span", { children: t('wb.media.clickToAttach', { site: siteName }) }), _jsx("span", { children: t('wb.media.youPost') })] })] }) }), document.body);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=MediaPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaPanel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/MediaPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { invoke, listen } from './bridge.ts';\nimport { useT } from './hooks.ts';\nimport { attachTarget, clipPreview, folderLabel, relativeTime, type ClipItem, type GalleryImage, type MediaSettings } from './mediaModel.ts';\nimport { site } from './site.ts';\nimport { isWeb, setOverlay, shell, type WebParams } from './state.ts';\n\nconst getError = (error: unknown) => error instanceof Error ? error.message : String(error);\n\nfunction targetTab() {\n const api = shell.api;\n const media = site().media;\n if (!api || !media) return null;\n const tabs = api.panels.filter(isWeb).map(panel => ({ id: panel.id, url: (panel.params as WebParams).url }));\n return attachTarget(tabs, api.activePanel?.id, media.canAttach);\n}\n\n/** Lazily loads one preview (a data URL read natively, only from inside a gallery folder). */\nfunction Thumb({ command, args, alt }: { command: string; args: Record<string, unknown>; alt: string }) {\n const [src, setSrc] = useState<string | null>(null);\n useEffect(() => {\n let live = true;\n invoke<string>(command, args).then(url => { if (live) setSrc(url); }).catch(() => {});\n return () => { live = false; };\n }, [command, JSON.stringify(args)]);\n return src ? <img src={src} alt={alt} loading=\"lazy\" draggable={false}/> : <span className=\"bt-media-thumb-empty\"/>;\n}\n\n/**\n * Media side panel: recent images from the owner's gallery folders and the local clipboard\n * history. Choosing an item attaches the image to (or inserts the text into) the composer of the\n * active site tab (`site.media.canAttach`). Nothing is posted; the user reviews and sends it themselves.\n */\nexport function MediaPanel({ onClose }: { onClose: () => void }) {\n const t = useT();\n const siteName = site().name;\n const [tab, setTab] = useState<'gallery' | 'clipboard'>('gallery');\n const [settings, setSettings] = useState<MediaSettings | null>(null);\n const [images, setImages] = useState<GalleryImage[] | null>(null);\n const [clips, setClips] = useState<ClipItem[] | null>(null);\n const [error, setError] = useState('');\n\n const refresh = () => {\n invoke<MediaSettings>('media_get').then(setSettings).catch(err => setError(getError(err)));\n invoke<GalleryImage[]>('gallery_list', { limit: 60 }).then(setImages).catch(err => setError(getError(err)));\n invoke<ClipItem[]>('clip_list').then(setClips).catch(err => setError(getError(err)));\n };\n\n useEffect(() => {\n setOverlay(1);\n invoke('shell_focus').catch(() => {});\n refresh();\n const unlisten = listen('clipboard-changed', () => { invoke<ClipItem[]>('clip_list').then(setClips).catch(() => {}); });\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); unlisten.then(dispose => dispose()).catch(() => {}); };\n }, []);\n\n const deliver = (command: 'tab_attach_image' | 'tab_insert_text', args: Record<string, unknown>) => {\n const target = targetTab();\n if (!target) { setError(t('wb.media.noComposer', { site: siteName })); return; }\n onClose();\n shell.api?.getPanel(target.id)?.api.setActive();\n // Wait until the tab webview is shown again (the overlay hid it), then attach. Never posts.\n setTimeout(() => {\n invoke(command, { id: target.id, ...args }).catch(err => console.warn('[shell] media attach failed', err));\n }, 150);\n };\n\n const addFolder = () => invoke<MediaSettings>('gallery_add_folder').then(next => { setSettings(next); refresh(); }).catch(err => setError(getError(err)));\n const removeClip = (id: string) => invoke<ClipItem[]>('clip_remove', { id }).then(setClips).catch(err => setError(getError(err)));\n\n return createPortal(<div className=\"bt-palette-backdrop bt-media-backdrop\" onMouseDown={onClose}>\n <aside className=\"bt-media\" role=\"dialog\" aria-label={t('wb.media.title')} onMouseDown={event => event.stopPropagation()}>\n <header className=\"bt-media-head\">\n <div className=\"bt-media-tabs\" role=\"tablist\">\n <button role=\"tab\" aria-selected={tab === 'gallery'} className={tab === 'gallery' ? 'active' : ''} onClick={() => setTab('gallery')}>{t('wb.media.gallery')}</button>\n <button role=\"tab\" aria-selected={tab === 'clipboard'} className={tab === 'clipboard' ? 'active' : ''} onClick={() => setTab('clipboard')}>{t('wb.media.clipboard')}</button>\n </div>\n <button className=\"bt-icon bt-media-close\" aria-label={t('wb.common.close')} title={t('wb.media.closeTitle')} onClick={onClose}><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg></button>\n </header>\n {error && <div className=\"bt-media-error\" role=\"alert\">{error}</div>}\n {tab === 'gallery' && <div className=\"bt-media-body\">\n {settings && settings.folders.length === 0 && <div className=\"bt-media-empty\"><p>{t('wb.media.pickFolders')}</p><button className=\"button small\" onClick={() => void addFolder()}>{t('wb.media.addFolder')}</button></div>}\n {settings && settings.folders.length > 0 && <div className=\"bt-media-folders\">{settings.folders.map(folder => <span key={folder} className=\"pill\" title={folder}>{folderLabel(folder)}</span>)}<button className=\"bt-media-link\" onClick={() => void addFolder()}>{t('wb.media.add')}</button></div>}\n {images && images.length > 0 && <div className=\"bt-media-grid\">\n {images.map(image => <button key={image.path} className=\"bt-media-tile\" title={t('wb.media.attachTitle', { name: image.name })} onClick={() => deliver('tab_attach_image', { source: { kind: 'gallery', path: image.path } })}>\n <Thumb command=\"gallery_thumb\" args={{ path: image.path }} alt={image.name}/>\n <span className=\"bt-media-caption\">{relativeTime(image.modifiedMs)}</span>\n </button>)}\n </div>}\n {settings && settings.folders.length > 0 && images?.length === 0 && <div className=\"bt-media-empty\"><p>{t('wb.media.noImages')}</p></div>}\n </div>}\n {tab === 'clipboard' && <div className=\"bt-media-body\">\n {settings && !settings.clipboardEnabled && <div className=\"bt-media-empty\"><p>{t('wb.media.clipOff', { count: settings.clipboardMax })}</p></div>}\n {clips && clips.length === 0 && settings?.clipboardEnabled && <div className=\"bt-media-empty\"><p>{t('wb.media.clipEmpty')}</p></div>}\n {clips && clips.length > 0 && <ul className=\"bt-media-clips\">\n {clips.map(item => <li key={item.id} className=\"bt-media-clip\">\n <button className=\"bt-media-clip-main\" title={t('wb.media.putIn')} onClick={() => item.kind === 'image'\n ? deliver('tab_attach_image', { source: { kind: 'clip', id: item.id } })\n : deliver('tab_insert_text', { text: item.text ?? '' })}>\n {item.kind === 'image' ? <span className=\"bt-media-clip-thumb\"><Thumb command=\"clip_thumb\" args={{ id: item.id }} alt={t('wb.media.copiedImage')}/></span> : <span className=\"bt-media-clip-text\">{clipPreview(item)}</span>}\n <small>{relativeTime(item.at)}</small>\n </button>\n <button className=\"bt-icon\" aria-label={t('wb.media.removeFromHistory')} title={t('wb.common.remove')} onClick={() => void removeClip(item.id)}><svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M6 6l12 12M18 6L6 18\"/></svg></button>\n </li>)}\n </ul>}\n </div>}\n <footer className=\"bt-palette-foot\"><span>{t('wb.media.clickToAttach', { site: siteName })}</span><span>{t('wb.media.youPost')}</span></footer>\n </aside>\n </div>, document.body);\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The new-tab page (and the empty-dock state): one search/address field, the site's quick links,
|
|
3
|
+
* recently closed tabs and the account the links open in. Drawn by the shell; it never has a webview.
|
|
4
|
+
*/
|
|
5
|
+
export declare function NewTabPage({ panelId, profile: initialProfile, onProfile }: {
|
|
6
|
+
panelId?: string;
|
|
7
|
+
profile?: string;
|
|
8
|
+
onProfile?: (id: string) => void;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { tabProfile } from "../profileModel.js";
|
|
4
|
+
import { invoke } from "./bridge.js";
|
|
5
|
+
import { useProfiles, useSiteText, useT } from "./hooks.js";
|
|
6
|
+
import { Avatar, Icon } from "./icons.js";
|
|
7
|
+
import { toUrl } from "./searchInput.js";
|
|
8
|
+
import { site } from "./site.js";
|
|
9
|
+
import { shell } from "./state.js";
|
|
10
|
+
const hostOf = (url) => { try {
|
|
11
|
+
return new URL(url).host.replace(/^www\./, '');
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return url;
|
|
15
|
+
} };
|
|
16
|
+
/** Human label for a closed tab without a stored title: the address bar's own reading of the URL. */
|
|
17
|
+
function labelFor(url, title) {
|
|
18
|
+
if (title)
|
|
19
|
+
return title;
|
|
20
|
+
const model = site().address(url);
|
|
21
|
+
if (!model)
|
|
22
|
+
return url;
|
|
23
|
+
return [model.site.label, ...model.segments.map(segment => segment.label)].join(' / ');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The new-tab page (and the empty-dock state): one search/address field, the site's quick links,
|
|
27
|
+
* recently closed tabs and the account the links open in. Drawn by the shell; it never has a webview.
|
|
28
|
+
*/
|
|
29
|
+
export function NewTabPage({ panelId, profile: initialProfile, onProfile }) {
|
|
30
|
+
const profiles = useProfiles();
|
|
31
|
+
useSiteText();
|
|
32
|
+
const [profile, setProfile] = useState(() => tabProfile(profiles, initialProfile ?? profiles.active).id);
|
|
33
|
+
const [query, setQuery] = useState('');
|
|
34
|
+
const [, refresh] = useState(0);
|
|
35
|
+
const input = useRef(null);
|
|
36
|
+
const multi = profiles.profiles.length > 1;
|
|
37
|
+
const recent = shell.closed.map((tab, index) => ({ ...tab, index })).reverse().slice(0, 6);
|
|
38
|
+
const { logo, newTab, isSiteUrl } = site();
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const focus = (event) => {
|
|
41
|
+
if (event.detail !== panelId)
|
|
42
|
+
return;
|
|
43
|
+
input.current?.focus();
|
|
44
|
+
input.current?.select();
|
|
45
|
+
};
|
|
46
|
+
window.addEventListener('bt-focus-address', focus);
|
|
47
|
+
return () => window.removeEventListener('bt-focus-address', focus);
|
|
48
|
+
}, [panelId]);
|
|
49
|
+
const open = (url) => shell.openFromStart(url, profile, panelId);
|
|
50
|
+
const pick = (id) => { setProfile(id); onProfile?.(id); };
|
|
51
|
+
const reopen = (index) => {
|
|
52
|
+
const [tab] = shell.closed.splice(index, 1);
|
|
53
|
+
refresh(value => value + 1);
|
|
54
|
+
if (tab)
|
|
55
|
+
shell.openFromStart(tab.url, tabProfile(profiles, tab.profile).id, panelId);
|
|
56
|
+
};
|
|
57
|
+
const t = useT();
|
|
58
|
+
const search = newTab.search();
|
|
59
|
+
return _jsx("div", { className: "bt-start", children: _jsxs("div", { className: "bt-start-inner", children: [_jsx("div", { className: "bt-start-mark bt-rise", "aria-hidden": "true", children: _jsx("img", { src: logo, alt: "", width: 40, height: 40, draggable: false }) }), _jsxs("form", { className: "bt-start-search bt-rise", style: { animationDelay: '30ms' }, role: "search", onSubmit: event => { event.preventDefault(); if (query.trim())
|
|
60
|
+
open(toUrl(query, site().searchUrl)); }, children: [_jsx(Icon, { name: "search" }), _jsx("input", { ref: input, value: query, onChange: event => setQuery(event.target.value), spellCheck: false, autoComplete: "off", "aria-label": search, placeholder: search, onFocus: () => invoke('shell_focus').catch(() => { }), onKeyDown: event => { if (event.key === 'Escape') {
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
setQuery('');
|
|
63
|
+
} } }), _jsx("kbd", { className: "bt-kbd", children: t('wb.newtab.enter') })] }), multi && _jsxs("div", { className: "bt-start-accounts bt-rise", style: { animationDelay: '60ms' }, role: "radiogroup", "aria-label": t('wb.newtab.openLinksAs'), children: [_jsx("span", { className: "bt-start-label", children: t('wb.newtab.openAs') }), profiles.profiles.map(item => _jsxs("button", { type: "button", role: "radio", "aria-checked": item.id === profile, className: "bt-start-account", onClick: () => pick(item.id), children: [_jsx(Avatar, { name: item.name, color: item.color, size: 20 }), _jsx("span", { children: item.name })] }, item.id))] }), newTab.links.length > 0 && _jsx("section", { className: "bt-start-section bt-rise", style: { animationDelay: '90ms' }, "aria-label": t('wb.newtab.goTo'), children: _jsx("div", { className: "bt-start-links", children: newTab.links.map(link => {
|
|
64
|
+
const url = link.url(shell.homeUrl);
|
|
65
|
+
return _jsxs("button", { type: "button", className: "bt-start-link", title: url, onClick: () => open(url), children: [_jsx("span", { className: "bt-start-link-icon", children: _jsx(Icon, { name: link.icon }) }), _jsx("span", { className: "bt-start-link-label", children: link.label() })] }, link.id);
|
|
66
|
+
}) }) }), recent.length > 0 && _jsxs("section", { className: "bt-start-section bt-rise", style: { animationDelay: '120ms' }, "aria-labelledby": "bt-start-recent", children: [_jsx("h2", { className: "bt-start-label", id: "bt-start-recent", children: t('wb.newtab.recent') }), _jsx("ul", { className: "bt-start-recent", children: recent.map(tab => {
|
|
67
|
+
const account = tabProfile(profiles, tab.profile);
|
|
68
|
+
return _jsx("li", { children: _jsxs("button", { type: "button", className: "bt-start-row", title: tab.url, onClick: () => reopen(tab.index), children: [isSiteUrl(tab.url) ? _jsx("img", { className: "bt-start-row-icon", src: logo, alt: "", width: 16, height: 16 }) : _jsx("span", { className: "bt-start-row-icon", children: _jsx(Icon, { name: "globe" }) }), _jsx("span", { className: "bt-start-row-title", children: labelFor(tab.url, tab.title) }), _jsx("span", { className: "bt-start-row-host", children: hostOf(tab.url) }), multi && _jsx(Avatar, { name: account.name, color: account.color, size: 16 })] }) }, `${tab.index}:${tab.url}`);
|
|
69
|
+
}) })] }), _jsxs("footer", { className: "bt-start-foot bt-rise", style: { animationDelay: '150ms' }, children: [_jsxs("span", { children: [_jsx("kbd", { className: "bt-kbd", children: "Ctrl" }), _jsx("kbd", { className: "bt-kbd", children: "K" }), " ", t('wb.newtab.commands')] }), _jsxs("span", { children: [_jsx("kbd", { className: "bt-kbd", children: "Ctrl" }), _jsx("kbd", { className: "bt-kbd", children: "\u21E7" }), _jsx("kbd", { className: "bt-kbd", children: "T" }), " ", t('wb.newtab.reopen')] }), _jsxs("span", { children: [_jsx("kbd", { className: "bt-kbd", children: "Ctrl" }), _jsx("kbd", { className: "bt-kbd", children: "\\" }), " ", t('wb.newtab.split')] })] })] }) });
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=NewTabPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewTabPage.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/NewTabPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { tabProfile } from '../profileModel.ts';\nimport { invoke } from './bridge.ts';\nimport { useProfiles, useSiteText, useT } from './hooks.ts';\nimport { Avatar, Icon } from './icons.tsx';\nimport { toUrl } from './searchInput.ts';\nimport { site } from './site.ts';\nimport { shell } from './state.ts';\n\nconst hostOf = (url: string) => { try { return new URL(url).host.replace(/^www\\./, ''); } catch { return url; } };\n\n/** Human label for a closed tab without a stored title: the address bar's own reading of the URL. */\nfunction labelFor(url: string, title: string | undefined): string {\n if (title) return title;\n const model = site().address(url);\n if (!model) return url;\n return [model.site.label, ...model.segments.map(segment => segment.label)].join(' / ');\n}\n\n/**\n * The new-tab page (and the empty-dock state): one search/address field, the site's quick links,\n * recently closed tabs and the account the links open in. Drawn by the shell; it never has a webview.\n */\nexport function NewTabPage({ panelId, profile: initialProfile, onProfile }: { panelId?: string; profile?: string; onProfile?: (id: string) => void }) {\n const profiles = useProfiles();\n useSiteText();\n const [profile, setProfile] = useState(() => tabProfile(profiles, initialProfile ?? profiles.active).id);\n const [query, setQuery] = useState('');\n const [, refresh] = useState(0);\n const input = useRef<HTMLInputElement>(null);\n const multi = profiles.profiles.length > 1;\n const recent = shell.closed.map((tab, index) => ({ ...tab, index })).reverse().slice(0, 6);\n const { logo, newTab, isSiteUrl } = site();\n\n useEffect(() => {\n const focus = (event: Event) => {\n if ((event as CustomEvent<string>).detail !== panelId) return;\n input.current?.focus();\n input.current?.select();\n };\n window.addEventListener('bt-focus-address', focus);\n return () => window.removeEventListener('bt-focus-address', focus);\n }, [panelId]);\n\n const open = (url: string) => shell.openFromStart(url, profile, panelId);\n const pick = (id: string) => { setProfile(id); onProfile?.(id); };\n const reopen = (index: number) => {\n const [tab] = shell.closed.splice(index, 1);\n refresh(value => value + 1);\n if (tab) shell.openFromStart(tab.url, tabProfile(profiles, tab.profile).id, panelId);\n };\n const t = useT();\n const search = newTab.search();\n\n return <div className=\"bt-start\">\n <div className=\"bt-start-inner\">\n <div className=\"bt-start-mark bt-rise\" aria-hidden=\"true\"><img src={logo} alt=\"\" width={40} height={40} draggable={false}/></div>\n <form className=\"bt-start-search bt-rise\" style={{ animationDelay: '30ms' }} role=\"search\"\n onSubmit={event => { event.preventDefault(); if (query.trim()) open(toUrl(query, site().searchUrl)); }}>\n <Icon name=\"search\"/>\n <input ref={input} value={query} onChange={event => setQuery(event.target.value)} spellCheck={false} autoComplete=\"off\"\n aria-label={search} placeholder={search}\n onFocus={() => invoke('shell_focus').catch(() => {})}\n onKeyDown={event => { if (event.key === 'Escape') { event.preventDefault(); setQuery(''); } }}/>\n <kbd className=\"bt-kbd\">{t('wb.newtab.enter')}</kbd>\n </form>\n\n {multi && <div className=\"bt-start-accounts bt-rise\" style={{ animationDelay: '60ms' }} role=\"radiogroup\" aria-label={t('wb.newtab.openLinksAs')}>\n <span className=\"bt-start-label\">{t('wb.newtab.openAs')}</span>\n {profiles.profiles.map(item => <button key={item.id} type=\"button\" role=\"radio\" aria-checked={item.id === profile}\n className=\"bt-start-account\" onClick={() => pick(item.id)}>\n <Avatar name={item.name} color={item.color} size={20}/><span>{item.name}</span>\n </button>)}\n </div>}\n\n {newTab.links.length > 0 && <section className=\"bt-start-section bt-rise\" style={{ animationDelay: '90ms' }} aria-label={t('wb.newtab.goTo')}>\n <div className=\"bt-start-links\">\n {newTab.links.map(link => {\n const url = link.url(shell.homeUrl);\n return <button key={link.id} type=\"button\" className=\"bt-start-link\" title={url} onClick={() => open(url)}>\n <span className=\"bt-start-link-icon\"><Icon name={link.icon}/></span>\n <span className=\"bt-start-link-label\">{link.label()}</span>\n </button>;\n })}\n </div>\n </section>}\n\n {recent.length > 0 && <section className=\"bt-start-section bt-rise\" style={{ animationDelay: '120ms' }} aria-labelledby=\"bt-start-recent\">\n <h2 className=\"bt-start-label\" id=\"bt-start-recent\">{t('wb.newtab.recent')}</h2>\n <ul className=\"bt-start-recent\">\n {recent.map(tab => {\n const account = tabProfile(profiles, tab.profile);\n return <li key={`${tab.index}:${tab.url}`}>\n <button type=\"button\" className=\"bt-start-row\" title={tab.url} onClick={() => reopen(tab.index)}>\n {isSiteUrl(tab.url) ? <img className=\"bt-start-row-icon\" src={logo} alt=\"\" width={16} height={16}/> : <span className=\"bt-start-row-icon\"><Icon name=\"globe\"/></span>}\n <span className=\"bt-start-row-title\">{labelFor(tab.url, tab.title)}</span>\n <span className=\"bt-start-row-host\">{hostOf(tab.url)}</span>\n {multi && <Avatar name={account.name} color={account.color} size={16}/>}\n </button>\n </li>;\n })}\n </ul>\n </section>}\n\n <footer className=\"bt-start-foot bt-rise\" style={{ animationDelay: '150ms' }}>\n <span><kbd className=\"bt-kbd\">Ctrl</kbd><kbd className=\"bt-kbd\">K</kbd> {t('wb.newtab.commands')}</span>\n <span><kbd className=\"bt-kbd\">Ctrl</kbd><kbd className=\"bt-kbd\">⇧</kbd><kbd className=\"bt-kbd\">T</kbd> {t('wb.newtab.reopen')}</span>\n <span><kbd className=\"bt-kbd\">Ctrl</kbd><kbd className=\"bt-kbd\">\\</kbd> {t('wb.newtab.split')}</span>\n </footer>\n </div>\n </div>;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ThemeDoc, ThemeStore } from './themeStore.ts';
|
|
2
|
+
import './paneTheme.css';
|
|
3
|
+
type Request = {
|
|
4
|
+
id: string;
|
|
5
|
+
profile: string;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const openPaneTheme: (request: Request) => void;
|
|
10
|
+
/** Three dots of a theme's page, text and accent. */
|
|
11
|
+
export declare function ThemeDots<Spec extends ThemeDoc>({ theme, store }: {
|
|
12
|
+
theme: Spec;
|
|
13
|
+
store?: ThemeStore<unknown, Spec>;
|
|
14
|
+
}): import("react").JSX.Element | null;
|
|
15
|
+
export declare function PaneThemeHost(): import("react").JSX.Element | null;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// "Theme for this pane": a menu (tab context menu, the address bar's ⋯ menu) that gives one pane its
|
|
3
|
+
// own theme or lets it follow its account's / the global theme again. Pane themes are stored with
|
|
4
|
+
// the other scopes (themeStore.ts → native `theme_scopes_set`), which re-themes that tab natively.
|
|
5
|
+
// Only with themes (`site.themes`).
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
|
+
import { createPortal } from 'react-dom';
|
|
8
|
+
import { useT, useThemeState } from "./hooks.js";
|
|
9
|
+
import { Icon } from "./icons.js";
|
|
10
|
+
import { site } from "./site.js";
|
|
11
|
+
import { setOverlay, shell } from "./state.js";
|
|
12
|
+
import { assign, themeIdFor } from "./themeScopes.js";
|
|
13
|
+
import './paneTheme.css';
|
|
14
|
+
let open = () => { };
|
|
15
|
+
export const openPaneTheme = (request) => open(request);
|
|
16
|
+
/** Three dots of a theme's page, text and accent. */
|
|
17
|
+
export function ThemeDots({ theme, store }) {
|
|
18
|
+
const themes = (store ?? site().themes);
|
|
19
|
+
if (!themes)
|
|
20
|
+
return null;
|
|
21
|
+
const c = themes.adapter.dots(theme);
|
|
22
|
+
return _jsxs("span", { className: "wb-dots", "aria-hidden": "true", style: { background: c.page }, children: [_jsx("i", { style: { background: c.bg, boxShadow: `inset 0 0 0 1px ${c.border}` } }), _jsx("i", { style: { background: c.text } }), _jsx("i", { style: { background: c.accent } })] });
|
|
23
|
+
}
|
|
24
|
+
export function PaneThemeHost() {
|
|
25
|
+
const [request, setRequest] = useState(null);
|
|
26
|
+
open = setRequest;
|
|
27
|
+
const themes = site().themes;
|
|
28
|
+
return request && themes ? _jsx(PaneThemeMenu, { request: request, store: themes, onClose: () => setRequest(null) }) : null;
|
|
29
|
+
}
|
|
30
|
+
function PaneThemeMenu({ request, store, onClose }) {
|
|
31
|
+
const { scopes, choice } = useThemeState(store);
|
|
32
|
+
const list = useRef(null);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setOverlay(1);
|
|
35
|
+
const onBlur = () => onClose();
|
|
36
|
+
window.addEventListener('blur', onBlur);
|
|
37
|
+
requestAnimationFrame(() => list.current?.querySelector('[aria-checked=true]')?.focus());
|
|
38
|
+
return () => { setOverlay(-1); window.removeEventListener('blur', onBlur); };
|
|
39
|
+
}, []);
|
|
40
|
+
const own = scopes.panes[request.id];
|
|
41
|
+
const inherited = themeIdFor({ ...scopes, panes: {} }, { profile: request.profile }, store.adapter.preset(choice), id => store.knownTheme(id));
|
|
42
|
+
const pick = (theme) => {
|
|
43
|
+
onClose();
|
|
44
|
+
void store.setScopes(assign(store.themeState().scopes, 'panes', request.id, theme)).catch(() => { });
|
|
45
|
+
};
|
|
46
|
+
const onKey = (event) => {
|
|
47
|
+
const items = [...(list.current?.querySelectorAll('button') ?? [])];
|
|
48
|
+
const index = items.indexOf(document.activeElement);
|
|
49
|
+
if (event.key === 'Escape') {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
onClose();
|
|
52
|
+
}
|
|
53
|
+
else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
items[(index + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length]?.focus();
|
|
56
|
+
}
|
|
57
|
+
else if (event.key === 'Home' || event.key === 'End') {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
items[event.key === 'Home' ? 0 : items.length - 1]?.focus();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const t = useT();
|
|
63
|
+
const left = Math.max(8, Math.min(request.x, window.innerWidth - 280));
|
|
64
|
+
const top = Math.max(8, Math.min(request.y, window.innerHeight - 440));
|
|
65
|
+
return createPortal(_jsx("div", { className: "bt-menu-backdrop", onMouseDown: onClose, onContextMenu: event => { event.preventDefault(); onClose(); }, children: _jsxs("div", { className: "bt-menu bt-pop wb-pane-menu", role: "menu", "aria-label": t('wb.pane.theme'), style: { left, top }, onMouseDown: event => event.stopPropagation(), onKeyDown: onKey, ref: list, children: [_jsxs("div", { className: "wb-pane-menu-head", children: [_jsx(Icon, { name: "palette" }), _jsx("span", { children: t('wb.pane.theme') })] }), _jsxs("button", { role: "menuitemradio", "aria-checked": !own, onClick: () => pick(null), children: [_jsxs("span", { className: "bt-menu-label", children: [inherited.source === 'account' ? t('wb.pane.followAccount') : t('wb.pane.followApp'), " ", _jsxs("small", { children: ["\u00B7 ", store.themeName(inherited.id)] })] }), !own && _jsx(Icon, { name: "check" })] }), _jsx("hr", {}), _jsx("div", { className: "wb-pane-menu-list", children: store.allThemes(choice).map(theme => _jsxs("button", { role: "menuitemradio", "aria-checked": own === theme.id, onClick: () => pick(theme.id), children: [_jsx(ThemeDots, { theme: theme, store: store }), _jsx("span", { className: "bt-menu-label", children: theme.name }), own === theme.id && _jsx(Icon, { name: "check" })] }, theme.id)) }), _jsx("hr", {}), _jsxs("button", { role: "menuitem", onClick: () => { onClose(); shell.openPanelSection('themes'); }, children: [_jsx(Icon, { name: "settings" }), _jsx("span", { className: "bt-menu-label", children: t('wb.pane.themesLink') })] })] }) }), document.body);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=PaneTheme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaneTheme.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/PaneTheme.tsx"],"names":[],"mappings":"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","sourcesContent":["// \"Theme for this pane\": a menu (tab context menu, the address bar's ⋯ menu) that gives one pane its\n// own theme or lets it follow its account's / the global theme again. Pane themes are stored with\n// the other scopes (themeStore.ts → native `theme_scopes_set`), which re-themes that tab natively.\n// Only with themes (`site.themes`).\n\nimport { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useT, useThemeState } from './hooks.ts';\nimport { Icon } from './icons.tsx';\nimport { site } from './site.ts';\nimport { setOverlay, shell } from './state.ts';\nimport { assign, themeIdFor } from './themeScopes.ts';\nimport type { ThemeDoc, ThemeStore } from './themeStore.ts';\nimport './paneTheme.css';\n\ntype Request = { id: string; profile: string; x: number; y: number };\nlet open: (request: Request | null) => void = () => {};\nexport const openPaneTheme = (request: Request) => open(request);\n\n/** Three dots of a theme's page, text and accent. */\nexport function ThemeDots<Spec extends ThemeDoc>({ theme, store }: { theme: Spec; store?: ThemeStore<unknown, Spec> }) {\n const themes = (store ?? site().themes) as ThemeStore<unknown, Spec> | undefined;\n if (!themes) return null;\n const c = themes.adapter.dots(theme);\n return <span className=\"wb-dots\" aria-hidden=\"true\" style={{ background: c.page }}>\n <i style={{ background: c.bg, boxShadow: `inset 0 0 0 1px ${c.border}` }}/><i style={{ background: c.text }}/><i style={{ background: c.accent }}/>\n </span>;\n}\n\nexport function PaneThemeHost() {\n const [request, setRequest] = useState<Request | null>(null);\n open = setRequest;\n const themes = site().themes;\n return request && themes ? <PaneThemeMenu request={request} store={themes} onClose={() => setRequest(null)}/> : null;\n}\n\nfunction PaneThemeMenu({ request, store, onClose }: { request: Request; store: ThemeStore<unknown, ThemeDoc>; onClose(): void }) {\n const { scopes, choice } = useThemeState(store);\n const list = useRef<HTMLDivElement>(null);\n useEffect(() => {\n setOverlay(1);\n const onBlur = () => onClose();\n window.addEventListener('blur', onBlur);\n requestAnimationFrame(() => list.current?.querySelector<HTMLButtonElement>('[aria-checked=true]')?.focus());\n return () => { setOverlay(-1); window.removeEventListener('blur', onBlur); };\n }, []);\n const own = scopes.panes[request.id];\n const inherited = themeIdFor({ ...scopes, panes: {} }, { profile: request.profile }, store.adapter.preset(choice), id => store.knownTheme(id));\n const pick = (theme: string | null) => {\n onClose();\n void store.setScopes(assign(store.themeState().scopes, 'panes', request.id, theme)).catch(() => {});\n };\n const onKey = (event: ReactKeyboardEvent) => {\n const items = [...(list.current?.querySelectorAll<HTMLButtonElement>('button') ?? [])];\n const index = items.indexOf(document.activeElement as HTMLButtonElement);\n if (event.key === 'Escape') { event.preventDefault(); onClose(); }\n else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n items[(index + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length]?.focus();\n } else if (event.key === 'Home' || event.key === 'End') { event.preventDefault(); items[event.key === 'Home' ? 0 : items.length - 1]?.focus(); }\n };\n const t = useT();\n const left = Math.max(8, Math.min(request.x, window.innerWidth - 280));\n const top = Math.max(8, Math.min(request.y, window.innerHeight - 440));\n return createPortal(<div className=\"bt-menu-backdrop\" onMouseDown={onClose} onContextMenu={event => { event.preventDefault(); onClose(); }}>\n <div className=\"bt-menu bt-pop wb-pane-menu\" role=\"menu\" aria-label={t('wb.pane.theme')} style={{ left, top }} onMouseDown={event => event.stopPropagation()} onKeyDown={onKey} ref={list}>\n <div className=\"wb-pane-menu-head\"><Icon name=\"palette\"/><span>{t('wb.pane.theme')}</span></div>\n <button role=\"menuitemradio\" aria-checked={!own} onClick={() => pick(null)}>\n <span className=\"bt-menu-label\">{inherited.source === 'account' ? t('wb.pane.followAccount') : t('wb.pane.followApp')} <small>· {store.themeName(inherited.id)}</small></span>\n {!own && <Icon name=\"check\"/>}\n </button>\n <hr/>\n <div className=\"wb-pane-menu-list\">\n {store.allThemes(choice).map(theme => <button key={theme.id} role=\"menuitemradio\" aria-checked={own === theme.id} onClick={() => pick(theme.id)}>\n <ThemeDots theme={theme} store={store}/><span className=\"bt-menu-label\">{theme.name}</span>{own === theme.id && <Icon name=\"check\"/>}\n </button>)}\n </div>\n <hr/>\n <button role=\"menuitem\" onClick={() => { onClose(); shell.openPanelSection('themes'); }}><Icon name=\"settings\"/><span className=\"bt-menu-label\">{t('wb.pane.themesLink')}</span></button>\n </div>\n </div>, document.body);\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// "Report a problem": a small dialog that shows the diagnostic summary (reportModel.ts) exactly as
|
|
3
|
+
// it would be shared, with Copy and a button that opens the project's new-issue page in the system
|
|
4
|
+
// browser. The app sends nothing itself: no request, and the summary is never put in a URL (the
|
|
5
|
+
// issue page opens bare; the owner pastes what they copied). Without a configured issue page the
|
|
6
|
+
// button is off and says why.
|
|
7
|
+
import { useEffect, useRef, useState } from 'react';
|
|
8
|
+
import { createPortal } from 'react-dom';
|
|
9
|
+
import { invoke } from "./bridge.js";
|
|
10
|
+
import { useT } from "./hooks.js";
|
|
11
|
+
import { textLocale } from "./i18n.js";
|
|
12
|
+
import { Icon } from "./icons.js";
|
|
13
|
+
import { menuText } from "./menuModel.js";
|
|
14
|
+
import { buildReport, systemFromUserAgent, webviewFromUserAgent } from "./reportModel.js";
|
|
15
|
+
import { safe } from "./safeStore.js";
|
|
16
|
+
import { site } from "./site.js";
|
|
17
|
+
import { setOverlay } from "./state.js";
|
|
18
|
+
/** What the engine says about the system when asked (Chromium webviews; others have the user agent only). */
|
|
19
|
+
async function systemHints() {
|
|
20
|
+
try {
|
|
21
|
+
const data = navigator.userAgentData;
|
|
22
|
+
return data ? await data.getHighEntropyValues(['platformVersion', 'architecture', 'bitness', 'fullVersionList']) : {};
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Gathers the facts a report may say: from the app's config and the shell's own state, nothing about the person. */
|
|
29
|
+
async function collect() {
|
|
30
|
+
const config = site();
|
|
31
|
+
const menu = config.menu ?? {};
|
|
32
|
+
const themes = config.themes;
|
|
33
|
+
const [appVersion, hints, mode, plugins, details] = await Promise.all([
|
|
34
|
+
menu.version ? menu.version().catch(() => '') : Promise.resolve(''),
|
|
35
|
+
systemHints(),
|
|
36
|
+
menu.modes ? menu.modes.current().catch(() => null) : Promise.resolve(undefined),
|
|
37
|
+
invoke('plugins_list').then(list => list.filter(plugin => plugin.enabled === true).map(plugin => String(plugin.file ?? '')), () => null),
|
|
38
|
+
menu.report?.details ? Promise.resolve(menu.report.details()).catch(() => []) : Promise.resolve([]),
|
|
39
|
+
]);
|
|
40
|
+
if (themes)
|
|
41
|
+
await themes.loadThemes().catch(() => { });
|
|
42
|
+
const choice = themes?.current().choice;
|
|
43
|
+
const theme = themes ? themes.adapter.resolve(choice) : null;
|
|
44
|
+
return {
|
|
45
|
+
product: config.product,
|
|
46
|
+
appVersion,
|
|
47
|
+
system: systemFromUserAgent(navigator.userAgent, hints),
|
|
48
|
+
webview: webviewFromUserAgent(navigator.userAgent, hints.fullVersionList),
|
|
49
|
+
language: menu.languages?.state().locale ?? textLocale(),
|
|
50
|
+
languageChoice: menu.languages?.state().preference ?? 'fixed',
|
|
51
|
+
mode,
|
|
52
|
+
theme: themes ? themes.adapter.preset(choice) : undefined,
|
|
53
|
+
iconPack: theme ? (typeof theme.icons?.pack === 'string' ? theme.icons.pack : '') : undefined,
|
|
54
|
+
plugins,
|
|
55
|
+
details,
|
|
56
|
+
safeMode: safe.active,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function ReportDialog({ onClose }) {
|
|
60
|
+
const t = useT();
|
|
61
|
+
const [text, setText] = useState(null);
|
|
62
|
+
const [copied, setCopied] = useState(false);
|
|
63
|
+
const dialog = useRef(null);
|
|
64
|
+
const issueUrl = site().menu?.report?.issueUrl;
|
|
65
|
+
const canOpen = typeof issueUrl === 'string' && /^https:\/\//.test(issueUrl);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
setOverlay(1);
|
|
68
|
+
invoke('shell_focus').catch(() => { });
|
|
69
|
+
let live = true;
|
|
70
|
+
collect().then(info => { if (live)
|
|
71
|
+
setText(buildReport(info)); }, () => { if (live)
|
|
72
|
+
setText(''); });
|
|
73
|
+
dialog.current?.focus();
|
|
74
|
+
return () => { live = false; setOverlay(-1); };
|
|
75
|
+
}, []);
|
|
76
|
+
const copy = async () => {
|
|
77
|
+
if (!text)
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
await navigator.clipboard.writeText(text);
|
|
81
|
+
setCopied(true);
|
|
82
|
+
setTimeout(() => setCopied(false), 2200);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
dialog.current?.querySelector('textarea')?.select();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return createPortal(_jsx("div", { className: "bt-palette-backdrop bt-report-backdrop", onMouseDown: onClose, children: _jsxs("div", { ref: dialog, className: "bt-palette bt-report bt-pop", role: "dialog", "aria-modal": "true", "aria-labelledby": "bt-report-title", "aria-describedby": "bt-report-lede", tabIndex: -1, onMouseDown: event => event.stopPropagation(), onKeyDown: event => { if (event.key === 'Escape') {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
onClose();
|
|
92
|
+
} }, children: [_jsxs("header", { className: "bt-report-head", children: [_jsx("h2", { id: "bt-report-title", children: menuText('reportTitle') }), _jsx("button", { className: "bt-icon", "aria-label": t('wb.common.close'), onClick: onClose, children: _jsx(Icon, { name: "close" }) })] }), _jsx("p", { id: "bt-report-lede", className: "bt-report-lede", children: menuText('reportLede') }), _jsx("textarea", { className: "bt-report-text", readOnly: true, spellCheck: false, dir: "ltr", lang: "en", rows: 12, "aria-label": menuText('reportTitle'), value: text ?? t('wb.common.loading'), onFocus: event => event.currentTarget.select() }), !canOpen && _jsx("p", { className: "bt-report-note", children: menuText('reportNoPage') }), _jsxs("footer", { className: "bt-report-foot", children: [_jsx("span", { className: "bt-report-copied", role: "status", "aria-live": "polite", children: copied ? t('wb.common.copied') : '' }), _jsxs("button", { className: "bt-deck-secondary", disabled: !canOpen, title: canOpen ? issueUrl : menuText('reportNoPage'), onClick: () => { if (canOpen)
|
|
93
|
+
invoke('open_external_url', { url: issueUrl }).catch(() => { }); }, children: [_jsx(Icon, { name: "external" }), menuText('reportOpen')] }), _jsxs("button", { className: "bt-deck-primary", disabled: !text, onClick: () => void copy(), children: [_jsx(Icon, { name: "copy" }), t('wb.common.copy')] })] })] }) }), document.body);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=ReportDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReportDialog.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/ReportDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["// \"Report a problem\": a small dialog that shows the diagnostic summary (reportModel.ts) exactly as\n// it would be shared, with Copy and a button that opens the project's new-issue page in the system\n// browser. The app sends nothing itself: no request, and the summary is never put in a URL (the\n// issue page opens bare; the owner pastes what they copied). Without a configured issue page the\n// button is off and says why.\n\nimport { useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { invoke } from './bridge.ts';\nimport { useT } from './hooks.ts';\nimport { textLocale } from './i18n.ts';\nimport { Icon } from './icons.tsx';\nimport { menuText } from './menuModel.ts';\nimport { buildReport, systemFromUserAgent, webviewFromUserAgent, type ReportInfo } from './reportModel.ts';\nimport { safe } from './safeStore.ts';\nimport { site } from './site.ts';\nimport { setOverlay } from './state.ts';\n\ntype Hints = { platformVersion?: string; architecture?: string; bitness?: string; fullVersionList?: Array<{ brand?: string; version?: string }> };\n\n/** What the engine says about the system when asked (Chromium webviews; others have the user agent only). */\nasync function systemHints(): Promise<Hints> {\n try {\n const data = (navigator as Navigator & { userAgentData?: { getHighEntropyValues(hints: string[]): Promise<Hints> } }).userAgentData;\n return data ? await data.getHighEntropyValues(['platformVersion', 'architecture', 'bitness', 'fullVersionList']) : {};\n } catch { return {}; }\n}\n\n/** Gathers the facts a report may say: from the app's config and the shell's own state, nothing about the person. */\nasync function collect(): Promise<ReportInfo> {\n const config = site();\n const menu = config.menu ?? {};\n const themes = config.themes;\n const [appVersion, hints, mode, plugins, details] = await Promise.all([\n menu.version ? menu.version().catch(() => '') : Promise.resolve(''),\n systemHints(),\n menu.modes ? menu.modes.current().catch(() => null) : Promise.resolve(undefined),\n invoke<Array<{ file?: unknown; enabled?: unknown }>>('plugins_list').then(list => list.filter(plugin => plugin.enabled === true).map(plugin => String(plugin.file ?? '')), () => null),\n menu.report?.details ? Promise.resolve(menu.report.details()).catch(() => []) : Promise.resolve([]),\n ]);\n if (themes) await themes.loadThemes().catch(() => {});\n const choice = themes?.current().choice;\n const theme = themes ? themes.adapter.resolve(choice) as { id?: unknown; icons?: { pack?: unknown } } : null;\n return {\n product: config.product,\n appVersion,\n system: systemFromUserAgent(navigator.userAgent, hints),\n webview: webviewFromUserAgent(navigator.userAgent, hints.fullVersionList),\n language: menu.languages?.state().locale ?? textLocale(),\n languageChoice: menu.languages?.state().preference ?? 'fixed',\n mode,\n theme: themes ? themes.adapter.preset(choice) : undefined,\n iconPack: theme ? (typeof theme.icons?.pack === 'string' ? theme.icons.pack : '') : undefined,\n plugins,\n details,\n safeMode: safe.active,\n };\n}\n\nexport function ReportDialog({ onClose }: { onClose(): void }) {\n const t = useT();\n const [text, setText] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n const dialog = useRef<HTMLDivElement>(null);\n const issueUrl = site().menu?.report?.issueUrl;\n const canOpen = typeof issueUrl === 'string' && /^https:\\/\\//.test(issueUrl);\n\n useEffect(() => {\n setOverlay(1);\n invoke('shell_focus').catch(() => {});\n let live = true;\n collect().then(info => { if (live) setText(buildReport(info)); }, () => { if (live) setText(''); });\n dialog.current?.focus();\n return () => { live = false; setOverlay(-1); };\n }, []);\n\n const copy = async () => {\n if (!text) return;\n try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2200); }\n catch { dialog.current?.querySelector<HTMLTextAreaElement>('textarea')?.select(); }\n };\n\n return createPortal(<div className=\"bt-palette-backdrop bt-report-backdrop\" onMouseDown={onClose}>\n <div ref={dialog} className=\"bt-palette bt-report bt-pop\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"bt-report-title\" aria-describedby=\"bt-report-lede\" tabIndex={-1}\n onMouseDown={event => event.stopPropagation()} onKeyDown={event => { if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); onClose(); } }}>\n <header className=\"bt-report-head\">\n <h2 id=\"bt-report-title\">{menuText('reportTitle')}</h2>\n <button className=\"bt-icon\" aria-label={t('wb.common.close')} onClick={onClose}><Icon name=\"close\"/></button>\n </header>\n <p id=\"bt-report-lede\" className=\"bt-report-lede\">{menuText('reportLede')}</p>\n <textarea className=\"bt-report-text\" readOnly spellCheck={false} dir=\"ltr\" lang=\"en\" rows={12} aria-label={menuText('reportTitle')}\n value={text ?? t('wb.common.loading')} onFocus={event => event.currentTarget.select()}/>\n {!canOpen && <p className=\"bt-report-note\">{menuText('reportNoPage')}</p>}\n <footer className=\"bt-report-foot\">\n <span className=\"bt-report-copied\" role=\"status\" aria-live=\"polite\">{copied ? t('wb.common.copied') : ''}</span>\n <button className=\"bt-deck-secondary\" disabled={!canOpen} title={canOpen ? issueUrl : menuText('reportNoPage')}\n onClick={() => { if (canOpen) invoke('open_external_url', { url: issueUrl }).catch(() => {}); }}><Icon name=\"external\"/>{menuText('reportOpen')}</button>\n <button className=\"bt-deck-primary\" disabled={!text} onClick={() => void copy()}><Icon name=\"copy\"/>{t('wb.common.copy')}</button>\n </footer>\n </div>\n </div>, document.body);\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IDockviewPanel } from 'dockview';
|
|
2
|
+
import 'dockview/dist/styles/dockview.css';
|
|
3
|
+
import './shell.css';
|
|
4
|
+
/** How long the startup cover waits, once the window is shown, for the visible site tabs to say they painted. */
|
|
5
|
+
export declare const STARTUP_CONTENT_WAIT = 8000;
|
|
6
|
+
export declare function setDevBuild(value: boolean): void;
|
|
7
|
+
export declare function splitTab(panel: IDockviewPanel, direction: 'right' | 'below'): void;
|
|
8
|
+
export default function Shell(): import("react").JSX.Element;
|