waybetter 0.1.1 → 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 +139 -6
- package/bin/waybetter.mjs +43 -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/release.mjs +437 -0
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +378 -0
- package/cli/strings.mjs +123 -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 +61 -0
- package/dist/runtime/stringPackTranslate.js +267 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +248 -0
- package/dist/runtime/stringPacks.js +610 -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/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.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 +476 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +133 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- 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 +52 -0
- package/dist/runtime/themeDoctor.js +112 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- 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 +130 -0
- package/dist/runtime/themeIcons.js +271 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- 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 +114 -0
- package/dist/runtime/themeRuntime.js +570 -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 +263 -0
- package/dist/runtime/themeSpec.js +435 -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 +176 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +78 -0
- package/dist/shell/StoreView.js +108 -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 +44 -0
- package/dist/shell/frame/AppMenu.js +721 -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 +9 -0
- package/dist/shell/frame/Shell.js +1139 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +17 -0
- package/dist/shell/frame/Titlebar.js +79 -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 +185 -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 +127 -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 +37 -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 +47 -0
- package/dist/shell/frame/chromeTheme.js +118 -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/edges.css +159 -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 +47 -0
- package/dist/shell/frame/mediaModel.js +67 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +96 -0
- package/dist/shell/frame/menuModel.d.ts +319 -0
- package/dist/shell/frame/menuModel.js +301 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- 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.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +114 -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 +634 -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 +101 -0
- package/dist/shell/frame/state.js +286 -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 +267 -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 +137 -0
- package/dist/shell/installController.js +172 -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 +265 -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 +117 -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 +7 -0
- package/dist/shell/panel/StoreSection.js +78 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +20 -0
- package/dist/shell/panel/StringPacks.js +131 -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 +240 -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 +73 -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 +803 -0
- package/dist/shell/panel/panelMessages.js +779 -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 +250 -0
- package/dist/shell/storeMessages.d.ts +193 -0
- package/dist/shell/storeMessages.js +196 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +205 -0
- package/dist/shell/storeModel.js +146 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +99 -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 +655 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1388 -0
- package/locales/bg.json +1387 -0
- package/locales/bn.json +1387 -0
- package/locales/ca.json +1387 -0
- package/locales/cs.json +1387 -0
- package/locales/da.json +1387 -0
- package/locales/de.json +1387 -0
- package/locales/el.json +1387 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1386 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1387 -0
- package/locales/eu.json +1387 -0
- package/locales/fa.json +1388 -0
- package/locales/fi.json +1387 -0
- package/locales/fil.json +1387 -0
- package/locales/fr.json +1387 -0
- package/locales/ga.json +1387 -0
- package/locales/gl.json +1387 -0
- package/locales/gu.json +1387 -0
- package/locales/ha.json +1387 -0
- package/locales/he.json +1388 -0
- package/locales/hi.json +1387 -0
- package/locales/hr.json +1387 -0
- package/locales/hu.json +1387 -0
- package/locales/id.json +1387 -0
- package/locales/ig.json +1387 -0
- package/locales/it.json +1387 -0
- package/locales/ja.json +1387 -0
- package/locales/kn.json +1387 -0
- package/locales/ko.json +1387 -0
- package/locales/mr.json +1387 -0
- package/locales/ms.json +1387 -0
- package/locales/nb.json +1387 -0
- package/locales/nl.json +1387 -0
- package/locales/pl.json +1387 -0
- package/locales/pt.json +1387 -0
- package/locales/ro.json +1387 -0
- package/locales/ru.json +1387 -0
- package/locales/sk.json +1387 -0
- package/locales/sr.json +1387 -0
- package/locales/sv.json +1387 -0
- package/locales/ta.json +1387 -0
- package/locales/th.json +1387 -0
- package/locales/tr.json +1387 -0
- package/locales/uk.json +1387 -0
- package/locales/ur.json +1388 -0
- package/locales/vi.json +1387 -0
- package/locales/yo.json +1387 -0
- package/locales/zh-Hans.json +1387 -0
- package/locales/zh-Hant.json +1387 -0
- package/package.json +138 -5
- package/store-catalog.schema.json +78 -0
- package/theme.schema.json +4668 -0
- package/windows/installer.nsi +946 -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,270 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Modes: the presets an app's feature table defines (Basic / Advanced / Power User, or whatever the
|
|
3
|
+
// app calls them). `Onboarding` is the first-run screen: three cards, one recommended and
|
|
4
|
+
// preselected; someone who set the app up before modes existed may dismiss it and keep exactly
|
|
5
|
+
// what they have. `ModeSettings` is the same choice later, in Settings, with the question whether
|
|
6
|
+
// the owner's own changes stay. A mode is a starting point: choosing one writes flag values
|
|
7
|
+
// (`features_set`) and remembers the choice (`mode_get/set`); it never takes a switch away, and it
|
|
8
|
+
// is never applied again on its own. When the flags are no longer what the mode starts from (the
|
|
9
|
+
// owner changed features, or an update made the mode larger) the mode reads "Custom (based on
|
|
10
|
+
// <mode>)" and one action, "Re-apply <mode>", lists what it turns on and off before it does.
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
import { areaFlag, featureWords, modeById, modeFlags, modeStatus, normalizeFlags, sparseFlags as sparse, } from "../../runtime/featureTable.js";
|
|
13
|
+
import { invoke } from "../frame/bridge.js";
|
|
14
|
+
import { useT } from "../frame/hooks.js";
|
|
15
|
+
import { tx } from "../frame/i18n.js";
|
|
16
|
+
import { shell } from "../frame/state.js";
|
|
17
|
+
import { Badge, Button, Row, Section } from "./controls.js";
|
|
18
|
+
import { modePlan } from "./featureModel.js";
|
|
19
|
+
import { featureTable, flagsChanged, useFlags } from "./PluginFeatures.js";
|
|
20
|
+
import { panelSite } from "./site.js";
|
|
21
|
+
import './plugins.css';
|
|
22
|
+
const getError = (error) => error instanceof Error ? error.message : String(error);
|
|
23
|
+
const listeners = new Set();
|
|
24
|
+
let cached = null;
|
|
25
|
+
const share = (next) => { cached = next; for (const listener of listeners)
|
|
26
|
+
listener(next); };
|
|
27
|
+
/** Tells the mode screens a mode was stored from elsewhere (an imported setup). */
|
|
28
|
+
export const rememberModeState = share;
|
|
29
|
+
/** The mode state, loaded once and shared by the first-run screen and Settings. Null until loaded (or without modes). */
|
|
30
|
+
export function useModeState() {
|
|
31
|
+
const [state, setState] = useState(cached);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
listeners.add(setState);
|
|
34
|
+
if (!cached && featureTable()?.modes.length)
|
|
35
|
+
invoke('mode_get').then(value => { cached = value; for (const listener of listeners)
|
|
36
|
+
listener(value); }).catch(() => { });
|
|
37
|
+
return () => { listeners.delete(setState); };
|
|
38
|
+
}, []);
|
|
39
|
+
return [state, next => { cached = next; for (const listener of listeners)
|
|
40
|
+
listener(next); }];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Applies mode `to`: saves its flags (over the owner's own changes, or under them with `keep`),
|
|
44
|
+
* turns off the old plugin files a fresh mode does not have, records the choice and runs the app's
|
|
45
|
+
* own step for the mode.
|
|
46
|
+
*/
|
|
47
|
+
async function applyMode(table, flags, from, to, keep, save) {
|
|
48
|
+
const plugins = await invoke('plugins_list').catch(() => []);
|
|
49
|
+
const plan = modePlan(table, flags, plugins, from, to, keep);
|
|
50
|
+
if (!await save(plan.flags))
|
|
51
|
+
return null;
|
|
52
|
+
for (const file of plan.disable)
|
|
53
|
+
await invoke('plugin_set_enabled', { file, enabled: false }).catch(() => { });
|
|
54
|
+
if (plan.disable.length)
|
|
55
|
+
window.dispatchEvent(new CustomEvent('bt-plugins-changed'));
|
|
56
|
+
const state = await invoke('mode_set', { mode: to, onboarded: true, preset: modeById(table, to)?.flags ?? {} });
|
|
57
|
+
flagsChanged();
|
|
58
|
+
await panelSite().features?.onMode?.(to);
|
|
59
|
+
return state;
|
|
60
|
+
}
|
|
61
|
+
/** "Re-apply <mode>": every flag back to what the mode starts from now. Plugin files are not touched. */
|
|
62
|
+
async function reapplyMode(table, mode, save) {
|
|
63
|
+
if (!modeById(table, mode) || !await save(modeFlags(table, mode)))
|
|
64
|
+
return null;
|
|
65
|
+
const state = await invoke('mode_set', { mode, onboarded: true, preset: modeById(table, mode).flags });
|
|
66
|
+
flagsChanged();
|
|
67
|
+
return state;
|
|
68
|
+
}
|
|
69
|
+
/** The "new features" note was looked at: the mode's preset of today is the one remembered, so it is said once. */
|
|
70
|
+
const presetSeen = (table, state) => invoke('mode_set', { mode: state.mode, onboarded: state.onboarded, preset: modeById(table, state.mode)?.flags ?? {} });
|
|
71
|
+
/** A flag as the owner knows it: the feature's label, or the area's name for its switch. */
|
|
72
|
+
export function flagName(table, id) {
|
|
73
|
+
const area = table.areas.find(entry => areaFlag(entry.id) === id);
|
|
74
|
+
if (area)
|
|
75
|
+
return area.name;
|
|
76
|
+
const feature = table.features.find(entry => entry.id === id);
|
|
77
|
+
return feature ? tx(featureWords(feature).label, undefined, id) : id;
|
|
78
|
+
}
|
|
79
|
+
const flagNames = (table, ids) => ids.map(id => flagName(table, id)).join(', ');
|
|
80
|
+
/** What "Re-apply" would do, in words: one line for what turns on, one for what turns off. */
|
|
81
|
+
function ReapplyList({ table, status }) {
|
|
82
|
+
const t = useT();
|
|
83
|
+
return _jsxs(_Fragment, { children: [status.on.length > 0 && _jsx("small", { children: t('wb.modes.turnsOn', { list: flagNames(table, status.on) }) }), status.off.length > 0 && _jsx("small", { children: t('wb.modes.turnsOff', { list: flagNames(table, status.off) }) })] });
|
|
84
|
+
}
|
|
85
|
+
function ModeCards({ table, selected, onSelect, Art }) {
|
|
86
|
+
const t = useT();
|
|
87
|
+
return _jsx("div", { className: "wbm-cards", role: "radiogroup", "aria-label": t('wb.modes.section'), children: table.modes.map(mode => _jsxs("button", { type: "button", role: "radio", "aria-checked": selected === mode.id, className: `wbm-card ${selected === mode.id ? 'is-on' : ''}`, onClick: () => onSelect(mode.id), children: [_jsx("span", { className: "wbm-art", "aria-hidden": "true", children: Art ? _jsx(Art, { mode: mode.id }) : _jsx(ModeBars, { index: table.modes.indexOf(mode), count: table.modes.length }) }), _jsxs("strong", { children: [tx(mode.name, undefined, mode.id), mode.recommended && _jsx(Badge, { tone: "accent", children: t('wb.modes.recommended') })] }), _jsx("span", { children: tx(mode.description, undefined, '') })] }, mode.id)) });
|
|
88
|
+
}
|
|
89
|
+
/** The default illustration: how much of the page a mode touches, as filled bars. */
|
|
90
|
+
function ModeBars({ index, count }) {
|
|
91
|
+
return _jsx("svg", { viewBox: "0 0 96 40", width: "96", height: "40", children: Array.from({ length: count + 2 }, (_, bar) => _jsx("rect", { x: 8 + bar * (80 / (count + 2)), y: 8, width: 80 / (count + 2) - 5, height: 24, rx: 3, fill: "currentColor", opacity: bar <= index + 1 ? 0.85 : 0.16 }, bar)) });
|
|
92
|
+
}
|
|
93
|
+
/** The first-run screen. `done` runs once a mode was chosen or the screen was dismissed. */
|
|
94
|
+
export function Onboarding({ state, done, notify }) {
|
|
95
|
+
const t = useT();
|
|
96
|
+
const table = featureTable();
|
|
97
|
+
const panel = panelSite();
|
|
98
|
+
const [flags] = useFlags(table, notify);
|
|
99
|
+
const recommended = table.modes.find(mode => mode.recommended)?.id ?? table.modes[0]?.id ?? null;
|
|
100
|
+
// Someone who set the app up before keeps what they have unless they pick a mode themselves.
|
|
101
|
+
const [selected, setSelected] = useState(state.existing ? null : recommended);
|
|
102
|
+
const [busy, setBusy] = useState(false);
|
|
103
|
+
const mode = modeById(table, selected);
|
|
104
|
+
const stored = modeById(table, state.mode);
|
|
105
|
+
const custom = !!stored && !!flags && modeStatus(table, flags, stored.id, state.preset).custom;
|
|
106
|
+
async function finish(next) {
|
|
107
|
+
setBusy(true);
|
|
108
|
+
try {
|
|
109
|
+
const result = await next();
|
|
110
|
+
if (result)
|
|
111
|
+
done(result);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
notify(getError(err), true);
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
setBusy(false);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const save = async (next) => { await invoke('features_set', { features: sparse(table, next) }); return true; };
|
|
121
|
+
const start = (keep) => flags && selected && void finish(() => applyMode(table, flags, state.mode, selected, keep, save));
|
|
122
|
+
const dismiss = () => void finish(() => invoke('mode_set', { mode: state.mode, onboarded: true }));
|
|
123
|
+
return _jsxs("div", { className: "wbm-onboarding", role: "dialog", "aria-labelledby": "wbm-title", children: [_jsx("img", { src: panel.brand.logo, alt: "", width: 44, height: 44 }), _jsx("h1", { id: "wbm-title", children: t('wb.modes.title', { app: panel.brand.name }) }), _jsx("p", { children: t('wb.modes.lede') }), _jsx(ModeCards, { table: table, selected: selected, onSelect: setSelected, Art: panel.features?.ModeArt }), state.existing && _jsx("p", { className: "wbm-note", children: t('wb.modes.existing', { app: panel.brand.name }) }), custom && _jsx("p", { className: "wbm-note", children: t('wb.modes.custom', { mode: tx(stored.name, undefined, stored.id) }) }), _jsxs("div", { className: "wbm-actions", children: [state.existing && _jsx(Button, { tone: selected ? 'ghost' : 'primary', disabled: busy, onClick: dismiss, children: t('wb.modes.keepSetup') }), mode && state.existing && _jsx(Button, { disabled: busy || !flags, onClick: () => start(true), children: t('wb.modes.keep') }), mode && _jsx(Button, { tone: "primary", disabled: busy || !flags, onClick: () => start(false), children: t('wb.modes.start', { mode: tx(mode.name, undefined, mode.id) }) })] })] });
|
|
124
|
+
}
|
|
125
|
+
/** Settings: the mode in use and the way to another one, keeping or dropping the owner's changes. */
|
|
126
|
+
export function ModeSettings({ notify }) {
|
|
127
|
+
const table = featureTable();
|
|
128
|
+
return table?.modes.length ? _jsx(ModeSettingsOf, { table: table, notify: notify }) : null;
|
|
129
|
+
}
|
|
130
|
+
function ModeSettingsOf({ table, notify }) {
|
|
131
|
+
const t = useT();
|
|
132
|
+
const [state, setState] = useModeState();
|
|
133
|
+
const [flags, , reload] = useFlags(table, notify);
|
|
134
|
+
const [asking, setAsking] = useState(null);
|
|
135
|
+
const [reviewing, setReviewing] = useState(false);
|
|
136
|
+
if (!state || !flags)
|
|
137
|
+
return null;
|
|
138
|
+
const name = (id) => tx(modeById(table, id)?.name ?? id, undefined, id);
|
|
139
|
+
const save = async (next) => { await invoke('features_set', { features: sparse(table, next) }); return true; };
|
|
140
|
+
const status = modeStatus(table, flags, state.mode, state.preset);
|
|
141
|
+
/** Opens the list of what re-applying does. Looking at it is what ends the "new features" note. */
|
|
142
|
+
function review() {
|
|
143
|
+
setAsking(null);
|
|
144
|
+
setReviewing(true);
|
|
145
|
+
if (status.added.length)
|
|
146
|
+
presetSeen(table, state).then(setState, () => { });
|
|
147
|
+
}
|
|
148
|
+
async function reapply() {
|
|
149
|
+
setReviewing(false);
|
|
150
|
+
try {
|
|
151
|
+
const next = await reapplyMode(table, state.mode, save);
|
|
152
|
+
if (next) {
|
|
153
|
+
setState(next);
|
|
154
|
+
await reload();
|
|
155
|
+
notify(t('wb.modes.applied', { mode: name(next.mode) }));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
notify(getError(err), true);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function apply(to, keep) {
|
|
163
|
+
setAsking(null);
|
|
164
|
+
try {
|
|
165
|
+
const next = await applyMode(table, flags, state.mode, to, keep, save);
|
|
166
|
+
if (next) {
|
|
167
|
+
setState(next);
|
|
168
|
+
await reload();
|
|
169
|
+
notify(t('wb.modes.applied', { mode: name(to) }));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
notify(getError(err), true);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function choose(to) {
|
|
177
|
+
const plugins = await invoke('plugins_list').catch(() => []);
|
|
178
|
+
const changes = modePlan(table, flags, plugins, state.mode, to, false).changes;
|
|
179
|
+
if (changes > 0)
|
|
180
|
+
setAsking({ to, changes });
|
|
181
|
+
else
|
|
182
|
+
void apply(to, false);
|
|
183
|
+
}
|
|
184
|
+
return _jsx(Section, { title: t('wb.modes.section'), hint: t('wb.modes.sectionHint'), id: "modes", children: table.modes.map(mode => {
|
|
185
|
+
const current = state.mode === mode.id;
|
|
186
|
+
const custom = current && status.custom;
|
|
187
|
+
if (custom)
|
|
188
|
+
return _jsx(Row, { label: name(mode.id), hint: tx(mode.description, undefined, ''), keywords: `mode preset custom ${mode.id}`, wide: reviewing, badge: _jsxs(_Fragment, { children: [_jsx(Badge, { tone: "accent", children: t('wb.modes.custom', { mode: name(mode.id) }) }), mode.recommended && _jsx(Badge, { children: t('wb.modes.recommended') })] }), children: reviewing
|
|
189
|
+
? _jsxs("span", { className: "wbf-ask", role: "alertdialog", children: [t('wb.modes.reapplyHint', { mode: name(mode.id) }), " ", _jsx(ReapplyList, { table: table, status: status }), _jsx(Button, { size: "sm", tone: "primary", onClick: () => void reapply(), children: t('wb.modes.reapply', { mode: name(mode.id) }) }), _jsx(Button, { size: "sm", tone: "ghost", onClick: () => setReviewing(false), children: t('wb.common.cancel') })] })
|
|
190
|
+
: _jsxs("span", { className: "wbf-ask", children: [status.added.length > 0 && _jsx("small", { children: t('wb.modes.grew', { mode: name(mode.id), count: status.added.length }) }), _jsx(Button, { size: "sm", onClick: review, children: status.added.length > 0 ? t('wb.modes.review') : t('wb.modes.reapply', { mode: name(mode.id) }) })] }) }, mode.id);
|
|
191
|
+
return _jsx(Row, { label: name(mode.id), hint: tx(mode.description, undefined, ''), keywords: `mode preset ${mode.id}`, wide: asking?.to === mode.id, badge: _jsxs(_Fragment, { children: [current && _jsx(Badge, { tone: "accent", children: t('wb.modes.current') }), mode.recommended && _jsx(Badge, { children: t('wb.modes.recommended') })] }), children: asking?.to === mode.id
|
|
192
|
+
? _jsxs("span", { className: "wbf-ask", role: "alertdialog", children: [t('wb.modes.keepQuestion'), " ", _jsx("small", { children: t('wb.modes.keepHint', { count: asking.changes }) }), _jsx(Button, { size: "sm", tone: "primary", onClick: () => void apply(mode.id, true), children: t('wb.modes.keep') }), _jsx(Button, { size: "sm", onClick: () => void apply(mode.id, false), children: t('wb.modes.reset', { mode: name(mode.id) }) }), _jsx(Button, { size: "sm", tone: "ghost", onClick: () => setAsking(null), children: t('wb.common.cancel') })] })
|
|
193
|
+
: _jsx(Button, { size: "sm", onClick: () => { setReviewing(false); void choose(mode.id); }, children: t('wb.modes.use') }) }, mode.id);
|
|
194
|
+
}) });
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Opens the app's panel (which shows the first-run screen) when the screen has not been answered.
|
|
198
|
+
* Call it from the app's `ShellSite.start`: it waits until the shell has restored its tabs.
|
|
199
|
+
*/
|
|
200
|
+
export function openOnboardingWhenDue() {
|
|
201
|
+
if (!featureTable()?.modes.length)
|
|
202
|
+
return;
|
|
203
|
+
invoke('mode_get').then(state => {
|
|
204
|
+
cached = state;
|
|
205
|
+
if (state.onboarded)
|
|
206
|
+
return;
|
|
207
|
+
let tries = 0;
|
|
208
|
+
const timer = setInterval(() => {
|
|
209
|
+
tries += 1;
|
|
210
|
+
const api = shell.api;
|
|
211
|
+
if (api && !shell.restoring && api.panels.length > 0) {
|
|
212
|
+
clearInterval(timer);
|
|
213
|
+
shell.openPanel(api.activePanel?.id);
|
|
214
|
+
}
|
|
215
|
+
else if (tries > 80)
|
|
216
|
+
clearInterval(timer);
|
|
217
|
+
}, 250);
|
|
218
|
+
}).catch(() => { });
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The app menu's Mode submenu (the frame's `ShellSite.menu.modes`): the same modes, the same
|
|
222
|
+
* question (keep my changes or take the mode as it is) and the same steps as Settings.
|
|
223
|
+
*/
|
|
224
|
+
export function menuModes() {
|
|
225
|
+
const state = async () => (cached ??= await invoke('mode_get'));
|
|
226
|
+
const flagsNow = async (table) => normalizeFlags(table, await invoke('features_get'));
|
|
227
|
+
const plugins = () => invoke('plugins_list').catch(() => []);
|
|
228
|
+
return {
|
|
229
|
+
list: () => (featureTable()?.modes ?? []).map(mode => ({ id: mode.id, label: tx(mode.name, undefined, mode.id) })),
|
|
230
|
+
current: async () => (featureTable()?.modes.length ? (await state()).mode : null),
|
|
231
|
+
async changes(to) {
|
|
232
|
+
const table = featureTable();
|
|
233
|
+
return table ? modePlan(table, await flagsNow(table), await plugins(), (await state()).mode, to, false).changes : 0;
|
|
234
|
+
},
|
|
235
|
+
async apply(to, keep) {
|
|
236
|
+
const table = featureTable();
|
|
237
|
+
if (!table)
|
|
238
|
+
return;
|
|
239
|
+
const save = async (next) => { await invoke('features_set', { features: sparse(table, next) }); return true; };
|
|
240
|
+
const next = await applyMode(table, await flagsNow(table), (await state()).mode, to, keep, save);
|
|
241
|
+
if (next)
|
|
242
|
+
share(next);
|
|
243
|
+
},
|
|
244
|
+
async status() {
|
|
245
|
+
const table = featureTable();
|
|
246
|
+
const now = table?.modes.length ? await state() : null;
|
|
247
|
+
if (!table || !now)
|
|
248
|
+
return { custom: false, on: [], off: [], added: 0 };
|
|
249
|
+
const status = modeStatus(table, await flagsNow(table), now.mode, now.preset);
|
|
250
|
+
return { custom: status.custom, on: status.on.map(id => flagName(table, id)), off: status.off.map(id => flagName(table, id)), added: status.added.length };
|
|
251
|
+
},
|
|
252
|
+
async reapply() {
|
|
253
|
+
const table = featureTable();
|
|
254
|
+
const mode = (await state()).mode;
|
|
255
|
+
if (!table || !mode)
|
|
256
|
+
return;
|
|
257
|
+
const save = async (next) => { await invoke('features_set', { features: sparse(table, next) }); return true; };
|
|
258
|
+
const next = await reapplyMode(table, mode, save);
|
|
259
|
+
if (next)
|
|
260
|
+
share(next);
|
|
261
|
+
},
|
|
262
|
+
async seen() {
|
|
263
|
+
const table = featureTable();
|
|
264
|
+
const now = await state();
|
|
265
|
+
if (table && now.mode)
|
|
266
|
+
share(await presetSeen(table, now));
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=Modes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modes.js","sourceRoot":"","sources":["../../../../../../shell/src/panel/Modes.tsx"],"names":[],"mappings":"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","sourcesContent":["// Modes: the presets an app's feature table defines (Basic / Advanced / Power User, or whatever the\n// app calls them). `Onboarding` is the first-run screen: three cards, one recommended and\n// preselected; someone who set the app up before modes existed may dismiss it and keep exactly\n// what they have. `ModeSettings` is the same choice later, in Settings, with the question whether\n// the owner's own changes stay. A mode is a starting point: choosing one writes flag values\n// (`features_set`) and remembers the choice (`mode_get/set`); it never takes a switch away, and it\n// is never applied again on its own. When the flags are no longer what the mode starts from (the\n// owner changed features, or an update made the mode larger) the mode reads \"Custom (based on\n// <mode>)\" and one action, \"Re-apply <mode>\", lists what it turns on and off before it does.\nimport { useEffect, useState, type ComponentType } from 'react';\nimport {\n areaFlag, featureWords, modeById, modeFlags, modeStatus, normalizeFlags, sparseFlags as sparse, type FeatureTable, type Flags, type ModeStatus,\n} from '../../../runtime/src/featureTable.ts';\nimport { invoke } from '../frame/bridge.ts';\nimport { useT } from '../frame/hooks.ts';\nimport { tx } from '../frame/i18n.ts';\nimport type { MenuModeStatus, MenuModes } from '../frame/menuModel.ts';\nimport { shell } from '../frame/state.ts';\nimport { Badge, Button, Row, Section } from './controls.tsx';\nimport { modePlan, type PluginFileState } from './featureModel.ts';\nimport { featureTable, flagsChanged, useFlags } from './PluginFeatures.tsx';\nimport { panelSite, type Notify } from './site.ts';\nimport './plugins.css';\n\n/**\n * The onboarding state native code keeps (waybetter-host `modes::ModeState`). `preset`: the mode's\n * flags as they were when it was applied (absent: not known).\n */\nexport type ModeState = { mode: string | null; onboarded: boolean; existing: boolean; preset?: Record<string, boolean> | null };\n\nconst getError = (error: unknown) => error instanceof Error ? error.message : String(error);\nconst listeners = new Set<(state: ModeState) => void>();\nlet cached: ModeState | null = null;\nconst share = (next: ModeState) => { cached = next; for (const listener of listeners) listener(next); };\n/** Tells the mode screens a mode was stored from elsewhere (an imported setup). */\nexport const rememberModeState = share;\n\n/** The mode state, loaded once and shared by the first-run screen and Settings. Null until loaded (or without modes). */\nexport function useModeState(): [ModeState | null, (next: ModeState) => void] {\n const [state, setState] = useState<ModeState | null>(cached);\n useEffect(() => {\n listeners.add(setState);\n if (!cached && featureTable()?.modes.length) invoke<ModeState>('mode_get').then(value => { cached = value; for (const listener of listeners) listener(value); }).catch(() => {});\n return () => { listeners.delete(setState); };\n }, []);\n return [state, next => { cached = next; for (const listener of listeners) listener(next); }];\n}\n\n/**\n * Applies mode `to`: saves its flags (over the owner's own changes, or under them with `keep`),\n * turns off the old plugin files a fresh mode does not have, records the choice and runs the app's\n * own step for the mode.\n */\nasync function applyMode(table: FeatureTable, flags: Flags, from: string | null, to: string, keep: boolean, save: (flags: Flags) => Promise<boolean>): Promise<ModeState | null> {\n const plugins = await invoke<PluginFileState[]>('plugins_list').catch(() => [] as PluginFileState[]);\n const plan = modePlan(table, flags, plugins, from, to, keep);\n if (!await save(plan.flags)) return null;\n for (const file of plan.disable) await invoke('plugin_set_enabled', { file, enabled: false }).catch(() => {});\n if (plan.disable.length) window.dispatchEvent(new CustomEvent('bt-plugins-changed'));\n const state = await invoke<ModeState>('mode_set', { mode: to, onboarded: true, preset: modeById(table, to)?.flags ?? {} });\n flagsChanged();\n await panelSite().features?.onMode?.(to);\n return state;\n}\n\n/** \"Re-apply <mode>\": every flag back to what the mode starts from now. Plugin files are not touched. */\nasync function reapplyMode(table: FeatureTable, mode: string, save: (flags: Flags) => Promise<boolean>): Promise<ModeState | null> {\n if (!modeById(table, mode) || !await save(modeFlags(table, mode))) return null;\n const state = await invoke<ModeState>('mode_set', { mode, onboarded: true, preset: modeById(table, mode)!.flags });\n flagsChanged();\n return state;\n}\n\n/** The \"new features\" note was looked at: the mode's preset of today is the one remembered, so it is said once. */\nconst presetSeen = (table: FeatureTable, state: ModeState) =>\n invoke<ModeState>('mode_set', { mode: state.mode, onboarded: state.onboarded, preset: modeById(table, state.mode)?.flags ?? {} });\n\n/** A flag as the owner knows it: the feature's label, or the area's name for its switch. */\nexport function flagName(table: FeatureTable, id: string): string {\n const area = table.areas.find(entry => areaFlag(entry.id) === id);\n if (area) return area.name;\n const feature = table.features.find(entry => entry.id === id);\n return feature ? tx(featureWords(feature).label, undefined, id) : id;\n}\nconst flagNames = (table: FeatureTable, ids: readonly string[]) => ids.map(id => flagName(table, id)).join(', ');\n\n/** What \"Re-apply\" would do, in words: one line for what turns on, one for what turns off. */\nfunction ReapplyList({ table, status }: { table: FeatureTable; status: ModeStatus }) {\n const t = useT();\n return <>\n {status.on.length > 0 && <small>{t('wb.modes.turnsOn', { list: flagNames(table, status.on) })}</small>}\n {status.off.length > 0 && <small>{t('wb.modes.turnsOff', { list: flagNames(table, status.off) })}</small>}\n </>;\n}\n\nfunction ModeCards({ table, selected, onSelect, Art }: { table: FeatureTable; selected: string | null; onSelect(id: string): void; Art?: ComponentType<{ mode: string }> }) {\n const t = useT();\n return <div className=\"wbm-cards\" role=\"radiogroup\" aria-label={t('wb.modes.section')}>\n {table.modes.map(mode => <button key={mode.id} type=\"button\" role=\"radio\" aria-checked={selected === mode.id} className={`wbm-card ${selected === mode.id ? 'is-on' : ''}`} onClick={() => onSelect(mode.id)}>\n <span className=\"wbm-art\" aria-hidden=\"true\">{Art ? <Art mode={mode.id}/> : <ModeBars index={table.modes.indexOf(mode)} count={table.modes.length}/>}</span>\n <strong>{tx(mode.name, undefined, mode.id)}{mode.recommended && <Badge tone=\"accent\">{t('wb.modes.recommended')}</Badge>}</strong>\n <span>{tx(mode.description, undefined, '')}</span>\n </button>)}\n </div>;\n}\n\n/** The default illustration: how much of the page a mode touches, as filled bars. */\nfunction ModeBars({ index, count }: { index: number; count: number }) {\n return <svg viewBox=\"0 0 96 40\" width=\"96\" height=\"40\">\n {Array.from({ length: count + 2 }, (_, bar) => <rect key={bar} x={8 + bar * (80 / (count + 2))} y={8} width={80 / (count + 2) - 5} height={24} rx={3}\n fill=\"currentColor\" opacity={bar <= index + 1 ? 0.85 : 0.16}/>)}\n </svg>;\n}\n\n/** The first-run screen. `done` runs once a mode was chosen or the screen was dismissed. */\nexport function Onboarding({ state, done, notify }: { state: ModeState; done(next: ModeState): void; notify: Notify }) {\n const t = useT();\n const table = featureTable()!;\n const panel = panelSite();\n const [flags] = useFlags(table, notify);\n const recommended = table.modes.find(mode => mode.recommended)?.id ?? table.modes[0]?.id ?? null;\n // Someone who set the app up before keeps what they have unless they pick a mode themselves.\n const [selected, setSelected] = useState<string | null>(state.existing ? null : recommended);\n const [busy, setBusy] = useState(false);\n const mode = modeById(table, selected);\n const stored = modeById(table, state.mode);\n const custom = !!stored && !!flags && modeStatus(table, flags, stored.id, state.preset).custom;\n\n async function finish(next: () => Promise<ModeState | null>) {\n setBusy(true);\n try { const result = await next(); if (result) done(result); }\n catch (err) { notify(getError(err), true); }\n finally { setBusy(false); }\n }\n const save = async (next: Flags) => { await invoke('features_set', { features: sparse(table, next) }); return true; };\n const start = (keep: boolean) => flags && selected && void finish(() => applyMode(table, flags, state.mode, selected, keep, save));\n const dismiss = () => void finish(() => invoke<ModeState>('mode_set', { mode: state.mode, onboarded: true }));\n\n return <div className=\"wbm-onboarding\" role=\"dialog\" aria-labelledby=\"wbm-title\">\n <img src={panel.brand.logo} alt=\"\" width={44} height={44}/>\n <h1 id=\"wbm-title\">{t('wb.modes.title', { app: panel.brand.name })}</h1>\n <p>{t('wb.modes.lede')}</p>\n <ModeCards table={table} selected={selected} onSelect={setSelected} Art={panel.features?.ModeArt}/>\n {state.existing && <p className=\"wbm-note\">{t('wb.modes.existing', { app: panel.brand.name })}</p>}\n {custom && <p className=\"wbm-note\">{t('wb.modes.custom', { mode: tx(stored!.name, undefined, stored!.id) })}</p>}\n <div className=\"wbm-actions\">\n {state.existing && <Button tone={selected ? 'ghost' : 'primary'} disabled={busy} onClick={dismiss}>{t('wb.modes.keepSetup')}</Button>}\n {mode && state.existing && <Button disabled={busy || !flags} onClick={() => start(true)}>{t('wb.modes.keep')}</Button>}\n {mode && <Button tone=\"primary\" disabled={busy || !flags} onClick={() => start(false)}>{t('wb.modes.start', { mode: tx(mode.name, undefined, mode.id) })}</Button>}\n </div>\n </div>;\n}\n\n/** Settings: the mode in use and the way to another one, keeping or dropping the owner's changes. */\nexport function ModeSettings({ notify }: { notify: Notify }) {\n const table = featureTable();\n return table?.modes.length ? <ModeSettingsOf table={table} notify={notify}/> : null;\n}\n\nfunction ModeSettingsOf({ table, notify }: { table: FeatureTable; notify: Notify }) {\n const t = useT();\n const [state, setState] = useModeState();\n const [flags, , reload] = useFlags(table, notify);\n const [asking, setAsking] = useState<{ to: string; changes: number } | null>(null);\n const [reviewing, setReviewing] = useState(false);\n if (!state || !flags) return null;\n const name = (id: string) => tx(modeById(table, id)?.name ?? id, undefined, id);\n const save = async (next: Flags) => { await invoke('features_set', { features: sparse(table, next) }); return true; };\n const status = modeStatus(table, flags, state.mode, state.preset);\n\n /** Opens the list of what re-applying does. Looking at it is what ends the \"new features\" note. */\n function review() {\n setAsking(null);\n setReviewing(true);\n if (status.added.length) presetSeen(table, state!).then(setState, () => {});\n }\n async function reapply() {\n setReviewing(false);\n try {\n const next = await reapplyMode(table, state!.mode!, save);\n if (next) { setState(next); await reload(); notify(t('wb.modes.applied', { mode: name(next.mode!) })); }\n } catch (err) { notify(getError(err), true); }\n }\n\n async function apply(to: string, keep: boolean) {\n setAsking(null);\n try {\n const next = await applyMode(table, flags!, state!.mode, to, keep, save);\n if (next) { setState(next); await reload(); notify(t('wb.modes.applied', { mode: name(to) })); }\n } catch (err) { notify(getError(err), true); }\n }\n async function choose(to: string) {\n const plugins = await invoke<PluginFileState[]>('plugins_list').catch(() => [] as PluginFileState[]);\n const changes = modePlan(table, flags!, plugins, state!.mode, to, false).changes;\n if (changes > 0) setAsking({ to, changes }); else void apply(to, false);\n }\n\n return <Section title={t('wb.modes.section')} hint={t('wb.modes.sectionHint')} id=\"modes\">\n {table.modes.map(mode => {\n const current = state.mode === mode.id;\n const custom = current && status.custom;\n if (custom) return <Row key={mode.id} label={name(mode.id)} hint={tx(mode.description, undefined, '')} keywords={`mode preset custom ${mode.id}`} wide={reviewing}\n badge={<><Badge tone=\"accent\">{t('wb.modes.custom', { mode: name(mode.id) })}</Badge>{mode.recommended && <Badge>{t('wb.modes.recommended')}</Badge>}</>}>\n {reviewing\n ? <span className=\"wbf-ask\" role=\"alertdialog\">{t('wb.modes.reapplyHint', { mode: name(mode.id) })} <ReapplyList table={table} status={status}/>\n <Button size=\"sm\" tone=\"primary\" onClick={() => void reapply()}>{t('wb.modes.reapply', { mode: name(mode.id) })}</Button>\n <Button size=\"sm\" tone=\"ghost\" onClick={() => setReviewing(false)}>{t('wb.common.cancel')}</Button>\n </span>\n : <span className=\"wbf-ask\">\n {status.added.length > 0 && <small>{t('wb.modes.grew', { mode: name(mode.id), count: status.added.length })}</small>}\n <Button size=\"sm\" onClick={review}>{status.added.length > 0 ? t('wb.modes.review') : t('wb.modes.reapply', { mode: name(mode.id) })}</Button>\n </span>}\n </Row>;\n return <Row key={mode.id} label={name(mode.id)} hint={tx(mode.description, undefined, '')} keywords={`mode preset ${mode.id}`} wide={asking?.to === mode.id}\n badge={<>{current && <Badge tone=\"accent\">{t('wb.modes.current')}</Badge>}{mode.recommended && <Badge>{t('wb.modes.recommended')}</Badge>}</>}>\n {asking?.to === mode.id\n ? <span className=\"wbf-ask\" role=\"alertdialog\">{t('wb.modes.keepQuestion')} <small>{t('wb.modes.keepHint', { count: asking.changes })}</small>\n <Button size=\"sm\" tone=\"primary\" onClick={() => void apply(mode.id, true)}>{t('wb.modes.keep')}</Button>\n <Button size=\"sm\" onClick={() => void apply(mode.id, false)}>{t('wb.modes.reset', { mode: name(mode.id) })}</Button>\n <Button size=\"sm\" tone=\"ghost\" onClick={() => setAsking(null)}>{t('wb.common.cancel')}</Button>\n </span>\n : <Button size=\"sm\" onClick={() => { setReviewing(false); void choose(mode.id); }}>{t('wb.modes.use')}</Button>}\n </Row>;\n })}\n </Section>;\n}\n\n/**\n * Opens the app's panel (which shows the first-run screen) when the screen has not been answered.\n * Call it from the app's `ShellSite.start`: it waits until the shell has restored its tabs.\n */\nexport function openOnboardingWhenDue(): void {\n if (!featureTable()?.modes.length) return;\n invoke<ModeState>('mode_get').then(state => {\n cached = state;\n if (state.onboarded) return;\n let tries = 0;\n const timer = setInterval(() => {\n tries += 1;\n const api = shell.api;\n if (api && !shell.restoring && api.panels.length > 0) { clearInterval(timer); shell.openPanel(api.activePanel?.id); }\n else if (tries > 80) clearInterval(timer);\n }, 250);\n }).catch(() => {});\n}\n\n/**\n * The app menu's Mode submenu (the frame's `ShellSite.menu.modes`): the same modes, the same\n * question (keep my changes or take the mode as it is) and the same steps as Settings.\n */\nexport function menuModes(): MenuModes {\n const state = async () => (cached ??= await invoke<ModeState>('mode_get'));\n const flagsNow = async (table: FeatureTable) => normalizeFlags(table, await invoke<unknown>('features_get'));\n const plugins = () => invoke<PluginFileState[]>('plugins_list').catch(() => [] as PluginFileState[]);\n return {\n list: () => (featureTable()?.modes ?? []).map(mode => ({ id: mode.id, label: tx(mode.name, undefined, mode.id) })),\n current: async () => (featureTable()?.modes.length ? (await state()).mode : null),\n async changes(to) {\n const table = featureTable();\n return table ? modePlan(table, await flagsNow(table), await plugins(), (await state()).mode, to, false).changes : 0;\n },\n async apply(to, keep) {\n const table = featureTable();\n if (!table) return;\n const save = async (next: Flags) => { await invoke('features_set', { features: sparse(table, next) }); return true; };\n const next = await applyMode(table, await flagsNow(table), (await state()).mode, to, keep, save);\n if (next) share(next);\n },\n async status(): Promise<MenuModeStatus> {\n const table = featureTable();\n const now = table?.modes.length ? await state() : null;\n if (!table || !now) return { custom: false, on: [], off: [], added: 0 };\n const status = modeStatus(table, await flagsNow(table), now.mode, now.preset);\n return { custom: status.custom, on: status.on.map(id => flagName(table, id)), off: status.off.map(id => flagName(table, id)), added: status.added.length };\n },\n async reapply() {\n const table = featureTable();\n const mode = (await state()).mode;\n if (!table || !mode) return;\n const save = async (next: Flags) => { await invoke('features_set', { features: sparse(table, next) }); return true; };\n const next = await reapplyMode(table, mode, save);\n if (next) share(next);\n },\n async seen() {\n const table = featureTable();\n const now = await state();\n if (table && now.mode) share(await presetSeen(table, now));\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/** A section's nav icon: a 16x16 stroke path. */
|
|
3
|
+
export function NavIcon({ d }) {
|
|
4
|
+
return _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": "true", children: _jsx("path", { d: d, fill: "none", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=NavIcon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavIcon.js","sourceRoot":"","sources":["../../../../../../shell/src/panel/NavIcon.tsx"],"names":[],"mappings":";AAAA,iDAAiD;AACjD,MAAM,UAAU,OAAO,CAAC,EAAE,CAAC,EAAiB;IAC1C,OAAO,cAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,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;AACjM,CAAC","sourcesContent":["/** A section's nav icon: a 16x16 stroke path. */\nexport function NavIcon({ d }: { d: string }) {\n return <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d={d} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>;\n}\n"]}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// The app's panel: a dockview tab in the shell, laid out for a narrow split pane beside the site
|
|
3
|
+
// first (tab strip) and a side rail from 720px. Night Ink, like the shell chrome. Every control
|
|
4
|
+
// changes the site live through native commands. A settings search filters every settings section
|
|
5
|
+
// at once. The framework brings the sections every app has; the app adds its own (`PanelSite`).
|
|
6
|
+
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
7
|
+
import { DEFAULT_PROFILE } from "../profileModel.js";
|
|
8
|
+
import { setDefaultAccount } from "../frame/accountModel.js";
|
|
9
|
+
import { AccountAvatar, accountLabel, addAccount, openTabs, removeAccount, saveProfiles, signIn, useProfiles } from "../frame/AccountSwitcher.js";
|
|
10
|
+
import { invoke } from "../frame/bridge.js";
|
|
11
|
+
import { useT, useUpdateStatus } from "../frame/hooks.js";
|
|
12
|
+
import { site } from "../frame/site.js";
|
|
13
|
+
import { shell } from "../frame/state.js";
|
|
14
|
+
import { Appearance } from "./Appearance.js";
|
|
15
|
+
import { BackupPanel } from "./BackupPanel.js";
|
|
16
|
+
import { Button, EmptyState, SearchField, SearchProvider } from "./controls.js";
|
|
17
|
+
import { DeveloperPanel } from "./DeveloperPanel.js";
|
|
18
|
+
import { Home } from "./Home.js";
|
|
19
|
+
import { LanguageSettings } from "./LanguageSettings.js";
|
|
20
|
+
import { MakePanel } from "./MakePanel.js";
|
|
21
|
+
import { navEntries } from "./nav.js";
|
|
22
|
+
import { NavIcon } from "./NavIcon.js";
|
|
23
|
+
import { ModeSettings, Onboarding, useModeState } from "./Modes.js";
|
|
24
|
+
import { AreaPlugins } from "./PluginFeatures.js";
|
|
25
|
+
import { ScriptPlugins } from "./Plugins.js";
|
|
26
|
+
import { ShareSetup } from "./ShareSetup.js";
|
|
27
|
+
import { PowerSettings } from "./PowerSettings.js";
|
|
28
|
+
import { AlertSettings, BrowserSettings, MediaSettingsRows } from "./Settings.js";
|
|
29
|
+
import { panelSite } from "./site.js";
|
|
30
|
+
import { StoreSection } from "./StoreSection.js";
|
|
31
|
+
import { ThemeBuilder } from "./ThemeBuilder.js";
|
|
32
|
+
import './panel.css';
|
|
33
|
+
const SEARCH_ICON = _jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("circle", { cx: "10.5", cy: "10.5", r: "6", fill: "none", stroke: "currentColor", strokeWidth: "1.6" }), _jsx("path", { d: "m15 15 5 5", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" })] });
|
|
34
|
+
const getError = (error) => error instanceof Error ? error.message : String(error);
|
|
35
|
+
export default function Panel({ section: requested }) {
|
|
36
|
+
const t = useT();
|
|
37
|
+
const panel = panelSite();
|
|
38
|
+
const entries = navEntries(panel);
|
|
39
|
+
const has = (id) => entries.some(entry => entry.id === id);
|
|
40
|
+
const [section, setSection] = useState(has(requested?.name) ? requested.name : 'home');
|
|
41
|
+
const [query, setQuery] = useState('');
|
|
42
|
+
const go = (id) => { if (has(id)) {
|
|
43
|
+
setSection(id);
|
|
44
|
+
setQuery('');
|
|
45
|
+
} };
|
|
46
|
+
useEffect(() => { if (requested)
|
|
47
|
+
go(requested.name); }, [requested?.nonce]);
|
|
48
|
+
// Sections link to each other (Appearance → Theme Builder).
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const onSection = (event) => go(event.detail);
|
|
51
|
+
window.addEventListener('bt-panel-section', onSection);
|
|
52
|
+
return () => window.removeEventListener('bt-panel-section', onSection);
|
|
53
|
+
}, []);
|
|
54
|
+
const [notice, setNotice] = useState(null);
|
|
55
|
+
const notify = (text, error = false) => setNotice({ id: Date.now(), text, error });
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!notice)
|
|
58
|
+
return;
|
|
59
|
+
const timer = setTimeout(() => setNotice(null), notice.error ? 8000 : 3200);
|
|
60
|
+
return () => clearTimeout(timer);
|
|
61
|
+
}, [notice]);
|
|
62
|
+
const body = useRef(null);
|
|
63
|
+
useEffect(() => { body.current?.scrollTo({ top: 0 }); }, [section]);
|
|
64
|
+
const searching = query.trim().length > 0;
|
|
65
|
+
const entry = entries.find(item => item.id === section);
|
|
66
|
+
const Custom = entry?.component ?? null;
|
|
67
|
+
const props = { notify, openSection: go };
|
|
68
|
+
// The first-run screen stands in for the whole panel until it is answered.
|
|
69
|
+
const [modeState, setModeState] = useModeState();
|
|
70
|
+
if (modeState && !modeState.onboarded)
|
|
71
|
+
return _jsx("div", { className: "btp-root", children: _jsxs("div", { className: "btp is-onboarding", children: [_jsx(Onboarding, { state: modeState, done: setModeState, notify: notify }), notice && _jsx("div", { className: `btp-toast ${notice.error ? 'is-error' : ''}`, role: notice.error ? 'alert' : 'status', onClick: () => setNotice(null), children: notice.text }, notice.id)] }) });
|
|
72
|
+
return _jsx("div", { className: "btp-root", children: _jsxs("div", { className: `btp ${searching ? 'is-searching' : ''}`, children: [_jsxs("header", { className: "btp-head", children: [_jsxs("div", { className: "btp-brand", children: [_jsx("img", { src: panel.brand.logo, alt: "", width: 22, height: 22 }), _jsx("strong", { children: panel.brand.name })] }), _jsx(SearchField, { label: t('wb.panel.search.label'), placeholder: t('wb.panel.search.label'), value: query, onChange: setQuery })] }), _jsx("nav", { className: "btp-nav", "aria-label": t('wb.panel.nav.label'), children: entries.map(item => _jsxs("button", { className: !searching && section === item.id ? 'is-on' : '', "aria-current": !searching && section === item.id ? 'page' : undefined, onClick: () => go(item.id), children: [_jsx(NavIcon, { d: item.icon }), _jsx("span", { children: item.label(t) })] }, item.id)) }), _jsx("main", { className: "btp-body", ref: body, children: _jsx("div", { className: "btp-page", children: searching ? _jsx(SearchResults, { query: query.trim(), ...props, onClear: () => setQuery('') }) : _jsxs(_Fragment, { children: [section !== 'home' && _jsx("h1", { className: "btp-title", children: entry?.label(t) ?? '' }), Custom && _jsx(Custom, { ...props }), !Custom && section === 'home' && _jsx(Home, { go: go }), !Custom && section === 'themes' && _jsx(Appearance, { notify: notify }), !Custom && section === 'builder' && _jsx(ThemeBuilder, { notify: notify }), !Custom && section === 'plugins' && _jsxs(_Fragment, { children: [_jsx(AreaPlugins, { notify: notify }), _jsx(ScriptPlugins, { notify: notify })] }), !Custom && section === 'store' && _jsx(StoreSection, { notify: notify }), !Custom && section === 'make' && _jsx(MakePanel, { ...props }), !Custom && section === 'accounts' && _jsx(Accounts, {}), !Custom && section === 'updates' && _jsx(Updates, {}), !Custom && section === 'power' && _jsx(PowerSettings, { notify: notify }), !Custom && section === 'settings' && _jsx(SettingsSection, { ...props }), !Custom && section === 'backup' && _jsxs(_Fragment, { children: [_jsx(BackupPanel, { notify: notify }), _jsx(ShareSetup, { notify: notify })] }), !Custom && section === 'developer' && _jsx(DeveloperPanel, { notify: notify })] }) }) }), notice && _jsx("div", { className: `btp-toast ${notice.error ? 'is-error' : ''}`, role: notice.error ? 'alert' : 'status', onClick: () => setNotice(null), children: notice.text }, notice.id)] }) });
|
|
73
|
+
}
|
|
74
|
+
/** Settings: the language, links and session, then what the app serves (alerts, the media panel) and adds. */
|
|
75
|
+
function SettingsSection(props) {
|
|
76
|
+
const panel = panelSite();
|
|
77
|
+
return _jsxs(_Fragment, { children: [panel.languages && _jsx(LanguageSettings, {}), _jsx(ModeSettings, { notify: props.notify }), _jsx(BrowserSettings, { notify: props.notify }), panel.settings?.alerts && _jsx(AlertSettings, { notify: props.notify }), site().media && _jsx(MediaSettingsRows, { notify: props.notify }), (panel.settings?.extra ?? []).map((Extra, index) => _jsx(Extra, { ...props }, index))] });
|
|
78
|
+
}
|
|
79
|
+
/** Every settings section at once, each row filtered by the query; an empty state when nothing matches. */
|
|
80
|
+
function SearchResults({ query, notify, openSection, onClear }) {
|
|
81
|
+
const t = useT();
|
|
82
|
+
const panel = panelSite();
|
|
83
|
+
const root = useRef(null);
|
|
84
|
+
const [count, setCount] = useState(null);
|
|
85
|
+
useLayoutEffect(() => {
|
|
86
|
+
const measure = () => setCount(root.current?.querySelectorAll('.bt-row').length ?? 0);
|
|
87
|
+
measure();
|
|
88
|
+
// Sections load their values asynchronously; count again once they have rendered.
|
|
89
|
+
const timer = setTimeout(measure, 250);
|
|
90
|
+
return () => clearTimeout(timer);
|
|
91
|
+
});
|
|
92
|
+
const props = { notify, openSection };
|
|
93
|
+
return _jsxs(SearchProvider, { value: query, children: [_jsxs("h1", { className: "btp-title", children: [t('wb.panel.search.results'), " ", _jsx("span", { className: "btp-title-sub", children: t('wb.panel.search.for', { query }) })] }), _jsxs("div", { ref: root, className: "btp-results", children: [panel.languages && _jsx(LanguageSettings, {}), panel.themes && _jsx(Appearance, { notify: notify }), (panel.sections ?? []).filter(section => section.searchable).map(section => _jsx(section.component, { ...props }, section.id)), _jsx(AreaPlugins, { notify: notify }), _jsx(ScriptPlugins, { notify: notify }), _jsx(ModeSettings, { notify: notify }), _jsx(BrowserSettings, { notify: notify }), site().deck && _jsx(PowerSettings, { notify: notify }), panel.settings?.alerts && _jsx(AlertSettings, { notify: notify }), site().media && _jsx(MediaSettingsRows, { notify: notify }), (panel.settings?.extra ?? []).map((Extra, index) => _jsx(Extra, { ...props }, index))] }), count === 0 && _jsx(EmptyState, { icon: SEARCH_ICON, title: t('wb.panel.search.none'), action: _jsx(Button, { size: "sm", onClick: onClear, children: t('wb.ui.search.clear') }), children: t('wb.panel.search.noneHint') })] });
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------------------------
|
|
96
|
+
// Accounts
|
|
97
|
+
function Accounts() {
|
|
98
|
+
const t = useT();
|
|
99
|
+
const settings = useProfiles();
|
|
100
|
+
const [confirming, setConfirming] = useState(null);
|
|
101
|
+
const [error, setError] = useState('');
|
|
102
|
+
async function run(action) {
|
|
103
|
+
setError('');
|
|
104
|
+
try {
|
|
105
|
+
await action();
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch (failure) {
|
|
109
|
+
setError(getError(failure));
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return _jsxs("section", { className: "btp-group", children: [_jsxs("div", { className: "btp-group-head", children: [_jsx("h2", { children: t('wb.panel.section.accounts') }), _jsx("p", { children: t('wb.panel.accounts.hint') })] }), _jsxs("div", { className: "btp-list", children: [settings.profiles.map(profile => {
|
|
114
|
+
const tabs = openTabs(profile.id);
|
|
115
|
+
const on = profile.id === settings.active;
|
|
116
|
+
const label = accountLabel(profile);
|
|
117
|
+
if (confirming === profile.id)
|
|
118
|
+
return _jsxs("div", { className: "btp-alert", role: "alertdialog", children: [t('wb.panel.accounts.removeConfirm', { name: label.title, tabs }), _jsxs("span", { className: "btp-row-actions", children: [_jsx("button", { className: "btp-btn is-danger", onClick: () => void run(() => removeAccount(settings, profile.id)).then(ok => ok && setConfirming(null)), children: t('wb.common.remove') }), _jsx("button", { className: "btp-btn", onClick: () => setConfirming(null), children: t('wb.common.cancel') })] })] }, profile.id);
|
|
119
|
+
return _jsxs("div", { className: `btp-account ${on ? 'is-on' : ''}`, children: [_jsx(AccountAvatar, { profile: profile, size: 32 }), _jsxs("button", { className: "btp-account-name", title: label.state === 'signed-in' ? t('wb.panel.accounts.openFeed') : t('wb.panel.accounts.signInBeside'), onClick: () => shell.openAccount(profile.id), children: [_jsx("strong", { children: label.title }), _jsxs("small", { children: [label.detail, on ? ` · ${t('wb.panel.accounts.newTabsBadge')}` : '', tabs ? ` · ${t('wb.panel.accounts.openCount', { count: tabs })}` : ''] })] }), label.state !== 'signed-in' && _jsx("button", { className: "btp-btn is-primary", onClick: () => signIn(profile.id), children: t('wb.panel.accounts.signIn') }), _jsx("button", { className: "btp-btn", "aria-pressed": on, disabled: on, title: t('wb.panel.accounts.newTabsTitle'), onClick: () => void run(() => saveProfiles(setDefaultAccount(settings, profile.id))), children: on ? t('wb.panel.accounts.newTabsHere') : t('wb.panel.accounts.useForNewTabs') }), profile.id !== DEFAULT_PROFILE && _jsx("button", { className: "btp-btn", onClick: () => setConfirming(profile.id), children: t('wb.common.remove') })] }, profile.id);
|
|
120
|
+
}), _jsx("button", { className: "btp-link", onClick: () => void run(() => addAccount(settings)), children: t('wb.panel.accounts.add') })] }), error && _jsx("div", { className: "btp-alert", role: "alert", children: error })] });
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------------------------
|
|
123
|
+
// Updates
|
|
124
|
+
const UPDATE_TEXT = {
|
|
125
|
+
idle: 'wb.panel.updates.idle',
|
|
126
|
+
checking: 'wb.panel.updates.checking',
|
|
127
|
+
upToDate: 'wb.panel.updates.upToDate',
|
|
128
|
+
downloading: 'wb.panel.updates.downloading',
|
|
129
|
+
installing: 'wb.panel.updates.installing',
|
|
130
|
+
ready: 'wb.panel.updates.ready',
|
|
131
|
+
error: 'wb.panel.updates.error',
|
|
132
|
+
problem: 'wb.panel.updates.problem',
|
|
133
|
+
};
|
|
134
|
+
function Updates() {
|
|
135
|
+
const t = useT();
|
|
136
|
+
const [status, apply] = useUpdateStatus();
|
|
137
|
+
return _jsxs("section", { className: "btp-group", children: [_jsxs("div", { className: "btp-group-head", children: [_jsx("h2", { children: t('wb.panel.section.updates') }), _jsx("p", { children: t('wb.panel.updates.hint') })] }), _jsxs("div", { className: "btp-card", children: [_jsxs("div", { children: [_jsx("strong", { children: t(UPDATE_TEXT[status.state]) }), 'version' in status && status.version && _jsx("small", { children: t('wb.panel.updates.version', { version: status.version }) }), status.state === 'error' && _jsx("small", { children: status.message }), status.state === 'ready' && status.notes && _jsx("p", { className: "btp-notes", children: status.notes })] }), status.state === 'ready' && _jsx("button", { className: "btp-btn is-primary", onClick: apply, children: t('wb.panel.updates.restart') }), status.state === 'problem' && _jsx("button", { className: "btp-btn", onClick: () => invoke('open_external_url', { url: status.downloadUrl }).catch(() => { }), children: t('wb.panel.updates.download') })] })] });
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=Panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.js","sourceRoot":"","sources":["../../../../../../shell/src/panel/Panel.tsx"],"names":[],"mappings":"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","sourcesContent":["// The app's panel: a dockview tab in the shell, laid out for a narrow split pane beside the site\n// first (tab strip) and a side rail from 720px. Night Ink, like the shell chrome. Every control\n// changes the site live through native commands. A settings search filters every settings section\n// at once. The framework brings the sections every app has; the app adds its own (`PanelSite`).\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { DEFAULT_PROFILE } from '../profileModel.ts';\nimport { setDefaultAccount } from '../frame/accountModel.ts';\nimport { AccountAvatar, accountLabel, addAccount, openTabs, removeAccount, saveProfiles, signIn, useProfiles } from '../frame/AccountSwitcher.tsx';\nimport { invoke } from '../frame/bridge.ts';\nimport { useT, useUpdateStatus } from '../frame/hooks.ts';\nimport { site } from '../frame/site.ts';\nimport { shell } from '../frame/state.ts';\nimport { Appearance } from './Appearance.tsx';\nimport { BackupPanel } from './BackupPanel.tsx';\nimport { Button, EmptyState, SearchField, SearchProvider } from './controls.tsx';\nimport { DeveloperPanel } from './DeveloperPanel.tsx';\nimport { Home } from './Home.tsx';\nimport { LanguageSettings } from './LanguageSettings.tsx';\nimport { MakePanel } from './MakePanel.tsx';\nimport { navEntries } from './nav.ts';\nimport { NavIcon } from './NavIcon.tsx';\nimport { ModeSettings, Onboarding, useModeState } from './Modes.tsx';\nimport { AreaPlugins } from './PluginFeatures.tsx';\nimport { ScriptPlugins } from './Plugins.tsx';\nimport { ShareSetup } from './ShareSetup.tsx';\nimport { PowerSettings } from './PowerSettings.tsx';\nimport { AlertSettings, BrowserSettings, MediaSettingsRows } from './Settings.tsx';\nimport { panelSite, type Notify, type SectionProps } from './site.ts';\nimport { StoreSection } from './StoreSection.tsx';\nimport { ThemeBuilder } from './ThemeBuilder.tsx';\nimport './panel.css';\n\nconst SEARCH_ICON = <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"10.5\" cy=\"10.5\" r=\"6\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\"/><path d=\"m15 15 5 5\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\"/></svg>;\nconst getError = (error: unknown) => error instanceof Error ? error.message : String(error);\n\nexport default function Panel({ section: requested }: { section?: { name: string; nonce: number } }) {\n const t = useT();\n const panel = panelSite();\n const entries = navEntries(panel);\n const has = (id: string | undefined) => entries.some(entry => entry.id === id);\n const [section, setSection] = useState<string>(has(requested?.name) ? requested!.name : 'home');\n const [query, setQuery] = useState('');\n const go = (id: string) => { if (has(id)) { setSection(id); setQuery(''); } };\n useEffect(() => { if (requested) go(requested.name); }, [requested?.nonce]);\n // Sections link to each other (Appearance → Theme Builder).\n useEffect(() => {\n const onSection = (event: Event) => go((event as CustomEvent<string>).detail);\n window.addEventListener('bt-panel-section', onSection);\n return () => window.removeEventListener('bt-panel-section', onSection);\n }, []);\n const [notice, setNotice] = useState<{ id: number; text: string; error: boolean } | null>(null);\n const notify: Notify = (text, error = false) => setNotice({ id: Date.now(), text, error });\n useEffect(() => {\n if (!notice) return;\n const timer = setTimeout(() => setNotice(null), notice.error ? 8000 : 3200);\n return () => clearTimeout(timer);\n }, [notice]);\n const body = useRef<HTMLElement>(null);\n useEffect(() => { body.current?.scrollTo({ top: 0 }); }, [section]);\n const searching = query.trim().length > 0;\n const entry = entries.find(item => item.id === section);\n const Custom = entry?.component ?? null;\n const props: SectionProps = { notify, openSection: go };\n // The first-run screen stands in for the whole panel until it is answered.\n const [modeState, setModeState] = useModeState();\n if (modeState && !modeState.onboarded) return <div className=\"btp-root\"><div className=\"btp is-onboarding\">\n <Onboarding state={modeState} done={setModeState} notify={notify}/>\n {notice && <div key={notice.id} className={`btp-toast ${notice.error ? 'is-error' : ''}`} role={notice.error ? 'alert' : 'status'} onClick={() => setNotice(null)}>{notice.text}</div>}\n </div></div>;\n\n return <div className=\"btp-root\"><div className={`btp ${searching ? 'is-searching' : ''}`}>\n <header className=\"btp-head\">\n <div className=\"btp-brand\"><img src={panel.brand.logo} alt=\"\" width={22} height={22}/><strong>{panel.brand.name}</strong></div>\n <SearchField label={t('wb.panel.search.label')} placeholder={t('wb.panel.search.label')} value={query} onChange={setQuery}/>\n </header>\n <nav className=\"btp-nav\" aria-label={t('wb.panel.nav.label')}>\n {entries.map(item => <button key={item.id} className={!searching && section === item.id ? 'is-on' : ''} aria-current={!searching && section === item.id ? 'page' : undefined}\n onClick={() => go(item.id)}><NavIcon d={item.icon}/><span>{item.label(t)}</span></button>)}\n </nav>\n <main className=\"btp-body\" ref={body}>\n <div className=\"btp-page\">\n {searching ? <SearchResults query={query.trim()} {...props} onClear={() => setQuery('')}/> : <>\n {section !== 'home' && <h1 className=\"btp-title\">{entry?.label(t) ?? ''}</h1>}\n {Custom && <Custom {...props}/>}\n {!Custom && section === 'home' && <Home go={go}/>}\n {!Custom && section === 'themes' && <Appearance notify={notify}/>}\n {!Custom && section === 'builder' && <ThemeBuilder notify={notify}/>}\n {!Custom && section === 'plugins' && <><AreaPlugins notify={notify}/><ScriptPlugins notify={notify}/></>}\n {!Custom && section === 'store' && <StoreSection notify={notify}/>}\n {!Custom && section === 'make' && <MakePanel {...props}/>}\n {!Custom && section === 'accounts' && <Accounts/>}\n {!Custom && section === 'updates' && <Updates/>}\n {!Custom && section === 'power' && <PowerSettings notify={notify}/>}\n {!Custom && section === 'settings' && <SettingsSection {...props}/>}\n {!Custom && section === 'backup' && <><BackupPanel notify={notify}/><ShareSetup notify={notify}/></>}\n {!Custom && section === 'developer' && <DeveloperPanel notify={notify}/>}\n </>}\n </div>\n </main>\n {notice && <div key={notice.id} className={`btp-toast ${notice.error ? 'is-error' : ''}`} role={notice.error ? 'alert' : 'status'} onClick={() => setNotice(null)}>{notice.text}</div>}\n </div></div>;\n}\n\n/** Settings: the language, links and session, then what the app serves (alerts, the media panel) and adds. */\nfunction SettingsSection(props: SectionProps) {\n const panel = panelSite();\n return <>\n {panel.languages && <LanguageSettings/>}\n <ModeSettings notify={props.notify}/>\n <BrowserSettings notify={props.notify}/>\n {panel.settings?.alerts && <AlertSettings notify={props.notify}/>}\n {site().media && <MediaSettingsRows notify={props.notify}/>}\n {(panel.settings?.extra ?? []).map((Extra, index) => <Extra key={index} {...props}/>)}\n </>;\n}\n\n/** Every settings section at once, each row filtered by the query; an empty state when nothing matches. */\nfunction SearchResults({ query, notify, openSection, onClear }: SectionProps & { query: string; onClear(): void }) {\n const t = useT();\n const panel = panelSite();\n const root = useRef<HTMLDivElement>(null);\n const [count, setCount] = useState<number | null>(null);\n useLayoutEffect(() => {\n const measure = () => setCount(root.current?.querySelectorAll('.bt-row').length ?? 0);\n measure();\n // Sections load their values asynchronously; count again once they have rendered.\n const timer = setTimeout(measure, 250);\n return () => clearTimeout(timer);\n });\n const props: SectionProps = { notify, openSection };\n return <SearchProvider value={query}>\n <h1 className=\"btp-title\">{t('wb.panel.search.results')} <span className=\"btp-title-sub\">{t('wb.panel.search.for', { query })}</span></h1>\n <div ref={root} className=\"btp-results\">\n {panel.languages && <LanguageSettings/>}\n {panel.themes && <Appearance notify={notify}/>}\n {(panel.sections ?? []).filter(section => section.searchable).map(section => <section.component key={section.id} {...props}/>)}\n <AreaPlugins notify={notify}/>\n <ScriptPlugins notify={notify}/>\n <ModeSettings notify={notify}/>\n <BrowserSettings notify={notify}/>\n {site().deck && <PowerSettings notify={notify}/>}\n {panel.settings?.alerts && <AlertSettings notify={notify}/>}\n {site().media && <MediaSettingsRows notify={notify}/>}\n {(panel.settings?.extra ?? []).map((Extra, index) => <Extra key={index} {...props}/>)}\n </div>\n {count === 0 && <EmptyState icon={SEARCH_ICON} title={t('wb.panel.search.none')} action={<Button size=\"sm\" onClick={onClear}>{t('wb.ui.search.clear')}</Button>}>\n {t('wb.panel.search.noneHint')}\n </EmptyState>}\n </SearchProvider>;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Accounts\n\nfunction Accounts() {\n const t = useT();\n const settings = useProfiles();\n const [confirming, setConfirming] = useState<string | null>(null);\n const [error, setError] = useState('');\n async function run(action: () => Promise<unknown>) {\n setError('');\n try { await action(); return true; } catch (failure) { setError(getError(failure)); return false; }\n }\n\n return <section className=\"btp-group\">\n <div className=\"btp-group-head\"><h2>{t('wb.panel.section.accounts')}</h2><p>{t('wb.panel.accounts.hint')}</p></div>\n <div className=\"btp-list\">\n {settings.profiles.map(profile => {\n const tabs = openTabs(profile.id);\n const on = profile.id === settings.active;\n const label = accountLabel(profile);\n if (confirming === profile.id) return <div key={profile.id} className=\"btp-alert\" role=\"alertdialog\">\n {t('wb.panel.accounts.removeConfirm', { name: label.title, tabs })}\n <span className=\"btp-row-actions\"><button className=\"btp-btn is-danger\" onClick={() => void run(() => removeAccount(settings, profile.id)).then(ok => ok && setConfirming(null))}>{t('wb.common.remove')}</button><button className=\"btp-btn\" onClick={() => setConfirming(null)}>{t('wb.common.cancel')}</button></span>\n </div>;\n return <div key={profile.id} className={`btp-account ${on ? 'is-on' : ''}`}>\n <AccountAvatar profile={profile} size={32}/>\n <button className=\"btp-account-name\" title={label.state === 'signed-in' ? t('wb.panel.accounts.openFeed') : t('wb.panel.accounts.signInBeside')} onClick={() => shell.openAccount(profile.id)}>\n <strong>{label.title}</strong><small>{label.detail}{on ? ` · ${t('wb.panel.accounts.newTabsBadge')}` : ''}{tabs ? ` · ${t('wb.panel.accounts.openCount', { count: tabs })}` : ''}</small>\n </button>\n {label.state !== 'signed-in' && <button className=\"btp-btn is-primary\" onClick={() => signIn(profile.id)}>{t('wb.panel.accounts.signIn')}</button>}\n <button className=\"btp-btn\" aria-pressed={on} disabled={on} title={t('wb.panel.accounts.newTabsTitle')} onClick={() => void run(() => saveProfiles(setDefaultAccount(settings, profile.id)))}>{on ? t('wb.panel.accounts.newTabsHere') : t('wb.panel.accounts.useForNewTabs')}</button>\n {profile.id !== DEFAULT_PROFILE && <button className=\"btp-btn\" onClick={() => setConfirming(profile.id)}>{t('wb.common.remove')}</button>}\n </div>;\n })}\n <button className=\"btp-link\" onClick={() => void run(() => addAccount(settings))}>{t('wb.panel.accounts.add')}</button>\n </div>\n {error && <div className=\"btp-alert\" role=\"alert\">{error}</div>}\n </section>;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Updates\n\nconst UPDATE_TEXT = {\n idle: 'wb.panel.updates.idle',\n checking: 'wb.panel.updates.checking',\n upToDate: 'wb.panel.updates.upToDate',\n downloading: 'wb.panel.updates.downloading',\n installing: 'wb.panel.updates.installing',\n ready: 'wb.panel.updates.ready',\n error: 'wb.panel.updates.error',\n problem: 'wb.panel.updates.problem',\n} as const;\n\nfunction Updates() {\n const t = useT();\n const [status, apply] = useUpdateStatus();\n return <section className=\"btp-group\">\n <div className=\"btp-group-head\"><h2>{t('wb.panel.section.updates')}</h2><p>{t('wb.panel.updates.hint')}</p></div>\n <div className=\"btp-card\">\n <div><strong>{t(UPDATE_TEXT[status.state])}</strong>\n {'version' in status && status.version && <small>{t('wb.panel.updates.version', { version: status.version })}</small>}\n {status.state === 'error' && <small>{status.message}</small>}\n {status.state === 'ready' && status.notes && <p className=\"btp-notes\">{status.notes}</p>}\n </div>\n {status.state === 'ready' && <button className=\"btp-btn is-primary\" onClick={apply}>{t('wb.panel.updates.restart')}</button>}\n {status.state === 'problem' && <button className=\"btp-btn\" onClick={() => invoke('open_external_url', { url: status.downloadUrl }).catch(() => {})}>{t('wb.panel.updates.download')}</button>}\n </div>\n </section>;\n}\n"]}
|