@jant/core 0.6.14 → 0.6.16

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 (350) hide show
  1. package/bin/commands/import-site.js +88 -13
  2. package/bin/commands/migrate.js +55 -0
  3. package/bin/commands/posts/rebuild-html.js +184 -0
  4. package/bin/commands/site/snapshot/import.js +14 -10
  5. package/bin/lib/d1-query.js +23 -5
  6. package/bin/lib/migration-runner.js +29 -7
  7. package/bin/lib/node-database.js +32 -0
  8. package/bin/lib/site-snapshot.js +347 -46
  9. package/bin/lib/sql-export.js +1 -1
  10. package/bin/lib/thread-collection-migration.js +326 -0
  11. package/dist/app-C75Zc8dD.js +6 -0
  12. package/dist/{app-2i7-WQHg.js → app-C7_4oab9.js} +7774 -6425
  13. package/dist/client/.vite/manifest.json +8 -8
  14. package/dist/client/_assets/chunks/{url-pLre2DM_.js → url-CU9pEbk5.js} +1 -1
  15. package/dist/client/_assets/{client-BvID5ucz.js → client-Bq0vre8Y.js} +59 -38
  16. package/dist/client/_assets/client-D3VZyG4L.css +2 -0
  17. package/dist/client/_assets/client-auth-F2rb9WfF.js +5571 -0
  18. package/dist/{env-OHRKGcMj.js → env-BPYViDJJ.js} +1 -1
  19. package/dist/{export-DWn149b7.js → export-Dl5KCiEs.js} +1348 -128
  20. package/dist/{github-api-BgSiE71w.js → github-api-BNF35Lkx.js} +1 -1
  21. package/dist/{github-app-BbklkFmU.js → github-app-DdiD-bC4.js} +1 -1
  22. package/dist/{github-sync-C0zyF6XS.js → github-sync-Bqg62IvV.js} +3 -3
  23. package/dist/{github-sync-Ckk0sJxK.js → github-sync-HdK2EgvJ.js} +3 -3
  24. package/dist/index.js +5 -5
  25. package/dist/node.js +7 -7
  26. package/dist/{url-BMYO-Zlt.js → url-CbLAtlZe.js} +517 -12
  27. package/package.json +11 -10
  28. package/src/__tests__/bin/posts-rebuild-html.test.ts +137 -0
  29. package/src/__tests__/dev-navigation-defaults.test.ts +22 -0
  30. package/src/__tests__/export-hugo-build.test.ts +63 -4
  31. package/src/__tests__/export-import-roundtrip.test.ts +6 -4
  32. package/src/__tests__/export-service.test.ts +142 -9
  33. package/src/__tests__/helpers/app.ts +3 -0
  34. package/src/__tests__/helpers/export-fixtures.ts +2 -0
  35. package/src/__tests__/import-site-command.test.ts +65 -0
  36. package/src/__tests__/mise-config.test.ts +22 -0
  37. package/src/__tests__/vite-config.test.ts +45 -0
  38. package/src/app.tsx +16 -3
  39. package/src/client/__tests__/collection-created-notice.test.ts +36 -0
  40. package/src/client/__tests__/collection-form-bridge.test.ts +10 -1
  41. package/src/client/__tests__/collection-page-actions.test.ts +71 -2
  42. package/src/client/__tests__/compose-bridge.test.ts +316 -2
  43. package/src/client/__tests__/compose-shortcuts.test.ts +20 -0
  44. package/src/client/__tests__/feed-video-player.test.ts +16 -1
  45. package/src/client/__tests__/footnote-rail.test.ts +472 -0
  46. package/src/client/__tests__/hydrate-partial.test.ts +3 -0
  47. package/src/client/__tests__/toast.test.ts +82 -1
  48. package/src/client/collection-created-notice.ts +66 -0
  49. package/src/client/collection-form-bridge.ts +17 -0
  50. package/src/client/collection-navigation.ts +44 -0
  51. package/src/client/collection-page-actions.ts +57 -1
  52. package/src/client/components/__tests__/compose-format-convert.test.ts +0 -19
  53. package/src/client/components/__tests__/jant-collection-directory.test.ts +155 -6
  54. package/src/client/components/__tests__/jant-command-palette.test.ts +51 -0
  55. package/src/client/components/__tests__/jant-compose-dialog.test.ts +2268 -206
  56. package/src/client/components/__tests__/jant-compose-editor.test.ts +147 -59
  57. package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +114 -64
  58. package/src/client/components/__tests__/jant-config-editor.test.ts +405 -0
  59. package/src/client/components/__tests__/jant-media-lightbox.test.ts +121 -0
  60. package/src/client/components/__tests__/jant-nav-manager.test.ts +538 -2
  61. package/src/client/components/__tests__/jant-post-form.test.ts +2 -2
  62. package/src/client/components/__tests__/jant-post-menu.test.ts +47 -5
  63. package/src/client/components/__tests__/jant-settings-avatar.test.ts +2 -2
  64. package/src/client/components/__tests__/jant-settings-general.test.ts +3 -3
  65. package/src/client/components/collection-manager-types.ts +9 -3
  66. package/src/client/components/compose-format-convert.ts +5 -1
  67. package/src/client/components/compose-types.ts +55 -3
  68. package/src/client/components/jant-collection-directory.ts +165 -30
  69. package/src/client/components/jant-command-palette.ts +14 -7
  70. package/src/client/components/jant-compose-dialog.ts +1542 -694
  71. package/src/client/components/jant-compose-editor.ts +237 -99
  72. package/src/client/components/jant-compose-fullscreen.ts +27 -9
  73. package/src/client/components/jant-config-editor.ts +722 -0
  74. package/src/client/components/jant-media-lightbox.ts +100 -18
  75. package/src/client/components/jant-nav-manager.ts +1283 -54
  76. package/src/client/components/jant-post-form.ts +3 -3
  77. package/src/client/components/jant-post-menu.ts +177 -95
  78. package/src/client/components/nav-manager-types.ts +51 -2
  79. package/src/client/components/post-form-types.ts +1 -1
  80. package/src/client/compose-bridge.ts +147 -123
  81. package/src/client/compose-launch.ts +13 -0
  82. package/src/client/compose-shortcuts.ts +5 -1
  83. package/src/client/feed-video-player.ts +62 -2
  84. package/src/client/footnote-rail.ts +478 -0
  85. package/src/client/hydrate-partial.ts +2 -0
  86. package/src/client/media-lightbox-events.ts +63 -0
  87. package/src/client/post-refresh.ts +135 -0
  88. package/src/client/site-header-fragment.ts +38 -0
  89. package/src/client/tiptap/__tests__/blockquote-editing.test.ts +201 -0
  90. package/src/client/tiptap/__tests__/clear-formatting.test.ts +168 -0
  91. package/src/client/tiptap/__tests__/link-input-rules.test.ts +121 -0
  92. package/src/client/tiptap/__tests__/list-editing.test.ts +447 -0
  93. package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +727 -4
  94. package/src/client/tiptap/__tests__/table-controls.test.ts +263 -0
  95. package/src/client/tiptap/__tests__/table-size-picker.test.ts +179 -0
  96. package/src/client/tiptap/bubble-menu.ts +88 -10
  97. package/src/client/tiptap/continuous-lists.ts +102 -0
  98. package/src/client/tiptap/create-editor.ts +3 -0
  99. package/src/client/tiptap/extensions.ts +14 -5
  100. package/src/client/tiptap/link-input-rules.ts +4 -4
  101. package/src/client/tiptap/markdown-clipboard.ts +608 -11
  102. package/src/client/tiptap/slash-commands.ts +8 -1
  103. package/src/client/tiptap/structural-keymap.ts +211 -0
  104. package/src/client/tiptap/tab-indent.ts +8 -22
  105. package/src/client/tiptap/table-control-labels.ts +30 -0
  106. package/src/client/tiptap/table-controls.ts +537 -0
  107. package/src/client/tiptap/table-size-picker.ts +254 -0
  108. package/src/client/toast.ts +133 -39
  109. package/src/client-auth.ts +1 -0
  110. package/src/client.ts +1 -0
  111. package/src/db/__tests__/backfill-thread-activity.test.ts +234 -0
  112. package/src/db/__tests__/d1-query.test.ts +43 -1
  113. package/src/db/__tests__/migration-runner.test.ts +63 -0
  114. package/src/db/__tests__/migrations.test.ts +469 -0
  115. package/src/db/__tests__/thread-activity.test.ts +113 -0
  116. package/src/db/__tests__/thread-collection-migration.test.ts +364 -0
  117. package/src/db/backfills/0005_split_thread_activity_from_quiet_replies.sql +68 -0
  118. package/src/db/migrations/0027_old_blue_blade.sql +39 -0
  119. package/src/db/migrations/0028_superb_post.sql +2 -0
  120. package/src/db/migrations/0029_boring_magma.sql +1 -0
  121. package/src/db/migrations/0030_typical_vivisector.sql +50 -0
  122. package/src/db/migrations/0031_many_ego.sql +3 -0
  123. package/src/db/migrations/meta/0027_snapshot.json +2511 -0
  124. package/src/db/migrations/meta/0028_snapshot.json +2511 -0
  125. package/src/db/migrations/meta/0029_snapshot.json +2519 -0
  126. package/src/db/migrations/meta/0030_snapshot.json +2541 -0
  127. package/src/db/migrations/meta/0031_snapshot.json +2562 -0
  128. package/src/db/migrations/meta/_journal.json +35 -0
  129. package/src/db/migrations/pg/0025_moaning_epoch.sql +39 -0
  130. package/src/db/migrations/pg/0026_talented_killer_shrike.sql +2 -0
  131. package/src/db/migrations/pg/0027_short_cannonball.sql +1 -0
  132. package/src/db/migrations/pg/0028_perfect_sharon_carter.sql +27 -0
  133. package/src/db/migrations/pg/0029_rare_hairball.sql +3 -0
  134. package/src/db/migrations/pg/meta/0025_snapshot.json +3204 -0
  135. package/src/db/migrations/pg/meta/0026_snapshot.json +3204 -0
  136. package/src/db/migrations/pg/meta/0027_snapshot.json +3211 -0
  137. package/src/db/migrations/pg/meta/0028_snapshot.json +3248 -0
  138. package/src/db/migrations/pg/meta/0029_snapshot.json +3289 -0
  139. package/src/db/migrations/pg/meta/_journal.json +35 -0
  140. package/src/db/pg/schema.ts +46 -20
  141. package/src/db/rehearsal-fixtures/demo-current.json +39 -4
  142. package/src/db/rehearsal-fixtures/demo-current.sql +121 -6
  143. package/src/db/schema.ts +48 -20
  144. package/src/db/thread-activity.ts +101 -0
  145. package/src/i18n/__tests__/detect.test.ts +8 -2
  146. package/src/i18n/detect.ts +14 -5
  147. package/src/i18n/locales/public/en.po +222 -51
  148. package/src/i18n/locales/public/en.ts +1 -1
  149. package/src/i18n/locales/public/zh-Hans.po +216 -45
  150. package/src/i18n/locales/public/zh-Hans.ts +1 -1
  151. package/src/i18n/locales/public/zh-Hant.po +216 -45
  152. package/src/i18n/locales/public/zh-Hant.ts +1 -1
  153. package/src/i18n/locales/settings/en.po +513 -10
  154. package/src/i18n/locales/settings/en.ts +1 -1
  155. package/src/i18n/locales/settings/zh-Hans.po +515 -12
  156. package/src/i18n/locales/settings/zh-Hans.ts +1 -1
  157. package/src/i18n/locales/settings/zh-Hant.po +515 -12
  158. package/src/i18n/locales/settings/zh-Hant.ts +1 -1
  159. package/src/lib/__tests__/api-settings.test.ts +299 -0
  160. package/src/lib/__tests__/constants.test.ts +5 -0
  161. package/src/lib/__tests__/feed-policy.test.ts +25 -0
  162. package/src/lib/__tests__/feed.test.ts +168 -0
  163. package/src/lib/__tests__/footnotes-upgrade.test.ts +181 -0
  164. package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +61 -0
  165. package/src/lib/__tests__/markdown-to-tiptap.test.ts +32 -4
  166. package/src/lib/__tests__/markdown.test.ts +24 -6
  167. package/src/lib/__tests__/navigation.test.ts +59 -2
  168. package/src/lib/__tests__/post-body-html.test.ts +176 -0
  169. package/src/lib/__tests__/post-display.test.ts +64 -0
  170. package/src/lib/__tests__/resolve-config.test.ts +113 -1
  171. package/src/lib/__tests__/slug.test.ts +18 -0
  172. package/src/lib/__tests__/summary.test.ts +82 -0
  173. package/src/lib/__tests__/timeline.test.ts +109 -70
  174. package/src/lib/__tests__/timezones.test.ts +31 -3
  175. package/src/lib/__tests__/tiptap-render.test.ts +268 -9
  176. package/src/lib/__tests__/tiptap-to-markdown.test.ts +6 -0
  177. package/src/lib/__tests__/translit.test.ts +87 -0
  178. package/src/lib/__tests__/url.test.ts +53 -0
  179. package/src/lib/__tests__/view.test.ts +53 -0
  180. package/src/lib/__tests__/worker-response-cache.test.ts +18 -1
  181. package/src/lib/api-settings.ts +239 -12
  182. package/src/lib/collection-sort.ts +7 -5
  183. package/src/lib/constants.ts +2 -0
  184. package/src/lib/feed-path.ts +25 -0
  185. package/src/lib/feed-policy.ts +64 -0
  186. package/src/lib/feed.ts +113 -11
  187. package/src/lib/footnotes.ts +264 -0
  188. package/src/lib/github-sync-site-config.ts +2 -0
  189. package/src/lib/hugo-markdown.ts +15 -3
  190. package/src/lib/jant-branding.ts +1 -0
  191. package/src/lib/link-preview.ts +25 -0
  192. package/src/lib/markdown-manager.ts +193 -5
  193. package/src/lib/markdown.ts +10 -3
  194. package/src/lib/navigation.ts +16 -3
  195. package/src/lib/post-body-html.ts +131 -0
  196. package/src/lib/post-display.ts +47 -8
  197. package/src/lib/render.tsx +9 -2
  198. package/src/lib/resolve-config.ts +100 -16
  199. package/src/lib/schemas.ts +133 -1
  200. package/src/lib/settings-paths.ts +5 -0
  201. package/src/lib/site-skill.ts +78 -0
  202. package/src/lib/summary.ts +16 -5
  203. package/src/lib/timeline.ts +137 -131
  204. package/src/lib/timezones.ts +54 -14
  205. package/src/lib/tiptap-render.ts +359 -83
  206. package/src/lib/translit.ts +288 -0
  207. package/src/lib/url.ts +123 -12
  208. package/src/lib/view.ts +58 -20
  209. package/src/lib/worker-response-cache.ts +11 -18
  210. package/src/middleware/__tests__/public-content-access.test.ts +91 -0
  211. package/src/middleware/config.ts +2 -2
  212. package/src/middleware/public-content-access.ts +87 -0
  213. package/src/node/__tests__/cli-export.test.ts +14 -0
  214. package/src/node/__tests__/cli-migrate.test.ts +6 -0
  215. package/src/node/__tests__/cli-site-snapshot.test.ts +205 -2
  216. package/src/node/__tests__/cli-snapshot-meta.test.ts +100 -0
  217. package/src/node/index.ts +2 -1
  218. package/src/preset.css +16 -2
  219. package/src/routes/__tests__/compose.test.ts +51 -0
  220. package/src/routes/__tests__/site-skill.test.ts +112 -0
  221. package/src/routes/api/__tests__/collections.test.ts +91 -19
  222. package/src/routes/api/__tests__/mcp.test.ts +65 -1
  223. package/src/routes/api/__tests__/nav-items.test.ts +91 -0
  224. package/src/routes/api/__tests__/palette.test.ts +44 -0
  225. package/src/routes/api/__tests__/public-access.test.ts +81 -0
  226. package/src/routes/api/__tests__/settings.test.ts +217 -0
  227. package/src/routes/api/collections.ts +22 -26
  228. package/src/routes/api/export.ts +2 -0
  229. package/src/routes/api/internal/__tests__/post-body-html.test.ts +163 -0
  230. package/src/routes/api/internal/__tests__/sites.test.ts +35 -2
  231. package/src/routes/api/internal/post-body-html.ts +43 -0
  232. package/src/routes/api/internal/sites.ts +24 -0
  233. package/src/routes/api/nav-items.ts +24 -1
  234. package/src/routes/api/posts.ts +14 -10
  235. package/src/routes/api/public/__tests__/archive.test.ts +35 -0
  236. package/src/routes/api/public/__tests__/posts.test.ts +246 -0
  237. package/src/routes/api/public/archive.ts +4 -0
  238. package/src/routes/api/public/posts.ts +48 -24
  239. package/src/routes/api/search.ts +3 -0
  240. package/src/routes/api/settings.ts +33 -0
  241. package/src/routes/auth/__tests__/setup.test.ts +7 -4
  242. package/src/routes/compose.tsx +8 -3
  243. package/src/routes/dash/settings.tsx +45 -2
  244. package/src/routes/feed/__tests__/feed.test.ts +210 -6
  245. package/src/routes/feed/__tests__/sitemap.test.ts +68 -1
  246. package/src/routes/feed/feed.ts +23 -14
  247. package/src/routes/pages/__tests__/archive-params.test.ts +384 -3
  248. package/src/routes/pages/__tests__/collection-routing.test.ts +63 -5
  249. package/src/routes/pages/__tests__/collections.test.ts +9 -9
  250. package/src/routes/pages/__tests__/featured.test.ts +6 -2
  251. package/src/routes/pages/__tests__/preview.test.ts +176 -0
  252. package/src/routes/pages/__tests__/search.test.ts +69 -0
  253. package/src/routes/pages/archive.tsx +90 -22
  254. package/src/routes/pages/collection.tsx +32 -19
  255. package/src/routes/pages/collections.tsx +6 -1
  256. package/src/routes/pages/page.tsx +86 -11
  257. package/src/routes/site-skill.ts +18 -0
  258. package/src/services/__tests__/auth.test.ts +7 -5
  259. package/src/services/__tests__/collection.test.ts +190 -44
  260. package/src/services/__tests__/navigation.test.ts +229 -21
  261. package/src/services/__tests__/post-timeline.test.ts +249 -39
  262. package/src/services/__tests__/post.test.ts +844 -5
  263. package/src/services/__tests__/search.test.ts +48 -1
  264. package/src/services/__tests__/settings.test.ts +8 -0
  265. package/src/services/__tests__/site-admin.test.ts +121 -1
  266. package/src/services/auth.ts +2 -2
  267. package/src/services/bootstrap.ts +3 -2
  268. package/src/services/collection.ts +224 -167
  269. package/src/services/export-theme/assets/client-site.css +1 -1
  270. package/src/services/export-theme/assets/client-site.js +46 -25
  271. package/src/services/export-theme/layouts/_default/list.html +18 -4
  272. package/src/services/export-theme/layouts/_default/rss.xml +8 -12
  273. package/src/services/export-theme/layouts/featured/list.html +5 -4
  274. package/src/services/export-theme/layouts/partials/featured-thread.html +56 -0
  275. package/src/services/export-theme/layouts/partials/footer.html +1 -1
  276. package/src/services/export-theme/layouts/partials/media-gallery.html +1 -0
  277. package/src/services/export-theme/styles/main.css +30 -2
  278. package/src/services/export.ts +94 -85
  279. package/src/services/mcp.ts +37 -27
  280. package/src/services/media.ts +1 -1
  281. package/src/services/navigation.ts +185 -46
  282. package/src/services/path.ts +4 -1
  283. package/src/services/post.ts +1142 -342
  284. package/src/services/search.ts +17 -2
  285. package/src/services/settings.ts +2 -10
  286. package/src/services/site-admin.ts +63 -43
  287. package/src/style-cjk-jp.css +1 -1
  288. package/src/style-cjk-kr.css +1 -1
  289. package/src/style-cjk-tc.css +1 -1
  290. package/src/style-cjk.css +1 -1
  291. package/src/styles/components.css +540 -14
  292. package/src/styles/site-media.css +111 -19
  293. package/src/styles/tokens.css +76 -10
  294. package/src/styles/ui.css +2227 -1347
  295. package/src/types/bindings.ts +3 -0
  296. package/src/types/config.ts +243 -12
  297. package/src/types/constants.ts +22 -1
  298. package/src/types/entities.ts +14 -8
  299. package/src/types/operations.ts +18 -10
  300. package/src/types/props.ts +20 -2
  301. package/src/types/raw-assets.d.ts +5 -0
  302. package/src/types/views.ts +22 -4
  303. package/src/ui/__tests__/font-themes.test.ts +42 -30
  304. package/src/ui/compose/ComposeDialog.tsx +109 -19
  305. package/src/ui/dash/appearance/NavigationContent.tsx +332 -4
  306. package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +23 -0
  307. package/src/ui/dash/settings/ConfigEditorContent.tsx +578 -0
  308. package/src/ui/dash/settings/GeneralContent.tsx +15 -5
  309. package/src/ui/dash/settings/SettingsRootContent.tsx +21 -1
  310. package/src/ui/dash/settings/__tests__/ConfigEditorContent.test.tsx +98 -0
  311. package/src/ui/dash/settings/__tests__/SettingsRootContent.test.tsx +15 -0
  312. package/src/ui/feed/CuratedThreadPreview.tsx +16 -4
  313. package/src/ui/feed/LinkCard.tsx +2 -12
  314. package/src/ui/feed/LinkPreview.tsx +2 -7
  315. package/src/ui/feed/NoteCard.tsx +10 -20
  316. package/src/ui/feed/PostStatusBadges.tsx +42 -3
  317. package/src/ui/feed/QuoteCard.tsx +2 -12
  318. package/src/ui/feed/ThreadPreview.tsx +26 -34
  319. package/src/ui/feed/TimelineFeed.tsx +2 -2
  320. package/src/ui/feed/__tests__/thread-preview.test.ts +197 -56
  321. package/src/ui/feed/__tests__/timeline-cards.test.ts +178 -3
  322. package/src/ui/feed/thread-preview-state.ts +5 -7
  323. package/src/ui/font-themes.ts +74 -26
  324. package/src/ui/layouts/BaseLayout.tsx +22 -8
  325. package/src/ui/layouts/__tests__/BaseLayout.test.tsx +64 -1
  326. package/src/ui/pages/ArchivePage.tsx +131 -24
  327. package/src/ui/pages/CollectionPage.tsx +101 -22
  328. package/src/ui/pages/CollectionsPage.tsx +3 -1
  329. package/src/ui/pages/PostPage.tsx +39 -12
  330. package/src/ui/pages/SearchPage.tsx +6 -14
  331. package/src/ui/pages/__tests__/ArchivePage.test.tsx +70 -0
  332. package/src/ui/pages/__tests__/PostPage.test.tsx +88 -0
  333. package/src/ui/shared/CollectionDirectory.tsx +13 -9
  334. package/src/ui/shared/CollectionsManager.tsx +17 -7
  335. package/src/ui/shared/DraftPreviewBar.tsx +49 -0
  336. package/src/ui/shared/HomePageBranding.tsx +2 -2
  337. package/src/ui/shared/MediaGallery.tsx +1 -0
  338. package/src/ui/shared/PostFooter.tsx +38 -13
  339. package/src/ui/shared/__tests__/home-page-branding.test.tsx +1 -1
  340. package/src/ui/shared/__tests__/media-gallery.test.ts +1 -0
  341. package/src/ui/shared/__tests__/navigation-labels.test.ts +2 -2
  342. package/src/ui/shared/__tests__/post-footer.test.ts +15 -0
  343. package/src/ui/shared/collection-management-labels.ts +33 -2
  344. package/src/ui/shared/custom-icons.ts +5 -0
  345. package/src/ui/shared/navigation-labels.ts +2 -4
  346. package/src/ui/shared/post-article-attributes.ts +52 -0
  347. package/dist/app-DZDlmh7C.js +0 -6
  348. package/dist/client/_assets/client-Cevfpm8H.css +0 -2
  349. package/dist/client/_assets/client-auth-v3yvhbgZ.js +0 -4736
  350. package/src/client/tiptap/wrapping-input-rules.ts +0 -102
