@jant/core 0.3.20 → 0.3.22
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 +60 -17
- package/dist/index.js +8 -0
- 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 +20 -16
- package/dist/routes/dash/collections.js +38 -10
- package/dist/routes/dash/navigation.js +22 -8
- package/dist/routes/dash/redirects.js +19 -5
- package/dist/routes/dash/settings.js +57 -15
- 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/PageForm.js +22 -8
- package/dist/theme/components/PostForm.js +22 -8
- package/dist/theme/components/index.js +1 -1
- package/dist/theme/components/timeline/ArticleCard.js +7 -11
- package/dist/theme/components/timeline/ImageCard.js +10 -13
- package/dist/theme/components/timeline/LinkCard.js +4 -7
- package/dist/theme/components/timeline/NoteCard.js +5 -8
- package/dist/theme/components/timeline/QuoteCard.js +3 -6
- package/dist/theme/components/timeline/ThreadPreview.js +9 -10
- package/dist/theme/components/timeline/TimelineFeed.js +8 -5
- package/dist/theme/components/timeline/TimelineItem.js +22 -2
- package/dist/theme/components/timeline/index.js +1 -1
- package/dist/theme/index.js +6 -3
- package/dist/theme/layouts/SiteLayout.js +10 -39
- package/dist/theme/pages/ArchivePage.js +157 -0
- package/dist/theme/pages/CollectionPage.js +63 -0
- package/dist/theme/pages/HomePage.js +26 -0
- package/dist/theme/pages/PostPage.js +48 -0
- package/dist/theme/pages/SearchPage.js +120 -0
- package/dist/theme/pages/SinglePage.js +23 -0
- package/dist/theme/pages/index.js +11 -0
- package/package.json +2 -1
- package/src/app.tsx +48 -17
- package/src/i18n/locales/en.po +171 -147
- package/src/i18n/locales/zh-Hans.po +171 -147
- package/src/i18n/locales/zh-Hant.po +171 -147
- package/src/index.ts +51 -2
- package/src/lib/__tests__/theme-components.test.ts +33 -14
- package/src/lib/__tests__/view.test.ts +375 -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 +32 -25
- package/src/routes/dash/collections.tsx +30 -10
- package/src/routes/dash/navigation.tsx +20 -10
- package/src/routes/dash/redirects.tsx +15 -5
- package/src/routes/dash/settings.tsx +53 -15
- 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/theme/components/MediaGallery.tsx +12 -12
- package/src/theme/components/PageForm.tsx +20 -10
- package/src/theme/components/PostForm.tsx +20 -10
- package/src/theme/components/index.ts +1 -0
- package/src/theme/components/timeline/ArticleCard.tsx +7 -19
- package/src/theme/components/timeline/ImageCard.tsx +10 -20
- package/src/theme/components/timeline/LinkCard.tsx +4 -11
- package/src/theme/components/timeline/NoteCard.tsx +5 -12
- package/src/theme/components/timeline/QuoteCard.tsx +3 -10
- package/src/theme/components/timeline/ThreadPreview.tsx +5 -5
- package/src/theme/components/timeline/TimelineFeed.tsx +7 -3
- package/src/theme/components/timeline/TimelineItem.tsx +43 -4
- package/src/theme/components/timeline/index.ts +1 -1
- package/src/theme/index.ts +7 -3
- package/src/theme/layouts/SiteLayout.tsx +25 -77
- package/src/theme/layouts/index.ts +2 -1
- package/src/theme/pages/ArchivePage.tsx +160 -0
- package/src/theme/pages/CollectionPage.tsx +60 -0
- package/src/theme/pages/HomePage.tsx +42 -0
- package/src/theme/pages/PostPage.tsx +44 -0
- package/src/theme/pages/SearchPage.tsx +128 -0
- package/src/theme/pages/SinglePage.tsx +24 -0
- package/src/theme/pages/index.ts +13 -0
- package/src/types.ts +262 -38
|
@@ -1,126 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "hono/jsx/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Search Page Route
|
|
4
4
|
*/ import { Hono } from "hono";
|
|
5
|
-
import {
|
|
6
|
-
import { BaseLayout, SiteLayout } from "../../theme/layouts/index.js";
|
|
7
|
-
import { PagePagination } from "../../theme/components/index.js";
|
|
8
|
-
import * as sqid from "../../lib/sqid.js";
|
|
9
|
-
import * as time from "../../lib/time.js";
|
|
5
|
+
import { SearchPage as DefaultSearchPage } from "../../theme/pages/SearchPage.js";
|
|
10
6
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
7
|
+
import { renderPublicPage } from "../../lib/render.js";
|
|
8
|
+
import { createMediaContext, toSearchResultViews } from "../../lib/view.js";
|
|
11
9
|
const PAGE_SIZE = 10;
|
|
12
10
|
export const searchRoutes = new Hono();
|
|
13
|
-
function SearchContent({ query, results, error, hasMore, page }) {
|
|
14
|
-
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
15
|
-
const searchTitle = $__i18n._({
|
|
16
|
-
id: "A1taO8",
|
|
17
|
-
message: "Search"
|
|
18
|
-
});
|
|
19
|
-
return /*#__PURE__*/ _jsxs("div", {
|
|
20
|
-
children: [
|
|
21
|
-
/*#__PURE__*/ _jsx("h1", {
|
|
22
|
-
class: "text-2xl font-semibold mb-6",
|
|
23
|
-
children: searchTitle
|
|
24
|
-
}),
|
|
25
|
-
/*#__PURE__*/ _jsx("form", {
|
|
26
|
-
method: "get",
|
|
27
|
-
action: "/search",
|
|
28
|
-
class: "mb-8",
|
|
29
|
-
children: /*#__PURE__*/ _jsxs("div", {
|
|
30
|
-
class: "flex gap-2",
|
|
31
|
-
children: [
|
|
32
|
-
/*#__PURE__*/ _jsx("input", {
|
|
33
|
-
type: "search",
|
|
34
|
-
name: "q",
|
|
35
|
-
class: "input flex-1",
|
|
36
|
-
placeholder: $__i18n._({
|
|
37
|
-
id: "MqghUt",
|
|
38
|
-
message: "Search posts..."
|
|
39
|
-
}),
|
|
40
|
-
value: query,
|
|
41
|
-
autofocus: true
|
|
42
|
-
}),
|
|
43
|
-
/*#__PURE__*/ _jsx("button", {
|
|
44
|
-
type: "submit",
|
|
45
|
-
class: "btn",
|
|
46
|
-
children: $__i18n._({
|
|
47
|
-
id: "A1taO8",
|
|
48
|
-
message: "Search"
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
]
|
|
52
|
-
})
|
|
53
|
-
}),
|
|
54
|
-
error && /*#__PURE__*/ _jsx("div", {
|
|
55
|
-
class: "alert-destructive mb-6",
|
|
56
|
-
children: /*#__PURE__*/ _jsx("h2", {
|
|
57
|
-
children: error
|
|
58
|
-
})
|
|
59
|
-
}),
|
|
60
|
-
query && !error && /*#__PURE__*/ _jsxs("div", {
|
|
61
|
-
children: [
|
|
62
|
-
/*#__PURE__*/ _jsx("p", {
|
|
63
|
-
class: "text-sm text-muted-foreground mb-4",
|
|
64
|
-
children: results.length === 0 ? $__i18n._({
|
|
65
|
-
id: "MZbQHL",
|
|
66
|
-
message: "No results found."
|
|
67
|
-
}) : results.length === 1 ? $__i18n._({
|
|
68
|
-
id: "z8ajIE",
|
|
69
|
-
message: "Found 1 result"
|
|
70
|
-
}) : $__i18n._({
|
|
71
|
-
id: "zH6KqE",
|
|
72
|
-
message: "Found {count} results"
|
|
73
|
-
})
|
|
74
|
-
}),
|
|
75
|
-
results.length > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
76
|
-
children: [
|
|
77
|
-
/*#__PURE__*/ _jsx("div", {
|
|
78
|
-
class: "flex flex-col gap-4",
|
|
79
|
-
children: results.map((result)=>/*#__PURE__*/ _jsx("article", {
|
|
80
|
-
class: "p-4 rounded-lg border hover:border-primary",
|
|
81
|
-
children: /*#__PURE__*/ _jsxs("a", {
|
|
82
|
-
href: `/p/${sqid.encode(result.post.id)}`,
|
|
83
|
-
class: "block",
|
|
84
|
-
children: [
|
|
85
|
-
/*#__PURE__*/ _jsx("h2", {
|
|
86
|
-
class: "font-medium hover:underline",
|
|
87
|
-
children: result.post.title || result.post.content?.slice(0, 60) || `Post #${result.post.id}`
|
|
88
|
-
}),
|
|
89
|
-
result.snippet && /*#__PURE__*/ _jsx("p", {
|
|
90
|
-
class: "text-sm text-muted-foreground mt-2 line-clamp-2",
|
|
91
|
-
dangerouslySetInnerHTML: {
|
|
92
|
-
__html: result.snippet
|
|
93
|
-
}
|
|
94
|
-
}),
|
|
95
|
-
/*#__PURE__*/ _jsxs("footer", {
|
|
96
|
-
class: "flex items-center gap-2 mt-2 text-xs text-muted-foreground",
|
|
97
|
-
children: [
|
|
98
|
-
/*#__PURE__*/ _jsx("span", {
|
|
99
|
-
class: "badge-outline",
|
|
100
|
-
children: result.post.type
|
|
101
|
-
}),
|
|
102
|
-
/*#__PURE__*/ _jsx("time", {
|
|
103
|
-
datetime: time.toISOString(result.post.publishedAt),
|
|
104
|
-
children: time.formatDate(result.post.publishedAt)
|
|
105
|
-
})
|
|
106
|
-
]
|
|
107
|
-
})
|
|
108
|
-
]
|
|
109
|
-
})
|
|
110
|
-
}, result.post.id))
|
|
111
|
-
}),
|
|
112
|
-
/*#__PURE__*/ _jsx(PagePagination, {
|
|
113
|
-
baseUrl: `/search?q=${encodeURIComponent(query)}`,
|
|
114
|
-
currentPage: page,
|
|
115
|
-
hasMore: hasMore
|
|
116
|
-
})
|
|
117
|
-
]
|
|
118
|
-
})
|
|
119
|
-
]
|
|
120
|
-
})
|
|
121
|
-
]
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
11
|
searchRoutes.get("/", async (c)=>{
|
|
125
12
|
const query = c.req.query("q") || "";
|
|
126
13
|
const pageParam = c.req.query("page");
|
|
@@ -128,7 +15,7 @@ searchRoutes.get("/", async (c)=>{
|
|
|
128
15
|
const navData = await getNavigationData(c);
|
|
129
16
|
// Only search if there's a query
|
|
130
17
|
let results = [];
|
|
131
|
-
let error
|
|
18
|
+
let error;
|
|
132
19
|
let hasMore = false;
|
|
133
20
|
if (query.trim()) {
|
|
134
21
|
try {
|
|
@@ -151,18 +38,21 @@ searchRoutes.get("/", async (c)=>{
|
|
|
151
38
|
error = "Search failed. Please try again.";
|
|
152
39
|
}
|
|
153
40
|
}
|
|
154
|
-
|
|
41
|
+
// Transform to View Models
|
|
42
|
+
const mediaCtx = createMediaContext(c);
|
|
43
|
+
const resultViews = toSearchResultViews(results, mediaCtx);
|
|
44
|
+
const components = c.var.config.theme?.components;
|
|
45
|
+
const Page = components?.SearchPage ?? DefaultSearchPage;
|
|
46
|
+
return renderPublicPage(c, {
|
|
155
47
|
title: query ? `Search: ${query} - ${navData.siteName}` : `Search - ${navData.siteName}`,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
page: page
|
|
165
|
-
})
|
|
48
|
+
navData,
|
|
49
|
+
content: /*#__PURE__*/ _jsx(Page, {
|
|
50
|
+
query: query,
|
|
51
|
+
results: resultViews,
|
|
52
|
+
error: error,
|
|
53
|
+
hasMore: hasMore,
|
|
54
|
+
page: page,
|
|
55
|
+
theme: components
|
|
166
56
|
})
|
|
167
|
-
})
|
|
57
|
+
});
|
|
168
58
|
});
|
|
@@ -17,8 +17,8 @@ export const MediaGallery = ({ attachments })=>{
|
|
|
17
17
|
target: "_blank",
|
|
18
18
|
rel: "noopener noreferrer",
|
|
19
19
|
children: /*#__PURE__*/ _jsx("img", {
|
|
20
|
-
src: img.
|
|
21
|
-
alt: img.
|
|
20
|
+
src: img.thumbnailUrl,
|
|
21
|
+
alt: img.altText || "",
|
|
22
22
|
width: img.width ?? undefined,
|
|
23
23
|
height: img.height ?? undefined,
|
|
24
24
|
class: "rounded-lg max-w-full h-auto",
|
|
@@ -36,8 +36,8 @@ export const MediaGallery = ({ attachments })=>{
|
|
|
36
36
|
rel: "noopener noreferrer",
|
|
37
37
|
class: "aspect-square",
|
|
38
38
|
children: /*#__PURE__*/ _jsx("img", {
|
|
39
|
-
src: img.
|
|
40
|
-
alt: img.
|
|
39
|
+
src: img.thumbnailUrl,
|
|
40
|
+
alt: img.altText || "",
|
|
41
41
|
class: "w-full h-full object-cover",
|
|
42
42
|
loading: "lazy"
|
|
43
43
|
})
|
|
@@ -56,8 +56,8 @@ export const MediaGallery = ({ attachments })=>{
|
|
|
56
56
|
rel: "noopener noreferrer",
|
|
57
57
|
class: "row-span-2",
|
|
58
58
|
children: /*#__PURE__*/ _jsx("img", {
|
|
59
|
-
src: first.
|
|
60
|
-
alt: first.
|
|
59
|
+
src: first.thumbnailUrl,
|
|
60
|
+
alt: first.altText || "",
|
|
61
61
|
class: "w-full h-full object-cover",
|
|
62
62
|
loading: "lazy"
|
|
63
63
|
})
|
|
@@ -68,8 +68,8 @@ export const MediaGallery = ({ attachments })=>{
|
|
|
68
68
|
rel: "noopener noreferrer",
|
|
69
69
|
class: "aspect-square",
|
|
70
70
|
children: /*#__PURE__*/ _jsx("img", {
|
|
71
|
-
src: img.
|
|
72
|
-
alt: img.
|
|
71
|
+
src: img.thumbnailUrl,
|
|
72
|
+
alt: img.altText || "",
|
|
73
73
|
class: "w-full h-full object-cover",
|
|
74
74
|
loading: "lazy"
|
|
75
75
|
})
|
|
@@ -89,8 +89,8 @@ export const MediaGallery = ({ attachments })=>{
|
|
|
89
89
|
class: "relative aspect-square",
|
|
90
90
|
children: [
|
|
91
91
|
/*#__PURE__*/ _jsx("img", {
|
|
92
|
-
src: img.
|
|
93
|
-
alt: img.
|
|
92
|
+
src: img.thumbnailUrl,
|
|
93
|
+
alt: img.altText || "",
|
|
94
94
|
class: "w-full h-full object-cover",
|
|
95
95
|
loading: "lazy"
|
|
96
96
|
}),
|
|
@@ -16,6 +16,7 @@ export const PageForm = ({ page, action, cancelUrl = "/dash/pages" })=>{
|
|
|
16
16
|
return /*#__PURE__*/ _jsxs("form", {
|
|
17
17
|
"data-signals": signals,
|
|
18
18
|
"data-on:submit__prevent": `@post('${action}')`,
|
|
19
|
+
"data-indicator": "_loading",
|
|
19
20
|
class: "flex flex-col gap-4",
|
|
20
21
|
children: [
|
|
21
22
|
/*#__PURE__*/ _jsx("div", {
|
|
@@ -149,16 +150,29 @@ export const PageForm = ({ page, action, cancelUrl = "/dash/pages" })=>{
|
|
|
149
150
|
/*#__PURE__*/ _jsxs("div", {
|
|
150
151
|
class: "flex gap-2",
|
|
151
152
|
children: [
|
|
152
|
-
/*#__PURE__*/
|
|
153
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
153
154
|
type: "submit",
|
|
154
155
|
class: "btn",
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
"data-attr-disabled": "$_loading",
|
|
157
|
+
children: [
|
|
158
|
+
/*#__PURE__*/ _jsx("span", {
|
|
159
|
+
"data-show": "!$_loading",
|
|
160
|
+
children: isEdit ? $__i18n._({
|
|
161
|
+
id: "oYPBa0",
|
|
162
|
+
message: "Update Page"
|
|
163
|
+
}) : $__i18n._({
|
|
164
|
+
id: "Y+7JGK",
|
|
165
|
+
message: "Create Page"
|
|
166
|
+
})
|
|
167
|
+
}),
|
|
168
|
+
/*#__PURE__*/ _jsx("span", {
|
|
169
|
+
"data-show": "$_loading",
|
|
170
|
+
children: $__i18n._({
|
|
171
|
+
id: "k1ifdL",
|
|
172
|
+
message: "Processing..."
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
]
|
|
162
176
|
}),
|
|
163
177
|
/*#__PURE__*/ _jsx("a", {
|
|
164
178
|
href: cancelUrl,
|
|
@@ -21,6 +21,7 @@ export const PostForm = ({ post, action, mediaAttachments, r2PublicUrl, imageTra
|
|
|
21
21
|
return /*#__PURE__*/ _jsxs("form", {
|
|
22
22
|
"data-signals": signals,
|
|
23
23
|
"data-on:submit__prevent": `@post('${action}')`,
|
|
24
|
+
"data-indicator": "_loading",
|
|
24
25
|
class: "flex flex-col gap-4",
|
|
25
26
|
children: [
|
|
26
27
|
/*#__PURE__*/ _jsx("div", {
|
|
@@ -330,16 +331,29 @@ export const PostForm = ({ post, action, mediaAttachments, r2PublicUrl, imageTra
|
|
|
330
331
|
/*#__PURE__*/ _jsxs("div", {
|
|
331
332
|
class: "flex gap-2",
|
|
332
333
|
children: [
|
|
333
|
-
/*#__PURE__*/
|
|
334
|
+
/*#__PURE__*/ _jsxs("button", {
|
|
334
335
|
type: "submit",
|
|
335
336
|
class: "btn",
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
337
|
+
"data-attr-disabled": "$_loading",
|
|
338
|
+
children: [
|
|
339
|
+
/*#__PURE__*/ _jsx("span", {
|
|
340
|
+
"data-show": "!$_loading",
|
|
341
|
+
children: isEdit ? $__i18n._({
|
|
342
|
+
id: "EkH9pt",
|
|
343
|
+
message: "Update"
|
|
344
|
+
}) : $__i18n._({
|
|
345
|
+
id: "EEYbdt",
|
|
346
|
+
message: "Publish"
|
|
347
|
+
})
|
|
348
|
+
}),
|
|
349
|
+
/*#__PURE__*/ _jsx("span", {
|
|
350
|
+
"data-show": "$_loading",
|
|
351
|
+
children: $__i18n._({
|
|
352
|
+
id: "k1ifdL",
|
|
353
|
+
message: "Processing..."
|
|
354
|
+
})
|
|
355
|
+
})
|
|
356
|
+
]
|
|
343
357
|
}),
|
|
344
358
|
/*#__PURE__*/ _jsx("a", {
|
|
345
359
|
href: "/dash/posts",
|
|
@@ -12,4 +12,4 @@ export { ThreadView } from "./ThreadView.js";
|
|
|
12
12
|
export { TypeBadge } from "./TypeBadge.js";
|
|
13
13
|
export { VisibilityBadge } from "./VisibilityBadge.js";
|
|
14
14
|
// Timeline components
|
|
15
|
-
export { NoteCard, ArticleCard, LinkCard, QuoteCard, ImageCard, ThreadPreview, TimelineItem, TimelineFeed } from "./timeline/index.js";
|
|
15
|
+
export { NoteCard, ArticleCard, LinkCard, QuoteCard, ImageCard, ThreadPreview, TimelineItem, TimelineItemFromPost, TimelineFeed } from "./timeline/index.js";
|
|
@@ -3,42 +3,38 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Prominent title + excerpt for type="article" 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 ArticleCard = ({ post, compact })=>{
|
|
9
|
-
const permalink = `/p/${sqid.encode(post.id)}`;
|
|
10
|
-
const excerpt = post.content ? post.content.length > 160 ? post.content.slice(0, 160) + "..." : post.content : null;
|
|
11
7
|
return /*#__PURE__*/ _jsxs("article", {
|
|
12
8
|
class: `h-entry timeline-card${compact ? " timeline-card-compact" : ""}`,
|
|
13
9
|
children: [
|
|
14
10
|
post.title && /*#__PURE__*/ _jsx("h2", {
|
|
15
11
|
class: `p-name font-semibold ${compact ? "text-sm" : "text-lg"} mb-1`,
|
|
16
12
|
children: /*#__PURE__*/ _jsx("a", {
|
|
17
|
-
href: permalink,
|
|
13
|
+
href: post.permalink,
|
|
18
14
|
class: "u-url hover:underline",
|
|
19
15
|
children: post.title
|
|
20
16
|
})
|
|
21
17
|
}),
|
|
22
|
-
!compact && excerpt && /*#__PURE__*/ _jsx("p", {
|
|
18
|
+
!compact && post.excerpt && /*#__PURE__*/ _jsx("p", {
|
|
23
19
|
class: "e-content text-sm text-muted-foreground line-clamp-3",
|
|
24
|
-
children: excerpt
|
|
20
|
+
children: post.excerpt
|
|
25
21
|
}),
|
|
26
22
|
/*#__PURE__*/ _jsxs("footer", {
|
|
27
23
|
class: "mt-2 text-xs text-muted-foreground",
|
|
28
24
|
children: [
|
|
29
25
|
/*#__PURE__*/ _jsx("a", {
|
|
30
|
-
href: permalink,
|
|
26
|
+
href: post.permalink,
|
|
31
27
|
class: "u-url hover:underline",
|
|
32
28
|
children: /*#__PURE__*/ _jsx("time", {
|
|
33
29
|
class: "dt-published",
|
|
34
|
-
datetime:
|
|
35
|
-
children:
|
|
30
|
+
datetime: post.publishedAt,
|
|
31
|
+
children: post.publishedAtFormatted
|
|
36
32
|
})
|
|
37
33
|
}),
|
|
38
34
|
!compact && /*#__PURE__*/ _jsx("span", {
|
|
39
35
|
class: "ml-2",
|
|
40
36
|
children: /*#__PURE__*/ _jsx("a", {
|
|
41
|
-
href: permalink,
|
|
37
|
+
href: post.permalink,
|
|
42
38
|
class: "hover:underline",
|
|
43
39
|
children: "Read more →"
|
|
44
40
|
})
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* Image-first layout for type="image" posts.
|
|
5
5
|
*/ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
6
6
|
import { MediaGallery } from "../MediaGallery.js";
|
|
7
|
-
import * as sqid from "../../../lib/sqid.js";
|
|
8
|
-
import * as time from "../../../lib/time.js";
|
|
9
7
|
export const ImageCard = ({ post, compact })=>{
|
|
10
|
-
const permalink = `/p/${sqid.encode(post.id)}`;
|
|
11
8
|
if (compact) {
|
|
12
9
|
return /*#__PURE__*/ _jsxs("article", {
|
|
13
10
|
class: "h-entry timeline-card timeline-card-compact",
|
|
@@ -15,7 +12,7 @@ export const ImageCard = ({ post, compact })=>{
|
|
|
15
12
|
post.title && /*#__PURE__*/ _jsx("h2", {
|
|
16
13
|
class: "p-name text-sm font-medium mb-1",
|
|
17
14
|
children: /*#__PURE__*/ _jsx("a", {
|
|
18
|
-
href: permalink,
|
|
15
|
+
href: post.permalink,
|
|
19
16
|
class: "u-url hover:underline",
|
|
20
17
|
children: post.title
|
|
21
18
|
})
|
|
@@ -29,12 +26,12 @@ export const ImageCard = ({ post, compact })=>{
|
|
|
29
26
|
/*#__PURE__*/ _jsx("footer", {
|
|
30
27
|
class: "mt-1 text-xs text-muted-foreground",
|
|
31
28
|
children: /*#__PURE__*/ _jsx("a", {
|
|
32
|
-
href: permalink,
|
|
29
|
+
href: post.permalink,
|
|
33
30
|
class: "u-url hover:underline",
|
|
34
31
|
children: /*#__PURE__*/ _jsx("time", {
|
|
35
32
|
class: "dt-published",
|
|
36
|
-
datetime:
|
|
37
|
-
children:
|
|
33
|
+
datetime: post.publishedAt,
|
|
34
|
+
children: post.publishedAtFormatted
|
|
38
35
|
})
|
|
39
36
|
})
|
|
40
37
|
})
|
|
@@ -44,10 +41,10 @@ export const ImageCard = ({ post, compact })=>{
|
|
|
44
41
|
return /*#__PURE__*/ _jsxs("article", {
|
|
45
42
|
class: "h-entry timeline-card timeline-card-image",
|
|
46
43
|
children: [
|
|
47
|
-
post.
|
|
44
|
+
post.media.length > 0 && /*#__PURE__*/ _jsx("div", {
|
|
48
45
|
class: "timeline-card-image-gallery",
|
|
49
46
|
children: /*#__PURE__*/ _jsx(MediaGallery, {
|
|
50
|
-
attachments: post.
|
|
47
|
+
attachments: post.media
|
|
51
48
|
})
|
|
52
49
|
}),
|
|
53
50
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -56,7 +53,7 @@ export const ImageCard = ({ post, compact })=>{
|
|
|
56
53
|
post.title && /*#__PURE__*/ _jsx("h2", {
|
|
57
54
|
class: "p-name font-medium mb-1",
|
|
58
55
|
children: /*#__PURE__*/ _jsx("a", {
|
|
59
|
-
href: permalink,
|
|
56
|
+
href: post.permalink,
|
|
60
57
|
class: "u-url hover:underline",
|
|
61
58
|
children: post.title
|
|
62
59
|
})
|
|
@@ -70,12 +67,12 @@ export const ImageCard = ({ post, compact })=>{
|
|
|
70
67
|
/*#__PURE__*/ _jsx("footer", {
|
|
71
68
|
class: "mt-2 text-xs text-muted-foreground",
|
|
72
69
|
children: /*#__PURE__*/ _jsx("a", {
|
|
73
|
-
href: permalink,
|
|
70
|
+
href: post.permalink,
|
|
74
71
|
class: "u-url hover:underline",
|
|
75
72
|
children: /*#__PURE__*/ _jsx("time", {
|
|
76
73
|
class: "dt-published",
|
|
77
|
-
datetime:
|
|
78
|
-
children:
|
|
74
|
+
datetime: post.publishedAt,
|
|
75
|
+
children: post.publishedAtFormatted
|
|
79
76
|
})
|
|
80
77
|
})
|
|
81
78
|
})
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* External link emphasis for type="link" 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 LinkCard = ({ post, compact })=>{
|
|
9
|
-
const permalink = `/p/${sqid.encode(post.id)}`;
|
|
10
7
|
return /*#__PURE__*/ _jsxs("article", {
|
|
11
8
|
class: `h-entry timeline-card timeline-card-link${compact ? " timeline-card-compact" : ""}`,
|
|
12
9
|
children: [
|
|
@@ -32,7 +29,7 @@ export const LinkCard = ({ post, compact })=>{
|
|
|
32
29
|
post.title && /*#__PURE__*/ _jsx("h2", {
|
|
33
30
|
class: `p-name font-semibold ${compact ? "text-sm" : "text-base"} mb-1`,
|
|
34
31
|
children: /*#__PURE__*/ _jsx("a", {
|
|
35
|
-
href: post.sourceUrl || permalink,
|
|
32
|
+
href: post.sourceUrl || post.permalink,
|
|
36
33
|
class: "u-url hover:underline",
|
|
37
34
|
target: post.sourceUrl ? "_blank" : undefined,
|
|
38
35
|
rel: post.sourceUrl ? "noopener noreferrer" : undefined,
|
|
@@ -48,12 +45,12 @@ export const LinkCard = ({ post, compact })=>{
|
|
|
48
45
|
/*#__PURE__*/ _jsx("footer", {
|
|
49
46
|
class: "mt-2 text-xs text-muted-foreground",
|
|
50
47
|
children: /*#__PURE__*/ _jsx("a", {
|
|
51
|
-
href: permalink,
|
|
48
|
+
href: post.permalink,
|
|
52
49
|
class: "hover:underline",
|
|
53
50
|
children: /*#__PURE__*/ _jsx("time", {
|
|
54
51
|
class: "dt-published",
|
|
55
|
-
datetime:
|
|
56
|
-
children:
|
|
52
|
+
datetime: post.publishedAt,
|
|
53
|
+
children: post.publishedAtFormatted
|
|
57
54
|
})
|
|
58
55
|
})
|
|
59
56
|
})
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* Text-first, minimal card for type="note" posts.
|
|
5
5
|
*/ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
6
6
|
import { MediaGallery } from "../MediaGallery.js";
|
|
7
|
-
import * as sqid from "../../../lib/sqid.js";
|
|
8
|
-
import * as time from "../../../lib/time.js";
|
|
9
7
|
export const NoteCard = ({ post, compact })=>{
|
|
10
|
-
const permalink = `/p/${sqid.encode(post.id)}`;
|
|
11
8
|
return /*#__PURE__*/ _jsxs("article", {
|
|
12
9
|
class: `h-entry timeline-card${compact ? " timeline-card-compact" : ""}`,
|
|
13
10
|
children: [
|
|
@@ -17,18 +14,18 @@ export const NoteCard = ({ post, compact })=>{
|
|
|
17
14
|
__html: post.contentHtml
|
|
18
15
|
}
|
|
19
16
|
}),
|
|
20
|
-
!compact && post.
|
|
21
|
-
attachments: post.
|
|
17
|
+
!compact && post.media.length > 0 && /*#__PURE__*/ _jsx(MediaGallery, {
|
|
18
|
+
attachments: post.media
|
|
22
19
|
}),
|
|
23
20
|
/*#__PURE__*/ _jsx("footer", {
|
|
24
21
|
class: "mt-2 text-xs text-muted-foreground",
|
|
25
22
|
children: /*#__PURE__*/ _jsx("a", {
|
|
26
|
-
href: permalink,
|
|
23
|
+
href: post.permalink,
|
|
27
24
|
class: "u-url hover:underline",
|
|
28
25
|
children: /*#__PURE__*/ _jsx("time", {
|
|
29
26
|
class: "dt-published",
|
|
30
|
-
datetime:
|
|
31
|
-
children:
|
|
27
|
+
datetime: post.publishedAt,
|
|
28
|
+
children: post.publishedAtFormatted
|
|
32
29
|
})
|
|
33
30
|
})
|
|
34
31
|
})
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Blockquote + attribution 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
8
|
class: `h-entry timeline-card timeline-card-quote${compact ? " timeline-card-compact" : ""}`,
|
|
12
9
|
children: [
|
|
@@ -37,12 +34,12 @@ export const QuoteCard = ({ post, compact })=>{
|
|
|
37
34
|
/*#__PURE__*/ _jsx("footer", {
|
|
38
35
|
class: "mt-2 text-xs text-muted-foreground",
|
|
39
36
|
children: /*#__PURE__*/ _jsx("a", {
|
|
40
|
-
href: permalink,
|
|
37
|
+
href: post.permalink,
|
|
41
38
|
class: "u-url hover:underline",
|
|
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
|
})
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
*/ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
6
6
|
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
7
7
|
import { TimelineItem } from "./TimelineItem.js";
|
|
8
|
-
import
|
|
9
|
-
export const ThreadPreview = ({ rootPost, previewReplies, totalReplyCount })=>{
|
|
8
|
+
import { TimelineItemFromPost } from "./TimelineItem.js";
|
|
9
|
+
export const ThreadPreview = ({ rootPost, previewReplies, totalReplyCount, theme })=>{
|
|
10
10
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
11
|
-
const permalink = `/p/${sqid.encode(rootPost.id)}`;
|
|
12
11
|
const remainingCount = totalReplyCount - previewReplies.length;
|
|
13
12
|
return /*#__PURE__*/ _jsxs("div", {
|
|
14
13
|
class: "timeline-thread",
|
|
@@ -16,24 +15,24 @@ export const ThreadPreview = ({ rootPost, previewReplies, totalReplyCount })=>{
|
|
|
16
15
|
/*#__PURE__*/ _jsx(TimelineItem, {
|
|
17
16
|
item: {
|
|
18
17
|
post: rootPost
|
|
19
|
-
}
|
|
18
|
+
},
|
|
19
|
+
theme: theme
|
|
20
20
|
}),
|
|
21
21
|
previewReplies.length > 0 && /*#__PURE__*/ _jsxs("div", {
|
|
22
22
|
class: "timeline-thread-replies",
|
|
23
23
|
children: [
|
|
24
24
|
previewReplies.map((reply)=>/*#__PURE__*/ _jsx("div", {
|
|
25
25
|
class: "timeline-thread-reply",
|
|
26
|
-
children: /*#__PURE__*/ _jsx(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
compact: true
|
|
26
|
+
children: /*#__PURE__*/ _jsx(TimelineItemFromPost, {
|
|
27
|
+
post: reply,
|
|
28
|
+
compact: true,
|
|
29
|
+
theme: theme
|
|
31
30
|
})
|
|
32
31
|
}, reply.id)),
|
|
33
32
|
remainingCount > 0 && /*#__PURE__*/ _jsx("div", {
|
|
34
33
|
class: "timeline-thread-reply",
|
|
35
34
|
children: /*#__PURE__*/ _jsx("a", {
|
|
36
|
-
href: permalink,
|
|
35
|
+
href: rootPost.permalink,
|
|
37
36
|
class: "text-sm text-muted-foreground hover:text-foreground hover:underline",
|
|
38
37
|
children: $__i18n._({
|
|
39
38
|
id: "smzF8S",
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
*/ import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
6
6
|
import { useLingui as $_useLingui } from "@jant/core/i18n";
|
|
7
7
|
import { TimelineItem } from "./TimelineItem.js";
|
|
8
|
-
import { ThreadPreview } from "./ThreadPreview.js";
|
|
9
|
-
export const TimelineFeed = ({ items, hasMore, nextCursor })=>{
|
|
8
|
+
import { ThreadPreview as DefaultThreadPreview } from "./ThreadPreview.js";
|
|
9
|
+
export const TimelineFeed = ({ items, hasMore, nextCursor, theme })=>{
|
|
10
10
|
const { i18n: $__i18n, _: $__ } = $_useLingui();
|
|
11
|
+
const ResolvedThreadPreview = theme?.ThreadPreview ?? DefaultThreadPreview;
|
|
11
12
|
return /*#__PURE__*/ _jsxs("div", {
|
|
12
13
|
children: [
|
|
13
14
|
/*#__PURE__*/ _jsx("div", {
|
|
@@ -15,14 +16,16 @@ export const TimelineFeed = ({ items, hasMore, nextCursor })=>{
|
|
|
15
16
|
class: "flex flex-col gap-4",
|
|
16
17
|
children: items.map((item)=>{
|
|
17
18
|
if (item.threadPreview) {
|
|
18
|
-
return /*#__PURE__*/ _jsx(
|
|
19
|
+
return /*#__PURE__*/ _jsx(ResolvedThreadPreview, {
|
|
19
20
|
rootPost: item.post,
|
|
20
21
|
previewReplies: item.threadPreview.replies,
|
|
21
|
-
totalReplyCount: item.threadPreview.totalReplyCount
|
|
22
|
+
totalReplyCount: item.threadPreview.totalReplyCount,
|
|
23
|
+
theme: theme
|
|
22
24
|
}, item.post.id);
|
|
23
25
|
}
|
|
24
26
|
return /*#__PURE__*/ _jsx(TimelineItem, {
|
|
25
|
-
item: item
|
|
27
|
+
item: item,
|
|
28
|
+
theme: theme
|
|
26
29
|
}, item.post.id);
|
|
27
30
|
})
|
|
28
31
|
}),
|