@jant/core 0.3.27 → 0.3.29

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 (314) hide show
  1. package/bin/reset-password.js +22 -0
  2. package/dist/client/client.css +1 -0
  3. package/dist/client/client.js +31561 -0
  4. package/dist/index.js +15209 -15
  5. package/package.json +25 -15
  6. package/src/__tests__/helpers/app.ts +19 -3
  7. package/src/__tests__/helpers/db.ts +44 -0
  8. package/src/__tests__/helpers/lingui-core-macro-mock.ts +33 -0
  9. package/src/app.tsx +111 -174
  10. package/src/client.ts +13 -0
  11. package/src/db/migrations/0007_post_collections_m2m.sql +94 -0
  12. package/src/db/migrations/0008_add_collection_dividers.sql +8 -0
  13. package/src/db/migrations/0009_drop_collection_show_divider.sql +2 -0
  14. package/src/db/migrations/0010_add_performance_indexes.sql +16 -0
  15. package/src/db/schema.ts +24 -4
  16. package/src/i18n/locales/en.po +810 -385
  17. package/src/i18n/locales/en.ts +1 -1
  18. package/src/i18n/locales/zh-Hans.po +733 -522
  19. package/src/i18n/locales/zh-Hans.ts +1 -1
  20. package/src/i18n/locales/zh-Hant.po +733 -522
  21. package/src/i18n/locales/zh-Hant.ts +1 -1
  22. package/src/i18n/middleware.ts +7 -11
  23. package/src/index.ts +1 -1
  24. package/src/lib/__tests__/icons.test.ts +178 -0
  25. package/src/lib/__tests__/resolve-config.test.ts +184 -0
  26. package/src/lib/__tests__/schemas.test.ts +12 -6
  27. package/src/lib/__tests__/theme.test.ts +62 -0
  28. package/src/lib/__tests__/timezones.test.ts +1 -1
  29. package/src/lib/__tests__/url.test.ts +12 -0
  30. package/src/lib/__tests__/view.test.ts +1 -5
  31. package/src/lib/avatar-upload.ts +18 -10
  32. package/src/lib/collection-form-bridge.ts +52 -0
  33. package/src/lib/collections-reorder.ts +28 -0
  34. package/src/lib/compose-bridge.ts +251 -0
  35. package/src/lib/errors.ts +116 -0
  36. package/src/lib/excerpt.ts +1 -1
  37. package/src/lib/favicon.ts +3 -5
  38. package/src/lib/html.ts +22 -0
  39. package/src/lib/icon-catalog.ts +181 -0
  40. package/src/lib/icons.ts +202 -0
  41. package/src/lib/navigation.ts +18 -33
  42. package/src/lib/pagination.ts +3 -2
  43. package/src/lib/post-form-bridge.ts +136 -0
  44. package/src/lib/render.tsx +11 -4
  45. package/src/lib/resolve-config.ts +157 -0
  46. package/src/lib/schemas.ts +76 -12
  47. package/src/lib/settings-bridge.ts +139 -0
  48. package/src/lib/storage.ts +37 -16
  49. package/src/lib/theme.ts +5 -7
  50. package/src/lib/timeline.ts +4 -8
  51. package/src/lib/toast.ts +134 -0
  52. package/src/lib/upload.ts +71 -0
  53. package/src/lib/url.ts +9 -1
  54. package/src/lib/version.ts +16 -0
  55. package/src/lib/view.ts +9 -10
  56. package/src/middleware/__tests__/auth.test.ts +6 -28
  57. package/src/middleware/__tests__/onboarding.test.ts +1 -1
  58. package/src/middleware/auth.ts +6 -12
  59. package/src/middleware/config.ts +51 -0
  60. package/src/middleware/error-handler.ts +56 -0
  61. package/src/middleware/onboarding.ts +1 -1
  62. package/src/preset.css +6 -0
  63. package/src/routes/__tests__/compose.test.ts +104 -17
  64. package/src/routes/api/__tests__/collections.test.ts +93 -2
  65. package/src/routes/api/__tests__/posts.test.ts +2 -1
  66. package/src/routes/api/__tests__/settings.test.ts +1 -1
  67. package/src/routes/api/collections.ts +64 -68
  68. package/src/routes/api/nav-items.ts +21 -59
  69. package/src/routes/api/pages.ts +18 -46
  70. package/src/routes/api/posts.ts +64 -86
  71. package/src/routes/api/search.ts +6 -4
  72. package/src/routes/api/settings.ts +8 -24
  73. package/src/routes/api/upload.ts +55 -53
  74. package/src/routes/auth/__tests__/setup.test.ts +118 -0
  75. package/src/routes/auth/reset.tsx +17 -66
  76. package/src/routes/auth/setup.tsx +67 -11
  77. package/src/routes/auth/signin.tsx +44 -8
  78. package/src/routes/compose.tsx +194 -0
  79. package/src/routes/dash/__tests__/font-theme.test.ts +110 -0
  80. package/src/routes/dash/__tests__/pages.test.ts +2 -2
  81. package/src/routes/dash/__tests__/settings-avatar.test.ts +23 -12
  82. package/src/routes/dash/appearance.tsx +173 -0
  83. package/src/routes/dash/collections.tsx +80 -14
  84. package/src/routes/dash/index.tsx +12 -14
  85. package/src/routes/dash/media.tsx +46 -49
  86. package/src/routes/dash/pages.tsx +85 -37
  87. package/src/routes/dash/posts.tsx +60 -23
  88. package/src/routes/dash/redirects.tsx +43 -33
  89. package/src/routes/dash/settings.tsx +234 -214
  90. package/src/routes/feed/__tests__/rss.test.ts +7 -3
  91. package/src/routes/feed/rss.ts +11 -16
  92. package/src/routes/feed/sitemap.ts +15 -9
  93. package/src/routes/pages/__tests__/collections.test.ts +9 -8
  94. package/src/routes/pages/archive.tsx +2 -2
  95. package/src/routes/pages/collection.tsx +76 -9
  96. package/src/routes/pages/collections.tsx +3 -1
  97. package/src/routes/pages/featured.tsx +2 -2
  98. package/src/routes/pages/home.tsx +3 -3
  99. package/src/routes/pages/latest.tsx +2 -2
  100. package/src/routes/pages/page.tsx +2 -2
  101. package/src/routes/pages/post.tsx +2 -2
  102. package/src/routes/pages/search.tsx +2 -2
  103. package/src/services/__tests__/collection.test.ts +324 -34
  104. package/src/services/__tests__/media.test.ts +1 -1
  105. package/src/services/__tests__/page.test.ts +116 -1
  106. package/src/services/auth.ts +88 -0
  107. package/src/services/collection.ts +169 -30
  108. package/src/services/index.ts +8 -3
  109. package/src/services/media.ts +39 -12
  110. package/src/services/navigation.ts +17 -5
  111. package/src/services/page.ts +24 -4
  112. package/src/services/post.ts +87 -19
  113. package/src/services/search.ts +0 -1
  114. package/src/services/settings.ts +21 -13
  115. package/src/style.css +3 -0
  116. package/src/styles/components.css +42 -1
  117. package/src/styles/tokens.css +4 -0
  118. package/src/styles/ui.css +902 -73
  119. package/src/types/app-context.ts +25 -0
  120. package/src/types/bindings.ts +1 -0
  121. package/src/types/config.ts +60 -23
  122. package/src/types/entities.ts +12 -2
  123. package/src/types/lingui-react-macro.d.ts +3 -3
  124. package/src/types/operations.ts +2 -4
  125. package/src/types/views.ts +1 -3
  126. package/src/ui/__tests__/font-themes.test.ts +27 -8
  127. package/src/ui/color-themes.ts +1 -1
  128. package/src/ui/components/__tests__/jant-collection-form.test.ts +153 -0
  129. package/src/ui/components/__tests__/jant-compose-dialog.test.ts +512 -0
  130. package/src/ui/components/__tests__/jant-compose-editor.test.ts +272 -0
  131. package/src/ui/components/__tests__/jant-post-form.test.ts +172 -0
  132. package/src/ui/components/__tests__/jant-settings-avatar.test.ts +235 -0
  133. package/src/ui/components/__tests__/jant-settings-general.test.ts +319 -0
  134. package/src/ui/components/collection-types.ts +45 -0
  135. package/src/ui/components/compose-types.ts +75 -0
  136. package/src/ui/components/jant-collection-form.ts +512 -0
  137. package/src/ui/components/jant-compose-dialog.ts +494 -0
  138. package/src/ui/components/jant-compose-editor.ts +799 -0
  139. package/src/ui/components/jant-post-form.ts +290 -0
  140. package/src/ui/components/jant-settings-avatar.ts +231 -0
  141. package/src/ui/components/jant-settings-general.ts +436 -0
  142. package/src/ui/components/post-form-template.ts +260 -0
  143. package/src/ui/components/post-form-types.ts +87 -0
  144. package/src/ui/components/settings-types.ts +62 -0
  145. package/src/ui/compose/ComposeDialog.tsx +141 -385
  146. package/src/ui/compose/ComposePrompt.tsx +3 -3
  147. package/src/ui/dash/PostList.tsx +55 -61
  148. package/src/ui/dash/appearance/AdvancedContent.tsx +80 -0
  149. package/src/ui/dash/appearance/AppearanceNav.tsx +56 -0
  150. package/src/ui/dash/appearance/ColorThemeContent.tsx +129 -0
  151. package/src/ui/dash/appearance/FontThemeContent.tsx +98 -0
  152. package/src/ui/dash/collections/CollectionForm.tsx +130 -117
  153. package/src/ui/dash/collections/CollectionsListContent.tsx +102 -41
  154. package/src/ui/dash/collections/IconPickerGrid.tsx +50 -0
  155. package/src/ui/dash/collections/ViewCollectionContent.tsx +14 -3
  156. package/src/ui/dash/index.ts +1 -1
  157. package/src/ui/dash/posts/PostForm.tsx +248 -0
  158. package/src/ui/dash/settings/AccountContent.tsx +69 -80
  159. package/src/ui/dash/settings/GeneralContent.tsx +159 -478
  160. package/src/ui/dash/settings/SettingsNav.tsx +4 -4
  161. package/src/ui/font-themes.ts +115 -32
  162. package/src/ui/layouts/BaseLayout.tsx +49 -19
  163. package/src/ui/layouts/DashLayout.tsx +14 -9
  164. package/src/ui/layouts/SiteLayout.tsx +38 -23
  165. package/src/ui/pages/CollectionPage.tsx +12 -2
  166. package/src/ui/pages/CollectionsPage.tsx +27 -27
  167. package/src/ui/pages/HomePage.tsx +15 -6
  168. package/src/ui/pages/SearchPage.tsx +1 -2
  169. package/src/ui/shared/CollectionsSidebar.tsx +59 -0
  170. package/src/ui/shared/Pagination.tsx +2 -2
  171. package/dist/app.js +0 -267
  172. package/dist/auth.js +0 -39
  173. package/dist/client.js +0 -13
  174. package/dist/db/index.js +0 -10
  175. package/dist/db/schema.js +0 -224
  176. package/dist/i18n/Trans.js +0 -24
  177. package/dist/i18n/context.js +0 -58
  178. package/dist/i18n/detect.js +0 -26
  179. package/dist/i18n/i18n.js +0 -49
  180. package/dist/i18n/index.js +0 -44
  181. package/dist/i18n/locales/en.js +0 -1
  182. package/dist/i18n/locales/zh-Hans.js +0 -1
  183. package/dist/i18n/locales/zh-Hant.js +0 -1
  184. package/dist/i18n/locales.js +0 -13
  185. package/dist/i18n/middleware.js +0 -30
  186. package/dist/lib/avatar-upload.js +0 -134
  187. package/dist/lib/config.js +0 -143
  188. package/dist/lib/constants.js +0 -50
  189. package/dist/lib/excerpt.js +0 -76
  190. package/dist/lib/favicon.js +0 -102
  191. package/dist/lib/feed.js +0 -123
  192. package/dist/lib/image-processor.js +0 -187
  193. package/dist/lib/image.js +0 -97
  194. package/dist/lib/index.js +0 -7
  195. package/dist/lib/markdown.js +0 -83
  196. package/dist/lib/media-helpers.js +0 -49
  197. package/dist/lib/media-upload.js +0 -104
  198. package/dist/lib/nav-reorder.js +0 -27
  199. package/dist/lib/navigation.js +0 -79
  200. package/dist/lib/pagination.js +0 -44
  201. package/dist/lib/render.js +0 -53
  202. package/dist/lib/schemas.js +0 -174
  203. package/dist/lib/sqid.js +0 -72
  204. package/dist/lib/sse.js +0 -218
  205. package/dist/lib/storage.js +0 -164
  206. package/dist/lib/theme.js +0 -65
  207. package/dist/lib/time.js +0 -159
  208. package/dist/lib/timeline.js +0 -95
  209. package/dist/lib/timezones.js +0 -388
  210. package/dist/lib/url.js +0 -89
  211. package/dist/lib/view.js +0 -217
  212. package/dist/middleware/auth.js +0 -52
  213. package/dist/middleware/onboarding.js +0 -41
  214. package/dist/routes/api/collections.js +0 -124
  215. package/dist/routes/api/nav-items.js +0 -104
  216. package/dist/routes/api/pages.js +0 -91
  217. package/dist/routes/api/posts.js +0 -218
  218. package/dist/routes/api/search.js +0 -48
  219. package/dist/routes/api/settings.js +0 -68
  220. package/dist/routes/api/upload.js +0 -246
  221. package/dist/routes/auth/reset.js +0 -221
  222. package/dist/routes/auth/setup.js +0 -194
  223. package/dist/routes/auth/signin.js +0 -176
  224. package/dist/routes/compose.js +0 -48
  225. package/dist/routes/dash/collections.js +0 -115
  226. package/dist/routes/dash/index.js +0 -118
  227. package/dist/routes/dash/media.js +0 -106
  228. package/dist/routes/dash/pages.js +0 -294
  229. package/dist/routes/dash/posts.js +0 -244
  230. package/dist/routes/dash/redirects.js +0 -257
  231. package/dist/routes/dash/settings.js +0 -379
  232. package/dist/routes/feed/rss.js +0 -62
  233. package/dist/routes/feed/sitemap.js +0 -49
  234. package/dist/routes/pages/archive.js +0 -62
  235. package/dist/routes/pages/collection.js +0 -34
  236. package/dist/routes/pages/collections.js +0 -28
  237. package/dist/routes/pages/featured.js +0 -36
  238. package/dist/routes/pages/home.js +0 -64
  239. package/dist/routes/pages/latest.js +0 -45
  240. package/dist/routes/pages/page.js +0 -68
  241. package/dist/routes/pages/post.js +0 -44
  242. package/dist/routes/pages/search.js +0 -54
  243. package/dist/services/collection.js +0 -109
  244. package/dist/services/index.js +0 -24
  245. package/dist/services/media.js +0 -117
  246. package/dist/services/navigation.js +0 -91
  247. package/dist/services/page.js +0 -84
  248. package/dist/services/post.js +0 -229
  249. package/dist/services/redirect.js +0 -48
  250. package/dist/services/search.js +0 -67
  251. package/dist/services/settings.js +0 -68
  252. package/dist/types/bindings.js +0 -3
  253. package/dist/types/config.js +0 -147
  254. package/dist/types/constants.js +0 -27
  255. package/dist/types/entities.js +0 -3
  256. package/dist/types/lingui-react-macro.d.js +0 -9
  257. package/dist/types/operations.js +0 -3
  258. package/dist/types/props.js +0 -3
  259. package/dist/types/sortablejs.d.js +0 -5
  260. package/dist/types/views.js +0 -5
  261. package/dist/types.js +0 -11
  262. package/dist/ui/color-themes.js +0 -268
  263. package/dist/ui/compose/ComposeDialog.js +0 -467
  264. package/dist/ui/compose/ComposePrompt.js +0 -55
  265. package/dist/ui/dash/ActionButtons.js +0 -46
  266. package/dist/ui/dash/CrudPageHeader.js +0 -22
  267. package/dist/ui/dash/DangerZone.js +0 -36
  268. package/dist/ui/dash/FormatBadge.js +0 -27
  269. package/dist/ui/dash/ListItemRow.js +0 -21
  270. package/dist/ui/dash/PageForm.js +0 -195
  271. package/dist/ui/dash/PostForm.js +0 -395
  272. package/dist/ui/dash/PostList.js +0 -83
  273. package/dist/ui/dash/StatusBadge.js +0 -46
  274. package/dist/ui/dash/collections/CollectionForm.js +0 -152
  275. package/dist/ui/dash/collections/CollectionsListContent.js +0 -68
  276. package/dist/ui/dash/collections/ViewCollectionContent.js +0 -96
  277. package/dist/ui/dash/index.js +0 -10
  278. package/dist/ui/dash/media/MediaListContent.js +0 -166
  279. package/dist/ui/dash/media/ViewMediaContent.js +0 -212
  280. package/dist/ui/dash/pages/LinkFormContent.js +0 -130
  281. package/dist/ui/dash/pages/UnifiedPagesContent.js +0 -193
  282. package/dist/ui/dash/settings/AccountContent.js +0 -209
  283. package/dist/ui/dash/settings/AppearanceContent.js +0 -259
  284. package/dist/ui/dash/settings/GeneralContent.js +0 -536
  285. package/dist/ui/dash/settings/SettingsNav.js +0 -41
  286. package/dist/ui/feed/LinkCard.js +0 -72
  287. package/dist/ui/feed/NoteCard.js +0 -58
  288. package/dist/ui/feed/QuoteCard.js +0 -63
  289. package/dist/ui/feed/ThreadPreview.js +0 -48
  290. package/dist/ui/feed/TimelineFeed.js +0 -41
  291. package/dist/ui/feed/TimelineItem.js +0 -27
  292. package/dist/ui/font-themes.js +0 -36
  293. package/dist/ui/layouts/BaseLayout.js +0 -153
  294. package/dist/ui/layouts/DashLayout.js +0 -141
  295. package/dist/ui/layouts/SiteLayout.js +0 -169
  296. package/dist/ui/pages/ArchivePage.js +0 -143
  297. package/dist/ui/pages/CollectionPage.js +0 -70
  298. package/dist/ui/pages/CollectionsPage.js +0 -76
  299. package/dist/ui/pages/FeaturedPage.js +0 -24
  300. package/dist/ui/pages/HomePage.js +0 -24
  301. package/dist/ui/pages/PostPage.js +0 -55
  302. package/dist/ui/pages/SearchPage.js +0 -122
  303. package/dist/ui/pages/SinglePage.js +0 -23
  304. package/dist/ui/shared/EmptyState.js +0 -27
  305. package/dist/ui/shared/MediaGallery.js +0 -35
  306. package/dist/ui/shared/Pagination.js +0 -195
  307. package/dist/ui/shared/ThreadView.js +0 -108
  308. package/dist/ui/shared/index.js +0 -5
  309. package/dist/vendor/datastar.js +0 -1606
  310. package/src/lib/__tests__/config.test.ts +0 -192
  311. package/src/lib/config.ts +0 -167
  312. package/src/routes/compose.ts +0 -63
  313. package/src/ui/dash/PostForm.tsx +0 -360
  314. package/src/ui/dash/settings/AppearanceContent.tsx +0 -254
