@jant/core 0.3.21 → 0.3.23
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/dist/app.js +23 -4
- package/dist/index.js +11 -4
- package/dist/lib/feed.js +112 -0
- package/dist/lib/navigation.js +9 -9
- package/dist/lib/render.js +48 -0
- package/dist/lib/theme-components.js +18 -18
- package/dist/lib/view.js +228 -0
- package/dist/routes/api/timeline.js +22 -18
- package/dist/routes/feed/rss.js +34 -78
- package/dist/routes/feed/sitemap.js +11 -26
- package/dist/routes/pages/archive.js +18 -195
- package/dist/routes/pages/collection.js +16 -70
- package/dist/routes/pages/home.js +25 -47
- package/dist/routes/pages/page.js +15 -27
- package/dist/routes/pages/post.js +25 -79
- package/dist/routes/pages/search.js +20 -130
- package/dist/theme/components/MediaGallery.js +10 -10
- package/dist/theme/components/index.js +0 -2
- package/dist/theme/index.js +10 -13
- package/dist/theme/layouts/index.js +0 -1
- package/dist/themes/minimal/MinimalSiteLayout.js +83 -0
- package/dist/themes/minimal/index.js +65 -0
- package/dist/themes/minimal/pages/ArchivePage.js +156 -0
- package/dist/themes/minimal/pages/CollectionPage.js +65 -0
- package/dist/themes/minimal/pages/HomePage.js +25 -0
- package/dist/themes/minimal/pages/PostPage.js +47 -0
- package/dist/themes/minimal/pages/SearchPage.js +121 -0
- package/dist/themes/minimal/pages/SinglePage.js +22 -0
- package/dist/themes/minimal/timeline/ArticleCard.js +36 -0
- package/dist/themes/minimal/timeline/ImageCard.js +67 -0
- package/dist/themes/minimal/timeline/LinkCard.js +47 -0
- package/dist/themes/minimal/timeline/NoteCard.js +34 -0
- package/dist/{theme/components → themes/minimal}/timeline/QuoteCard.js +9 -12
- package/dist/themes/minimal/timeline/ThreadPreview.js +46 -0
- package/dist/themes/minimal/timeline/TimelineFeed.js +48 -0
- package/dist/themes/minimal/timeline/TimelineItem.js +44 -0
- package/package.json +2 -1
- package/src/app.tsx +27 -4
- package/src/i18n/locales/en.po +53 -53
- package/src/i18n/locales/zh-Hans.po +53 -53
- package/src/i18n/locales/zh-Hant.po +53 -53
- package/src/index.ts +54 -6
- package/src/lib/__tests__/theme-components.test.ts +33 -14
- package/src/lib/__tests__/view.test.ts +377 -0
- package/src/lib/feed.ts +148 -0
- package/src/lib/navigation.ts +11 -11
- package/src/lib/render.tsx +67 -0
- package/src/lib/theme-components.ts +27 -35
- package/src/lib/view.ts +318 -0
- package/src/routes/api/__tests__/timeline.test.ts +3 -3
- package/src/routes/api/timeline.tsx +34 -27
- package/src/routes/feed/rss.ts +47 -94
- package/src/routes/feed/sitemap.ts +8 -30
- package/src/routes/pages/archive.tsx +24 -209
- package/src/routes/pages/collection.tsx +19 -75
- package/src/routes/pages/home.tsx +42 -76
- package/src/routes/pages/page.tsx +17 -28
- package/src/routes/pages/post.tsx +28 -86
- package/src/routes/pages/search.tsx +29 -151
- package/src/services/search.ts +2 -8
- package/src/styles/components.css +0 -54
- package/src/theme/components/MediaGallery.tsx +12 -12
- package/src/theme/components/index.ts +0 -12
- package/src/theme/index.ts +11 -13
- package/src/theme/layouts/index.ts +1 -1
- package/src/themes/minimal/MinimalSiteLayout.tsx +100 -0
- package/src/themes/minimal/index.ts +83 -0
- package/src/themes/minimal/pages/ArchivePage.tsx +157 -0
- package/src/themes/minimal/pages/CollectionPage.tsx +60 -0
- package/src/themes/minimal/pages/HomePage.tsx +41 -0
- package/src/themes/minimal/pages/PostPage.tsx +43 -0
- package/src/themes/minimal/pages/SearchPage.tsx +122 -0
- package/src/themes/minimal/pages/SinglePage.tsx +23 -0
- package/src/themes/minimal/timeline/ArticleCard.tsx +37 -0
- package/src/themes/minimal/timeline/ImageCard.tsx +63 -0
- package/src/themes/minimal/timeline/LinkCard.tsx +48 -0
- package/src/themes/minimal/timeline/NoteCard.tsx +35 -0
- package/src/{theme/components → themes/minimal}/timeline/QuoteCard.tsx +11 -17
- package/src/themes/minimal/timeline/ThreadPreview.tsx +47 -0
- package/src/{theme/components → themes/minimal}/timeline/TimelineFeed.tsx +20 -15
- package/src/themes/minimal/timeline/TimelineItem.tsx +75 -0
- package/src/types.ts +262 -38
- package/dist/theme/components/timeline/ArticleCard.js +0 -50
- package/dist/theme/components/timeline/ImageCard.js +0 -86
- package/dist/theme/components/timeline/LinkCard.js +0 -62
- package/dist/theme/components/timeline/NoteCard.js +0 -37
- package/dist/theme/components/timeline/ThreadPreview.js +0 -52
- package/dist/theme/components/timeline/TimelineFeed.js +0 -43
- package/dist/theme/components/timeline/TimelineItem.js +0 -25
- package/dist/theme/components/timeline/index.js +0 -8
- package/dist/theme/layouts/SiteLayout.js +0 -160
- package/src/theme/components/timeline/ArticleCard.tsx +0 -57
- package/src/theme/components/timeline/ImageCard.tsx +0 -80
- package/src/theme/components/timeline/LinkCard.tsx +0 -66
- package/src/theme/components/timeline/NoteCard.tsx +0 -41
- package/src/theme/components/timeline/ThreadPreview.tsx +0 -49
- package/src/theme/components/timeline/TimelineItem.tsx +0 -39
- package/src/theme/components/timeline/index.ts +0 -8
- package/src/theme/layouts/SiteLayout.tsx +0 -184
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Quote Card
|
|
2
|
+
* Minimal Theme - Quote Card
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Subtle blockquote with left border for type="quote" posts.
|
|
5
5
|
*/ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
6
|
-
import * as sqid from "../../../lib/sqid.js";
|
|
7
|
-
import * as time from "../../../lib/time.js";
|
|
8
6
|
export const QuoteCard = ({ post, compact })=>{
|
|
9
|
-
const permalink = `/p/${sqid.encode(post.id)}`;
|
|
10
7
|
return /*#__PURE__*/ _jsxs("article", {
|
|
11
|
-
class: `h-entry
|
|
8
|
+
class: `h-entry${compact ? " text-sm" : ""}`,
|
|
12
9
|
children: [
|
|
13
10
|
post.contentHtml && /*#__PURE__*/ _jsx("blockquote", {
|
|
14
|
-
class: `e-content italic ${compact ? "text-sm" : "
|
|
11
|
+
class: `e-content border-l-2 border-muted-foreground/30 pl-4 italic ${compact ? "text-sm" : ""} leading-relaxed`,
|
|
15
12
|
children: /*#__PURE__*/ _jsx("div", {
|
|
16
13
|
dangerouslySetInnerHTML: {
|
|
17
14
|
__html: post.contentHtml
|
|
@@ -35,14 +32,14 @@ export const QuoteCard = ({ post, compact })=>{
|
|
|
35
32
|
]
|
|
36
33
|
}),
|
|
37
34
|
/*#__PURE__*/ _jsx("footer", {
|
|
38
|
-
class: "mt-2
|
|
35
|
+
class: "mt-2",
|
|
39
36
|
children: /*#__PURE__*/ _jsx("a", {
|
|
40
|
-
href: permalink,
|
|
41
|
-
class: "u-url hover:
|
|
37
|
+
href: post.permalink,
|
|
38
|
+
class: "u-url text-xs text-muted-foreground hover:text-foreground",
|
|
42
39
|
children: /*#__PURE__*/ _jsx("time", {
|
|
43
40
|
class: "dt-published",
|
|
44
|
-
datetime:
|
|
45
|
-
children:
|
|
41
|
+
datetime: post.publishedAt,
|
|
42
|
+
children: post.publishedAtFormatted
|
|
46
43
|
})
|
|
47
44
|
})
|
|
48
45
|
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Theme - Thread Preview
|
|
3
|
+
*
|
|
4
|
+
* Minimal thread indicator: root post + compact replies + "show more" link.
|
|
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, theme })=>{
|
|
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
|
+
theme: theme
|
|
19
|
+
}),
|
|
20
|
+
previewReplies.length > 0 && /*#__PURE__*/ _jsxs("div", {
|
|
21
|
+
class: "ml-4 mt-2 border-l border-border pl-4 flex flex-col gap-3",
|
|
22
|
+
children: [
|
|
23
|
+
previewReplies.map((reply)=>/*#__PURE__*/ _jsx("div", {
|
|
24
|
+
children: /*#__PURE__*/ _jsx(TimelineItemFromPost, {
|
|
25
|
+
post: reply,
|
|
26
|
+
compact: true,
|
|
27
|
+
theme: theme
|
|
28
|
+
})
|
|
29
|
+
}, reply.id)),
|
|
30
|
+
remainingCount > 0 && /*#__PURE__*/ _jsx("a", {
|
|
31
|
+
href: rootPost.permalink,
|
|
32
|
+
class: "text-sm text-muted-foreground hover:text-foreground hover:underline",
|
|
33
|
+
children: $__i18n._({
|
|
34
|
+
id: "smzF8S",
|
|
35
|
+
message: "Show {remainingCount} more {0}",
|
|
36
|
+
values: {
|
|
37
|
+
remainingCount: remainingCount,
|
|
38
|
+
0: remainingCount === 1 ? "reply" : "replies"
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
})
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Theme - Timeline Feed
|
|
3
|
+
*
|
|
4
|
+
* Divider-separated stream of posts with load-more button.
|
|
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 { ThreadPreview as DefaultThreadPreview } from "./ThreadPreview.js";
|
|
9
|
+
export const TimelineFeed = ({ items, hasMore, nextCursor, theme })=>{
|
|
10
|
+
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
11
|
+
const ResolvedThreadPreview = theme?.ThreadPreview ?? DefaultThreadPreview;
|
|
12
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ _jsx("div", {
|
|
15
|
+
id: "timeline-feed",
|
|
16
|
+
class: "flex flex-col",
|
|
17
|
+
children: items.map((item, i)=>/*#__PURE__*/ _jsxs("div", {
|
|
18
|
+
children: [
|
|
19
|
+
i > 0 && /*#__PURE__*/ _jsx("hr", {
|
|
20
|
+
class: "my-6 border-border"
|
|
21
|
+
}),
|
|
22
|
+
item.threadPreview ? /*#__PURE__*/ _jsx(ResolvedThreadPreview, {
|
|
23
|
+
rootPost: item.post,
|
|
24
|
+
previewReplies: item.threadPreview.replies,
|
|
25
|
+
totalReplyCount: item.threadPreview.totalReplyCount,
|
|
26
|
+
theme: theme
|
|
27
|
+
}) : /*#__PURE__*/ _jsx(TimelineItem, {
|
|
28
|
+
item: item,
|
|
29
|
+
theme: theme
|
|
30
|
+
})
|
|
31
|
+
]
|
|
32
|
+
}, item.post.id))
|
|
33
|
+
}),
|
|
34
|
+
hasMore && nextCursor && /*#__PURE__*/ _jsx("div", {
|
|
35
|
+
id: "load-more-container",
|
|
36
|
+
class: "mt-8 text-center",
|
|
37
|
+
children: /*#__PURE__*/ _jsx("button", {
|
|
38
|
+
class: "text-sm text-muted-foreground hover:text-foreground hover:underline",
|
|
39
|
+
"data-on:click": `@get('/api/timeline?cursor=${nextCursor}')`,
|
|
40
|
+
children: $__i18n._({
|
|
41
|
+
id: "yQ2kGp",
|
|
42
|
+
message: "Load more"
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
]
|
|
47
|
+
});
|
|
48
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Theme - Timeline Item
|
|
3
|
+
*
|
|
4
|
+
* Dispatches to the correct card component based on post type.
|
|
5
|
+
*/ import { jsx as _jsx } from "hono/jsx/jsx-runtime";
|
|
6
|
+
import { NoteCard } from "./NoteCard.js";
|
|
7
|
+
import { ArticleCard } from "./ArticleCard.js";
|
|
8
|
+
import { LinkCard } from "./LinkCard.js";
|
|
9
|
+
import { QuoteCard } from "./QuoteCard.js";
|
|
10
|
+
import { ImageCard } from "./ImageCard.js";
|
|
11
|
+
const CARD_MAP = {
|
|
12
|
+
note: NoteCard,
|
|
13
|
+
article: ArticleCard,
|
|
14
|
+
link: LinkCard,
|
|
15
|
+
quote: QuoteCard,
|
|
16
|
+
image: ImageCard,
|
|
17
|
+
page: NoteCard
|
|
18
|
+
};
|
|
19
|
+
const THEME_KEY_MAP = {
|
|
20
|
+
note: "NoteCard",
|
|
21
|
+
article: "ArticleCard",
|
|
22
|
+
link: "LinkCard",
|
|
23
|
+
quote: "QuoteCard",
|
|
24
|
+
image: "ImageCard",
|
|
25
|
+
page: "NoteCard"
|
|
26
|
+
};
|
|
27
|
+
export const TimelineItem = ({ item, compact, cardOverride, theme })=>{
|
|
28
|
+
const themeKey = THEME_KEY_MAP[item.post.type];
|
|
29
|
+
const themeCard = theme?.[themeKey];
|
|
30
|
+
const Card = cardOverride ?? themeCard ?? CARD_MAP[item.post.type];
|
|
31
|
+
return /*#__PURE__*/ _jsx(Card, {
|
|
32
|
+
post: item.post,
|
|
33
|
+
compact: compact
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
export const TimelineItemFromPost = ({ post, compact, cardOverride, theme })=>{
|
|
37
|
+
const themeKey = THEME_KEY_MAP[post.type];
|
|
38
|
+
const themeCard = theme?.[themeKey];
|
|
39
|
+
const Card = cardOverride ?? themeCard ?? CARD_MAP[post.type];
|
|
40
|
+
return /*#__PURE__*/ _jsx(Card, {
|
|
41
|
+
post: post,
|
|
42
|
+
compact: compact
|
|
43
|
+
});
|
|
44
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jant/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.23",
|
|
4
4
|
"description": "A modern, open-source microblogging platform built on Cloudflare Workers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"zod": "^4.3.6"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
+
"hono": "^4.0.0",
|
|
48
49
|
"tailwindcss": "^4.0.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
package/src/app.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import { i18nMiddleware } from "./i18n/index.js";
|
|
|
11
11
|
import { useLingui } from "@lingui/react/macro";
|
|
12
12
|
import type { Bindings, JantConfig } from "./types.js";
|
|
13
13
|
import { SETTINGS_KEYS } from "./lib/constants.js";
|
|
14
|
+
import { theme as minimalTheme } from "./themes/minimal/index.js";
|
|
14
15
|
import { hashPassword } from "better-auth/crypto";
|
|
15
16
|
|
|
16
17
|
// Routes - Pages
|
|
@@ -77,11 +78,30 @@ export type App = Hono<{ Bindings: Bindings; Variables: AppVariables }>;
|
|
|
77
78
|
* import { createApp } from "@jant/core";
|
|
78
79
|
*
|
|
79
80
|
* export default createApp({
|
|
80
|
-
* theme: { components: {
|
|
81
|
+
* theme: { components: { PostPage: MyPostPage } },
|
|
81
82
|
* });
|
|
82
83
|
* ```
|
|
83
84
|
*/
|
|
84
85
|
export function createApp(config: JantConfig = {}): App {
|
|
86
|
+
// Merge with default minimal theme
|
|
87
|
+
const defaultTheme = minimalTheme();
|
|
88
|
+
const resolvedConfig: JantConfig = {
|
|
89
|
+
...config,
|
|
90
|
+
theme: {
|
|
91
|
+
name: config.theme?.name ?? defaultTheme.name,
|
|
92
|
+
components: {
|
|
93
|
+
...defaultTheme.components,
|
|
94
|
+
...config.theme?.components,
|
|
95
|
+
},
|
|
96
|
+
cssVariables: {
|
|
97
|
+
...defaultTheme.cssVariables,
|
|
98
|
+
...config.theme?.cssVariables,
|
|
99
|
+
},
|
|
100
|
+
colorThemes: config.theme?.colorThemes ?? defaultTheme.colorThemes,
|
|
101
|
+
feed: config.theme?.feed,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
85
105
|
const app = new Hono<{ Bindings: Bindings; Variables: AppVariables }>();
|
|
86
106
|
|
|
87
107
|
// Initialize services, auth, and config middleware
|
|
@@ -96,7 +116,7 @@ export function createApp(config: JantConfig = {}): App {
|
|
|
96
116
|
const db = createDatabase(session as unknown as D1Database);
|
|
97
117
|
const services = createServices(db, session as unknown as D1Database);
|
|
98
118
|
c.set("services", services);
|
|
99
|
-
c.set("config",
|
|
119
|
+
c.set("config", resolvedConfig);
|
|
100
120
|
c.set("storage", createStorageDriver(c.env));
|
|
101
121
|
|
|
102
122
|
if (c.env.AUTH_SECRET) {
|
|
@@ -117,11 +137,14 @@ export function createApp(config: JantConfig = {}): App {
|
|
|
117
137
|
// Theme middleware - resolve active color theme and build CSS
|
|
118
138
|
app.use("*", async (c, next) => {
|
|
119
139
|
const themeId = await c.var.services.settings.get(SETTINGS_KEYS.THEME);
|
|
120
|
-
const themes = getAvailableThemes(
|
|
140
|
+
const themes = getAvailableThemes(resolvedConfig);
|
|
121
141
|
const activeTheme = themeId
|
|
122
142
|
? themes.find((t) => t.id === themeId)
|
|
123
143
|
: undefined;
|
|
124
|
-
const themeStyle = buildThemeStyle(
|
|
144
|
+
const themeStyle = buildThemeStyle(
|
|
145
|
+
activeTheme,
|
|
146
|
+
resolvedConfig.theme?.cssVariables,
|
|
147
|
+
);
|
|
125
148
|
c.set("themeStyle", themeStyle);
|
|
126
149
|
await next();
|
|
127
150
|
});
|
package/src/i18n/locales/en.po
CHANGED
|
@@ -14,9 +14,9 @@ msgstr ""
|
|
|
14
14
|
"Plural-Forms: \n"
|
|
15
15
|
|
|
16
16
|
#. @context: Archive post reply indicator - plural
|
|
17
|
-
#: src/
|
|
18
|
-
msgid "{count} replies"
|
|
19
|
-
msgstr "{count} replies"
|
|
17
|
+
#: src/theme/pages/ArchivePage.tsx:168
|
|
18
|
+
#~ msgid "{count} replies"
|
|
19
|
+
#~ msgstr "{count} replies"
|
|
20
20
|
|
|
21
21
|
#. @context: Navigation link
|
|
22
22
|
#: src/routes/dash/collections.tsx:282
|
|
@@ -31,9 +31,9 @@ msgstr "← Back to Collections"
|
|
|
31
31
|
#~ msgstr "← Back to home"
|
|
32
32
|
|
|
33
33
|
#. @context: Archive post reply indicator - single
|
|
34
|
-
#: src/
|
|
35
|
-
msgid "1 reply"
|
|
36
|
-
msgstr "1 reply"
|
|
34
|
+
#: src/theme/pages/ArchivePage.tsx:163
|
|
35
|
+
#~ msgid "1 reply"
|
|
36
|
+
#~ msgstr "1 reply"
|
|
37
37
|
|
|
38
38
|
#. @context: Redirect type option
|
|
39
39
|
#: src/routes/dash/redirects.tsx:146
|
|
@@ -56,7 +56,7 @@ msgid "Add Media"
|
|
|
56
56
|
msgstr "Add Media"
|
|
57
57
|
|
|
58
58
|
#. @context: Archive filter - all types
|
|
59
|
-
#: src/
|
|
59
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:90
|
|
60
60
|
msgid "All"
|
|
61
61
|
msgstr "All"
|
|
62
62
|
|
|
@@ -66,7 +66,7 @@ msgid "Appearance"
|
|
|
66
66
|
msgstr "Appearance"
|
|
67
67
|
|
|
68
68
|
#. @context: Archive page title
|
|
69
|
-
#: src/
|
|
69
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:76
|
|
70
70
|
msgid "Archive"
|
|
71
71
|
msgstr "Archive"
|
|
72
72
|
|
|
@@ -78,14 +78,14 @@ msgstr "Are you sure you want to delete this post? This cannot be undone."
|
|
|
78
78
|
#. @context: Post type badge - article
|
|
79
79
|
#. @context: Post type label - article
|
|
80
80
|
#. @context: Post type option
|
|
81
|
-
#: src/routes/pages/archive.tsx:28
|
|
82
81
|
#: src/theme/components/PostForm.tsx:74
|
|
83
82
|
#: src/theme/components/TypeBadge.tsx:20
|
|
83
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:17
|
|
84
84
|
msgid "Article"
|
|
85
85
|
msgstr "Article"
|
|
86
86
|
|
|
87
87
|
#. @context: Post type label plural - articles
|
|
88
|
-
#: src/
|
|
88
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:42
|
|
89
89
|
msgid "Articles"
|
|
90
90
|
msgstr "Articles"
|
|
91
91
|
|
|
@@ -153,7 +153,7 @@ msgid "Color theme"
|
|
|
153
153
|
msgstr "Color theme"
|
|
154
154
|
|
|
155
155
|
#. @context: Setup form submit button
|
|
156
|
-
#: src/app.tsx:
|
|
156
|
+
#: src/app.tsx:277
|
|
157
157
|
msgid "Complete Setup"
|
|
158
158
|
msgstr "Complete Setup"
|
|
159
159
|
|
|
@@ -163,7 +163,7 @@ msgid "Confirm New Password"
|
|
|
163
163
|
msgstr "Confirm New Password"
|
|
164
164
|
|
|
165
165
|
#. @context: Password reset form field
|
|
166
|
-
#: src/app.tsx:
|
|
166
|
+
#: src/app.tsx:538
|
|
167
167
|
msgid "Confirm Password"
|
|
168
168
|
msgstr "Confirm Password"
|
|
169
169
|
|
|
@@ -202,7 +202,7 @@ msgid "Create Redirect"
|
|
|
202
202
|
msgstr "Create Redirect"
|
|
203
203
|
|
|
204
204
|
#. @context: Setup page description
|
|
205
|
-
#: src/app.tsx:
|
|
205
|
+
#: src/app.tsx:217
|
|
206
206
|
msgid "Create your admin account."
|
|
207
207
|
msgstr "Create your admin account."
|
|
208
208
|
|
|
@@ -268,7 +268,7 @@ msgid "Deleting this media will remove it permanently from storage."
|
|
|
268
268
|
msgstr "Deleting this media will remove it permanently from storage."
|
|
269
269
|
|
|
270
270
|
#. @context: Hint shown on signin page when demo credentials are pre-filled
|
|
271
|
-
#: src/app.tsx:
|
|
271
|
+
#: src/app.tsx:376
|
|
272
272
|
msgid "Demo account pre-filled. Just click Sign In."
|
|
273
273
|
msgstr "Demo account pre-filled. Just click Sign In."
|
|
274
274
|
|
|
@@ -358,13 +358,13 @@ msgstr "Edit Post"
|
|
|
358
358
|
|
|
359
359
|
#. @context: Setup/signin form field - email
|
|
360
360
|
#. @context: Setup/signin form field - email
|
|
361
|
-
#: src/app.tsx:
|
|
362
|
-
#: src/app.tsx:
|
|
361
|
+
#: src/app.tsx:247
|
|
362
|
+
#: src/app.tsx:391
|
|
363
363
|
msgid "Email"
|
|
364
364
|
msgstr "Email"
|
|
365
365
|
|
|
366
366
|
#. @context: Password reset page description
|
|
367
|
-
#: src/app.tsx:
|
|
367
|
+
#: src/app.tsx:507
|
|
368
368
|
msgid "Enter your new password."
|
|
369
369
|
msgstr "Enter your new password."
|
|
370
370
|
|
|
@@ -376,12 +376,12 @@ msgid "Featured"
|
|
|
376
376
|
msgstr "Featured"
|
|
377
377
|
|
|
378
378
|
#. @context: Search results count - multiple
|
|
379
|
-
#: src/
|
|
379
|
+
#: src/themes/minimal/pages/SearchPage.tsx:73
|
|
380
380
|
msgid "Found {count} results"
|
|
381
381
|
msgstr "Found {count} results"
|
|
382
382
|
|
|
383
383
|
#. @context: Search results count - single
|
|
384
|
-
#: src/
|
|
384
|
+
#: src/themes/minimal/pages/SearchPage.tsx:69
|
|
385
385
|
msgid "Found 1 result"
|
|
386
386
|
msgstr "Found 1 result"
|
|
387
387
|
|
|
@@ -400,14 +400,14 @@ msgstr "General"
|
|
|
400
400
|
#. @context: Post type badge - image
|
|
401
401
|
#. @context: Post type label - image
|
|
402
402
|
#. @context: Post type option
|
|
403
|
-
#: src/routes/pages/archive.tsx:37
|
|
404
403
|
#: src/theme/components/PostForm.tsx:83
|
|
405
404
|
#: src/theme/components/TypeBadge.tsx:29
|
|
405
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:26
|
|
406
406
|
msgid "Image"
|
|
407
407
|
msgstr "Image"
|
|
408
408
|
|
|
409
409
|
#. @context: Post type label plural - images
|
|
410
|
-
#: src/
|
|
410
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:54
|
|
411
411
|
msgid "Images"
|
|
412
412
|
msgstr "Images"
|
|
413
413
|
|
|
@@ -417,7 +417,7 @@ msgid "Images are automatically optimized: resized to max 1920px, converted to W
|
|
|
417
417
|
msgstr "Images are automatically optimized: resized to max 1920px, converted to WebP, and metadata stripped."
|
|
418
418
|
|
|
419
419
|
#. @context: Password reset error heading
|
|
420
|
-
#: src/app.tsx:
|
|
420
|
+
#: src/app.tsx:582
|
|
421
421
|
msgid "Invalid or Expired Link"
|
|
422
422
|
msgstr "Invalid or Expired Link"
|
|
423
423
|
|
|
@@ -439,21 +439,21 @@ msgstr "Language"
|
|
|
439
439
|
#. @context: Post type badge - link
|
|
440
440
|
#. @context: Post type label - link
|
|
441
441
|
#. @context: Post type option
|
|
442
|
-
#: src/routes/pages/archive.tsx:32
|
|
443
442
|
#: src/theme/components/PostForm.tsx:77
|
|
444
443
|
#: src/theme/components/TypeBadge.tsx:24
|
|
444
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:21
|
|
445
445
|
msgid "Link"
|
|
446
446
|
msgstr "Link"
|
|
447
447
|
|
|
448
448
|
#. @context: Post type label plural - links
|
|
449
|
-
#: src/
|
|
449
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:46
|
|
450
450
|
msgid "Links"
|
|
451
451
|
msgstr "Links"
|
|
452
452
|
|
|
453
453
|
#. @context: Button to load more posts in timeline
|
|
454
454
|
#. @context: Pagination button - load more items
|
|
455
455
|
#: src/theme/components/Pagination.tsx:103
|
|
456
|
-
#: src/
|
|
456
|
+
#: src/themes/minimal/timeline/TimelineFeed.tsx:48
|
|
457
457
|
msgid "Load more"
|
|
458
458
|
msgstr "Load more"
|
|
459
459
|
|
|
@@ -535,7 +535,7 @@ msgstr "New Page"
|
|
|
535
535
|
|
|
536
536
|
#. @context: Password form field
|
|
537
537
|
#. @context: Password reset form field
|
|
538
|
-
#: src/app.tsx:
|
|
538
|
+
#: src/app.tsx:522
|
|
539
539
|
#: src/routes/dash/settings.tsx:442
|
|
540
540
|
msgid "New Password"
|
|
541
541
|
msgstr "New Password"
|
|
@@ -586,21 +586,21 @@ msgid "No pages yet."
|
|
|
586
586
|
msgstr "No pages yet."
|
|
587
587
|
|
|
588
588
|
#. @context: Archive empty state
|
|
589
|
-
#: src/
|
|
589
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:110
|
|
590
590
|
msgid "No posts found."
|
|
591
591
|
msgstr "No posts found."
|
|
592
592
|
|
|
593
593
|
#. @context: Empty state message
|
|
594
594
|
#. @context: Empty state message
|
|
595
595
|
#: src/routes/dash/collections.tsx:243
|
|
596
|
-
#: src/
|
|
596
|
+
#: src/themes/minimal/pages/CollectionPage.tsx:29
|
|
597
597
|
msgid "No posts in this collection."
|
|
598
598
|
msgstr "No posts in this collection."
|
|
599
599
|
|
|
600
600
|
#. @context: Empty state message on home page
|
|
601
601
|
#. @context: Empty state message when no posts exist
|
|
602
|
-
#: src/routes/pages/home.tsx:42
|
|
603
602
|
#: src/theme/components/PostList.tsx:25
|
|
603
|
+
#: src/themes/minimal/pages/HomePage.tsx:26
|
|
604
604
|
msgid "No posts yet."
|
|
605
605
|
msgstr "No posts yet."
|
|
606
606
|
|
|
@@ -610,21 +610,21 @@ msgid "No redirects configured."
|
|
|
610
610
|
msgstr "No redirects configured."
|
|
611
611
|
|
|
612
612
|
#. @context: Search empty results
|
|
613
|
-
#: src/
|
|
613
|
+
#: src/themes/minimal/pages/SearchPage.tsx:64
|
|
614
614
|
msgid "No results found."
|
|
615
615
|
msgstr "No results found."
|
|
616
616
|
|
|
617
617
|
#. @context: Post type badge - note
|
|
618
618
|
#. @context: Post type label - note
|
|
619
619
|
#. @context: Post type option
|
|
620
|
-
#: src/routes/pages/archive.tsx:27
|
|
621
620
|
#: src/theme/components/PostForm.tsx:71
|
|
622
621
|
#: src/theme/components/TypeBadge.tsx:19
|
|
622
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:16
|
|
623
623
|
msgid "Note"
|
|
624
624
|
msgstr "Note"
|
|
625
625
|
|
|
626
626
|
#. @context: Post type label plural - notes
|
|
627
|
-
#: src/
|
|
627
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:38
|
|
628
628
|
msgid "Notes"
|
|
629
629
|
msgstr "Notes"
|
|
630
630
|
|
|
@@ -632,8 +632,8 @@ msgstr "Notes"
|
|
|
632
632
|
#. @context: Post type badge - page
|
|
633
633
|
#. @context: Post type label - page
|
|
634
634
|
#: src/routes/dash/pages.tsx:125
|
|
635
|
-
#: src/routes/pages/archive.tsx:41
|
|
636
635
|
#: src/theme/components/TypeBadge.tsx:33
|
|
636
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:30
|
|
637
637
|
msgid "Page"
|
|
638
638
|
msgstr "Page"
|
|
639
639
|
|
|
@@ -656,15 +656,15 @@ msgstr "Page title..."
|
|
|
656
656
|
#. @context: Pages main heading
|
|
657
657
|
#. @context: Post type label plural - pages
|
|
658
658
|
#: src/routes/dash/pages.tsx:36
|
|
659
|
-
#: src/routes/pages/archive.tsx:69
|
|
660
659
|
#: src/theme/layouts/DashLayout.tsx:96
|
|
660
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:58
|
|
661
661
|
msgid "Pages"
|
|
662
662
|
msgstr "Pages"
|
|
663
663
|
|
|
664
664
|
#. @context: Setup/signin form field - password
|
|
665
665
|
#. @context: Setup/signin form field - password
|
|
666
|
-
#: src/app.tsx:
|
|
667
|
-
#: src/app.tsx:
|
|
666
|
+
#: src/app.tsx:262
|
|
667
|
+
#: src/app.tsx:400
|
|
668
668
|
msgid "Password"
|
|
669
669
|
msgstr "Password"
|
|
670
670
|
|
|
@@ -680,8 +680,8 @@ msgstr "Path (e.g. /archive) or full URL (e.g. https://example.com)"
|
|
|
680
680
|
|
|
681
681
|
#. @context: Link to individual post in thread
|
|
682
682
|
#. @context: Link to permanent URL of post
|
|
683
|
-
#: src/routes/pages/post.tsx:56
|
|
684
683
|
#: src/theme/components/ThreadView.tsx:68
|
|
684
|
+
#: src/themes/minimal/pages/PostPage.tsx:35
|
|
685
685
|
msgid "Permalink"
|
|
686
686
|
msgstr "Permalink"
|
|
687
687
|
|
|
@@ -732,9 +732,9 @@ msgstr "Previous"
|
|
|
732
732
|
#. @context: Loading text shown on submit button while request is in progress
|
|
733
733
|
#. @context: Loading text shown on submit button while request is in progress
|
|
734
734
|
#. @context: Upload status - processing
|
|
735
|
-
#: src/app.tsx:
|
|
736
|
-
#: src/app.tsx:
|
|
737
|
-
#: src/app.tsx:
|
|
735
|
+
#: src/app.tsx:283
|
|
736
|
+
#: src/app.tsx:420
|
|
737
|
+
#: src/app.tsx:560
|
|
738
738
|
#: src/routes/dash/collections.tsx:178
|
|
739
739
|
#: src/routes/dash/collections.tsx:357
|
|
740
740
|
#: src/routes/dash/media.tsx:119
|
|
@@ -788,14 +788,14 @@ msgstr "Quiet (normal)"
|
|
|
788
788
|
#. @context: Post type badge - quote
|
|
789
789
|
#. @context: Post type label - quote
|
|
790
790
|
#. @context: Post type option
|
|
791
|
-
#: src/routes/pages/archive.tsx:33
|
|
792
791
|
#: src/theme/components/PostForm.tsx:80
|
|
793
792
|
#: src/theme/components/TypeBadge.tsx:25
|
|
793
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:22
|
|
794
794
|
msgid "Quote"
|
|
795
795
|
msgstr "Quote"
|
|
796
796
|
|
|
797
797
|
#. @context: Post type label plural - quotes
|
|
798
|
-
#: src/
|
|
798
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:50
|
|
799
799
|
msgid "Quotes"
|
|
800
800
|
msgstr "Quotes"
|
|
801
801
|
|
|
@@ -815,8 +815,8 @@ msgstr "Remove"
|
|
|
815
815
|
|
|
816
816
|
#. @context: Password reset form submit button
|
|
817
817
|
#. @context: Password reset page heading
|
|
818
|
-
#: src/app.tsx:
|
|
819
|
-
#: src/app.tsx:
|
|
818
|
+
#: src/app.tsx:501
|
|
819
|
+
#: src/app.tsx:554
|
|
820
820
|
msgid "Reset Password"
|
|
821
821
|
msgstr "Reset Password"
|
|
822
822
|
|
|
@@ -837,8 +837,8 @@ msgstr "Save Settings"
|
|
|
837
837
|
|
|
838
838
|
#. @context: Search page title
|
|
839
839
|
#. @context: Search submit button
|
|
840
|
-
#: src/
|
|
841
|
-
#: src/
|
|
840
|
+
#: src/themes/minimal/pages/SearchPage.tsx:21
|
|
841
|
+
#: src/themes/minimal/pages/SearchPage.tsx:46
|
|
842
842
|
msgid "Search"
|
|
843
843
|
msgstr "Search"
|
|
844
844
|
|
|
@@ -848,7 +848,7 @@ msgstr "Search"
|
|
|
848
848
|
#~ msgstr "Search failed. Please try again."
|
|
849
849
|
|
|
850
850
|
#. @context: Search input placeholder
|
|
851
|
-
#: src/
|
|
851
|
+
#: src/themes/minimal/pages/SearchPage.tsx:38
|
|
852
852
|
msgid "Search posts..."
|
|
853
853
|
msgstr "Search posts..."
|
|
854
854
|
|
|
@@ -875,14 +875,14 @@ msgstr "Settings"
|
|
|
875
875
|
|
|
876
876
|
#. @context: Link to show remaining thread replies
|
|
877
877
|
#. placeholder {0}: remainingCount === 1 ? "reply" : "replies"
|
|
878
|
-
#: src/
|
|
878
|
+
#: src/themes/minimal/timeline/ThreadPreview.tsx:37
|
|
879
879
|
msgid "Show {remainingCount} more {0}"
|
|
880
880
|
msgstr "Show {remainingCount} more {0}"
|
|
881
881
|
|
|
882
882
|
#. @context: Sign in form submit button
|
|
883
883
|
#. @context: Sign in page heading
|
|
884
|
-
#: src/app.tsx:
|
|
885
|
-
#: src/app.tsx:
|
|
884
|
+
#: src/app.tsx:367
|
|
885
|
+
#: src/app.tsx:414
|
|
886
886
|
msgid "Sign In"
|
|
887
887
|
msgstr "Sign In"
|
|
888
888
|
|
|
@@ -944,7 +944,7 @@ msgid "The URL path for this page. Use lowercase letters, numbers, and hyphens."
|
|
|
944
944
|
msgstr "The URL path for this page. Use lowercase letters, numbers, and hyphens."
|
|
945
945
|
|
|
946
946
|
#. @context: Password reset error description
|
|
947
|
-
#: src/app.tsx:
|
|
947
|
+
#: src/app.tsx:590
|
|
948
948
|
msgid "This password reset link is invalid or has expired. Please generate a new one."
|
|
949
949
|
msgstr "This password reset link is invalid or has expired. Please generate a new one."
|
|
950
950
|
|
|
@@ -1093,7 +1093,7 @@ msgid "Visibility"
|
|
|
1093
1093
|
msgstr "Visibility"
|
|
1094
1094
|
|
|
1095
1095
|
#. @context: Setup page welcome heading
|
|
1096
|
-
#: src/app.tsx:
|
|
1096
|
+
#: src/app.tsx:211
|
|
1097
1097
|
msgid "Welcome to Jant"
|
|
1098
1098
|
msgstr "Welcome to Jant"
|
|
1099
1099
|
|
|
@@ -1108,6 +1108,6 @@ msgid "What's this collection about?"
|
|
|
1108
1108
|
msgstr "What's this collection about?"
|
|
1109
1109
|
|
|
1110
1110
|
#. @context: Setup form field - user name
|
|
1111
|
-
#: src/app.tsx:
|
|
1111
|
+
#: src/app.tsx:232
|
|
1112
1112
|
msgid "Your Name"
|
|
1113
1113
|
msgstr "Your Name"
|