@jant/core 0.6.14 → 0.6.15
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/commands/import-site.js +81 -13
- package/bin/commands/migrate.js +55 -0
- package/bin/commands/posts/rebuild-html.js +184 -0
- package/bin/commands/site/snapshot/import.js +14 -10
- package/bin/lib/d1-query.js +23 -5
- package/bin/lib/migration-runner.js +29 -7
- package/bin/lib/node-database.js +32 -0
- package/bin/lib/site-snapshot.js +347 -46
- package/bin/lib/sql-export.js +1 -1
- package/bin/lib/thread-collection-migration.js +326 -0
- package/dist/app-BxCOR3Uc.js +6 -0
- package/dist/{app-2i7-WQHg.js → app-C-oi_t8W.js} +7408 -6343
- package/dist/client/.vite/manifest.json +3 -3
- package/dist/client/_assets/client-B_eGKN5p.css +2 -0
- package/dist/client/_assets/{client-BvID5ucz.js → client-DxY5BFe8.js} +58 -37
- package/dist/client/_assets/client-auth-CakPESv9.js +5533 -0
- package/dist/{export-DWn149b7.js → export-CsFx6F_M.js} +1259 -125
- package/dist/{github-sync-Ckk0sJxK.js → github-sync-Cq1pzzOI.js} +1 -1
- package/dist/{github-sync-C0zyF6XS.js → github-sync-ppWXN3jb.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/node.js +5 -5
- package/package.json +11 -10
- package/src/__tests__/bin/posts-rebuild-html.test.ts +137 -0
- package/src/__tests__/dev-navigation-defaults.test.ts +22 -0
- package/src/__tests__/export-hugo-build.test.ts +63 -4
- package/src/__tests__/export-import-roundtrip.test.ts +6 -4
- package/src/__tests__/export-service.test.ts +142 -9
- package/src/__tests__/helpers/app.ts +3 -0
- package/src/__tests__/helpers/export-fixtures.ts +2 -0
- package/src/__tests__/import-site-command.test.ts +65 -0
- package/src/__tests__/vite-config.test.ts +45 -0
- package/src/app.tsx +16 -3
- package/src/client/__tests__/collection-created-notice.test.ts +36 -0
- package/src/client/__tests__/collection-form-bridge.test.ts +10 -1
- package/src/client/__tests__/collection-page-actions.test.ts +71 -2
- package/src/client/__tests__/compose-bridge.test.ts +64 -0
- package/src/client/__tests__/feed-video-player.test.ts +16 -1
- package/src/client/__tests__/footnote-rail.test.ts +472 -0
- package/src/client/__tests__/hydrate-partial.test.ts +3 -0
- package/src/client/__tests__/toast.test.ts +18 -1
- package/src/client/collection-created-notice.ts +66 -0
- package/src/client/collection-form-bridge.ts +17 -0
- package/src/client/collection-navigation.ts +44 -0
- package/src/client/collection-page-actions.ts +57 -1
- package/src/client/components/__tests__/jant-collection-directory.test.ts +155 -6
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +370 -5
- package/src/client/components/__tests__/jant-compose-editor.test.ts +97 -0
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +104 -0
- package/src/client/components/__tests__/jant-config-editor.test.ts +405 -0
- package/src/client/components/__tests__/jant-media-lightbox.test.ts +121 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +538 -2
- package/src/client/components/__tests__/jant-post-form.test.ts +2 -2
- package/src/client/components/__tests__/jant-post-menu.test.ts +47 -5
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +2 -2
- package/src/client/components/__tests__/jant-settings-general.test.ts +3 -3
- package/src/client/components/collection-manager-types.ts +9 -3
- package/src/client/components/compose-types.ts +8 -0
- package/src/client/components/jant-collection-directory.ts +165 -30
- package/src/client/components/jant-command-palette.ts +2 -1
- package/src/client/components/jant-compose-dialog.ts +85 -21
- package/src/client/components/jant-compose-editor.ts +13 -7
- package/src/client/components/jant-compose-fullscreen.ts +24 -4
- package/src/client/components/jant-config-editor.ts +722 -0
- package/src/client/components/jant-media-lightbox.ts +100 -18
- package/src/client/components/jant-nav-manager.ts +1283 -54
- package/src/client/components/jant-post-form.ts +3 -3
- package/src/client/components/jant-post-menu.ts +86 -74
- package/src/client/components/nav-manager-types.ts +51 -2
- package/src/client/components/post-form-types.ts +1 -1
- package/src/client/compose-bridge.ts +4 -1
- package/src/client/feed-video-player.ts +62 -2
- package/src/client/footnote-rail.ts +478 -0
- package/src/client/hydrate-partial.ts +2 -0
- package/src/client/media-lightbox-events.ts +63 -0
- package/src/client/site-header-fragment.ts +38 -0
- package/src/client/tiptap/__tests__/blockquote-editing.test.ts +201 -0
- package/src/client/tiptap/__tests__/clear-formatting.test.ts +168 -0
- package/src/client/tiptap/__tests__/list-editing.test.ts +447 -0
- package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +727 -4
- package/src/client/tiptap/__tests__/table-controls.test.ts +263 -0
- package/src/client/tiptap/__tests__/table-size-picker.test.ts +179 -0
- package/src/client/tiptap/bubble-menu.ts +88 -10
- package/src/client/tiptap/continuous-lists.ts +102 -0
- package/src/client/tiptap/create-editor.ts +3 -0
- package/src/client/tiptap/extensions.ts +14 -5
- package/src/client/tiptap/markdown-clipboard.ts +608 -11
- package/src/client/tiptap/slash-commands.ts +8 -1
- package/src/client/tiptap/structural-keymap.ts +211 -0
- package/src/client/tiptap/tab-indent.ts +8 -22
- package/src/client/tiptap/table-control-labels.ts +30 -0
- package/src/client/tiptap/table-controls.ts +537 -0
- package/src/client/tiptap/table-size-picker.ts +254 -0
- package/src/client/toast.ts +8 -6
- package/src/client-auth.ts +1 -0
- package/src/client.ts +1 -0
- package/src/db/__tests__/d1-query.test.ts +43 -1
- package/src/db/__tests__/migration-runner.test.ts +63 -0
- package/src/db/__tests__/migrations.test.ts +469 -0
- package/src/db/__tests__/thread-collection-migration.test.ts +364 -0
- package/src/db/migrations/0027_old_blue_blade.sql +39 -0
- package/src/db/migrations/0028_superb_post.sql +2 -0
- package/src/db/migrations/0029_boring_magma.sql +1 -0
- package/src/db/migrations/0030_typical_vivisector.sql +50 -0
- package/src/db/migrations/meta/0027_snapshot.json +2511 -0
- package/src/db/migrations/meta/0028_snapshot.json +2511 -0
- package/src/db/migrations/meta/0029_snapshot.json +2519 -0
- package/src/db/migrations/meta/0030_snapshot.json +2541 -0
- package/src/db/migrations/meta/_journal.json +28 -0
- package/src/db/migrations/pg/0025_moaning_epoch.sql +39 -0
- package/src/db/migrations/pg/0026_talented_killer_shrike.sql +2 -0
- package/src/db/migrations/pg/0027_short_cannonball.sql +1 -0
- package/src/db/migrations/pg/0028_perfect_sharon_carter.sql +27 -0
- package/src/db/migrations/pg/meta/0025_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0026_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0027_snapshot.json +3211 -0
- package/src/db/migrations/pg/meta/0028_snapshot.json +3248 -0
- package/src/db/migrations/pg/meta/_journal.json +28 -0
- package/src/db/pg/schema.ts +28 -20
- package/src/db/rehearsal-fixtures/demo-current.json +39 -4
- package/src/db/rehearsal-fixtures/demo-current.sql +121 -6
- package/src/db/schema.ts +28 -20
- package/src/i18n/__tests__/detect.test.ts +8 -2
- package/src/i18n/detect.ts +14 -5
- package/src/i18n/locales/public/en.po +133 -30
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +128 -25
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +128 -25
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/i18n/locales/settings/en.po +513 -10
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +515 -12
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +515 -12
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/lib/__tests__/api-settings.test.ts +299 -0
- package/src/lib/__tests__/constants.test.ts +5 -0
- package/src/lib/__tests__/feed-policy.test.ts +25 -0
- package/src/lib/__tests__/footnotes-upgrade.test.ts +181 -0
- package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +61 -0
- package/src/lib/__tests__/markdown-to-tiptap.test.ts +32 -4
- package/src/lib/__tests__/markdown.test.ts +8 -6
- package/src/lib/__tests__/navigation.test.ts +59 -2
- package/src/lib/__tests__/post-body-html.test.ts +176 -0
- package/src/lib/__tests__/post-display.test.ts +64 -0
- package/src/lib/__tests__/resolve-config.test.ts +113 -1
- package/src/lib/__tests__/summary.test.ts +82 -0
- package/src/lib/__tests__/timeline.test.ts +109 -70
- package/src/lib/__tests__/timezones.test.ts +31 -3
- package/src/lib/__tests__/tiptap-render.test.ts +268 -9
- package/src/lib/__tests__/tiptap-to-markdown.test.ts +6 -0
- package/src/lib/__tests__/view.test.ts +53 -0
- package/src/lib/__tests__/worker-response-cache.test.ts +18 -1
- package/src/lib/api-settings.ts +239 -12
- package/src/lib/collection-sort.ts +7 -5
- package/src/lib/constants.ts +2 -0
- package/src/lib/feed-path.ts +25 -0
- package/src/lib/feed-policy.ts +64 -0
- package/src/lib/footnotes.ts +264 -0
- package/src/lib/github-sync-site-config.ts +2 -0
- package/src/lib/hugo-markdown.ts +10 -3
- package/src/lib/jant-branding.ts +1 -0
- package/src/lib/markdown-manager.ts +188 -5
- package/src/lib/markdown.ts +10 -3
- package/src/lib/navigation.ts +16 -3
- package/src/lib/post-body-html.ts +131 -0
- package/src/lib/post-display.ts +7 -1
- package/src/lib/render.tsx +9 -2
- package/src/lib/resolve-config.ts +100 -16
- package/src/lib/schemas.ts +133 -1
- package/src/lib/settings-paths.ts +5 -0
- package/src/lib/site-skill.ts +78 -0
- package/src/lib/summary.ts +16 -5
- package/src/lib/timeline.ts +98 -122
- package/src/lib/timezones.ts +54 -14
- package/src/lib/tiptap-render.ts +355 -81
- package/src/lib/view.ts +30 -20
- package/src/lib/worker-response-cache.ts +11 -18
- package/src/middleware/__tests__/public-content-access.test.ts +91 -0
- package/src/middleware/config.ts +2 -2
- package/src/middleware/public-content-access.ts +87 -0
- package/src/node/__tests__/cli-export.test.ts +14 -0
- package/src/node/__tests__/cli-migrate.test.ts +6 -0
- package/src/node/__tests__/cli-site-snapshot.test.ts +205 -2
- package/src/node/__tests__/cli-snapshot-meta.test.ts +100 -0
- package/src/node/index.ts +2 -1
- package/src/preset.css +16 -2
- package/src/routes/__tests__/compose.test.ts +51 -0
- package/src/routes/__tests__/site-skill.test.ts +112 -0
- package/src/routes/api/__tests__/collections.test.ts +91 -19
- package/src/routes/api/__tests__/mcp.test.ts +65 -1
- package/src/routes/api/__tests__/nav-items.test.ts +91 -0
- package/src/routes/api/__tests__/public-access.test.ts +81 -0
- package/src/routes/api/__tests__/settings.test.ts +217 -0
- package/src/routes/api/collections.ts +22 -26
- package/src/routes/api/export.ts +2 -0
- package/src/routes/api/internal/__tests__/post-body-html.test.ts +163 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +35 -2
- package/src/routes/api/internal/post-body-html.ts +43 -0
- package/src/routes/api/internal/sites.ts +24 -0
- package/src/routes/api/nav-items.ts +24 -1
- package/src/routes/api/posts.ts +2 -2
- package/src/routes/api/public/__tests__/archive.test.ts +35 -0
- package/src/routes/api/public/__tests__/posts.test.ts +208 -0
- package/src/routes/api/public/archive.ts +4 -0
- package/src/routes/api/public/posts.ts +41 -24
- package/src/routes/api/search.ts +3 -0
- package/src/routes/api/settings.ts +33 -0
- package/src/routes/auth/__tests__/setup.test.ts +7 -4
- package/src/routes/compose.tsx +2 -1
- package/src/routes/dash/settings.tsx +45 -2
- package/src/routes/feed/__tests__/feed.test.ts +210 -6
- package/src/routes/feed/feed.ts +23 -14
- package/src/routes/pages/__tests__/archive-params.test.ts +92 -3
- package/src/routes/pages/__tests__/collection-routing.test.ts +63 -5
- package/src/routes/pages/__tests__/collections.test.ts +9 -9
- package/src/routes/pages/__tests__/preview.test.ts +174 -0
- package/src/routes/pages/__tests__/search.test.ts +69 -0
- package/src/routes/pages/archive.tsx +27 -7
- package/src/routes/pages/collection.tsx +32 -19
- package/src/routes/pages/collections.tsx +6 -1
- package/src/routes/pages/page.tsx +83 -11
- package/src/routes/site-skill.ts +18 -0
- package/src/services/__tests__/auth.test.ts +7 -5
- package/src/services/__tests__/collection.test.ts +159 -44
- package/src/services/__tests__/navigation.test.ts +229 -21
- package/src/services/__tests__/post-timeline.test.ts +109 -30
- package/src/services/__tests__/post.test.ts +567 -5
- package/src/services/__tests__/search.test.ts +48 -1
- package/src/services/__tests__/settings.test.ts +8 -0
- package/src/services/__tests__/site-admin.test.ts +121 -1
- package/src/services/auth.ts +2 -2
- package/src/services/bootstrap.ts +3 -2
- package/src/services/collection.ts +226 -167
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export-theme/assets/client-site.js +46 -25
- package/src/services/export-theme/layouts/_default/list.html +18 -4
- package/src/services/export-theme/layouts/_default/rss.xml +8 -12
- package/src/services/export-theme/layouts/featured/list.html +5 -4
- package/src/services/export-theme/layouts/partials/featured-thread.html +56 -0
- package/src/services/export-theme/layouts/partials/footer.html +1 -1
- package/src/services/export-theme/layouts/partials/media-gallery.html +1 -0
- package/src/services/export-theme/styles/main.css +30 -2
- package/src/services/export.ts +91 -80
- package/src/services/mcp.ts +37 -27
- package/src/services/media.ts +1 -1
- package/src/services/navigation.ts +185 -46
- package/src/services/post.ts +874 -271
- package/src/services/search.ts +8 -2
- package/src/services/settings.ts +2 -10
- package/src/services/site-admin.ts +63 -43
- package/src/style-cjk-jp.css +1 -1
- package/src/style-cjk-kr.css +1 -1
- package/src/style-cjk-tc.css +1 -1
- package/src/style-cjk.css +1 -1
- package/src/styles/components.css +540 -0
- package/src/styles/site-media.css +111 -19
- package/src/styles/tokens.css +14 -9
- package/src/styles/ui.css +829 -29
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +243 -12
- package/src/types/constants.ts +22 -1
- package/src/types/entities.ts +9 -8
- package/src/types/operations.ts +18 -10
- package/src/types/props.ts +8 -2
- package/src/types/raw-assets.d.ts +5 -0
- package/src/types/views.ts +16 -4
- package/src/ui/__tests__/font-themes.test.ts +42 -30
- package/src/ui/compose/ComposeDialog.tsx +92 -2
- package/src/ui/dash/appearance/NavigationContent.tsx +332 -4
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +23 -0
- package/src/ui/dash/settings/ConfigEditorContent.tsx +578 -0
- package/src/ui/dash/settings/GeneralContent.tsx +15 -5
- package/src/ui/dash/settings/SettingsRootContent.tsx +21 -1
- package/src/ui/dash/settings/__tests__/ConfigEditorContent.test.tsx +98 -0
- package/src/ui/dash/settings/__tests__/SettingsRootContent.test.tsx +15 -0
- package/src/ui/feed/CuratedThreadPreview.tsx +16 -4
- package/src/ui/feed/LinkCard.tsx +2 -12
- package/src/ui/feed/NoteCard.tsx +10 -20
- package/src/ui/feed/QuoteCard.tsx +2 -12
- package/src/ui/feed/ThreadPreview.tsx +26 -34
- package/src/ui/feed/TimelineFeed.tsx +2 -2
- package/src/ui/feed/__tests__/thread-preview.test.ts +197 -56
- package/src/ui/feed/__tests__/timeline-cards.test.ts +178 -3
- package/src/ui/feed/thread-preview-state.ts +5 -7
- package/src/ui/font-themes.ts +74 -26
- package/src/ui/layouts/BaseLayout.tsx +22 -8
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +64 -1
- package/src/ui/pages/CollectionPage.tsx +101 -22
- package/src/ui/pages/CollectionsPage.tsx +3 -1
- package/src/ui/pages/PostPage.tsx +39 -12
- package/src/ui/pages/SearchPage.tsx +6 -14
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +7 -0
- package/src/ui/pages/__tests__/PostPage.test.tsx +88 -0
- package/src/ui/shared/CollectionDirectory.tsx +13 -9
- package/src/ui/shared/CollectionsManager.tsx +17 -7
- package/src/ui/shared/DraftPreviewBar.tsx +33 -0
- package/src/ui/shared/HomePageBranding.tsx +2 -2
- package/src/ui/shared/MediaGallery.tsx +1 -0
- package/src/ui/shared/PostFooter.tsx +3 -1
- package/src/ui/shared/__tests__/home-page-branding.test.tsx +1 -1
- package/src/ui/shared/__tests__/media-gallery.test.ts +1 -0
- package/src/ui/shared/__tests__/navigation-labels.test.ts +2 -2
- package/src/ui/shared/__tests__/post-footer.test.ts +15 -0
- package/src/ui/shared/collection-management-labels.ts +33 -2
- package/src/ui/shared/navigation-labels.ts +2 -4
- package/src/ui/shared/post-article-attributes.ts +46 -0
- package/dist/app-DZDlmh7C.js +0 -6
- package/dist/client/_assets/client-Cevfpm8H.css +0 -2
- package/dist/client/_assets/client-auth-v3yvhbgZ.js +0 -4736
- package/src/client/tiptap/wrapping-input-rules.ts +0 -102
package/src/types/views.ts
CHANGED
|
@@ -92,7 +92,7 @@ export interface PostView {
|
|
|
92
92
|
// Media -- URLs pre-computed
|
|
93
93
|
media: MediaView[];
|
|
94
94
|
|
|
95
|
-
// Collections this post
|
|
95
|
+
// Thread-level Collections projected onto this post
|
|
96
96
|
collections: CollectionTagView[];
|
|
97
97
|
|
|
98
98
|
// Thread context
|
|
@@ -157,6 +157,7 @@ export interface NavItemView {
|
|
|
157
157
|
type: NavItemType;
|
|
158
158
|
systemKey?: SystemNavKey;
|
|
159
159
|
collectionId?: string;
|
|
160
|
+
postId?: string;
|
|
160
161
|
label: string;
|
|
161
162
|
url: string;
|
|
162
163
|
/** "header" = visible in nav bar, "more" = under More dropdown */
|
|
@@ -173,7 +174,7 @@ export interface NavItemView {
|
|
|
173
174
|
|
|
174
175
|
export type SuggestedNavLinkTargetType = "page" | "collection" | "archive";
|
|
175
176
|
|
|
176
|
-
export type SuggestedNavLinkNavItemType = "link" | "collection";
|
|
177
|
+
export type SuggestedNavLinkNavItemType = "link" | "collection" | "page";
|
|
177
178
|
|
|
178
179
|
export interface SuggestedNavLink {
|
|
179
180
|
key: string;
|
|
@@ -182,6 +183,15 @@ export interface SuggestedNavLink {
|
|
|
182
183
|
targetType: SuggestedNavLinkTargetType;
|
|
183
184
|
navItemType: SuggestedNavLinkNavItemType;
|
|
184
185
|
collectionId?: string;
|
|
186
|
+
postId?: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** A published titled note eligible to be added to site navigation. */
|
|
190
|
+
export interface NavigationPageCandidate {
|
|
191
|
+
id: string;
|
|
192
|
+
title: string;
|
|
193
|
+
slug: string;
|
|
194
|
+
updatedAt: number;
|
|
185
195
|
}
|
|
186
196
|
|
|
187
197
|
/**
|
|
@@ -215,13 +225,15 @@ export interface SearchResultView {
|
|
|
215
225
|
export interface TimelineItemView {
|
|
216
226
|
post: PostView;
|
|
217
227
|
threadPreview?: {
|
|
218
|
-
|
|
219
|
-
|
|
228
|
+
leadingReplies: PostView[];
|
|
229
|
+
trailingReplies: PostView[];
|
|
220
230
|
latestReply: PostView;
|
|
221
231
|
totalReplyCount: number;
|
|
222
232
|
};
|
|
223
233
|
curatedThread?: {
|
|
224
234
|
rootPost: PostView;
|
|
235
|
+
/** Show ratings on non-highlighted context posts (complete Collection Threads). */
|
|
236
|
+
showContextRatings: boolean;
|
|
225
237
|
segments: {
|
|
226
238
|
post: PostView;
|
|
227
239
|
hiddenBeforeCount: number;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
BUILTIN_FONT_THEMES,
|
|
4
|
+
DEFAULT_FONT_CJK_SANS_FALLBACK,
|
|
4
5
|
DEFAULT_FONT_CJK_SERIF_FALLBACK,
|
|
5
|
-
|
|
6
|
+
getCjkFontCssVariables,
|
|
6
7
|
getFontThemeCssVariables,
|
|
8
|
+
resolveCjkFontProfile,
|
|
7
9
|
} from "../font-themes.js";
|
|
8
10
|
|
|
9
11
|
describe("BUILTIN_FONT_THEMES", () => {
|
|
@@ -90,52 +92,62 @@ describe("BUILTIN_FONT_THEMES", () => {
|
|
|
90
92
|
expect(variables["--type-label-weight"]).toBe("var(--fw-semibold)");
|
|
91
93
|
});
|
|
92
94
|
|
|
93
|
-
it("routes zh-Hans to
|
|
94
|
-
const variables =
|
|
95
|
-
const
|
|
95
|
+
it("routes zh-Hans content to simplified serif and sans fallbacks", () => {
|
|
96
|
+
const variables = getCjkFontCssVariables("zh-Hans", "off");
|
|
97
|
+
const serif = variables["--font-cjk-serif-fallback"];
|
|
98
|
+
const sans = variables["--font-cjk-sans-fallback"];
|
|
96
99
|
|
|
97
|
-
expect(
|
|
98
|
-
expect(
|
|
99
|
-
expect(
|
|
100
|
-
|
|
100
|
+
expect(serif).toContain('"Songti SC"');
|
|
101
|
+
expect(serif).toContain('"Noto Serif SC"');
|
|
102
|
+
expect(sans.indexOf('"PingFang SC"')).toBeLessThan(
|
|
103
|
+
sans.indexOf('"PingFang TC"'),
|
|
101
104
|
);
|
|
102
105
|
});
|
|
103
106
|
|
|
104
|
-
it("routes zh-Hant to
|
|
105
|
-
const variables =
|
|
106
|
-
const
|
|
107
|
+
it("routes zh-Hant content to traditional serif and sans fallbacks", () => {
|
|
108
|
+
const variables = getCjkFontCssVariables("zh-Hant", "off");
|
|
109
|
+
const serif = variables["--font-cjk-serif-fallback"];
|
|
110
|
+
const sans = variables["--font-cjk-sans-fallback"];
|
|
107
111
|
|
|
108
|
-
expect(
|
|
109
|
-
expect(
|
|
110
|
-
expect(
|
|
111
|
-
|
|
112
|
+
expect(serif).toContain('"Songti TC"');
|
|
113
|
+
expect(serif).toContain('"Noto Serif TC"');
|
|
114
|
+
expect(sans.indexOf('"PingFang TC"')).toBeLessThan(
|
|
115
|
+
sans.indexOf('"PingFang SC"'),
|
|
112
116
|
);
|
|
113
117
|
});
|
|
114
118
|
|
|
115
|
-
it("routes
|
|
116
|
-
const variables =
|
|
117
|
-
const stack = variables["--font-cjk-serif-fallback"];
|
|
119
|
+
it("routes Japanese content to the Japanese font profile", () => {
|
|
120
|
+
const variables = getCjkFontCssVariables("ja", "off");
|
|
118
121
|
|
|
119
|
-
expect(
|
|
122
|
+
expect(variables["--font-cjk-serif-fallback"]).toContain('"Noto Serif JP"');
|
|
123
|
+
expect(variables["--font-cjk-sans-fallback"]).toContain('"Noto Sans JP"');
|
|
120
124
|
});
|
|
121
125
|
|
|
122
|
-
it("routes
|
|
123
|
-
const variables =
|
|
124
|
-
const stack = variables["--font-cjk-serif-fallback"];
|
|
126
|
+
it("routes Korean content to the Korean font profile", () => {
|
|
127
|
+
const variables = getCjkFontCssVariables("ko", "off");
|
|
125
128
|
|
|
126
|
-
expect(
|
|
129
|
+
expect(variables["--font-cjk-serif-fallback"]).toContain('"Noto Serif KR"');
|
|
130
|
+
expect(variables["--font-cjk-sans-fallback"]).toContain('"Noto Sans KR"');
|
|
127
131
|
});
|
|
128
132
|
|
|
129
|
-
it("
|
|
130
|
-
expect(
|
|
133
|
+
it("uses the explicit CJK fallback for an unadapted content language", () => {
|
|
134
|
+
expect(resolveCjkFontProfile("en", "zh-Hans")).toBe("zh-Hans");
|
|
131
135
|
});
|
|
132
136
|
|
|
133
|
-
it("
|
|
134
|
-
expect(
|
|
137
|
+
it("lets an adapted content language override the manual fallback", () => {
|
|
138
|
+
expect(resolveCjkFontProfile("zh-Hant", "zh-Hans")).toBe("zh-Hant");
|
|
135
139
|
});
|
|
136
140
|
|
|
137
|
-
it("keeps
|
|
138
|
-
expect(
|
|
139
|
-
expect(DEFAULT_FONT_CJK_SERIF_FALLBACK).
|
|
141
|
+
it("keeps the default profile neutral", () => {
|
|
142
|
+
expect(getCjkFontCssVariables("en", "off")).toEqual({});
|
|
143
|
+
expect(DEFAULT_FONT_CJK_SERIF_FALLBACK).toBe('"Jant Language Fallback"');
|
|
144
|
+
expect(DEFAULT_FONT_CJK_SANS_FALLBACK).toBe('"Jant Language Fallback"');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("puts language slots into every serif and sans theme stack", () => {
|
|
148
|
+
for (const theme of BUILTIN_FONT_THEMES) {
|
|
149
|
+
const combined = `${theme.headingFontFamily} ${theme.bodyFontFamily}`;
|
|
150
|
+
expect(combined).toMatch(/var\(--font-cjk-(?:serif|sans)-fallback\)/);
|
|
151
|
+
}
|
|
140
152
|
});
|
|
141
153
|
});
|
|
@@ -13,6 +13,7 @@ import type { FC } from "hono/jsx";
|
|
|
13
13
|
import { MAX_THREAD_POSTS, type Collection } from "../../types.js";
|
|
14
14
|
import { useLingui } from "../../i18n/context.js";
|
|
15
15
|
import { getCollectionFormLabels } from "../shared/collection-management-labels.js";
|
|
16
|
+
import type { ComposeLabels } from "../../client/components/compose-types.js";
|
|
16
17
|
|
|
17
18
|
export interface ComposeDialogProps {
|
|
18
19
|
collections?: Collection[];
|
|
@@ -36,7 +37,7 @@ export const ComposeForm: FC<ComposeFormProps> = ({
|
|
|
36
37
|
}) => {
|
|
37
38
|
const { i18n } = useLingui();
|
|
38
39
|
|
|
39
|
-
const
|
|
40
|
+
const labelsObject = {
|
|
40
41
|
cancel: i18n._(
|
|
41
42
|
msg({
|
|
42
43
|
message: "Cancel",
|
|
@@ -476,6 +477,19 @@ export const ComposeForm: FC<ComposeFormProps> = ({
|
|
|
476
477
|
comment: "@context: Drafts panel empty state",
|
|
477
478
|
}),
|
|
478
479
|
),
|
|
480
|
+
previewDraft: i18n._(
|
|
481
|
+
msg({
|
|
482
|
+
message: "Preview",
|
|
483
|
+
comment: "@context: Draft item action that opens its rendered preview",
|
|
484
|
+
}),
|
|
485
|
+
),
|
|
486
|
+
draftActions: i18n._(
|
|
487
|
+
msg({
|
|
488
|
+
message: "Draft actions",
|
|
489
|
+
comment:
|
|
490
|
+
"@context: Accessible label for a draft item's more-actions button",
|
|
491
|
+
}),
|
|
492
|
+
),
|
|
479
493
|
deleteDraft: i18n._(
|
|
480
494
|
msg({
|
|
481
495
|
message: "Delete Draft",
|
|
@@ -807,8 +821,84 @@ export const ComposeForm: FC<ComposeFormProps> = ({
|
|
|
807
821
|
"@context: First-use hint shown over the compose editor to surface the slash command menu",
|
|
808
822
|
}),
|
|
809
823
|
),
|
|
824
|
+
tableControls: {
|
|
825
|
+
toolbarLabel: i18n._(
|
|
826
|
+
msg({
|
|
827
|
+
message: "Table controls",
|
|
828
|
+
comment: "@context: Accessible label for the compose table toolbar",
|
|
829
|
+
}),
|
|
830
|
+
),
|
|
831
|
+
addRowAbove: i18n._(
|
|
832
|
+
msg({
|
|
833
|
+
message: "Add row above",
|
|
834
|
+
comment: "@context: Compose table action",
|
|
835
|
+
}),
|
|
836
|
+
),
|
|
837
|
+
addRowBelow: i18n._(
|
|
838
|
+
msg({
|
|
839
|
+
message: "Add row below",
|
|
840
|
+
comment: "@context: Compose table action",
|
|
841
|
+
}),
|
|
842
|
+
),
|
|
843
|
+
addColumnBefore: i18n._(
|
|
844
|
+
msg({
|
|
845
|
+
message: "Add column before",
|
|
846
|
+
comment: "@context: Compose table action",
|
|
847
|
+
}),
|
|
848
|
+
),
|
|
849
|
+
addColumnAfter: i18n._(
|
|
850
|
+
msg({
|
|
851
|
+
message: "Add column after",
|
|
852
|
+
comment: "@context: Compose table action",
|
|
853
|
+
}),
|
|
854
|
+
),
|
|
855
|
+
options: i18n._(
|
|
856
|
+
msg({
|
|
857
|
+
message: "Table options",
|
|
858
|
+
comment: "@context: Compose table menu button label",
|
|
859
|
+
}),
|
|
860
|
+
),
|
|
861
|
+
deleteRow: i18n._(
|
|
862
|
+
msg({
|
|
863
|
+
message: "Delete row",
|
|
864
|
+
comment: "@context: Compose table action",
|
|
865
|
+
}),
|
|
866
|
+
),
|
|
867
|
+
deleteColumn: i18n._(
|
|
868
|
+
msg({
|
|
869
|
+
message: "Delete column",
|
|
870
|
+
comment: "@context: Compose table action",
|
|
871
|
+
}),
|
|
872
|
+
),
|
|
873
|
+
toggleHeaderRow: i18n._(
|
|
874
|
+
msg({
|
|
875
|
+
message: "Toggle header row",
|
|
876
|
+
comment: "@context: Compose table action",
|
|
877
|
+
}),
|
|
878
|
+
),
|
|
879
|
+
deleteTable: i18n._(
|
|
880
|
+
msg({
|
|
881
|
+
message: "Delete table",
|
|
882
|
+
comment: "@context: Destructive compose table action",
|
|
883
|
+
}),
|
|
884
|
+
),
|
|
885
|
+
sizePickerLabel: i18n._(
|
|
886
|
+
msg({
|
|
887
|
+
message: "Choose table size",
|
|
888
|
+
comment: "@context: Accessible title for the table dimension picker",
|
|
889
|
+
}),
|
|
890
|
+
),
|
|
891
|
+
insertTableSize: i18n._(
|
|
892
|
+
msg({
|
|
893
|
+
message: "Insert %rows% by %cols% table",
|
|
894
|
+
comment:
|
|
895
|
+
"@context: Accessible label for a table size option. %rows% and %cols% are replaced with dimensions",
|
|
896
|
+
}),
|
|
897
|
+
),
|
|
898
|
+
},
|
|
810
899
|
collectionFormLabels: getCollectionFormLabels(i18n),
|
|
811
|
-
}
|
|
900
|
+
} satisfies ComposeLabels;
|
|
901
|
+
const labels = JSON.stringify(labelsObject).replace(/</g, "\\u003c");
|
|
812
902
|
|
|
813
903
|
const collectionsJson = JSON.stringify(
|
|
814
904
|
(collections ?? []).map((c) => ({
|
|
@@ -17,7 +17,9 @@ import type {
|
|
|
17
17
|
NavManagerSuggestedLink,
|
|
18
18
|
SystemNavConfig,
|
|
19
19
|
} from "../../../client/components/nav-manager-types.js";
|
|
20
|
+
import type { CollectionFormLabels } from "../../../client/components/collection-types.js";
|
|
20
21
|
import { toPublicHref, toPublicPath } from "../../../lib/url.js";
|
|
22
|
+
import { getCollectionFormLabels } from "../../shared/collection-management-labels.js";
|
|
21
23
|
import {
|
|
22
24
|
getNavItemDisplayLabel,
|
|
23
25
|
getSystemNavDescription,
|
|
@@ -34,6 +36,7 @@ export function NavigationContent({
|
|
|
34
36
|
directoryData,
|
|
35
37
|
suggestedLinks,
|
|
36
38
|
mainRssFeed,
|
|
39
|
+
rssFeedsEnabled,
|
|
37
40
|
siteName,
|
|
38
41
|
sitePathPrefix = "",
|
|
39
42
|
}: {
|
|
@@ -41,6 +44,7 @@ export function NavigationContent({
|
|
|
41
44
|
directoryData: CollectionsDirectoryData;
|
|
42
45
|
suggestedLinks: SuggestedNavLink[];
|
|
43
46
|
mainRssFeed: string;
|
|
47
|
+
rssFeedsEnabled: boolean;
|
|
44
48
|
siteName: string;
|
|
45
49
|
sitePathPrefix?: string;
|
|
46
50
|
}) {
|
|
@@ -64,6 +68,90 @@ export function NavigationContent({
|
|
|
64
68
|
}),
|
|
65
69
|
);
|
|
66
70
|
const moreLabel = i18n._(NAV_MORE_LABEL);
|
|
71
|
+
const createCollectionLabel = i18n._(
|
|
72
|
+
msg({
|
|
73
|
+
message: "Create Collection",
|
|
74
|
+
comment:
|
|
75
|
+
"@context: Button and dialog title for quick collection creation in Navigation settings",
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
const collectionFormLabels: CollectionFormLabels = {
|
|
79
|
+
...getCollectionFormLabels(i18n),
|
|
80
|
+
titleLabel: i18n._(
|
|
81
|
+
msg({
|
|
82
|
+
message: "Title",
|
|
83
|
+
comment: "@context: Collection title field in Navigation settings",
|
|
84
|
+
}),
|
|
85
|
+
),
|
|
86
|
+
titlePlaceholder: i18n._(
|
|
87
|
+
msg({
|
|
88
|
+
message: "My Collection",
|
|
89
|
+
comment:
|
|
90
|
+
"@context: Collection title placeholder in Navigation settings",
|
|
91
|
+
}),
|
|
92
|
+
),
|
|
93
|
+
slugLabel: i18n._(
|
|
94
|
+
msg({
|
|
95
|
+
message: "Collection link",
|
|
96
|
+
comment: "@context: Collection slug field in Navigation settings",
|
|
97
|
+
}),
|
|
98
|
+
),
|
|
99
|
+
slugHelp: i18n._(
|
|
100
|
+
msg({
|
|
101
|
+
message: "This is the last part of the collection link.",
|
|
102
|
+
comment: "@context: Collection slug help text in Navigation settings",
|
|
103
|
+
}),
|
|
104
|
+
),
|
|
105
|
+
slugInvalidHelp: i18n._(
|
|
106
|
+
msg({
|
|
107
|
+
message: "Use lowercase letters, numbers, and hyphens only.",
|
|
108
|
+
comment:
|
|
109
|
+
"@context: Collection slug validation error in Navigation settings",
|
|
110
|
+
}),
|
|
111
|
+
),
|
|
112
|
+
slugReservedHelp: i18n._(
|
|
113
|
+
msg({
|
|
114
|
+
message: "This link is reserved. Choose something else.",
|
|
115
|
+
comment:
|
|
116
|
+
"@context: Reserved collection slug error in Navigation settings",
|
|
117
|
+
}),
|
|
118
|
+
),
|
|
119
|
+
slugTooLongHelp: i18n._(
|
|
120
|
+
msg({
|
|
121
|
+
message: "Keep this link under 200 characters.",
|
|
122
|
+
comment: "@context: Long collection slug error in Navigation settings",
|
|
123
|
+
}),
|
|
124
|
+
),
|
|
125
|
+
editSlugLabel: i18n._(
|
|
126
|
+
msg({
|
|
127
|
+
message: "Edit link",
|
|
128
|
+
comment:
|
|
129
|
+
"@context: Button to edit the generated collection slug in Navigation settings",
|
|
130
|
+
}),
|
|
131
|
+
),
|
|
132
|
+
resetSlugLabel: i18n._(
|
|
133
|
+
msg({
|
|
134
|
+
message: "Reset link",
|
|
135
|
+
comment:
|
|
136
|
+
"@context: Button to reset the collection slug in Navigation settings",
|
|
137
|
+
}),
|
|
138
|
+
),
|
|
139
|
+
quickHint: i18n._(
|
|
140
|
+
msg({
|
|
141
|
+
message: "More options are available after you create it.",
|
|
142
|
+
comment:
|
|
143
|
+
"@context: Helper text in quick collection creation in Navigation settings",
|
|
144
|
+
}),
|
|
145
|
+
),
|
|
146
|
+
quickSubmitLabel: createCollectionLabel,
|
|
147
|
+
createdLabel: i18n._(
|
|
148
|
+
msg({
|
|
149
|
+
message: "Collection created.",
|
|
150
|
+
comment:
|
|
151
|
+
"@context: Heading after quick collection creation in Navigation settings",
|
|
152
|
+
}),
|
|
153
|
+
),
|
|
154
|
+
};
|
|
67
155
|
|
|
68
156
|
const suggestedTargetLabels = {
|
|
69
157
|
page: i18n._(
|
|
@@ -98,6 +186,7 @@ export function NavigationContent({
|
|
|
98
186
|
type: item.type,
|
|
99
187
|
systemKey: item.systemKey,
|
|
100
188
|
collectionId: item.collectionId,
|
|
189
|
+
postId: item.postId,
|
|
101
190
|
label: item.label,
|
|
102
191
|
displayLabel: getNavItemDisplayLabel(item, i18n, sitePathPrefix),
|
|
103
192
|
url,
|
|
@@ -185,6 +274,12 @@ export function NavigationContent({
|
|
|
185
274
|
comment: "@context: Nav item type badge",
|
|
186
275
|
}),
|
|
187
276
|
),
|
|
277
|
+
page: i18n._(
|
|
278
|
+
msg({
|
|
279
|
+
message: "page",
|
|
280
|
+
comment: "@context: Nav item type badge for page items",
|
|
281
|
+
}),
|
|
282
|
+
),
|
|
188
283
|
system: i18n._(
|
|
189
284
|
msg({
|
|
190
285
|
message: "system",
|
|
@@ -235,6 +330,13 @@ export function NavigationContent({
|
|
|
235
330
|
"@context: Confirm dialog for deleting a custom navigation link",
|
|
236
331
|
}),
|
|
237
332
|
),
|
|
333
|
+
confirmDeletePage: i18n._(
|
|
334
|
+
msg({
|
|
335
|
+
message:
|
|
336
|
+
"Remove this page from navigation? The page itself won't be deleted.",
|
|
337
|
+
comment: "@context: Confirm dialog for removing a page from navigation",
|
|
338
|
+
}),
|
|
339
|
+
),
|
|
238
340
|
orderSaved: i18n._(
|
|
239
341
|
msg({
|
|
240
342
|
message: "Navigation order updated.",
|
|
@@ -353,6 +455,182 @@ export function NavigationContent({
|
|
|
353
455
|
comment: "@context: Toast after adding a suggested nav link",
|
|
354
456
|
}),
|
|
355
457
|
),
|
|
458
|
+
addPageToNavigation: i18n._(
|
|
459
|
+
msg({
|
|
460
|
+
message: "Add page to navigation",
|
|
461
|
+
comment: "@context: Section heading for adding a page to navigation",
|
|
462
|
+
}),
|
|
463
|
+
),
|
|
464
|
+
addPageDescription: i18n._(
|
|
465
|
+
msg({
|
|
466
|
+
message:
|
|
467
|
+
"Choose a titled note that isn't already in navigation, or create a new page.",
|
|
468
|
+
comment: "@context: Description for adding a page to navigation",
|
|
469
|
+
}),
|
|
470
|
+
),
|
|
471
|
+
addPage: i18n._(
|
|
472
|
+
msg({
|
|
473
|
+
message: "Add Page",
|
|
474
|
+
comment: "@context: Button that opens the navigation page picker",
|
|
475
|
+
}),
|
|
476
|
+
),
|
|
477
|
+
searchPages: i18n._(
|
|
478
|
+
msg({
|
|
479
|
+
message: "Search pages",
|
|
480
|
+
comment: "@context: Placeholder for the navigation page search",
|
|
481
|
+
}),
|
|
482
|
+
),
|
|
483
|
+
recentPages: i18n._(
|
|
484
|
+
msg({
|
|
485
|
+
message: "Recently updated",
|
|
486
|
+
comment: "@context: Heading above recent pages in the page picker",
|
|
487
|
+
}),
|
|
488
|
+
),
|
|
489
|
+
searchingPages: i18n._(
|
|
490
|
+
msg({
|
|
491
|
+
message: "Searching pages…",
|
|
492
|
+
comment: "@context: Loading state in the navigation page picker",
|
|
493
|
+
}),
|
|
494
|
+
),
|
|
495
|
+
noMatchingPages: i18n._(
|
|
496
|
+
msg({
|
|
497
|
+
message:
|
|
498
|
+
"No matching pages available to add. Try another title or create a new page.",
|
|
499
|
+
comment: "@context: Empty search results in the page picker",
|
|
500
|
+
}),
|
|
501
|
+
),
|
|
502
|
+
noPages: i18n._(
|
|
503
|
+
msg({
|
|
504
|
+
message: "No pages available. Create one to add it to navigation.",
|
|
505
|
+
comment: "@context: Empty state in the navigation page picker",
|
|
506
|
+
}),
|
|
507
|
+
),
|
|
508
|
+
pageSearchFailed: i18n._(
|
|
509
|
+
msg({
|
|
510
|
+
message: "Couldn't load pages. Try again in a moment.",
|
|
511
|
+
comment: "@context: Error shown when navigation page search fails",
|
|
512
|
+
}),
|
|
513
|
+
),
|
|
514
|
+
createNewPage: i18n._(
|
|
515
|
+
msg({
|
|
516
|
+
message: "Create new page",
|
|
517
|
+
comment: "@context: Action at the bottom of the navigation page picker",
|
|
518
|
+
}),
|
|
519
|
+
),
|
|
520
|
+
createPage: i18n._(
|
|
521
|
+
msg({
|
|
522
|
+
message: "Create Page",
|
|
523
|
+
comment: "@context: Button and dialog title for quick page creation",
|
|
524
|
+
}),
|
|
525
|
+
),
|
|
526
|
+
createPageDescription: i18n._(
|
|
527
|
+
msg({
|
|
528
|
+
message: "Create a public page that won't appear in Latest.",
|
|
529
|
+
comment: "@context: Description in the quick-create page dialog",
|
|
530
|
+
}),
|
|
531
|
+
),
|
|
532
|
+
pageTitle: i18n._(
|
|
533
|
+
msg({
|
|
534
|
+
message: "Title",
|
|
535
|
+
comment: "@context: Title field label in quick page creation",
|
|
536
|
+
}),
|
|
537
|
+
),
|
|
538
|
+
pageAddress: i18n._(
|
|
539
|
+
msg({
|
|
540
|
+
message: "Page address",
|
|
541
|
+
comment: "@context: Slug field label in quick page creation",
|
|
542
|
+
}),
|
|
543
|
+
),
|
|
544
|
+
pageVisibilityHint: i18n._(
|
|
545
|
+
msg({
|
|
546
|
+
message: "The page is public but stays out of Latest.",
|
|
547
|
+
comment: "@context: Visibility note in quick page creation",
|
|
548
|
+
}),
|
|
549
|
+
),
|
|
550
|
+
titleRequired: i18n._(
|
|
551
|
+
msg({
|
|
552
|
+
message: "Enter a page title.",
|
|
553
|
+
comment: "@context: Validation error for an empty quick page title",
|
|
554
|
+
}),
|
|
555
|
+
),
|
|
556
|
+
slugInvalid: i18n._(
|
|
557
|
+
msg({
|
|
558
|
+
message: "Use lowercase letters, numbers, and hyphens.",
|
|
559
|
+
comment: "@context: Validation error for an invalid page slug",
|
|
560
|
+
}),
|
|
561
|
+
),
|
|
562
|
+
slugReserved: i18n._(
|
|
563
|
+
msg({
|
|
564
|
+
message: "That address is reserved. Choose another one.",
|
|
565
|
+
comment: "@context: Validation error for a reserved page slug",
|
|
566
|
+
}),
|
|
567
|
+
),
|
|
568
|
+
slugTooLong: i18n._(
|
|
569
|
+
msg({
|
|
570
|
+
message: "Keep the page address under 200 characters.",
|
|
571
|
+
comment: "@context: Validation error for a long page slug",
|
|
572
|
+
}),
|
|
573
|
+
),
|
|
574
|
+
slugUnavailable: i18n._(
|
|
575
|
+
msg({
|
|
576
|
+
message: "That address is already in use. Choose another one.",
|
|
577
|
+
comment: "@context: Validation error for an unavailable page slug",
|
|
578
|
+
}),
|
|
579
|
+
),
|
|
580
|
+
checkingAddress: i18n._(
|
|
581
|
+
msg({
|
|
582
|
+
message: "Checking address…",
|
|
583
|
+
comment: "@context: Loading text while checking page slug availability",
|
|
584
|
+
}),
|
|
585
|
+
),
|
|
586
|
+
creatingPage: i18n._(
|
|
587
|
+
msg({
|
|
588
|
+
message: "Creating page…",
|
|
589
|
+
comment: "@context: Loading label while creating a page",
|
|
590
|
+
}),
|
|
591
|
+
),
|
|
592
|
+
createPageFailed: i18n._(
|
|
593
|
+
msg({
|
|
594
|
+
message: "Couldn't create the page. Check the details and try again.",
|
|
595
|
+
comment: "@context: Error when quick page creation fails",
|
|
596
|
+
}),
|
|
597
|
+
),
|
|
598
|
+
pageCreated: i18n._(
|
|
599
|
+
msg({
|
|
600
|
+
message: "Page created.",
|
|
601
|
+
comment: "@context: Heading after quick page creation",
|
|
602
|
+
}),
|
|
603
|
+
),
|
|
604
|
+
pageCreatedDescription: i18n._(
|
|
605
|
+
msg({
|
|
606
|
+
message: "Add it to navigation now or open the editor to add content.",
|
|
607
|
+
comment: "@context: Description after quick page creation",
|
|
608
|
+
}),
|
|
609
|
+
),
|
|
610
|
+
addToNavigation: i18n._(
|
|
611
|
+
msg({
|
|
612
|
+
message: "Add to Navigation",
|
|
613
|
+
comment: "@context: Button that adds a created page to navigation",
|
|
614
|
+
}),
|
|
615
|
+
),
|
|
616
|
+
editPage: i18n._(
|
|
617
|
+
msg({
|
|
618
|
+
message: "Edit Page",
|
|
619
|
+
comment: "@context: Button that opens a page for editing",
|
|
620
|
+
}),
|
|
621
|
+
),
|
|
622
|
+
pageAdded: i18n._(
|
|
623
|
+
msg({
|
|
624
|
+
message: "Page added to navigation.",
|
|
625
|
+
comment: "@context: Confirmation after adding a page to navigation",
|
|
626
|
+
}),
|
|
627
|
+
),
|
|
628
|
+
back: i18n._(
|
|
629
|
+
msg({
|
|
630
|
+
message: "Back",
|
|
631
|
+
comment: "@context: Button returning from page creation to page search",
|
|
632
|
+
}),
|
|
633
|
+
),
|
|
356
634
|
collection: i18n._(
|
|
357
635
|
msg({
|
|
358
636
|
message: "collection",
|
|
@@ -387,12 +665,56 @@ export function NavigationContent({
|
|
|
387
665
|
),
|
|
388
666
|
noCollections: i18n._(
|
|
389
667
|
msg({
|
|
390
|
-
message:
|
|
391
|
-
"No collections yet. Create one first, then add it to your navigation.",
|
|
668
|
+
message: "No collections yet. Create one here to add it to navigation.",
|
|
392
669
|
comment:
|
|
393
670
|
"@context: Empty state when no collections exist for nav picker",
|
|
394
671
|
}),
|
|
395
672
|
),
|
|
673
|
+
createNewCollection: i18n._(
|
|
674
|
+
msg({
|
|
675
|
+
message: "Create new collection",
|
|
676
|
+
comment:
|
|
677
|
+
"@context: Action at the bottom of the Navigation collection picker",
|
|
678
|
+
}),
|
|
679
|
+
),
|
|
680
|
+
createCollection: createCollectionLabel,
|
|
681
|
+
creatingCollection: i18n._(
|
|
682
|
+
msg({
|
|
683
|
+
message: "Creating collection…",
|
|
684
|
+
comment:
|
|
685
|
+
"@context: Loading label while creating a collection in Navigation settings",
|
|
686
|
+
}),
|
|
687
|
+
),
|
|
688
|
+
createCollectionFailed: i18n._(
|
|
689
|
+
msg({
|
|
690
|
+
message:
|
|
691
|
+
"Couldn't create the collection. Check the details and try again.",
|
|
692
|
+
comment:
|
|
693
|
+
"@context: Error when quick collection creation fails in Navigation settings",
|
|
694
|
+
}),
|
|
695
|
+
),
|
|
696
|
+
collectionCreatedDescription: i18n._(
|
|
697
|
+
msg({
|
|
698
|
+
message: "Add it to navigation now or open the editor to add details.",
|
|
699
|
+
comment:
|
|
700
|
+
"@context: Description after quick collection creation in Navigation settings",
|
|
701
|
+
}),
|
|
702
|
+
),
|
|
703
|
+
editCollection: i18n._(
|
|
704
|
+
msg({
|
|
705
|
+
message: "Edit Collection",
|
|
706
|
+
comment:
|
|
707
|
+
"@context: Button that opens a newly created collection for editing",
|
|
708
|
+
}),
|
|
709
|
+
),
|
|
710
|
+
collectionAdded: i18n._(
|
|
711
|
+
msg({
|
|
712
|
+
message: "Collection added to navigation.",
|
|
713
|
+
comment:
|
|
714
|
+
"@context: Confirmation after adding a collection to navigation",
|
|
715
|
+
}),
|
|
716
|
+
),
|
|
717
|
+
collectionFormLabels,
|
|
396
718
|
confirmDeleteCollection: i18n._(
|
|
397
719
|
msg({
|
|
398
720
|
message:
|
|
@@ -414,13 +736,19 @@ export function NavigationContent({
|
|
|
414
736
|
collections={escapeJson(collectionsData)}
|
|
415
737
|
suggested-links={escapeJson(suggestedLinksData)}
|
|
416
738
|
site-name={siteName}
|
|
739
|
+
rss-feeds-enabled={rssFeedsEnabled || undefined}
|
|
417
740
|
>
|
|
418
741
|
{/* SSR fallback: static preview until JS hydrates */}
|
|
419
742
|
{(() => {
|
|
420
|
-
const
|
|
743
|
+
const previewItems = rssFeedsEnabled
|
|
744
|
+
? navItems
|
|
745
|
+
: navItems.filter(
|
|
746
|
+
(item) => item.type !== "system" || item.systemKey !== "rss",
|
|
747
|
+
);
|
|
748
|
+
const headerNavItems = previewItems.filter(
|
|
421
749
|
(item) => item.placement !== "more",
|
|
422
750
|
);
|
|
423
|
-
const moreNavItems =
|
|
751
|
+
const moreNavItems = previewItems.filter(
|
|
424
752
|
(item) => item.placement === "more",
|
|
425
753
|
);
|
|
426
754
|
return (
|