@jant/core 0.3.22 → 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 +22 -3
- package/dist/index.js +3 -4
- package/dist/lib/render.js +1 -1
- package/dist/lib/view.js +1 -1
- package/dist/routes/api/timeline.js +3 -3
- package/dist/routes/pages/archive.js +1 -1
- package/dist/routes/pages/collection.js +1 -1
- package/dist/routes/pages/home.js +1 -1
- package/dist/routes/pages/page.js +1 -1
- package/dist/routes/pages/post.js +1 -1
- package/dist/routes/pages/search.js +1 -1
- package/dist/theme/components/index.js +0 -2
- package/dist/theme/index.js +10 -16
- 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/{theme → themes/minimal}/pages/ArchivePage.js +7 -8
- package/dist/{theme → themes/minimal}/pages/CollectionPage.js +7 -5
- package/dist/{theme → themes/minimal}/pages/HomePage.js +2 -3
- package/dist/{theme → themes/minimal}/pages/PostPage.js +5 -6
- package/dist/{theme → themes/minimal}/pages/SearchPage.js +11 -10
- package/dist/{theme → themes/minimal}/pages/SinglePage.js +3 -4
- package/dist/themes/minimal/timeline/ArticleCard.js +36 -0
- package/dist/themes/minimal/timeline/ImageCard.js +67 -0
- package/dist/{theme/components → themes/minimal}/timeline/LinkCard.js +14 -26
- package/dist/{theme/components → themes/minimal}/timeline/NoteCard.js +7 -7
- package/dist/{theme/components → themes/minimal}/timeline/QuoteCard.js +6 -6
- package/dist/{theme/components → themes/minimal}/timeline/ThreadPreview.js +13 -18
- package/dist/themes/minimal/timeline/TimelineFeed.js +48 -0
- package/dist/{theme/components → themes/minimal}/timeline/TimelineItem.js +1 -2
- package/package.json +1 -1
- package/src/app.tsx +26 -3
- package/src/i18n/locales/en.po +47 -47
- package/src/i18n/locales/zh-Hans.po +47 -47
- package/src/i18n/locales/zh-Hant.po +47 -47
- package/src/index.ts +4 -5
- package/src/lib/__tests__/view.test.ts +18 -16
- package/src/lib/render.tsx +1 -1
- package/src/lib/view.ts +1 -1
- package/src/routes/api/timeline.tsx +3 -3
- package/src/routes/pages/archive.tsx +1 -1
- package/src/routes/pages/collection.tsx +1 -1
- package/src/routes/pages/home.tsx +1 -1
- package/src/routes/pages/page.tsx +1 -1
- package/src/routes/pages/post.tsx +1 -1
- package/src/routes/pages/search.tsx +1 -1
- package/src/styles/components.css +0 -54
- package/src/theme/components/index.ts +0 -13
- package/src/theme/index.ts +10 -16
- package/src/theme/layouts/index.ts +0 -1
- package/src/themes/minimal/MinimalSiteLayout.tsx +100 -0
- package/src/themes/minimal/index.ts +83 -0
- package/src/{theme → themes/minimal}/pages/ArchivePage.tsx +8 -11
- package/src/{theme → themes/minimal}/pages/CollectionPage.tsx +6 -6
- package/src/{theme → themes/minimal}/pages/HomePage.tsx +3 -4
- package/src/{theme → themes/minimal}/pages/PostPage.tsx +6 -7
- package/src/{theme → themes/minimal}/pages/SearchPage.tsx +11 -17
- package/src/{theme → themes/minimal}/pages/SinglePage.tsx +4 -5
- 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/{theme/components → themes/minimal}/timeline/NoteCard.tsx +10 -9
- package/src/{theme/components → themes/minimal}/timeline/QuoteCard.tsx +9 -8
- package/src/{theme/components → themes/minimal}/timeline/ThreadPreview.tsx +14 -16
- package/src/{theme/components → themes/minimal}/timeline/TimelineFeed.tsx +14 -13
- package/src/{theme/components → themes/minimal}/timeline/TimelineItem.tsx +1 -4
- package/dist/theme/components/timeline/ArticleCard.js +0 -46
- package/dist/theme/components/timeline/ImageCard.js +0 -83
- package/dist/theme/components/timeline/TimelineFeed.js +0 -46
- package/dist/theme/components/timeline/index.js +0 -8
- package/dist/theme/layouts/SiteLayout.js +0 -131
- package/dist/theme/pages/index.js +0 -11
- package/src/theme/components/timeline/ArticleCard.tsx +0 -45
- package/src/theme/components/timeline/ImageCard.tsx +0 -70
- package/src/theme/components/timeline/LinkCard.tsx +0 -59
- package/src/theme/components/timeline/index.ts +0 -8
- package/src/theme/layouts/SiteLayout.tsx +0 -132
- package/src/theme/pages/index.ts +0 -13
|
@@ -49,7 +49,7 @@ msgid "Add Media"
|
|
|
49
49
|
msgstr "添加媒體"
|
|
50
50
|
|
|
51
51
|
#. @context: Archive filter - all types
|
|
52
|
-
#: src/
|
|
52
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:90
|
|
53
53
|
msgid "All"
|
|
54
54
|
msgstr "所有"
|
|
55
55
|
|
|
@@ -59,7 +59,7 @@ msgid "Appearance"
|
|
|
59
59
|
msgstr "外觀"
|
|
60
60
|
|
|
61
61
|
#. @context: Archive page title
|
|
62
|
-
#: src/
|
|
62
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:76
|
|
63
63
|
msgid "Archive"
|
|
64
64
|
msgstr "檔案館"
|
|
65
65
|
|
|
@@ -73,12 +73,12 @@ msgstr ""
|
|
|
73
73
|
#. @context: Post type option
|
|
74
74
|
#: src/theme/components/PostForm.tsx:74
|
|
75
75
|
#: src/theme/components/TypeBadge.tsx:20
|
|
76
|
-
#: src/
|
|
76
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:17
|
|
77
77
|
msgid "Article"
|
|
78
78
|
msgstr "文章"
|
|
79
79
|
|
|
80
80
|
#. @context: Post type label plural - articles
|
|
81
|
-
#: src/
|
|
81
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:42
|
|
82
82
|
msgid "Articles"
|
|
83
83
|
msgstr "文章"
|
|
84
84
|
|
|
@@ -137,7 +137,7 @@ msgid "Color theme"
|
|
|
137
137
|
msgstr "顏色主題"
|
|
138
138
|
|
|
139
139
|
#. @context: Setup form submit button
|
|
140
|
-
#: src/app.tsx:
|
|
140
|
+
#: src/app.tsx:277
|
|
141
141
|
msgid "Complete Setup"
|
|
142
142
|
msgstr "完成設置"
|
|
143
143
|
|
|
@@ -147,7 +147,7 @@ msgid "Confirm New Password"
|
|
|
147
147
|
msgstr "確認新密碼"
|
|
148
148
|
|
|
149
149
|
#. @context: Password reset form field
|
|
150
|
-
#: src/app.tsx:
|
|
150
|
+
#: src/app.tsx:538
|
|
151
151
|
msgid "Confirm Password"
|
|
152
152
|
msgstr "確認密碼"
|
|
153
153
|
|
|
@@ -186,7 +186,7 @@ msgid "Create Redirect"
|
|
|
186
186
|
msgstr "建立重定向"
|
|
187
187
|
|
|
188
188
|
#. @context: Setup page description
|
|
189
|
-
#: src/app.tsx:
|
|
189
|
+
#: src/app.tsx:217
|
|
190
190
|
msgid "Create your admin account."
|
|
191
191
|
msgstr "建立您的管理員帳戶。"
|
|
192
192
|
|
|
@@ -252,7 +252,7 @@ msgid "Deleting this media will remove it permanently from storage."
|
|
|
252
252
|
msgstr "刪除此媒體將永久從存儲中移除它。"
|
|
253
253
|
|
|
254
254
|
#. @context: Hint shown on signin page when demo credentials are pre-filled
|
|
255
|
-
#: src/app.tsx:
|
|
255
|
+
#: src/app.tsx:376
|
|
256
256
|
msgid "Demo account pre-filled. Just click Sign In."
|
|
257
257
|
msgstr "示範帳戶已預填。只需點擊登入。"
|
|
258
258
|
|
|
@@ -333,13 +333,13 @@ msgstr "編輯文章"
|
|
|
333
333
|
|
|
334
334
|
#. @context: Setup/signin form field - email
|
|
335
335
|
#. @context: Setup/signin form field - email
|
|
336
|
-
#: src/app.tsx:
|
|
337
|
-
#: src/app.tsx:
|
|
336
|
+
#: src/app.tsx:247
|
|
337
|
+
#: src/app.tsx:391
|
|
338
338
|
msgid "Email"
|
|
339
339
|
msgstr "電子郵件"
|
|
340
340
|
|
|
341
341
|
#. @context: Password reset page description
|
|
342
|
-
#: src/app.tsx:
|
|
342
|
+
#: src/app.tsx:507
|
|
343
343
|
msgid "Enter your new password."
|
|
344
344
|
msgstr "請輸入您的新密碼。"
|
|
345
345
|
|
|
@@ -351,12 +351,12 @@ msgid "Featured"
|
|
|
351
351
|
msgstr "精選"
|
|
352
352
|
|
|
353
353
|
#. @context: Search results count - multiple
|
|
354
|
-
#: src/
|
|
354
|
+
#: src/themes/minimal/pages/SearchPage.tsx:73
|
|
355
355
|
msgid "Found {count} results"
|
|
356
356
|
msgstr "找到 {count} 個結果"
|
|
357
357
|
|
|
358
358
|
#. @context: Search results count - single
|
|
359
|
-
#: src/
|
|
359
|
+
#: src/themes/minimal/pages/SearchPage.tsx:69
|
|
360
360
|
msgid "Found 1 result"
|
|
361
361
|
msgstr "找到 1 個結果"
|
|
362
362
|
|
|
@@ -377,12 +377,12 @@ msgstr "一般設定"
|
|
|
377
377
|
#. @context: Post type option
|
|
378
378
|
#: src/theme/components/PostForm.tsx:83
|
|
379
379
|
#: src/theme/components/TypeBadge.tsx:29
|
|
380
|
-
#: src/
|
|
380
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:26
|
|
381
381
|
msgid "Image"
|
|
382
382
|
msgstr "圖片"
|
|
383
383
|
|
|
384
384
|
#. @context: Post type label plural - images
|
|
385
|
-
#: src/
|
|
385
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:54
|
|
386
386
|
msgid "Images"
|
|
387
387
|
msgstr "圖片"
|
|
388
388
|
|
|
@@ -392,7 +392,7 @@ msgid "Images are automatically optimized: resized to max 1920px, converted to W
|
|
|
392
392
|
msgstr "圖片會自動優化:調整大小至最大 1920 像素,轉換為 WebP 格式,並去除元數據。"
|
|
393
393
|
|
|
394
394
|
#. @context: Password reset error heading
|
|
395
|
-
#: src/app.tsx:
|
|
395
|
+
#: src/app.tsx:582
|
|
396
396
|
msgid "Invalid or Expired Link"
|
|
397
397
|
msgstr "無效或已過期的連結"
|
|
398
398
|
|
|
@@ -411,19 +411,19 @@ msgstr "語言"
|
|
|
411
411
|
#. @context: Post type option
|
|
412
412
|
#: src/theme/components/PostForm.tsx:77
|
|
413
413
|
#: src/theme/components/TypeBadge.tsx:24
|
|
414
|
-
#: src/
|
|
414
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:21
|
|
415
415
|
msgid "Link"
|
|
416
416
|
msgstr "連結"
|
|
417
417
|
|
|
418
418
|
#. @context: Post type label plural - links
|
|
419
|
-
#: src/
|
|
419
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:46
|
|
420
420
|
msgid "Links"
|
|
421
421
|
msgstr "連結"
|
|
422
422
|
|
|
423
423
|
#. @context: Button to load more posts in timeline
|
|
424
424
|
#. @context: Pagination button - load more items
|
|
425
425
|
#: src/theme/components/Pagination.tsx:103
|
|
426
|
-
#: src/
|
|
426
|
+
#: src/themes/minimal/timeline/TimelineFeed.tsx:48
|
|
427
427
|
msgid "Load more"
|
|
428
428
|
msgstr "載入更多"
|
|
429
429
|
|
|
@@ -500,7 +500,7 @@ msgstr "新頁面"
|
|
|
500
500
|
|
|
501
501
|
#. @context: Password form field
|
|
502
502
|
#. @context: Password reset form field
|
|
503
|
-
#: src/app.tsx:
|
|
503
|
+
#: src/app.tsx:522
|
|
504
504
|
#: src/routes/dash/settings.tsx:442
|
|
505
505
|
msgid "New Password"
|
|
506
506
|
msgstr "新密碼"
|
|
@@ -551,21 +551,21 @@ msgid "No pages yet."
|
|
|
551
551
|
msgstr "尚未有頁面。"
|
|
552
552
|
|
|
553
553
|
#. @context: Archive empty state
|
|
554
|
-
#: src/
|
|
554
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:110
|
|
555
555
|
msgid "No posts found."
|
|
556
556
|
msgstr "未找到任何帖子。"
|
|
557
557
|
|
|
558
558
|
#. @context: Empty state message
|
|
559
559
|
#. @context: Empty state message
|
|
560
560
|
#: src/routes/dash/collections.tsx:243
|
|
561
|
-
#: src/
|
|
561
|
+
#: src/themes/minimal/pages/CollectionPage.tsx:29
|
|
562
562
|
msgid "No posts in this collection."
|
|
563
563
|
msgstr "此集合中沒有帖子。"
|
|
564
564
|
|
|
565
565
|
#. @context: Empty state message on home page
|
|
566
566
|
#. @context: Empty state message when no posts exist
|
|
567
567
|
#: src/theme/components/PostList.tsx:25
|
|
568
|
-
#: src/
|
|
568
|
+
#: src/themes/minimal/pages/HomePage.tsx:26
|
|
569
569
|
msgid "No posts yet."
|
|
570
570
|
msgstr "尚未有帖子。"
|
|
571
571
|
|
|
@@ -575,7 +575,7 @@ msgid "No redirects configured."
|
|
|
575
575
|
msgstr "未配置任何重定向。"
|
|
576
576
|
|
|
577
577
|
#. @context: Search empty results
|
|
578
|
-
#: src/
|
|
578
|
+
#: src/themes/minimal/pages/SearchPage.tsx:64
|
|
579
579
|
msgid "No results found."
|
|
580
580
|
msgstr "未找到結果。"
|
|
581
581
|
|
|
@@ -584,12 +584,12 @@ msgstr "未找到結果。"
|
|
|
584
584
|
#. @context: Post type option
|
|
585
585
|
#: src/theme/components/PostForm.tsx:71
|
|
586
586
|
#: src/theme/components/TypeBadge.tsx:19
|
|
587
|
-
#: src/
|
|
587
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:16
|
|
588
588
|
msgid "Note"
|
|
589
589
|
msgstr "備註"
|
|
590
590
|
|
|
591
591
|
#. @context: Post type label plural - notes
|
|
592
|
-
#: src/
|
|
592
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:38
|
|
593
593
|
msgid "Notes"
|
|
594
594
|
msgstr "筆記"
|
|
595
595
|
|
|
@@ -598,7 +598,7 @@ msgstr "筆記"
|
|
|
598
598
|
#. @context: Post type label - page
|
|
599
599
|
#: src/routes/dash/pages.tsx:125
|
|
600
600
|
#: src/theme/components/TypeBadge.tsx:33
|
|
601
|
-
#: src/
|
|
601
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:30
|
|
602
602
|
msgid "Page"
|
|
603
603
|
msgstr "頁面"
|
|
604
604
|
|
|
@@ -622,14 +622,14 @@ msgstr "頁面標題..."
|
|
|
622
622
|
#. @context: Post type label plural - pages
|
|
623
623
|
#: src/routes/dash/pages.tsx:36
|
|
624
624
|
#: src/theme/layouts/DashLayout.tsx:96
|
|
625
|
-
#: src/
|
|
625
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:58
|
|
626
626
|
msgid "Pages"
|
|
627
627
|
msgstr "頁面"
|
|
628
628
|
|
|
629
629
|
#. @context: Setup/signin form field - password
|
|
630
630
|
#. @context: Setup/signin form field - password
|
|
631
|
-
#: src/app.tsx:
|
|
632
|
-
#: src/app.tsx:
|
|
631
|
+
#: src/app.tsx:262
|
|
632
|
+
#: src/app.tsx:400
|
|
633
633
|
msgid "Password"
|
|
634
634
|
msgstr "密碼"
|
|
635
635
|
|
|
@@ -646,7 +646,7 @@ msgstr "路徑(例如 /archive)或完整網址(例如 https://example.com
|
|
|
646
646
|
#. @context: Link to individual post in thread
|
|
647
647
|
#. @context: Link to permanent URL of post
|
|
648
648
|
#: src/theme/components/ThreadView.tsx:68
|
|
649
|
-
#: src/
|
|
649
|
+
#: src/themes/minimal/pages/PostPage.tsx:35
|
|
650
650
|
msgid "Permalink"
|
|
651
651
|
msgstr "永久鏈接"
|
|
652
652
|
|
|
@@ -697,9 +697,9 @@ msgstr "上一頁"
|
|
|
697
697
|
#. @context: Loading text shown on submit button while request is in progress
|
|
698
698
|
#. @context: Loading text shown on submit button while request is in progress
|
|
699
699
|
#. @context: Upload status - processing
|
|
700
|
-
#: src/app.tsx:
|
|
701
|
-
#: src/app.tsx:
|
|
702
|
-
#: src/app.tsx:
|
|
700
|
+
#: src/app.tsx:283
|
|
701
|
+
#: src/app.tsx:420
|
|
702
|
+
#: src/app.tsx:560
|
|
703
703
|
#: src/routes/dash/collections.tsx:178
|
|
704
704
|
#: src/routes/dash/collections.tsx:357
|
|
705
705
|
#: src/routes/dash/media.tsx:119
|
|
@@ -755,12 +755,12 @@ msgstr "安靜(正常)"
|
|
|
755
755
|
#. @context: Post type option
|
|
756
756
|
#: src/theme/components/PostForm.tsx:80
|
|
757
757
|
#: src/theme/components/TypeBadge.tsx:25
|
|
758
|
-
#: src/
|
|
758
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:22
|
|
759
759
|
msgid "Quote"
|
|
760
760
|
msgstr "引用"
|
|
761
761
|
|
|
762
762
|
#. @context: Post type label plural - quotes
|
|
763
|
-
#: src/
|
|
763
|
+
#: src/themes/minimal/pages/ArchivePage.tsx:50
|
|
764
764
|
msgid "Quotes"
|
|
765
765
|
msgstr "引用"
|
|
766
766
|
|
|
@@ -780,8 +780,8 @@ msgstr "移除"
|
|
|
780
780
|
|
|
781
781
|
#. @context: Password reset form submit button
|
|
782
782
|
#. @context: Password reset page heading
|
|
783
|
-
#: src/app.tsx:
|
|
784
|
-
#: src/app.tsx:
|
|
783
|
+
#: src/app.tsx:501
|
|
784
|
+
#: src/app.tsx:554
|
|
785
785
|
msgid "Reset Password"
|
|
786
786
|
msgstr "重設密碼"
|
|
787
787
|
|
|
@@ -802,13 +802,13 @@ msgstr "保存設定"
|
|
|
802
802
|
|
|
803
803
|
#. @context: Search page title
|
|
804
804
|
#. @context: Search submit button
|
|
805
|
-
#: src/
|
|
806
|
-
#: src/
|
|
805
|
+
#: src/themes/minimal/pages/SearchPage.tsx:21
|
|
806
|
+
#: src/themes/minimal/pages/SearchPage.tsx:46
|
|
807
807
|
msgid "Search"
|
|
808
808
|
msgstr "搜尋"
|
|
809
809
|
|
|
810
810
|
#. @context: Search input placeholder
|
|
811
|
-
#: src/
|
|
811
|
+
#: src/themes/minimal/pages/SearchPage.tsx:38
|
|
812
812
|
msgid "Search posts..."
|
|
813
813
|
msgstr "搜尋帖子..."
|
|
814
814
|
|
|
@@ -830,14 +830,14 @@ msgstr "設定"
|
|
|
830
830
|
|
|
831
831
|
#. @context: Link to show remaining thread replies
|
|
832
832
|
#. placeholder {0}: remainingCount === 1 ? "reply" : "replies"
|
|
833
|
-
#: src/
|
|
833
|
+
#: src/themes/minimal/timeline/ThreadPreview.tsx:37
|
|
834
834
|
msgid "Show {remainingCount} more {0}"
|
|
835
835
|
msgstr "顯示 {remainingCount} 個更多 {0}"
|
|
836
836
|
|
|
837
837
|
#. @context: Sign in form submit button
|
|
838
838
|
#. @context: Sign in page heading
|
|
839
|
-
#: src/app.tsx:
|
|
840
|
-
#: src/app.tsx:
|
|
839
|
+
#: src/app.tsx:367
|
|
840
|
+
#: src/app.tsx:414
|
|
841
841
|
msgid "Sign In"
|
|
842
842
|
msgstr "登入"
|
|
843
843
|
|
|
@@ -894,7 +894,7 @@ msgid "The URL path for this page. Use lowercase letters, numbers, and hyphens."
|
|
|
894
894
|
msgstr "此頁面的 URL 路徑。使用小寫字母、數字和連字符。"
|
|
895
895
|
|
|
896
896
|
#. @context: Password reset error description
|
|
897
|
-
#: src/app.tsx:
|
|
897
|
+
#: src/app.tsx:590
|
|
898
898
|
msgid "This password reset link is invalid or has expired. Please generate a new one."
|
|
899
899
|
msgstr "此密碼重設連結無效或已過期。請生成一個新的連結。"
|
|
900
900
|
|
|
@@ -1033,7 +1033,7 @@ msgid "Visibility"
|
|
|
1033
1033
|
msgstr "可見性"
|
|
1034
1034
|
|
|
1035
1035
|
#. @context: Setup page welcome heading
|
|
1036
|
-
#: src/app.tsx:
|
|
1036
|
+
#: src/app.tsx:211
|
|
1037
1037
|
msgid "Welcome to Jant"
|
|
1038
1038
|
msgstr "歡迎來到 Jant"
|
|
1039
1039
|
|
|
@@ -1048,6 +1048,6 @@ msgid "What's this collection about?"
|
|
|
1048
1048
|
msgstr "這個收藏是關於什麼的?"
|
|
1049
1049
|
|
|
1050
1050
|
#. @context: Setup form field - user name
|
|
1051
|
-
#: src/app.tsx:
|
|
1051
|
+
#: src/app.tsx:232
|
|
1052
1052
|
msgid "Your Name"
|
|
1053
1053
|
msgstr "您的姓名"
|
package/src/index.ts
CHANGED
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createApp as _createApp } from "./app.js";
|
|
8
|
-
|
|
9
7
|
// Main app factory
|
|
10
8
|
export { createApp } from "./app.js";
|
|
11
9
|
export type { App, AppVariables } from "./app.js";
|
|
12
10
|
|
|
11
|
+
// Default theme
|
|
12
|
+
export { theme as minimalTheme } from "./themes/minimal/index.js";
|
|
13
|
+
export type { ThemeOptions as MinimalThemeOptions } from "./themes/minimal/index.js";
|
|
14
|
+
|
|
13
15
|
// Types
|
|
14
16
|
export type {
|
|
15
17
|
PostType,
|
|
@@ -96,6 +98,3 @@ export {
|
|
|
96
98
|
defaultAtomRenderer,
|
|
97
99
|
defaultSitemapRenderer,
|
|
98
100
|
} from "./lib/feed.js";
|
|
99
|
-
|
|
100
|
-
// Default export for running core directly (e.g., for development)
|
|
101
|
-
export default _createApp();
|
|
@@ -194,8 +194,8 @@ describe("toPostViews", () => {
|
|
|
194
194
|
const posts = [makePostWithMedia({ id: 1 }), makePostWithMedia({ id: 2 })];
|
|
195
195
|
const views = toPostViews(posts, EMPTY_CTX);
|
|
196
196
|
expect(views).toHaveLength(2);
|
|
197
|
-
expect(views[0]
|
|
198
|
-
expect(views[1]
|
|
197
|
+
expect(views[0]).toHaveProperty("id", 1);
|
|
198
|
+
expect(views[1]).toHaveProperty("id", 2);
|
|
199
199
|
});
|
|
200
200
|
});
|
|
201
201
|
|
|
@@ -305,9 +305,9 @@ describe("toNavLinkViews", () => {
|
|
|
305
305
|
];
|
|
306
306
|
const views = toNavLinkViews(links, "/archive");
|
|
307
307
|
expect(views).toHaveLength(3);
|
|
308
|
-
expect(views[0]
|
|
309
|
-
expect(views[1]
|
|
310
|
-
expect(views[2]
|
|
308
|
+
expect(views[0]).toHaveProperty("isActive", false);
|
|
309
|
+
expect(views[1]).toHaveProperty("isActive", true);
|
|
310
|
+
expect(views[2]).toHaveProperty("isExternal", true);
|
|
311
311
|
});
|
|
312
312
|
});
|
|
313
313
|
|
|
@@ -347,15 +347,16 @@ describe("toArchiveGroups", () => {
|
|
|
347
347
|
const groups = toArchiveGroups(grouped, EMPTY_CTX);
|
|
348
348
|
expect(groups).toHaveLength(2);
|
|
349
349
|
|
|
350
|
-
expect(groups[0]
|
|
351
|
-
expect(groups[0]
|
|
352
|
-
expect(groups[0]
|
|
353
|
-
expect(groups[0]
|
|
350
|
+
expect(groups[0]).toHaveProperty("year", "2024");
|
|
351
|
+
expect(groups[0]).toHaveProperty("month", "02");
|
|
352
|
+
expect(groups[0]).toHaveProperty("label", "February 2024");
|
|
353
|
+
expect(groups[0]).toHaveProperty("posts");
|
|
354
|
+
expect(groups[0]?.posts).toHaveLength(2);
|
|
354
355
|
|
|
355
|
-
expect(groups[1]
|
|
356
|
-
expect(groups[1]
|
|
357
|
-
expect(groups[1]
|
|
358
|
-
expect(groups[1]
|
|
356
|
+
expect(groups[1]).toHaveProperty("year", "2024");
|
|
357
|
+
expect(groups[1]).toHaveProperty("month", "01");
|
|
358
|
+
expect(groups[1]).toHaveProperty("label", "January 2024");
|
|
359
|
+
expect(groups[1]?.posts).toHaveLength(1);
|
|
359
360
|
});
|
|
360
361
|
|
|
361
362
|
it("converts posts to PostView within groups", () => {
|
|
@@ -363,9 +364,10 @@ describe("toArchiveGroups", () => {
|
|
|
363
364
|
grouped.set("2024-02", [makePost({ id: 1 })]);
|
|
364
365
|
|
|
365
366
|
const groups = toArchiveGroups(grouped, EMPTY_CTX);
|
|
366
|
-
const post = groups[0]
|
|
367
|
-
expect(post
|
|
368
|
-
expect(post
|
|
367
|
+
const post = groups[0]?.posts[0];
|
|
368
|
+
expect(post).toBeDefined();
|
|
369
|
+
expect(post?.permalink).toBeDefined();
|
|
370
|
+
expect(post?.publishedAtFormatted).toBeDefined();
|
|
369
371
|
});
|
|
370
372
|
|
|
371
373
|
it("handles empty map", () => {
|
package/src/lib/render.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import type { Context } from "hono";
|
|
|
12
12
|
import type { Child } from "hono/jsx";
|
|
13
13
|
import type { ThemeComponents, SiteLayoutProps } from "../types.js";
|
|
14
14
|
import { BaseLayout } from "../theme/layouts/BaseLayout.js";
|
|
15
|
-
import { SiteLayout as DefaultSiteLayout } from "../
|
|
15
|
+
import { SiteLayout as DefaultSiteLayout } from "../themes/minimal/MinimalSiteLayout.js";
|
|
16
16
|
import type { NavigationData } from "./navigation.js";
|
|
17
17
|
|
|
18
18
|
export interface RenderPublicPageOptions {
|
package/src/lib/view.ts
CHANGED
|
@@ -109,7 +109,7 @@ export function toMediaView(media: Media, ctx: MediaContext): MediaView {
|
|
|
109
109
|
* const postView = toPostView({ ...post, mediaAttachments: [...] }, mediaCtx);
|
|
110
110
|
* ```
|
|
111
111
|
*/
|
|
112
|
-
export function toPostView(post: PostWithMedia,
|
|
112
|
+
export function toPostView(post: PostWithMedia, _ctx: MediaContext): PostView {
|
|
113
113
|
const permalink = `/p/${encode(post.id)}`;
|
|
114
114
|
|
|
115
115
|
// Pre-compute excerpt from raw content
|
|
@@ -9,8 +9,8 @@ import type { Bindings, TimelineItemView } from "../../types.js";
|
|
|
9
9
|
import type { AppVariables } from "../../app.js";
|
|
10
10
|
import { sse } from "../../lib/sse.js";
|
|
11
11
|
import { buildMediaMap } from "../../lib/media-helpers.js";
|
|
12
|
-
import { TimelineItem } from "../../
|
|
13
|
-
import { ThreadPreview as DefaultThreadPreview } from "../../
|
|
12
|
+
import { TimelineItem } from "../../themes/minimal/timeline/TimelineItem.js";
|
|
13
|
+
import { ThreadPreview as DefaultThreadPreview } from "../../themes/minimal/timeline/ThreadPreview.js";
|
|
14
14
|
import { createMediaContext, toPostView, toPostViews } from "../../lib/view.js";
|
|
15
15
|
|
|
16
16
|
type Env = { Bindings: Bindings; Variables: AppVariables };
|
|
@@ -140,7 +140,7 @@ timelineApiRoutes.get("/", async (c) => {
|
|
|
140
140
|
|
|
141
141
|
// Build load-more button HTML
|
|
142
142
|
const loadMoreHtml = nextCursor
|
|
143
|
-
? `<div id="load-more-container" class="mt-
|
|
143
|
+
? `<div id="load-more-container" class="mt-8 text-center"><button class="text-sm text-muted-foreground hover:text-foreground hover:underline" data-on:click="@get('/api/timeline?cursor=${nextCursor}')">Load more</button></div>`
|
|
144
144
|
: "";
|
|
145
145
|
|
|
146
146
|
return sse(c, async (stream) => {
|
|
@@ -8,7 +8,7 @@ import { Hono } from "hono";
|
|
|
8
8
|
import type { Bindings, PostType } from "../../types.js";
|
|
9
9
|
import type { AppVariables } from "../../app.js";
|
|
10
10
|
import { POST_TYPES } from "../../types.js";
|
|
11
|
-
import { ArchivePage as DefaultArchivePage } from "../../
|
|
11
|
+
import { ArchivePage as DefaultArchivePage } from "../../themes/minimal/pages/ArchivePage.js";
|
|
12
12
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
13
13
|
import { renderPublicPage } from "../../lib/render.js";
|
|
14
14
|
import { createMediaContext, toArchiveGroups } from "../../lib/view.js";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import type { Bindings } from "../../types.js";
|
|
7
7
|
import type { AppVariables } from "../../app.js";
|
|
8
|
-
import { CollectionPage as DefaultCollectionPage } from "../../
|
|
8
|
+
import { CollectionPage as DefaultCollectionPage } from "../../themes/minimal/pages/CollectionPage.js";
|
|
9
9
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
10
10
|
import { renderPublicPage } from "../../lib/render.js";
|
|
11
11
|
import { createMediaContext, toPostViewsFromPosts } from "../../lib/view.js";
|
|
@@ -10,7 +10,7 @@ import type { AppVariables } from "../../app.js";
|
|
|
10
10
|
import { buildMediaMap } from "../../lib/media-helpers.js";
|
|
11
11
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
12
12
|
import { renderPublicPage } from "../../lib/render.js";
|
|
13
|
-
import { HomePage as DefaultHomePage } from "../../
|
|
13
|
+
import { HomePage as DefaultHomePage } from "../../themes/minimal/pages/HomePage.js";
|
|
14
14
|
import { createMediaContext, toPostView, toPostViews } from "../../lib/view.js";
|
|
15
15
|
|
|
16
16
|
type Env = { Bindings: Bindings; Variables: AppVariables };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { Hono } from "hono";
|
|
8
8
|
import type { Bindings } from "../../types.js";
|
|
9
9
|
import type { AppVariables } from "../../app.js";
|
|
10
|
-
import { SinglePage as DefaultSinglePage } from "../../
|
|
10
|
+
import { SinglePage as DefaultSinglePage } from "../../themes/minimal/pages/SinglePage.js";
|
|
11
11
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
12
12
|
import { renderPublicPage } from "../../lib/render.js";
|
|
13
13
|
import { createMediaContext, toPostViewFromPost } from "../../lib/view.js";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import type { Bindings } from "../../types.js";
|
|
7
7
|
import type { AppVariables } from "../../app.js";
|
|
8
|
-
import { PostPage as DefaultPostPage } from "../../
|
|
8
|
+
import { PostPage as DefaultPostPage } from "../../themes/minimal/pages/PostPage.js";
|
|
9
9
|
import * as sqid from "../../lib/sqid.js";
|
|
10
10
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
11
11
|
import { renderPublicPage } from "../../lib/render.js";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import type { Bindings, SearchResult } from "../../types.js";
|
|
7
7
|
import type { AppVariables } from "../../app.js";
|
|
8
|
-
import { SearchPage as DefaultSearchPage } from "../../
|
|
8
|
+
import { SearchPage as DefaultSearchPage } from "../../themes/minimal/pages/SearchPage.js";
|
|
9
9
|
import { getNavigationData } from "../../lib/navigation.js";
|
|
10
10
|
import { renderPublicPage } from "../../lib/render.js";
|
|
11
11
|
import { createMediaContext, toSearchResultViews } from "../../lib/view.js";
|
|
@@ -124,60 +124,6 @@
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
/* Timeline cards */
|
|
128
|
-
@layer components {
|
|
129
|
-
.timeline-card {
|
|
130
|
-
@apply rounded-lg border p-4;
|
|
131
|
-
border-color: var(--color-border);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.timeline-card-link {
|
|
135
|
-
border-left-width: 4px;
|
|
136
|
-
border-left-color: var(--color-primary);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.timeline-card-quote {
|
|
140
|
-
border-left-width: 4px;
|
|
141
|
-
border-left-color: var(--color-muted-foreground);
|
|
142
|
-
background-color: var(--color-muted);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.timeline-card-image {
|
|
146
|
-
@apply p-0 overflow-hidden;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.timeline-card-image-gallery {
|
|
150
|
-
/* Remove default margin from MediaGallery inside image cards */
|
|
151
|
-
> div {
|
|
152
|
-
@apply mt-0;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.timeline-card-compact {
|
|
157
|
-
@apply p-3 text-sm;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.timeline-thread-replies {
|
|
161
|
-
@apply relative ml-5;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.timeline-thread-reply {
|
|
165
|
-
@apply relative pl-5 mt-3;
|
|
166
|
-
|
|
167
|
-
&::after {
|
|
168
|
-
content: "";
|
|
169
|
-
@apply absolute left-0 top-0 bottom-0 w-px;
|
|
170
|
-
background-color: var(--color-border);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
&::before {
|
|
174
|
-
content: "";
|
|
175
|
-
@apply absolute left-0 top-4 h-px w-4;
|
|
176
|
-
background-color: var(--color-border);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
127
|
@keyframes toast-in {
|
|
182
128
|
from {
|
|
183
129
|
opacity: 0;
|
|
@@ -21,16 +21,3 @@ export {
|
|
|
21
21
|
VisibilityBadge,
|
|
22
22
|
type VisibilityBadgeProps,
|
|
23
23
|
} from "./VisibilityBadge.js";
|
|
24
|
-
|
|
25
|
-
// Timeline components
|
|
26
|
-
export {
|
|
27
|
-
NoteCard,
|
|
28
|
-
ArticleCard,
|
|
29
|
-
LinkCard,
|
|
30
|
-
QuoteCard,
|
|
31
|
-
ImageCard,
|
|
32
|
-
ThreadPreview,
|
|
33
|
-
TimelineItem,
|
|
34
|
-
TimelineItemFromPost,
|
|
35
|
-
TimelineFeed,
|
|
36
|
-
} from "./timeline/index.js";
|
package/src/theme/index.ts
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Jant Theme
|
|
2
|
+
* Jant Theme - Shared Infrastructure
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Exports shared layouts, components, and color themes used by all themes.
|
|
5
|
+
* Individual theme packages (minimal, card, etc.) import from here.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```typescript
|
|
8
|
-
*
|
|
9
|
-
* import
|
|
10
|
-
*
|
|
11
|
-
* export function MyPostPage(props: PostPageProps) {
|
|
12
|
-
* return (
|
|
13
|
-
* <div class="my-wrapper">
|
|
14
|
-
* <PostPage {...props} />
|
|
15
|
-
* </div>
|
|
16
|
-
* );
|
|
17
|
-
* }
|
|
9
|
+
* // In a theme package:
|
|
10
|
+
* import { MediaGallery, Pagination } from "@jant/core/theme";
|
|
11
|
+
* import type { ColorTheme } from "@jant/core/theme";
|
|
18
12
|
* ```
|
|
19
13
|
*/
|
|
20
14
|
|
|
21
|
-
// Layout components
|
|
15
|
+
// Layout components (BaseLayout, DashLayout)
|
|
22
16
|
export * from "./layouts/index.js";
|
|
23
17
|
|
|
24
|
-
// UI components
|
|
18
|
+
// Shared UI components (MediaGallery, Pagination, EmptyState, etc.)
|
|
25
19
|
export * from "./components/index.js";
|
|
26
20
|
|
|
27
|
-
//
|
|
28
|
-
export * from "./
|
|
21
|
+
// Color themes
|
|
22
|
+
export * from "./color-themes.js";
|