@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
|
@@ -26,15 +26,16 @@ import {
|
|
|
26
26
|
setSortableDraggingState,
|
|
27
27
|
} from "../sortable-list.js";
|
|
28
28
|
import { showConfirmDialog } from "../confirm.js";
|
|
29
|
-
import { publicPath } from "../runtime-paths.js";
|
|
29
|
+
import { publicPath, viewLang, viewPath } from "../runtime-paths.js";
|
|
30
30
|
import { showToast, showToastWithAction } from "../toast.js";
|
|
31
|
-
import {
|
|
32
|
-
|
|
31
|
+
import {
|
|
32
|
+
addCollectionToNavigation,
|
|
33
|
+
addSmartCollectionToNavigation,
|
|
34
|
+
} from "../collection-navigation.js";
|
|
33
35
|
import { getDividerCollectionGroup } from "../../lib/collection-groups.js";
|
|
34
36
|
import {
|
|
35
|
-
|
|
37
|
+
getCollectionPagePath,
|
|
36
38
|
getCollectionSelectionPath,
|
|
37
|
-
getCollectionsDirectoryPath,
|
|
38
39
|
} from "../../lib/collection-paths.js";
|
|
39
40
|
import { NAVIGATION_SETTINGS_PATH } from "../../lib/settings-paths.js";
|
|
40
41
|
import { render as renderMarkdown } from "../../lib/markdown.js";
|
|
@@ -47,7 +48,12 @@ import type {
|
|
|
47
48
|
CollectionManagerItem,
|
|
48
49
|
CollectionManagerLabels,
|
|
49
50
|
ManagedCollection,
|
|
51
|
+
ManagedSmartCollection,
|
|
50
52
|
} from "./collection-manager-types.js";
|
|
53
|
+
import { FUNNEL_ICON_SVG } from "../icons.js";
|
|
54
|
+
import { openCollectionDialog } from "../collection-dialog-host.js";
|
|
55
|
+
import { openSmartCollectionDialog } from "../smart-collection-dialog-host.js";
|
|
56
|
+
import { setCollectionVocabulary } from "./smart-collection-conditions.js";
|
|
51
57
|
|
|
52
58
|
interface CollectionsResponse {
|
|
53
59
|
collections?: Array<{
|
|
@@ -59,10 +65,22 @@ interface CollectionsResponse {
|
|
|
59
65
|
threadCount: number;
|
|
60
66
|
recentActivityAt: number;
|
|
61
67
|
}>;
|
|
68
|
+
smartCollections?: Array<{
|
|
69
|
+
id: string;
|
|
70
|
+
slug: string;
|
|
71
|
+
title: string;
|
|
72
|
+
description: string | null;
|
|
73
|
+
selection: Record<string, unknown>;
|
|
74
|
+
sort: string;
|
|
75
|
+
layout: string | null;
|
|
76
|
+
threadCount: number;
|
|
77
|
+
recentActivityAt: number;
|
|
78
|
+
}>;
|
|
62
79
|
directoryItems?: Array<{
|
|
63
80
|
id: string;
|
|
64
|
-
type: "collection" | "divider" | "link";
|
|
81
|
+
type: "collection" | "smart_collection" | "divider" | "link";
|
|
65
82
|
collectionId: string | null;
|
|
83
|
+
smartCollectionId: string | null;
|
|
66
84
|
label: string | null;
|
|
67
85
|
url: string | null;
|
|
68
86
|
description: string | null;
|
|
@@ -105,6 +123,7 @@ export class JantCollectionsManager extends LitElement {
|
|
|
105
123
|
|
|
106
124
|
declare items: CollectionManagerItem[];
|
|
107
125
|
declare labels: CollectionManagerLabels;
|
|
126
|
+
/** Collections and smart collections already in the site navigation. */
|
|
108
127
|
declare navigationCollectionIds: string[];
|
|
109
128
|
|
|
110
129
|
declare _items: CollectionManagerItem[];
|
|
@@ -186,6 +205,17 @@ export class JantCollectionsManager extends LitElement {
|
|
|
186
205
|
case "link":
|
|
187
206
|
this.#openLinkForm();
|
|
188
207
|
break;
|
|
208
|
+
case "collection":
|
|
209
|
+
void this.#createCollection();
|
|
210
|
+
break;
|
|
211
|
+
case "smart-collection":
|
|
212
|
+
// Beside Add link and Add divider rather than a second `+` button:
|
|
213
|
+
// the `+` is where a collection is created, and two plus signs would
|
|
214
|
+
// immediately raise "which plus".
|
|
215
|
+
void openSmartCollectionDialog({}).then((changed) => {
|
|
216
|
+
if (changed) void this.#refreshList();
|
|
217
|
+
});
|
|
218
|
+
break;
|
|
189
219
|
default:
|
|
190
220
|
break;
|
|
191
221
|
}
|
|
@@ -199,12 +229,33 @@ export class JantCollectionsManager extends LitElement {
|
|
|
199
229
|
connectedCallback() {
|
|
200
230
|
super.connectedCallback();
|
|
201
231
|
this.#bindManagerRoot();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Create a collection, then point at the row it became.
|
|
236
|
+
*
|
|
237
|
+
* The inline notice offering navigation is the reason the new collection's
|
|
238
|
+
* id is carried back out of the dialog: without it the author would have to
|
|
239
|
+
* find the row themselves to do the one thing they are most likely to want
|
|
240
|
+
* next.
|
|
241
|
+
*/
|
|
242
|
+
async #createCollection() {
|
|
243
|
+
const result = await openCollectionDialog();
|
|
244
|
+
if (!result.changed) return;
|
|
245
|
+
await this.#refreshList();
|
|
246
|
+
if (result.collection) {
|
|
247
|
+
this._createdCollectionId = result.collection.id;
|
|
205
248
|
}
|
|
206
249
|
}
|
|
207
250
|
|
|
251
|
+
/** Edit a collection from its directory row, then re-read the row. */
|
|
252
|
+
async #editCollection(collectionId: string) {
|
|
253
|
+
this._showItemMenuId = null;
|
|
254
|
+
document.removeEventListener("click", this.#closeItemMenu);
|
|
255
|
+
const { changed } = await openCollectionDialog({ collectionId });
|
|
256
|
+
if (changed) await this.#refreshList();
|
|
257
|
+
}
|
|
258
|
+
|
|
208
259
|
constructor() {
|
|
209
260
|
super();
|
|
210
261
|
this.items = [];
|
|
@@ -257,6 +308,7 @@ export class JantCollectionsManager extends LitElement {
|
|
|
257
308
|
return this._items.some(
|
|
258
309
|
(item) =>
|
|
259
310
|
(item.type === "collection" && item.collection) ||
|
|
311
|
+
(item.type === "smart_collection" && item.smartCollection) ||
|
|
260
312
|
(item.type === "link" && item.label && item.url),
|
|
261
313
|
);
|
|
262
314
|
}
|
|
@@ -327,6 +379,30 @@ export class JantCollectionsManager extends LitElement {
|
|
|
327
379
|
}
|
|
328
380
|
}
|
|
329
381
|
|
|
382
|
+
/**
|
|
383
|
+
* Keep the shared collection vocabulary current.
|
|
384
|
+
*
|
|
385
|
+
* The upgrade check on a `/archive?collection=…` link has to resolve that
|
|
386
|
+
* slug, and this component already holds every collection on the site, so
|
|
387
|
+
* doing it here costs nothing — and means the menu item never disappears
|
|
388
|
+
* merely because a lookup had not happened yet.
|
|
389
|
+
*/
|
|
390
|
+
#syncCollectionVocabulary() {
|
|
391
|
+
setCollectionVocabulary(
|
|
392
|
+
this._items.flatMap((item) =>
|
|
393
|
+
item.collection
|
|
394
|
+
? [
|
|
395
|
+
{
|
|
396
|
+
id: item.collection.id,
|
|
397
|
+
slug: item.collection.slug,
|
|
398
|
+
title: item.collection.title,
|
|
399
|
+
},
|
|
400
|
+
]
|
|
401
|
+
: [],
|
|
402
|
+
),
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
|
|
330
406
|
#toItems(json: CollectionsResponse): CollectionManagerItem[] {
|
|
331
407
|
const collections = json.collections ?? [];
|
|
332
408
|
const directoryItems = json.directoryItems ?? [];
|
|
@@ -344,7 +420,24 @@ export class JantCollectionsManager extends LitElement {
|
|
|
344
420
|
});
|
|
345
421
|
}
|
|
346
422
|
|
|
423
|
+
const smartCollections = json.smartCollections ?? [];
|
|
424
|
+
const smartCollectionMap = new Map<string, ManagedSmartCollection>();
|
|
425
|
+
for (const smartCollection of smartCollections) {
|
|
426
|
+
smartCollectionMap.set(smartCollection.id, {
|
|
427
|
+
id: smartCollection.id,
|
|
428
|
+
slug: smartCollection.slug,
|
|
429
|
+
title: smartCollection.title,
|
|
430
|
+
description: smartCollection.description,
|
|
431
|
+
selection: smartCollection.selection ?? {},
|
|
432
|
+
sort: smartCollection.sort,
|
|
433
|
+
layout: smartCollection.layout,
|
|
434
|
+
threadCount: smartCollection.threadCount ?? 0,
|
|
435
|
+
recentActivityAt: smartCollection.recentActivityAt,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
|
|
347
439
|
const seenCollections = new Set<string>();
|
|
440
|
+
const seenSmartCollections = new Set<string>();
|
|
348
441
|
const orderedItems: CollectionManagerItem[] = [];
|
|
349
442
|
|
|
350
443
|
for (const item of directoryItems) {
|
|
@@ -352,31 +445,48 @@ export class JantCollectionsManager extends LitElement {
|
|
|
352
445
|
item.collectionId != null
|
|
353
446
|
? collectionMap.get(item.collectionId)
|
|
354
447
|
: undefined;
|
|
448
|
+
const smartCollection =
|
|
449
|
+
item.smartCollectionId != null
|
|
450
|
+
? smartCollectionMap.get(item.smartCollectionId)
|
|
451
|
+
: undefined;
|
|
355
452
|
|
|
356
453
|
if (item.type === "collection" && !collection) {
|
|
357
454
|
continue;
|
|
358
455
|
}
|
|
456
|
+
if (item.type === "smart_collection" && !smartCollection) {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
359
459
|
|
|
360
460
|
if (collection) {
|
|
361
461
|
seenCollections.add(collection.id);
|
|
362
462
|
}
|
|
463
|
+
if (smartCollection) {
|
|
464
|
+
seenSmartCollections.add(smartCollection.id);
|
|
465
|
+
}
|
|
363
466
|
|
|
364
467
|
orderedItems.push({
|
|
365
468
|
id: item.id,
|
|
366
469
|
type: item.type,
|
|
367
470
|
collectionId: item.collectionId,
|
|
471
|
+
smartCollectionId: item.smartCollectionId,
|
|
368
472
|
label: item.label,
|
|
369
473
|
url: item.url,
|
|
370
474
|
description: item.description,
|
|
371
475
|
position: item.position,
|
|
372
476
|
collection,
|
|
477
|
+
smartCollection,
|
|
373
478
|
});
|
|
374
479
|
}
|
|
375
480
|
|
|
481
|
+
// Anything with no directory row is appended, both kinds alike. That is
|
|
482
|
+
// what makes "a collection missing from /collections" an impossible state.
|
|
483
|
+
// Such a row carries its own id, exactly as the server renders it, because
|
|
484
|
+
// there is no row id to carry — the move endpoint reads that as "place this
|
|
485
|
+
// first, then move it".
|
|
376
486
|
for (const collection of collections) {
|
|
377
487
|
if (seenCollections.has(collection.id)) continue;
|
|
378
488
|
orderedItems.push({
|
|
379
|
-
id:
|
|
489
|
+
id: collection.id,
|
|
380
490
|
type: "collection",
|
|
381
491
|
collectionId: collection.id,
|
|
382
492
|
label: null,
|
|
@@ -386,12 +496,33 @@ export class JantCollectionsManager extends LitElement {
|
|
|
386
496
|
});
|
|
387
497
|
}
|
|
388
498
|
|
|
499
|
+
for (const smartCollection of smartCollections) {
|
|
500
|
+
if (seenSmartCollections.has(smartCollection.id)) continue;
|
|
501
|
+
orderedItems.push({
|
|
502
|
+
id: smartCollection.id,
|
|
503
|
+
type: "smart_collection",
|
|
504
|
+
smartCollectionId: smartCollection.id,
|
|
505
|
+
label: null,
|
|
506
|
+
url: null,
|
|
507
|
+
position: "",
|
|
508
|
+
smartCollection: smartCollectionMap.get(smartCollection.id),
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
|
|
389
512
|
return orderedItems;
|
|
390
513
|
}
|
|
391
514
|
|
|
392
515
|
async #refreshList() {
|
|
393
516
|
try {
|
|
394
|
-
|
|
517
|
+
// The counts are narrowed to this view's language, exactly as the
|
|
518
|
+
// server rendered them — without this a reorder would make every number
|
|
519
|
+
// jump to its site-wide value.
|
|
520
|
+
const lang = viewLang();
|
|
521
|
+
const res = await fetch(
|
|
522
|
+
lang
|
|
523
|
+
? `/api/collections?lang=${encodeURIComponent(lang)}`
|
|
524
|
+
: "/api/collections",
|
|
525
|
+
);
|
|
395
526
|
if (!res.ok) return;
|
|
396
527
|
const json = (await res.json()) as CollectionsResponse;
|
|
397
528
|
this._items = this.#toItems(json);
|
|
@@ -481,6 +612,7 @@ export class JantCollectionsManager extends LitElement {
|
|
|
481
612
|
): void {
|
|
482
613
|
this.#bindManagerRoot();
|
|
483
614
|
this.#syncHeaderState();
|
|
615
|
+
this.#syncCollectionVocabulary();
|
|
484
616
|
|
|
485
617
|
if (this._reorderMode) {
|
|
486
618
|
this.#initSortable();
|
|
@@ -682,18 +814,29 @@ export class JantCollectionsManager extends LitElement {
|
|
|
682
814
|
}
|
|
683
815
|
}
|
|
684
816
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
817
|
+
/**
|
|
818
|
+
* Put a directory entry in the site navigation. Collections and smart
|
|
819
|
+
* collections differ only in which endpoint payload they send, so they share
|
|
820
|
+
* the pending state, the id list and the confirmation.
|
|
821
|
+
*
|
|
822
|
+
* @param targetId - TypeID of the collection or smart collection
|
|
823
|
+
* @param add - Helper that creates the navigation item for that kind
|
|
824
|
+
*/
|
|
825
|
+
async #addToNavigation(
|
|
826
|
+
targetId: string,
|
|
827
|
+
add: (id: string) => Promise<string | undefined>,
|
|
828
|
+
) {
|
|
829
|
+
if (!targetId || this._addingToNavigationId) return;
|
|
830
|
+
|
|
831
|
+
const usesInlineNotice = this._createdCollectionId === targetId;
|
|
689
832
|
this._showItemMenuId = null;
|
|
690
|
-
this._addingToNavigationId =
|
|
833
|
+
this._addingToNavigationId = targetId;
|
|
691
834
|
document.removeEventListener("click", this.#closeItemMenu);
|
|
692
835
|
|
|
693
836
|
try {
|
|
694
|
-
await
|
|
837
|
+
await add(targetId);
|
|
695
838
|
this.navigationCollectionIds = [
|
|
696
|
-
...new Set([...this.navigationCollectionIds,
|
|
839
|
+
...new Set([...this.navigationCollectionIds, targetId]),
|
|
697
840
|
];
|
|
698
841
|
if (!usesInlineNotice) {
|
|
699
842
|
showToastWithAction(this.labels.addedToNavigation, {
|
|
@@ -804,6 +947,7 @@ export class JantCollectionsManager extends LitElement {
|
|
|
804
947
|
#computeSequenceLabels(): string[] {
|
|
805
948
|
const isContentItem = (item: CollectionManagerItem) =>
|
|
806
949
|
(item.type === "collection" && item.collection) ||
|
|
950
|
+
(item.type === "smart_collection" && item.smartCollection) ||
|
|
807
951
|
(item.type === "link" && item.label && item.url);
|
|
808
952
|
|
|
809
953
|
const groupSizes: number[] = [];
|
|
@@ -864,7 +1008,9 @@ export class JantCollectionsManager extends LitElement {
|
|
|
864
1008
|
const collection = item.collection;
|
|
865
1009
|
if (!collection) return nothing;
|
|
866
1010
|
|
|
867
|
-
|
|
1011
|
+
// A collection page is served once per language, so this link has to stay
|
|
1012
|
+
// in the view the reader is already in.
|
|
1013
|
+
const collectionHref = viewPath(
|
|
868
1014
|
getCollectionSelectionPath(collection.slug),
|
|
869
1015
|
);
|
|
870
1016
|
|
|
@@ -878,17 +1024,19 @@ export class JantCollectionsManager extends LitElement {
|
|
|
878
1024
|
<span class="collection-directory-title">${collection.title}</span>
|
|
879
1025
|
</a>
|
|
880
1026
|
</div>
|
|
881
|
-
${
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
1027
|
+
${
|
|
1028
|
+
collection.description
|
|
1029
|
+
? html`
|
|
1030
|
+
<div class="collection-directory-description prose">
|
|
1031
|
+
${unsafeHTML(
|
|
1032
|
+
renderMarkdown(collection.description, {
|
|
1033
|
+
namespace: collection.id,
|
|
1034
|
+
}),
|
|
1035
|
+
)}
|
|
1036
|
+
</div>
|
|
1037
|
+
`
|
|
1038
|
+
: nothing
|
|
1039
|
+
}
|
|
892
1040
|
<p class="collection-directory-summary">
|
|
893
1041
|
<span class="collection-directory-meta"
|
|
894
1042
|
>${this.#countLabel(collection.threadCount)}</span
|
|
@@ -956,6 +1104,141 @@ export class JantCollectionsManager extends LitElement {
|
|
|
956
1104
|
`;
|
|
957
1105
|
}
|
|
958
1106
|
|
|
1107
|
+
/**
|
|
1108
|
+
* One smart collection row.
|
|
1109
|
+
*
|
|
1110
|
+
* The same row shape as a collection — count, then last activity — with the
|
|
1111
|
+
* `funnel` marker in the slot the link rows already use. Only the marker
|
|
1112
|
+
* says the membership came from conditions; the two measures beside it are
|
|
1113
|
+
* the same two, and are meant to be read against the rows above and below.
|
|
1114
|
+
*/
|
|
1115
|
+
#renderSmartCollectionItem(item: CollectionManagerItem, sequence: string) {
|
|
1116
|
+
const smartCollection = item.smartCollection;
|
|
1117
|
+
if (!smartCollection) return nothing;
|
|
1118
|
+
|
|
1119
|
+
const href = viewPath(getCollectionPagePath(smartCollection.slug));
|
|
1120
|
+
const body = html`
|
|
1121
|
+
<div class="collection-directory-main">
|
|
1122
|
+
<span class="collection-directory-sequence" aria-hidden="true"
|
|
1123
|
+
>${sequence}</span
|
|
1124
|
+
>
|
|
1125
|
+
<div class="collection-directory-title-row">
|
|
1126
|
+
<a href=${publicPath(href)} class="collection-directory-title-link">
|
|
1127
|
+
<span class="collection-directory-title"
|
|
1128
|
+
>${smartCollection.title}
|
|
1129
|
+
<span
|
|
1130
|
+
class="collection-directory-smart-icon"
|
|
1131
|
+
role="img"
|
|
1132
|
+
aria-label=${this.labels.smartCollectionNoun}
|
|
1133
|
+
title=${this.labels.smartCollectionNoun}
|
|
1134
|
+
>${unsafeHTML(FUNNEL_ICON_SVG)}</span
|
|
1135
|
+
></span
|
|
1136
|
+
>
|
|
1137
|
+
</a>
|
|
1138
|
+
</div>
|
|
1139
|
+
${
|
|
1140
|
+
smartCollection.description
|
|
1141
|
+
? html`
|
|
1142
|
+
<div class="collection-directory-description prose">
|
|
1143
|
+
${unsafeHTML(
|
|
1144
|
+
renderMarkdown(smartCollection.description, {
|
|
1145
|
+
namespace: smartCollection.id,
|
|
1146
|
+
}),
|
|
1147
|
+
)}
|
|
1148
|
+
</div>
|
|
1149
|
+
`
|
|
1150
|
+
: nothing
|
|
1151
|
+
}
|
|
1152
|
+
<p class="collection-directory-summary">
|
|
1153
|
+
<span class="collection-directory-meta"
|
|
1154
|
+
>${this.#countLabel(smartCollection.threadCount)}</span
|
|
1155
|
+
>
|
|
1156
|
+
<span class="collection-directory-meta-separator" aria-hidden="true"
|
|
1157
|
+
>/</span
|
|
1158
|
+
>
|
|
1159
|
+
<time
|
|
1160
|
+
class="collection-directory-updated"
|
|
1161
|
+
datetime=${toISOString(smartCollection.recentActivityAt)}
|
|
1162
|
+
>
|
|
1163
|
+
${formatRelativeAge(smartCollection.recentActivityAt)}
|
|
1164
|
+
</time>
|
|
1165
|
+
</p>
|
|
1166
|
+
</div>
|
|
1167
|
+
`;
|
|
1168
|
+
|
|
1169
|
+
if (this._reorderMode) {
|
|
1170
|
+
return html`
|
|
1171
|
+
<div
|
|
1172
|
+
data-directory-item=${item.id}
|
|
1173
|
+
class="collection-directory-item collection-directory-item-reorder"
|
|
1174
|
+
>
|
|
1175
|
+
<div class="collection-directory-handle" data-drag-handle>
|
|
1176
|
+
<svg
|
|
1177
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1178
|
+
width="16"
|
|
1179
|
+
height="16"
|
|
1180
|
+
viewBox="0 0 24 24"
|
|
1181
|
+
fill="none"
|
|
1182
|
+
stroke="currentColor"
|
|
1183
|
+
stroke-width="2"
|
|
1184
|
+
stroke-linecap="round"
|
|
1185
|
+
stroke-linejoin="round"
|
|
1186
|
+
>
|
|
1187
|
+
<circle cx="9" cy="12" r="1" />
|
|
1188
|
+
<circle cx="9" cy="5" r="1" />
|
|
1189
|
+
<circle cx="9" cy="19" r="1" />
|
|
1190
|
+
<circle cx="15" cy="12" r="1" />
|
|
1191
|
+
<circle cx="15" cy="5" r="1" />
|
|
1192
|
+
<circle cx="15" cy="19" r="1" />
|
|
1193
|
+
</svg>
|
|
1194
|
+
</div>
|
|
1195
|
+
<div class="collection-directory-reorder-main">${body}</div>
|
|
1196
|
+
</div>
|
|
1197
|
+
`;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
return html`
|
|
1201
|
+
<div
|
|
1202
|
+
class=${classMap({
|
|
1203
|
+
"group relative": true,
|
|
1204
|
+
"collection-directory-managed-row": true,
|
|
1205
|
+
"z-50": this._showItemMenuId === item.id,
|
|
1206
|
+
})}
|
|
1207
|
+
>
|
|
1208
|
+
<div
|
|
1209
|
+
class="collection-directory-item collection-directory-item-manageable"
|
|
1210
|
+
>
|
|
1211
|
+
${body}
|
|
1212
|
+
</div>
|
|
1213
|
+
${this.#renderItemMenu(item)}
|
|
1214
|
+
</div>
|
|
1215
|
+
`;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
async #deleteSmartCollection(smartCollection: ManagedSmartCollection) {
|
|
1219
|
+
this._showItemMenuId = null;
|
|
1220
|
+
document.removeEventListener("click", this.#closeItemMenu);
|
|
1221
|
+
|
|
1222
|
+
const confirmed = await showConfirmDialog({
|
|
1223
|
+
message: this.labels.confirmDeleteSmartCollection,
|
|
1224
|
+
confirmLabel: this.labels.deleteSmartCollection,
|
|
1225
|
+
cancelLabel: this.labels.cancel,
|
|
1226
|
+
tone: "danger",
|
|
1227
|
+
});
|
|
1228
|
+
if (!confirmed) return;
|
|
1229
|
+
|
|
1230
|
+
try {
|
|
1231
|
+
const res = await fetch(`/api/smart-collections/${smartCollection.id}`, {
|
|
1232
|
+
method: "DELETE",
|
|
1233
|
+
});
|
|
1234
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1235
|
+
showToast(this.labels.smartCollectionDeleted);
|
|
1236
|
+
await this.#refreshList();
|
|
1237
|
+
} catch {
|
|
1238
|
+
showToast(this.labels.saveFailed, "error");
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
959
1242
|
#renderLinkEditPanel(item: CollectionManagerItem) {
|
|
960
1243
|
if (this._editingLinkId !== item.id) return nothing;
|
|
961
1244
|
|
|
@@ -1016,9 +1299,7 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1016
1299
|
>
|
|
1017
1300
|
${this.labels.cancel}
|
|
1018
1301
|
</button>
|
|
1019
|
-
<button type="submit" class="btn-sm">
|
|
1020
|
-
${this.labels.formLabels.submitLabel}
|
|
1021
|
-
</button>
|
|
1302
|
+
<button type="submit" class="btn-sm">${this.labels.save}</button>
|
|
1022
1303
|
</div>
|
|
1023
1304
|
</form>
|
|
1024
1305
|
</div>
|
|
@@ -1072,21 +1353,23 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1072
1353
|
</span>
|
|
1073
1354
|
</a>
|
|
1074
1355
|
</div>
|
|
1075
|
-
${
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
<
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1356
|
+
${
|
|
1357
|
+
item.description
|
|
1358
|
+
? html`
|
|
1359
|
+
<div class="collection-directory-description prose">
|
|
1360
|
+
${unsafeHTML(
|
|
1361
|
+
renderMarkdown(item.description, { namespace: item.id }),
|
|
1362
|
+
)}
|
|
1363
|
+
</div>
|
|
1364
|
+
`
|
|
1365
|
+
: html`
|
|
1366
|
+
<p class="collection-directory-summary">
|
|
1367
|
+
<span class="collection-directory-meta"
|
|
1368
|
+
>${this.labels.linkDescriptionPlaceholder}</span
|
|
1369
|
+
>
|
|
1370
|
+
</p>
|
|
1371
|
+
`
|
|
1372
|
+
}
|
|
1090
1373
|
</div>
|
|
1091
1374
|
`;
|
|
1092
1375
|
|
|
@@ -1142,8 +1425,9 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1142
1425
|
|
|
1143
1426
|
#renderItemMenu(item: CollectionManagerItem) {
|
|
1144
1427
|
const collection = item.collection;
|
|
1428
|
+
const smartCollection = item.smartCollection;
|
|
1145
1429
|
const isLink = item.type === "link" && !!item.label && !!item.url;
|
|
1146
|
-
if (!collection && !isLink) return nothing;
|
|
1430
|
+
if (!collection && !smartCollection && !isLink) return nothing;
|
|
1147
1431
|
|
|
1148
1432
|
const isOpen = this._showItemMenuId === item.id;
|
|
1149
1433
|
|
|
@@ -1179,85 +1463,165 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1179
1463
|
<circle cx="19" cy="12" r="2" />
|
|
1180
1464
|
</svg>
|
|
1181
1465
|
</button>
|
|
1182
|
-
${
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1466
|
+
${
|
|
1467
|
+
isOpen
|
|
1468
|
+
? html`
|
|
1469
|
+
<div
|
|
1470
|
+
class="collections-page-menu"
|
|
1471
|
+
@click=${(e: Event) => e.stopPropagation()}
|
|
1472
|
+
>
|
|
1473
|
+
${
|
|
1474
|
+
smartCollection
|
|
1475
|
+
? html`
|
|
1476
|
+
<!-- Opens the dialog, not an editor page: creating and
|
|
1477
|
+
editing a smart collection are one surface. There is
|
|
1478
|
+
deliberately no "Remove from Collections" — a
|
|
1479
|
+
directory row is only a position, and deleting it
|
|
1480
|
+
would move the entry to the end rather than hide it,
|
|
1481
|
+
so the menu item would not do what it says. -->
|
|
1482
|
+
<button
|
|
1483
|
+
type="button"
|
|
1484
|
+
class="collections-page-menu-item"
|
|
1485
|
+
@click=${() => {
|
|
1486
|
+
this._showItemMenuId = null;
|
|
1487
|
+
document.removeEventListener(
|
|
1488
|
+
"click",
|
|
1489
|
+
this.#closeItemMenu,
|
|
1490
|
+
);
|
|
1491
|
+
void openSmartCollectionDialog({
|
|
1492
|
+
smartCollectionId: smartCollection.id,
|
|
1493
|
+
}).then((changed) => {
|
|
1494
|
+
if (changed) void this.#refreshList();
|
|
1495
|
+
});
|
|
1496
|
+
}}
|
|
1497
|
+
>
|
|
1498
|
+
${this.labels.edit}
|
|
1499
|
+
</button>
|
|
1500
|
+
${
|
|
1501
|
+
this.navigationCollectionIds.includes(
|
|
1502
|
+
smartCollection.id,
|
|
1503
|
+
)
|
|
1504
|
+
? html`
|
|
1505
|
+
<a
|
|
1506
|
+
href=${publicPath(NAVIGATION_SETTINGS_PATH)}
|
|
1507
|
+
class="collections-page-menu-item"
|
|
1508
|
+
>
|
|
1509
|
+
${this.labels.editNavigation}
|
|
1510
|
+
</a>
|
|
1511
|
+
`
|
|
1512
|
+
: html`
|
|
1513
|
+
<button
|
|
1514
|
+
type="button"
|
|
1515
|
+
class="collections-page-menu-item"
|
|
1516
|
+
?disabled=${
|
|
1517
|
+
this._addingToNavigationId ===
|
|
1518
|
+
smartCollection.id
|
|
1519
|
+
}
|
|
1520
|
+
@click=${() =>
|
|
1521
|
+
void this.#addToNavigation(
|
|
1522
|
+
smartCollection.id,
|
|
1523
|
+
addSmartCollectionToNavigation,
|
|
1524
|
+
)}
|
|
1525
|
+
>
|
|
1526
|
+
${
|
|
1527
|
+
this._addingToNavigationId ===
|
|
1528
|
+
smartCollection.id
|
|
1529
|
+
? this.labels.addingToNavigation
|
|
1530
|
+
: this.labels.addToNavigation
|
|
1531
|
+
}
|
|
1532
|
+
</button>
|
|
1533
|
+
`
|
|
1534
|
+
}
|
|
1535
|
+
<button
|
|
1536
|
+
type="button"
|
|
1537
|
+
class="collections-page-menu-item collections-page-menu-item-danger"
|
|
1538
|
+
@click=${() =>
|
|
1539
|
+
void this.#deleteSmartCollection(smartCollection)}
|
|
1540
|
+
>
|
|
1541
|
+
${this.labels.deleteSmartCollection}
|
|
1542
|
+
</button>
|
|
1543
|
+
`
|
|
1544
|
+
: collection
|
|
1203
1545
|
? html`
|
|
1204
|
-
<
|
|
1205
|
-
|
|
1546
|
+
<button
|
|
1547
|
+
type="button"
|
|
1206
1548
|
class="collections-page-menu-item"
|
|
1549
|
+
@click=${() =>
|
|
1550
|
+
void this.#editCollection(collection.id)}
|
|
1207
1551
|
>
|
|
1208
|
-
${this.labels.
|
|
1209
|
-
</
|
|
1552
|
+
${this.labels.edit}
|
|
1553
|
+
</button>
|
|
1554
|
+
${
|
|
1555
|
+
this.navigationCollectionIds.includes(
|
|
1556
|
+
collection.id,
|
|
1557
|
+
)
|
|
1558
|
+
? html`
|
|
1559
|
+
<a
|
|
1560
|
+
href=${publicPath(NAVIGATION_SETTINGS_PATH)}
|
|
1561
|
+
class="collections-page-menu-item"
|
|
1562
|
+
>
|
|
1563
|
+
${this.labels.editNavigation}
|
|
1564
|
+
</a>
|
|
1565
|
+
`
|
|
1566
|
+
: html`
|
|
1567
|
+
<button
|
|
1568
|
+
type="button"
|
|
1569
|
+
class="collections-page-menu-item"
|
|
1570
|
+
?disabled=${
|
|
1571
|
+
this._addingToNavigationId ===
|
|
1572
|
+
collection.id
|
|
1573
|
+
}
|
|
1574
|
+
@click=${() =>
|
|
1575
|
+
void this.#addToNavigation(
|
|
1576
|
+
collection.id,
|
|
1577
|
+
addCollectionToNavigation,
|
|
1578
|
+
)}
|
|
1579
|
+
>
|
|
1580
|
+
${
|
|
1581
|
+
this._addingToNavigationId ===
|
|
1582
|
+
collection.id
|
|
1583
|
+
? this.labels.addingToNavigation
|
|
1584
|
+
: this.labels.addToNavigation
|
|
1585
|
+
}
|
|
1586
|
+
</button>
|
|
1587
|
+
`
|
|
1588
|
+
}
|
|
1589
|
+
<button
|
|
1590
|
+
type="button"
|
|
1591
|
+
class="collections-page-menu-item collections-page-menu-item-danger"
|
|
1592
|
+
@click=${() => this.#deleteCollection(collection)}
|
|
1593
|
+
>
|
|
1594
|
+
${this.labels.deleteCollection}
|
|
1595
|
+
</button>
|
|
1210
1596
|
`
|
|
1211
1597
|
: html`
|
|
1212
1598
|
<button
|
|
1213
1599
|
type="button"
|
|
1214
1600
|
class="collections-page-menu-item"
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
)
|
|
1601
|
+
@click=${() => {
|
|
1602
|
+
this._showItemMenuId = null;
|
|
1603
|
+
document.removeEventListener(
|
|
1604
|
+
"click",
|
|
1605
|
+
this.#closeItemMenu,
|
|
1606
|
+
);
|
|
1607
|
+
this.#toggleLinkEdit(item);
|
|
1608
|
+
}}
|
|
1221
1609
|
>
|
|
1222
|
-
${this.
|
|
1223
|
-
? this.labels.addingToNavigation
|
|
1224
|
-
: this.labels.addToNavigation}
|
|
1610
|
+
${this.labels.edit}
|
|
1225
1611
|
</button>
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
@click=${() => {
|
|
1240
|
-
this._showItemMenuId = null;
|
|
1241
|
-
document.removeEventListener(
|
|
1242
|
-
"click",
|
|
1243
|
-
this.#closeItemMenu,
|
|
1244
|
-
);
|
|
1245
|
-
this.#toggleLinkEdit(item);
|
|
1246
|
-
}}
|
|
1247
|
-
>
|
|
1248
|
-
${this.labels.edit}
|
|
1249
|
-
</button>
|
|
1250
|
-
<button
|
|
1251
|
-
type="button"
|
|
1252
|
-
class="collections-page-menu-item collections-page-menu-item-danger"
|
|
1253
|
-
@click=${() => this.#deleteLink(item)}
|
|
1254
|
-
>
|
|
1255
|
-
${this.labels.deleteLink}
|
|
1256
|
-
</button>
|
|
1257
|
-
`}
|
|
1258
|
-
</div>
|
|
1259
|
-
`
|
|
1260
|
-
: nothing}
|
|
1612
|
+
<button
|
|
1613
|
+
type="button"
|
|
1614
|
+
class="collections-page-menu-item collections-page-menu-item-danger"
|
|
1615
|
+
@click=${() => this.#deleteLink(item)}
|
|
1616
|
+
>
|
|
1617
|
+
${this.labels.deleteLink}
|
|
1618
|
+
</button>
|
|
1619
|
+
`
|
|
1620
|
+
}
|
|
1621
|
+
</div>
|
|
1622
|
+
`
|
|
1623
|
+
: nothing
|
|
1624
|
+
}
|
|
1261
1625
|
</div>
|
|
1262
1626
|
`;
|
|
1263
1627
|
}
|
|
@@ -1351,27 +1715,31 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1351
1715
|
class="collection-directory-divider-row"
|
|
1352
1716
|
aria-hidden=${hasLabel ? nothing : "true"}
|
|
1353
1717
|
>
|
|
1354
|
-
${
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1718
|
+
${
|
|
1719
|
+
hasLabel
|
|
1720
|
+
? html`
|
|
1721
|
+
${
|
|
1722
|
+
group
|
|
1723
|
+
? html`
|
|
1724
|
+
<a
|
|
1725
|
+
href=${viewPath(
|
|
1726
|
+
getCollectionSelectionPath(group.slugExpression),
|
|
1727
|
+
)}
|
|
1728
|
+
class="collection-directory-divider-link collection-directory-divider-text"
|
|
1729
|
+
>
|
|
1730
|
+
${item.label}
|
|
1731
|
+
</a>
|
|
1732
|
+
`
|
|
1733
|
+
: html`
|
|
1734
|
+
<span class="collection-directory-divider-text">
|
|
1735
|
+
${item.label}
|
|
1736
|
+
</span>
|
|
1737
|
+
`
|
|
1738
|
+
}
|
|
1739
|
+
<hr class="collection-directory-divider-line" />
|
|
1740
|
+
`
|
|
1741
|
+
: html`<hr class="collection-directory-divider-line" />`
|
|
1742
|
+
}
|
|
1375
1743
|
</div>
|
|
1376
1744
|
</div>
|
|
1377
1745
|
`;
|
|
@@ -1476,33 +1844,42 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1476
1844
|
id="collection-created-notice-title"
|
|
1477
1845
|
class="collection-created-notice-message"
|
|
1478
1846
|
>
|
|
1479
|
-
${
|
|
1480
|
-
|
|
1481
|
-
|
|
1847
|
+
${
|
|
1848
|
+
isInNavigation
|
|
1849
|
+
? this.labels.addedToNavigation
|
|
1850
|
+
: this.labels.formLabels.createdLabel
|
|
1851
|
+
}
|
|
1482
1852
|
</p>
|
|
1483
1853
|
<div class="collection-created-notice-actions">
|
|
1484
|
-
${
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1854
|
+
${
|
|
1855
|
+
isInNavigation
|
|
1856
|
+
? html`
|
|
1857
|
+
<a
|
|
1858
|
+
href=${publicPath(NAVIGATION_SETTINGS_PATH)}
|
|
1859
|
+
class="collection-created-notice-action collection-created-notice-action-primary"
|
|
1860
|
+
>
|
|
1861
|
+
${this.labels.editNavigation}
|
|
1862
|
+
</a>
|
|
1863
|
+
`
|
|
1864
|
+
: html`
|
|
1865
|
+
<button
|
|
1866
|
+
type="button"
|
|
1867
|
+
class="collection-created-notice-action collection-created-notice-action-primary"
|
|
1868
|
+
?disabled=${this._addingToNavigationId === collection.id}
|
|
1869
|
+
@click=${() =>
|
|
1870
|
+
void this.#addToNavigation(
|
|
1871
|
+
collection.id,
|
|
1872
|
+
addCollectionToNavigation,
|
|
1873
|
+
)}
|
|
1874
|
+
>
|
|
1875
|
+
${
|
|
1876
|
+
this._addingToNavigationId === collection.id
|
|
1877
|
+
? this.labels.addingToNavigation
|
|
1878
|
+
: this.labels.addToNavigation
|
|
1879
|
+
}
|
|
1880
|
+
</button>
|
|
1881
|
+
`
|
|
1882
|
+
}
|
|
1506
1883
|
<button
|
|
1507
1884
|
type="button"
|
|
1508
1885
|
class="collection-created-notice-dismiss"
|
|
@@ -1536,24 +1913,32 @@ export class JantCollectionsManager extends LitElement {
|
|
|
1536
1913
|
render() {
|
|
1537
1914
|
return html`
|
|
1538
1915
|
${this.#renderCreatedCollectionNotice()} ${this.#renderCreateLinkForm()}
|
|
1539
|
-
${
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1916
|
+
${
|
|
1917
|
+
this.#hasDirectoryContent()
|
|
1918
|
+
? html`
|
|
1919
|
+
<div id="collections-manager-list" class="collection-directory">
|
|
1920
|
+
${(() => {
|
|
1921
|
+
const labels = this.#computeSequenceLabels();
|
|
1922
|
+
return this._items.map((item, index) => {
|
|
1923
|
+
if (item.type === "collection") {
|
|
1924
|
+
return this.#renderCollectionItem(item, labels[index]);
|
|
1925
|
+
}
|
|
1926
|
+
if (item.type === "smart_collection") {
|
|
1927
|
+
return this.#renderSmartCollectionItem(
|
|
1928
|
+
item,
|
|
1929
|
+
labels[index],
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1932
|
+
if (item.type === "link") {
|
|
1933
|
+
return this.#renderLinkItem(item, labels[index]);
|
|
1934
|
+
}
|
|
1935
|
+
return this.#renderDividerItem(item, index);
|
|
1936
|
+
});
|
|
1937
|
+
})()}
|
|
1938
|
+
</div>
|
|
1939
|
+
`
|
|
1940
|
+
: html`<p class="text-muted-foreground">${this.labels.emptyState}</p>`
|
|
1941
|
+
}
|
|
1557
1942
|
`;
|
|
1558
1943
|
}
|
|
1559
1944
|
}
|