@jant/core 0.2.12 → 0.2.14

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 (146) hide show
  1. package/bin/jant.js +3 -1
  2. package/dist/app.d.ts.map +1 -1
  3. package/dist/app.js +112 -85
  4. package/dist/auth.d.ts +1 -0
  5. package/dist/auth.d.ts.map +1 -1
  6. package/dist/auth.js +2 -1
  7. package/dist/client.js +1 -1
  8. package/dist/db/schema.d.ts.map +1 -1
  9. package/dist/i18n/context.d.ts.map +1 -1
  10. package/dist/i18n/context.js +0 -3
  11. package/dist/i18n/detect.d.ts +0 -11
  12. package/dist/i18n/detect.d.ts.map +1 -1
  13. package/dist/i18n/detect.js +1 -52
  14. package/dist/i18n/i18n.d.ts +4 -14
  15. package/dist/i18n/i18n.d.ts.map +1 -1
  16. package/dist/i18n/i18n.js +19 -25
  17. package/dist/i18n/index.d.ts +1 -1
  18. package/dist/i18n/index.d.ts.map +1 -1
  19. package/dist/i18n/index.js +1 -1
  20. package/dist/i18n/middleware.d.ts +2 -5
  21. package/dist/i18n/middleware.d.ts.map +1 -1
  22. package/dist/i18n/middleware.js +12 -23
  23. package/dist/lib/constants.d.ts.map +1 -1
  24. package/dist/lib/image.d.ts.map +1 -1
  25. package/dist/lib/schemas.d.ts.map +1 -1
  26. package/dist/lib/sse.d.ts +45 -17
  27. package/dist/lib/sse.d.ts.map +1 -1
  28. package/dist/lib/sse.js +77 -37
  29. package/dist/middleware/auth.d.ts.map +1 -1
  30. package/dist/routes/api/posts.js +0 -1
  31. package/dist/routes/api/upload.js +3 -1
  32. package/dist/routes/dash/collections.d.ts.map +1 -1
  33. package/dist/routes/dash/collections.js +134 -142
  34. package/dist/routes/dash/index.js +25 -26
  35. package/dist/routes/dash/media.d.ts.map +1 -1
  36. package/dist/routes/dash/media.js +60 -56
  37. package/dist/routes/dash/pages.js +64 -66
  38. package/dist/routes/dash/posts.d.ts.map +1 -1
  39. package/dist/routes/dash/posts.js +50 -59
  40. package/dist/routes/dash/redirects.d.ts.map +1 -1
  41. package/dist/routes/dash/redirects.js +63 -60
  42. package/dist/routes/dash/settings.d.ts.map +1 -1
  43. package/dist/routes/dash/settings.js +251 -93
  44. package/dist/routes/feed/rss.js +6 -4
  45. package/dist/routes/pages/archive.js +60 -62
  46. package/dist/routes/pages/collection.js +8 -8
  47. package/dist/routes/pages/home.js +14 -14
  48. package/dist/routes/pages/page.js +7 -6
  49. package/dist/routes/pages/post.js +8 -8
  50. package/dist/routes/pages/search.js +29 -29
  51. package/dist/services/collection.d.ts.map +1 -1
  52. package/dist/services/index.d.ts.map +1 -1
  53. package/dist/services/media.d.ts.map +1 -1
  54. package/dist/services/post.d.ts.map +1 -1
  55. package/dist/services/redirect.d.ts.map +1 -1
  56. package/dist/services/settings.d.ts.map +1 -1
  57. package/dist/theme/components/ActionButtons.d.ts +1 -1
  58. package/dist/theme/components/ActionButtons.d.ts.map +1 -1
  59. package/dist/theme/components/ActionButtons.js +17 -21
  60. package/dist/theme/components/CrudPageHeader.d.ts.map +1 -1
  61. package/dist/theme/components/DangerZone.d.ts.map +1 -1
  62. package/dist/theme/components/DangerZone.js +12 -15
  63. package/dist/theme/components/EmptyState.d.ts.map +1 -1
  64. package/dist/theme/components/PageForm.d.ts.map +1 -1
  65. package/dist/theme/components/PageForm.js +58 -56
  66. package/dist/theme/components/Pagination.d.ts.map +1 -1
  67. package/dist/theme/components/Pagination.js +22 -25
  68. package/dist/theme/components/PostForm.d.ts +0 -1
  69. package/dist/theme/components/PostForm.d.ts.map +1 -1
  70. package/dist/theme/components/PostForm.js +85 -77
  71. package/dist/theme/components/PostList.d.ts.map +1 -1
  72. package/dist/theme/components/PostList.js +17 -17
  73. package/dist/theme/components/ThreadView.d.ts.map +1 -1
  74. package/dist/theme/components/ThreadView.js +15 -18
  75. package/dist/theme/components/TypeBadge.d.ts.map +1 -1
  76. package/dist/theme/components/TypeBadge.js +20 -20
  77. package/dist/theme/components/VisibilityBadge.d.ts.map +1 -1
  78. package/dist/theme/components/VisibilityBadge.js +14 -14
  79. package/dist/theme/components/index.d.ts +1 -1
  80. package/dist/theme/components/index.d.ts.map +1 -1
  81. package/dist/theme/layouts/BaseLayout.d.ts.map +1 -1
  82. package/dist/theme/layouts/BaseLayout.js +4 -2
  83. package/dist/theme/layouts/DashLayout.d.ts.map +1 -1
  84. package/dist/theme/layouts/DashLayout.js +29 -29
  85. package/dist/types/lingui-react-macro.d.js +9 -0
  86. package/dist/types.d.ts +2 -0
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/vendor/datastar.js +1606 -0
  89. package/package.json +5 -2
  90. package/src/app.tsx +175 -56
  91. package/src/auth.ts +5 -1
  92. package/src/client.ts +1 -1
  93. package/src/db/schema.ts +22 -7
  94. package/src/i18n/EXAMPLES.md +34 -14
  95. package/src/i18n/README.md +19 -9
  96. package/src/i18n/context.tsx +1 -4
  97. package/src/i18n/detect.ts +1 -67
  98. package/src/i18n/i18n.ts +15 -19
  99. package/src/i18n/index.ts +0 -3
  100. package/src/i18n/middleware.ts +12 -24
  101. package/src/lib/constants.ts +2 -1
  102. package/src/lib/image-processor.ts +23 -7
  103. package/src/lib/image.ts +6 -2
  104. package/src/lib/schemas.ts +6 -2
  105. package/src/lib/sse.ts +138 -50
  106. package/src/middleware/auth.ts +6 -2
  107. package/src/routes/api/posts.ts +14 -5
  108. package/src/routes/api/upload.ts +25 -7
  109. package/src/routes/dash/collections.tsx +162 -70
  110. package/src/routes/dash/index.tsx +22 -7
  111. package/src/routes/dash/media.tsx +59 -16
  112. package/src/routes/dash/pages.tsx +102 -44
  113. package/src/routes/dash/posts.tsx +87 -54
  114. package/src/routes/dash/redirects.tsx +74 -26
  115. package/src/routes/dash/settings.tsx +252 -57
  116. package/src/routes/feed/rss.ts +6 -4
  117. package/src/routes/pages/archive.tsx +71 -21
  118. package/src/routes/pages/collection.tsx +21 -6
  119. package/src/routes/pages/home.tsx +30 -9
  120. package/src/routes/pages/page.tsx +14 -5
  121. package/src/routes/pages/post.tsx +21 -7
  122. package/src/routes/pages/search.tsx +42 -11
  123. package/src/services/collection.ts +34 -9
  124. package/src/services/index.ts +4 -1
  125. package/src/services/media.ts +15 -3
  126. package/src/services/post.ts +39 -10
  127. package/src/services/redirect.ts +4 -1
  128. package/src/services/settings.ts +14 -3
  129. package/src/theme/components/ActionButtons.tsx +26 -14
  130. package/src/theme/components/CrudPageHeader.tsx +6 -1
  131. package/src/theme/components/DangerZone.tsx +19 -13
  132. package/src/theme/components/EmptyState.tsx +6 -1
  133. package/src/theme/components/PageForm.tsx +71 -24
  134. package/src/theme/components/Pagination.tsx +26 -8
  135. package/src/theme/components/PostForm.tsx +72 -25
  136. package/src/theme/components/PostList.tsx +16 -5
  137. package/src/theme/components/ThreadView.tsx +25 -7
  138. package/src/theme/components/TypeBadge.tsx +13 -4
  139. package/src/theme/components/VisibilityBadge.tsx +17 -5
  140. package/src/theme/components/index.ts +4 -1
  141. package/src/theme/layouts/BaseLayout.tsx +5 -2
  142. package/src/theme/layouts/DashLayout.tsx +41 -12
  143. package/src/types/lingui-react-macro.d.ts +34 -0
  144. package/src/types.ts +16 -2
  145. package/src/vendor/datastar.js +9 -0
  146. package/src/vendor/datastar.js.map +7 -0
