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,287 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useLayoutEffect, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import { COLUMN_GAP, COLUMN_WIDTHS, isSourcePage, layoutColumns, pageOf, unreadTotal } from "../deckModel.js";
5
+ import { tabProfile } from "../profileModel.js";
6
+ import { AccountAvatar, accountName } from "./AccountSwitcher.js";
7
+ import { AddColumnDialog } from "./AddColumnDialog.js";
8
+ import { invoke } from "./bridge.js";
9
+ import { addColumn, bump, columnSourceUrl, configureColumn, deckById, decks, patchColumn, removeColumn, shiftColumn, } from "./deckStore.js";
10
+ import { FindBar } from "./FindBar.js";
11
+ import { useDecks, useProfiles, useT } from "./hooks.js";
12
+ import { Icon } from "./icons.js";
13
+ import { site } from "./site.js";
14
+ import { scheduleSync, setOverlay, shell, tabAction } from "./state.js";
15
+ import { useTabStill } from "./tabStill.js";
16
+ import './deck.css';
17
+ const emitDecks = () => window.dispatchEvent(new CustomEvent('bt-decks'));
18
+ const unreadLabel = (count) => (count > 999 ? '999+' : String(count));
19
+ const deckSite = () => site().deck;
20
+ /** Width of the columns row minus an open compose dock. */
21
+ function columnsWidth(total, deckId) {
22
+ const compose = deckSite().compose;
23
+ return compose && decks.compose.has(deckId) ? Math.max(0, total - compose.width - COLUMN_GAP) : total;
24
+ }
25
+ /** The row width each deck was last laid out at (for paging from keys). */
26
+ const rowWidths = new Map();
27
+ /** Focuses a column: it becomes the deck's focused column, its page is shown and its webview gets the keys. */
28
+ export function focusColumn(deckId, columnId, giveKeys = true) {
29
+ const deck = deckById(deckId);
30
+ const column = deck?.columns.find(c => c.id === columnId);
31
+ if (!deck || !column)
32
+ return;
33
+ decks.focus.set(deckId, columnId);
34
+ const width = columnsWidth(rowWidths.get(deckId) ?? window.innerWidth, deckId);
35
+ decks.page.set(deckId, pageOf(width, deck.columns, columnId, { maxVisible: decks.settings.maxVisible }, decks.page.get(deckId)));
36
+ emitDecks();
37
+ scheduleSync();
38
+ if (giveKeys)
39
+ requestAnimationFrame(() => tabAction(column.tabId, 'focus'));
40
+ }
41
+ export function runDeckCommand(deckId, command) {
42
+ const deck = deckById(deckId);
43
+ if (!deck)
44
+ return;
45
+ const focused = deck.columns.find(c => c.id === decks.focus.get(deckId)) ?? deck.columns[0];
46
+ const index = focused ? deck.columns.indexOf(focused) : -1;
47
+ const digit = /^column-([1-9])$/.exec(command);
48
+ if (digit) {
49
+ const target = deck.columns[Number(digit[1]) - 1];
50
+ if (target)
51
+ focusColumn(deckId, target.id);
52
+ return;
53
+ }
54
+ switch (command) {
55
+ case 'column-prev':
56
+ case 'column-next': {
57
+ const target = deck.columns[Math.min(deck.columns.length - 1, Math.max(0, index + (command === 'column-next' ? 1 : -1)))];
58
+ if (target)
59
+ focusColumn(deckId, target.id);
60
+ break;
61
+ }
62
+ case 'column-page-prev':
63
+ case 'column-page-next': {
64
+ const width = columnsWidth(rowWidths.get(deckId) ?? window.innerWidth, deckId);
65
+ const layout = layoutColumns(width, deck.columns, (decks.page.get(deckId) ?? 0) + (command === 'column-page-next' ? 1 : -1), { maxVisible: decks.settings.maxVisible });
66
+ decks.page.set(deckId, layout.page);
67
+ const first = layout.visible[0];
68
+ if (first)
69
+ decks.focus.set(deckId, first.id);
70
+ emitDecks();
71
+ scheduleSync();
72
+ break;
73
+ }
74
+ case 'column-mark-read':
75
+ if (focused)
76
+ bump(focused, 'read');
77
+ break;
78
+ case 'column-jump-unread':
79
+ if (focused)
80
+ bump(focused, 'jump');
81
+ break;
82
+ case 'deck-compose':
83
+ toggleCompose(deckId, focused?.profile);
84
+ break;
85
+ }
86
+ }
87
+ export function toggleCompose(deckId, profile) {
88
+ if (!deckSite().compose)
89
+ return;
90
+ if (decks.compose.has(deckId))
91
+ decks.compose.delete(deckId);
92
+ else
93
+ decks.compose.set(deckId, { profile: tabProfile(shell.profiles, profile ?? shell.profiles.active).id });
94
+ emitDecks();
95
+ scheduleSync();
96
+ }
97
+ // ---------------------------------------------------------------------------------------------
98
+ // Popovers (the shell rises above the tab webviews, or hides them, while one is open)
99
+ function Popover({ anchor, onClose, children, width = 260, label }) {
100
+ useEffect(() => {
101
+ setOverlay(1);
102
+ const onKey = (event) => { if (event.key === 'Escape') {
103
+ event.stopPropagation();
104
+ onClose();
105
+ } };
106
+ window.addEventListener('keydown', onKey, true);
107
+ window.addEventListener('blur', onClose);
108
+ return () => { setOverlay(-1); window.removeEventListener('keydown', onKey, true); window.removeEventListener('blur', onClose); };
109
+ }, []);
110
+ const left = Math.max(8, Math.min(anchor.right - width, window.innerWidth - width - 8));
111
+ const style = { top: anchor.bottom + 6, left, width };
112
+ return createPortal(_jsx("div", { className: "bt-menu-backdrop", onMouseDown: onClose, onContextMenu: event => { event.preventDefault(); onClose(); }, children: _jsx("div", { className: "bt-menu bt-deck-pop bt-pop bt-pop--right", role: "dialog", "aria-label": label, style: style, onMouseDown: event => event.stopPropagation(), children: children }) }), document.body);
113
+ }
114
+ function FilterPopover({ deckId, column, anchor, onClose }) {
115
+ const tr = useT();
116
+ const [text, setText] = useState('');
117
+ const input = useRef(null);
118
+ useEffect(() => { input.current?.focus(); }, []);
119
+ const filters = column.filters;
120
+ const set = (patch) => patchColumn(deckId, column.id, { filters: { ...filters, ...patch } });
121
+ const add = () => {
122
+ const terms = text.split(/\n|,(?![^/]*\/[a-z]*$)/).map(t => t.trim()).filter(Boolean).filter(t => t.length <= 200);
123
+ if (!terms.length)
124
+ return;
125
+ set({ terms: [...filters.terms, ...terms.filter(t => !filters.terms.includes(t))].slice(0, 32) });
126
+ setText('');
127
+ };
128
+ const toggle = (key, label, hint) => _jsxs("label", { className: "bt-deck-check", children: [_jsx("input", { type: "checkbox", checked: filters[key], onChange: event => set({ [key]: event.target.checked }) }), _jsx("span", { className: "bt-deck-check-box", "aria-hidden": "true", children: _jsx(Icon, { name: "check" }) }), _jsxs("span", { className: "bt-deck-check-text", children: [_jsx("strong", { children: label }), _jsx("small", { children: hint })] })] });
129
+ return _jsxs(Popover, { anchor: anchor, onClose: onClose, width: 300, label: tr('wb.deck.filters.label'), children: [_jsxs("div", { className: "bt-deck-pop-head", children: [_jsx(Icon, { name: "filter" }), _jsx("strong", { children: tr('wb.deck.filters') }), _jsx("span", { children: deckSite().title(column.source, column.title).title })] }), _jsxs("div", { className: "bt-deck-terms", children: [_jsx("input", { ref: input, className: "bt-deck-input", spellCheck: false, placeholder: tr('wb.deck.mutePlaceholder'), "aria-label": tr('wb.deck.muteLabel'), value: text, onChange: event => setText(event.target.value), onKeyDown: event => { if (event.key === 'Enter') {
130
+ event.preventDefault();
131
+ add();
132
+ } } }), filters.terms.length > 0 && _jsx("div", { className: "bt-deck-chips", children: filters.terms.map(term => _jsxs("span", { className: `bt-deck-chip ${/^\/.+\/[imsu]*$/.test(term) ? 'is-regex' : ''}`, children: [_jsx("span", { children: term }), _jsx("button", { type: "button", "aria-label": tr('wb.common.removeItem', { item: term }), onClick: () => set({ terms: filters.terms.filter(t => t !== term) }), children: _jsx(Icon, { name: "close" }) })] }, term)) })] }), _jsx("hr", {}), toggle('hideReplies', tr('wb.deck.hideReplies'), tr('wb.deck.hideRepliesHint')), toggle('hideReposts', tr('wb.deck.hideReposts'), tr('wb.deck.hideRepostsHint')), toggle('mediaOnly', tr('wb.deck.mediaOnly'), tr('wb.deck.mediaOnlyHint'))] });
133
+ }
134
+ function ColumnMenu({ deck, column, anchor, onClose, onRemove }) {
135
+ const tr = useT();
136
+ const index = deck.columns.indexOf(column);
137
+ const item = (label, icon, action, disabled = false, keys) => _jsxs("button", { role: "menuitem", disabled: disabled, onClick: () => { onClose(); action(); }, children: [_jsx(Icon, { name: icon }), _jsx("span", { className: "bt-menu-label", children: label }), keys && _jsx("span", { className: "bt-menu-keys", children: keys })] });
138
+ const url = decks.runtime.get(column.tabId)?.url ?? columnSourceUrl(column.source) ?? '';
139
+ return _jsxs(Popover, { anchor: anchor, onClose: onClose, width: 236, label: tr('wb.deck.menu'), children: [item(tr('wb.deck.markRead'), 'check', () => bump(column, 'read'), false, 'Alt R'), item(tr('wb.deck.jumpUnread'), 'history', () => bump(column, 'jump'), false, 'Alt U'), _jsx("hr", {}), item(tr('wb.deck.moveLeft'), 'back', () => shiftColumn(deck.id, column.id, -1), index <= 0), item(tr('wb.deck.moveRight'), 'forward', () => shiftColumn(deck.id, column.id, 1), index >= deck.columns.length - 1), _jsxs("div", { className: "bt-deck-widths", role: "group", "aria-label": tr('wb.deck.widthLabel'), children: [_jsx("span", { children: tr('wb.deck.width') }), COLUMN_WIDTHS.map(width => _jsx("button", { type: "button", "aria-pressed": column.width === width, className: column.width === width ? 'is-on' : '', onClick: () => { patchColumn(deck.id, column.id, { width }); scheduleSync(); }, children: width }, width))] }), _jsx("hr", {}), item(tr('wb.shell.menu.duplicate'), 'duplicate', () => addColumn(deck.id, { profile: column.profile, source: column.source, filters: column.filters, flags: column.flags, width: column.width }, column.id)), item(tr('wb.deck.openAsTab'), 'external', () => shell.openUrl(url, column.profile), !url), _jsx("hr", {}), item(tr('wb.deck.remove'), 'trash', onRemove)] });
140
+ }
141
+ // ---------------------------------------------------------------------------------------------
142
+ // One column: header strip + the placeholder its webview covers
143
+ function ColumnView({ deck, column, x, width, focused, number }) {
144
+ const tr = useT();
145
+ const profiles = useProfiles();
146
+ const body = useRef(null);
147
+ const still = useTabStill(column.tabId);
148
+ const [menu, setMenu] = useState(null);
149
+ const [leaving, setLeaving] = useState(false);
150
+ // Find in page for this column (Ctrl+F pressed in it): the find bar lies over the column's header.
151
+ const [finding, setFinding] = useState(false);
152
+ useEffect(() => {
153
+ const openFindBar = (event) => { if (event.detail === column.tabId)
154
+ setFinding(true); };
155
+ window.addEventListener('bt-find', openFindBar);
156
+ return () => window.removeEventListener('bt-find', openFindBar);
157
+ }, [column.tabId]);
158
+ const spec = deckSite();
159
+ const runtime = decks.runtime.get(column.tabId);
160
+ const account = tabProfile(profiles, column.profile);
161
+ const type = spec.kinds.find(kind => kind.kind === column.source.kind);
162
+ const { title, detail } = spec.title(column.source, column.title);
163
+ const source = columnSourceUrl(column.source);
164
+ const away = !!(runtime?.url && source && !isSourcePage(runtime.url, source));
165
+ const unread = runtime?.unread ?? 0;
166
+ const filtered = column.filters.terms.length > 0 || column.filters.hideReplies || column.filters.hideReposts || column.filters.mediaOnly;
167
+ const pageTitle = spec.pageTitle ?? ((text) => text);
168
+ useLayoutEffect(() => {
169
+ const el = body.current;
170
+ if (!el || leaving)
171
+ return;
172
+ shell.placeholders.set(column.tabId, el);
173
+ const observer = new ResizeObserver(scheduleSync);
174
+ observer.observe(el);
175
+ scheduleSync();
176
+ return () => {
177
+ observer.disconnect();
178
+ if (shell.placeholders.get(column.tabId) === el)
179
+ shell.placeholders.delete(column.tabId);
180
+ scheduleSync();
181
+ };
182
+ }, [column.tabId, leaving]);
183
+ // Position changes (paging, reordering, width) move the webview with the placeholder.
184
+ useEffect(() => { scheduleSync(); }, [x, width]);
185
+ const open = (kind) => (event) => setMenu(menu?.kind === kind ? null : { kind, anchor: event.currentTarget.getBoundingClientRect() });
186
+ const remove = () => {
187
+ setLeaving(true);
188
+ // The webview hides at once (no placeholder); the header slides out, then the column goes.
189
+ const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
190
+ setTimeout(() => removeColumn(deck.id, column.id), reduced ? 0 : 180);
191
+ };
192
+ return _jsxs("section", { className: `bt-col${focused ? ' is-focused' : ''}${leaving ? ' is-leaving' : ''}`, style: { left: x, width, ['--bt-col-account']: account.color }, "aria-label": tr('wb.deck.columnLabel', { title }), onMouseDown: () => { if (!focused)
193
+ focusColumn(deck.id, column.id, false); }, children: [_jsxs("header", { className: "bt-col-head", children: [away
194
+ ? _jsx("button", { className: "bt-col-glyph bt-col-back", title: tr('wb.deck.backTo', { title }), "aria-label": tr('wb.deck.backTo', { title }), onClick: () => { if (source)
195
+ invoke('tab_navigate', { id: column.tabId, url: source }).catch(() => { }); }, children: _jsx(Icon, { name: "back" }) })
196
+ : _jsx("span", { className: "bt-col-glyph", "aria-hidden": "true", children: _jsx(Icon, { name: type?.icon ?? 'globe' }) }), _jsxs("div", { className: "bt-col-titles", title: detail ? `${title} · ${detail}` : title, children: [_jsx("strong", { children: title }), _jsx("span", { children: away ? (pageTitle(runtime?.title ?? '') || tr('wb.deck.viewingPost')) : detail ?? `${site().accounts.handlePrefix}${account.account?.handle ?? account.name}` })] }), unread > 0 && _jsx("button", { className: "bt-col-unread", title: tr('wb.deck.jumpUnreadTitle'), "aria-label": tr('wb.deck.unreadLabel', { count: unread }), onClick: () => bump(column, 'jump'), children: unreadLabel(unread) }), _jsx("span", { className: "bt-col-fill" }), _jsx("span", { className: "bt-col-account", title: tr('wb.shell.tab.account', { name: accountName(account) }), children: _jsx(AccountAvatar, { profile: account, size: 20 }) }), _jsx("button", { className: `bt-icon bt-col-btn${filtered ? ' is-active' : ''}`, title: tr('wb.deck.filters'), "aria-label": tr('wb.deck.filters'), "aria-haspopup": "dialog", "aria-expanded": menu?.kind === 'filters', onClick: open('filters'), children: _jsx(Icon, { name: "filter" }) }), _jsx("button", { className: "bt-icon bt-col-btn", title: tr('wb.deck.menu'), "aria-label": tr('wb.deck.menu'), "aria-haspopup": "menu", "aria-expanded": menu?.kind === 'menu', onClick: open('menu'), children: _jsx("svg", { className: "bt-glyph", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M6 12h.01M12 12h.01M18 12h.01", strokeWidth: "3" }) }) }), number <= 9 && _jsx("span", { className: "bt-col-key", "aria-hidden": "true", children: number }), runtime?.loading && _jsx("span", { className: "bt-col-progress", "aria-label": tr('wb.common.loading') }), finding && _jsx("div", { className: "bt-col-find", children: _jsx(FindBar, { tabId: column.tabId, url: runtime?.url ?? source ?? '', onClose: () => setFinding(false) }) })] }), _jsx("div", { className: "bt-col-body", ref: body, children: still
197
+ ? _jsx("div", { className: "bt-still", "aria-hidden": "true", style: { backgroundImage: `url("${still}")` } })
198
+ : _jsxs("div", { className: "bt-col-hint", children: [_jsx("span", { className: "bt-spinner", "aria-hidden": "true" }), _jsx("span", { children: title })] }) }), menu?.kind === 'filters' && _jsx(FilterPopover, { deckId: deck.id, column: column, anchor: menu.anchor, onClose: () => setMenu(null) }), menu?.kind === 'menu' && _jsx(ColumnMenu, { deck: deck, column: column, anchor: menu.anchor, onClose: () => setMenu(null), onRemove: remove })] });
199
+ }
200
+ // ---------------------------------------------------------------------------------------------
201
+ function EmptyDeck({ deck, onAdd }) {
202
+ const tr = useT();
203
+ const profiles = useProfiles();
204
+ const ids = profiles.profiles.map(p => p.id);
205
+ const ordered = [profiles.active, ...ids.filter(id => id !== profiles.active)];
206
+ return _jsxs("div", { className: "bt-deck-empty bt-rise", children: [_jsx("div", { className: "bt-deck-empty-art", "aria-hidden": "true", children: [0, 1, 2, 3].map(i => _jsx("span", { style: { animationDelay: `${i * 70}ms` } }, i)) }), _jsx("h2", { children: tr('wb.deck.title') }), _jsx("p", { children: tr('wb.deck.emptyHint', { site: site().name }) }), _jsxs("div", { className: "bt-deck-empty-actions", children: [_jsxs("button", { className: "bt-deck-primary", onClick: onAdd, children: [_jsx(Icon, { name: "plus" }), tr('wb.deck.addColumn')] }), (deckSite().presets ?? []).map(preset => {
207
+ const needs = preset.needsTwoAccounts && ids.length < 2 ? preset.needsTwoAccounts() : undefined;
208
+ return _jsx("button", { className: "bt-deck-secondary", disabled: !!needs, title: needs, onClick: () => { for (const column of preset.columns(ordered))
209
+ addColumn(deck.id, column); }, children: preset.label() }, preset.id);
210
+ })] }), _jsxs("p", { className: "bt-deck-empty-keys", children: [_jsxs("span", { children: [_jsx("span", { className: "bt-kbd", children: "[" }), _jsx("span", { className: "bt-kbd", children: "]" }), " ", tr('wb.deck.key.columns')] }), _jsxs("span", { children: [_jsx("span", { className: "bt-kbd", children: "Alt" }), _jsx("span", { className: "bt-kbd", children: "1\u20139" }), " ", tr('wb.deck.key.jump')] }), _jsxs("span", { children: [_jsx("span", { className: "bt-kbd", children: "Alt" }), _jsx("span", { className: "bt-kbd", children: "R" }), " ", tr('wb.deck.key.read')] }), deckSite().compose && _jsxs("span", { children: [_jsx("span", { className: "bt-kbd", children: "Ctrl" }), _jsx("span", { className: "bt-kbd", children: "Alt" }), _jsx("span", { className: "bt-kbd", children: "N" }), " ", tr('wb.deck.key.post')] })] })] });
211
+ }
212
+ export function DeckView(props) {
213
+ const tr = useT();
214
+ useDecks();
215
+ const deckId = props.params.deckId;
216
+ const row = useRef(null);
217
+ const [rowWidth, setRowWidth] = useState(0);
218
+ const [adding, setAdding] = useState(false);
219
+ const deck = deckById(deckId);
220
+ const compose = deckSite().compose;
221
+ useLayoutEffect(() => {
222
+ const el = row.current;
223
+ if (!el)
224
+ return;
225
+ const measure = () => { const w = Math.floor(el.getBoundingClientRect().width); rowWidths.set(deckId, w); setRowWidth(w); };
226
+ const observer = new ResizeObserver(measure);
227
+ observer.observe(el);
228
+ measure();
229
+ return () => observer.disconnect();
230
+ }, [deckId, !!deck]);
231
+ useEffect(() => {
232
+ const visibility = props.api.onDidVisibilityChange(scheduleSync);
233
+ // The palette's "Add column…" opens this deck's dialog.
234
+ const add = (event) => { if (event.detail === deckId)
235
+ setAdding(true); };
236
+ window.addEventListener('bt-deck-add', add);
237
+ return () => { visibility.dispose(); window.removeEventListener('bt-deck-add', add); };
238
+ }, [props.api, deckId]);
239
+ // Every column gets its config before its webview exists (no flash of the site's chrome);
240
+ // unmounting the deck forgets what was sent, so reopening it configures again.
241
+ useEffect(() => {
242
+ if (!deck)
243
+ return;
244
+ for (const column of deck.columns) {
245
+ if (decks.sent.has(column.tabId))
246
+ continue;
247
+ void configureColumn(column, true).then(() => { decks.ready.add(column.tabId); scheduleSync(); });
248
+ }
249
+ });
250
+ useEffect(() => () => {
251
+ for (const column of deckById(deckId)?.columns ?? []) {
252
+ decks.sent.delete(column.tabId);
253
+ decks.ready.delete(column.tabId);
254
+ }
255
+ }, [deckId]);
256
+ if (!deck) {
257
+ return _jsx("div", { className: "bt-deck", children: _jsxs("div", { className: "bt-deck-empty", children: [_jsx("h2", { children: tr('wb.deck.gone') }), _jsx("p", { children: tr('wb.deck.goneHint') }), _jsx("button", { className: "bt-deck-secondary", onClick: () => props.api.close(), children: tr('wb.shell.menu.close') })] }) });
258
+ }
259
+ const settings = decks.settings;
260
+ const width = columnsWidth(rowWidth, deck.id);
261
+ const layout = layoutColumns(width, deck.columns, decks.page.get(deck.id) ?? 0, { maxVisible: settings.maxVisible });
262
+ const focusedId = decks.focus.get(deck.id) ?? layout.visible[0]?.id;
263
+ const total = unreadTotal(new Map(deck.columns.map(c => [c.tabId, decks.runtime.get(c.tabId)?.unread ?? 0])), deck.columns);
264
+ const setPage = (page) => { decks.page.set(deck.id, page); emitDecks(); scheduleSync(); };
265
+ const composing = compose && decks.compose.get(deck.id);
266
+ const overLimit = deck.columns.length > settings.maxVisible;
267
+ return _jsxs("div", { className: "bt-deck", children: [_jsxs("div", { className: "bt-deck-bar", children: [_jsx("span", { className: "bt-deck-mark", "aria-hidden": "true", children: _jsx(Icon, { name: "grid" }) }), _jsx("strong", { className: "bt-deck-name", children: deck.name }), _jsx("span", { className: "bt-deck-count", children: tr('wb.deck.columnCount', { count: deck.columns.length }) }), total > 0 && _jsx("span", { className: "bt-deck-total", title: tr('wb.deck.unreadTitle'), children: tr('wb.deck.newCount', { count: unreadLabel(total) }) }), _jsx("span", { className: "bt-deck-fill" }), layout.pages > 1 && _jsxs("div", { className: "bt-deck-pager", role: "group", "aria-label": tr('wb.deck.pages'), children: [_jsx("button", { className: "bt-icon", title: tr('wb.deck.prevTitle'), "aria-label": tr('wb.deck.prev'), disabled: layout.page === 0, onClick: () => setPage(layout.page - 1), children: _jsx(Icon, { name: "back" }) }), Array.from({ length: layout.pages }, (_, i) => _jsx("button", { className: `bt-deck-dot${i === layout.page ? ' is-on' : ''}`, "aria-label": tr('wb.deck.page', { n: i + 1 }), "aria-current": i === layout.page ? 'page' : undefined, onClick: () => setPage(i) }, i)), _jsx("button", { className: "bt-icon", title: tr('wb.deck.nextTitle'), "aria-label": tr('wb.deck.next'), disabled: layout.page >= layout.pages - 1, onClick: () => setPage(layout.page + 1), children: _jsx(Icon, { name: "forward" }) })] }), overLimit && _jsx("span", { className: "bt-deck-memory", title: tr('wb.deck.memoryTitle', { count: decks.settings.maxVisible, site: site().name }), children: tr('wb.deck.onScreen', { visible: layout.visible.length, total: deck.columns.length }) }), _jsxs("button", { className: "bt-deck-action", onClick: () => setAdding(true), title: tr('wb.deck.addColumn'), children: [_jsx(Icon, { name: "plus" }), _jsx("span", { children: tr('wb.deck.column') })] }), compose && _jsxs("button", { className: `bt-deck-action${composing ? ' is-on' : ''}`, onClick: () => toggleCompose(deck.id, deck.columns.find(c => c.id === focusedId)?.profile), title: tr('wb.deck.postTitle'), "aria-pressed": !!composing, children: [_jsx(Icon, { name: "edit" }), _jsx("span", { children: tr('wb.deck.post') })] }), _jsx("button", { className: "bt-icon bt-deck-settings", title: tr('wb.deck.settings'), "aria-label": tr('wb.deck.settings'), onClick: () => shell.openPanelSection('power'), children: _jsx(Icon, { name: "settings" }) })] }), _jsxs("div", { className: "bt-deck-row", ref: row, children: [deck.columns.length === 0
268
+ ? _jsx(EmptyDeck, { deck: deck, onAdd: () => setAdding(true) })
269
+ : layout.visible.map(place => {
270
+ const column = deck.columns.find(c => c.id === place.id);
271
+ return _jsx(ColumnView, { deck: deck, column: column, x: place.x, width: place.width, focused: column.id === focusedId, number: deck.columns.indexOf(column) + 1 }, column.id);
272
+ }), compose && composing && _jsx(compose.Dock, { deckId: deck.id, left: width + COLUMN_GAP })] }), adding && _jsx(AddColumnDialog, { deck: deck, onClose: () => setAdding(false), onAdd: input => {
273
+ const column = addColumn(deck.id, input);
274
+ void configureColumn(column, true).then(() => { decks.ready.add(column.tabId); focusColumn(deck.id, column.id, false); });
275
+ setAdding(false);
276
+ } })] });
277
+ }
278
+ /** Unread total of a deck on its dockview tab. */
279
+ export function DeckTabBadge({ deckId }) {
280
+ useDecks();
281
+ const deck = deckById(deckId);
282
+ if (!deck)
283
+ return null;
284
+ const total = unreadTotal(new Map(deck.columns.map(c => [c.tabId, decks.runtime.get(c.tabId)?.unread ?? 0])), deck.columns);
285
+ return total > 0 ? _jsx("span", { className: "bt-tab-unread", "aria-label": `${total} unread`, children: unreadLabel(total) }) : null;
286
+ }
287
+ //# sourceMappingURL=DeckView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeckView.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/DeckView.tsx"],"names":[],"mappings":"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","sourcesContent":["// Decks: site columns side by side in one shell tab (dockview component `deck`). The shell draws\n// the deck bar and a header per column; each column's body is a placeholder that a real site tab\n// webview (its own account profile) covers, laid out by state.ts. Paging, not pixel scrolling: a\n// page holds as many whole columns as fit; the others are parked off-page. Every request and every\n// action in a column is the site's own; the shell only navigates, focuses and configures columns\n// (native `column_configure`). The kinds of columns are the site's (`site.deck`).\n\nimport type { IDockviewPanelProps } from 'dockview';\nimport { useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { COLUMN_GAP, COLUMN_WIDTHS, isSourcePage, layoutColumns, pageOf, unreadTotal } from '../deckModel.ts';\nimport { tabProfile } from '../profileModel.ts';\nimport { AccountAvatar, accountName } from './AccountSwitcher.tsx';\nimport { AddColumnDialog } from './AddColumnDialog.tsx';\nimport { invoke } from './bridge.ts';\nimport {\n addColumn, bump, columnSourceUrl, configureColumn, deckById, decks, patchColumn, removeColumn, shiftColumn,\n type Deck, type DeckColumn,\n} from './deckStore.ts';\nimport { FindBar } from './FindBar.tsx';\nimport { useDecks, useProfiles, useT } from './hooks.ts';\nimport { Icon, type IconName } from './icons.tsx';\nimport { site } from './site.ts';\nimport { scheduleSync, setOverlay, shell, tabAction, type DeckParams } from './state.ts';\nimport { useTabStill } from './tabStill.ts';\nimport './deck.css';\n\nconst emitDecks = () => window.dispatchEvent(new CustomEvent('bt-decks'));\nconst unreadLabel = (count: number) => (count > 999 ? '999+' : String(count));\nconst deckSite = () => site().deck!;\n\n/** Width of the columns row minus an open compose dock. */\nfunction columnsWidth(total: number, deckId: string) {\n const compose = deckSite().compose;\n return compose && decks.compose.has(deckId) ? Math.max(0, total - compose.width - COLUMN_GAP) : total;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Deck commands (keys, palette, column menus)\n\nexport type DeckCommand =\n | 'column-prev' | 'column-next' | 'column-page-prev' | 'column-page-next' | 'column-mark-read' | 'column-jump-unread' | 'deck-compose'\n | `column-${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`;\n\n/** The row width each deck was last laid out at (for paging from keys). */\nconst rowWidths = new Map<string, number>();\n\n/** Focuses a column: it becomes the deck's focused column, its page is shown and its webview gets the keys. */\nexport function focusColumn(deckId: string, columnId: string, giveKeys = true) {\n const deck = deckById(deckId);\n const column = deck?.columns.find(c => c.id === columnId);\n if (!deck || !column) return;\n decks.focus.set(deckId, columnId);\n const width = columnsWidth(rowWidths.get(deckId) ?? window.innerWidth, deckId);\n decks.page.set(deckId, pageOf(width, deck.columns, columnId, { maxVisible: decks.settings.maxVisible }, decks.page.get(deckId)));\n emitDecks();\n scheduleSync();\n if (giveKeys) requestAnimationFrame(() => tabAction(column.tabId, 'focus'));\n}\n\nexport function runDeckCommand(deckId: string, command: string) {\n const deck = deckById(deckId);\n if (!deck) return;\n const focused = deck.columns.find(c => c.id === decks.focus.get(deckId)) ?? deck.columns[0];\n const index = focused ? deck.columns.indexOf(focused) : -1;\n const digit = /^column-([1-9])$/.exec(command);\n if (digit) { const target = deck.columns[Number(digit[1]) - 1]; if (target) focusColumn(deckId, target.id); return; }\n switch (command) {\n case 'column-prev': case 'column-next': {\n const target = deck.columns[Math.min(deck.columns.length - 1, Math.max(0, index + (command === 'column-next' ? 1 : -1)))];\n if (target) focusColumn(deckId, target.id);\n break;\n }\n case 'column-page-prev': case 'column-page-next': {\n const width = columnsWidth(rowWidths.get(deckId) ?? window.innerWidth, deckId);\n const layout = layoutColumns(width, deck.columns, (decks.page.get(deckId) ?? 0) + (command === 'column-page-next' ? 1 : -1), { maxVisible: decks.settings.maxVisible });\n decks.page.set(deckId, layout.page);\n const first = layout.visible[0];\n if (first) decks.focus.set(deckId, first.id);\n emitDecks();\n scheduleSync();\n break;\n }\n case 'column-mark-read': if (focused) bump(focused, 'read'); break;\n case 'column-jump-unread': if (focused) bump(focused, 'jump'); break;\n case 'deck-compose': toggleCompose(deckId, focused?.profile); break;\n }\n}\n\nexport function toggleCompose(deckId: string, profile?: string) {\n if (!deckSite().compose) return;\n if (decks.compose.has(deckId)) decks.compose.delete(deckId);\n else decks.compose.set(deckId, { profile: tabProfile(shell.profiles, profile ?? shell.profiles.active).id });\n emitDecks();\n scheduleSync();\n}\n\n// ---------------------------------------------------------------------------------------------\n// Popovers (the shell rises above the tab webviews, or hides them, while one is open)\n\nfunction Popover({ anchor, onClose, children, width = 260, label }: { anchor: DOMRect; onClose(): void; children: ReactNode; width?: number; label: string }) {\n useEffect(() => {\n setOverlay(1);\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') { event.stopPropagation(); onClose(); } };\n window.addEventListener('keydown', onKey, true);\n window.addEventListener('blur', onClose);\n return () => { setOverlay(-1); window.removeEventListener('keydown', onKey, true); window.removeEventListener('blur', onClose); };\n }, []);\n const left = Math.max(8, Math.min(anchor.right - width, window.innerWidth - width - 8));\n const style: CSSProperties = { top: anchor.bottom + 6, left, width };\n return createPortal(<div className=\"bt-menu-backdrop\" onMouseDown={onClose} onContextMenu={event => { event.preventDefault(); onClose(); }}>\n <div className=\"bt-menu bt-deck-pop bt-pop bt-pop--right\" role=\"dialog\" aria-label={label} style={style} onMouseDown={event => event.stopPropagation()}>{children}</div>\n </div>, document.body);\n}\n\nfunction FilterPopover({ deckId, column, anchor, onClose }: { deckId: string; column: DeckColumn; anchor: DOMRect; onClose(): void }) {\n const tr = useT();\n const [text, setText] = useState('');\n const input = useRef<HTMLInputElement>(null);\n useEffect(() => { input.current?.focus(); }, []);\n const filters = column.filters;\n const set = (patch: Partial<DeckColumn['filters']>) => patchColumn(deckId, column.id, { filters: { ...filters, ...patch } });\n const add = () => {\n const terms = text.split(/\\n|,(?![^/]*\\/[a-z]*$)/).map(t => t.trim()).filter(Boolean).filter(t => t.length <= 200);\n if (!terms.length) return;\n set({ terms: [...filters.terms, ...terms.filter(t => !filters.terms.includes(t))].slice(0, 32) });\n setText('');\n };\n const toggle = (key: 'hideReplies' | 'hideReposts' | 'mediaOnly', label: string, hint: string) =>\n <label className=\"bt-deck-check\"><input type=\"checkbox\" checked={filters[key]} onChange={event => set({ [key]: event.target.checked })}/>\n <span className=\"bt-deck-check-box\" aria-hidden=\"true\"><Icon name=\"check\"/></span><span className=\"bt-deck-check-text\"><strong>{label}</strong><small>{hint}</small></span></label>;\n return <Popover anchor={anchor} onClose={onClose} width={300} label={tr('wb.deck.filters.label')}>\n <div className=\"bt-deck-pop-head\"><Icon name=\"filter\"/><strong>{tr('wb.deck.filters')}</strong><span>{deckSite().title(column.source, column.title).title}</span></div>\n <div className=\"bt-deck-terms\">\n <input ref={input} className=\"bt-deck-input\" spellCheck={false} placeholder={tr('wb.deck.mutePlaceholder')} aria-label={tr('wb.deck.muteLabel')} value={text}\n onChange={event => setText(event.target.value)} onKeyDown={event => { if (event.key === 'Enter') { event.preventDefault(); add(); } }}/>\n {filters.terms.length > 0 && <div className=\"bt-deck-chips\">\n {filters.terms.map(term => <span key={term} className={`bt-deck-chip ${/^\\/.+\\/[imsu]*$/.test(term) ? 'is-regex' : ''}`}>\n <span>{term}</span><button type=\"button\" aria-label={tr('wb.common.removeItem', { item: term })} onClick={() => set({ terms: filters.terms.filter(t => t !== term) })}><Icon name=\"close\"/></button></span>)}\n </div>}\n </div>\n <hr/>\n {toggle('hideReplies', tr('wb.deck.hideReplies'), tr('wb.deck.hideRepliesHint'))}\n {toggle('hideReposts', tr('wb.deck.hideReposts'), tr('wb.deck.hideRepostsHint'))}\n {toggle('mediaOnly', tr('wb.deck.mediaOnly'), tr('wb.deck.mediaOnlyHint'))}\n </Popover>;\n}\n\nfunction ColumnMenu({ deck, column, anchor, onClose, onRemove }: { deck: Deck; column: DeckColumn; anchor: DOMRect; onClose(): void; onRemove(): void }) {\n const tr = useT();\n const index = deck.columns.indexOf(column);\n const item = (label: string, icon: IconName, action: () => void, disabled = false, keys?: string) =>\n <button role=\"menuitem\" disabled={disabled} onClick={() => { onClose(); action(); }}>\n <Icon name={icon}/><span className=\"bt-menu-label\">{label}</span>{keys && <span className=\"bt-menu-keys\">{keys}</span>}</button>;\n const url = decks.runtime.get(column.tabId)?.url ?? columnSourceUrl(column.source) ?? '';\n return <Popover anchor={anchor} onClose={onClose} width={236} label={tr('wb.deck.menu')}>\n {item(tr('wb.deck.markRead'), 'check', () => bump(column, 'read'), false, 'Alt R')}\n {item(tr('wb.deck.jumpUnread'), 'history', () => bump(column, 'jump'), false, 'Alt U')}\n <hr/>\n {item(tr('wb.deck.moveLeft'), 'back', () => shiftColumn(deck.id, column.id, -1), index <= 0)}\n {item(tr('wb.deck.moveRight'), 'forward', () => shiftColumn(deck.id, column.id, 1), index >= deck.columns.length - 1)}\n <div className=\"bt-deck-widths\" role=\"group\" aria-label={tr('wb.deck.widthLabel')}>\n <span>{tr('wb.deck.width')}</span>\n {COLUMN_WIDTHS.map(width => <button key={width} type=\"button\" aria-pressed={column.width === width} className={column.width === width ? 'is-on' : ''}\n onClick={() => { patchColumn(deck.id, column.id, { width }); scheduleSync(); }}>{width}</button>)}\n </div>\n <hr/>\n {item(tr('wb.shell.menu.duplicate'), 'duplicate', () => addColumn(deck.id, { profile: column.profile, source: column.source, filters: column.filters, flags: column.flags, width: column.width }, column.id))}\n {item(tr('wb.deck.openAsTab'), 'external', () => shell.openUrl(url, column.profile), !url)}\n <hr/>\n {item(tr('wb.deck.remove'), 'trash', onRemove)}\n </Popover>;\n}\n\n// ---------------------------------------------------------------------------------------------\n// One column: header strip + the placeholder its webview covers\n\nfunction ColumnView({ deck, column, x, width, focused, number }: { deck: Deck; column: DeckColumn; x: number; width: number; focused: boolean; number: number }) {\n const tr = useT();\n const profiles = useProfiles();\n const body = useRef<HTMLDivElement>(null);\n const still = useTabStill(column.tabId);\n const [menu, setMenu] = useState<null | { kind: 'filters' | 'menu'; anchor: DOMRect }>(null);\n const [leaving, setLeaving] = useState(false);\n // Find in page for this column (Ctrl+F pressed in it): the find bar lies over the column's header.\n const [finding, setFinding] = useState(false);\n useEffect(() => {\n const openFindBar = (event: Event) => { if ((event as CustomEvent<string>).detail === column.tabId) setFinding(true); };\n window.addEventListener('bt-find', openFindBar);\n return () => window.removeEventListener('bt-find', openFindBar);\n }, [column.tabId]);\n const spec = deckSite();\n const runtime = decks.runtime.get(column.tabId);\n const account = tabProfile(profiles, column.profile);\n const type = spec.kinds.find(kind => kind.kind === column.source.kind);\n const { title, detail } = spec.title(column.source, column.title);\n const source = columnSourceUrl(column.source);\n const away = !!(runtime?.url && source && !isSourcePage(runtime.url, source));\n const unread = runtime?.unread ?? 0;\n const filtered = column.filters.terms.length > 0 || column.filters.hideReplies || column.filters.hideReposts || column.filters.mediaOnly;\n const pageTitle = spec.pageTitle ?? ((text: string) => text);\n\n useLayoutEffect(() => {\n const el = body.current;\n if (!el || leaving) return;\n shell.placeholders.set(column.tabId, el);\n const observer = new ResizeObserver(scheduleSync);\n observer.observe(el);\n scheduleSync();\n return () => {\n observer.disconnect();\n if (shell.placeholders.get(column.tabId) === el) shell.placeholders.delete(column.tabId);\n scheduleSync();\n };\n }, [column.tabId, leaving]);\n // Position changes (paging, reordering, width) move the webview with the placeholder.\n useEffect(() => { scheduleSync(); }, [x, width]);\n\n const open = (kind: 'filters' | 'menu') => (event: ReactMouseEvent<HTMLButtonElement>) =>\n setMenu(menu?.kind === kind ? null : { kind, anchor: event.currentTarget.getBoundingClientRect() });\n const remove = () => {\n setLeaving(true);\n // The webview hides at once (no placeholder); the header slides out, then the column goes.\n const reduced = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n setTimeout(() => removeColumn(deck.id, column.id), reduced ? 0 : 180);\n };\n\n return <section className={`bt-col${focused ? ' is-focused' : ''}${leaving ? ' is-leaving' : ''}`} style={{ left: x, width, ['--bt-col-account' as string]: account.color }}\n aria-label={tr('wb.deck.columnLabel', { title })} onMouseDown={() => { if (!focused) focusColumn(deck.id, column.id, false); }}>\n <header className=\"bt-col-head\">\n {away\n ? <button className=\"bt-col-glyph bt-col-back\" title={tr('wb.deck.backTo', { title })} aria-label={tr('wb.deck.backTo', { title })}\n onClick={() => { if (source) invoke('tab_navigate', { id: column.tabId, url: source }).catch(() => {}); }}><Icon name=\"back\"/></button>\n : <span className=\"bt-col-glyph\" aria-hidden=\"true\"><Icon name={type?.icon ?? 'globe'}/></span>}\n <div className=\"bt-col-titles\" title={detail ? `${title} · ${detail}` : title}>\n <strong>{title}</strong>\n <span>{away ? (pageTitle(runtime?.title ?? '') || tr('wb.deck.viewingPost')) : detail ?? `${site().accounts.handlePrefix}${account.account?.handle ?? account.name}`}</span>\n </div>\n {unread > 0 && <button className=\"bt-col-unread\" title={tr('wb.deck.jumpUnreadTitle')} aria-label={tr('wb.deck.unreadLabel', { count: unread })} onClick={() => bump(column, 'jump')}>{unreadLabel(unread)}</button>}\n <span className=\"bt-col-fill\"/>\n <span className=\"bt-col-account\" title={tr('wb.shell.tab.account', { name: accountName(account) })}><AccountAvatar profile={account} size={20}/></span>\n <button className={`bt-icon bt-col-btn${filtered ? ' is-active' : ''}`} title={tr('wb.deck.filters')} aria-label={tr('wb.deck.filters')} aria-haspopup=\"dialog\" aria-expanded={menu?.kind === 'filters'} onClick={open('filters')}><Icon name=\"filter\"/></button>\n <button className=\"bt-icon bt-col-btn\" title={tr('wb.deck.menu')} aria-label={tr('wb.deck.menu')} aria-haspopup=\"menu\" aria-expanded={menu?.kind === 'menu'} onClick={open('menu')}>\n <svg className=\"bt-glyph\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M6 12h.01M12 12h.01M18 12h.01\" strokeWidth=\"3\"/></svg></button>\n {number <= 9 && <span className=\"bt-col-key\" aria-hidden=\"true\">{number}</span>}\n {runtime?.loading && <span className=\"bt-col-progress\" aria-label={tr('wb.common.loading')}/>}\n {finding && <div className=\"bt-col-find\"><FindBar tabId={column.tabId} url={runtime?.url ?? source ?? ''} onClose={() => setFinding(false)}/></div>}\n </header>\n <div className=\"bt-col-body\" ref={body}>\n {still\n ? <div className=\"bt-still\" aria-hidden=\"true\" style={{ backgroundImage: `url(\"${still}\")` }}/>\n : <div className=\"bt-col-hint\"><span className=\"bt-spinner\" aria-hidden=\"true\"/><span>{title}</span></div>}\n </div>\n {menu?.kind === 'filters' && <FilterPopover deckId={deck.id} column={column} anchor={menu.anchor} onClose={() => setMenu(null)}/>}\n {menu?.kind === 'menu' && <ColumnMenu deck={deck} column={column} anchor={menu.anchor} onClose={() => setMenu(null)} onRemove={remove}/>}\n </section>;\n}\n\n// ---------------------------------------------------------------------------------------------\n\nfunction EmptyDeck({ deck, onAdd }: { deck: Deck; onAdd(): void }) {\n const tr = useT();\n const profiles = useProfiles();\n const ids = profiles.profiles.map(p => p.id);\n const ordered = [profiles.active, ...ids.filter(id => id !== profiles.active)];\n return <div className=\"bt-deck-empty bt-rise\">\n <div className=\"bt-deck-empty-art\" aria-hidden=\"true\">{[0, 1, 2, 3].map(i => <span key={i} style={{ animationDelay: `${i * 70}ms` }}/>)}</div>\n <h2>{tr('wb.deck.title')}</h2>\n <p>{tr('wb.deck.emptyHint', { site: site().name })}</p>\n <div className=\"bt-deck-empty-actions\">\n <button className=\"bt-deck-primary\" onClick={onAdd}><Icon name=\"plus\"/>{tr('wb.deck.addColumn')}</button>\n {(deckSite().presets ?? []).map(preset => {\n const needs = preset.needsTwoAccounts && ids.length < 2 ? preset.needsTwoAccounts() : undefined;\n return <button key={preset.id} className=\"bt-deck-secondary\" disabled={!!needs} title={needs}\n onClick={() => { for (const column of preset.columns(ordered)) addColumn(deck.id, column); }}>{preset.label()}</button>;\n })}\n </div>\n <p className=\"bt-deck-empty-keys\">\n <span><span className=\"bt-kbd\">[</span><span className=\"bt-kbd\">]</span> {tr('wb.deck.key.columns')}</span>\n <span><span className=\"bt-kbd\">Alt</span><span className=\"bt-kbd\">1–9</span> {tr('wb.deck.key.jump')}</span>\n <span><span className=\"bt-kbd\">Alt</span><span className=\"bt-kbd\">R</span> {tr('wb.deck.key.read')}</span>\n {deckSite().compose && <span><span className=\"bt-kbd\">Ctrl</span><span className=\"bt-kbd\">Alt</span><span className=\"bt-kbd\">N</span> {tr('wb.deck.key.post')}</span>}\n </p>\n </div>;\n}\n\nexport function DeckView(props: IDockviewPanelProps<DeckParams>) {\n const tr = useT();\n useDecks();\n const deckId = props.params.deckId;\n const row = useRef<HTMLDivElement>(null);\n const [rowWidth, setRowWidth] = useState(0);\n const [adding, setAdding] = useState(false);\n const deck = deckById(deckId);\n const compose = deckSite().compose;\n\n useLayoutEffect(() => {\n const el = row.current;\n if (!el) return;\n const measure = () => { const w = Math.floor(el.getBoundingClientRect().width); rowWidths.set(deckId, w); setRowWidth(w); };\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n measure();\n return () => observer.disconnect();\n }, [deckId, !!deck]);\n useEffect(() => {\n const visibility = props.api.onDidVisibilityChange(scheduleSync);\n // The palette's \"Add column…\" opens this deck's dialog.\n const add = (event: Event) => { if ((event as CustomEvent<string>).detail === deckId) setAdding(true); };\n window.addEventListener('bt-deck-add', add);\n return () => { visibility.dispose(); window.removeEventListener('bt-deck-add', add); };\n }, [props.api, deckId]);\n // Every column gets its config before its webview exists (no flash of the site's chrome);\n // unmounting the deck forgets what was sent, so reopening it configures again.\n useEffect(() => {\n if (!deck) return;\n for (const column of deck.columns) {\n if (decks.sent.has(column.tabId)) continue;\n void configureColumn(column, true).then(() => { decks.ready.add(column.tabId); scheduleSync(); });\n }\n });\n useEffect(() => () => {\n for (const column of deckById(deckId)?.columns ?? []) { decks.sent.delete(column.tabId); decks.ready.delete(column.tabId); }\n }, [deckId]);\n\n if (!deck) {\n return <div className=\"bt-deck\"><div className=\"bt-deck-empty\"><h2>{tr('wb.deck.gone')}</h2><p>{tr('wb.deck.goneHint')}</p>\n <button className=\"bt-deck-secondary\" onClick={() => props.api.close()}>{tr('wb.shell.menu.close')}</button></div></div>;\n }\n const settings = decks.settings;\n const width = columnsWidth(rowWidth, deck.id);\n const layout = layoutColumns(width, deck.columns, decks.page.get(deck.id) ?? 0, { maxVisible: settings.maxVisible });\n const focusedId = decks.focus.get(deck.id) ?? layout.visible[0]?.id;\n const total = unreadTotal(new Map(deck.columns.map(c => [c.tabId, decks.runtime.get(c.tabId)?.unread ?? 0])), deck.columns);\n const setPage = (page: number) => { decks.page.set(deck.id, page); emitDecks(); scheduleSync(); };\n const composing = compose && decks.compose.get(deck.id);\n const overLimit = deck.columns.length > settings.maxVisible;\n\n return <div className=\"bt-deck\">\n <div className=\"bt-deck-bar\">\n <span className=\"bt-deck-mark\" aria-hidden=\"true\"><Icon name=\"grid\"/></span>\n <strong className=\"bt-deck-name\">{deck.name}</strong>\n <span className=\"bt-deck-count\">{tr('wb.deck.columnCount', { count: deck.columns.length })}</span>\n {total > 0 && <span className=\"bt-deck-total\" title={tr('wb.deck.unreadTitle')}>{tr('wb.deck.newCount', { count: unreadLabel(total) })}</span>}\n <span className=\"bt-deck-fill\"/>\n {layout.pages > 1 && <div className=\"bt-deck-pager\" role=\"group\" aria-label={tr('wb.deck.pages')}>\n <button className=\"bt-icon\" title={tr('wb.deck.prevTitle')} aria-label={tr('wb.deck.prev')} disabled={layout.page === 0} onClick={() => setPage(layout.page - 1)}><Icon name=\"back\"/></button>\n {Array.from({ length: layout.pages }, (_, i) => <button key={i} className={`bt-deck-dot${i === layout.page ? ' is-on' : ''}`} aria-label={tr('wb.deck.page', { n: i + 1 })} aria-current={i === layout.page ? 'page' : undefined} onClick={() => setPage(i)}/>)}\n <button className=\"bt-icon\" title={tr('wb.deck.nextTitle')} aria-label={tr('wb.deck.next')} disabled={layout.page >= layout.pages - 1} onClick={() => setPage(layout.page + 1)}><Icon name=\"forward\"/></button>\n </div>}\n {overLimit && <span className=\"bt-deck-memory\" title={tr('wb.deck.memoryTitle', { count: decks.settings.maxVisible, site: site().name })}>{tr('wb.deck.onScreen', { visible: layout.visible.length, total: deck.columns.length })}</span>}\n <button className=\"bt-deck-action\" onClick={() => setAdding(true)} title={tr('wb.deck.addColumn')}><Icon name=\"plus\"/><span>{tr('wb.deck.column')}</span></button>\n {compose && <button className={`bt-deck-action${composing ? ' is-on' : ''}`} onClick={() => toggleCompose(deck.id, deck.columns.find(c => c.id === focusedId)?.profile)} title={tr('wb.deck.postTitle')} aria-pressed={!!composing}>\n <Icon name=\"edit\"/><span>{tr('wb.deck.post')}</span></button>}\n <button className=\"bt-icon bt-deck-settings\" title={tr('wb.deck.settings')} aria-label={tr('wb.deck.settings')} onClick={() => shell.openPanelSection('power')}><Icon name=\"settings\"/></button>\n </div>\n <div className=\"bt-deck-row\" ref={row}>\n {deck.columns.length === 0\n ? <EmptyDeck deck={deck} onAdd={() => setAdding(true)}/>\n : layout.visible.map(place => {\n const column = deck.columns.find(c => c.id === place.id)!;\n return <ColumnView key={column.id} deck={deck} column={column} x={place.x} width={place.width} focused={column.id === focusedId}\n number={deck.columns.indexOf(column) + 1}/>;\n })}\n {compose && composing && <compose.Dock deckId={deck.id} left={width + COLUMN_GAP}/>}\n </div>\n {adding && <AddColumnDialog deck={deck} onClose={() => setAdding(false)} onAdd={input => {\n const column = addColumn(deck.id, input);\n void configureColumn(column, true).then(() => { decks.ready.add(column.tabId); focusColumn(deck.id, column.id, false); });\n setAdding(false);\n }}/>}\n </div>;\n}\n\n/** Unread total of a deck on its dockview tab. */\nexport function DeckTabBadge({ deckId }: { deckId: string }) {\n useDecks();\n const deck = deckById(deckId);\n if (!deck) return null;\n const total = unreadTotal(new Map(deck.columns.map(c => [c.tabId, decks.runtime.get(c.tabId)?.unread ?? 0])), deck.columns);\n return total > 0 ? <span className=\"bt-tab-unread\" aria-label={`${total} unread`}>{unreadLabel(total)}</span> : null;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import './findBar.css';
2
+ /** Opens (or focuses) the find bar of web tab `id`. */
3
+ export declare const openFind: (id: string) => boolean;
4
+ /** The next (`1`) or previous (`-1`) match in tab `id`, when its find bar is open (F3 anywhere in the shell). */
5
+ export declare const stepFind: (id: string, direction: 1 | -1) => boolean;
6
+ export declare function FindBar({ tabId, url, onClose }: {
7
+ tabId: string;
8
+ url: string;
9
+ onClose(): void;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,108 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Find in page: the shell's find bar for one pane. It takes the address field's place in that
3
+ // pane's toolbar while it is open (so the page under it does not move and, in split view, the bar
4
+ // is plainly the searched pane's). Native code does the searching (`tab_find`, shell-only): the
5
+ // engine's own find where the build can drive it (WebView2: highlights and a match count, which
6
+ // arrive as `tab-find` events), else the engine's `window.find` evaluated by native code (next and
7
+ // previous work, no count). Only what the page has rendered can be found, as in a browser: a
8
+ // virtualized list (X's timeline) holds the posts near the viewport, not the whole feed.
9
+ //
10
+ // The query lives in this component's state while the bar is open and nowhere else: it is not
11
+ // saved, logged or put in a URL, and closing the bar clears the engine's highlights.
12
+ // Keys: Enter / F3 next, Shift+Enter / Shift+F3 previous, Esc closes and gives the page the focus.
13
+ import { useEffect, useRef, useState } from 'react';
14
+ import { invoke, listen } from "./bridge.js";
15
+ import { describe, diag } from "./diag.js";
16
+ import { useT } from "./hooks.js";
17
+ import { formatNumber } from "./i18n.js";
18
+ import { Icon } from "./icons.js";
19
+ import { findLabel, menuText } from "./menuModel.js";
20
+ import { tabAction } from "./state.js";
21
+ import './findBar.css';
22
+ /** Opens (or focuses) the find bar of web tab `id`. */
23
+ export const openFind = (id) => window.dispatchEvent(new CustomEvent('bt-find', { detail: id }));
24
+ /** The next (`1`) or previous (`-1`) match in tab `id`, when its find bar is open (F3 anywhere in the shell). */
25
+ export const stepFind = (id, direction) => window.dispatchEvent(new CustomEvent('bt-find-step', { detail: { id, direction } }));
26
+ const find = (id, action, query) => invoke('tab_find', { id, action, ...(query ? { query } : {}) }).catch(() => { });
27
+ export function FindBar({ tabId, url, onClose }) {
28
+ useT();
29
+ const [query, setQuery] = useState('');
30
+ // What the engine reported for the query on screen (null: nothing yet, or an engine that does not count).
31
+ const [counts, setCounts] = useState(null);
32
+ const input = useRef(null);
33
+ const live = useRef(query);
34
+ live.current = query;
35
+ const close = () => {
36
+ onClose();
37
+ // The page gets the keyboard back.
38
+ void tabAction(tabId, 'focus');
39
+ };
40
+ const step = (direction) => { if (live.current)
41
+ void find(tabId, direction > 0 ? 'next' : 'previous', live.current); };
42
+ // The shell takes the keyboard (Ctrl+F was pressed in the page); closing clears the highlights.
43
+ useEffect(() => {
44
+ const focusField = () => { if (input.current && document.activeElement !== input.current)
45
+ input.current.focus(); };
46
+ invoke('shell_focus').then(focusField, () => { });
47
+ focusField();
48
+ diag(`find bar open: hasFocus=${document.hasFocus()} active=${describe(document.activeElement)}`);
49
+ // The page may keep the keyboard (the keys that opened the bar were pressed in it): if the shell
50
+ // still does not have it a moment later, ask once more, so typing never lands in the page.
51
+ const retry = setTimeout(() => {
52
+ diag(`find bar +250ms: hasFocus=${document.hasFocus()} active=${describe(document.activeElement)}`);
53
+ if (!document.hasFocus())
54
+ invoke('shell_focus').then(() => { focusField(); diag(`find bar refocused: hasFocus=${document.hasFocus()}`); }, () => { });
55
+ else
56
+ focusField();
57
+ }, 250);
58
+ const again = (event) => { if (event.detail === tabId) {
59
+ input.current?.focus();
60
+ input.current?.select();
61
+ } };
62
+ const onStep = (event) => { const detail = event.detail; if (detail.id === tabId)
63
+ step(detail.direction); };
64
+ window.addEventListener('bt-find', again);
65
+ window.addEventListener('bt-find-step', onStep);
66
+ let disposed = false;
67
+ let unlisten;
68
+ listen('tab-find', ({ payload }) => {
69
+ if (payload.id === tabId && live.current)
70
+ setCounts({ count: payload.count, index: payload.index });
71
+ }).then(dispose => { if (disposed)
72
+ dispose();
73
+ else
74
+ unlisten = dispose; }).catch(() => { });
75
+ return () => {
76
+ disposed = true;
77
+ clearTimeout(retry);
78
+ unlisten?.();
79
+ window.removeEventListener('bt-find', again);
80
+ window.removeEventListener('bt-find-step', onStep);
81
+ void find(tabId, 'stop');
82
+ };
83
+ }, [tabId]);
84
+ // A new query (or a new page under the same query) starts a new search, a beat after the last key.
85
+ useEffect(() => {
86
+ setCounts(null);
87
+ if (!query) {
88
+ void find(tabId, 'stop');
89
+ return;
90
+ }
91
+ const timer = setTimeout(() => void find(tabId, 'start', query), 140);
92
+ return () => clearTimeout(timer);
93
+ }, [query, url, tabId]);
94
+ const status = query && counts ? findLabel(counts, value => formatNumber(value)) : '';
95
+ return _jsxs("div", { className: `bt-omni bt-omni--edit bt-find${query && counts?.count === 0 ? ' is-none' : ''}`, role: "search", title: menuText('findHint'), children: [_jsx(Icon, { name: "search", className: "bt-omni-lead" }), _jsx("input", { ref: input, type: "text", spellCheck: false, autoComplete: "off", maxLength: 256, value: query, placeholder: menuText('findField'), "aria-label": menuText('findField'), onChange: event => setQuery(event.target.value.replace(/[\u0000-\u001f\u007f]/g, '')), onKeyDown: event => {
96
+ if (event.key === 'Enter' || event.key === 'F3') {
97
+ event.preventDefault();
98
+ event.stopPropagation();
99
+ step(event.shiftKey ? -1 : 1);
100
+ }
101
+ if (event.key === 'Escape') {
102
+ event.preventDefault();
103
+ event.stopPropagation();
104
+ close();
105
+ }
106
+ } }), _jsx("span", { className: "bt-find-count", role: "status", "aria-live": "polite", children: status }), _jsx("button", { type: "button", className: "bt-omni-action", disabled: !query, title: `${menuText('findPrevious')} (Shift+Enter)`, "aria-label": menuText('findPrevious'), onMouseDown: event => event.preventDefault(), onClick: () => step(-1), children: _jsx(Icon, { name: "chevron", className: "bt-find-up" }) }), _jsx("button", { type: "button", className: "bt-omni-action", disabled: !query, title: `${menuText('findNext')} (Enter)`, "aria-label": menuText('findNext'), onMouseDown: event => event.preventDefault(), onClick: () => step(1), children: _jsx(Icon, { name: "chevron" }) }), _jsx("button", { type: "button", className: "bt-omni-action", title: `${menuText('findClose')} (Esc)`, "aria-label": menuText('findClose'), onClick: close, children: _jsx(Icon, { name: "close" }) })] });
107
+ }
108
+ //# sourceMappingURL=FindBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FindBar.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/FindBar.tsx"],"names":[],"mappings":"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","sourcesContent":["// Find in page: the shell's find bar for one pane. It takes the address field's place in that\n// pane's toolbar while it is open (so the page under it does not move and, in split view, the bar\n// is plainly the searched pane's). Native code does the searching (`tab_find`, shell-only): the\n// engine's own find where the build can drive it (WebView2: highlights and a match count, which\n// arrive as `tab-find` events), else the engine's `window.find` evaluated by native code (next and\n// previous work, no count). Only what the page has rendered can be found, as in a browser: a\n// virtualized list (X's timeline) holds the posts near the viewport, not the whole feed.\n//\n// The query lives in this component's state while the bar is open and nowhere else: it is not\n// saved, logged or put in a URL, and closing the bar clears the engine's highlights.\n// Keys: Enter / F3 next, Shift+Enter / Shift+F3 previous, Esc closes and gives the page the focus.\n\nimport { useEffect, useRef, useState } from 'react';\nimport { invoke, listen } from './bridge.ts';\nimport { describe, diag } from './diag.ts';\nimport { useT } from './hooks.ts';\nimport { formatNumber } from './i18n.ts';\nimport { Icon } from './icons.tsx';\nimport { findLabel, menuText } from './menuModel.ts';\nimport { tabAction } from './state.ts';\nimport './findBar.css';\n\n/** Opens (or focuses) the find bar of web tab `id`. */\nexport const openFind = (id: string) => window.dispatchEvent(new CustomEvent('bt-find', { detail: id }));\n/** The next (`1`) or previous (`-1`) match in tab `id`, when its find bar is open (F3 anywhere in the shell). */\nexport const stepFind = (id: string, direction: 1 | -1) => window.dispatchEvent(new CustomEvent('bt-find-step', { detail: { id, direction } }));\n\nconst find = (id: string, action: 'start' | 'next' | 'previous' | 'stop', query?: string) =>\n invoke('tab_find', { id, action, ...(query ? { query } : {}) }).catch(() => {});\n\nexport function FindBar({ tabId, url, onClose }: { tabId: string; url: string; onClose(): void }) {\n useT();\n const [query, setQuery] = useState('');\n // What the engine reported for the query on screen (null: nothing yet, or an engine that does not count).\n const [counts, setCounts] = useState<{ count: number; index: number } | null>(null);\n const input = useRef<HTMLInputElement>(null);\n const live = useRef(query);\n live.current = query;\n\n const close = () => {\n onClose();\n // The page gets the keyboard back.\n void tabAction(tabId, 'focus');\n };\n const step = (direction: 1 | -1) => { if (live.current) void find(tabId, direction > 0 ? 'next' : 'previous', live.current); };\n\n // The shell takes the keyboard (Ctrl+F was pressed in the page); closing clears the highlights.\n useEffect(() => {\n const focusField = () => { if (input.current && document.activeElement !== input.current) input.current.focus(); };\n invoke('shell_focus').then(focusField, () => {});\n focusField();\n diag(`find bar open: hasFocus=${document.hasFocus()} active=${describe(document.activeElement)}`);\n // The page may keep the keyboard (the keys that opened the bar were pressed in it): if the shell\n // still does not have it a moment later, ask once more, so typing never lands in the page.\n const retry = setTimeout(() => {\n diag(`find bar +250ms: hasFocus=${document.hasFocus()} active=${describe(document.activeElement)}`);\n if (!document.hasFocus()) invoke('shell_focus').then(() => { focusField(); diag(`find bar refocused: hasFocus=${document.hasFocus()}`); }, () => {});\n else focusField();\n }, 250);\n const again = (event: Event) => { if ((event as CustomEvent<string>).detail === tabId) { input.current?.focus(); input.current?.select(); } };\n const onStep = (event: Event) => { const detail = (event as CustomEvent<{ id: string; direction: 1 | -1 }>).detail; if (detail.id === tabId) step(detail.direction); };\n window.addEventListener('bt-find', again);\n window.addEventListener('bt-find-step', onStep);\n let disposed = false;\n let unlisten: (() => void) | undefined;\n listen<{ id: string; count: number; index: number }>('tab-find', ({ payload }) => {\n if (payload.id === tabId && live.current) setCounts({ count: payload.count, index: payload.index });\n }).then(dispose => { if (disposed) dispose(); else unlisten = dispose; }).catch(() => {});\n return () => {\n disposed = true;\n clearTimeout(retry);\n unlisten?.();\n window.removeEventListener('bt-find', again);\n window.removeEventListener('bt-find-step', onStep);\n void find(tabId, 'stop');\n };\n }, [tabId]);\n\n // A new query (or a new page under the same query) starts a new search, a beat after the last key.\n useEffect(() => {\n setCounts(null);\n if (!query) { void find(tabId, 'stop'); return; }\n const timer = setTimeout(() => void find(tabId, 'start', query), 140);\n return () => clearTimeout(timer);\n }, [query, url, tabId]);\n\n const status = query && counts ? findLabel(counts, value => formatNumber(value)) : '';\n return <div className={`bt-omni bt-omni--edit bt-find${query && counts?.count === 0 ? ' is-none' : ''}`} role=\"search\" title={menuText('findHint')}>\n <Icon name=\"search\" className=\"bt-omni-lead\"/>\n <input ref={input} type=\"text\" spellCheck={false} autoComplete=\"off\" maxLength={256} value={query} placeholder={menuText('findField')} aria-label={menuText('findField')}\n onChange={event => setQuery(event.target.value.replace(/[\\u0000-\\u001f\\u007f]/g, ''))}\n onKeyDown={event => {\n if (event.key === 'Enter' || event.key === 'F3') { event.preventDefault(); event.stopPropagation(); step(event.shiftKey ? -1 : 1); }\n if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); close(); }\n }}/>\n <span className=\"bt-find-count\" role=\"status\" aria-live=\"polite\">{status}</span>\n <button type=\"button\" className=\"bt-omni-action\" disabled={!query} title={`${menuText('findPrevious')} (Shift+Enter)`} aria-label={menuText('findPrevious')}\n onMouseDown={event => event.preventDefault()} onClick={() => step(-1)}><Icon name=\"chevron\" className=\"bt-find-up\"/></button>\n <button type=\"button\" className=\"bt-omni-action\" disabled={!query} title={`${menuText('findNext')} (Enter)`} aria-label={menuText('findNext')}\n onMouseDown={event => event.preventDefault()} onClick={() => step(1)}><Icon name=\"chevron\"/></button>\n <button type=\"button\" className=\"bt-omni-action\" title={`${menuText('findClose')} (Esc)`} aria-label={menuText('findClose')} onClick={close}><Icon name=\"close\"/></button>\n </div>;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Media side panel: recent images from the owner's gallery folders and the local clipboard
3
+ * history. Choosing an item attaches the image to (or inserts the text into) the composer of the
4
+ * active site tab (`site.media.canAttach`). Nothing is posted; the user reviews and sends it themselves.
5
+ */
6
+ export declare function MediaPanel({ onClose }: {
7
+ onClose: () => void;
8
+ }): import("react").ReactPortal;