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.
Files changed (515) hide show
  1. package/README.md +140 -6
  2. package/bin/waybetter.mjs +46 -0
  3. package/build/runtime.mjs +105 -0
  4. package/cli/buildenv.mjs +130 -0
  5. package/cli/dev.mjs +97 -0
  6. package/cli/i18n.mjs +382 -0
  7. package/cli/manifests.mjs +383 -0
  8. package/cli/privacy.mjs +768 -0
  9. package/cli/release.mjs +444 -0
  10. package/cli/remote.mjs +260 -0
  11. package/cli/store.mjs +326 -0
  12. package/cli/strings.mjs +121 -0
  13. package/dist/runtime/column.d.ts +93 -0
  14. package/dist/runtime/column.js +451 -0
  15. package/dist/runtime/column.js.map +1 -0
  16. package/dist/runtime/commandReport.d.ts +19 -0
  17. package/dist/runtime/commandReport.js +47 -0
  18. package/dist/runtime/commandReport.js.map +1 -0
  19. package/dist/runtime/commands.d.ts +72 -0
  20. package/dist/runtime/commands.js +214 -0
  21. package/dist/runtime/commands.js.map +1 -0
  22. package/dist/runtime/devErrors.d.ts +16 -0
  23. package/dist/runtime/devErrors.js +30 -0
  24. package/dist/runtime/devErrors.js.map +1 -0
  25. package/dist/runtime/domHub.d.ts +21 -0
  26. package/dist/runtime/domHub.js +139 -4
  27. package/dist/runtime/domHub.js.map +1 -1
  28. package/dist/runtime/featureModules.d.ts +157 -0
  29. package/dist/runtime/featureModules.js +484 -0
  30. package/dist/runtime/featureModules.js.map +1 -0
  31. package/dist/runtime/featureTable.d.ts +144 -0
  32. package/dist/runtime/featureTable.js +223 -0
  33. package/dist/runtime/featureTable.js.map +1 -0
  34. package/dist/runtime/fonts.d.ts +22 -0
  35. package/dist/runtime/fonts.js +72 -0
  36. package/dist/runtime/fonts.js.map +1 -0
  37. package/dist/runtime/i18n.d.ts +138 -0
  38. package/dist/runtime/i18n.js +614 -0
  39. package/dist/runtime/i18n.js.map +1 -0
  40. package/dist/runtime/i18nCheck.d.ts +30 -0
  41. package/dist/runtime/i18nCheck.js +224 -0
  42. package/dist/runtime/i18nCheck.js.map +1 -0
  43. package/dist/runtime/pageLang.d.ts +8 -0
  44. package/dist/runtime/pageLang.js +64 -0
  45. package/dist/runtime/pageLang.js.map +1 -0
  46. package/dist/runtime/pageStrings.d.ts +35 -0
  47. package/dist/runtime/pageStrings.js +76 -0
  48. package/dist/runtime/pageStrings.js.map +1 -0
  49. package/dist/runtime/panelButton.d.ts +33 -0
  50. package/dist/runtime/panelButton.js +83 -0
  51. package/dist/runtime/panelButton.js.map +1 -0
  52. package/dist/runtime/permissions.d.ts +47 -0
  53. package/dist/runtime/permissions.js +141 -0
  54. package/dist/runtime/permissions.js.map +1 -0
  55. package/dist/runtime/pluginApi.d.ts +51 -2
  56. package/dist/runtime/pluginApi.js +137 -22
  57. package/dist/runtime/pluginApi.js.map +1 -1
  58. package/dist/runtime/pluginI18n.d.ts +29 -0
  59. package/dist/runtime/pluginI18n.js +119 -0
  60. package/dist/runtime/pluginI18n.js.map +1 -0
  61. package/dist/runtime/settingsForm.d.ts +66 -0
  62. package/dist/runtime/settingsForm.js +114 -0
  63. package/dist/runtime/settingsForm.js.map +1 -0
  64. package/dist/runtime/site.d.ts +5 -0
  65. package/dist/runtime/site.js +1 -1
  66. package/dist/runtime/site.js.map +1 -1
  67. package/dist/runtime/siteRuntime.d.ts +144 -0
  68. package/dist/runtime/siteRuntime.js +175 -0
  69. package/dist/runtime/siteRuntime.js.map +1 -0
  70. package/dist/runtime/stringPackHook.d.ts +84 -0
  71. package/dist/runtime/stringPackHook.js +220 -0
  72. package/dist/runtime/stringPackHook.js.map +1 -0
  73. package/dist/runtime/stringPackTranslate.d.ts +59 -0
  74. package/dist/runtime/stringPackTranslate.js +264 -0
  75. package/dist/runtime/stringPackTranslate.js.map +1 -0
  76. package/dist/runtime/stringPacks.d.ts +200 -0
  77. package/dist/runtime/stringPacks.js +474 -0
  78. package/dist/runtime/stringPacks.js.map +1 -0
  79. package/dist/runtime/styles.d.ts +15 -0
  80. package/dist/runtime/styles.js +81 -0
  81. package/dist/runtime/styles.js.map +1 -0
  82. package/dist/runtime/textNet.d.ts +15 -0
  83. package/dist/runtime/textNet.js +131 -0
  84. package/dist/runtime/textNet.js.map +1 -0
  85. package/dist/runtime/themeApi.d.ts +121 -0
  86. package/dist/runtime/themeApi.js +220 -0
  87. package/dist/runtime/themeApi.js.map +1 -0
  88. package/dist/runtime/themeChoice.d.ts +52 -0
  89. package/dist/runtime/themeChoice.js +69 -0
  90. package/dist/runtime/themeChoice.js.map +1 -0
  91. package/dist/runtime/themeComponents.d.ts +435 -0
  92. package/dist/runtime/themeComponents.js +463 -0
  93. package/dist/runtime/themeComponents.js.map +1 -0
  94. package/dist/runtime/themeDecor.d.ts +73 -0
  95. package/dist/runtime/themeDecor.js +131 -0
  96. package/dist/runtime/themeDecor.js.map +1 -0
  97. package/dist/runtime/themeDoctor.d.ts +11 -0
  98. package/dist/runtime/themeDoctor.js +51 -0
  99. package/dist/runtime/themeDoctor.js.map +1 -0
  100. package/dist/runtime/themeIcons.d.ts +130 -0
  101. package/dist/runtime/themeIcons.js +263 -0
  102. package/dist/runtime/themeIcons.js.map +1 -0
  103. package/dist/runtime/themeRuntime.d.ts +100 -0
  104. package/dist/runtime/themeRuntime.js +497 -0
  105. package/dist/runtime/themeRuntime.js.map +1 -0
  106. package/dist/runtime/themeSchema.d.ts +10 -0
  107. package/dist/runtime/themeSchema.js +150 -0
  108. package/dist/runtime/themeSchema.js.map +1 -0
  109. package/dist/runtime/themeSpec.d.ts +259 -0
  110. package/dist/runtime/themeSpec.js +439 -0
  111. package/dist/runtime/themeSpec.js.map +1 -0
  112. package/dist/runtime/themeTokens.d.ts +12 -0
  113. package/dist/runtime/themeTokens.js +14 -6
  114. package/dist/runtime/themeTokens.js.map +1 -1
  115. package/dist/runtime/themeVariants.d.ts +30 -0
  116. package/dist/runtime/themeVariants.js +53 -0
  117. package/dist/runtime/themeVariants.js.map +1 -0
  118. package/dist/runtime/ui.d.ts +192 -0
  119. package/dist/runtime/ui.js +926 -0
  120. package/dist/runtime/ui.js.map +1 -0
  121. package/dist/shell/InstallDialog.d.ts +40 -0
  122. package/dist/shell/InstallDialog.js +170 -0
  123. package/dist/shell/InstallDialog.js.map +1 -0
  124. package/dist/shell/StoreView.d.ts +66 -0
  125. package/dist/shell/StoreView.js +103 -0
  126. package/dist/shell/StoreView.js.map +1 -0
  127. package/dist/shell/addressModel.js.map +1 -1
  128. package/dist/shell/chrome.js.map +1 -1
  129. package/dist/shell/deckModel.d.ts +117 -0
  130. package/dist/shell/deckModel.js +267 -0
  131. package/dist/shell/deckModel.js.map +1 -0
  132. package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
  133. package/dist/shell/frame/AccountSwitcher.js +243 -0
  134. package/dist/shell/frame/AccountSwitcher.js.map +1 -0
  135. package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
  136. package/dist/shell/frame/AddColumnDialog.js +81 -0
  137. package/dist/shell/frame/AddColumnDialog.js.map +1 -0
  138. package/dist/shell/frame/AppMenu.d.ts +21 -0
  139. package/dist/shell/frame/AppMenu.js +642 -0
  140. package/dist/shell/frame/AppMenu.js.map +1 -0
  141. package/dist/shell/frame/CommandPalette.d.ts +7 -0
  142. package/dist/shell/frame/CommandPalette.js +118 -0
  143. package/dist/shell/frame/CommandPalette.js.map +1 -0
  144. package/dist/shell/frame/DeckView.d.ts +13 -0
  145. package/dist/shell/frame/DeckView.js +287 -0
  146. package/dist/shell/frame/DeckView.js.map +1 -0
  147. package/dist/shell/frame/FindBar.d.ts +10 -0
  148. package/dist/shell/frame/FindBar.js +108 -0
  149. package/dist/shell/frame/FindBar.js.map +1 -0
  150. package/dist/shell/frame/MediaPanel.d.ts +8 -0
  151. package/dist/shell/frame/MediaPanel.js +76 -0
  152. package/dist/shell/frame/MediaPanel.js.map +1 -0
  153. package/dist/shell/frame/NewTabPage.d.ts +9 -0
  154. package/dist/shell/frame/NewTabPage.js +71 -0
  155. package/dist/shell/frame/NewTabPage.js.map +1 -0
  156. package/dist/shell/frame/PaneTheme.d.ts +16 -0
  157. package/dist/shell/frame/PaneTheme.js +67 -0
  158. package/dist/shell/frame/PaneTheme.js.map +1 -0
  159. package/dist/shell/frame/ReportDialog.d.ts +3 -0
  160. package/dist/shell/frame/ReportDialog.js +95 -0
  161. package/dist/shell/frame/ReportDialog.js.map +1 -0
  162. package/dist/shell/frame/Shell.d.ts +8 -0
  163. package/dist/shell/frame/Shell.js +1131 -0
  164. package/dist/shell/frame/Shell.js.map +1 -0
  165. package/dist/shell/frame/Titlebar.d.ts +16 -0
  166. package/dist/shell/frame/Titlebar.js +77 -0
  167. package/dist/shell/frame/Titlebar.js.map +1 -0
  168. package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
  169. package/dist/shell/frame/TitlebarExtras.js +202 -0
  170. package/dist/shell/frame/TitlebarExtras.js.map +1 -0
  171. package/dist/shell/frame/WebPanel.d.ts +4 -0
  172. package/dist/shell/frame/WebPanel.js +182 -0
  173. package/dist/shell/frame/WebPanel.js.map +1 -0
  174. package/dist/shell/frame/accountModel.d.ts +49 -0
  175. package/dist/shell/frame/accountModel.js +67 -0
  176. package/dist/shell/frame/accountModel.js.map +1 -0
  177. package/dist/shell/frame/accountSwitcher.css +91 -0
  178. package/dist/shell/frame/appI18n.d.ts +44 -0
  179. package/dist/shell/frame/appI18n.js +64 -0
  180. package/dist/shell/frame/appI18n.js.map +1 -0
  181. package/dist/shell/frame/appMenu.css +121 -0
  182. package/dist/shell/frame/backupModel.d.ts +38 -0
  183. package/dist/shell/frame/backupModel.js +192 -0
  184. package/dist/shell/frame/backupModel.js.map +1 -0
  185. package/dist/shell/frame/boot.d.ts +8 -0
  186. package/dist/shell/frame/boot.js +35 -0
  187. package/dist/shell/frame/boot.js.map +1 -0
  188. package/dist/shell/frame/brand.d.ts +1 -0
  189. package/dist/shell/frame/brand.js +4 -0
  190. package/dist/shell/frame/brand.js.map +1 -0
  191. package/dist/shell/frame/bridge.d.ts +35 -0
  192. package/dist/shell/frame/bridge.js +70 -0
  193. package/dist/shell/frame/bridge.js.map +1 -0
  194. package/dist/shell/frame/chromeTheme.d.ts +29 -0
  195. package/dist/shell/frame/chromeTheme.js +81 -0
  196. package/dist/shell/frame/chromeTheme.js.map +1 -0
  197. package/dist/shell/frame/deck.css +209 -0
  198. package/dist/shell/frame/deckStore.d.ts +89 -0
  199. package/dist/shell/frame/deckStore.js +239 -0
  200. package/dist/shell/frame/deckStore.js.map +1 -0
  201. package/dist/shell/frame/devHost.d.ts +35 -0
  202. package/dist/shell/frame/devHost.js +80 -0
  203. package/dist/shell/frame/devHost.js.map +1 -0
  204. package/dist/shell/frame/devModel.d.ts +7 -0
  205. package/dist/shell/frame/devModel.js +17 -0
  206. package/dist/shell/frame/devModel.js.map +1 -0
  207. package/dist/shell/frame/diag.d.ts +7 -0
  208. package/dist/shell/frame/diag.js +39 -0
  209. package/dist/shell/frame/diag.js.map +1 -0
  210. package/dist/shell/frame/findBar.css +14 -0
  211. package/dist/shell/frame/frameMessages.d.ts +248 -0
  212. package/dist/shell/frame/frameMessages.js +252 -0
  213. package/dist/shell/frame/frameMessages.js.map +1 -0
  214. package/dist/shell/frame/hooks.d.ts +39 -0
  215. package/dist/shell/frame/hooks.js +97 -0
  216. package/dist/shell/frame/hooks.js.map +1 -0
  217. package/dist/shell/frame/i18n.d.ts +27 -0
  218. package/dist/shell/frame/i18n.js +66 -0
  219. package/dist/shell/frame/i18n.js.map +1 -0
  220. package/dist/shell/frame/iconPack.d.ts +11 -0
  221. package/dist/shell/frame/iconPack.js +45 -0
  222. package/dist/shell/frame/iconPack.js.map +1 -0
  223. package/dist/shell/frame/icons.d.ts +71 -0
  224. package/dist/shell/frame/icons.js +75 -0
  225. package/dist/shell/frame/icons.js.map +1 -0
  226. package/dist/shell/frame/index.d.ts +34 -0
  227. package/dist/shell/frame/index.js +43 -0
  228. package/dist/shell/frame/index.js.map +1 -0
  229. package/dist/shell/frame/language.d.ts +58 -0
  230. package/dist/shell/frame/language.js +165 -0
  231. package/dist/shell/frame/language.js.map +1 -0
  232. package/dist/shell/frame/mediaModel.d.ts +34 -0
  233. package/dist/shell/frame/mediaModel.js +53 -0
  234. package/dist/shell/frame/mediaModel.js.map +1 -0
  235. package/dist/shell/frame/menuMessages.en.json +54 -0
  236. package/dist/shell/frame/menuModel.d.ts +277 -0
  237. package/dist/shell/frame/menuModel.js +293 -0
  238. package/dist/shell/frame/menuModel.js.map +1 -0
  239. package/dist/shell/frame/paletteModel.d.ts +139 -0
  240. package/dist/shell/frame/paletteModel.js +112 -0
  241. package/dist/shell/frame/paletteModel.js.map +1 -0
  242. package/dist/shell/frame/paneTheme.css +9 -0
  243. package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
  244. package/dist/shell/frame/pluginCommandStore.js +70 -0
  245. package/dist/shell/frame/pluginCommandStore.js.map +1 -0
  246. package/dist/shell/frame/reportModel.d.ts +52 -0
  247. package/dist/shell/frame/reportModel.js +105 -0
  248. package/dist/shell/frame/reportModel.js.map +1 -0
  249. package/dist/shell/frame/safeStore.d.ts +7 -0
  250. package/dist/shell/frame/safeStore.js +40 -0
  251. package/dist/shell/frame/safeStore.js.map +1 -0
  252. package/dist/shell/frame/searchInput.d.ts +2 -0
  253. package/dist/shell/frame/searchInput.js +11 -0
  254. package/dist/shell/frame/searchInput.js.map +1 -0
  255. package/dist/shell/frame/shell.css +629 -0
  256. package/dist/shell/frame/site.d.ts +206 -0
  257. package/dist/shell/frame/site.js +22 -0
  258. package/dist/shell/frame/site.js.map +1 -0
  259. package/dist/shell/frame/state.d.ts +99 -0
  260. package/dist/shell/frame/state.js +284 -0
  261. package/dist/shell/frame/state.js.map +1 -0
  262. package/dist/shell/frame/syncGate.d.ts +10 -0
  263. package/dist/shell/frame/syncGate.js +36 -0
  264. package/dist/shell/frame/syncGate.js.map +1 -0
  265. package/dist/shell/frame/syncHost.d.ts +35 -0
  266. package/dist/shell/frame/syncHost.js +85 -0
  267. package/dist/shell/frame/syncHost.js.map +1 -0
  268. package/dist/shell/frame/tabStill.d.ts +2 -0
  269. package/dist/shell/frame/tabStill.js +62 -0
  270. package/dist/shell/frame/tabStill.js.map +1 -0
  271. package/dist/shell/frame/themeScopes.d.ts +29 -0
  272. package/dist/shell/frame/themeScopes.js +61 -0
  273. package/dist/shell/frame/themeScopes.js.map +1 -0
  274. package/dist/shell/frame/themeStore.d.ts +99 -0
  275. package/dist/shell/frame/themeStore.js +252 -0
  276. package/dist/shell/frame/themeStore.js.map +1 -0
  277. package/dist/shell/frame/windowBinding.d.ts +2 -0
  278. package/dist/shell/frame/windowBinding.js +7 -0
  279. package/dist/shell/frame/windowBinding.js.map +1 -0
  280. package/dist/shell/frame/workspaceModel.d.ts +82 -0
  281. package/dist/shell/frame/workspaceModel.js +250 -0
  282. package/dist/shell/frame/workspaceModel.js.map +1 -0
  283. package/dist/shell/frame/workspaces.css +84 -0
  284. package/dist/shell/frame/workspaces.d.ts +22 -0
  285. package/dist/shell/frame/workspaces.js +125 -0
  286. package/dist/shell/frame/workspaces.js.map +1 -0
  287. package/dist/shell/frame/zoomStore.d.ts +10 -0
  288. package/dist/shell/frame/zoomStore.js +65 -0
  289. package/dist/shell/frame/zoomStore.js.map +1 -0
  290. package/dist/shell/installController.d.ts +122 -0
  291. package/dist/shell/installController.js +146 -0
  292. package/dist/shell/installController.js.map +1 -0
  293. package/dist/shell/installerMessages.d.ts +30 -0
  294. package/dist/shell/installerMessages.js +36 -0
  295. package/dist/shell/installerMessages.js.map +1 -0
  296. package/dist/shell/linkDrop.js.map +1 -1
  297. package/dist/shell/messages.d.ts +16 -0
  298. package/dist/shell/messages.js +27 -0
  299. package/dist/shell/messages.js.map +1 -0
  300. package/dist/shell/palette.js.map +1 -1
  301. package/dist/shell/paneModel.d.ts +22 -0
  302. package/dist/shell/paneModel.js +24 -1
  303. package/dist/shell/paneModel.js.map +1 -1
  304. package/dist/shell/panel/Appearance.d.ts +8 -0
  305. package/dist/shell/panel/Appearance.js +256 -0
  306. package/dist/shell/panel/Appearance.js.map +1 -0
  307. package/dist/shell/panel/BackupPanel.d.ts +5 -0
  308. package/dist/shell/panel/BackupPanel.js +198 -0
  309. package/dist/shell/panel/BackupPanel.js.map +1 -0
  310. package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
  311. package/dist/shell/panel/DeveloperPanel.js +51 -0
  312. package/dist/shell/panel/DeveloperPanel.js.map +1 -0
  313. package/dist/shell/panel/FeatureToggles.d.ts +13 -0
  314. package/dist/shell/panel/FeatureToggles.js +42 -0
  315. package/dist/shell/panel/FeatureToggles.js.map +1 -0
  316. package/dist/shell/panel/Home.d.ts +3 -0
  317. package/dist/shell/panel/Home.js +23 -0
  318. package/dist/shell/panel/Home.js.map +1 -0
  319. package/dist/shell/panel/IconPackInstall.d.ts +15 -0
  320. package/dist/shell/panel/IconPackInstall.js +41 -0
  321. package/dist/shell/panel/IconPackInstall.js.map +1 -0
  322. package/dist/shell/panel/LanguageSettings.d.ts +1 -0
  323. package/dist/shell/panel/LanguageSettings.js +54 -0
  324. package/dist/shell/panel/LanguageSettings.js.map +1 -0
  325. package/dist/shell/panel/MakePanel.d.ts +3 -0
  326. package/dist/shell/panel/MakePanel.js +237 -0
  327. package/dist/shell/panel/MakePanel.js.map +1 -0
  328. package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
  329. package/dist/shell/panel/MarkdownDoc.js +35 -0
  330. package/dist/shell/panel/MarkdownDoc.js.map +1 -0
  331. package/dist/shell/panel/Modes.d.ts +40 -0
  332. package/dist/shell/panel/Modes.js +270 -0
  333. package/dist/shell/panel/Modes.js.map +1 -0
  334. package/dist/shell/panel/NavIcon.d.ts +4 -0
  335. package/dist/shell/panel/NavIcon.js +6 -0
  336. package/dist/shell/panel/NavIcon.js.map +1 -0
  337. package/dist/shell/panel/Panel.d.ts +7 -0
  338. package/dist/shell/panel/Panel.js +139 -0
  339. package/dist/shell/panel/Panel.js.map +1 -0
  340. package/dist/shell/panel/PluginFeatures.d.ts +24 -0
  341. package/dist/shell/panel/PluginFeatures.js +165 -0
  342. package/dist/shell/panel/PluginFeatures.js.map +1 -0
  343. package/dist/shell/panel/Plugins.d.ts +33 -0
  344. package/dist/shell/panel/Plugins.js +112 -0
  345. package/dist/shell/panel/Plugins.js.map +1 -0
  346. package/dist/shell/panel/PowerSettings.d.ts +4 -0
  347. package/dist/shell/panel/PowerSettings.js +52 -0
  348. package/dist/shell/panel/PowerSettings.js.map +1 -0
  349. package/dist/shell/panel/Settings.d.ts +23 -0
  350. package/dist/shell/panel/Settings.js +116 -0
  351. package/dist/shell/panel/Settings.js.map +1 -0
  352. package/dist/shell/panel/ShareSetup.d.ts +8 -0
  353. package/dist/shell/panel/ShareSetup.js +130 -0
  354. package/dist/shell/panel/ShareSetup.js.map +1 -0
  355. package/dist/shell/panel/StoreSection.d.ts +6 -0
  356. package/dist/shell/panel/StoreSection.js +48 -0
  357. package/dist/shell/panel/StoreSection.js.map +1 -0
  358. package/dist/shell/panel/StringPacks.d.ts +11 -0
  359. package/dist/shell/panel/StringPacks.js +106 -0
  360. package/dist/shell/panel/StringPacks.js.map +1 -0
  361. package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
  362. package/dist/shell/panel/ThemeBuilder.js +205 -0
  363. package/dist/shell/panel/ThemeBuilder.js.map +1 -0
  364. package/dist/shell/panel/backup.css +34 -0
  365. package/dist/shell/panel/builder.css +232 -0
  366. package/dist/shell/panel/builderModel.d.ts +55 -0
  367. package/dist/shell/panel/builderModel.js +95 -0
  368. package/dist/shell/panel/builderModel.js.map +1 -0
  369. package/dist/shell/panel/compare.d.ts +10 -0
  370. package/dist/shell/panel/compare.js +51 -0
  371. package/dist/shell/panel/compare.js.map +1 -0
  372. package/dist/shell/panel/controls.d.ts +135 -0
  373. package/dist/shell/panel/controls.js +213 -0
  374. package/dist/shell/panel/controls.js.map +1 -0
  375. package/dist/shell/panel/featureModel.d.ts +69 -0
  376. package/dist/shell/panel/featureModel.js +79 -0
  377. package/dist/shell/panel/featureModel.js.map +1 -0
  378. package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
  379. package/dist/shell/panel/fonts/FontBrowser.js +189 -0
  380. package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
  381. package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
  382. package/dist/shell/panel/fonts/FontRoles.js +77 -0
  383. package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
  384. package/dist/shell/panel/fonts/catalog.d.ts +37 -0
  385. package/dist/shell/panel/fonts/catalog.js +68 -0
  386. package/dist/shell/panel/fonts/catalog.js.map +1 -0
  387. package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
  388. package/dist/shell/panel/index.d.ts +20 -0
  389. package/dist/shell/panel/index.js +34 -0
  390. package/dist/shell/panel/index.js.map +1 -0
  391. package/dist/shell/panel/languageModel.d.ts +5 -0
  392. package/dist/shell/panel/languageModel.js +7 -0
  393. package/dist/shell/panel/languageModel.js.map +1 -0
  394. package/dist/shell/panel/make.css +72 -0
  395. package/dist/shell/panel/makeModel.d.ts +32 -0
  396. package/dist/shell/panel/makeModel.js +84 -0
  397. package/dist/shell/panel/makeModel.js.map +1 -0
  398. package/dist/shell/panel/markdown.d.ts +46 -0
  399. package/dist/shell/panel/markdown.js +100 -0
  400. package/dist/shell/panel/markdown.js.map +1 -0
  401. package/dist/shell/panel/nav.d.ts +12 -0
  402. package/dist/shell/panel/nav.js +50 -0
  403. package/dist/shell/panel/nav.js.map +1 -0
  404. package/dist/shell/panel/panel.css +401 -0
  405. package/dist/shell/panel/panelMessages.d.ts +763 -0
  406. package/dist/shell/panel/panelMessages.js +767 -0
  407. package/dist/shell/panel/panelMessages.js.map +1 -0
  408. package/dist/shell/panel/plugins.css +59 -0
  409. package/dist/shell/panel/setupModel.d.ts +87 -0
  410. package/dist/shell/panel/setupModel.js +152 -0
  411. package/dist/shell/panel/setupModel.js.map +1 -0
  412. package/dist/shell/panel/site.d.ts +259 -0
  413. package/dist/shell/panel/site.js +25 -0
  414. package/dist/shell/panel/site.js.map +1 -0
  415. package/dist/shell/panel/strings.css +7 -0
  416. package/dist/shell/panel/themes.d.ts +10 -0
  417. package/dist/shell/panel/themes.js +8 -0
  418. package/dist/shell/panel/themes.js.map +1 -0
  419. package/dist/shell/profileModel.d.ts +3 -2
  420. package/dist/shell/profileModel.js +7 -5
  421. package/dist/shell/profileModel.js.map +1 -1
  422. package/dist/shell/store.css +230 -0
  423. package/dist/shell/storeMessages.d.ts +169 -0
  424. package/dist/shell/storeMessages.js +172 -0
  425. package/dist/shell/storeMessages.js.map +1 -0
  426. package/dist/shell/storeModel.d.ts +181 -0
  427. package/dist/shell/storeModel.js +133 -0
  428. package/dist/shell/storeModel.js.map +1 -0
  429. package/dist/shell/stringPacksModel.d.ts +44 -0
  430. package/dist/shell/stringPacksModel.js +94 -0
  431. package/dist/shell/stringPacksModel.js.map +1 -0
  432. package/dist/shell/updateModel.d.ts +2 -1
  433. package/dist/shell/updateModel.js +5 -4
  434. package/dist/shell/updateModel.js.map +1 -1
  435. package/dist/shell/windowControls.d.ts +4 -0
  436. package/dist/shell/windowControls.js +5 -0
  437. package/dist/shell/windowControls.js.map +1 -1
  438. package/i18n-config.schema.json +29 -0
  439. package/i18n-meta.schema.json +26 -0
  440. package/i18n.schema.json +42 -0
  441. package/icons.schema.json +646 -0
  442. package/languages.schema.json +23 -0
  443. package/locales/ar-x-fm.json +11 -0
  444. package/locales/ar.json +1281 -0
  445. package/locales/bg.json +1280 -0
  446. package/locales/bn.json +1280 -0
  447. package/locales/ca.json +1280 -0
  448. package/locales/cs.json +1280 -0
  449. package/locales/da.json +1280 -0
  450. package/locales/de.json +1280 -0
  451. package/locales/el.json +1280 -0
  452. package/locales/en-GB.json +27 -0
  453. package/locales/en.json +1280 -0
  454. package/locales/en.meta.json +51 -0
  455. package/locales/es.json +1280 -0
  456. package/locales/eu.json +1280 -0
  457. package/locales/fa.json +1281 -0
  458. package/locales/fi.json +1280 -0
  459. package/locales/fil.json +1280 -0
  460. package/locales/fr.json +1280 -0
  461. package/locales/ga.json +1280 -0
  462. package/locales/gl.json +1280 -0
  463. package/locales/gu.json +1280 -0
  464. package/locales/ha.json +1280 -0
  465. package/locales/he.json +1281 -0
  466. package/locales/hi.json +1280 -0
  467. package/locales/hr.json +1280 -0
  468. package/locales/hu.json +1279 -0
  469. package/locales/id.json +1280 -0
  470. package/locales/ig.json +1280 -0
  471. package/locales/it.json +1280 -0
  472. package/locales/ja.json +1280 -0
  473. package/locales/kn.json +1280 -0
  474. package/locales/ko.json +1280 -0
  475. package/locales/mr.json +1280 -0
  476. package/locales/ms.json +1280 -0
  477. package/locales/nb.json +1280 -0
  478. package/locales/nl.json +1280 -0
  479. package/locales/pl.json +1280 -0
  480. package/locales/pt.json +1280 -0
  481. package/locales/ro.json +1280 -0
  482. package/locales/ru.json +1280 -0
  483. package/locales/sk.json +1280 -0
  484. package/locales/sr.json +1280 -0
  485. package/locales/sv.json +1280 -0
  486. package/locales/ta.json +1280 -0
  487. package/locales/th.json +1280 -0
  488. package/locales/tr.json +1280 -0
  489. package/locales/uk.json +1280 -0
  490. package/locales/ur.json +1281 -0
  491. package/locales/vi.json +1280 -0
  492. package/locales/yo.json +1280 -0
  493. package/locales/zh-Hans.json +1280 -0
  494. package/locales/zh-Hant.json +1280 -0
  495. package/package.json +139 -5
  496. package/store-catalog.schema.json +65 -0
  497. package/theme.schema.json +4659 -0
  498. package/windows/installer.nsi +926 -0
  499. package/windows/languages/Basque.nsh +28 -0
  500. package/windows/languages/Catalan.nsh +28 -0
  501. package/windows/languages/Croatian.nsh +28 -0
  502. package/windows/languages/Czech.nsh +28 -0
  503. package/windows/languages/Danish.nsh +28 -0
  504. package/windows/languages/Finnish.nsh +28 -0
  505. package/windows/languages/Galician.nsh +28 -0
  506. package/windows/languages/Greek.nsh +28 -0
  507. package/windows/languages/Hungarian.nsh +28 -0
  508. package/windows/languages/Indonesian.nsh +28 -0
  509. package/windows/languages/Irish.nsh +28 -0
  510. package/windows/languages/Malay.nsh +28 -0
  511. package/windows/languages/Polish.nsh +28 -0
  512. package/windows/languages/Romanian.nsh +28 -0
  513. package/windows/languages/Serbian.nsh +28 -0
  514. package/windows/languages/Slovak.nsh +28 -0
  515. 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,3 @@
1
+ export declare function ReportDialog({ onClose }: {
2
+ onClose(): void;
3
+ }): import("react").ReactPortal;
@@ -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;