@@ -2,120 +2,237 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "hono/jsx/jsx-
2
2
  /**
3
3
  * Dashboard Settings Routes
4
4
  */ import { Hono } from "hono";
5
- import { useLingui } from "../../i18n/index.js";
5
+ import { useLingui as $_useLingui } from "@jant/core/i18n";
6
6
  import { DashLayout } from "../../theme/layouts/index.js";
7
+ import { sse } from "../../lib/sse.js";
7
8
  export const settingsRoutes = new Hono();
8
- function SettingsContent({ siteName, siteDescription, siteLanguage }) {
9
- const { t } = useLingui();
9
+ function SettingsContent({ siteName, siteDescription, siteLanguage, saved }) {
10
+ const { i18n: $__i18n, _: $__ } = $_useLingui();
11
+ const generalSignals = JSON.stringify({
12
+ siteName,
13
+ siteDescription,
14
+ siteLanguage
15
+ }).replace(/</g, "\\u003c");
10
16
  return /*#__PURE__*/ _jsxs(_Fragment, {
11
17
  children: [
12
18
  /*#__PURE__*/ _jsx("h1", {
13
19
  class: "text-2xl font-semibold mb-6",
14
- children: t({
15
- message: "Settings",
16
- comment: "@context: Dashboard heading"
20
+ children: $__i18n._({
21
+ id: "Tz0i8g",
22
+ message: "Settings"
17
23
  })
18
24
  }),
19
- /*#__PURE__*/ _jsxs("form", {
20
- method: "post",
21
- action: "/dash/settings",
25
+ saved && /*#__PURE__*/ _jsx("div", {
26
+ id: "settings-saved-toast",
27
+ class: "alert mb-4 max-w-lg transition-opacity duration-300",
28
+ "data-init": `console.log('[toast] init fired at', Date.now()); history.replaceState({}, '', '/dash/settings'); setTimeout(() => { console.log('[toast] hiding at', Date.now()); const el = document.getElementById('settings-saved-toast'); if (el) { el.style.opacity = '0'; setTimeout(() => el.remove(), 300) } }, 3000)`,
29
+ children: /*#__PURE__*/ _jsx("h2", {
30
+ children: $__i18n._({
31
+ id: "T0bsor",
32
+ message: "Settings saved successfully."
33
+ })
34
+ })
35
+ }),
36
+ /*#__PURE__*/ _jsxs("div", {
22
37
  class: "flex flex-col gap-6 max-w-lg",
23
38
  children: [
24
- /*#__PURE__*/ _jsxs("div", {
25
- class: "card",
39
+ /*#__PURE__*/ _jsxs("form", {
40
+ "data-signals": generalSignals,
41
+ "data-on:submit__prevent": "@post('/dash/settings')",
26
42
  children: [
27
- /*#__PURE__*/ _jsx("header", {
28
- children: /*#__PURE__*/ _jsx("h2", {
29
- children: t({
30
- message: "General",
31
- comment: "@context: Settings section heading"
32
- })
33
- })
43
+ /*#__PURE__*/ _jsx("div", {
44
+ id: "settings-message"
34
45
  }),
35
- /*#__PURE__*/ _jsxs("section", {
36
- class: "flex flex-col gap-4",
46
+ /*#__PURE__*/ _jsxs("div", {
47
+ class: "card",
37
48
  children: [
38
- /*#__PURE__*/ _jsxs("div", {
39
- class: "field",
40
- children: [
41
- /*#__PURE__*/ _jsx("label", {
42
- class: "label",
43
- children: t({
44
- message: "Site Name",
45
- comment: "@context: Settings form field"
46
- })
47
- }),
48
- /*#__PURE__*/ _jsx("input", {
49
- type: "text",
50
- name: "siteName",
51
- class: "input",
52
- value: siteName,
53
- required: true
49
+ /*#__PURE__*/ _jsx("header", {
50
+ children: /*#__PURE__*/ _jsx("h2", {
51
+ children: $__i18n._({
52
+ id: "Weq9zb",
53
+ message: "General"
54
54
  })
55
- ]
55
+ })
56
56
  }),
57
- /*#__PURE__*/ _jsxs("div", {
58
- class: "field",
57
+ /*#__PURE__*/ _jsxs("section", {
58
+ class: "flex flex-col gap-4",
59
59
  children: [
60
- /*#__PURE__*/ _jsx("label", {
61
- class: "label",
62
- children: t({
63
- message: "Site Description",
64
- comment: "@context: Settings form field"
65
- })
60
+ /*#__PURE__*/ _jsxs("div", {
61
+ class: "field",
62
+ children: [
63
+ /*#__PURE__*/ _jsx("label", {
64
+ class: "label",
65
+ children: $__i18n._({
66
+ id: "SJmfuf",
67
+ message: "Site Name"
68
+ })
69
+ }),
70
+ /*#__PURE__*/ _jsx("input", {
71
+ type: "text",
72
+ "data-bind": "siteName",
73
+ class: "input",
74
+ required: true
75
+ })
76
+ ]
66
77
  }),
67
- /*#__PURE__*/ _jsx("textarea", {
68
- name: "siteDescription",
69
- class: "textarea",
70
- rows: 3,
71
- children: siteDescription
78
+ /*#__PURE__*/ _jsxs("div", {
79
+ class: "field",
80
+ children: [
81
+ /*#__PURE__*/ _jsx("label", {
82
+ class: "label",
83
+ children: $__i18n._({
84
+ id: "u2f7vd",
85
+ message: "Site Description"
86
+ })
87
+ }),
88
+ /*#__PURE__*/ _jsx("textarea", {
89
+ "data-bind": "siteDescription",
90
+ class: "textarea",
91
+ rows: 3,
92
+ children: siteDescription
93
+ })
94
+ ]
95
+ }),
96
+ /*#__PURE__*/ _jsxs("div", {
97
+ class: "field",
98
+ children: [
99
+ /*#__PURE__*/ _jsx("label", {
100
+ class: "label",
101
+ children: $__i18n._({
102
+ id: "vXIe7J",
103
+ message: "Language"
104
+ })
105
+ }),
106
+ /*#__PURE__*/ _jsxs("select", {
107
+ "data-bind": "siteLanguage",
108
+ class: "select",
109
+ children: [
110
+ /*#__PURE__*/ _jsx("option", {
111
+ value: "en",
112
+ selected: siteLanguage === "en",
113
+ children: "English"
114
+ }),
115
+ /*#__PURE__*/ _jsx("option", {
116
+ value: "zh-Hans",
117
+ selected: siteLanguage === "zh-Hans",
118
+ children: "简体中文"
119
+ }),
120
+ /*#__PURE__*/ _jsx("option", {
121
+ value: "zh-Hant",
122
+ selected: siteLanguage === "zh-Hant",
123
+ children: "繁體中文"
124
+ })
125
+ ]
126
+ })
127
+ ]
72
128
  })
73
129
  ]
130
+ })
131
+ ]
132
+ }),
133
+ /*#__PURE__*/ _jsx("button", {
134
+ type: "submit",
135
+ class: "btn mt-4",
136
+ children: $__i18n._({
137
+ id: "UGT5vp",
138
+ message: "Save Settings"
139
+ })
140
+ })
141
+ ]
142
+ }),
143
+ /*#__PURE__*/ _jsxs("form", {
144
+ "data-signals": "{currentPassword: '', newPassword: '', confirmPassword: ''}",
145
+ "data-on:submit__prevent": "@post('/dash/settings/password')",
146
+ children: [
147
+ /*#__PURE__*/ _jsx("div", {
148
+ id: "password-message"
149
+ }),
150
+ /*#__PURE__*/ _jsxs("div", {
151
+ class: "card",
152
+ children: [
153
+ /*#__PURE__*/ _jsx("header", {
154
+ children: /*#__PURE__*/ _jsx("h2", {
155
+ children: $__i18n._({
156
+ id: "VhMDMg",
157
+ message: "Change Password"
158
+ })
159
+ })
74
160
  }),
75
- /*#__PURE__*/ _jsxs("div", {
76
- class: "field",
161
+ /*#__PURE__*/ _jsxs("section", {
162
+ class: "flex flex-col gap-4",
77
163
  children: [
78
- /*#__PURE__*/ _jsx("label", {
79
- class: "label",
80
- children: t({
81
- message: "Language",
82
- comment: "@context: Settings form field"
83
- })
164
+ /*#__PURE__*/ _jsxs("div", {
165
+ class: "field",
166
+ children: [
167
+ /*#__PURE__*/ _jsx("label", {
168
+ class: "label",
169
+ children: $__i18n._({
170
+ id: "DCKkhU",
171
+ message: "Current Password"
172
+ })
173
+ }),
174
+ /*#__PURE__*/ _jsx("input", {
175
+ type: "password",
176
+ "data-bind": "currentPassword",
177
+ class: "input",
178
+ required: true,
179
+ autocomplete: "current-password"
180
+ })
181
+ ]
84
182
  }),
85
- /*#__PURE__*/ _jsxs("select", {
86
- name: "siteLanguage",
87
- class: "select",
183
+ /*#__PURE__*/ _jsxs("div", {
184
+ class: "field",
88
185
  children: [
89
- /*#__PURE__*/ _jsx("option", {
90
- value: "en",
91
- selected: siteLanguage === "en",
92
- children: "English"
186
+ /*#__PURE__*/ _jsx("label", {
187
+ class: "label",
188
+ children: $__i18n._({
189
+ id: "7vhWI8",
190
+ message: "New Password"
191
+ })
93
192
  }),
94
- /*#__PURE__*/ _jsx("option", {
95
- value: "zh-Hans",
96
- selected: siteLanguage === "zh-Hans",
97
- children: "简体中文"
193
+ /*#__PURE__*/ _jsx("input", {
194
+ type: "password",
195
+ "data-bind": "newPassword",
196
+ class: "input",
197
+ required: true,
198
+ minlength: 8,
199
+ autocomplete: "new-password"
200
+ })
201
+ ]
202
+ }),
203
+ /*#__PURE__*/ _jsxs("div", {
204
+ class: "field",
205
+ children: [
206
+ /*#__PURE__*/ _jsx("label", {
207
+ class: "label",
208
+ children: $__i18n._({
209
+ id: "yjkELF",
210
+ message: "Confirm New Password"
211
+ })
98
212
  }),
99
- /*#__PURE__*/ _jsx("option", {
100
- value: "zh-Hant",
101
- selected: siteLanguage === "zh-Hant",
102
- children: "繁體中文"
213
+ /*#__PURE__*/ _jsx("input", {
214
+ type: "password",
215
+ "data-bind": "confirmPassword",
216
+ class: "input",
217
+ required: true,
218
+ minlength: 8,
219
+ autocomplete: "new-password"
103
220
  })
104
221
  ]
105
222
  })
106
223
  ]
107
224
  })
108
225
  ]
226
+ }),
227
+ /*#__PURE__*/ _jsx("button", {
228
+ type: "submit",
229
+ class: "btn mt-4",
230
+ children: $__i18n._({
231
+ id: "VhMDMg",
232
+ message: "Change Password"
233
+ })
109
234
  })
110
235
  ]
111
- }),
112
- /*#__PURE__*/ _jsx("button", {
113
- type: "submit",
114
- class: "btn",
115
- children: t({
116
- message: "Save Settings",
117
- comment: "@context: Button to save settings"
118
- })
119
236
  })
120
237
  ]
121
238
  })
@@ -124,9 +241,11 @@ function SettingsContent({ siteName, siteDescription, siteLanguage }) {
124
241
  }
125
242
  // Settings page
126
243
  settingsRoutes.get("/", async (c)=>{
127
- const siteName = await c.var.services.settings.get("SITE_NAME") ?? "Jant";
128
- const siteDescription = await c.var.services.settings.get("SITE_DESCRIPTION") ?? "";
129
- const siteLanguage = await c.var.services.settings.get("SITE_LANGUAGE") ?? "en";
244
+ const all = await c.var.services.settings.getAll();
245
+ const siteName = all["SITE_NAME"] ?? "Jant";
246
+ const siteDescription = all["SITE_DESCRIPTION"] ?? "";
247
+ const siteLanguage = all["SITE_LANGUAGE"] ?? "en";
248
+ const saved = c.req.query("saved") !== undefined;
130
249
  return c.html(/*#__PURE__*/ _jsx(DashLayout, {
131
250
  c: c,
132
251
  title: "Settings",
@@ -135,20 +254,59 @@ settingsRoutes.get("/", async (c)=>{
135
254
  children: /*#__PURE__*/ _jsx(SettingsContent, {
136
255
  siteName: siteName,
137
256
  siteDescription: siteDescription,
138
- siteLanguage: siteLanguage
257
+ siteLanguage: siteLanguage,
258
+ saved: saved
139
259
  })
140
260
  }));
141
261
  });
142
262
  // Update settings
143
263
  settingsRoutes.post("/", async (c)=>{
144
- const formData = await c.req.formData();
145
- const siteName = formData.get("siteName");
146
- const siteDescription = formData.get("siteDescription");
147
- const siteLanguage = formData.get("siteLanguage");
264
+ const body = await c.req.json();
265
+ const oldLanguage = await c.var.services.settings.get("SITE_LANGUAGE") ?? "en";
148
266
  await c.var.services.settings.setMany({
149
- SITE_NAME: siteName,
150
- SITE_DESCRIPTION: siteDescription,
151
- SITE_LANGUAGE: siteLanguage
267
+ SITE_NAME: body.siteName,
268
+ SITE_DESCRIPTION: body.siteDescription,
269
+ SITE_LANGUAGE: body.siteLanguage
270
+ });
271
+ const languageChanged = oldLanguage !== body.siteLanguage;
272
+ return sse(c, async (stream)=>{
273
+ if (languageChanged) {
274
+ // Language changed - full reload needed to update all UI text
275
+ await stream.redirect("/dash/settings?saved");
276
+ } else {
277
+ // No language change - show inline success message
278
+ await stream.patchElements('<div id="settings-message"><div class="alert mb-4 transition-opacity duration-300" data-init="setTimeout(() => { el.style.opacity = \'0\'; setTimeout(() => el.remove(), 300) }, 3000)"><h2>Settings saved successfully.</h2></div></div>');
279
+ }
280
+ });
281
+ });
282
+ // Change password
283
+ settingsRoutes.post("/password", async (c)=>{
284
+ const body = await c.req.json();
285
+ if (body.newPassword !== body.confirmPassword) {
286
+ return sse(c, async (stream)=>{
287
+ await stream.patchElements('<div id="password-message"><div class="alert-destructive mb-4"><h2>Passwords do not match.</h2></div></div>');
288
+ });
289
+ }
290
+ try {
291
+ await c.var.auth.api.changePassword({
292
+ body: {
293
+ currentPassword: body.currentPassword,
294
+ newPassword: body.newPassword,
295
+ revokeOtherSessions: false
296
+ },
297
+ headers: c.req.raw.headers
298
+ });
299
+ } catch {
300
+ return sse(c, async (stream)=>{
301
+ await stream.patchElements('<div id="password-message"><div class="alert-destructive mb-4"><h2>Current password is incorrect.</h2></div></div>');
302
+ });
303
+ }
304
+ return sse(c, async (stream)=>{
305
+ await stream.patchElements('<div id="password-message"><div class="alert mb-4"><h2>Password changed successfully.</h2></div></div>');
306
+ await stream.patchSignals({
307
+ currentPassword: "",
308
+ newPassword: "",
309
+ confirmPassword: ""
310
+ });
152
311
  });
153
- return c.redirect("/dash/settings?saved=1");
154
312
  });
@@ -6,8 +6,9 @@ import * as time from "../../lib/time.js";
6
6
  export const rssRoutes = new Hono();
7
7
  // RSS 2.0 Feed - main feed at /feed
8
8
  rssRoutes.get("/", async (c)=>{
9
- const siteName = await c.var.services.settings.get("SITE_NAME") ?? "Jant";
10
- const siteDescription = await c.var.services.settings.get("SITE_DESCRIPTION") ?? "";
9
+ const all = await c.var.services.settings.getAll();
10
+ const siteName = all["SITE_NAME"] ?? "Jant";
11
+ const siteDescription = all["SITE_DESCRIPTION"] ?? "";
11
12
  const siteUrl = c.env.SITE_URL;
12
13
  const posts = await c.var.services.posts.list({
13
14
  visibility: [
@@ -48,8 +49,9 @@ rssRoutes.get("/", async (c)=>{
48
49
  });
49
50
  // Atom Feed
50
51
  rssRoutes.get("/atom.xml", async (c)=>{
51
- const siteName = await c.var.services.settings.get("SITE_NAME") ?? "Jant";
52
- const siteDescription = await c.var.services.settings.get("SITE_DESCRIPTION") ?? "";
52
+ const all = await c.var.services.settings.getAll();
53
+ const siteName = all["SITE_NAME"] ?? "Jant";
54
+ const siteDescription = all["SITE_DESCRIPTION"] ?? "";
53
55
  const siteUrl = c.env.SITE_URL;
54
56
  const posts = await c.var.services.posts.list({
55
57
  visibility: [
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
4
4
  *
5
5
  * Shows all posts, optionally filtered by type
6
6
  */ import { Hono } from "hono";
7
- import { useLingui } from "../../i18n/index.js";
7
+ import { useLingui as $_useLingui } from "@jant/core/i18n";
8
8
  import { BaseLayout } from "../../theme/layouts/index.js";
9
9
  import { Pagination } from "../../theme/components/index.js";
10
10
  import { POST_TYPES } from "../../types.js";
@@ -13,61 +13,61 @@ import * as time from "../../lib/time.js";
13
13
  const PAGE_SIZE = 50;
14
14
  export const archiveRoutes = new Hono();
15
15
  function getTypeLabel(type) {
16
- const { t } = useLingui();
16
+ const { i18n: $__i18n, _: $__ } = $_useLingui();
17
17
  const labels = {
18
- note: t({
19
- message: "Note",
20
- comment: "@context: Post type label - note"
18
+ note: $__i18n._({
19
+ id: "KiJn9B",
20
+ message: "Note"
21
21
  }),
22
- article: t({
23
- message: "Article",
24
- comment: "@context: Post type label - article"
22
+ article: $__i18n._({
23
+ id: "f6e0Ry",
24
+ message: "Article"
25
25
  }),
26
- link: t({
27
- message: "Link",
28
- comment: "@context: Post type label - link"
26
+ link: $__i18n._({
27
+ id: "yzF66j",
28
+ message: "Link"
29
29
  }),
30
- quote: t({
31
- message: "Quote",
32
- comment: "@context: Post type label - quote"
30
+ quote: $__i18n._({
31
+ id: "ZhhOwV",
32
+ message: "Quote"
33
33
  }),
34
- image: t({
35
- message: "Image",
36
- comment: "@context: Post type label - image"
34
+ image: $__i18n._({
35
+ id: "hG89Ed",
36
+ message: "Image"
37
37
  }),
38
- page: t({
39
- message: "Page",
40
- comment: "@context: Post type label - page"
38
+ page: $__i18n._({
39
+ id: "6WdDG7",
40
+ message: "Page"
41
41
  })
42
42
  };
43
43
  return labels[type] ?? type;
44
44
  }
45
45
  function getTypeLabelPlural(type) {
46
- const { t } = useLingui();
46
+ const { i18n: $__i18n, _: $__ } = $_useLingui();
47
47
  const labels = {
48
- note: t({
49
- message: "Notes",
50
- comment: "@context: Post type label plural - notes"
48
+ note: $__i18n._({
49
+ id: "1DBGsz",
50
+ message: "Notes"
51
51
  }),
52
- article: t({
53
- message: "Articles",
54
- comment: "@context: Post type label plural - articles"
52
+ article: $__i18n._({
53
+ id: "Tt5T6+",
54
+ message: "Articles"
55
55
  }),
56
- link: t({
57
- message: "Links",
58
- comment: "@context: Post type label plural - links"
56
+ link: $__i18n._({
57
+ id: "Rj01Fz",
58
+ message: "Links"
59
59
  }),
60
- quote: t({
61
- message: "Quotes",
62
- comment: "@context: Post type label plural - quotes"
60
+ quote: $__i18n._({
61
+ id: "eWLklq",
62
+ message: "Quotes"
63
63
  }),
64
- image: t({
65
- message: "Images",
66
- comment: "@context: Post type label plural - images"
64
+ image: $__i18n._({
65
+ id: "an5hVd",
66
+ message: "Images"
67
67
  }),
68
- page: t({
69
- message: "Pages",
70
- comment: "@context: Post type label plural - pages"
68
+ page: $__i18n._({
69
+ id: "wRR604",
70
+ message: "Pages"
71
71
  })
72
72
  };
73
73
  return labels[type] ?? `${type}s`;
@@ -82,10 +82,10 @@ function formatYearMonth(yearMonth) {
82
82
  });
83
83
  }
84
84
  function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, replyCounts }) {
85
- const { t } = useLingui();
86
- const title = type ? getTypeLabelPlural(type) : t({
87
- message: "Archive",
88
- comment: "@context: Archive page title"
85
+ const { i18n: $__i18n, _: $__ } = $_useLingui();
86
+ const title = type ? getTypeLabelPlural(type) : $__i18n._({
87
+ id: "B495Gs",
88
+ message: "Archive"
89
89
  });
90
90
  return /*#__PURE__*/ _jsxs("div", {
91
91
  class: "container py-8",
@@ -103,9 +103,9 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
103
103
  /*#__PURE__*/ _jsx("a", {
104
104
  href: "/archive",
105
105
  class: `badge ${!type ? "badge-primary" : "badge-outline"}`,
106
- children: t({
107
- message: "All",
108
- comment: "@context: Archive filter - all types"
106
+ children: $__i18n._({
107
+ id: "N40H+G",
108
+ message: "All"
109
109
  })
110
110
  }),
111
111
  POST_TYPES.filter((t)=>t !== "page").map((typeKey)=>/*#__PURE__*/ _jsx("a", {
@@ -120,9 +120,9 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
120
120
  /*#__PURE__*/ _jsx("main", {
121
121
  children: displayPosts.length === 0 ? /*#__PURE__*/ _jsx("p", {
122
122
  class: "text-muted-foreground",
123
- children: t({
124
- message: "No posts found.",
125
- comment: "@context: Archive empty state"
123
+ children: $__i18n._({
124
+ id: "Hzi9AA",
125
+ message: "No posts found."
126
126
  })
127
127
  }) : Array.from(grouped.entries()).map(([yearMonth, monthPosts])=>/*#__PURE__*/ _jsxs("section", {
128
128
  class: "mb-8",
@@ -159,15 +159,12 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
159
159
  class: "ml-2 text-xs text-muted-foreground",
160
160
  children: [
161
161
  "(",
162
- replyCount === 1 ? t({
163
- message: "1 reply",
164
- comment: "@context: Archive post reply indicator - single"
165
- }) : t({
166
- message: "{count} replies",
167
- comment: "@context: Archive post reply indicator - plural",
168
- values: {
169
- count: String(replyCount)
170
- }
162
+ replyCount === 1 ? $__i18n._({
163
+ id: "TxE+Mj",
164
+ message: "1 reply"
165
+ }) : $__i18n._({
166
+ id: "90Luob",
167
+ message: "{count} replies"
171
168
  }),
172
169
  ")"
173
170
  ]
@@ -192,10 +189,11 @@ function ArchiveContent({ displayPosts, hasMore, nextCursor, type, grouped, repl
192
189
  href: "/",
193
190
  class: "text-sm hover:underline",
194
191
  children: [
195
- "← ",
196
- t({
197
- message: "Back to home",
198
- comment: "@context: Navigation link back to home page"
192
+ "←",
193
+ " ",
194
+ $__i18n._({
195
+ id: "x4RuFo",
196
+ message: "Back to home"
199
197
  })
200
198
  ]
201
199
  })