@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
|
@@ -0,0 +1,1112 @@
|
|
|
1
|
+
import{h as e,i as t,n,s as r,t as i,u as a}from"./chunks/lit-DW8VmJAT.js";import{a as o,i as s,r as c,s as l,t as u}from"./chunks/jant-locale-picker-DL6mIOT5.js";import{n as d}from"./chunks/confirm-D7GrwsCN.js";import{_ as f,d as p,h as m,l as h,m as g,p as _,u as v}from"./chunks/types-D5iF3H1a.js";import{r as y,t as b}from"./chunks/create-editor-CD3FhrOB.js";var x={ICO_16:16,ICO_32:32,APPLE_TOUCH:512};function S(e){let t=e.length*16,n=6+t,r=new ArrayBuffer(6+t),i=new DataView(r);i.setUint16(0,0,!0),i.setUint16(2,1,!0),i.setUint16(4,e.length,!0);let a=[];for(let t=0;t<e.length;t++){let r=e[t],o=6+t*16;i.setUint8(o+0,r.size<256?r.size:0),i.setUint8(o+1,r.size<256?r.size:0),i.setUint8(o+2,0),i.setUint8(o+3,0),i.setUint16(o+4,1,!0),i.setUint16(o+6,32,!0),i.setUint32(o+8,r.png.byteLength,!0),i.setUint32(o+12,n,!0),n+=r.png.byteLength,a.push(r.png)}return new Blob([r,...a],{type:`image/x-icon`})}var C=180;function w(e){return new Promise((t,n)=>{let r=new Image;r.onload=()=>{URL.revokeObjectURL(r.src),t(r)},r.onerror=()=>n(Error(`Failed to load image`)),r.src=URL.createObjectURL(e)})}function T(e,t){let n=document.createElement(`canvas`);n.width=t,n.height=t;let r=n.getContext(`2d`);if(!r)throw Error(`Failed to get canvas context`);r.imageSmoothingEnabled=!0,r.imageSmoothingQuality=`high`;let i=Math.max(t/e.width,t/e.height),a=t/i,o=t/i,s=(e.width-a)/2,c=(e.height-o)/2;return r.drawImage(e,s,c,a,o,0,0,t,t),new Promise((e,t)=>{n.toBlob(n=>{n?e(n):t(Error(`Failed to create PNG blob`))},`image/png`)})}function E(e,t){return e.type===`image/png`&&t.width===t.height&&t.width>=C&&t.height>=C}async function D(t,n){let r=t.closest(`form`)?.querySelector(`label`),i=r?.textContent??``;try{r&&(r.textContent=t.dataset.textProcessing||`Processing...`);let i=await w(n),a=n,o=n.name;if(n.type!==`image/svg+xml`){let e=await T(i,512);a=new File([e],n.name.replace(/\.[^.]+$/,`.png`),{type:`image/png`}),o=a.name}let s=E(n,i)?Promise.resolve(n):T(i,x.APPLE_TOUCH),[c,l,u]=await Promise.all([T(i,16),T(i,32),s]),[d,p]=await Promise.all([c.arrayBuffer(),l.arrayBuffer()]),m=S([{size:16,png:d},{size:32,png:p}]);r&&(r.textContent=t.dataset.textUploading||`Uploading...`);let h=new FormData;h.append(`file`,a,o),h.append(`favicon`,m,`favicon.ico`),h.append(`appleTouch`,u,`apple-touch-icon.png`);let g=await fetch(e(`/settings/avatar`),{method:`POST`,headers:{Accept:`application/json`},body:h});if(!g.ok){let e=t.dataset.textError||`Upload failed. Please try again.`;try{let t=await f(g);e=_(t,`error`)??_(t,`message`)??e}catch{}throw Error(e)}let v=await f(g),y=_(v,`status`),b=_(v,`url`);if(y===`redirect`&&b){window.location.href=b;return}window.location.href=e(`/settings/avatar?saved`)}catch(e){r&&(r.textContent=i),a(e instanceof Error&&e.message?e.message:t.dataset.textError||`Upload failed. Please try again.`,`error`)}t.value=``}function O(){document.addEventListener(`change`,e=>{let t=e.target.closest(`[data-avatar-upload]`);t?.files?.[0]&&(e.stopPropagation(),D(t,t.files[0]))})}O();var k=[`latest`,`featured`,`off`];function A(e){let t=e?.trim();return t&&k.includes(t)?t:null}function ee(e){if(e.demoMode||!e.rssFeedsEnabled)return`none`;let t=A(e.storedValue);if(t)return t===`off`?`none`:t;if(e.noindex)return`none`;let n=A(e.defaultValue);return n?n===`off`?`none`:n:`none`}var j={links:`Links`,quotes:`Quotes`};function M(e,t){let n=[],r=t.filter(e=>e.term&&e.href).sort((e,t)=>t.term.length-e.term.length);for(let{term:t,href:i}of r)for(let r=e.indexOf(t);r!==-1;r=e.indexOf(t,r+1)){let e=r+t.length;if(!n.some(t=>r<t.end&&t.start<e)){n.push({start:r,end:e,href:i});break}}n.sort((e,t)=>e.start-t.start);let i=[],a=0;for(let{start:t,end:r,href:o}of n)t>a&&i.push({text:e.slice(a,t)}),i.push({text:e.slice(t,r),href:o}),a=r;return a<e.length&&i.push({text:e.slice(a)}),i}function N(e,t,n){return n?M(e,[{term:t.name,href:n.home},{term:j.links,href:n.links},{term:j.quotes,href:n.quotes},{term:t.rules,href:n.rules}]):[{text:e}]}var P=`flex flex-col py-8 first:pt-0 last:pb-0`,F=class extends i{static properties={labels:{type:Object},timezones:{type:Array},siteNameFallback:{type:String,attribute:`sitename-fallback`},siteDescriptionFallback:{type:String,attribute:`sitedescription-fallback`},demoMode:{type:Boolean,attribute:`demo-mode`},discoverDefault:{type:String,attribute:`discover-default`},discoverPages:{type:Object,attribute:`discover-pages`},discoverStatus:{type:String,attribute:`discover-status`},feedsEnabled:{type:Boolean,attribute:`feeds-enabled`},mainFeedUrl:{type:String,attribute:`main-feed-url`},latestFeedUrl:{type:String,attribute:`latest-feed-url`},featuredFeedUrl:{type:String,attribute:`featured-feed-url`},archiveFeedUrl:{type:String,attribute:`archive-feed-url`},feedsDocsUrl:{type:String,attribute:`feeds-docs-url`},aboutPage:{type:Object,attribute:`about-page`},aboutEditUrl:{type:String,attribute:`about-edit-url`},aboutCreateUrl:{type:String,attribute:`about-create-url`},_siteName:{state:!0},_siteDescription:{state:!0},_siteFooter:{state:!0},_origSite:{state:!0},_siteDirty:{state:!0},_siteLoading:{state:!0},_timeZone:{state:!0},_origLocale:{state:!0},_localeDirty:{state:!0},_localeLoading:{state:!0},_mainRssFeed:{state:!0},_origMainRssFeed:{state:!0},_feedLoading:{state:!0},_showJantBrandingOnHome:{state:!0},_origShowJantBrandingOnHome:{state:!0},_homeLoading:{state:!0},_noindex:{state:!0},_origNoindex:{state:!0},_searchLoading:{state:!0},_discover:{state:!0},_origDiscover:{state:!0},_discoverLoading:{state:!0}};_descEditor=null;_footerEditor=null;createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.labels={},this.timezones=[],this.siteNameFallback=``,this.siteDescriptionFallback=``,this.demoMode=!1,this.mainFeedUrl=`/feed`,this.latestFeedUrl=`/latest/feed`,this.featuredFeedUrl=`/featured/feed`,this.archiveFeedUrl=`/archive/feed`,this.feedsDocsUrl=``,this.aboutPage={state:`missing`,path:`/about`},this.aboutEditUrl=`/about?edit=1`,this.aboutCreateUrl=`/settings/general/about-page`,this._siteName=``,this._siteDescription=``,this._siteFooter=``,this._origSite={siteName:``,siteDescription:``,siteFooter:``},this._siteDirty=!1,this._siteLoading=!1,this._timeZone=`UTC`,this._origLocale={timeZone:`UTC`},this._localeDirty=!1,this._localeLoading=!1,this._mainRssFeed=`featured`,this._origMainRssFeed=`featured`,this._feedLoading=!1,this._noindex=!1,this._origNoindex=!1,this._showJantBrandingOnHome=!1,this._origShowJantBrandingOnHome=!1,this._homeLoading=!1,this._searchLoading=!1,this.discoverDefault=``,this.discoverPages=null,this.discoverStatus=``,this.feedsEnabled=!1,this._discover=``,this._origDiscover=``,this._discoverLoading=!1}connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this._descEditor?.destroy(),this._descEditor=null,this._footerEditor?.destroy(),this._footerEditor=null}initData(e){this._siteName=e.siteName,this._siteDescription=e.siteDescription,this._siteFooter=e.siteFooter,this._timeZone=e.timeZone,this._origLocale={timeZone:e.timeZone},this._mainRssFeed=e.mainRssFeed,this._origMainRssFeed=e.mainRssFeed,this._showJantBrandingOnHome=e.showJantBrandingOnHome,this._origShowJantBrandingOnHome=e.showJantBrandingOnHome,this._noindex=e.noindex,this._origNoindex=e.noindex,this._discover=e.discover,this._origDiscover=e.discover,this.updateComplete.then(()=>{this._initEditors(),this._origSite={siteName:e.siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter}})}sectionSaved(e){e===`site`?(this._origSite={siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},this._siteDirty=!1,this._siteLoading=!1):e===`time`?(this._origLocale={timeZone:this._timeZone},this._localeDirty=!1,this._localeLoading=!1):e===`feeds`?(this._origMainRssFeed=this._mainRssFeed,this._feedLoading=!1):e===`home`?(this._origShowJantBrandingOnHome=this._showJantBrandingOnHome,this._homeLoading=!1):e===`search`?(this._origNoindex=this._noindex,this._searchLoading=!1):e===`discover`&&(this._origDiscover=this._discover,this._discoverLoading=!1)}sectionError(e){e===`site`?this._siteLoading=!1:e===`time`?this._localeLoading=!1:e===`feeds`?(this._mainRssFeed=this._origMainRssFeed,this._feedLoading=!1):e===`home`?(this._showJantBrandingOnHome=this._origShowJantBrandingOnHome,this._homeLoading=!1):e===`search`?(this._noindex=this._origNoindex,this._searchLoading=!1):e===`discover`&&(this._discover=this._origDiscover,this._discoverLoading=!1)}_initEditors(){this._initDescEditor(),this._initFooterEditor()}_initDescEditor(){let e=this.querySelector(`[data-settings-desc-editor]`);if(!e||this._descEditor)return;this._descEditor=b({element:e,placeholder:this.siteDescriptionFallback,content:this._siteDescription||void 0,onUpdate:e=>{this._siteDescription=e,this._syncSiteDirty()}}),this._siteDescription=y(this._descEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`3rem`)}_initFooterEditor(){let e=this.querySelector(`[data-settings-footer-editor]`);if(!e||this._footerEditor)return;this._footerEditor=b({element:e,content:this._siteFooter||void 0,onUpdate:e=>{this._siteFooter=e,this._syncSiteDirty()}}),this._siteFooter=y(this._footerEditor.getJSON());let t=e.querySelector(`.ProseMirror`);t&&(t.style.outline=`none`,t.style.minHeight=`6rem`)}_syncSiteDirty(){this._siteDirty=this._siteName!==this._origSite.siteName||this._siteDescription!==this._origSite.siteDescription||this._siteFooter!==this._origSite.siteFooter}_saveSite(){!this._siteLoading&&this._siteDirty&&(this._siteLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general`,data:{siteName:this._siteName,siteDescription:this._siteDescription,siteFooter:this._siteFooter},section:`site`}})))}_syncLocaleDirty(){this._localeDirty=this._timeZone!==this._origLocale.timeZone}_saveLocale(){!this._localeLoading&&this._localeDirty&&(this._localeLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/time`,data:{timeZone:this._timeZone},section:`time`}})))}_saveMainRssFeed(e){this._feedLoading||e===this._mainRssFeed||(this._mainRssFeed=e,this._feedLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/feeds`,data:{mainRssFeed:e},section:`feeds`}})))}_saveHomeToggle(e){this._homeLoading||(this._showJantBrandingOnHome=e,this._homeLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/home`,data:{showJantBrandingOnHome:e},section:`home`}})))}_saveSearchToggle(e){this.demoMode||this._searchLoading||(this._noindex=!e,this._searchLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/search`,data:{allowIndexing:e},section:`search`}})))}_effectiveDiscoverMode(e={}){return ee({storedValue:this._discover||null,defaultValue:this.discoverDefault||null,demoMode:this.demoMode,noindex:e.noindex??this._noindex,rssFeedsEnabled:this.feedsEnabled})}_onDiscoverToggle(e){this._saveDiscover(e?`latest`:`off`)}_saveDiscover(e){this._discoverLoading||(this._discover=e,this._discoverLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/discover`,data:{discover:e},section:`discover`}})))}_onKeydown(e,t,n,r){e.isComposing||e.keyCode===229||e.key===`Enter`&&!r&&n&&!(e.target instanceof HTMLTextAreaElement)&&(e.preventDefault(),t())}_renderSaveAction(e,r,i){return t`
|
|
2
|
+
<div class="flex mt-4">
|
|
3
|
+
<button
|
|
4
|
+
type="button"
|
|
5
|
+
class="btn"
|
|
6
|
+
?disabled=${e||!r}
|
|
7
|
+
@click=${i}
|
|
8
|
+
>
|
|
9
|
+
${e?t`<svg
|
|
10
|
+
class="animate-spin size-4"
|
|
11
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
12
|
+
viewBox="0 0 24 24"
|
|
13
|
+
fill="none"
|
|
14
|
+
stroke="currentColor"
|
|
15
|
+
stroke-width="2"
|
|
16
|
+
stroke-linecap="round"
|
|
17
|
+
stroke-linejoin="round"
|
|
18
|
+
role="status"
|
|
19
|
+
>
|
|
20
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
21
|
+
</svg>`:n}
|
|
22
|
+
${this.labels.save}
|
|
23
|
+
</button>
|
|
24
|
+
</div>
|
|
25
|
+
`}_renderSectionTitle(e){return t`<h3 class="text-sm font-semibold tracking-[0.01em]">
|
|
26
|
+
${e}
|
|
27
|
+
</h3>`}_renderMainRssFeedOption(e,n,r){let i=this._mainRssFeed===e;return t`
|
|
28
|
+
<label
|
|
29
|
+
class=${`flex items-start gap-3 rounded-xl border p-3 cursor-pointer transition-colors ${i?`border-primary`:`border-border`}`}
|
|
30
|
+
>
|
|
31
|
+
<input
|
|
32
|
+
type="radio"
|
|
33
|
+
name="main-rss-feed"
|
|
34
|
+
value=${e}
|
|
35
|
+
class="mt-1"
|
|
36
|
+
.checked=${i}
|
|
37
|
+
?disabled=${this._feedLoading}
|
|
38
|
+
@change=${()=>this._saveMainRssFeed(e)}
|
|
39
|
+
/>
|
|
40
|
+
<div>
|
|
41
|
+
<div class="font-medium">${n}</div>
|
|
42
|
+
<div class="text-sm text-muted-foreground">${r}</div>
|
|
43
|
+
</div>
|
|
44
|
+
</label>
|
|
45
|
+
`}_renderFeedUrl(e,n,r){return t`
|
|
46
|
+
<div class=${s} data-copy-field-root>
|
|
47
|
+
<p class="text-sm font-medium">${e}</p>
|
|
48
|
+
${r?t`<p class="text-sm text-muted-foreground">${r}</p>`:``}
|
|
49
|
+
<div class=${o}>
|
|
50
|
+
<input
|
|
51
|
+
type="text"
|
|
52
|
+
class=${l}
|
|
53
|
+
.value=${n}
|
|
54
|
+
readonly
|
|
55
|
+
aria-label=${e}
|
|
56
|
+
data-copy-field-value
|
|
57
|
+
/>
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
class=${c}
|
|
61
|
+
data-copy-field=${this.labels.feedUrlCopied}
|
|
62
|
+
data-copy-field-failed=${this.labels.copyFailed}
|
|
63
|
+
>
|
|
64
|
+
${this.labels.copy}
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
`}_renderAboutPageRow(){let e=this.aboutPage;return t`
|
|
69
|
+
<div class="mt-2 text-sm text-muted-foreground" data-about-page-row>
|
|
70
|
+
${this.labels.aboutPagePrompt}
|
|
71
|
+
${e.state===`ready`?t`
|
|
72
|
+
<a
|
|
73
|
+
class="font-medium text-foreground underline-offset-4 hover:underline"
|
|
74
|
+
href=${this.aboutEditUrl}
|
|
75
|
+
>
|
|
76
|
+
${this.labels.editAboutPage}
|
|
77
|
+
</a>
|
|
78
|
+
`:e.state===`missing`?t`
|
|
79
|
+
<form
|
|
80
|
+
class="inline"
|
|
81
|
+
method="post"
|
|
82
|
+
action=${this.aboutCreateUrl}
|
|
83
|
+
>
|
|
84
|
+
<button
|
|
85
|
+
type="submit"
|
|
86
|
+
class="inline cursor-pointer border-0 bg-transparent p-0 font-medium text-foreground underline-offset-4 hover:underline"
|
|
87
|
+
>
|
|
88
|
+
${this.labels.createAboutPage}
|
|
89
|
+
</button>
|
|
90
|
+
</form>
|
|
91
|
+
`:t`
|
|
92
|
+
<span class="text-destructive"
|
|
93
|
+
>${this.labels.aboutPageConflict}</span
|
|
94
|
+
>
|
|
95
|
+
`}
|
|
96
|
+
</div>
|
|
97
|
+
`}_renderSiteSection(){return t`
|
|
98
|
+
<section
|
|
99
|
+
class="${P} gap-4"
|
|
100
|
+
@keydown=${e=>this._onKeydown(e,()=>this._saveSite(),this._siteDirty,this._siteLoading)}
|
|
101
|
+
>
|
|
102
|
+
${this._renderSectionTitle(this.labels.site)}
|
|
103
|
+
<div class="field">
|
|
104
|
+
<label class="label">${this.labels.siteName}</label>
|
|
105
|
+
<input
|
|
106
|
+
type="text"
|
|
107
|
+
class="input"
|
|
108
|
+
maxlength=${120}
|
|
109
|
+
.value=${this._siteName}
|
|
110
|
+
placeholder=${this.siteNameFallback}
|
|
111
|
+
@input=${e=>{this._siteName=e.target.value,this._syncSiteDirty()}}
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div class="field">
|
|
116
|
+
<label class="label">${this.labels.aboutBlog}</label>
|
|
117
|
+
<div class="settings-tiptap-editor" data-settings-desc-editor></div>
|
|
118
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
119
|
+
${this.labels.aboutBlogHelp}
|
|
120
|
+
</p>
|
|
121
|
+
${this._renderAboutPageRow()}
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="field">
|
|
125
|
+
<label class="label">${this.labels.siteFooter}</label>
|
|
126
|
+
<div class="settings-tiptap-editor" data-settings-footer-editor></div>
|
|
127
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
128
|
+
${this.labels.footerHelp}
|
|
129
|
+
</p>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
${this._renderSaveAction(this._siteLoading,this._siteDirty,()=>this._saveSite())}
|
|
133
|
+
</section>
|
|
134
|
+
`}_renderVisibilitySection(){return t`
|
|
135
|
+
<section class="${P} gap-6">
|
|
136
|
+
${this._renderSectionTitle(this.labels.siteVisibility)}
|
|
137
|
+
<div class="flex flex-col gap-2">
|
|
138
|
+
<label class="flex items-center gap-2 cursor-pointer">
|
|
139
|
+
<input
|
|
140
|
+
type="checkbox"
|
|
141
|
+
class="checkbox"
|
|
142
|
+
.checked=${!this._noindex}
|
|
143
|
+
?disabled=${this.demoMode||this._searchLoading}
|
|
144
|
+
@change=${e=>this._saveSearchToggle(e.target.checked)}
|
|
145
|
+
/>
|
|
146
|
+
<span>${this.labels.allowIndexing}</span>
|
|
147
|
+
</label>
|
|
148
|
+
${this.demoMode?t`<p class="text-sm text-muted-foreground">
|
|
149
|
+
${this.labels.demoSeoLocked}
|
|
150
|
+
</p>`:n}
|
|
151
|
+
</div>
|
|
152
|
+
${this._renderDiscoverForm()}
|
|
153
|
+
</section>
|
|
154
|
+
`}_renderFeedsSection(){return t`
|
|
155
|
+
<section class="${P} gap-4">
|
|
156
|
+
${this._renderSectionTitle(this.labels.feeds)}
|
|
157
|
+
<div class="field">
|
|
158
|
+
<p class="label">${this.labels.mainRssFeed}</p>
|
|
159
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
160
|
+
${this.labels.mainRssFeedHelp}
|
|
161
|
+
</p>
|
|
162
|
+
<div class="mt-3 flex flex-col gap-2">
|
|
163
|
+
${this._renderMainRssFeedOption(`featured`,this.labels.featuredFeedOption,this.labels.featuredFeedOptionDescription)}
|
|
164
|
+
${this._renderMainRssFeedOption(`latest`,this.labels.latestFeedOption,this.labels.latestFeedOptionDescription)}
|
|
165
|
+
</div>
|
|
166
|
+
<p class="text-sm text-muted-foreground mt-2">
|
|
167
|
+
${this.labels.mainRssFeedWarning}
|
|
168
|
+
</p>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div class="rounded-xl border border-border/70 bg-muted/30 p-4">
|
|
172
|
+
<div class="flex flex-col gap-4">
|
|
173
|
+
<div class="flex flex-col gap-1">
|
|
174
|
+
<p class="text-sm font-medium">
|
|
175
|
+
${this.labels.availableFeedUrls}
|
|
176
|
+
</p>
|
|
177
|
+
<p class="text-sm text-muted-foreground">
|
|
178
|
+
${this.labels.availableFeedUrlsHelp}
|
|
179
|
+
${this.feedsDocsUrl?t`
|
|
180
|
+
<a
|
|
181
|
+
href=${this.feedsDocsUrl}
|
|
182
|
+
target="_blank"
|
|
183
|
+
rel="noopener noreferrer"
|
|
184
|
+
class="underline hover:text-foreground transition-colors"
|
|
185
|
+
>${this.labels.feedsDocs}</a
|
|
186
|
+
>
|
|
187
|
+
`:``}
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
${this._renderFeedUrl(this.labels.mainFeedUrl,this.mainFeedUrl)}
|
|
192
|
+
${this._renderFeedUrl(this.labels.latestFeedUrl,this.latestFeedUrl)}
|
|
193
|
+
${this._renderFeedUrl(this.labels.featuredFeedUrl,this.featuredFeedUrl)}
|
|
194
|
+
${this._renderFeedUrl(this.labels.archiveFeedUrl,this.archiveFeedUrl,this.labels.archiveFeedUrlHelp)}
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</section>
|
|
198
|
+
`}_renderTimeSection(){return t`
|
|
199
|
+
<section
|
|
200
|
+
class="${P} gap-4"
|
|
201
|
+
@keydown=${e=>this._onKeydown(e,()=>this._saveLocale(),this._localeDirty,this._localeLoading)}
|
|
202
|
+
>
|
|
203
|
+
${this._renderSectionTitle(this.labels.timeSection)}
|
|
204
|
+
<div class="field">
|
|
205
|
+
<label class="label">${this.labels.timeZone}</label>
|
|
206
|
+
<select
|
|
207
|
+
class="select"
|
|
208
|
+
@change=${e=>{this._timeZone=e.target.value,this._syncLocaleDirty()}}
|
|
209
|
+
>
|
|
210
|
+
${this.timezones.map(e=>t`
|
|
211
|
+
<option
|
|
212
|
+
value=${e.value}
|
|
213
|
+
?selected=${this._timeZone===e.value}
|
|
214
|
+
>
|
|
215
|
+
${e.label}
|
|
216
|
+
</option>
|
|
217
|
+
`)}
|
|
218
|
+
</select>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
${this._renderSaveAction(this._localeLoading,this._localeDirty,()=>this._saveLocale())}
|
|
222
|
+
</section>
|
|
223
|
+
`}_renderHomeSection(){return t`
|
|
224
|
+
<section class="${P} gap-4">
|
|
225
|
+
${this._renderSectionTitle(this.labels.home)}
|
|
226
|
+
<label class="flex items-center gap-2 cursor-pointer">
|
|
227
|
+
<input
|
|
228
|
+
type="checkbox"
|
|
229
|
+
class="checkbox"
|
|
230
|
+
.checked=${this._showJantBrandingOnHome}
|
|
231
|
+
?disabled=${this._homeLoading}
|
|
232
|
+
@change=${e=>this._saveHomeToggle(e.target.checked)}
|
|
233
|
+
/>
|
|
234
|
+
<span>${this.labels.showJantBrandingOnHome}</span>
|
|
235
|
+
</label>
|
|
236
|
+
</section>
|
|
237
|
+
`}_renderDiscoverForm(){let e=this._effectiveDiscoverMode()!==`none`,r=this.demoMode||!this.feedsEnabled,i=!r&&!e&&this._effectiveDiscoverMode({noindex:!1})!==`none`;return t`
|
|
238
|
+
<div class="flex flex-col gap-3">
|
|
239
|
+
<div class="flex flex-col gap-2">
|
|
240
|
+
<label class="flex items-center gap-2 cursor-pointer">
|
|
241
|
+
<input
|
|
242
|
+
type="checkbox"
|
|
243
|
+
class="checkbox"
|
|
244
|
+
.checked=${e}
|
|
245
|
+
?disabled=${r||this._discoverLoading}
|
|
246
|
+
@change=${e=>this._onDiscoverToggle(e.target.checked)}
|
|
247
|
+
/>
|
|
248
|
+
<span>${this.labels.discoverEnabled}</span>
|
|
249
|
+
</label>
|
|
250
|
+
<p class="text-sm text-muted-foreground">
|
|
251
|
+
${r?this.demoMode?this.labels.discoverDemoLocked:this.labels.discoverFeedsOffLocked:this._renderDiscoverIntro()}
|
|
252
|
+
</p>
|
|
253
|
+
${i?t`<p class="text-sm text-muted-foreground">
|
|
254
|
+
${this.labels.discoverSearchOff}
|
|
255
|
+
</p>`:n}
|
|
256
|
+
</div>
|
|
257
|
+
${r?n:this._renderDiscoverStatus()}
|
|
258
|
+
</div>
|
|
259
|
+
`}_renderDiscoverIntro(){return N(this.labels.discoverIntro??``,{name:this.labels.discoverName??``,rules:this.labels.discoverRules??``},this.discoverPages).map(e=>e.href?t`<a
|
|
260
|
+
href=${e.href}
|
|
261
|
+
target="_blank"
|
|
262
|
+
rel="noopener noreferrer"
|
|
263
|
+
class="underline hover:text-foreground transition-colors"
|
|
264
|
+
>${e.text}</a
|
|
265
|
+
>`:e.text)}_renderDiscoverStatus(){let e=this._parsedDiscoverStatus();return!e||this._effectiveDiscoverMode()===`none`||e.lines.length===0&&!e.showAnnounce?n:t`
|
|
266
|
+
<div class="flex flex-col gap-1 border-t pt-3">
|
|
267
|
+
${e.lines.map(e=>t`<p class="text-sm text-muted-foreground">${e}</p>`)}
|
|
268
|
+
${e.showAnnounce?t`
|
|
269
|
+
<div class="flex flex-wrap items-center gap-3 mt-1">
|
|
270
|
+
<button
|
|
271
|
+
type="button"
|
|
272
|
+
class="btn-outline"
|
|
273
|
+
?disabled=${this._discoverLoading}
|
|
274
|
+
@click=${()=>this._announce()}
|
|
275
|
+
>
|
|
276
|
+
${this.labels.discoverAnnounce}
|
|
277
|
+
</button>
|
|
278
|
+
${e.submitUrl?t`<a
|
|
279
|
+
class="text-sm underline hover:text-foreground transition-colors"
|
|
280
|
+
href=${e.submitUrl}
|
|
281
|
+
target="_blank"
|
|
282
|
+
rel="noopener noreferrer"
|
|
283
|
+
>${this.labels.discoverAnnounceManual}</a
|
|
284
|
+
>`:n}
|
|
285
|
+
</div>
|
|
286
|
+
`:n}
|
|
287
|
+
</div>
|
|
288
|
+
`}_parsedDiscoverStatus(){if(!this.discoverStatus)return null;try{let e=JSON.parse(this.discoverStatus);if(typeof e!=`object`||!e)return null;let t=e;return{lines:Array.isArray(t.lines)?t.lines.filter(e=>typeof e==`string`):[],showAnnounce:t.showAnnounce===!0,submitUrl:typeof t.submitUrl==`string`?t.submitUrl:null}}catch{return null}}_announce(){this._discoverLoading||(this._discoverLoading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/general/discover/announce`,data:{},section:`discover`}})))}render(){return t`
|
|
289
|
+
<div class="flex flex-col gap-8">
|
|
290
|
+
<h2 class="text-lg font-semibold">${this.labels.general}</h2>
|
|
291
|
+
<div class="flex flex-col divide-y">
|
|
292
|
+
${this._renderSiteSection()} ${this._renderVisibilitySection()}
|
|
293
|
+
${this._renderFeedsSection()} ${this._renderTimeSection()}
|
|
294
|
+
${this._renderHomeSection()}
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
`}};customElements.define(`jant-settings-general`,F);var I=`${typeof __JANT_DEV__<`u`&&__JANT_DEV__===!0?`https://jant-cloud.localtest.me`:`https://jant.me`}/docs`;function L(e=``){return e?`${I}/${e}`:I}var R=[``,`en`,`zh-Hans`,`zh-Hant`],z=L(`multilingual`);function B(e,t){return e.replace(/\{(\w+)\}/g,(e,n)=>t[n]??e)}var V=class extends i{static properties={labels:{type:Object},locales:{type:Array},_contentLanguage:{state:!0},_dashboardLanguage:{state:!0},_multilingualEnabled:{state:!0},_additional:{state:!0},_unmarkedPostCount:{state:!0},_sitePathPrefix:{state:!0},_savingSite:{state:!0},_savingDashboard:{state:!0},_removeError:{state:!0},_rowMenuOpen:{state:!0},_enableError:{state:!0},_enableOpen:{state:!0},_enableAdditional:{state:!0},_enablePrimary:{state:!0},_enableBusy:{state:!0}};#e=z;createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.labels={},this.locales=[],this._contentLanguage=`en`,this._dashboardLanguage=``,this._multilingualEnabled=!1,this._additional=[],this._unmarkedPostCount=0,this._sitePathPrefix=``,this._savingSite=!1,this._savingDashboard=!1,this._removeError=null,this._rowMenuOpen=null,this._enableError=null,this._enableOpen=!1,this._enableAdditional=[],this._enablePrimary=`en`,this._enableBusy=!1}connectedCallback(){super.connectedCallback(),this.#t(),document.addEventListener(`click`,this.#s),document.addEventListener(`keydown`,this.#c)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`click`,this.#s),document.removeEventListener(`keydown`,this.#c)}#t(){let e=document.getElementById(`language-settings-initial-data`);if(!e?.textContent)return;let t;try{t=JSON.parse(e.textContent)}catch{return}let n=t;this._contentLanguage=n.contentLanguage??`en`,this._dashboardLanguage=n.dashboardLanguage??``,this._multilingualEnabled=n.multilingualEnabled??!1,this._additional=Array.isArray(n.additionalLanguages)?[...n.additionalLanguages]:[],this._unmarkedPostCount=n.unmarkedPostCount??0,this._sitePathPrefix=n.sitePathPrefix??``,this.#e=n.multilingualDocsUrl||z}#n(e){return this.locales.find(t=>t.tag===e)??{tag:e,native:e,english:e,coverage:0}}#r(e){let t=this.#n(e);return t.native||t.tag}#i(e){return`${this._sitePathPrefix}/${e.toLowerCase()}`}#a(e){return`${this._sitePathPrefix}/settings/language${e}`}#o(){return this.querySelector(`jant-locale-picker[open]`)!==null}#s=e=>{if(!this._rowMenuOpen)return;let t=e.target;t&&this.contains(t)&&t.closest?.(`[data-row-menu]`)||(this._rowMenuOpen=null)};#c=e=>{if(e.key===`Escape`){if(this._rowMenuOpen){e.stopPropagation(),this._rowMenuOpen=null;return}this._enableOpen&&(e.stopPropagation(),this.#_())}};#l(e){this._rowMenuOpen=this._rowMenuOpen===e?null:e}async#u(e,t){try{let n=await fetch(this.#a(e),{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(t)}),r=await f(n);return n.ok?{ok:!0,message:_(r,`toast`)}:{ok:!1,message:_(r,`error`)??`HTTP ${n.status}`,language:_(r,`language`)}}catch{return{ok:!1,message:`Couldn't reach the server. Try again.`}}}async#d(e){if(this._removeError=null,e===this._contentLanguage)return;if(this._multilingualEnabled){let t=this._contentLanguage;if(!await d({title:this.labels.changePrimaryTitle,message:B(this.labels.changePrimaryBody,{next:this.#r(e),previous:this.#r(t),prefix:this.#i(t)}),confirmLabel:this.labels.changePrimaryConfirm,cancelLabel:this.labels.cancel}))return;this._savingSite=!0;let n=await this.#u(`/primary`,{language:e});if(this._savingSite=!1,!n.ok){a(n.message??``,`error`);return}this._additional=[...this._additional.filter(t=>t!==e),t],this._contentLanguage=e,n.message&&a(n.message);return}this._savingSite=!0;let t=this._contentLanguage;this._contentLanguage=e;let n=await this.#u(``,{contentLanguage:e});if(this._savingSite=!1,!n.ok){this._contentLanguage=t,a(n.message??``,`error`);return}n.message&&a(n.message)}async#f(e){let t=this._dashboardLanguage;this._dashboardLanguage=e,this._savingDashboard=!0;let n=await this.#u(``,{dashboardLanguage:e});if(this._savingDashboard=!1,!n.ok){this._dashboardLanguage=t,a(n.message??``,`error`);return}window.location.reload()}async#p(e){this._removeError=null;let t=await this.#u(`/add`,{language:e});if(!t.ok){a(t.message??``,`error`);return}this._additional=[...this._additional,e],t.message&&a(t.message)}async#m(e){this._removeError=null;let t=this._multilingualEnabled&&this._additional.length===1&&this._additional[0]===e;if(t&&!await d({title:this.labels.removeLastTitle,message:B(this.labels.removeLastBody,{language:this.#r(e),prefix:this.#i(e)}),confirmLabel:this.labels.removeLastConfirm,cancelLabel:this.labels.cancel}))return;let n=await this.#u(`/remove`,{language:e});if(!n.ok){this._removeError={tag:e,message:n.message??``};return}if(this._additional=this._additional.filter(t=>t!==e),t){this._multilingualEnabled=!1,n.message&&r(n.message),window.location.reload();return}n.message&&a(n.message)}async#h(){if(this._removeError=null,!await d({title:this.labels.disableTitle,message:B(this.labels.disableBody,{prefix:this.#i(this._additional[0]??`en`)}),confirmLabel:this.labels.disableConfirm,cancelLabel:this.labels.cancel}))return;let e=await this.#u(`/disable`,{});if(!e.ok){a(e.message??``,`error`);return}this._multilingualEnabled=!1,e.message&&r(e.message),window.location.reload()}#g(){this._removeError=null,this._enableError=null,this._enablePrimary=this._contentLanguage,this._enableAdditional=[...this._additional],this._enableOpen=!0,this.updateComplete.then(()=>{let e=this.querySelector(`[data-enable-dialog]`);e&&!e.open&&e.showModal(),e?.querySelector(`[data-enable-panel]`)?.focus()})}#_(){let e=this.querySelector(`[data-enable-dialog]`);e?.open&&e.close(),this._enableOpen=!1}async#v(){if(this._enableAdditional.length===0||this._enableBusy)return;this._enableBusy=!0,this._enableError=null;let e=await this.#u(`/enable`,{primary:this._enablePrimary,additional:this._enableAdditional});if(this._enableBusy=!1,!e.ok){this._enableError={message:e.message??``,...e.language?{language:e.language}:{}};return}this._contentLanguage=this._enablePrimary,this._additional=[...this._enableAdditional],this._multilingualEnabled=!0,this._unmarkedPostCount=0,this.#_(),e.message&&r(e.message),window.location.reload()}get#y(){return this.#b??={search:this.labels.searchPlaceholder,empty:this.labels.noMatches},this.#b}#b=null;#x(e){return t`
|
|
298
|
+
<jant-locale-picker
|
|
299
|
+
.locales=${this.locales}
|
|
300
|
+
.labels=${this.#y}
|
|
301
|
+
.value=${e.current??``}
|
|
302
|
+
.exclude=${[...e.exclude]}
|
|
303
|
+
.triggerLabel=${e.triggerLabel??``}
|
|
304
|
+
.triggerClass=${e.triggerClass}
|
|
305
|
+
.labelledby=${e.labelId}
|
|
306
|
+
@locale-select=${t=>e.onSelect(t.detail.tag)}
|
|
307
|
+
></jant-locale-picker>
|
|
308
|
+
`}#S(e){return t`
|
|
309
|
+
<div class="flex flex-wrap items-center gap-2" role="alert">
|
|
310
|
+
<p class="text-sm text-destructive">${e.message}</p>
|
|
311
|
+
${e.language?t`
|
|
312
|
+
<button
|
|
313
|
+
type="button"
|
|
314
|
+
class="btn-sm-outline"
|
|
315
|
+
data-enable-add-back
|
|
316
|
+
@click=${()=>this.#C(e.language??``)}
|
|
317
|
+
>
|
|
318
|
+
${B(this.labels.addMissingLanguage,{language:this.#r(e.language)})}
|
|
319
|
+
</button>
|
|
320
|
+
`:n}
|
|
321
|
+
</div>
|
|
322
|
+
`}#C(e){e&&(this._enableError=null,!(e===this._enablePrimary||this._enableAdditional.includes(e))&&(this._enableAdditional=[...this._enableAdditional,e]))}#w(){if(!this._enableOpen)return n;let e=this._unmarkedPostCount>0?B(this.labels.enableMarkWarning,{language:this.#r(this._enablePrimary)}):null;return t`
|
|
323
|
+
<dialog
|
|
324
|
+
class="dialog confirm-dialog"
|
|
325
|
+
data-enable-dialog
|
|
326
|
+
@cancel=${e=>{e.preventDefault(),this.#_()}}
|
|
327
|
+
@click=${e=>{e.target===e.currentTarget&&this.#_()}}
|
|
328
|
+
@keydown=${e=>{e.key===`Enter`&&!e.shiftKey&&!this.#o()&&(e.preventDefault(),this.#v())}}
|
|
329
|
+
>
|
|
330
|
+
<div
|
|
331
|
+
class="confirm-dialog-panel"
|
|
332
|
+
data-enable-panel
|
|
333
|
+
tabindex="-1"
|
|
334
|
+
role="document"
|
|
335
|
+
aria-labelledby="language-enable-title"
|
|
336
|
+
>
|
|
337
|
+
<header class="confirm-dialog-header">
|
|
338
|
+
<h2 id="language-enable-title" class="confirm-dialog-title">
|
|
339
|
+
${this.labels.enableTitle}
|
|
340
|
+
</h2>
|
|
341
|
+
</header>
|
|
342
|
+
|
|
343
|
+
<div class="flex flex-col gap-4 py-2">
|
|
344
|
+
<div class="field">
|
|
345
|
+
<span id="language-enable-primary-label" class="label"
|
|
346
|
+
>${this.labels.primaryLanguage}</span
|
|
347
|
+
>
|
|
348
|
+
${this.#x({labelId:`language-enable-primary-label`,current:this._enablePrimary,exclude:this._enableAdditional,triggerLabel:this.#r(this._enablePrimary),triggerClass:u,onSelect:e=>{this._enablePrimary=e,this._enableAdditional=this._enableAdditional.filter(t=>t!==e)}})}
|
|
349
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
350
|
+
${this.labels.primaryLanguageHelp}
|
|
351
|
+
</p>
|
|
352
|
+
</div>
|
|
353
|
+
|
|
354
|
+
<div class="field">
|
|
355
|
+
<span id="language-enable-add-label" class="label"
|
|
356
|
+
>${this.labels.otherLanguages}</span
|
|
357
|
+
>
|
|
358
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
359
|
+
${this._enableAdditional.map(e=>t`
|
|
360
|
+
<span class="badge-secondary gap-1">
|
|
361
|
+
${this.#r(e)}
|
|
362
|
+
<button
|
|
363
|
+
type="button"
|
|
364
|
+
class="cursor-pointer opacity-70 hover:opacity-100"
|
|
365
|
+
aria-label=${B(this.labels.removeLanguage,{language:this.#r(e)})}
|
|
366
|
+
@click=${()=>{this._enableAdditional=this._enableAdditional.filter(t=>t!==e)}}
|
|
367
|
+
>
|
|
368
|
+
×
|
|
369
|
+
</button>
|
|
370
|
+
</span>
|
|
371
|
+
`)}
|
|
372
|
+
${this.#x({labelId:`language-enable-add-label`,exclude:[this._enablePrimary,...this._enableAdditional],triggerLabel:`+ ${this.labels.addLanguage}`,triggerClass:`btn-sm-outline`,onSelect:e=>{this._enableAdditional=[...this._enableAdditional,e]}})}
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
${e?t`
|
|
377
|
+
<div class="alert">
|
|
378
|
+
<svg
|
|
379
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
380
|
+
viewBox="0 0 24 24"
|
|
381
|
+
fill="none"
|
|
382
|
+
stroke="currentColor"
|
|
383
|
+
stroke-width="2"
|
|
384
|
+
stroke-linecap="round"
|
|
385
|
+
stroke-linejoin="round"
|
|
386
|
+
aria-hidden="true"
|
|
387
|
+
>
|
|
388
|
+
<path
|
|
389
|
+
d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
|
390
|
+
/>
|
|
391
|
+
<path d="M12 9v4" />
|
|
392
|
+
<path d="M12 17h.01" />
|
|
393
|
+
</svg>
|
|
394
|
+
<strong>${this.labels.enableMarkTitle}</strong>
|
|
395
|
+
<section>
|
|
396
|
+
<p>${e}</p>
|
|
397
|
+
<p>${this.labels.enableFixHint}</p>
|
|
398
|
+
</section>
|
|
399
|
+
</div>
|
|
400
|
+
`:n}
|
|
401
|
+
|
|
402
|
+
<p class="text-sm text-muted-foreground">
|
|
403
|
+
${this.labels.enableReassurance}
|
|
404
|
+
</p>
|
|
405
|
+
|
|
406
|
+
${this._enableAdditional.length===0?t`<p class="text-sm text-muted-foreground">
|
|
407
|
+
${this.labels.enableNeedsLanguage}
|
|
408
|
+
</p>`:n}
|
|
409
|
+
${this._enableError?this.#S(this._enableError):n}
|
|
410
|
+
</div>
|
|
411
|
+
|
|
412
|
+
<footer class="confirm-dialog-actions">
|
|
413
|
+
<button
|
|
414
|
+
type="button"
|
|
415
|
+
class="btn-outline"
|
|
416
|
+
@click=${()=>this.#_()}
|
|
417
|
+
>
|
|
418
|
+
${this.labels.cancel}
|
|
419
|
+
</button>
|
|
420
|
+
<button
|
|
421
|
+
type="button"
|
|
422
|
+
class="btn"
|
|
423
|
+
data-enable-confirm
|
|
424
|
+
?disabled=${this._enableAdditional.length===0||this._enableBusy}
|
|
425
|
+
@click=${()=>void this.#v()}
|
|
426
|
+
>
|
|
427
|
+
${this._enableBusy?this.labels.saving:this.labels.save}
|
|
428
|
+
</button>
|
|
429
|
+
</footer>
|
|
430
|
+
</div>
|
|
431
|
+
</dialog>
|
|
432
|
+
`}#T(e){let r=this._rowMenuOpen===e,i=this.#r(e);return t`
|
|
433
|
+
<span class="relative ml-auto flex items-center" data-row-menu>
|
|
434
|
+
<button
|
|
435
|
+
type="button"
|
|
436
|
+
class="btn-sm-ghost text-muted-foreground"
|
|
437
|
+
aria-haspopup="menu"
|
|
438
|
+
aria-expanded=${r?`true`:`false`}
|
|
439
|
+
aria-label=${B(this.labels.languageMenu,{language:i})}
|
|
440
|
+
data-language-menu
|
|
441
|
+
@click=${()=>this.#l(e)}
|
|
442
|
+
>
|
|
443
|
+
⋯
|
|
444
|
+
</button>
|
|
445
|
+
${r?t`
|
|
446
|
+
<div
|
|
447
|
+
role="menu"
|
|
448
|
+
class="absolute right-0 top-full z-20 mt-1 min-w-40 rounded-md border bg-popover py-1 text-popover-foreground shadow-md"
|
|
449
|
+
>
|
|
450
|
+
<button
|
|
451
|
+
type="button"
|
|
452
|
+
role="menuitem"
|
|
453
|
+
class="block w-full cursor-pointer px-3 py-2 text-left text-sm hover:bg-accent"
|
|
454
|
+
?disabled=${this._savingSite}
|
|
455
|
+
@click=${()=>{this._rowMenuOpen=null,this.#d(e)}}
|
|
456
|
+
>
|
|
457
|
+
${this.labels.makePrimary}
|
|
458
|
+
</button>
|
|
459
|
+
<button
|
|
460
|
+
type="button"
|
|
461
|
+
role="menuitem"
|
|
462
|
+
class="block w-full cursor-pointer px-3 py-2 text-left text-sm text-destructive hover:bg-accent"
|
|
463
|
+
@click=${()=>{this._rowMenuOpen=null,this.#m(e)}}
|
|
464
|
+
>
|
|
465
|
+
${B(this.labels.removeLanguage,{language:i})}
|
|
466
|
+
</button>
|
|
467
|
+
</div>
|
|
468
|
+
`:n}
|
|
469
|
+
</span>
|
|
470
|
+
`}#E(){let e=[this._contentLanguage,...this._additional];return t`
|
|
471
|
+
<div class="field">
|
|
472
|
+
<span id="language-list-label" class="label"
|
|
473
|
+
>${this.labels.languagesLabel}${this._savingSite?` ${this.labels.saving}`:``}</span
|
|
474
|
+
>
|
|
475
|
+
<ul
|
|
476
|
+
class="flex flex-col rounded-md border divide-y"
|
|
477
|
+
aria-labelledby="language-list-label"
|
|
478
|
+
>
|
|
479
|
+
${e.map(e=>{let r=e===this._contentLanguage,i=r?`${this._sitePathPrefix}/`:this.#i(e);return t`
|
|
480
|
+
<li class="flex flex-col px-3 py-1.5 text-sm">
|
|
481
|
+
<div class="flex min-h-8 items-center gap-3">
|
|
482
|
+
<span class="min-w-0 truncate" lang=${e}
|
|
483
|
+
>${this.#r(e)}</span
|
|
484
|
+
>
|
|
485
|
+
<a
|
|
486
|
+
href=${i}
|
|
487
|
+
target="_blank"
|
|
488
|
+
rel="noopener noreferrer"
|
|
489
|
+
class="shrink-0"
|
|
490
|
+
>
|
|
491
|
+
<code
|
|
492
|
+
class="rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
|
|
493
|
+
>${i}</code
|
|
494
|
+
>
|
|
495
|
+
</a>
|
|
496
|
+
${r?t`<span class="badge-secondary ml-auto"
|
|
497
|
+
>${this.labels.primaryBadge}</span
|
|
498
|
+
>`:this.#T(e)}
|
|
499
|
+
</div>
|
|
500
|
+
${this._removeError?.tag===e?t`
|
|
501
|
+
<p class="pb-1 text-sm text-destructive" role="alert">
|
|
502
|
+
${this._removeError.message}${this._multilingualEnabled?t`
|
|
503
|
+
<a
|
|
504
|
+
class="underline underline-offset-2"
|
|
505
|
+
href=${`${this.#i(e)}/archive`}
|
|
506
|
+
target="_blank"
|
|
507
|
+
rel="noopener noreferrer"
|
|
508
|
+
>${this.labels.viewPosts}</a
|
|
509
|
+
>
|
|
510
|
+
`:n}
|
|
511
|
+
</p>
|
|
512
|
+
`:n}
|
|
513
|
+
</li>
|
|
514
|
+
`})}
|
|
515
|
+
</ul>
|
|
516
|
+
<div class="mt-2">
|
|
517
|
+
${this.#x({labelId:`language-list-label`,exclude:[this._contentLanguage,...this._additional],triggerLabel:`+ ${this.labels.addLanguage}`,triggerClass:`btn-sm-outline`,onSelect:e=>void this.#p(e)})}
|
|
518
|
+
</div>
|
|
519
|
+
</div>
|
|
520
|
+
`}render(){return this.labels.contentLanguage?t`
|
|
521
|
+
<div class="flex flex-col gap-8">
|
|
522
|
+
<section class="flex flex-col gap-4">
|
|
523
|
+
<h2 class="text-lg font-medium">${this.labels.siteSection}</h2>
|
|
524
|
+
|
|
525
|
+
${this._multilingualEnabled?this.#E():t`
|
|
526
|
+
<div class="field">
|
|
527
|
+
<span id="language-primary-label" class="label"
|
|
528
|
+
>${this.labels.contentLanguage}</span
|
|
529
|
+
>
|
|
530
|
+
${this.#x({labelId:`language-primary-label`,current:this._contentLanguage,exclude:[],triggerLabel:this.#r(this._contentLanguage),triggerClass:u,onSelect:e=>void this.#d(e)})}
|
|
531
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
532
|
+
${this.labels.contentLanguageHelp}${this._savingSite?` ${this.labels.saving}`:``}
|
|
533
|
+
</p>
|
|
534
|
+
</div>
|
|
535
|
+
`}
|
|
536
|
+
</section>
|
|
537
|
+
|
|
538
|
+
<section class="flex flex-col gap-3 border-t pt-8">
|
|
539
|
+
<h2 class="text-lg font-medium">${this.labels.multilingual}</h2>
|
|
540
|
+
<p class="text-sm text-muted-foreground">
|
|
541
|
+
${this.labels.multilingualHelp}
|
|
542
|
+
</p>
|
|
543
|
+
<p class="text-sm text-muted-foreground">
|
|
544
|
+
<a
|
|
545
|
+
href=${this.#e}
|
|
546
|
+
target="_blank"
|
|
547
|
+
rel="noopener noreferrer"
|
|
548
|
+
class="underline hover:text-foreground transition-colors"
|
|
549
|
+
>${this.labels.multilingualDocs}</a
|
|
550
|
+
>
|
|
551
|
+
— ${this.labels.multilingualDocsHelp}
|
|
552
|
+
</p>
|
|
553
|
+
<div class="flex items-center gap-3">
|
|
554
|
+
${this._multilingualEnabled?t`
|
|
555
|
+
<span class="badge-secondary">${this.labels.statusOn}</span>
|
|
556
|
+
<button
|
|
557
|
+
type="button"
|
|
558
|
+
class="btn-link h-auto p-0 text-sm text-muted-foreground"
|
|
559
|
+
data-multilingual-off
|
|
560
|
+
@click=${()=>void this.#h()}
|
|
561
|
+
>
|
|
562
|
+
${this.labels.disableConfirm}
|
|
563
|
+
</button>
|
|
564
|
+
`:t`
|
|
565
|
+
<button
|
|
566
|
+
type="button"
|
|
567
|
+
class="btn-sm-outline"
|
|
568
|
+
data-multilingual-setup
|
|
569
|
+
@click=${()=>this.#g()}
|
|
570
|
+
>
|
|
571
|
+
${this.labels.turnOn}
|
|
572
|
+
</button>
|
|
573
|
+
`}
|
|
574
|
+
</div>
|
|
575
|
+
</section>
|
|
576
|
+
|
|
577
|
+
<section class="flex flex-col gap-4 border-t pt-8">
|
|
578
|
+
<h2 class="text-lg font-medium">${this.labels.dashboardSection}</h2>
|
|
579
|
+
|
|
580
|
+
<div class="field">
|
|
581
|
+
<label id="dashboard-language-label" class="label"
|
|
582
|
+
>${this.labels.dashboardLanguage}</label
|
|
583
|
+
>
|
|
584
|
+
<select
|
|
585
|
+
class="select"
|
|
586
|
+
aria-labelledby="dashboard-language-label"
|
|
587
|
+
?disabled=${this._savingDashboard}
|
|
588
|
+
@change=${e=>void this.#f(e.target.value)}
|
|
589
|
+
>
|
|
590
|
+
${R.map(e=>t`
|
|
591
|
+
<option
|
|
592
|
+
value=${e}
|
|
593
|
+
?selected=${this._dashboardLanguage===e}
|
|
594
|
+
>
|
|
595
|
+
${e===``?this.labels.followContent:this.#r(e)}
|
|
596
|
+
</option>
|
|
597
|
+
`)}
|
|
598
|
+
</select>
|
|
599
|
+
<p class="text-sm text-muted-foreground mt-1">
|
|
600
|
+
${this.labels.dashboardLanguageHelp}
|
|
601
|
+
</p>
|
|
602
|
+
</div>
|
|
603
|
+
</section>
|
|
604
|
+
</div>
|
|
605
|
+
|
|
606
|
+
${this.#w()}
|
|
607
|
+
`:n}};customElements.define(`jant-settings-language`,V);var H=class extends i{static properties={avatarUrl:{type:String,attribute:`avatar-url`},showInHeader:{type:Boolean,attribute:`show-in-header`},labels:{type:Object},_showInHeader:{state:!0},_origShowInHeader:{state:!0},_dirty:{state:!0},_loading:{state:!0},_removeLoading:{state:!0}};createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.avatarUrl=``,this.showInHeader=!1,this.labels={},this._showInHeader=!1,this._origShowInHeader=!1,this._dirty=!1,this._loading=!1,this._removeLoading=!1}connectedCallback(){super.connectedCallback(),this._showInHeader=this.showInHeader,this._origShowInHeader=this.showInHeader}saved(){this._origShowInHeader=this._showInHeader,this._dirty=!1,this._loading=!1}saveError(){this._loading=!1}removeError(){this._removeLoading=!1}_toggleDisplay(){this._showInHeader=!this._showInHeader,this._dirty=this._showInHeader!==this._origShowInHeader}_cancelDisplay(){this._showInHeader=this._origShowInHeader,this._dirty=!1}_saveDisplay(){!this._loading&&this._dirty&&(this._loading=!0,this.dispatchEvent(new CustomEvent(`jant:settings-save`,{bubbles:!0,detail:{endpoint:`/settings/avatar/display`,data:{showHeaderAvatar:this._showInHeader?`true`:``},section:`avatar-display`}})))}async _removeAvatar(){await d({message:this.labels.confirmRemoveAvatar,confirmLabel:this.labels.remove,cancelLabel:this.labels.cancel,tone:`danger`})&&(this._removeLoading||(this._removeLoading=!0,this.dispatchEvent(new CustomEvent(`jant:avatar-remove`,{bubbles:!0,detail:{endpoint:`/settings/avatar/remove`}}))))}_renderPreview(){let e=`rounded-full size-16 overflow-hidden border border-border/70 bg-muted/40 flex items-center justify-center shrink-0`;return this.avatarUrl?t`
|
|
608
|
+
<div class=${e}>
|
|
609
|
+
<img
|
|
610
|
+
src=${this.avatarUrl}
|
|
611
|
+
alt=""
|
|
612
|
+
class="w-full h-full object-cover"
|
|
613
|
+
/>
|
|
614
|
+
</div>
|
|
615
|
+
`:t`
|
|
616
|
+
<div class="${e} text-muted-foreground">
|
|
617
|
+
<svg
|
|
618
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
619
|
+
width="24"
|
|
620
|
+
height="24"
|
|
621
|
+
viewBox="0 0 24 24"
|
|
622
|
+
fill="none"
|
|
623
|
+
stroke="currentColor"
|
|
624
|
+
stroke-width="2"
|
|
625
|
+
stroke-linecap="round"
|
|
626
|
+
stroke-linejoin="round"
|
|
627
|
+
>
|
|
628
|
+
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
|
629
|
+
<circle cx="9" cy="9" r="2" />
|
|
630
|
+
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
|
631
|
+
</svg>
|
|
632
|
+
</div>
|
|
633
|
+
`}render(){return t`
|
|
634
|
+
<div>
|
|
635
|
+
<h2 class="text-lg font-semibold mb-4">${this.labels.blogAvatar}</h2>
|
|
636
|
+
<div class="flex flex-col gap-4">
|
|
637
|
+
<div class="flex items-center gap-4">
|
|
638
|
+
${this._renderPreview()}
|
|
639
|
+
<div class="flex flex-col gap-2">
|
|
640
|
+
<form
|
|
641
|
+
action=${e(`/settings/avatar`)}
|
|
642
|
+
method="post"
|
|
643
|
+
enctype="multipart/form-data"
|
|
644
|
+
class="inline"
|
|
645
|
+
>
|
|
646
|
+
<label class="btn text-sm cursor-pointer">
|
|
647
|
+
${this.labels.uploadAvatar}
|
|
648
|
+
<input
|
|
649
|
+
type="file"
|
|
650
|
+
name="file"
|
|
651
|
+
accept="image/jpeg,image/png,image/gif,image/webp,image/svg+xml"
|
|
652
|
+
class="hidden"
|
|
653
|
+
data-avatar-upload
|
|
654
|
+
data-text-processing=${this.labels.processing}
|
|
655
|
+
data-text-uploading=${this.labels.uploading}
|
|
656
|
+
data-text-error=${this.labels.uploadError}
|
|
657
|
+
/>
|
|
658
|
+
</label>
|
|
659
|
+
</form>
|
|
660
|
+
${this.avatarUrl?t`
|
|
661
|
+
<button
|
|
662
|
+
type="button"
|
|
663
|
+
class="btn-outline text-sm"
|
|
664
|
+
?disabled=${this._removeLoading}
|
|
665
|
+
@click=${()=>void this._removeAvatar()}
|
|
666
|
+
>
|
|
667
|
+
${this.labels.remove}
|
|
668
|
+
</button>
|
|
669
|
+
`:n}
|
|
670
|
+
</div>
|
|
671
|
+
</div>
|
|
672
|
+
<p class="text-sm text-muted-foreground">${this.labels.avatarHelp}</p>
|
|
673
|
+
<label class="flex items-center gap-2 cursor-pointer">
|
|
674
|
+
<input
|
|
675
|
+
type="checkbox"
|
|
676
|
+
class="checkbox"
|
|
677
|
+
.checked=${this._showInHeader}
|
|
678
|
+
@change=${this._toggleDisplay}
|
|
679
|
+
/>
|
|
680
|
+
<span>${this.labels.displayInHeader}</span>
|
|
681
|
+
</label>
|
|
682
|
+
<div class="flex gap-2 mt-4">
|
|
683
|
+
<button
|
|
684
|
+
type="button"
|
|
685
|
+
class="btn"
|
|
686
|
+
?disabled=${this._loading||!this._dirty}
|
|
687
|
+
@click=${this._saveDisplay}
|
|
688
|
+
>
|
|
689
|
+
${this._loading?t`<svg
|
|
690
|
+
class="animate-spin size-4"
|
|
691
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
692
|
+
viewBox="0 0 24 24"
|
|
693
|
+
fill="none"
|
|
694
|
+
stroke="currentColor"
|
|
695
|
+
stroke-width="2"
|
|
696
|
+
stroke-linecap="round"
|
|
697
|
+
stroke-linejoin="round"
|
|
698
|
+
role="status"
|
|
699
|
+
>
|
|
700
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
701
|
+
</svg>`:n}
|
|
702
|
+
${this.labels.save}
|
|
703
|
+
</button>
|
|
704
|
+
<button
|
|
705
|
+
type="button"
|
|
706
|
+
class="btn-outline"
|
|
707
|
+
?disabled=${this._loading||!this._dirty}
|
|
708
|
+
@click=${this._cancelDisplay}
|
|
709
|
+
>
|
|
710
|
+
${this.labels.cancel}
|
|
711
|
+
</button>
|
|
712
|
+
</div>
|
|
713
|
+
</div>
|
|
714
|
+
</div>
|
|
715
|
+
`}};customElements.define(`jant-settings-avatar`,H);var U={search:`Search settings`,modifiedOnly:`Show only modified`,modified:`Modified`,locked:`Locked`,reset:`Reset to default`,saving:`Saving…`,saved:`Saved`,saveError:`This setting wasn't saved. Check the value and try again.`,noMatches:`Nothing matches this search. Try a different name or description.`,countTemplate:`{count} settings shown`,openSetting:`Open setting`,configured:`Configured`,notConfigured:`Not configured`};function W(e){if(!g(e))return;let t={};for(let[n,r]of Object.entries(e)){if(typeof r!=`string`)return;t[n]=r}return t}function G(e){if(!g(e))return null;let t=_(e,`key`),n=_(e,`mode`),r=_(e,`type`),i=_(e,`value`),a=_(e,`fallbackValue`),o=_(e,`description`),s=_(e,`settingsPath`),c=_(e,`display`),l=_(e,`fallbackKey`);if(!t||n!==`edit`&&n!==`link`||r!==`boolean`&&r!==`string`&&r!==`number`&&r!==`enum`||i===void 0||a===void 0||o===void 0||typeof e.modified!=`boolean`||typeof e.locked!=`boolean`||n===`link`&&(!s||c!==`value`&&c!==`configured`))return null;let u=Array.isArray(e.options)?e.options.filter(e=>typeof e==`string`):void 0;if(n===`edit`&&r===`enum`&&(!u||u.length===0))return null;let d=W(e.optionLabels);return{key:t,mode:n,type:r,value:i,fallbackValue:a,modified:e.modified,locked:e.locked,description:o,...typeof e.maxLength==`number`&&{maxLength:e.maxLength},...typeof e.min==`number`&&{min:e.min},...typeof e.max==`number`&&{max:e.max},...typeof e.step==`number`&&{step:e.step},...u&&{options:u},...d&&{optionLabels:d},...s&&{settingsPath:s},...c===`value`||c===`configured`?{display:c}:{},...e.resettable===!0&&{resettable:!0},...l&&{fallbackKey:l}}}function K(e){try{let t=JSON.parse(e);return!g(t)||!Array.isArray(t.fields)?[]:t.fields.map(G).filter(e=>e!==null)}catch{return[]}}function q(e){try{let t=JSON.parse(e);if(!g(t))return U;let n={...U};for(let e of Object.keys(n)){let r=t[e];typeof r==`string`&&r&&(n[e]=r)}return n}catch{return U}}var J=class extends i{static properties={endpoint:{type:String},initialData:{type:String,attribute:`initial-data`},labelsJson:{type:String,attribute:`labels`},_items:{state:!0},_labels:{state:!0},_query:{state:!0},_modifiedOnly:{state:!0},_drafts:{state:!0},_pending:{state:!0},_statuses:{state:!0}};_statusTimeouts=new Map;createRenderRoot(){return this}constructor(){super(),this.endpoint=`/api/settings`,this.initialData=``,this.labelsJson=``,this._items=[],this._labels=U,this._query=``,this._modifiedOnly=!1,this._drafts={},this._pending={},this._statuses={}}connectedCallback(){super.connectedCallback(),this.querySelector(`:scope > .config-editor-fallback`)?.remove();let e=this.getAttribute(`initial-data`)??this.initialData,t=this.getAttribute(`labels`)??this.labelsJson;this._items=K(e),this._labels=q(t),this._drafts=Object.fromEntries(this._items.map(e=>[e.key,e.value]))}disconnectedCallback(){for(let e of this._statusTimeouts.values())window.clearTimeout(e);this._statusTimeouts.clear(),super.disconnectedCallback()}_filteredItems(){let e=v(this._query);return this._items.map((t,n)=>({item:t,index:n,rank:e?h([t.key,t.description,t.type,t.value],e):0})).filter(e=>e.rank!==null&&(!this._modifiedOnly||e.item.modified)).sort((e,t)=>(e.rank??0)-(t.rank??0)||e.index-t.index).map(({item:e})=>e)}_setDraft(e,t){this._drafts={...this._drafts,[e]:t},this._statuses[e]&&this._setStatus(e,void 0)}_setPending(e,t){this._pending={...this._pending,[e]:t}}_setStatus(e,t){let n=this._statusTimeouts.get(e);if(n!==void 0&&(window.clearTimeout(n),this._statusTimeouts.delete(e)),this._statuses={...this._statuses,[e]:t},t?.state===`saved`){let t=window.setTimeout(()=>{this._statuses[e]?.state===`saved`&&(this._statuses={...this._statuses,[e]:void 0}),this._statusTimeouts.delete(e)},2e3);this._statusTimeouts.set(e,t)}}_replaceItem(e,t){this._items=this._items.map(n=>n.key===e?t(n):n)}_commitValue(e,t,n){let r={...this._drafts,[e]:t};this._items=this._items.map(i=>i.key===e?{...i,value:t,modified:n}:i.fallbackKey===e?i.modified?{...i,fallbackValue:t}:(r[i.key]=t,{...i,value:t,fallbackValue:t}):i),this._drafts=r}async _save(e,t){if(e.locked||this._pending[e.key])return;let n=e.type===`boolean`||e.type===`enum`,r=e.value;n&&this._replaceItem(e.key,e=>({...e,value:t})),this._setPending(e.key,!0),this._setStatus(e.key,{state:`saving`});try{let n=await fetch(this.endpoint,{method:`PUT`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify({[e.key]:t})});if(!n.ok)throw Error(await m(n,this._labels.saveError));let r=(await f(n)).settings,i=_(r,e.key)??t;this._commitValue(e.key,i,!0),this._setStatus(e.key,{state:`saved`})}catch(t){n&&this._replaceItem(e.key,e=>({...e,value:r})),this._setStatus(e.key,{state:`error`,message:t instanceof Error?t.message:this._labels.saveError})}finally{this._setPending(e.key,!1)}}async _reset(e){if(!(!e.modified||e.locked||e.mode===`link`&&!e.resettable||this._pending[e.key])){this._setPending(e.key,!0),this._setStatus(e.key,{state:`saving`});try{let t=await fetch(`${this.endpoint}/${encodeURIComponent(e.key)}`,{method:`DELETE`,headers:{Accept:`application/json`}});if(!t.ok)throw Error(await m(t,this._labels.saveError));let n=await f(t),r=g(n.setting)?n.setting:void 0,i=_(r,`value`)??_(n.settings,e.key)??e.fallbackValue;this._commitValue(e.key,i,!1),this._setStatus(e.key,{state:`saved`})}catch(t){this._setStatus(e.key,{state:`error`,message:t instanceof Error?t.message:this._labels.saveError})}finally{this._setPending(e.key,!1)}}}_renderStatus(e){let r=this._statuses[e.key];return r?r.state===`saving`?t`<span class="config-editor-status" role="status"
|
|
716
|
+
>${this._labels.saving}</span
|
|
717
|
+
>`:r.state===`saved`?t`<span
|
|
718
|
+
class="config-editor-status config-editor-status-saved"
|
|
719
|
+
role="status"
|
|
720
|
+
>${this._labels.saved}</span
|
|
721
|
+
>`:t`<span
|
|
722
|
+
class="config-editor-status config-editor-status-error"
|
|
723
|
+
role="alert"
|
|
724
|
+
>${r.message}</span
|
|
725
|
+
>`:n}_renderControl(e){let r=`config-editor-${e.key.toLowerCase().replaceAll(`_`,`-`)}`,i=!!this._pending[e.key]||e.locked;if(e.type===`boolean`)return t`<input
|
|
726
|
+
id=${r}
|
|
727
|
+
name=${e.key}
|
|
728
|
+
type="checkbox"
|
|
729
|
+
role="switch"
|
|
730
|
+
class="input"
|
|
731
|
+
aria-describedby=${`${r}-description`}
|
|
732
|
+
.checked=${e.value===`true`}
|
|
733
|
+
?disabled=${i}
|
|
734
|
+
@change=${t=>void this._save(e,String(t.target.checked))}
|
|
735
|
+
/>`;if(e.type===`enum`)return t`<select
|
|
736
|
+
id=${r}
|
|
737
|
+
name=${e.key}
|
|
738
|
+
class="select config-editor-select"
|
|
739
|
+
aria-describedby=${`${r}-description`}
|
|
740
|
+
.value=${e.value}
|
|
741
|
+
?disabled=${i}
|
|
742
|
+
@change=${t=>void this._save(e,t.target.value)}
|
|
743
|
+
>
|
|
744
|
+
${(e.options??[]).map(n=>t`<option value=${n} ?selected=${n===e.value}>
|
|
745
|
+
${e.optionLabels?.[n]??n}
|
|
746
|
+
</option>`)}
|
|
747
|
+
</select>`;let a=this._drafts[e.key]??e.value,o=a!==e.value;return t`<input
|
|
748
|
+
id=${r}
|
|
749
|
+
name=${e.key}
|
|
750
|
+
class="input config-editor-value-input"
|
|
751
|
+
type=${e.type===`number`?`number`:`text`}
|
|
752
|
+
autocomplete="off"
|
|
753
|
+
spellcheck="false"
|
|
754
|
+
aria-describedby=${`${r}-description`}
|
|
755
|
+
.value=${a}
|
|
756
|
+
maxlength=${e.maxLength??n}
|
|
757
|
+
min=${e.min??n}
|
|
758
|
+
max=${e.max??n}
|
|
759
|
+
step=${e.step??n}
|
|
760
|
+
?disabled=${i}
|
|
761
|
+
@input=${t=>this._setDraft(e.key,t.target.value)}
|
|
762
|
+
@blur=${t=>{let n=t.target.value;n!==e.value&&this._save(e,n)}}
|
|
763
|
+
@keydown=${t=>{t.key===`Escape`?(t.preventDefault(),this._setDraft(e.key,e.value)):t.key===`Enter`&&!t.isComposing&&o&&(t.preventDefault(),this._save(e,a))}}
|
|
764
|
+
/>`}_renderLinkedSetting(e){let n=e.display===`configured`?e.value===`true`?this._labels.configured:this._labels.notConfigured:e.value;return t`
|
|
765
|
+
<a
|
|
766
|
+
class="config-editor-open-control"
|
|
767
|
+
href=${e.settingsPath??`/settings`}
|
|
768
|
+
aria-describedby=${`config-editor-${e.key.toLowerCase().replaceAll(`_`,`-`)}-description`}
|
|
769
|
+
>
|
|
770
|
+
<span class="config-editor-linked-value" translate="no">${n}</span>
|
|
771
|
+
<span class="config-editor-open-action">
|
|
772
|
+
${this._labels.openSetting}
|
|
773
|
+
<svg
|
|
774
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
775
|
+
width="15"
|
|
776
|
+
height="15"
|
|
777
|
+
viewBox="0 0 24 24"
|
|
778
|
+
fill="none"
|
|
779
|
+
stroke="currentColor"
|
|
780
|
+
stroke-width="2"
|
|
781
|
+
stroke-linecap="round"
|
|
782
|
+
stroke-linejoin="round"
|
|
783
|
+
aria-hidden="true"
|
|
784
|
+
>
|
|
785
|
+
<path d="M5 12h14" />
|
|
786
|
+
<path d="m13 6 6 6-6 6" />
|
|
787
|
+
</svg>
|
|
788
|
+
</span>
|
|
789
|
+
</a>
|
|
790
|
+
`}_canReset(e){return e.modified&&!e.locked&&(e.mode===`edit`||e.resettable===!0)}_renderRow(e){let r=`config-editor-${e.key.toLowerCase().replaceAll(`_`,`-`)}`,i=[`config-editor-control-row`,e.mode===`edit`&&e.type===`enum`?`config-editor-control-row-select`:``,e.mode===`edit`&&e.type===`number`?`config-editor-control-row-number`:``].filter(Boolean).join(` `);return t`
|
|
791
|
+
<li
|
|
792
|
+
class="config-editor-row"
|
|
793
|
+
data-modified=${String(e.modified)}
|
|
794
|
+
aria-busy=${String(!!this._pending[e.key])}
|
|
795
|
+
>
|
|
796
|
+
<div class="config-editor-copy">
|
|
797
|
+
<div class="config-editor-heading">
|
|
798
|
+
${e.mode===`edit`?t`<label for=${r}
|
|
799
|
+
><code class="config-editor-key" translate="no"
|
|
800
|
+
>${e.key}</code
|
|
801
|
+
></label
|
|
802
|
+
>`:t`<code class="config-editor-key" translate="no"
|
|
803
|
+
>${e.key}</code
|
|
804
|
+
>`}
|
|
805
|
+
${e.modified?t`<span class="config-editor-state config-editor-modified"
|
|
806
|
+
>${this._labels.modified}</span
|
|
807
|
+
>`:n}
|
|
808
|
+
${e.locked?t`<span class="config-editor-state config-editor-locked"
|
|
809
|
+
>${this._labels.locked}</span
|
|
810
|
+
>`:n}
|
|
811
|
+
</div>
|
|
812
|
+
<p class="config-editor-description" id=${`${r}-description`}>
|
|
813
|
+
${e.description}
|
|
814
|
+
</p>
|
|
815
|
+
</div>
|
|
816
|
+
<div class="config-editor-value-column">
|
|
817
|
+
<div class=${i}>
|
|
818
|
+
${e.mode===`link`?this._renderLinkedSetting(e):this._renderControl(e)}
|
|
819
|
+
${this._canReset(e)?t`<button
|
|
820
|
+
type="button"
|
|
821
|
+
class="config-editor-reset"
|
|
822
|
+
aria-label=${this._labels.reset}
|
|
823
|
+
title=${this._labels.reset}
|
|
824
|
+
?disabled=${!!this._pending[e.key]}
|
|
825
|
+
@click=${()=>void this._reset(e)}
|
|
826
|
+
>
|
|
827
|
+
<svg
|
|
828
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
829
|
+
width="15"
|
|
830
|
+
height="15"
|
|
831
|
+
viewBox="0 0 24 24"
|
|
832
|
+
fill="none"
|
|
833
|
+
stroke="currentColor"
|
|
834
|
+
stroke-width="2"
|
|
835
|
+
stroke-linecap="round"
|
|
836
|
+
stroke-linejoin="round"
|
|
837
|
+
aria-hidden="true"
|
|
838
|
+
>
|
|
839
|
+
<path d="M3 12a9 9 0 1 0 3-6.7L3 8" />
|
|
840
|
+
<path d="M3 3v5h5" />
|
|
841
|
+
</svg>
|
|
842
|
+
</button>`:n}
|
|
843
|
+
</div>
|
|
844
|
+
${this._renderStatus(e)}
|
|
845
|
+
</div>
|
|
846
|
+
</li>
|
|
847
|
+
`}render(){let e=this._filteredItems(),n=this._labels.countTemplate.replace(`{count}`,String(e.length));return t`
|
|
848
|
+
<div class="config-editor-toolbar">
|
|
849
|
+
<div class="config-editor-search">
|
|
850
|
+
<svg
|
|
851
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
852
|
+
width="17"
|
|
853
|
+
height="17"
|
|
854
|
+
viewBox="0 0 24 24"
|
|
855
|
+
fill="none"
|
|
856
|
+
stroke="currentColor"
|
|
857
|
+
stroke-width="2"
|
|
858
|
+
stroke-linecap="round"
|
|
859
|
+
stroke-linejoin="round"
|
|
860
|
+
aria-hidden="true"
|
|
861
|
+
>
|
|
862
|
+
<circle cx="11" cy="11" r="8"></circle>
|
|
863
|
+
<path d="m21 21-4.3-4.3"></path>
|
|
864
|
+
</svg>
|
|
865
|
+
<input
|
|
866
|
+
type="search"
|
|
867
|
+
name="config-search"
|
|
868
|
+
class="input config-editor-search-input"
|
|
869
|
+
autocomplete="off"
|
|
870
|
+
spellcheck="false"
|
|
871
|
+
placeholder=${this._labels.search}
|
|
872
|
+
aria-label=${this._labels.search}
|
|
873
|
+
.value=${this._query}
|
|
874
|
+
@input=${e=>{this._query=e.target.value}}
|
|
875
|
+
@keydown=${e=>{e.key===`Escape`&&this._query&&(e.preventDefault(),this._query=``)}}
|
|
876
|
+
/>
|
|
877
|
+
</div>
|
|
878
|
+
</div>
|
|
879
|
+
<div class="config-editor-toolbar-meta">
|
|
880
|
+
<p class="config-editor-count" aria-live="polite">${n}</p>
|
|
881
|
+
<label class="config-editor-modified-filter">
|
|
882
|
+
<input
|
|
883
|
+
type="checkbox"
|
|
884
|
+
name="modified-only"
|
|
885
|
+
class="input"
|
|
886
|
+
.checked=${this._modifiedOnly}
|
|
887
|
+
@change=${e=>{this._modifiedOnly=e.target.checked}}
|
|
888
|
+
/>
|
|
889
|
+
<span>${this._labels.modifiedOnly}</span>
|
|
890
|
+
</label>
|
|
891
|
+
</div>
|
|
892
|
+
${e.length>0?t`<ul class="config-editor-list">
|
|
893
|
+
${e.map(e=>this._renderRow(e))}
|
|
894
|
+
</ul>`:t`<div class="config-editor-empty" role="status">
|
|
895
|
+
<p>${this._labels.noMatches}</p>
|
|
896
|
+
</div>`}
|
|
897
|
+
`}};customElements.get(`jant-config-editor`)||customElements.define(`jant-config-editor`,J);var Y=300,X=1,Z=class extends i{static properties={labels:{type:Object},apiBase:{type:String,attribute:`api-base`},connectUrl:{type:String,attribute:`connect-url`},installUrl:{type:String,attribute:`install-url`},cancelUrl:{type:String,attribute:`cancel-url`},createRepoNameHint:{type:String,attribute:`create-repo-name-hint`},_installations:{state:!0},_selectedOwner:{state:!0},_ownerOpen:{state:!0},_repos:{state:!0},_totalCount:{state:!0},_hasMore:{state:!0},_nextPage:{state:!0},_reposMode:{state:!0},_repoOpen:{state:!0},_repoSearch:{state:!0},_loadingRepos:{state:!0},_selectedRepo:{state:!0},_classification:{state:!0},_classifying:{state:!0},_confirmText:{state:!0},_connecting:{state:!0},_error:{state:!0}};#e=null;#t=0;#n=!1;#r=null;createRenderRoot(){return this.innerHTML=``,this}constructor(){super(),this.labels={},this.apiBase=``,this.connectUrl=``,this.installUrl=``,this.cancelUrl=``,this.createRepoNameHint=``,this._installations=[],this._selectedOwner=null,this._ownerOpen=!1,this._repos=[],this._totalCount=0,this._hasMore=!1,this._nextPage=null,this._reposMode=`list`,this._repoOpen=!1,this._repoSearch=``,this._loadingRepos=!1,this._selectedRepo=null,this._classification=null,this._classifying=!1,this._confirmText=``,this._connecting=!1,this._error=null}connectedCallback(){super.connectedCallback(),document.addEventListener(`click`,this.#m),document.addEventListener(`keydown`,this.#h),window.addEventListener(`focus`,this.#g),this.#i()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(`click`,this.#m),document.removeEventListener(`keydown`,this.#h),window.removeEventListener(`focus`,this.#g),this.#e&&clearTimeout(this.#e)}async#i(){try{let e=await fetch(`${this.apiBase}/installations`,{headers:{Accept:`application/json`},credentials:`same-origin`});if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();this._installations=t.installations;let n=t.installations.length===1?t.installations[0]:null;n&&this.#u(n)}catch(e){this._error=e instanceof Error?e.message:String(e)}}async#a(e,t={}){let n=++this.#t;this._loadingRepos=!0;try{let r=new URLSearchParams({installationId:e});t.q&&r.set(`q`,t.q);let i=await fetch(`${this.apiBase}/repos?${r.toString()}`,{headers:{Accept:`application/json`},credentials:`same-origin`});if(n!==this.#t)return;if(i.status===410){this._installations=this._installations.filter(t=>t.installationId!==e),this._selectedOwner=null,this._repos=[];return}if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}let a=await i.json();this._repos=a.repos,this._totalCount=a.totalCount,this._hasMore=a.hasMore,this._nextPage=a.nextPage,this._reposMode=a.mode}catch(e){n===this.#t&&(this._error=e instanceof Error?e.message:String(e))}finally{n===this.#t&&(this._loadingRepos=!1)}}async#o(e,t){this._classifying=!0,this._classification=null,this._confirmText=``;try{let n=await fetch(`${this.apiBase}/classify`,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},credentials:`same-origin`,body:JSON.stringify({installationId:e,repo:t})}),r=await n.json();if(!n.ok||!r.classification)throw Error(r.error??`HTTP ${n.status}`);this._classification=r.classification}catch(e){this._error=e instanceof Error?e.message:String(e)}finally{this._classifying=!1}}async#s(){if(this._selectedOwner&&this._selectedRepo&&this._classification){this._connecting=!0,this._error=null;try{let e=this._classification.kind===`foreign`||this._classification.kind===`owned-by-other-site`,t=await fetch(this.connectUrl,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},credentials:`same-origin`,body:JSON.stringify({installationId:this._selectedOwner.installationId,repo:this._selectedRepo.fullName,confirmForeign:e})}),n=await t.json().catch(()=>({}));if(!t.ok||!n.ok)throw Error(n.error??`HTTP ${t.status}`);window.location.href=n.redirect??this.cancelUrl}catch(e){this._error=e instanceof Error?e.message:String(e),this._connecting=!1}}}#c(){let e=this._selectedOwner;if(!e)return;let t=this.createRepoNameHint||``,n=new URL(`https://github.com/new`);t&&n.searchParams.set(`name`,t),n.searchParams.set(`owner`,e.account.login),n.searchParams.set(`visibility`,`private`),this.#n=!0,this.#r=t||null,window.open(n.toString(),`_blank`,`noopener,noreferrer`),this._repoOpen=!1}#l(){if(!this._selectedOwner)return;let e=this._repoSearch.trim();this.#a(this._selectedOwner.installationId,e?{q:e}:{})}#u(e){if(this._selectedOwner?.installationId===e.installationId){this._ownerOpen=!1;return}this._selectedOwner=e,this._ownerOpen=!1,this._selectedRepo=null,this._classification=null,this._confirmText=``,this._repoSearch=``,this.#a(e.installationId)}#d(e){this._selectedRepo=e,this._repoOpen=!1,this._repoSearch=``,this._selectedOwner&&this.#o(this._selectedOwner.installationId,e.fullName)}#f(e){let t=e.target.value;if(this._repoSearch=t,this.#e&&clearTimeout(this.#e),!this._selectedOwner)return;let n=t.trim();if(n.length<X){this._reposMode===`search`&&this.#a(this._selectedOwner.installationId);return}this.#e=setTimeout(()=>{this._selectedOwner&&this.#a(this._selectedOwner.installationId,{q:n})},Y)}#p(){let e=this._repoSearch.trim().toLowerCase();return!e||this._reposMode===`search`?this._repos:this._repos.filter(t=>t.name.toLowerCase().includes(e)||t.fullName.toLowerCase().includes(e))}#m=e=>{if(!this._ownerOpen&&!this._repoOpen)return;let t=e.target,n=this.querySelector(`.repo-picker-owner`),r=this.querySelector(`.repo-picker-repo`);n&&!n.contains(t)&&(this._ownerOpen=!1),r&&!r.contains(t)&&(this._repoOpen=!1)};#h=e=>{e.key===`Escape`&&(e.isComposing||e.keyCode===229||(this._ownerOpen||this._repoOpen)&&(this._ownerOpen=!1,this._repoOpen=!1))};#g=()=>{if(!this.#n)return;let e=this._selectedOwner;if(!e){this.#n=!1;return}let t=this.#r;this.#n=!1,this.#r=null,(async()=>{if(this._repoSearch=``,await this.#a(e.installationId),t){let e=this._repos.find(e=>e.name===t);e&&this.#d(e)}})()};#_(){this._ownerOpen=!this._ownerOpen,this._repoOpen=!1}#v(){this._selectedOwner&&(this._repoOpen=!this._repoOpen,this._ownerOpen=!1,this._repoOpen&&queueMicrotask(()=>{this.querySelector(`.repo-picker-repo-search`)?.focus()}))}render(){return t`
|
|
898
|
+
<div class="flex flex-col gap-6 max-w-lg">
|
|
899
|
+
<div>
|
|
900
|
+
<h2 class="text-lg font-medium mb-1">${this.labels.pageTitle}</h2>
|
|
901
|
+
<p class="text-sm text-muted-foreground">
|
|
902
|
+
${this.labels.pageSubtitle}
|
|
903
|
+
</p>
|
|
904
|
+
</div>
|
|
905
|
+
|
|
906
|
+
${this.#y()} ${this.#x()}
|
|
907
|
+
${this.#C()} ${this.#T()}
|
|
908
|
+
${this._error?t`<div class="alert-destructive text-sm" role="alert">
|
|
909
|
+
<section><p>${this._error}</p></section>
|
|
910
|
+
</div>`:n}
|
|
911
|
+
</div>
|
|
912
|
+
`}#y(){let e=this._selectedOwner;return t`
|
|
913
|
+
<div class="field repo-picker-owner relative">
|
|
914
|
+
<label class="label">${this.labels.ownerLabel}</label>
|
|
915
|
+
<button
|
|
916
|
+
type="button"
|
|
917
|
+
class="btn-outline w-full justify-between font-normal"
|
|
918
|
+
@click=${()=>this.#_()}
|
|
919
|
+
aria-haspopup="listbox"
|
|
920
|
+
aria-expanded=${this._ownerOpen}
|
|
921
|
+
>
|
|
922
|
+
<span class="flex items-center gap-2 truncate">
|
|
923
|
+
${e?t`
|
|
924
|
+
${e.account.avatarUrl?t`<img
|
|
925
|
+
src=${e.account.avatarUrl}
|
|
926
|
+
alt=""
|
|
927
|
+
class="w-5 h-5 rounded-full"
|
|
928
|
+
loading="lazy"
|
|
929
|
+
/>`:n}
|
|
930
|
+
<span class="truncate">${e.account.login}</span>
|
|
931
|
+
`:t`<span class="text-muted-foreground"
|
|
932
|
+
>${this._installations.length===0?this.labels.ownerEmpty:this.labels.ownerPlaceholder}</span
|
|
933
|
+
>`}
|
|
934
|
+
</span>
|
|
935
|
+
<span class="text-muted-foreground">▾</span>
|
|
936
|
+
</button>
|
|
937
|
+
${this._ownerOpen?this.#b():n}
|
|
938
|
+
</div>
|
|
939
|
+
`}#b(){return t`
|
|
940
|
+
<div
|
|
941
|
+
class="absolute z-10 mt-1 w-full rounded-md border bg-background shadow-lg"
|
|
942
|
+
role="listbox"
|
|
943
|
+
>
|
|
944
|
+
<ul class="max-h-64 overflow-y-auto py-1">
|
|
945
|
+
${this._installations.map(e=>t`
|
|
946
|
+
<li>
|
|
947
|
+
<button
|
|
948
|
+
type="button"
|
|
949
|
+
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-muted"
|
|
950
|
+
@click=${()=>this.#u(e)}
|
|
951
|
+
role="option"
|
|
952
|
+
aria-selected=${this._selectedOwner?.installationId===e.installationId}
|
|
953
|
+
>
|
|
954
|
+
${e.account.avatarUrl?t`<img
|
|
955
|
+
src=${e.account.avatarUrl}
|
|
956
|
+
alt=""
|
|
957
|
+
class="w-5 h-5 rounded-full"
|
|
958
|
+
loading="lazy"
|
|
959
|
+
/>`:n}
|
|
960
|
+
<span class="truncate">${e.account.login}</span>
|
|
961
|
+
<span class="ml-auto text-xs text-muted-foreground">
|
|
962
|
+
${e.account.type===`Organization`?`Org`:``}
|
|
963
|
+
</span>
|
|
964
|
+
</button>
|
|
965
|
+
</li>
|
|
966
|
+
`)}
|
|
967
|
+
${this.installUrl?t`
|
|
968
|
+
<li class="border-t mt-1 pt-1">
|
|
969
|
+
<a
|
|
970
|
+
href=${this.installUrl}
|
|
971
|
+
class="block px-3 py-2 text-sm text-primary hover:bg-muted"
|
|
972
|
+
>
|
|
973
|
+
${this.labels.installAnother}
|
|
974
|
+
</a>
|
|
975
|
+
</li>
|
|
976
|
+
`:n}
|
|
977
|
+
</ul>
|
|
978
|
+
</div>
|
|
979
|
+
`}#x(){let e=this._selectedRepo,r=!this._selectedOwner;return t`
|
|
980
|
+
<div class="field repo-picker-repo relative">
|
|
981
|
+
<label class="label">${this.labels.repositoryLabel}</label>
|
|
982
|
+
<button
|
|
983
|
+
type="button"
|
|
984
|
+
class="btn-outline w-full justify-between font-normal"
|
|
985
|
+
@click=${()=>this.#v()}
|
|
986
|
+
aria-haspopup="listbox"
|
|
987
|
+
aria-expanded=${this._repoOpen}
|
|
988
|
+
?disabled=${r}
|
|
989
|
+
>
|
|
990
|
+
<span class="truncate">
|
|
991
|
+
${e?t`<span>${e.name}</span> ${e.private?t`<span class="text-xs text-muted-foreground ml-1"
|
|
992
|
+
>${this.labels.privateBadge}</span
|
|
993
|
+
>`:n}`:t`<span class="text-muted-foreground"
|
|
994
|
+
>${r?this.labels.repoPlaceholderNoOwner:this.labels.repoPlaceholder}</span
|
|
995
|
+
>`}
|
|
996
|
+
</span>
|
|
997
|
+
<span class="text-muted-foreground">▾</span>
|
|
998
|
+
</button>
|
|
999
|
+
${this._repoOpen?this.#S():n}
|
|
1000
|
+
</div>
|
|
1001
|
+
`}#S(){let e=this.#p();return t`
|
|
1002
|
+
<div
|
|
1003
|
+
class="absolute z-10 mt-1 w-full rounded-md border bg-background shadow-lg"
|
|
1004
|
+
>
|
|
1005
|
+
<div class="p-2 border-b flex items-center gap-2">
|
|
1006
|
+
<input
|
|
1007
|
+
type="text"
|
|
1008
|
+
class="input repo-picker-repo-search flex-1"
|
|
1009
|
+
placeholder=${this.labels.repoSearchPlaceholder}
|
|
1010
|
+
.value=${this._repoSearch}
|
|
1011
|
+
@input=${e=>this.#f(e)}
|
|
1012
|
+
/>
|
|
1013
|
+
<button
|
|
1014
|
+
type="button"
|
|
1015
|
+
class="btn-icon-ghost"
|
|
1016
|
+
title=${this.labels.refreshRepos}
|
|
1017
|
+
aria-label=${this.labels.refreshRepos}
|
|
1018
|
+
@click=${()=>this.#l()}
|
|
1019
|
+
?disabled=${this._loadingRepos}
|
|
1020
|
+
>
|
|
1021
|
+
<!-- Simple refresh glyph; matches BaseCoat icon button sizing -->
|
|
1022
|
+
<span aria-hidden="true">⟳</span>
|
|
1023
|
+
</button>
|
|
1024
|
+
</div>
|
|
1025
|
+
${this._hasMore&&this._reposMode===`list`?t`<p class="px-3 pt-2 text-xs text-muted-foreground">
|
|
1026
|
+
${this.labels.repoShowingOf.replace(`{shown}`,String(this._repos.length)).replace(`{total}`,String(this._totalCount))}
|
|
1027
|
+
— ${this.labels.repoSearchHint}
|
|
1028
|
+
</p>`:n}
|
|
1029
|
+
<ul class="max-h-64 overflow-y-auto py-1" role="listbox">
|
|
1030
|
+
${this._loadingRepos?t`<li class="px-3 py-2 text-sm text-muted-foreground">
|
|
1031
|
+
${this.labels.repoLoading}
|
|
1032
|
+
</li>`:e.length===0?t`<li class="px-3 py-2 text-sm text-muted-foreground">
|
|
1033
|
+
${this.labels.repoEmpty}
|
|
1034
|
+
</li>`:e.map(e=>t`
|
|
1035
|
+
<li>
|
|
1036
|
+
<button
|
|
1037
|
+
type="button"
|
|
1038
|
+
class="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-muted"
|
|
1039
|
+
@click=${()=>this.#d(e)}
|
|
1040
|
+
role="option"
|
|
1041
|
+
aria-selected=${this._selectedRepo?.fullName===e.fullName}
|
|
1042
|
+
>
|
|
1043
|
+
<span class="truncate">${e.name}</span>
|
|
1044
|
+
${e.private?t`<span
|
|
1045
|
+
class="ml-auto text-xs text-muted-foreground"
|
|
1046
|
+
>${this.labels.privateBadge}</span
|
|
1047
|
+
>`:n}
|
|
1048
|
+
</button>
|
|
1049
|
+
</li>
|
|
1050
|
+
`)}
|
|
1051
|
+
</ul>
|
|
1052
|
+
<div class="border-t p-2">
|
|
1053
|
+
<button
|
|
1054
|
+
type="button"
|
|
1055
|
+
class="flex w-full items-start gap-2 px-2 py-2 text-left text-sm text-primary hover:bg-muted rounded-md"
|
|
1056
|
+
@click=${()=>this.#c()}
|
|
1057
|
+
>
|
|
1058
|
+
<span class="flex flex-col">
|
|
1059
|
+
<span class="font-medium">${this.labels.createOnGitHub} →</span>
|
|
1060
|
+
${this.createRepoNameHint?t`<span class="text-xs text-muted-foreground">
|
|
1061
|
+
${this.labels.createOnGitHubHint.replace(`{name}`,this.createRepoNameHint)}
|
|
1062
|
+
</span>`:n}
|
|
1063
|
+
</span>
|
|
1064
|
+
</button>
|
|
1065
|
+
</div>
|
|
1066
|
+
</div>
|
|
1067
|
+
`}#C(){if(this._classifying)return t`<p class="text-sm text-muted-foreground">
|
|
1068
|
+
${this.labels.classifyLoading}
|
|
1069
|
+
</p>`;if(!this._classification||!this._selectedRepo)return n;let e=this._classification;if(e.kind===`empty`)return t`<p class="text-sm text-muted-foreground">
|
|
1070
|
+
${this.labels.classificationEmpty}
|
|
1071
|
+
</p>`;if(e.kind===`owned`)return t`<p class="text-sm text-muted-foreground">
|
|
1072
|
+
${this.labels.classificationOwned}
|
|
1073
|
+
</p>`;if(e.kind===`owned-by-other-site`)return t`<div class="alert-destructive text-sm" role="alert">
|
|
1074
|
+
<section>
|
|
1075
|
+
<p>
|
|
1076
|
+
${this.labels.classificationOwnedByOther.replace(`{host}`,e.marker.site_host)}
|
|
1077
|
+
</p>
|
|
1078
|
+
</section>
|
|
1079
|
+
</div>`;let r=this._selectedRepo.fullName;return t`
|
|
1080
|
+
<div class="alert flex flex-col gap-3 text-sm">
|
|
1081
|
+
<div>
|
|
1082
|
+
<strong class="block mb-1">${this.labels.confirmHeading}</strong>
|
|
1083
|
+
<span>${this.labels.confirmBody.replace(`{repo}`,r)}</span>
|
|
1084
|
+
</div>
|
|
1085
|
+
<div class="field">
|
|
1086
|
+
<label class="label text-xs">
|
|
1087
|
+
${this.labels.confirmInputLabel.replace(`{repo}`,r)}
|
|
1088
|
+
</label>
|
|
1089
|
+
<input
|
|
1090
|
+
type="text"
|
|
1091
|
+
class="input w-full"
|
|
1092
|
+
placeholder=${this.labels.confirmInputPlaceholder}
|
|
1093
|
+
.value=${this._confirmText}
|
|
1094
|
+
@input=${e=>{this._confirmText=e.target.value}}
|
|
1095
|
+
autocomplete="off"
|
|
1096
|
+
spellcheck="false"
|
|
1097
|
+
/>
|
|
1098
|
+
</div>
|
|
1099
|
+
</div>
|
|
1100
|
+
`}#w(){if(!this._selectedRepo||!this._classification||this._classifying||this._connecting)return!1;let e=this._classification;return e.kind===`owned-by-other-site`?!1:e.kind!==`foreign`||this._confirmText.trim()===this._selectedRepo.fullName}#T(){return t`
|
|
1101
|
+
<div class="flex items-center gap-2">
|
|
1102
|
+
<button
|
|
1103
|
+
type="button"
|
|
1104
|
+
class="btn"
|
|
1105
|
+
?disabled=${!this.#w()}
|
|
1106
|
+
@click=${()=>this.#s()}
|
|
1107
|
+
>
|
|
1108
|
+
${this._connecting?this.labels.connecting:this.labels.connect}
|
|
1109
|
+
</button>
|
|
1110
|
+
<a href=${this.cancelUrl} class="btn-ghost">${this.labels.cancel}</a>
|
|
1111
|
+
</div>
|
|
1112
|
+
`}};customElements.define(`jant-repo-picker`,Z);function Q(e){let t=_(e,`siteName`),n=_(e,`siteDescription`),r=_(e,`mainRssFeed`),i=_(e,`timeZone`),a=_(e,`siteFooter`),o=p(e,`showJantBrandingOnHome`),s=p(e,`noindex`),c=_(e,`discover`);return t===void 0||n===void 0||r===void 0||i===void 0||a===void 0||o===void 0||s===void 0||c===void 0?null:{siteName:t,siteDescription:n,mainRssFeed:r,timeZone:i,siteFooter:a,showJantBrandingOnHome:o,noindex:s,discover:c}}document.addEventListener(`jant:settings-save`,async e=>{let{endpoint:t,data:n,section:r}=e.detail,i=document.querySelector(`jant-settings-general`),o=document.querySelector(`jant-settings-avatar`);try{let e=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`},body:JSON.stringify(n)});if(!e.ok)throw Error(`HTTP ${e.status}`);let s=await f(e),c=_(s,`status`),l=_(s,`url`),u=_(s,`toast`);if(c===`redirect`&&l){window.location.href=l;return}u&&a(u),r===`avatar-display`?o?.saved():i?.sectionSaved(r)}catch{a(`Failed to save. Please try again.`,`error`),r===`avatar-display`?o?.saveError():i?.sectionError(r)}}),document.addEventListener(`jant:avatar-remove`,async e=>{let{endpoint:t}=e.detail,n=document.querySelector(`jant-settings-avatar`);try{let e=await fetch(t,{method:`POST`,headers:{"Content-Type":`application/json`,Accept:`application/json`}});if(!e.ok)throw Error(`HTTP ${e.status}`);let n=await f(e),r=_(n,`status`),i=_(n,`url`);if(r===`redirect`&&i){window.location.href=i;return}}catch{a(`Failed to remove avatar. Please try again.`,`error`),n?.removeError()}});function $(){let e=document.querySelector(`jant-settings-general`);if(!e)return;let t=document.getElementById(`settings-initial-data`);if(t?.textContent)try{let n=Q(JSON.parse(t.textContent));n&&e.initData(n)}catch{}}document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,$):queueMicrotask($);
|