@@ -1,58 +0,0 @@
1
- /**
2
- * Note Card
3
- *
4
- * Without title: plain text note with full date in footer.
5
- * With title: article-style rendering with summary excerpt and "Read more" link.
6
- */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
7
- import { MediaGallery } from "../shared/MediaGallery.js";
8
- export const NoteCard = ({ post, compact })=>{
9
- const isArticle = !!post.title;
10
- const displayHtml = isArticle ? post.summaryHtml : post.bodyHtml;
11
- return /*#__PURE__*/ _jsxs("article", {
12
- class: `h-entry${compact ? " feed-compact" : ""}`,
13
- "data-post": true,
14
- "data-format": "note",
15
- children: [
16
- isArticle && /*#__PURE__*/ _jsx("h2", {
17
- class: `p-name font-semibold ${compact ? "text-sm" : "text-base"} mb-1`,
18
- children: /*#__PURE__*/ _jsx("a", {
19
- href: post.permalink,
20
- class: "u-url hover:underline",
21
- children: post.title
22
- })
23
- }),
24
- displayHtml && /*#__PURE__*/ _jsx("div", {
25
- class: `e-content prose ${compact ? "prose-sm" : isArticle ? "text-muted-foreground" : ""}`,
26
- "data-post-body": true,
27
- dangerouslySetInnerHTML: {
28
- __html: displayHtml
29
- }
30
- }),
31
- !compact && post.media.length > 0 && /*#__PURE__*/ _jsx("div", {
32
- class: "mt-3",
33
- "data-post-media": true,
34
- children: /*#__PURE__*/ _jsx(MediaGallery, {
35
- attachments: post.media
36
- })
37
- }),
38
- !compact && isArticle && post.summaryHasMore && /*#__PURE__*/ _jsx("a", {
39
- href: post.permalink,
40
- class: "text-sm text-muted-foreground hover:underline mt-1 inline-block",
41
- children: "Read more →"
42
- }),
43
- /*#__PURE__*/ _jsx("footer", {
44
- class: "mt-2",
45
- "data-post-meta": true,
46
- children: /*#__PURE__*/ _jsx("a", {
47
- href: post.permalink,
48
- class: "u-url text-xs text-muted-foreground hover:underline",
49
- children: /*#__PURE__*/ _jsx("time", {
50
- class: "dt-published",
51
- datetime: post.publishedAt,
52
- children: post.publishedAtFormatted
53
- })
54
- })
55
- })
56
- ]
57
- });
58
- };
@@ -1,63 +0,0 @@
1
- /**
2
- * Quote Card
3
- *
4
- * Left-border accent blockquote with full date in footer.
5
- *
6
- * Fields:
7
- * - quoteText: the quoted text
8
- * - title: attribution (who said it)
9
- * - url: source link
10
- * - bodyHtml: commentary
11
- */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
12
- export const QuoteCard = ({ post, compact })=>{
13
- return /*#__PURE__*/ _jsxs("article", {
14
- class: `h-entry${compact ? " feed-compact" : ""}`,
15
- "data-post": true,
16
- "data-format": "quote",
17
- children: [
18
- post.quoteText && /*#__PURE__*/ _jsx("blockquote", {
19
- class: "feed-quote",
20
- children: /*#__PURE__*/ _jsx("div", {
21
- class: `e-content ${compact ? "text-sm" : "text-base"} leading-relaxed`,
22
- children: post.quoteText
23
- })
24
- }),
25
- !compact && (post.title || post.url) && /*#__PURE__*/ _jsxs("div", {
26
- class: "mt-2 text-sm text-muted-foreground",
27
- children: [
28
- "—",
29
- " ",
30
- post.url ? /*#__PURE__*/ _jsx("a", {
31
- href: post.url,
32
- class: "hover:underline",
33
- target: "_blank",
34
- rel: "noopener noreferrer",
35
- children: post.title || "Source"
36
- }) : /*#__PURE__*/ _jsx("span", {
37
- children: post.title
38
- })
39
- ]
40
- }),
41
- !compact && post.bodyHtml && /*#__PURE__*/ _jsx("div", {
42
- class: "mt-3 prose text-muted-foreground",
43
- "data-post-body": true,
44
- dangerouslySetInnerHTML: {
45
- __html: post.bodyHtml
46
- }
47
- }),
48
- /*#__PURE__*/ _jsx("footer", {
49
- class: "mt-2",
50
- "data-post-meta": true,
51
- children: /*#__PURE__*/ _jsx("a", {
52
- href: post.permalink,
53
- class: "u-url text-xs text-muted-foreground hover:underline",
54
- children: /*#__PURE__*/ _jsx("time", {
55
- class: "dt-published",
56
- datetime: post.publishedAt,
57
- children: post.publishedAtFormatted
58
- })
59
- })
60
- })
61
- ]
62
- });
63
- };
@@ -1,48 +0,0 @@
1
- /**
2
- * Thread Preview
3
- *
4
- * Root post + vertical line connector + compact replies underneath.
5
- */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
6
- import { useLingui as $_useLingui } from "@jant/core/i18n";
7
- import { TimelineItem } from "./TimelineItem.js";
8
- import { TimelineItemFromPost } from "./TimelineItem.js";
9
- export const ThreadPreview = ({ rootPost, previewReplies, totalReplyCount })=>{
10
- const { i18n: $__i18n, _: $__ } = $_useLingui();
11
- const remainingCount = totalReplyCount - previewReplies.length;
12
- return /*#__PURE__*/ _jsxs("div", {
13
- children: [
14
- /*#__PURE__*/ _jsx(TimelineItem, {
15
- item: {
16
- post: rootPost
17
- }
18
- }),
19
- previewReplies.length > 0 && /*#__PURE__*/ _jsxs("div", {
20
- class: "feed-replies",
21
- children: [
22
- previewReplies.map((reply)=>/*#__PURE__*/ _jsx("div", {
23
- class: "feed-reply",
24
- children: /*#__PURE__*/ _jsx(TimelineItemFromPost, {
25
- post: reply,
26
- compact: true
27
- })
28
- }, reply.id)),
29
- remainingCount > 0 && /*#__PURE__*/ _jsx("div", {
30
- class: "feed-reply",
31
- children: /*#__PURE__*/ _jsx("a", {
32
- href: rootPost.permalink,
33
- class: "text-sm text-muted-foreground hover:text-foreground hover:underline",
34
- children: $__i18n._({
35
- id: "smzF8S",
36
- message: "Show {remainingCount} more {0}",
37
- values: {
38
- remainingCount: remainingCount,
39
- 0: remainingCount === 1 ? "reply" : "replies"
40
- }
41
- })
42
- })
43
- })
44
- ]
45
- })
46
- ]
47
- });
48
- };
@@ -1,41 +0,0 @@
1
- /**
2
- * Timeline Feed
3
- *
4
- * Flat list of posts separated by simple dividers.
5
- */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
6
- import { TimelineItem } from "./TimelineItem.js";
7
- import { ThreadPreview } from "./ThreadPreview.js";
8
- import { PagePagination } from "../shared/Pagination.js";
9
- export const TimelineFeed = ({ items, currentPage, totalPages })=>{
10
- return /*#__PURE__*/ _jsxs("div", {
11
- "data-feed": true,
12
- children: [
13
- /*#__PURE__*/ _jsx("div", {
14
- id: "timeline-feed",
15
- children: /*#__PURE__*/ _jsx("div", {
16
- id: "timeline-items",
17
- class: "flex flex-col",
18
- children: items.map((item, i)=>/*#__PURE__*/ _jsxs("div", {
19
- children: [
20
- i > 0 && /*#__PURE__*/ _jsx("hr", {
21
- class: "feed-divider"
22
- }),
23
- item.threadPreview ? /*#__PURE__*/ _jsx(ThreadPreview, {
24
- rootPost: item.post,
25
- previewReplies: item.threadPreview.replies,
26
- totalReplyCount: item.threadPreview.totalReplyCount
27
- }) : /*#__PURE__*/ _jsx(TimelineItem, {
28
- item: item
29
- })
30
- ]
31
- }, item.post.id))
32
- })
33
- }),
34
- currentPage !== undefined && totalPages !== undefined && totalPages > 1 && /*#__PURE__*/ _jsx(PagePagination, {
35
- baseUrl: "/",
36
- currentPage: currentPage,
37
- totalPages: totalPages
38
- })
39
- ]
40
- });
41
- };
@@ -1,27 +0,0 @@
1
- /**
2
- * Timeline Item
3
- *
4
- * Dispatches to the correct card component based on post format.
5
- */ import { jsx as _jsx } from "hono/jsx/jsx-runtime";
6
- import { NoteCard } from "./NoteCard.js";
7
- import { LinkCard } from "./LinkCard.js";
8
- import { QuoteCard } from "./QuoteCard.js";
9
- const CARD_MAP = {
10
- note: NoteCard,
11
- link: LinkCard,
12
- quote: QuoteCard
13
- };
14
- export const TimelineItem = ({ item, compact })=>{
15
- const Card = CARD_MAP[item.post.format];
16
- return /*#__PURE__*/ _jsx(Card, {
17
- post: item.post,
18
- compact: compact
19
- });
20
- };
21
- export const TimelineItemFromPost = ({ post, compact })=>{
22
- const Card = CARD_MAP[post.format];
23
- return /*#__PURE__*/ _jsx(Card, {
24
- post: post,
25
- compact: compact
26
- });
27
- };
@@ -1,36 +0,0 @@
1
- /**
2
- * Built-in Font Themes
3
- *
4
- * System-font-only presets — no external font loading required.
5
- */ /**
6
- * A font theme definition with display metadata.
7
- */ export const BUILTIN_FONT_THEMES = [
8
- {
9
- id: "default",
10
- name: "System Default",
11
- // 现代系统字体栈:先英文,后 Mac/iOS 中文,再 Win 中文
12
- fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans CN", sans-serif',
13
- description: "与你的操作系统保持一致,最稳定的阅读体验"
14
- },
15
- {
16
- id: "serif",
17
- name: "Classic Serif",
18
- // Charter 是 Apple 系统自带的极品衬线体
19
- fontFamily: 'Charter, "Bitstream Charter", "Sitka Text", Georgia, "Songti SC", "Source Han Serif CN", "STSong", "SimSun", serif',
20
- description: "传统的衬线体,适合深度长文阅读"
21
- },
22
- {
23
- id: "humanist",
24
- name: "Humanist",
25
- // Optima 具有书法韵味,Candara 是 Windows 上的优质人文体
26
- fontFamily: 'Optima, Candara, "Noto Sans", "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif',
27
- description: "温润如玉的字体风格,兼具现代感与书法美感"
28
- },
29
- {
30
- id: "mono",
31
- name: "Monospace",
32
- // 优先使用 JetBrains Mono 或 SF Mono
33
- fontFamily: '"JetBrains Mono", "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", "PingFang SC", "Microsoft YaHei", monospace',
34
- description: "等宽字体,适合技术内容或代码展示"
35
- }
36
- ];
@@ -1,153 +0,0 @@
1
- /**
2
- * Base HTML Layout
3
- *
4
- * Provides the HTML shell with meta tags, styles, and scripts.
5
- * If Context is provided, automatically wraps children with I18nProvider.
6
- *
7
- * Uses vite-ssr-components for automatic dev/prod asset path resolution.
8
- */ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "hono/jsx/jsx-runtime";
9
- import { Script, Link, ViteClient } from "vite-ssr-components/hono";
10
- import { I18nProvider } from "../../i18n/index.js";
11
- export const BaseLayout = ({ title, description, lang, c, toast, faviconUrl, noindex, children })=>{
12
- // Read lang from Hono context if available, otherwise use prop or default
13
- const resolvedLang = lang ?? (c ? c.get("lang") : "en");
14
- // Read faviconUrl from context when not provided as prop (fixes dashboard favicon)
15
- const resolvedFaviconUrl = faviconUrl ?? (c ? c.get("faviconUrl") : undefined);
16
- // Read noindex from context when not provided as prop
17
- const resolvedNoindex = noindex ?? (c ? c.get("noindex") : undefined);
18
- // Automatically wrap with I18nProvider if Context is provided
19
- const content = c ? /*#__PURE__*/ _jsx(I18nProvider, {
20
- c: c,
21
- children: children
22
- }) : children;
23
- // Read theme style from Hono context if available
24
- const themeStyle = c ? c.get("themeStyle") : undefined;
25
- // Read custom CSS from Hono context if available
26
- const customCSS = c ? c.get("customCSS") : undefined;
27
- // Check authentication status for data attribute
28
- const isAuthenticated = c ? c.get("isAuthenticated") : false;
29
- return /*#__PURE__*/ _jsxs("html", {
30
- lang: resolvedLang,
31
- children: [
32
- /*#__PURE__*/ _jsxs("head", {
33
- children: [
34
- /*#__PURE__*/ _jsx("meta", {
35
- charset: "UTF-8"
36
- }),
37
- /*#__PURE__*/ _jsx("meta", {
38
- name: "viewport",
39
- content: "width=device-width, initial-scale=1.0"
40
- }),
41
- /*#__PURE__*/ _jsx("title", {
42
- children: title
43
- }),
44
- description && /*#__PURE__*/ _jsx("meta", {
45
- name: "description",
46
- content: description
47
- }),
48
- resolvedNoindex && /*#__PURE__*/ _jsx("meta", {
49
- name: "robots",
50
- content: "noindex, nofollow"
51
- }),
52
- resolvedFaviconUrl && /*#__PURE__*/ _jsxs(_Fragment, {
53
- children: [
54
- /*#__PURE__*/ _jsx("link", {
55
- rel: "icon",
56
- href: "/favicon.ico",
57
- sizes: "16x16 32x32"
58
- }),
59
- /*#__PURE__*/ _jsx("link", {
60
- rel: "apple-touch-icon",
61
- href: "/apple-touch-icon.png",
62
- sizes: "180x180"
63
- })
64
- ]
65
- }),
66
- /*#__PURE__*/ _jsx(ViteClient, {}),
67
- /*#__PURE__*/ _jsx(Link, {
68
- href: "/src/style.css",
69
- rel: "stylesheet"
70
- }),
71
- themeStyle && /*#__PURE__*/ _jsx("style", {
72
- children: themeStyle
73
- }),
74
- customCSS && /*#__PURE__*/ _jsx("style", {
75
- children: customCSS
76
- }),
77
- /*#__PURE__*/ _jsx(Script, {
78
- src: "/src/client.ts"
79
- })
80
- ]
81
- }),
82
- /*#__PURE__*/ _jsxs("body", {
83
- class: "bg-background text-foreground antialiased",
84
- ...isAuthenticated ? {
85
- "data-authenticated": true
86
- } : {},
87
- children: [
88
- content,
89
- /*#__PURE__*/ _jsx("div", {
90
- id: "toast-container",
91
- class: "toast-container",
92
- children: toast && /*#__PURE__*/ _jsxs("div", {
93
- class: `toast ${toast.type === "error" ? "toast-error" : "toast-success"}`,
94
- "data-init": "history.replaceState({}, '', location.pathname); setTimeout(() => { el.classList.add('toast-out'); el.addEventListener('animationend', () => el.remove()) }, 3000)",
95
- children: [
96
- toast.type === "error" ? /*#__PURE__*/ _jsxs("svg", {
97
- xmlns: "http://www.w3.org/2000/svg",
98
- fill: "none",
99
- viewBox: "0 0 24 24",
100
- "stroke-width": "2",
101
- stroke: "currentColor",
102
- children: [
103
- /*#__PURE__*/ _jsx("circle", {
104
- cx: "12",
105
- cy: "12",
106
- r: "10"
107
- }),
108
- /*#__PURE__*/ _jsx("path", {
109
- d: "m15 9-6 6M9 9l6 6"
110
- })
111
- ]
112
- }) : /*#__PURE__*/ _jsxs("svg", {
113
- xmlns: "http://www.w3.org/2000/svg",
114
- fill: "none",
115
- viewBox: "0 0 24 24",
116
- "stroke-width": "2",
117
- stroke: "currentColor",
118
- children: [
119
- /*#__PURE__*/ _jsx("circle", {
120
- cx: "12",
121
- cy: "12",
122
- r: "10"
123
- }),
124
- /*#__PURE__*/ _jsx("path", {
125
- d: "m9 12 2 2 4-4"
126
- })
127
- ]
128
- }),
129
- /*#__PURE__*/ _jsx("span", {
130
- children: toast.message
131
- }),
132
- /*#__PURE__*/ _jsx("button", {
133
- class: "toast-close",
134
- "data-on:click": "el.closest('.toast').classList.add('toast-out'); el.closest('.toast').addEventListener('animationend', () => el.closest('.toast').remove())",
135
- children: /*#__PURE__*/ _jsx("svg", {
136
- xmlns: "http://www.w3.org/2000/svg",
137
- fill: "none",
138
- viewBox: "0 0 24 24",
139
- "stroke-width": "2",
140
- stroke: "currentColor",
141
- children: /*#__PURE__*/ _jsx("path", {
142
- d: "M18 6 6 18M6 6l12 12"
143
- })
144
- })
145
- })
146
- ]
147
- })
148
- })
149
- ]
150
- })
151
- ]
152
- });
153
- };
@@ -1,141 +0,0 @@
1
- /**
2
- * Dashboard Layout
3
- *
4
- * Layout for admin dashboard pages
5
- */ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
6
- import { useLingui as $_useLingui } from "@jant/core/i18n";
7
- import { BaseLayout } from "./BaseLayout.js";
8
- function DashLayoutContent({ siteName, currentPath, children }) {
9
- const { i18n: $__i18n, _: $__ } = $_useLingui();
10
- const isActive = (path, match)=>{
11
- if (!currentPath) return false;
12
- if (match) return match.test(currentPath);
13
- return currentPath === path;
14
- };
15
- const navClass = (path, match)=>`justify-start px-3 py-2 text-sm rounded-md ${isActive(path, match) ? "bg-accent text-accent-foreground font-medium" : "text-muted-foreground hover:bg-accent hover:text-accent-foreground"}`;
16
- return /*#__PURE__*/ _jsxs("div", {
17
- class: "min-h-screen",
18
- children: [
19
- /*#__PURE__*/ _jsx("header", {
20
- class: "border-b bg-card",
21
- children: /*#__PURE__*/ _jsxs("div", {
22
- class: "container flex h-14 items-center justify-between",
23
- children: [
24
- /*#__PURE__*/ _jsx("a", {
25
- id: "site-name",
26
- href: "/dash",
27
- class: "font-semibold",
28
- children: siteName
29
- }),
30
- /*#__PURE__*/ _jsxs("nav", {
31
- class: "flex items-center gap-4",
32
- children: [
33
- /*#__PURE__*/ _jsx("a", {
34
- href: "/",
35
- class: "text-sm text-muted-foreground hover:text-foreground",
36
- children: $__i18n._({
37
- id: "4/SFQS",
38
- message: "View Site"
39
- })
40
- }),
41
- /*#__PURE__*/ _jsx("a", {
42
- href: "/signout",
43
- class: "text-sm text-muted-foreground hover:text-foreground",
44
- children: $__i18n._({
45
- id: "bHYIks",
46
- message: "Sign Out"
47
- })
48
- })
49
- ]
50
- })
51
- ]
52
- })
53
- }),
54
- /*#__PURE__*/ _jsxs("div", {
55
- class: "container flex gap-8 py-8",
56
- children: [
57
- /*#__PURE__*/ _jsx("aside", {
58
- class: "w-48 shrink-0",
59
- children: /*#__PURE__*/ _jsxs("nav", {
60
- class: "flex flex-col gap-1",
61
- children: [
62
- /*#__PURE__*/ _jsx("a", {
63
- href: "/dash",
64
- class: navClass("/dash", /^\/dash$/),
65
- children: $__i18n._({
66
- id: "7p5kLi",
67
- message: "Dashboard"
68
- })
69
- }),
70
- /*#__PURE__*/ _jsx("a", {
71
- href: "/dash/posts",
72
- class: navClass("/dash/posts", /^\/dash\/posts/),
73
- children: $__i18n._({
74
- id: "+owNNn",
75
- message: "Posts"
76
- })
77
- }),
78
- /*#__PURE__*/ _jsx("a", {
79
- href: "/dash/pages",
80
- class: navClass("/dash/pages", /^\/dash\/pages/),
81
- children: $__i18n._({
82
- id: "wRR604",
83
- message: "Pages"
84
- })
85
- }),
86
- /*#__PURE__*/ _jsx("a", {
87
- href: "/dash/media",
88
- class: navClass("/dash/media", /^\/dash\/media/),
89
- children: $__i18n._({
90
- id: "xYilR2",
91
- message: "Media"
92
- })
93
- }),
94
- /*#__PURE__*/ _jsx("a", {
95
- href: "/dash/collections",
96
- class: navClass("/dash/collections", /^\/dash\/collections/),
97
- children: $__i18n._({
98
- id: "DoJzLz",
99
- message: "Collections"
100
- })
101
- }),
102
- /*#__PURE__*/ _jsx("a", {
103
- href: "/dash/redirects",
104
- class: navClass("/dash/redirects", /^\/dash\/redirects/),
105
- children: $__i18n._({
106
- id: "M9xgHy",
107
- message: "Redirects"
108
- })
109
- }),
110
- /*#__PURE__*/ _jsx("a", {
111
- href: "/dash/settings",
112
- class: navClass("/dash/settings", /^\/dash\/settings/),
113
- children: $__i18n._({
114
- id: "Tz0i8g",
115
- message: "Settings"
116
- })
117
- })
118
- ]
119
- })
120
- }),
121
- /*#__PURE__*/ _jsx("main", {
122
- class: "flex-1 min-w-0",
123
- children: children
124
- })
125
- ]
126
- })
127
- ]
128
- });
129
- }
130
- export const DashLayout = ({ c, title, siteName, currentPath, toast, children })=>{
131
- return /*#__PURE__*/ _jsx(BaseLayout, {
132
- title: `${title} - ${siteName}`,
133
- c: c,
134
- toast: toast,
135
- children: /*#__PURE__*/ _jsx(DashLayoutContent, {
136
- siteName: siteName,
137
- currentPath: currentPath,
138
- children: children
139
- })
140
- });
141
- };