@@ -10,7 +10,7 @@ import type { Editor, JSONContent } from "@tiptap/core";
10
10
  import type {
11
11
  PostFormInitial,
12
12
  PostFormLabels,
13
- PostCollectionOption,
13
+ ThreadCollectionOption,
14
14
  PostMediaItem,
15
15
  PostSubmitDetail,
16
16
  PostFormat,
@@ -116,7 +116,7 @@ export class JantPostForm extends LitElement {
116
116
 
117
117
  declare labels: PostFormLabels;
118
118
  declare initial: PostFormInitial;
119
- declare collections: PostCollectionOption[];
119
+ declare collections: ThreadCollectionOption[];
120
120
  declare media: PostMediaItem[];
121
121
  declare action: string;
122
122
  declare cancelHref: string;
@@ -191,7 +191,7 @@ export class JantPostForm extends LitElement {
191
191
  });
192
192
  }
193
193
  if (typeof this.collections === "string") {
194
- this.collections = parseJson<PostCollectionOption[]>(
194
+ this.collections = parseJson<ThreadCollectionOption[]>(
195
195
  this.collections,
196
196
  [],
197
197
  );
@@ -16,6 +16,7 @@ import {
16
16
  FEATURED_SPARKLE_PATH,
17
17
  } from "../../lib/featured-icons.js";
18
18
  import { showConfirmDialog } from "../confirm.js";
19
+ import { refreshArticleView } from "../post-refresh.js";
19
20
  import { showToast } from "../toast.js";
20
21
  import { publicPath } from "../runtime-paths.js";
21
22
  import {
@@ -27,11 +28,13 @@ import type { CollectionSubmitDetail } from "./collection-types.js";
27
28
 
28
29
  interface PostMenuData {
29
30
  id: string;
31
+ threadId: string;
30
32
  pinned: boolean;
31
33
  pinnedInCollection: boolean;
32
34
  featured: boolean;
33
35
  visibility: string;
34
36
  isReply: boolean;
37
+ isDraft: boolean;
35
38
  }
36
39
 
37
40
  interface CollectionItem {
@@ -44,7 +47,7 @@ interface CollectionsResponse {
44
47
  collections?: CollectionItem[];
45
48
  }
46
49
 
47
- interface PostCollectionsResponse {
50
+ interface ThreadCollectionsResponse {
48
51
  collectionIds?: string[];
49
52
  }
50
53
 
@@ -78,6 +81,35 @@ export function removeLeadingFeedDivider(
78
81
  firstDivider?.remove();
79
82
  }
80
83
 
84
+ function findThreadRootArticle(threadId: string): HTMLElement | null {
85
+ return (
86
+ Array.from(
87
+ document.querySelectorAll<HTMLElement>("article[data-post-id]"),
88
+ ).find((article) => article.dataset.postId === threadId) ?? null
89
+ );
90
+ }
91
+
92
+ function readPostMenuData(article: HTMLElement): PostMenuData | null {
93
+ const id = article.dataset.postId;
94
+ if (!id) return null;
95
+
96
+ const threadId = article.dataset.threadRootId ?? id;
97
+ const threadRootArticle = findThreadRootArticle(threadId) ?? article;
98
+
99
+ return {
100
+ id,
101
+ threadId,
102
+ pinned: article.hasAttribute("data-post-pinned"),
103
+ pinnedInCollection: threadRootArticle.hasAttribute(
104
+ "data-post-pinned-in-collection",
105
+ ),
106
+ featured: article.hasAttribute("data-post-featured"),
107
+ visibility: article.dataset.postVisibility ?? "public",
108
+ isReply: threadId !== id || article.hasAttribute("data-post-reply"),
109
+ isDraft: article.hasAttribute("data-post-draft"),
110
+ };
111
+ }
112
+
81
113
  export class JantPostMenu extends LitElement {
82
114
  static properties = {
83
115
  _open: { state: true },
@@ -89,7 +121,7 @@ export class JantPostMenu extends LitElement {
89
121
  _collections: { state: true },
90
122
  _collectionsLoading: { state: true },
91
123
  _collectionSearch: { state: true },
92
- _postCollectionIds: { state: true },
124
+ _threadCollectionIds: { state: true },
93
125
  _addCollectionPanelOpen: { state: true },
94
126
  };
95
127
 
@@ -102,7 +134,7 @@ export class JantPostMenu extends LitElement {
102
134
  declare _collections: CollectionItem[] | null;
103
135
  declare _collectionsLoading: boolean;
104
136
  declare _collectionSearch: string;
105
- declare _postCollectionIds: string[];
137
+ declare _threadCollectionIds: string[];
106
138
  declare _addCollectionPanelOpen: boolean;
107
139
  declare _triggerEl: HTMLElement | null;
108
140
 
@@ -127,7 +159,7 @@ export class JantPostMenu extends LitElement {
127
159
  this._collections = null;
128
160
  this._collectionsLoading = false;
129
161
  this._collectionSearch = "";
130
- this._postCollectionIds = [];
162
+ this._threadCollectionIds = [];
131
163
  this._addCollectionPanelOpen = false;
132
164
  this._triggerEl = null;
133
165
  }
@@ -246,25 +278,16 @@ export class JantPostMenu extends LitElement {
246
278
  const article = trigger.closest<HTMLElement>("article[data-post]");
247
279
  if (!article) return;
248
280
 
249
- const postId = article.dataset.postId;
250
- if (!postId) return;
281
+ const menuData = readPostMenuData(article);
282
+ if (!menuData) return;
251
283
 
252
284
  // Toggle: close if same post, open if different
253
- if (this._open && this._data?.id === postId) {
285
+ if (this._open && this._data?.id === menuData.id) {
254
286
  this.#close();
255
287
  return;
256
288
  }
257
289
 
258
- this._data = {
259
- id: postId,
260
- pinned: article.hasAttribute("data-post-pinned"),
261
- pinnedInCollection: article.hasAttribute(
262
- "data-post-pinned-in-collection",
263
- ),
264
- featured: article.hasAttribute("data-post-featured"),
265
- visibility: article.dataset.postVisibility ?? "public",
266
- isReply: article.hasAttribute("data-post-reply"),
267
- };
290
+ this._data = menuData;
268
291
 
269
292
  // Position relative to trigger
270
293
  this._triggerEl = trigger;
@@ -472,19 +495,10 @@ export class JantPostMenu extends LitElement {
472
495
  * relative to the post's menu trigger button.
473
496
  */
474
497
  openCollectionsForPost(article: HTMLElement) {
475
- const postId = article.dataset.postId;
476
- if (!postId) return;
477
-
478
- this._data = {
479
- id: postId,
480
- pinned: article.hasAttribute("data-post-pinned"),
481
- pinnedInCollection: article.hasAttribute(
482
- "data-post-pinned-in-collection",
483
- ),
484
- featured: article.hasAttribute("data-post-featured"),
485
- visibility: article.dataset.postVisibility ?? "public",
486
- isReply: article.hasAttribute("data-post-reply"),
487
- };
498
+ const menuData = readPostMenuData(article);
499
+ if (!menuData || menuData.isReply) return;
500
+
501
+ this._data = menuData;
488
502
 
489
503
  const trigger = article.querySelector<HTMLElement>(
490
504
  "[data-post-menu-trigger]",
@@ -518,6 +532,36 @@ export class JantPostMenu extends LitElement {
518
532
  }
519
533
  }
520
534
 
535
+ async #publish() {
536
+ if (!this._data) return;
537
+ const postId = this._data.id;
538
+ const trigger = this._triggerEl;
539
+ this.#close({ restoreFocus: false });
540
+
541
+ const article = document.querySelector<HTMLElement>(
542
+ `article[data-post-id="${postId}"]`,
543
+ );
544
+
545
+ try {
546
+ const res = await fetch(`/api/posts/${postId}`, {
547
+ method: "PUT",
548
+ headers: { "Content-Type": "application/json" },
549
+ body: JSON.stringify({ status: "published" }),
550
+ });
551
+ if (!res.ok) throw new Error();
552
+
553
+ showToast("Draft published.");
554
+ // The badge, the timestamp, and any drafts published alongside this one
555
+ // all change at once — re-render the surface rather than patching it.
556
+ if (!article || !(await refreshArticleView(article))) {
557
+ globalThis.location.reload();
558
+ }
559
+ } catch {
560
+ showToast("Could not publish the draft. Try again.", "error");
561
+ trigger?.focus();
562
+ }
563
+ }
564
+
521
565
  #setVisibility(newVisibility: string) {
522
566
  if (!this._data) return;
523
567
  const postId = this._data.id;
@@ -650,7 +694,7 @@ export class JantPostMenu extends LitElement {
650
694
 
651
695
  #toggleCollectionPin() {
652
696
  if (!this._data) return;
653
- const postId = this._data.id;
697
+ const threadId = this._data.threadId;
654
698
  const collectionId = document.querySelector<HTMLElement>(
655
699
  "[data-collection-id]",
656
700
  )?.dataset.collectionId;
@@ -659,9 +703,7 @@ export class JantPostMenu extends LitElement {
659
703
  const newPinned = !this._data.pinnedInCollection;
660
704
 
661
705
  // Optimistic update
662
- const article = document.querySelector<HTMLElement>(
663
- `article[data-post-id="${postId}"]`,
664
- );
706
+ const article = findThreadRootArticle(threadId);
665
707
  if (article) {
666
708
  if (newPinned) {
667
709
  article.setAttribute("data-post-pinned-in-collection", "");
@@ -677,14 +719,14 @@ export class JantPostMenu extends LitElement {
677
719
  this.#close();
678
720
 
679
721
  const method = newPinned ? "PUT" : "DELETE";
680
- fetch(`/api/collections/${collectionId}/posts/${postId}/pin`, { method })
722
+ fetch(`/api/collections/${collectionId}/threads/${threadId}/pin`, {
723
+ method,
724
+ })
681
725
  .then((res) => {
682
726
  if (!res.ok) throw new Error();
683
727
  })
684
728
  .catch(() => {
685
- const el = document.querySelector<HTMLElement>(
686
- `article[data-post-id="${postId}"]`,
687
- );
729
+ const el = findThreadRootArticle(threadId);
688
730
  if (el) {
689
731
  if (newPinned) {
690
732
  el.removeAttribute("data-post-pinned-in-collection");
@@ -702,8 +744,10 @@ export class JantPostMenu extends LitElement {
702
744
  this.#close({ restoreFocus: false });
703
745
 
704
746
  const confirmed = await showConfirmDialog({
705
- message: "Delete this post permanently? This can't be undone.",
706
- confirmLabel: "Delete",
747
+ message: this._data.isDraft
748
+ ? "Discard this draft permanently? This can't be undone."
749
+ : "Delete this post permanently? This can't be undone.",
750
+ confirmLabel: this._data.isDraft ? "Discard" : "Delete",
707
751
  cancelLabel: "Cancel",
708
752
  tone: "danger",
709
753
  });
@@ -754,7 +798,7 @@ export class JantPostMenu extends LitElement {
754
798
  }
755
799
 
756
800
  async #openCollectionPicker() {
757
- if (!this._data) return;
801
+ if (!this._data || this._data.isReply) return;
758
802
  const postId = this._data.id;
759
803
  this._view = "collections";
760
804
  this._collectionSearch = "";
@@ -776,18 +820,18 @@ export class JantPostMenu extends LitElement {
776
820
  const collectionsData =
777
821
  (await collectionsRes.json()) as CollectionsResponse;
778
822
  const collections = collectionsData.collections ?? [];
779
- let postCollectionIds = this._postCollectionIds;
823
+ let threadCollectionIds = this._threadCollectionIds;
780
824
 
781
825
  if (postRes.ok) {
782
- const postData = (await postRes.json()) as PostCollectionsResponse;
783
- postCollectionIds = postData.collectionIds ?? [];
826
+ const postData = (await postRes.json()) as ThreadCollectionsResponse;
827
+ threadCollectionIds = postData.collectionIds ?? [];
784
828
  }
785
829
  this.#collectionPickerOrder = getSelectedFirstOrder(
786
830
  collections,
787
- postCollectionIds,
831
+ threadCollectionIds,
788
832
  );
789
833
  this._collections = collections;
790
- this._postCollectionIds = postCollectionIds;
834
+ this._threadCollectionIds = threadCollectionIds;
791
835
  } catch {
792
836
  this._collections = this._collections ?? [];
793
837
  showToast("Could not load collections.", "error");
@@ -800,23 +844,23 @@ export class JantPostMenu extends LitElement {
800
844
 
801
845
  #toggleCollection(collectionId: string) {
802
846
  if (!this._data) return;
803
- const postId = this._data.id;
804
- const isSelected = this._postCollectionIds.includes(collectionId);
847
+ const threadId = this._data.threadId;
848
+ const isSelected = this._threadCollectionIds.includes(collectionId);
805
849
 
806
850
  // Optimistic update
807
851
  if (isSelected) {
808
- this._postCollectionIds = this._postCollectionIds.filter(
852
+ this._threadCollectionIds = this._threadCollectionIds.filter(
809
853
  (id) => id !== collectionId,
810
854
  );
811
855
  } else {
812
- this._postCollectionIds = [...this._postCollectionIds, collectionId];
856
+ this._threadCollectionIds = [...this._threadCollectionIds, collectionId];
813
857
  }
814
858
  this.#collectionsDirty = true;
815
859
  showToast(isSelected ? "Removed from collection." : "Added to collection.");
816
860
 
817
861
  // Fire request in background, revert on failure
818
862
  if (isSelected) {
819
- fetch(`/api/collections/${collectionId}/posts/${postId}`, {
863
+ fetch(`/api/collections/${collectionId}/threads/${threadId}`, {
820
864
  method: "DELETE",
821
865
  })
822
866
  .then((res) => {
@@ -825,19 +869,19 @@ export class JantPostMenu extends LitElement {
825
869
  })
826
870
  .catch(() => {
827
871
  // Revert: re-add
828
- if (!this._postCollectionIds.includes(collectionId)) {
829
- this._postCollectionIds = [
830
- ...this._postCollectionIds,
872
+ if (!this._threadCollectionIds.includes(collectionId)) {
873
+ this._threadCollectionIds = [
874
+ ...this._threadCollectionIds,
831
875
  collectionId,
832
876
  ];
833
877
  }
834
878
  showToast("Could not remove from collection. Try again.", "error");
835
879
  });
836
880
  } else {
837
- fetch(`/api/collections/${collectionId}/posts`, {
881
+ fetch(`/api/collections/${collectionId}/threads`, {
838
882
  method: "POST",
839
883
  headers: { "Content-Type": "application/json" },
840
- body: JSON.stringify({ postId }),
884
+ body: JSON.stringify({ threadId }),
841
885
  })
842
886
  .then((res) => {
843
887
  if (!res.ok) {
@@ -849,7 +893,7 @@ export class JantPostMenu extends LitElement {
849
893
  })
850
894
  .catch(() => {
851
895
  // Revert: remove
852
- this._postCollectionIds = this._postCollectionIds.filter(
896
+ this._threadCollectionIds = this._threadCollectionIds.filter(
853
897
  (id) => id !== collectionId,
854
898
  );
855
899
  showToast("Could not add to collection. Try again.", "error");
@@ -920,14 +964,14 @@ export class JantPostMenu extends LitElement {
920
964
 
921
965
  this._collections = [...(this._collections ?? []), newItem];
922
966
 
923
- // Auto-add the post to the newly created collection
967
+ // Auto-add the thread to the newly created collection
924
968
  if (this._data) {
925
- await fetch(`/api/collections/${created.id}/posts`, {
969
+ await fetch(`/api/collections/${created.id}/threads`, {
926
970
  method: "POST",
927
971
  headers: { "Content-Type": "application/json" },
928
- body: JSON.stringify({ postId: this._data.id }),
972
+ body: JSON.stringify({ threadId: this._data.threadId }),
929
973
  });
930
- this._postCollectionIds = [...this._postCollectionIds, created.id];
974
+ this._threadCollectionIds = [...this._threadCollectionIds, created.id];
931
975
  }
932
976
 
933
977
  await this.#refreshComposeCollections();
@@ -983,6 +1027,21 @@ export class JantPostMenu extends LitElement {
983
1027
 
984
1028
  // --- Icons (inline SVG) ---
985
1029
 
1030
+ #iconPublish() {
1031
+ return html`<svg
1032
+ xmlns="http://www.w3.org/2000/svg"
1033
+ viewBox="0 0 24 24"
1034
+ fill="none"
1035
+ stroke="currentColor"
1036
+ stroke-width="1.75"
1037
+ stroke-linecap="round"
1038
+ stroke-linejoin="round"
1039
+ >
1040
+ <path d="M12 19V5" />
1041
+ <path d="m5 12 7-7 7 7" />
1042
+ </svg>`;
1043
+ }
1044
+
986
1045
  #iconEdit() {
987
1046
  return html`<svg
988
1047
  xmlns="http://www.w3.org/2000/svg"
@@ -1193,7 +1252,7 @@ export class JantPostMenu extends LitElement {
1193
1252
  ? html`<div class="post-menu-picker-empty">Loading...</div>`
1194
1253
  : filtered.length > 0
1195
1254
  ? filtered.map((c) => {
1196
- const selected = this._postCollectionIds.includes(c.id);
1255
+ const selected = this._threadCollectionIds.includes(c.id);
1197
1256
  return html`
1198
1257
  <button
1199
1258
  type="button"
@@ -1492,19 +1551,37 @@ export class JantPostMenu extends LitElement {
1492
1551
  <span class="post-menu-item-trailing">${this.#iconEdit()}</span>
1493
1552
  </button>
1494
1553
 
1495
- <button
1496
- type="button"
1497
- role="menuitem"
1498
- class="post-menu-item"
1499
- data-post-menu-open-collections
1500
- @click=${() => this.#openCollectionPicker()}
1501
- >
1502
- <span class="post-menu-item-label">Add to collection</span>
1503
- <span class="post-menu-item-trailing post-menu-item-chevron"
1504
- >${this.#iconChevronRight()}</span
1505
- >
1506
- </button>
1507
-
1554
+ ${this._data.isDraft
1555
+ ? html`
1556
+ <button
1557
+ type="button"
1558
+ role="menuitem"
1559
+ class="post-menu-item"
1560
+ @click=${() => this.#publish()}
1561
+ >
1562
+ <span class="post-menu-item-label">Publish</span>
1563
+ <span class="post-menu-item-trailing"
1564
+ >${this.#iconPublish()}</span
1565
+ >
1566
+ </button>
1567
+ `
1568
+ : nothing}
1569
+ ${this._data.isReply
1570
+ ? nothing
1571
+ : html`
1572
+ <button
1573
+ type="button"
1574
+ role="menuitem"
1575
+ class="post-menu-item"
1576
+ data-post-menu-open-collections
1577
+ @click=${() => this.#openCollectionPicker()}
1578
+ >
1579
+ <span class="post-menu-item-label">Add to collection</span>
1580
+ <span class="post-menu-item-trailing post-menu-item-chevron"
1581
+ >${this.#iconChevronRight()}</span
1582
+ >
1583
+ </button>
1584
+ `}
1508
1585
  ${this._data.isReply
1509
1586
  ? nothing
1510
1587
  : html`
@@ -1527,24 +1604,27 @@ export class JantPostMenu extends LitElement {
1527
1604
  </div>
1528
1605
 
1529
1606
  <div class="post-menu-section">
1530
- <button
1531
- type="button"
1532
- role="menuitem"
1533
- class="post-menu-item"
1534
- @click=${() => this.#setFeatured(!isFeatured)}
1535
- >
1536
- <span class="post-menu-item-label"
1537
- >${isFeatured
1538
- ? "Remove from Featured"
1539
- : "Add to Featured"}</span
1540
- >
1541
- <span class="post-menu-item-trailing"
1542
- >${isFeatured
1543
- ? this.#iconFeaturedOff()
1544
- : this.#iconFeatured()}</span
1545
- >
1546
- </button>
1547
-
1607
+ ${this._data.isDraft
1608
+ ? nothing
1609
+ : html`
1610
+ <button
1611
+ type="button"
1612
+ role="menuitem"
1613
+ class="post-menu-item"
1614
+ @click=${() => this.#setFeatured(!isFeatured)}
1615
+ >
1616
+ <span class="post-menu-item-label"
1617
+ >${isFeatured
1618
+ ? "Remove from Featured"
1619
+ : "Add to Featured"}</span
1620
+ >
1621
+ <span class="post-menu-item-trailing"
1622
+ >${isFeatured
1623
+ ? this.#iconFeaturedOff()
1624
+ : this.#iconFeatured()}</span
1625
+ >
1626
+ </button>
1627
+ `}
1548
1628
  ${this._data.isReply
1549
1629
  ? nothing
1550
1630
  : html`
@@ -1562,7 +1642,7 @@ export class JantPostMenu extends LitElement {
1562
1642
  >
1563
1643
  </button>
1564
1644
  `}
1565
- ${collectionId
1645
+ ${collectionId && !this._data.isReply
1566
1646
  ? html`
1567
1647
  <button
1568
1648
  type="button"
@@ -1592,7 +1672,9 @@ export class JantPostMenu extends LitElement {
1592
1672
  class="post-menu-item post-menu-item-danger"
1593
1673
  @click=${() => this.#delete()}
1594
1674
  >
1595
- <span class="post-menu-item-label">Delete</span>
1675
+ <span class="post-menu-item-label"
1676
+ >${this._data.isDraft ? "Discard" : "Delete"}</span
1677
+ >
1596
1678
  <span class="post-menu-item-trailing">${this.#iconTrash()}</span>
1597
1679
  </button>
1598
1680
  </div>
@@ -3,18 +3,27 @@
3
3
  */
4
4
 
5
5
  import type { SystemNavKey } from "../../types/constants.js";
6
+ import type { CollectionFormLabels } from "./collection-types.js";
6
7
 
7
8
  export interface NavManagerItem {
8
9
  id: string;
9
- type: "link" | "system" | "collection";
10
+ type: "link" | "system" | "collection" | "page";
10
11
  systemKey?: SystemNavKey;
11
12
  collectionId?: string;
13
+ postId?: string;
12
14
  label: string;
13
15
  displayLabel?: string;
14
16
  url: string;
15
17
  placement?: "header" | "more";
16
18
  }
17
19
 
20
+ export interface NavManagerPage {
21
+ id: string;
22
+ title: string;
23
+ slug: string;
24
+ updatedAt: number;
25
+ }
26
+
18
27
  export interface SystemNavConfig {
19
28
  key: SystemNavKey;
20
29
  label: string;
@@ -36,8 +45,9 @@ export interface NavManagerSuggestedLink {
36
45
  url: string;
37
46
  targetType: "page" | "collection" | "archive";
38
47
  targetLabel: string;
39
- navItemType: "link" | "collection";
48
+ navItemType: "link" | "collection" | "page";
40
49
  collectionId?: string;
50
+ postId?: string;
41
51
  }
42
52
 
43
53
  export interface NavManagerLabels {
@@ -45,6 +55,7 @@ export interface NavManagerLabels {
45
55
  navigationItems: string;
46
56
  emptyState: string;
47
57
  link: string;
58
+ page: string;
48
59
  system: string;
49
60
  toggleEdit: string;
50
61
  label: string;
@@ -53,6 +64,7 @@ export interface NavManagerLabels {
53
64
  delete: string;
54
65
  remove: string;
55
66
  confirmDeleteLink: string;
67
+ confirmDeletePage: string;
56
68
  orderSaved: string;
57
69
  labelRequired: string;
58
70
  saveFailed: string;
@@ -68,12 +80,49 @@ export interface NavManagerLabels {
68
80
  suggestedLinksDescription: string;
69
81
  addSuggestedLink: string;
70
82
  suggestedLinkAdded: string;
83
+ addPageToNavigation: string;
84
+ addPageDescription: string;
85
+ addPage: string;
86
+ searchPages: string;
87
+ recentPages: string;
88
+ searchingPages: string;
89
+ noMatchingPages: string;
90
+ noPages: string;
91
+ pageSearchFailed: string;
92
+ createNewPage: string;
93
+ createPage: string;
94
+ createPageDescription: string;
95
+ pageTitle: string;
96
+ pageAddress: string;
97
+ pageVisibilityHint: string;
98
+ titleRequired: string;
99
+ slugInvalid: string;
100
+ slugReserved: string;
101
+ slugTooLong: string;
102
+ slugUnavailable: string;
103
+ checkingAddress: string;
104
+ creatingPage: string;
105
+ createPageFailed: string;
106
+ pageCreated: string;
107
+ pageCreatedDescription: string;
108
+ addToNavigation: string;
109
+ editPage: string;
110
+ pageAdded: string;
111
+ back: string;
71
112
  collection: string;
72
113
  addCollection: string;
73
114
  addCollectionToNavigation: string;
74
115
  addCollectionDescription: string;
75
116
  allCollectionsAdded: string;
76
117
  noCollections: string;
118
+ createNewCollection: string;
119
+ createCollection: string;
120
+ creatingCollection: string;
121
+ createCollectionFailed: string;
122
+ collectionCreatedDescription: string;
123
+ editCollection: string;
124
+ collectionAdded: string;
125
+ collectionFormLabels: CollectionFormLabels;
77
126
  confirmDeleteCollection: string;
78
127
  headerSection: string;
79
128
  moreSection: string;
@@ -59,7 +59,7 @@ export interface PostFormInitial {
59
59
  mediaIds: string[];
60
60
  }
61
61
 
62
- export interface PostCollectionOption {
62
+ export interface ThreadCollectionOption {
63
63
  id: number;
64
64
  title: string;
65
65
  }