@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.
- package/bin/jant.js +3 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +112 -85
- package/dist/auth.d.ts +1 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +2 -1
- package/dist/client.js +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/i18n/context.d.ts.map +1 -1
- package/dist/i18n/context.js +0 -3
- package/dist/i18n/detect.d.ts +0 -11
- package/dist/i18n/detect.d.ts.map +1 -1
- package/dist/i18n/detect.js +1 -52
- package/dist/i18n/i18n.d.ts +4 -14
- package/dist/i18n/i18n.d.ts.map +1 -1
- package/dist/i18n/i18n.js +19 -25
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/middleware.d.ts +2 -5
- package/dist/i18n/middleware.d.ts.map +1 -1
- package/dist/i18n/middleware.js +12 -23
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/image.d.ts.map +1 -1
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/sse.d.ts +45 -17
- package/dist/lib/sse.d.ts.map +1 -1
- package/dist/lib/sse.js +77 -37
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/routes/api/posts.js +0 -1
- package/dist/routes/api/upload.js +3 -1
- package/dist/routes/dash/collections.d.ts.map +1 -1
- package/dist/routes/dash/collections.js +134 -142
- package/dist/routes/dash/index.js +25 -26
- package/dist/routes/dash/media.d.ts.map +1 -1
- package/dist/routes/dash/media.js +60 -56
- package/dist/routes/dash/pages.js +64 -66
- package/dist/routes/dash/posts.d.ts.map +1 -1
- package/dist/routes/dash/posts.js +50 -59
- package/dist/routes/dash/redirects.d.ts.map +1 -1
- package/dist/routes/dash/redirects.js +63 -60
- package/dist/routes/dash/settings.d.ts.map +1 -1
- package/dist/routes/dash/settings.js +251 -93
- package/dist/routes/feed/rss.js +6 -4
- package/dist/routes/pages/archive.js +60 -62
- package/dist/routes/pages/collection.js +8 -8
- package/dist/routes/pages/home.js +14 -14
- package/dist/routes/pages/page.js +7 -6
- package/dist/routes/pages/post.js +8 -8
- package/dist/routes/pages/search.js +29 -29
- package/dist/services/collection.d.ts.map +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/media.d.ts.map +1 -1
- package/dist/services/post.d.ts.map +1 -1
- package/dist/services/redirect.d.ts.map +1 -1
- package/dist/services/settings.d.ts.map +1 -1
- package/dist/theme/components/ActionButtons.d.ts +1 -1
- package/dist/theme/components/ActionButtons.d.ts.map +1 -1
- package/dist/theme/components/ActionButtons.js +17 -21
- package/dist/theme/components/CrudPageHeader.d.ts.map +1 -1
- package/dist/theme/components/DangerZone.d.ts.map +1 -1
- package/dist/theme/components/DangerZone.js +12 -15
- package/dist/theme/components/EmptyState.d.ts.map +1 -1
- package/dist/theme/components/PageForm.d.ts.map +1 -1
- package/dist/theme/components/PageForm.js +58 -56
- package/dist/theme/components/Pagination.d.ts.map +1 -1
- package/dist/theme/components/Pagination.js +22 -25
- package/dist/theme/components/PostForm.d.ts +0 -1
- package/dist/theme/components/PostForm.d.ts.map +1 -1
- package/dist/theme/components/PostForm.js +85 -77
- package/dist/theme/components/PostList.d.ts.map +1 -1
- package/dist/theme/components/PostList.js +17 -17
- package/dist/theme/components/ThreadView.d.ts.map +1 -1
- package/dist/theme/components/ThreadView.js +15 -18
- package/dist/theme/components/TypeBadge.d.ts.map +1 -1
- package/dist/theme/components/TypeBadge.js +20 -20
- package/dist/theme/components/VisibilityBadge.d.ts.map +1 -1
- package/dist/theme/components/VisibilityBadge.js +14 -14
- package/dist/theme/components/index.d.ts +1 -1
- package/dist/theme/components/index.d.ts.map +1 -1
- package/dist/theme/layouts/BaseLayout.d.ts.map +1 -1
- package/dist/theme/layouts/BaseLayout.js +4 -2
- package/dist/theme/layouts/DashLayout.d.ts.map +1 -1
- package/dist/theme/layouts/DashLayout.js +29 -29
- package/dist/types/lingui-react-macro.d.js +9 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vendor/datastar.js +1606 -0
- package/package.json +5 -2
- package/src/app.tsx +175 -56
- package/src/auth.ts +5 -1
- package/src/client.ts +1 -1
- package/src/db/schema.ts +22 -7
- package/src/i18n/EXAMPLES.md +34 -14
- package/src/i18n/README.md +19 -9
- package/src/i18n/context.tsx +1 -4
- package/src/i18n/detect.ts +1 -67
- package/src/i18n/i18n.ts +15 -19
- package/src/i18n/index.ts +0 -3
- package/src/i18n/middleware.ts +12 -24
- package/src/lib/constants.ts +2 -1
- package/src/lib/image-processor.ts +23 -7
- package/src/lib/image.ts +6 -2
- package/src/lib/schemas.ts +6 -2
- package/src/lib/sse.ts +138 -50
- package/src/middleware/auth.ts +6 -2
- package/src/routes/api/posts.ts +14 -5
- package/src/routes/api/upload.ts +25 -7
- package/src/routes/dash/collections.tsx +162 -70
- package/src/routes/dash/index.tsx +22 -7
- package/src/routes/dash/media.tsx +59 -16
- package/src/routes/dash/pages.tsx +102 -44
- package/src/routes/dash/posts.tsx +87 -54
- package/src/routes/dash/redirects.tsx +74 -26
- package/src/routes/dash/settings.tsx +252 -57
- package/src/routes/feed/rss.ts +6 -4
- package/src/routes/pages/archive.tsx +71 -21
- package/src/routes/pages/collection.tsx +21 -6
- package/src/routes/pages/home.tsx +30 -9
- package/src/routes/pages/page.tsx +14 -5
- package/src/routes/pages/post.tsx +21 -7
- package/src/routes/pages/search.tsx +42 -11
- package/src/services/collection.ts +34 -9
- package/src/services/index.ts +4 -1
- package/src/services/media.ts +15 -3
- package/src/services/post.ts +39 -10
- package/src/services/redirect.ts +4 -1
- package/src/services/settings.ts +14 -3
- package/src/theme/components/ActionButtons.tsx +26 -14
- package/src/theme/components/CrudPageHeader.tsx +6 -1
- package/src/theme/components/DangerZone.tsx +19 -13
- package/src/theme/components/EmptyState.tsx +6 -1
- package/src/theme/components/PageForm.tsx +71 -24
- package/src/theme/components/Pagination.tsx +26 -8
- package/src/theme/components/PostForm.tsx +72 -25
- package/src/theme/components/PostList.tsx +16 -5
- package/src/theme/components/ThreadView.tsx +25 -7
- package/src/theme/components/TypeBadge.tsx +13 -4
- package/src/theme/components/VisibilityBadge.tsx +17 -5
- package/src/theme/components/index.ts +4 -1
- package/src/theme/layouts/BaseLayout.tsx +5 -2
- package/src/theme/layouts/DashLayout.tsx +41 -12
- package/src/types/lingui-react-macro.d.ts +34 -0
- package/src/types.ts +16 -2
- package/src/vendor/datastar.js +9 -0
- 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 "
|
|
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 {
|
|
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:
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
children: $__i18n._({
|
|
21
|
+
id: "Tz0i8g",
|
|
22
|
+
message: "Settings"
|
|
17
23
|
})
|
|
18
24
|
}),
|
|
19
|
-
/*#__PURE__*/
|
|
20
|
-
|
|
21
|
-
|
|
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("
|
|
25
|
-
|
|
39
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
40
|
+
"data-signals": generalSignals,
|
|
41
|
+
"data-on:submit__prevent": "@post('/dash/settings')",
|
|
26
42
|
children: [
|
|
27
|
-
/*#__PURE__*/ _jsx("
|
|
28
|
-
|
|
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("
|
|
36
|
-
class: "
|
|
46
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
47
|
+
class: "card",
|
|
37
48
|
children: [
|
|
38
|
-
/*#__PURE__*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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("
|
|
58
|
-
class: "
|
|
57
|
+
/*#__PURE__*/ _jsxs("section", {
|
|
58
|
+
class: "flex flex-col gap-4",
|
|
59
59
|
children: [
|
|
60
|
-
/*#__PURE__*/
|
|
61
|
-
class: "
|
|
62
|
-
children:
|
|
63
|
-
|
|
64
|
-
|
|
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__*/
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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("
|
|
76
|
-
class: "
|
|
161
|
+
/*#__PURE__*/ _jsxs("section", {
|
|
162
|
+
class: "flex flex-col gap-4",
|
|
77
163
|
children: [
|
|
78
|
-
/*#__PURE__*/
|
|
79
|
-
class: "
|
|
80
|
-
children:
|
|
81
|
-
|
|
82
|
-
|
|
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("
|
|
86
|
-
|
|
87
|
-
class: "select",
|
|
183
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
184
|
+
class: "field",
|
|
88
185
|
children: [
|
|
89
|
-
/*#__PURE__*/ _jsx("
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
186
|
+
/*#__PURE__*/ _jsx("label", {
|
|
187
|
+
class: "label",
|
|
188
|
+
children: $__i18n._({
|
|
189
|
+
id: "7vhWI8",
|
|
190
|
+
message: "New Password"
|
|
191
|
+
})
|
|
93
192
|
}),
|
|
94
|
-
/*#__PURE__*/ _jsx("
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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("
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
128
|
-
const
|
|
129
|
-
const
|
|
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
|
|
145
|
-
const
|
|
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
|
});
|
package/dist/routes/feed/rss.js
CHANGED
|
@@ -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
|
|
10
|
-
const
|
|
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
|
|
52
|
-
const
|
|
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 "
|
|
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 {
|
|
16
|
+
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
17
17
|
const labels = {
|
|
18
|
-
note:
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
note: $__i18n._({
|
|
19
|
+
id: "KiJn9B",
|
|
20
|
+
message: "Note"
|
|
21
21
|
}),
|
|
22
|
-
article:
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
article: $__i18n._({
|
|
23
|
+
id: "f6e0Ry",
|
|
24
|
+
message: "Article"
|
|
25
25
|
}),
|
|
26
|
-
link:
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
link: $__i18n._({
|
|
27
|
+
id: "yzF66j",
|
|
28
|
+
message: "Link"
|
|
29
29
|
}),
|
|
30
|
-
quote:
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
quote: $__i18n._({
|
|
31
|
+
id: "ZhhOwV",
|
|
32
|
+
message: "Quote"
|
|
33
33
|
}),
|
|
34
|
-
image:
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
image: $__i18n._({
|
|
35
|
+
id: "hG89Ed",
|
|
36
|
+
message: "Image"
|
|
37
37
|
}),
|
|
38
|
-
page:
|
|
39
|
-
|
|
40
|
-
|
|
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 {
|
|
46
|
+
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
47
47
|
const labels = {
|
|
48
|
-
note:
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
note: $__i18n._({
|
|
49
|
+
id: "1DBGsz",
|
|
50
|
+
message: "Notes"
|
|
51
51
|
}),
|
|
52
|
-
article:
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
article: $__i18n._({
|
|
53
|
+
id: "Tt5T6+",
|
|
54
|
+
message: "Articles"
|
|
55
55
|
}),
|
|
56
|
-
link:
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
link: $__i18n._({
|
|
57
|
+
id: "Rj01Fz",
|
|
58
|
+
message: "Links"
|
|
59
59
|
}),
|
|
60
|
-
quote:
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
quote: $__i18n._({
|
|
61
|
+
id: "eWLklq",
|
|
62
|
+
message: "Quotes"
|
|
63
63
|
}),
|
|
64
|
-
image:
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
image: $__i18n._({
|
|
65
|
+
id: "an5hVd",
|
|
66
|
+
message: "Images"
|
|
67
67
|
}),
|
|
68
|
-
page:
|
|
69
|
-
|
|
70
|
-
|
|
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 {
|
|
86
|
-
const title = type ? getTypeLabelPlural(type) :
|
|
87
|
-
|
|
88
|
-
|
|
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:
|
|
107
|
-
|
|
108
|
-
|
|
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:
|
|
124
|
-
|
|
125
|
-
|
|
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 ?
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}) :
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
192
|
+
"←",
|
|
193
|
+
" ",
|
|
194
|
+
$__i18n._({
|
|
195
|
+
id: "x4RuFo",
|
|
196
|
+
message: "Back to home"
|
|
199
197
|
})
|
|
200
198
|
]
|
|
201
199
|
})
|