@jant/core 0.6.16 → 0.7.0
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/README.md +11 -11
- package/bin/commands/assets/upload.js +192 -15
- package/bin/commands/import-site.js +60 -4
- package/bin/commands/reset-password.js +21 -8
- package/bin/commands/site/snapshot/export.js +1 -1
- package/bin/commands/site/snapshot/import.js +1 -1
- package/bin/lib/d1-query.js +5 -16
- package/bin/lib/node-env.js +40 -4
- package/bin/lib/site-selection.js +85 -29
- package/bin/lib/wrangler-cli.js +28 -2
- package/bin/lib/wrangler-json.js +35 -0
- package/dist/{app-C7_4oab9.js → app-K_Aa1MMn.js} +52476 -13330
- package/dist/client/.vite/manifest.json +255 -90
- package/dist/client/_assets/chunks/confirm-D7GrwsCN.js +45 -0
- package/dist/client/_assets/chunks/create-editor-CD3FhrOB.js +257 -0
- package/dist/client/_assets/chunks/{native-DpcrFAPh.js → emoji-mart-C4RpRKcU.js} +716 -1
- package/dist/client/_assets/chunks/footnote-rail-CmeoVtnU.js +1 -0
- package/dist/client/_assets/chunks/heic-to-CuP2Qlsw.js +1 -0
- package/dist/client/_assets/chunks/jant-locale-picker-DL6mIOT5.js +69 -0
- package/dist/client/_assets/chunks/lit-DW8VmJAT.js +2 -0
- package/dist/client/_assets/chunks/mediabunny-DRaCQ1r-.js +31 -0
- package/dist/client/_assets/chunks/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/client/_assets/chunks/settings-paths-BcdySNx6.js +84 -0
- package/dist/client/_assets/chunks/site-header-nav-DzXsFk05.js +1 -0
- package/dist/client/_assets/chunks/slug-format-CRXO1AL5.js +1 -0
- package/dist/client/_assets/chunks/slugify-373citbs.js +1 -0
- package/dist/client/_assets/chunks/sortable-list-CgaL2jCs.js +2 -0
- package/dist/client/_assets/chunks/types-D5iF3H1a.js +1 -0
- package/dist/client/_assets/chunks/unsafe-html-B5ZEXaxg.js +1 -0
- package/dist/client/_assets/chunks/unsafe-svg-0QCkP0vZ.js +2 -0
- package/dist/client/_assets/client-GiYENVw8.css +2 -0
- package/dist/client/_assets/client-VnFxJN7G.js +295 -0
- package/dist/client/_assets/client-auth-k8gJ6QJj.js +828 -0
- package/dist/client/_assets/client-author-DQ8R-8KR.css +2 -0
- package/dist/client/_assets/client-compose-B_kDtWkW.js +2004 -0
- package/dist/client/_assets/client-manage-M90aSTOk.js +2170 -0
- package/dist/client/_assets/client-settings-DfYs9n1F.js +1112 -0
- package/dist/{export-Dl5KCiEs.js → github-sync-BPAvT999.js} +2254 -107
- package/dist/index.js +2 -5
- package/dist/node.js +5 -7
- package/package.json +3 -3
- package/src/__tests__/auth-session-freshness.test.ts +57 -0
- package/src/__tests__/basecoat-variants.test.ts +121 -0
- package/src/__tests__/bin/assets-upload.test.ts +68 -0
- package/src/__tests__/export-hugo-build.test.ts +260 -0
- package/src/__tests__/export-service.test.ts +231 -0
- package/src/__tests__/helpers/component-css.ts +91 -0
- package/src/__tests__/helpers/db.ts +33 -0
- package/src/__tests__/helpers/export-fixtures.ts +3 -0
- package/src/__tests__/stylesheet-audience.test.ts +159 -0
- package/src/__tests__/stylesheet-breakpoints.test.ts +183 -0
- package/src/app.tsx +71 -16
- package/src/auth.ts +18 -1
- package/src/client/__tests__/collection-page-actions.test.ts +51 -2
- package/src/client/__tests__/compose-bridge-image-upload.test.ts +196 -0
- package/src/client/__tests__/compose-bridge-video-poster.test.ts +159 -0
- package/src/client/__tests__/compose-bridge.test.ts +272 -0
- package/src/client/__tests__/compose-launch.test.ts +62 -1
- package/src/client/__tests__/compose-shortcuts.test.ts +38 -9
- package/src/client/__tests__/compose-triggers.test.ts +90 -0
- package/src/client/__tests__/copy-field.test.ts +162 -0
- package/src/client/__tests__/custom-url-menu.test.ts +127 -6
- package/src/client/__tests__/image-processor.test.ts +324 -2
- package/src/client/__tests__/lazy-entries.test.ts +92 -0
- package/src/client/__tests__/media-scroll-hint.test.ts +155 -0
- package/src/client/__tests__/runtime-paths.test.ts +84 -0
- package/src/client/__tests__/smart-collection-page-actions.test.ts +158 -0
- package/src/client/__tests__/toast.test.ts +23 -0
- package/src/client/__tests__/video-processor-probe.test.ts +175 -0
- package/src/client/__tests__/video-processor.test.ts +181 -0
- package/src/client/audio-processor.ts +24 -15
- package/src/client/audio-waveform.ts +49 -0
- package/src/client/collection-dialog-host.ts +72 -0
- package/src/client/collection-navigation.ts +51 -16
- package/src/client/collection-page-actions.ts +26 -0
- package/src/client/components/__tests__/jant-collection-dialog.test.ts +329 -0
- package/src/client/components/__tests__/jant-collection-directory.test.ts +274 -10
- package/src/client/components/__tests__/jant-collection-form.test.ts +59 -178
- package/src/client/components/__tests__/jant-command-palette.test.ts +28 -0
- package/src/client/components/__tests__/jant-compose-dialog-draft-storage.test.ts +340 -0
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +1250 -53
- package/src/client/components/__tests__/jant-compose-editor.test.ts +544 -40
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +0 -1
- package/src/client/components/__tests__/jant-locale-picker.test.ts +207 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +234 -15
- package/src/client/components/__tests__/jant-post-menu.test.ts +413 -2
- package/src/client/components/__tests__/jant-post-picker.test.ts +197 -0
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +15 -12
- package/src/client/components/__tests__/jant-settings-general.test.ts +541 -172
- package/src/client/components/__tests__/jant-settings-language.test.ts +851 -0
- package/src/client/components/__tests__/jant-smart-collection-dialog.test.ts +665 -0
- package/src/client/components/collection-dialog-types.ts +49 -0
- package/src/client/components/collection-manager-types.ts +32 -1
- package/src/client/components/collection-types.ts +1 -15
- package/src/client/components/compose-types.ts +75 -1
- package/src/client/components/jant-collection-dialog.ts +722 -0
- package/src/client/components/jant-collection-directory.ts +567 -182
- package/src/client/components/jant-collection-form.ts +53 -232
- package/src/client/components/jant-command-palette.ts +100 -49
- package/src/client/components/jant-compose-dialog.ts +1486 -707
- package/src/client/components/jant-compose-editor.ts +673 -336
- package/src/client/components/jant-compose-fullscreen.ts +51 -43
- package/src/client/components/jant-config-editor.ts +65 -53
- package/src/client/components/jant-confirm-dialog.ts +13 -11
- package/src/client/components/jant-locale-picker.ts +418 -0
- package/src/client/components/jant-media-lightbox.ts +146 -136
- package/src/client/components/jant-nav-manager.ts +690 -366
- package/src/client/components/jant-post-menu.ts +1086 -282
- package/src/client/components/jant-post-picker.ts +324 -0
- package/src/client/components/jant-repo-picker.ts +138 -106
- package/src/client/components/jant-settings-avatar.ts +31 -27
- package/src/client/components/jant-settings-general.ts +617 -543
- package/src/client/components/jant-settings-language.ts +1087 -0
- package/src/client/components/jant-smart-collection-dialog.ts +1021 -0
- package/src/client/components/jant-text-preview.ts +94 -86
- package/src/client/components/nav-manager-types.ts +62 -1
- package/src/client/components/settings-types.ts +14 -29
- package/src/client/components/smart-collection-conditions.ts +285 -0
- package/src/client/components/smart-collection-dialog-types.ts +68 -0
- package/src/client/compose-bridge.ts +214 -141
- package/src/client/compose-launch.ts +76 -2
- package/src/client/compose-shortcuts.ts +6 -8
- package/src/client/compose-triggers.ts +50 -0
- package/src/client/copy-field.ts +108 -0
- package/src/client/custom-url-menu.ts +60 -4
- package/src/client/icons.ts +14 -0
- package/src/client/image-plan.ts +165 -0
- package/src/client/image-processor.ts +195 -117
- package/src/client/image-worker-client.ts +45 -0
- package/src/client/image-worker.ts +135 -0
- package/src/client/lazy-entries.ts +95 -0
- package/src/client/lazy-slugify.ts +2 -2
- package/src/client/media-scroll-hint.ts +43 -2
- package/src/client/mediabunny.ts +29 -0
- package/src/client/post-picker.ts +41 -0
- package/src/client/runtime-paths.ts +74 -1
- package/src/client/settings-bridge.ts +4 -10
- package/src/client/site-header-nav.js +18 -6
- package/src/client/smart-collection-dialog-host.ts +116 -0
- package/src/client/smart-collection-page-actions.ts +208 -0
- package/src/client/tiptap/__tests__/bubble-menu.test.ts +110 -0
- package/src/client/tiptap/__tests__/floating-position.test.ts +136 -1
- package/src/client/tiptap/__tests__/inline-image-upload.test.ts +37 -0
- package/src/client/tiptap/bubble-menu.ts +47 -16
- package/src/client/tiptap/floating-position.ts +216 -2
- package/src/client/tiptap/inline-image-upload.ts +7 -3
- package/src/client/tiptap/link-toolbar.ts +22 -9
- package/src/client/toast.ts +13 -0
- package/src/client/types/vite-worker.d.ts +12 -0
- package/src/client/upload-with-metadata.ts +3 -13
- package/src/client/video-processor.ts +351 -107
- package/src/client-auth.ts +14 -31
- package/src/client-compose.ts +19 -0
- package/src/client-manage.ts +13 -0
- package/src/client-settings.ts +14 -0
- package/src/client-site.ts +10 -3
- package/src/client.ts +4 -0
- package/src/db/__tests__/backfill-nav-label-mirrors.test.ts +149 -0
- package/src/db/__tests__/schema-enum-sources.test.ts +33 -0
- package/src/db/__tests__/smart-collection-placement.test.ts +402 -0
- package/src/db/backfills/0006_clear_mirrored_page_nav_labels.sql +31 -0
- package/src/db/migrations/0032_married_tomas.sql +3 -0
- package/src/db/migrations/0033_busy_johnny_storm.sql +198 -0
- package/src/db/migrations/0034_cheerful_rumiko_fujikawa.sql +35 -0
- package/src/db/migrations/meta/0032_snapshot.json +2582 -0
- package/src/db/migrations/meta/0033_snapshot.json +2816 -0
- package/src/db/migrations/meta/0034_snapshot.json +2816 -0
- package/src/db/migrations/meta/_journal.json +21 -0
- package/src/db/migrations/pg/0030_abandoned_nighthawk.sql +3 -0
- package/src/db/migrations/pg/0031_strong_ultimatum.sql +128 -0
- package/src/db/migrations/pg/0032_furry_multiple_man.sql +6 -0
- package/src/db/migrations/pg/meta/0030_snapshot.json +3329 -0
- package/src/db/migrations/pg/meta/0031_snapshot.json +3660 -0
- package/src/db/migrations/pg/meta/0032_snapshot.json +3660 -0
- package/src/db/migrations/pg/meta/_journal.json +21 -0
- package/src/db/pg/schema.ts +195 -27
- package/src/db/post-visibility.ts +117 -0
- package/src/db/schema.ts +222 -27
- package/src/i18n/__tests__/detect.test.ts +26 -81
- package/src/i18n/__tests__/supported-locales.test.ts +83 -0
- package/src/i18n/context.tsx +12 -2
- package/src/i18n/detect.ts +7 -66
- package/src/i18n/locales/glossary.zh-Hans.yml +44 -4
- package/src/i18n/locales/glossary.zh-Hant.yml +44 -4
- package/src/i18n/locales/public/en.po +490 -158
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +487 -155
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +487 -155
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/i18n/locales/settings/en.po +551 -69
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +597 -115
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +610 -128
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/i18n/locales.ts +94 -0
- package/src/i18n/middleware.ts +12 -2
- package/src/i18n/supported-locales.ts +80 -0
- package/src/lib/__tests__/api-settings.test.ts +11 -2
- package/src/lib/__tests__/asset-path.test.ts +92 -0
- package/src/lib/__tests__/deferred.test.ts +90 -0
- package/src/lib/__tests__/discover-ping.test.ts +89 -0
- package/src/lib/__tests__/discover.test.ts +410 -0
- package/src/lib/__tests__/feed-policy.test.ts +26 -0
- package/src/lib/__tests__/feed.test.ts +1526 -15
- package/src/lib/__tests__/filter-dimensions.test.ts +341 -0
- package/src/lib/__tests__/hosted-signin.test.ts +1 -1
- package/src/lib/__tests__/http-cache.test.ts +162 -0
- package/src/lib/__tests__/jant-docs-dev.test.ts +21 -0
- package/src/lib/__tests__/jant-docs.test.ts +23 -0
- package/src/lib/__tests__/lang-detect.test.ts +231 -0
- package/src/lib/__tests__/media-helpers.test.ts +81 -0
- package/src/lib/__tests__/navigation.test.ts +135 -1
- package/src/lib/__tests__/resolve-config.test.ts +64 -3
- package/src/lib/__tests__/schemas.test.ts +42 -4
- package/src/lib/__tests__/site-unavailable-page.test.ts +25 -0
- package/src/lib/__tests__/slug.test.ts +70 -0
- package/src/lib/__tests__/slugify.test.ts +85 -0
- package/src/lib/__tests__/storage.test.ts +32 -0
- package/src/lib/__tests__/thread-fold.test.ts +113 -0
- package/src/lib/__tests__/upload-sideload.test.ts +14 -0
- package/src/lib/__tests__/url-fetch.test.ts +1 -2
- package/src/lib/__tests__/url.test.ts +78 -72
- package/src/lib/__tests__/view-language.test.ts +413 -0
- package/src/lib/__tests__/worker-response-cache.test.ts +90 -0
- package/src/lib/address.ts +57 -0
- package/src/lib/api-posts.ts +12 -0
- package/src/lib/asset-path.ts +98 -1
- package/src/lib/build-env.ts +16 -0
- package/src/lib/collection-groups.ts +5 -1
- package/src/lib/collection-paths.ts +3 -10
- package/src/lib/constants.ts +28 -3
- package/src/lib/copy-field.ts +36 -0
- package/src/lib/crypto.ts +40 -0
- package/src/lib/csp-builder.ts +2 -1
- package/src/lib/deferred.ts +79 -0
- package/src/lib/discover-ping.ts +141 -0
- package/src/lib/discover.ts +437 -0
- package/src/lib/env.ts +134 -0
- package/src/lib/errors.ts +33 -0
- package/src/lib/feed-policy.ts +236 -2
- package/src/lib/feed.ts +926 -73
- package/src/lib/filter-dimensions.ts +1349 -0
- package/src/lib/github-sync-site-config.ts +3 -0
- package/src/lib/hosted-signin.ts +1 -1
- package/src/lib/http-cache.ts +148 -0
- package/src/lib/hugo-markdown.ts +16 -0
- package/src/lib/icons.ts +9 -2
- package/src/lib/ids.ts +3 -0
- package/src/lib/jant-docs.ts +42 -0
- package/src/lib/lang-detect.ts +308 -0
- package/src/lib/media-helpers.ts +13 -1
- package/src/lib/navigation.ts +78 -11
- package/src/lib/pagination.ts +28 -24
- package/src/lib/per-language-surfaces.ts +67 -0
- package/src/lib/post-meta.ts +19 -0
- package/src/lib/render.tsx +55 -7
- package/src/lib/resolve-config.ts +53 -5
- package/src/lib/schemas.ts +201 -10
- package/src/lib/site-header-fragment.tsx +2 -1
- package/src/lib/site-unavailable-page.ts +47 -0
- package/src/lib/slug.ts +51 -7
- package/src/lib/slugify.ts +113 -0
- package/src/lib/startup-config.ts +4 -6
- package/src/lib/storage.ts +7 -0
- package/src/lib/summary.ts +50 -0
- package/src/lib/thread-fold.ts +161 -0
- package/src/lib/time.ts +32 -0
- package/src/lib/timeline.ts +42 -1
- package/src/lib/tiptap-render.ts +1 -2
- package/src/lib/upload.ts +16 -13
- package/src/lib/url.ts +139 -86
- package/src/lib/version.ts +10 -8
- package/src/lib/view-language.ts +436 -0
- package/src/lib/view.ts +51 -23
- package/src/lib/viewer-context.ts +62 -0
- package/src/middleware/__tests__/auth.test.ts +70 -2
- package/src/middleware/__tests__/cache-control.test.ts +71 -3
- package/src/middleware/__tests__/onboarding.test.ts +76 -5
- package/src/middleware/__tests__/secure-headers.test.ts +1 -1
- package/src/middleware/__tests__/session.test.ts +181 -33
- package/src/middleware/auth.ts +50 -31
- package/src/middleware/cache-control.ts +75 -10
- package/src/middleware/config.ts +6 -6
- package/src/middleware/error-handler.ts +12 -0
- package/src/middleware/onboarding.ts +32 -10
- package/src/middleware/secure-headers.ts +1 -1
- package/src/middleware/session.ts +96 -8
- package/src/node/__tests__/cli-migrate.test.ts +21 -19
- package/src/node/__tests__/cli-reset-password.test.ts +81 -8
- package/src/node/__tests__/cli-runtime-target.test.ts +48 -1
- package/src/node/__tests__/cli-site-selection.test.ts +128 -38
- package/src/node/__tests__/runtime.test.ts +37 -0
- package/src/node/index.ts +1 -0
- package/src/preset.css +76 -22
- package/src/routes/__tests__/feed-validator.test.ts +156 -0
- package/src/routes/api/__tests__/collections.test.ts +114 -0
- package/src/routes/api/__tests__/discover.test.ts +222 -0
- package/src/routes/api/__tests__/nav-items.test.ts +212 -2
- package/src/routes/api/__tests__/post-translations.test.ts +829 -0
- package/src/routes/api/__tests__/settings.test.ts +24 -3
- package/src/routes/api/__tests__/telegram.test.ts +6 -5
- package/src/routes/api/collections.ts +49 -6
- package/src/routes/api/custom-urls.ts +0 -1
- package/src/routes/api/discover.ts +95 -0
- package/src/routes/api/export.ts +3 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +42 -2
- package/src/routes/api/nav-items.ts +55 -8
- package/src/routes/api/posts.ts +159 -0
- package/src/routes/api/public/__tests__/archive.test.ts +111 -0
- package/src/routes/api/public/archive.ts +77 -81
- package/src/routes/api/public/posts.ts +23 -6
- package/src/routes/api/smart-collections.ts +132 -0
- package/src/routes/api/telegram.ts +2 -40
- package/src/routes/api/uploads.ts +1 -2
- package/src/routes/auth/__tests__/setup-auth.test.ts +137 -0
- package/src/routes/auth/__tests__/setup-discover.test.ts +204 -0
- package/src/routes/auth/__tests__/setup-flow.test.ts +270 -0
- package/src/routes/auth/__tests__/setup-page.test.tsx +329 -0
- package/src/routes/auth/__tests__/setup-steps.test.ts +310 -0
- package/src/routes/auth/__tests__/setup.test.ts +278 -26
- package/src/routes/auth/__tests__/signin.test.ts +135 -0
- package/src/routes/auth/setup.tsx +934 -186
- package/src/routes/auth/signin.tsx +10 -8
- package/src/routes/compose.tsx +5 -0
- package/src/routes/dash/__tests__/custom-urls-archive.test.ts +44 -0
- package/src/routes/dash/__tests__/custom-urls-page.test.ts +49 -0
- package/src/routes/dash/__tests__/delete-account.test.ts +106 -0
- package/src/routes/dash/__tests__/settings-discover.test.ts +213 -0
- package/src/routes/dash/custom-urls.tsx +1 -37
- package/src/routes/dash/settings.tsx +502 -41
- package/src/routes/discover-announce.ts +96 -0
- package/src/routes/feed/__tests__/feed.test.ts +165 -2
- package/src/routes/feed/feed.ts +69 -40
- package/src/routes/feed/sitemap.ts +95 -11
- package/src/routes/pages/__tests__/archive-indexing.test.ts +200 -0
- package/src/routes/pages/__tests__/archive-params.test.ts +370 -6
- package/src/routes/pages/__tests__/collection-routing.test.ts +16 -0
- package/src/routes/pages/__tests__/collections-feed-links.test.ts +72 -0
- package/src/routes/pages/__tests__/collections.test.ts +9 -3
- package/src/routes/pages/__tests__/custom-archive-url.test.ts +119 -0
- package/src/routes/pages/__tests__/feed-autodiscovery.test.ts +148 -0
- package/src/routes/pages/__tests__/language-routing.test.ts +679 -0
- package/src/routes/pages/__tests__/post-preview-partial.test.ts +96 -0
- package/src/routes/pages/__tests__/smart-collection.test.ts +298 -0
- package/src/routes/pages/__tests__/subscribe.test.ts +248 -0
- package/src/routes/pages/archive.tsx +471 -369
- package/src/routes/pages/collection.tsx +94 -96
- package/src/routes/pages/collections.tsx +38 -50
- package/src/routes/pages/featured.tsx +32 -13
- package/src/routes/pages/home.tsx +25 -6
- package/src/routes/pages/language.tsx +113 -0
- package/src/routes/pages/latest.tsx +26 -16
- package/src/routes/pages/new.tsx +3 -0
- package/src/routes/pages/page.tsx +178 -17
- package/src/routes/pages/partials.tsx +41 -0
- package/src/routes/pages/search.tsx +18 -3
- package/src/routes/pages/smart-collection.tsx +340 -0
- package/src/routes/pages/subscribe.tsx +182 -0
- package/src/runtime/__tests__/index.test.ts +19 -0
- package/src/runtime/__tests__/node.test.ts +129 -4
- package/src/runtime/cloudflare.ts +21 -2
- package/src/runtime/index.ts +27 -1
- package/src/runtime/node.ts +18 -1
- package/src/runtime/site.ts +95 -24
- package/src/services/__tests__/auth.test.ts +116 -7
- package/src/services/__tests__/collection.test.ts +108 -4
- package/src/services/__tests__/language.test.ts +495 -0
- package/src/services/__tests__/navigation.test.ts +213 -10
- package/src/services/__tests__/path.test.ts +180 -0
- package/src/services/__tests__/post-language.test.ts +830 -0
- package/src/services/__tests__/post.test.ts +46 -9
- package/src/services/__tests__/settings.test.ts +228 -17
- package/src/services/__tests__/site-admin.test.ts +5 -5
- package/src/services/__tests__/smart-collection.test.ts +651 -0
- package/src/services/about-page.ts +22 -1
- package/src/services/auth.ts +51 -49
- package/src/services/bootstrap.ts +188 -38
- package/src/services/collection-directory-position.ts +76 -0
- package/src/services/collection.ts +331 -46
- package/src/services/custom-url.ts +27 -22
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export-theme/assets/client-site.js +123 -123
- package/src/services/export-theme/layouts/_default/rss.xml +77 -1
- package/src/services/export-theme/layouts/partials/feed-post-content.xml +105 -2
- package/src/services/export-theme/layouts/partials/media-gallery.html +35 -21
- package/src/services/export-theme/layouts/partials/pagination.html +14 -13
- package/src/services/export-theme/layouts/partials/post-card.html +8 -4
- package/src/services/export-theme/layouts/partials/reply.html +2 -1
- package/src/services/export-theme/layouts/partials/thread-preview.html +40 -30
- package/src/services/export-theme/styles/main.css +13 -1
- package/src/services/export.ts +278 -19
- package/src/services/index.ts +34 -3
- package/src/services/language.ts +412 -0
- package/src/services/mcp.ts +3 -1
- package/src/services/media.ts +14 -6
- package/src/services/navigation.ts +429 -67
- package/src/services/path.ts +221 -6
- package/src/services/post.ts +1021 -152
- package/src/services/search.ts +39 -2
- package/src/services/settings.ts +238 -43
- package/src/services/site-admin.ts +24 -7
- package/src/services/site.ts +77 -1
- package/src/services/smart-collection.ts +636 -0
- package/src/services/telegram.ts +20 -22
- package/src/services/upload-session.ts +1 -3
- package/src/style-author.css +27 -0
- package/src/styles/components-author.css +1622 -0
- package/src/styles/components.css +24 -1571
- package/src/styles/site-media.css +16 -2
- package/src/styles/tokens.css +82 -12
- package/src/styles/ui-author.css +7602 -0
- package/src/styles/ui.css +1087 -7219
- package/src/types/app-context.ts +7 -0
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +94 -15
- package/src/types/constants.ts +188 -16
- package/src/types/entities.ts +87 -1
- package/src/types/operations.ts +64 -2
- package/src/types/props.ts +157 -31
- package/src/types/views.ts +55 -1
- package/src/ui/__tests__/font-themes.test.ts +52 -12
- package/src/ui/compose/ComposeDialog.tsx +201 -7
- package/src/ui/compose/ComposePrompt.tsx +1 -5
- package/src/ui/compose/__tests__/ComposeDialog.test.tsx +125 -0
- package/src/ui/dash/appearance/AdvancedContent.tsx +2 -2
- package/src/ui/dash/appearance/CodeInjectionContent.tsx +12 -16
- package/src/ui/dash/appearance/NavigationContent.tsx +117 -16
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +33 -11
- package/src/ui/dash/appearance/__tests__/system-nav-descriptions.test.ts +44 -0
- package/src/ui/dash/appearance/system-nav-descriptions.ts +75 -0
- package/src/ui/dash/settings/AccountMenuContent.tsx +2 -2
- package/src/ui/dash/settings/ApiTokensContent.tsx +2 -1
- package/src/ui/dash/settings/ConfigEditorContent.tsx +35 -16
- package/src/ui/dash/settings/GeneralContent.tsx +275 -113
- package/src/ui/dash/settings/LanguageContent.tsx +409 -0
- package/src/ui/dash/settings/SettingsRootContent.tsx +19 -1
- package/src/ui/dash/settings/__tests__/GeneralContent.test.tsx +324 -4
- package/src/ui/dash/settings/__tests__/LanguageContent.test.tsx +144 -0
- package/src/ui/dash/settings/__tests__/discover-copy.test.ts +66 -0
- package/src/ui/dash/settings/discover-copy.ts +116 -0
- package/src/ui/feed/LinkCard.tsx +55 -45
- package/src/ui/feed/NoteCard.tsx +9 -4
- package/src/ui/feed/PostStatusBadges.tsx +90 -43
- package/src/ui/feed/QuoteCard.tsx +55 -30
- package/src/ui/feed/ThreadPreview.tsx +6 -2
- package/src/ui/feed/__tests__/thread-preview.test.ts +13 -16
- package/src/ui/feed/__tests__/timeline-cards.test.ts +314 -49
- package/src/ui/feed/thread-preview-state.ts +20 -6
- package/src/ui/font-themes.ts +39 -29
- package/src/ui/layouts/BaseLayout.tsx +155 -10
- package/src/ui/layouts/SiteLayout.tsx +192 -34
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +196 -17
- package/src/ui/layouts/__tests__/SiteLayout.test.tsx +109 -85
- package/src/ui/pages/ArchivePage.tsx +282 -289
- package/src/ui/pages/CollectionPage.tsx +86 -76
- package/src/ui/pages/CollectionsPage.tsx +5 -0
- package/src/ui/pages/ComposePage.tsx +8 -0
- package/src/ui/pages/PostPage.tsx +47 -0
- package/src/ui/pages/SearchPage.tsx +3 -3
- package/src/ui/pages/SmartCollectionPage.tsx +434 -0
- package/src/ui/pages/SubscribePage.tsx +236 -0
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +65 -9
- package/src/ui/pages/__tests__/collections-directory-rows.test.tsx +92 -0
- package/src/ui/pages/__tests__/collections-view-links.test.tsx +81 -0
- package/src/ui/shared/CollectionDirectory.tsx +178 -3
- package/src/ui/shared/CollectionsManager.tsx +70 -17
- package/src/ui/shared/CopyField.tsx +127 -0
- package/src/ui/shared/EmptyPostContent.tsx +23 -0
- package/src/ui/shared/MediaGallery.tsx +125 -46
- package/src/ui/shared/Pagination.tsx +20 -5
- package/src/ui/shared/PostFooter.tsx +20 -11
- package/src/ui/shared/__tests__/archive-labels.test.ts +100 -0
- package/src/ui/shared/__tests__/media-gallery.test.ts +210 -2
- package/src/ui/shared/__tests__/navigation-labels.test.ts +16 -22
- package/src/ui/shared/__tests__/pagination.test.ts +38 -24
- package/src/ui/shared/__tests__/post-footer.test.ts +32 -0
- package/src/ui/shared/archive-labels.ts +98 -0
- package/src/ui/shared/collection-management-labels.ts +94 -16
- package/src/ui/shared/navigation-labels.ts +45 -71
- package/src/ui/shared/post-article-attributes.ts +2 -0
- package/src/ui/shared/smart-collection-labels.ts +343 -0
- package/dist/app-C75Zc8dD.js +0 -6
- package/dist/client/_assets/chunks/heic-to-DUUaO23q.js +0 -1
- package/dist/client/_assets/chunks/module-DcsAZQZ_.js +0 -716
- package/dist/client/_assets/chunks/url-CU9pEbk5.js +0 -1
- package/dist/client/_assets/client-Bq0vre8Y.js +0 -296
- package/dist/client/_assets/client-D3VZyG4L.css +0 -2
- package/dist/client/_assets/client-auth-F2rb9WfF.js +0 -5571
- package/dist/env-BPYViDJJ.js +0 -281
- package/dist/github-api-BNF35Lkx.js +0 -176
- package/dist/github-app-DdiD-bC4.js +0 -275
- package/dist/github-sync-Bqg62IvV.js +0 -4
- package/dist/github-sync-HdK2EgvJ.js +0 -431
- package/dist/url-CbLAtlZe.js +0 -900
- package/src/client/__tests__/collection-created-notice.test.ts +0 -36
- package/src/client/__tests__/collection-form-bridge.test.ts +0 -216
- package/src/client/__tests__/post-form-bridge.test.ts +0 -82
- package/src/client/collection-created-notice.ts +0 -66
- package/src/client/collection-form-bridge.ts +0 -191
- package/src/client/components/__tests__/jant-post-form.test.ts +0 -193
- package/src/client/components/jant-post-form.ts +0 -422
- package/src/client/components/post-form-template.ts +0 -352
- package/src/client/components/post-form-types.ts +0 -96
- package/src/client/media-metadata.ts +0 -247
- package/src/client/post-form-bridge.ts +0 -193
- package/src/ui/pages/CollectionEditorPage.tsx +0 -175
|
@@ -11,6 +11,8 @@ import type {
|
|
|
11
11
|
SystemNavKey,
|
|
12
12
|
} from "../../../types.js";
|
|
13
13
|
import { SYSTEM_NAV_KEYS } from "../../../types.js";
|
|
14
|
+
import { getSystemNavDescription } from "./system-nav-descriptions.js";
|
|
15
|
+
import { getSmartCollectionLabels } from "../../shared/smart-collection-labels.js";
|
|
14
16
|
import type {
|
|
15
17
|
NavManagerCollection,
|
|
16
18
|
NavManagerLabels,
|
|
@@ -19,10 +21,12 @@ import type {
|
|
|
19
21
|
} from "../../../client/components/nav-manager-types.js";
|
|
20
22
|
import type { CollectionFormLabels } from "../../../client/components/collection-types.js";
|
|
21
23
|
import { toPublicHref, toPublicPath } from "../../../lib/url.js";
|
|
22
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
getCollectionDialogLabels,
|
|
26
|
+
getCollectionFormLabels,
|
|
27
|
+
} from "../../shared/collection-management-labels.js";
|
|
23
28
|
import {
|
|
24
29
|
getNavItemDisplayLabel,
|
|
25
|
-
getSystemNavDescription,
|
|
26
30
|
getSystemNavDisplayLabel,
|
|
27
31
|
NAV_MORE_LABEL,
|
|
28
32
|
} from "../../shared/navigation-labels.js";
|
|
@@ -210,16 +214,35 @@ export function NavigationContent({
|
|
|
210
214
|
slug: item.collection.slug,
|
|
211
215
|
group: currentGroup,
|
|
212
216
|
});
|
|
217
|
+
} else if (item.type === "smart_collection" && item.smartCollection) {
|
|
218
|
+
result.push({
|
|
219
|
+
id: item.smartCollection.id,
|
|
220
|
+
title: item.smartCollection.title,
|
|
221
|
+
slug: item.smartCollection.slug,
|
|
222
|
+
group: currentGroup,
|
|
223
|
+
isSmart: true,
|
|
224
|
+
});
|
|
213
225
|
}
|
|
214
226
|
}
|
|
215
227
|
|
|
216
|
-
// Append
|
|
228
|
+
// Append anything with no directory row, both kinds alike.
|
|
217
229
|
const includedIds = new Set(result.map((c) => c.id));
|
|
218
230
|
for (const c of directoryData.collections) {
|
|
219
231
|
if (!includedIds.has(c.id)) {
|
|
220
232
|
result.push({ id: c.id, title: c.title, slug: c.slug, group: null });
|
|
221
233
|
}
|
|
222
234
|
}
|
|
235
|
+
for (const c of directoryData.smartCollections) {
|
|
236
|
+
if (!includedIds.has(c.id)) {
|
|
237
|
+
result.push({
|
|
238
|
+
id: c.id,
|
|
239
|
+
title: c.title,
|
|
240
|
+
slug: c.slug,
|
|
241
|
+
group: null,
|
|
242
|
+
isSmart: true,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
223
246
|
|
|
224
247
|
return result;
|
|
225
248
|
})();
|
|
@@ -237,20 +260,17 @@ export function NavigationContent({
|
|
|
237
260
|
).map((key) => ({
|
|
238
261
|
key,
|
|
239
262
|
label: getSystemNavDisplayLabel(key, i18n),
|
|
240
|
-
|
|
263
|
+
// Only the RSS line takes a value: it names which end /feed currently
|
|
264
|
+
// returns. The strings live in `system-nav-descriptions.ts` so the RSS and
|
|
265
|
+
// Subscribe pair stays written — and edited — together, and so they land in
|
|
266
|
+
// the translated catalog rather than the English-only public one.
|
|
267
|
+
description: getSystemNavDescription(
|
|
268
|
+
key,
|
|
269
|
+
i18n,
|
|
241
270
|
key === "rss"
|
|
242
|
-
?
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
"Header RSS points to your {feed} feed (/feed). Change what /feed returns in General.",
|
|
246
|
-
comment:
|
|
247
|
-
"@context: Description for the RSS system navigation toggle. {feed} is either Latest or Featured.",
|
|
248
|
-
}),
|
|
249
|
-
{
|
|
250
|
-
feed: mainRssFeed === "latest" ? latestLabel : featuredLabel,
|
|
251
|
-
},
|
|
252
|
-
)
|
|
253
|
-
: getSystemNavDescription(key, i18n),
|
|
271
|
+
? { feed: mainRssFeed === "latest" ? latestLabel : featuredLabel }
|
|
272
|
+
: undefined,
|
|
273
|
+
),
|
|
254
274
|
}));
|
|
255
275
|
|
|
256
276
|
const labels: NavManagerLabels = {
|
|
@@ -406,6 +426,7 @@ export function NavigationContent({
|
|
|
406
426
|
"@context: Section label for nav items hidden under More dropdown",
|
|
407
427
|
}),
|
|
408
428
|
),
|
|
429
|
+
previewMore: moreLabel,
|
|
409
430
|
moreEmptyHint: i18n._(
|
|
410
431
|
msg({
|
|
411
432
|
message: "Drag links here to show them under the More menu",
|
|
@@ -480,12 +501,83 @@ export function NavigationContent({
|
|
|
480
501
|
comment: "@context: Placeholder for the navigation page search",
|
|
481
502
|
}),
|
|
482
503
|
),
|
|
504
|
+
searchPagesHint: i18n._(
|
|
505
|
+
msg({
|
|
506
|
+
message: "Search pages, or paste an address",
|
|
507
|
+
comment:
|
|
508
|
+
"@context: Placeholder for the navigation page search, which also accepts a pasted URL or path",
|
|
509
|
+
}),
|
|
510
|
+
),
|
|
483
511
|
recentPages: i18n._(
|
|
484
512
|
msg({
|
|
485
513
|
message: "Recently updated",
|
|
486
514
|
comment: "@context: Heading above recent pages in the page picker",
|
|
487
515
|
}),
|
|
488
516
|
),
|
|
517
|
+
addressMatch: i18n._(
|
|
518
|
+
msg({
|
|
519
|
+
message: "At that address",
|
|
520
|
+
comment:
|
|
521
|
+
"@context: Heading above the page a pasted address resolved to",
|
|
522
|
+
}),
|
|
523
|
+
),
|
|
524
|
+
addressAlreadyAdded: i18n._(
|
|
525
|
+
msg({
|
|
526
|
+
message: "Already in navigation. Drag it in the list above to move it.",
|
|
527
|
+
comment:
|
|
528
|
+
"@context: Shown when a pasted address is already a navigation item",
|
|
529
|
+
}),
|
|
530
|
+
),
|
|
531
|
+
addressNotFound: i18n._(
|
|
532
|
+
msg({
|
|
533
|
+
message: "Nothing at {address}. Check it, or search by title.",
|
|
534
|
+
comment:
|
|
535
|
+
"@context: Shown when a pasted address matches no page on the site",
|
|
536
|
+
}),
|
|
537
|
+
// Filled in the browser with the address that was looked up.
|
|
538
|
+
{ address: "{address}" },
|
|
539
|
+
),
|
|
540
|
+
addressUnpublished: i18n._(
|
|
541
|
+
msg({
|
|
542
|
+
message: "That page is a draft. Publish it, then add it.",
|
|
543
|
+
comment: "@context: Shown when a pasted address resolves to a draft",
|
|
544
|
+
}),
|
|
545
|
+
),
|
|
546
|
+
addressPrivate: i18n._(
|
|
547
|
+
msg({
|
|
548
|
+
message: "That page is private, so nobody could open it from a menu.",
|
|
549
|
+
comment:
|
|
550
|
+
"@context: Shown when a pasted address resolves to a private page",
|
|
551
|
+
}),
|
|
552
|
+
),
|
|
553
|
+
addressUntitled: i18n._(
|
|
554
|
+
msg({
|
|
555
|
+
message: "That page has no title yet, so a menu has nothing to show.",
|
|
556
|
+
comment:
|
|
557
|
+
"@context: Shown when a pasted address resolves to an untitled post",
|
|
558
|
+
}),
|
|
559
|
+
),
|
|
560
|
+
addressExternal: i18n._(
|
|
561
|
+
msg({
|
|
562
|
+
message:
|
|
563
|
+
"That address is on another site. Navigation holds it as a link.",
|
|
564
|
+
comment: "@context: Shown when a pasted address points off the site",
|
|
565
|
+
}),
|
|
566
|
+
),
|
|
567
|
+
addressLinkOnly: i18n._(
|
|
568
|
+
msg({
|
|
569
|
+
message: "Navigation holds that address as a link.",
|
|
570
|
+
comment:
|
|
571
|
+
"@context: Shown for a page on the site that can only be a link, such as an archive URL",
|
|
572
|
+
}),
|
|
573
|
+
),
|
|
574
|
+
addressAddAsLink: i18n._(
|
|
575
|
+
msg({
|
|
576
|
+
message: "Add as link",
|
|
577
|
+
comment:
|
|
578
|
+
"@context: Button that opens the link form with the pasted address filled in",
|
|
579
|
+
}),
|
|
580
|
+
),
|
|
489
581
|
searchingPages: i18n._(
|
|
490
582
|
msg({
|
|
491
583
|
message: "Searching pages…",
|
|
@@ -643,6 +735,7 @@ export function NavigationContent({
|
|
|
643
735
|
comment: "@context: Button for adding a collection to nav",
|
|
644
736
|
}),
|
|
645
737
|
),
|
|
738
|
+
smartCollectionLabel: getSmartCollectionLabels(i18n).noun,
|
|
646
739
|
addCollectionToNavigation: i18n._(
|
|
647
740
|
msg({
|
|
648
741
|
message: "Add collection to navigation",
|
|
@@ -729,6 +822,14 @@ export function NavigationContent({
|
|
|
729
822
|
|
|
730
823
|
return (
|
|
731
824
|
<div class="max-w-3xl flex flex-col gap-8">
|
|
825
|
+
{/* The dialog is a Lit component and cannot reach the i18n catalogs, so
|
|
826
|
+
the page that can open it carries its strings. */}
|
|
827
|
+
<div
|
|
828
|
+
hidden
|
|
829
|
+
data-collection-dialog-labels={escapeJson(
|
|
830
|
+
getCollectionDialogLabels(i18n),
|
|
831
|
+
)}
|
|
832
|
+
/>
|
|
732
833
|
<jant-nav-manager
|
|
733
834
|
items={escapeJson(itemsData)}
|
|
734
835
|
labels={escapeJson(labels)}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Context } from "hono";
|
|
2
2
|
import { renderToString } from "hono/jsx/dom/server";
|
|
3
3
|
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { readComponentCss } from "../../../../__tests__/helpers/component-css.js";
|
|
4
5
|
import { I18nProvider } from "../../../../i18n/context.js";
|
|
5
6
|
import { createI18n } from "../../../../i18n/i18n.js";
|
|
6
7
|
import { NavigationContent } from "../NavigationContent.js";
|
|
@@ -21,7 +22,12 @@ function renderNavigationContent(
|
|
|
21
22
|
return renderToString(
|
|
22
23
|
NavigationContent({
|
|
23
24
|
navItems: [],
|
|
24
|
-
directoryData: {
|
|
25
|
+
directoryData: {
|
|
26
|
+
collections: [],
|
|
27
|
+
smartCollections: [],
|
|
28
|
+
items: [],
|
|
29
|
+
directoryItems: [],
|
|
30
|
+
},
|
|
25
31
|
suggestedLinks: [],
|
|
26
32
|
mainRssFeed: "latest",
|
|
27
33
|
rssFeedsEnabled: true,
|
|
@@ -32,20 +38,24 @@ function renderNavigationContent(
|
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
describe("NavigationContent", () => {
|
|
35
|
-
it("
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
it("names which end the RSS entry currently points at", () => {
|
|
42
|
+
expect(renderNavigationContent({ mainRssFeed: "latest" })).toContain(
|
|
43
|
+
"currently your Latest feed",
|
|
44
|
+
);
|
|
45
|
+
expect(renderNavigationContent({ mainRssFeed: "featured" })).toContain(
|
|
46
|
+
"currently your Featured feed",
|
|
40
47
|
);
|
|
41
48
|
});
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
// RSS and Subscribe are the only pair an author has to choose between, and
|
|
51
|
+
// they are adjacent switches. Each has to say who it is for, or the choice is
|
|
52
|
+
// two near-identical toggles.
|
|
53
|
+
it("offers RSS and Subscribe as a legible choice", () => {
|
|
54
|
+
const html = renderNavigationContent({ mainRssFeed: "latest" });
|
|
45
55
|
|
|
46
|
-
expect(html).toContain(
|
|
47
|
-
|
|
48
|
-
);
|
|
56
|
+
expect(html).toContain("already use a feed reader");
|
|
57
|
+
expect(html).toContain("a page listing your feeds with copy buttons");
|
|
58
|
+
expect(html).toContain("don't already use one");
|
|
49
59
|
});
|
|
50
60
|
|
|
51
61
|
it("renders the built-in links heading", () => {
|
|
@@ -93,4 +103,16 @@ describe("NavigationContent", () => {
|
|
|
93
103
|
expect(html).toContain("suggested-links=");
|
|
94
104
|
expect(html).toContain(""targetLabel":"Collection"");
|
|
95
105
|
});
|
|
106
|
+
|
|
107
|
+
it("leaves the preview frame unclipped so the More menu can escape it", () => {
|
|
108
|
+
const css = readComponentCss();
|
|
109
|
+
const frame = css.match(/\.nav-preview \{[^}]*\}/)?.[0] ?? "";
|
|
110
|
+
|
|
111
|
+
// The menu opens below the frame's own bottom edge. Clipping here cuts it
|
|
112
|
+
// off entirely — a stacking order cannot escape an ancestor's overflow.
|
|
113
|
+
expect(frame).not.toContain("overflow-hidden");
|
|
114
|
+
expect(css).toMatch(
|
|
115
|
+
/\.nav-preview-chrome \{[\s\S]*?border-top-left-radius/,
|
|
116
|
+
);
|
|
117
|
+
});
|
|
96
118
|
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { I18n, MessageDescriptor } from "@lingui/core";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { getSystemNavDescription } from "../system-nav-descriptions.js";
|
|
4
|
+
|
|
5
|
+
const i18n = {
|
|
6
|
+
_(descriptor: MessageDescriptor, values?: Record<string, unknown>) {
|
|
7
|
+
const message = descriptor.message ?? "";
|
|
8
|
+
return values
|
|
9
|
+
? message.replace(/\{(\w+)\}/g, (_, key: string) => String(values[key]))
|
|
10
|
+
: message;
|
|
11
|
+
},
|
|
12
|
+
} satisfies Pick<I18n, "_">;
|
|
13
|
+
|
|
14
|
+
describe("getSystemNavDescription", () => {
|
|
15
|
+
it("describes each system nav toggle", () => {
|
|
16
|
+
expect(getSystemNavDescription("latest", i18n)).toBe(
|
|
17
|
+
"Link to your latest posts. Your homepage shows this feed.",
|
|
18
|
+
);
|
|
19
|
+
expect(getSystemNavDescription("featured", i18n)).toBe(
|
|
20
|
+
"Link to posts you've marked as featured.",
|
|
21
|
+
);
|
|
22
|
+
expect(getSystemNavDescription("archive", i18n)).toBe(
|
|
23
|
+
"Link to the post archive",
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("names which end the RSS entry currently points at", () => {
|
|
28
|
+
expect(getSystemNavDescription("rss", i18n, { feed: "Latest" })).toContain(
|
|
29
|
+
"currently your Latest feed",
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// The two feed entries are the only pair an author has to choose between, so
|
|
34
|
+
// each has to say who it is for. Losing either half loses the choice.
|
|
35
|
+
it("tells the two feed entries apart by who they are for", () => {
|
|
36
|
+
const rss = getSystemNavDescription("rss", i18n, { feed: "Latest" });
|
|
37
|
+
const subscribe = getSystemNavDescription("subscribe", i18n);
|
|
38
|
+
|
|
39
|
+
expect(rss).toContain("/feed");
|
|
40
|
+
expect(rss).toContain("already use a feed reader");
|
|
41
|
+
expect(subscribe).toContain("/subscribe");
|
|
42
|
+
expect(subscribe).toContain("don't already use one");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The line under each system nav toggle in Appearance, saying what turning it
|
|
3
|
+
* on does.
|
|
4
|
+
*
|
|
5
|
+
* These live under `ui/dash/` rather than beside the nav labels in `ui/shared/`
|
|
6
|
+
* because that is what puts them in the translated catalog: `lingui.config`
|
|
7
|
+
* splits by path, and only `routes/dash/**`, `ui/dash/**` and the setup page
|
|
8
|
+
* are translated. The labels themselves stay in `ui/shared/` — they render in
|
|
9
|
+
* the public site nav, which is English in every view.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { msg } from "@lingui/core/macro";
|
|
13
|
+
import type { MessageDescriptor } from "@lingui/core";
|
|
14
|
+
import type { I18n, TranslationValues } from "../../../i18n/i18n.js";
|
|
15
|
+
import type { SystemNavKey } from "../../../types.js";
|
|
16
|
+
|
|
17
|
+
type Translator = Pick<I18n, "_">;
|
|
18
|
+
|
|
19
|
+
const SYSTEM_NAV_DESCRIPTIONS: Record<SystemNavKey, MessageDescriptor> = {
|
|
20
|
+
latest: msg({
|
|
21
|
+
message: "Link to your latest posts. Your homepage shows this feed.",
|
|
22
|
+
comment: "@context: Description for the latest system navigation toggle",
|
|
23
|
+
}),
|
|
24
|
+
featured: msg({
|
|
25
|
+
message: "Link to posts you've marked as featured.",
|
|
26
|
+
comment: "@context: Description for the featured system navigation toggle",
|
|
27
|
+
}),
|
|
28
|
+
// These two sit next to each other in the same list and are the only pair an
|
|
29
|
+
// author has to choose between, so they are written as a contrast: the raw
|
|
30
|
+
// file versus the page about it, readers who already have a feed reader
|
|
31
|
+
// versus readers who do not. Change one and change the other.
|
|
32
|
+
rss: msg({
|
|
33
|
+
message:
|
|
34
|
+
"Links straight to /feed — the raw Atom file, currently your {feed} feed. Best for readers who already use a feed reader.",
|
|
35
|
+
comment:
|
|
36
|
+
"@context: Description for the RSS system navigation toggle. {feed} is either Latest or Featured. Pairs with the Subscribe toggle's description.",
|
|
37
|
+
}),
|
|
38
|
+
subscribe: msg({
|
|
39
|
+
message:
|
|
40
|
+
"Links to /subscribe, a page listing your feeds with copy buttons. Best for readers who don't already use one.",
|
|
41
|
+
comment:
|
|
42
|
+
"@context: Description for the Subscribe system navigation toggle. Pairs with the RSS toggle's description.",
|
|
43
|
+
}),
|
|
44
|
+
settings: msg({
|
|
45
|
+
message: "Shows 'Settings' when logged in, 'Sign in' when logged out",
|
|
46
|
+
comment: "@context: Description for the settings system navigation toggle",
|
|
47
|
+
}),
|
|
48
|
+
collections: msg({
|
|
49
|
+
message: "Link to your collections page",
|
|
50
|
+
comment:
|
|
51
|
+
"@context: Description for the collections system navigation toggle",
|
|
52
|
+
}),
|
|
53
|
+
archive: msg({
|
|
54
|
+
message: "Link to the post archive",
|
|
55
|
+
comment: "@context: Description for the archive system navigation toggle",
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The description for one system nav toggle.
|
|
61
|
+
*
|
|
62
|
+
* @param key - Which system nav entry
|
|
63
|
+
* @param i18n - Translator for the current request
|
|
64
|
+
* @param values - Placeholder values, for the descriptions that carry one
|
|
65
|
+
* @returns The description text
|
|
66
|
+
* @example
|
|
67
|
+
* getSystemNavDescription("rss", i18n, { feed: "Latest" });
|
|
68
|
+
*/
|
|
69
|
+
export function getSystemNavDescription(
|
|
70
|
+
key: SystemNavKey,
|
|
71
|
+
i18n: Translator,
|
|
72
|
+
values?: TranslationValues,
|
|
73
|
+
): string {
|
|
74
|
+
return i18n._(SYSTEM_NAV_DESCRIPTIONS[key], values);
|
|
75
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { msg } from "@lingui/core/macro";
|
|
6
6
|
import { coalesceDisplayText } from "../../../lib/display-text.js";
|
|
7
7
|
import { useLingui } from "../../../i18n/context.js";
|
|
8
|
+
import { getJantDocsUrl } from "../../../lib/jant-docs.js";
|
|
8
9
|
import { extractDomain, toPublicPath } from "../../../lib/url.js";
|
|
9
10
|
import { CORE_VERSION } from "../../../lib/version.js";
|
|
10
11
|
import {
|
|
@@ -13,8 +14,7 @@ import {
|
|
|
13
14
|
SettingsDirectorySection,
|
|
14
15
|
} from "./SettingsDirectory.js";
|
|
15
16
|
|
|
16
|
-
const BACKUPS_DOCS_URL =
|
|
17
|
-
"https://github.com/jant-me/jant/blob/main/docs/backups.md";
|
|
17
|
+
const BACKUPS_DOCS_URL = getJantDocsUrl("backups");
|
|
18
18
|
const GITHUB_COMMIT_BASE = "https://github.com/jant-me/jant/tree";
|
|
19
19
|
|
|
20
20
|
const ICONS = {
|
|
@@ -9,10 +9,11 @@ import { msg } from "@lingui/core/macro";
|
|
|
9
9
|
import { useLingui } from "../../../i18n/context.js";
|
|
10
10
|
import type { ApiToken } from "../../../types/entities.js";
|
|
11
11
|
import { buildConfirmActionExpression } from "../../../lib/confirm.js";
|
|
12
|
+
import { getJantDocsUrl } from "../../../lib/jant-docs.js";
|
|
12
13
|
import { formatDate } from "../../../lib/time.js";
|
|
13
14
|
import { toPublicPath } from "../../../lib/url.js";
|
|
14
15
|
|
|
15
|
-
const API_DOCS_URL = "
|
|
16
|
+
const API_DOCS_URL = getJantDocsUrl("api");
|
|
16
17
|
|
|
17
18
|
function TokenRow({
|
|
18
19
|
token,
|
|
@@ -76,27 +76,23 @@ export function ConfigEditorContent({
|
|
|
76
76
|
"zh-Hant": "繁體中文",
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
|
-
|
|
79
|
+
MULTILINGUAL_ENABLED: {
|
|
80
80
|
description: i18n._(
|
|
81
81
|
msg({
|
|
82
82
|
message:
|
|
83
|
-
"
|
|
84
|
-
comment: "@context: Config Editor setting description",
|
|
83
|
+
"Whether each language gets its own home page, archive, and feed. Managed on the Language page.",
|
|
84
|
+
comment: "@context: Config Editor linked setting description",
|
|
85
|
+
}),
|
|
86
|
+
),
|
|
87
|
+
},
|
|
88
|
+
ADDITIONAL_LANGUAGES: {
|
|
89
|
+
description: i18n._(
|
|
90
|
+
msg({
|
|
91
|
+
message:
|
|
92
|
+
"The languages served under a URL prefix. Managed on the Language page.",
|
|
93
|
+
comment: "@context: Config Editor linked setting description",
|
|
85
94
|
}),
|
|
86
95
|
),
|
|
87
|
-
optionLabels: {
|
|
88
|
-
off: i18n._(
|
|
89
|
-
msg({
|
|
90
|
-
message: "Follow content language",
|
|
91
|
-
comment:
|
|
92
|
-
"@context: Config Editor enum option for automatic CJK font fallback",
|
|
93
|
-
}),
|
|
94
|
-
),
|
|
95
|
-
"zh-Hans": "简体中文",
|
|
96
|
-
"zh-Hant": "繁體中文",
|
|
97
|
-
ja: "日本語",
|
|
98
|
-
ko: "한국어",
|
|
99
|
-
},
|
|
100
96
|
},
|
|
101
97
|
MAIN_RSS_FEED: {
|
|
102
98
|
description: i18n._(
|
|
@@ -120,6 +116,29 @@ export function ConfigEditorContent({
|
|
|
120
116
|
),
|
|
121
117
|
},
|
|
122
118
|
},
|
|
119
|
+
ARCHIVE_DEFAULT_LAYOUT: {
|
|
120
|
+
description: i18n._(
|
|
121
|
+
msg({
|
|
122
|
+
message:
|
|
123
|
+
"Which layout /archive opens with. Readers can switch layouts from the page.",
|
|
124
|
+
comment: "@context: Config Editor setting description",
|
|
125
|
+
}),
|
|
126
|
+
),
|
|
127
|
+
optionLabels: {
|
|
128
|
+
list: i18n._(
|
|
129
|
+
msg({
|
|
130
|
+
message: "Full posts",
|
|
131
|
+
comment: "@context: Config Editor archive layout enum option",
|
|
132
|
+
}),
|
|
133
|
+
),
|
|
134
|
+
grid: i18n._(
|
|
135
|
+
msg({
|
|
136
|
+
message: "Tile grid",
|
|
137
|
+
comment: "@context: Config Editor archive layout enum option",
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
140
|
+
},
|
|
141
|
+
},
|
|
123
142
|
PAGE_SIZE: {
|
|
124
143
|
description: i18n._(
|
|
125
144
|
msg({
|