@jant/core 0.6.14 → 0.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/commands/import-site.js +81 -13
- package/bin/commands/migrate.js +55 -0
- package/bin/commands/posts/rebuild-html.js +184 -0
- package/bin/commands/site/snapshot/import.js +14 -10
- package/bin/lib/d1-query.js +23 -5
- package/bin/lib/migration-runner.js +29 -7
- package/bin/lib/node-database.js +32 -0
- package/bin/lib/site-snapshot.js +347 -46
- package/bin/lib/sql-export.js +1 -1
- package/bin/lib/thread-collection-migration.js +326 -0
- package/dist/app-BxCOR3Uc.js +6 -0
- package/dist/{app-2i7-WQHg.js → app-C-oi_t8W.js} +7408 -6343
- package/dist/client/.vite/manifest.json +3 -3
- package/dist/client/_assets/client-B_eGKN5p.css +2 -0
- package/dist/client/_assets/{client-BvID5ucz.js → client-DxY5BFe8.js} +58 -37
- package/dist/client/_assets/client-auth-CakPESv9.js +5533 -0
- package/dist/{export-DWn149b7.js → export-CsFx6F_M.js} +1259 -125
- package/dist/{github-sync-Ckk0sJxK.js → github-sync-Cq1pzzOI.js} +1 -1
- package/dist/{github-sync-C0zyF6XS.js → github-sync-ppWXN3jb.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/node.js +5 -5
- package/package.json +11 -10
- package/src/__tests__/bin/posts-rebuild-html.test.ts +137 -0
- package/src/__tests__/dev-navigation-defaults.test.ts +22 -0
- package/src/__tests__/export-hugo-build.test.ts +63 -4
- package/src/__tests__/export-import-roundtrip.test.ts +6 -4
- package/src/__tests__/export-service.test.ts +142 -9
- package/src/__tests__/helpers/app.ts +3 -0
- package/src/__tests__/helpers/export-fixtures.ts +2 -0
- package/src/__tests__/import-site-command.test.ts +65 -0
- package/src/__tests__/vite-config.test.ts +45 -0
- package/src/app.tsx +16 -3
- package/src/client/__tests__/collection-created-notice.test.ts +36 -0
- package/src/client/__tests__/collection-form-bridge.test.ts +10 -1
- package/src/client/__tests__/collection-page-actions.test.ts +71 -2
- package/src/client/__tests__/compose-bridge.test.ts +64 -0
- package/src/client/__tests__/feed-video-player.test.ts +16 -1
- package/src/client/__tests__/footnote-rail.test.ts +472 -0
- package/src/client/__tests__/hydrate-partial.test.ts +3 -0
- package/src/client/__tests__/toast.test.ts +18 -1
- package/src/client/collection-created-notice.ts +66 -0
- package/src/client/collection-form-bridge.ts +17 -0
- package/src/client/collection-navigation.ts +44 -0
- package/src/client/collection-page-actions.ts +57 -1
- package/src/client/components/__tests__/jant-collection-directory.test.ts +155 -6
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +370 -5
- package/src/client/components/__tests__/jant-compose-editor.test.ts +97 -0
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +104 -0
- package/src/client/components/__tests__/jant-config-editor.test.ts +405 -0
- package/src/client/components/__tests__/jant-media-lightbox.test.ts +121 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +538 -2
- package/src/client/components/__tests__/jant-post-form.test.ts +2 -2
- package/src/client/components/__tests__/jant-post-menu.test.ts +47 -5
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +2 -2
- package/src/client/components/__tests__/jant-settings-general.test.ts +3 -3
- package/src/client/components/collection-manager-types.ts +9 -3
- package/src/client/components/compose-types.ts +8 -0
- package/src/client/components/jant-collection-directory.ts +165 -30
- package/src/client/components/jant-command-palette.ts +2 -1
- package/src/client/components/jant-compose-dialog.ts +85 -21
- package/src/client/components/jant-compose-editor.ts +13 -7
- package/src/client/components/jant-compose-fullscreen.ts +24 -4
- package/src/client/components/jant-config-editor.ts +722 -0
- package/src/client/components/jant-media-lightbox.ts +100 -18
- package/src/client/components/jant-nav-manager.ts +1283 -54
- package/src/client/components/jant-post-form.ts +3 -3
- package/src/client/components/jant-post-menu.ts +86 -74
- package/src/client/components/nav-manager-types.ts +51 -2
- package/src/client/components/post-form-types.ts +1 -1
- package/src/client/compose-bridge.ts +4 -1
- package/src/client/feed-video-player.ts +62 -2
- package/src/client/footnote-rail.ts +478 -0
- package/src/client/hydrate-partial.ts +2 -0
- package/src/client/media-lightbox-events.ts +63 -0
- package/src/client/site-header-fragment.ts +38 -0
- package/src/client/tiptap/__tests__/blockquote-editing.test.ts +201 -0
- package/src/client/tiptap/__tests__/clear-formatting.test.ts +168 -0
- package/src/client/tiptap/__tests__/list-editing.test.ts +447 -0
- package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +727 -4
- package/src/client/tiptap/__tests__/table-controls.test.ts +263 -0
- package/src/client/tiptap/__tests__/table-size-picker.test.ts +179 -0
- package/src/client/tiptap/bubble-menu.ts +88 -10
- package/src/client/tiptap/continuous-lists.ts +102 -0
- package/src/client/tiptap/create-editor.ts +3 -0
- package/src/client/tiptap/extensions.ts +14 -5
- package/src/client/tiptap/markdown-clipboard.ts +608 -11
- package/src/client/tiptap/slash-commands.ts +8 -1
- package/src/client/tiptap/structural-keymap.ts +211 -0
- package/src/client/tiptap/tab-indent.ts +8 -22
- package/src/client/tiptap/table-control-labels.ts +30 -0
- package/src/client/tiptap/table-controls.ts +537 -0
- package/src/client/tiptap/table-size-picker.ts +254 -0
- package/src/client/toast.ts +8 -6
- package/src/client-auth.ts +1 -0
- package/src/client.ts +1 -0
- package/src/db/__tests__/d1-query.test.ts +43 -1
- package/src/db/__tests__/migration-runner.test.ts +63 -0
- package/src/db/__tests__/migrations.test.ts +469 -0
- package/src/db/__tests__/thread-collection-migration.test.ts +364 -0
- package/src/db/migrations/0027_old_blue_blade.sql +39 -0
- package/src/db/migrations/0028_superb_post.sql +2 -0
- package/src/db/migrations/0029_boring_magma.sql +1 -0
- package/src/db/migrations/0030_typical_vivisector.sql +50 -0
- package/src/db/migrations/meta/0027_snapshot.json +2511 -0
- package/src/db/migrations/meta/0028_snapshot.json +2511 -0
- package/src/db/migrations/meta/0029_snapshot.json +2519 -0
- package/src/db/migrations/meta/0030_snapshot.json +2541 -0
- package/src/db/migrations/meta/_journal.json +28 -0
- package/src/db/migrations/pg/0025_moaning_epoch.sql +39 -0
- package/src/db/migrations/pg/0026_talented_killer_shrike.sql +2 -0
- package/src/db/migrations/pg/0027_short_cannonball.sql +1 -0
- package/src/db/migrations/pg/0028_perfect_sharon_carter.sql +27 -0
- package/src/db/migrations/pg/meta/0025_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0026_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0027_snapshot.json +3211 -0
- package/src/db/migrations/pg/meta/0028_snapshot.json +3248 -0
- package/src/db/migrations/pg/meta/_journal.json +28 -0
- package/src/db/pg/schema.ts +28 -20
- package/src/db/rehearsal-fixtures/demo-current.json +39 -4
- package/src/db/rehearsal-fixtures/demo-current.sql +121 -6
- package/src/db/schema.ts +28 -20
- package/src/i18n/__tests__/detect.test.ts +8 -2
- package/src/i18n/detect.ts +14 -5
- package/src/i18n/locales/public/en.po +133 -30
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +128 -25
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +128 -25
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/i18n/locales/settings/en.po +513 -10
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +515 -12
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +515 -12
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/lib/__tests__/api-settings.test.ts +299 -0
- package/src/lib/__tests__/constants.test.ts +5 -0
- package/src/lib/__tests__/feed-policy.test.ts +25 -0
- package/src/lib/__tests__/footnotes-upgrade.test.ts +181 -0
- package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +61 -0
- package/src/lib/__tests__/markdown-to-tiptap.test.ts +32 -4
- package/src/lib/__tests__/markdown.test.ts +8 -6
- package/src/lib/__tests__/navigation.test.ts +59 -2
- package/src/lib/__tests__/post-body-html.test.ts +176 -0
- package/src/lib/__tests__/post-display.test.ts +64 -0
- package/src/lib/__tests__/resolve-config.test.ts +113 -1
- package/src/lib/__tests__/summary.test.ts +82 -0
- package/src/lib/__tests__/timeline.test.ts +109 -70
- package/src/lib/__tests__/timezones.test.ts +31 -3
- package/src/lib/__tests__/tiptap-render.test.ts +268 -9
- package/src/lib/__tests__/tiptap-to-markdown.test.ts +6 -0
- package/src/lib/__tests__/view.test.ts +53 -0
- package/src/lib/__tests__/worker-response-cache.test.ts +18 -1
- package/src/lib/api-settings.ts +239 -12
- package/src/lib/collection-sort.ts +7 -5
- package/src/lib/constants.ts +2 -0
- package/src/lib/feed-path.ts +25 -0
- package/src/lib/feed-policy.ts +64 -0
- package/src/lib/footnotes.ts +264 -0
- package/src/lib/github-sync-site-config.ts +2 -0
- package/src/lib/hugo-markdown.ts +10 -3
- package/src/lib/jant-branding.ts +1 -0
- package/src/lib/markdown-manager.ts +188 -5
- package/src/lib/markdown.ts +10 -3
- package/src/lib/navigation.ts +16 -3
- package/src/lib/post-body-html.ts +131 -0
- package/src/lib/post-display.ts +7 -1
- package/src/lib/render.tsx +9 -2
- package/src/lib/resolve-config.ts +100 -16
- package/src/lib/schemas.ts +133 -1
- package/src/lib/settings-paths.ts +5 -0
- package/src/lib/site-skill.ts +78 -0
- package/src/lib/summary.ts +16 -5
- package/src/lib/timeline.ts +98 -122
- package/src/lib/timezones.ts +54 -14
- package/src/lib/tiptap-render.ts +355 -81
- package/src/lib/view.ts +30 -20
- package/src/lib/worker-response-cache.ts +11 -18
- package/src/middleware/__tests__/public-content-access.test.ts +91 -0
- package/src/middleware/config.ts +2 -2
- package/src/middleware/public-content-access.ts +87 -0
- package/src/node/__tests__/cli-export.test.ts +14 -0
- package/src/node/__tests__/cli-migrate.test.ts +6 -0
- package/src/node/__tests__/cli-site-snapshot.test.ts +205 -2
- package/src/node/__tests__/cli-snapshot-meta.test.ts +100 -0
- package/src/node/index.ts +2 -1
- package/src/preset.css +16 -2
- package/src/routes/__tests__/compose.test.ts +51 -0
- package/src/routes/__tests__/site-skill.test.ts +112 -0
- package/src/routes/api/__tests__/collections.test.ts +91 -19
- package/src/routes/api/__tests__/mcp.test.ts +65 -1
- package/src/routes/api/__tests__/nav-items.test.ts +91 -0
- package/src/routes/api/__tests__/public-access.test.ts +81 -0
- package/src/routes/api/__tests__/settings.test.ts +217 -0
- package/src/routes/api/collections.ts +22 -26
- package/src/routes/api/export.ts +2 -0
- package/src/routes/api/internal/__tests__/post-body-html.test.ts +163 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +35 -2
- package/src/routes/api/internal/post-body-html.ts +43 -0
- package/src/routes/api/internal/sites.ts +24 -0
- package/src/routes/api/nav-items.ts +24 -1
- package/src/routes/api/posts.ts +2 -2
- package/src/routes/api/public/__tests__/archive.test.ts +35 -0
- package/src/routes/api/public/__tests__/posts.test.ts +208 -0
- package/src/routes/api/public/archive.ts +4 -0
- package/src/routes/api/public/posts.ts +41 -24
- package/src/routes/api/search.ts +3 -0
- package/src/routes/api/settings.ts +33 -0
- package/src/routes/auth/__tests__/setup.test.ts +7 -4
- package/src/routes/compose.tsx +2 -1
- package/src/routes/dash/settings.tsx +45 -2
- package/src/routes/feed/__tests__/feed.test.ts +210 -6
- package/src/routes/feed/feed.ts +23 -14
- package/src/routes/pages/__tests__/archive-params.test.ts +92 -3
- package/src/routes/pages/__tests__/collection-routing.test.ts +63 -5
- package/src/routes/pages/__tests__/collections.test.ts +9 -9
- package/src/routes/pages/__tests__/preview.test.ts +174 -0
- package/src/routes/pages/__tests__/search.test.ts +69 -0
- package/src/routes/pages/archive.tsx +27 -7
- package/src/routes/pages/collection.tsx +32 -19
- package/src/routes/pages/collections.tsx +6 -1
- package/src/routes/pages/page.tsx +83 -11
- package/src/routes/site-skill.ts +18 -0
- package/src/services/__tests__/auth.test.ts +7 -5
- package/src/services/__tests__/collection.test.ts +159 -44
- package/src/services/__tests__/navigation.test.ts +229 -21
- package/src/services/__tests__/post-timeline.test.ts +109 -30
- package/src/services/__tests__/post.test.ts +567 -5
- package/src/services/__tests__/search.test.ts +48 -1
- package/src/services/__tests__/settings.test.ts +8 -0
- package/src/services/__tests__/site-admin.test.ts +121 -1
- package/src/services/auth.ts +2 -2
- package/src/services/bootstrap.ts +3 -2
- package/src/services/collection.ts +226 -167
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export-theme/assets/client-site.js +46 -25
- package/src/services/export-theme/layouts/_default/list.html +18 -4
- package/src/services/export-theme/layouts/_default/rss.xml +8 -12
- package/src/services/export-theme/layouts/featured/list.html +5 -4
- package/src/services/export-theme/layouts/partials/featured-thread.html +56 -0
- package/src/services/export-theme/layouts/partials/footer.html +1 -1
- package/src/services/export-theme/layouts/partials/media-gallery.html +1 -0
- package/src/services/export-theme/styles/main.css +30 -2
- package/src/services/export.ts +91 -80
- package/src/services/mcp.ts +37 -27
- package/src/services/media.ts +1 -1
- package/src/services/navigation.ts +185 -46
- package/src/services/post.ts +874 -271
- package/src/services/search.ts +8 -2
- package/src/services/settings.ts +2 -10
- package/src/services/site-admin.ts +63 -43
- package/src/style-cjk-jp.css +1 -1
- package/src/style-cjk-kr.css +1 -1
- package/src/style-cjk-tc.css +1 -1
- package/src/style-cjk.css +1 -1
- package/src/styles/components.css +540 -0
- package/src/styles/site-media.css +111 -19
- package/src/styles/tokens.css +14 -9
- package/src/styles/ui.css +829 -29
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +243 -12
- package/src/types/constants.ts +22 -1
- package/src/types/entities.ts +9 -8
- package/src/types/operations.ts +18 -10
- package/src/types/props.ts +8 -2
- package/src/types/raw-assets.d.ts +5 -0
- package/src/types/views.ts +16 -4
- package/src/ui/__tests__/font-themes.test.ts +42 -30
- package/src/ui/compose/ComposeDialog.tsx +92 -2
- package/src/ui/dash/appearance/NavigationContent.tsx +332 -4
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +23 -0
- package/src/ui/dash/settings/ConfigEditorContent.tsx +578 -0
- package/src/ui/dash/settings/GeneralContent.tsx +15 -5
- package/src/ui/dash/settings/SettingsRootContent.tsx +21 -1
- package/src/ui/dash/settings/__tests__/ConfigEditorContent.test.tsx +98 -0
- package/src/ui/dash/settings/__tests__/SettingsRootContent.test.tsx +15 -0
- package/src/ui/feed/CuratedThreadPreview.tsx +16 -4
- package/src/ui/feed/LinkCard.tsx +2 -12
- package/src/ui/feed/NoteCard.tsx +10 -20
- package/src/ui/feed/QuoteCard.tsx +2 -12
- package/src/ui/feed/ThreadPreview.tsx +26 -34
- package/src/ui/feed/TimelineFeed.tsx +2 -2
- package/src/ui/feed/__tests__/thread-preview.test.ts +197 -56
- package/src/ui/feed/__tests__/timeline-cards.test.ts +178 -3
- package/src/ui/feed/thread-preview-state.ts +5 -7
- package/src/ui/font-themes.ts +74 -26
- package/src/ui/layouts/BaseLayout.tsx +22 -8
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +64 -1
- package/src/ui/pages/CollectionPage.tsx +101 -22
- package/src/ui/pages/CollectionsPage.tsx +3 -1
- package/src/ui/pages/PostPage.tsx +39 -12
- package/src/ui/pages/SearchPage.tsx +6 -14
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +7 -0
- package/src/ui/pages/__tests__/PostPage.test.tsx +88 -0
- package/src/ui/shared/CollectionDirectory.tsx +13 -9
- package/src/ui/shared/CollectionsManager.tsx +17 -7
- package/src/ui/shared/DraftPreviewBar.tsx +33 -0
- package/src/ui/shared/HomePageBranding.tsx +2 -2
- package/src/ui/shared/MediaGallery.tsx +1 -0
- package/src/ui/shared/PostFooter.tsx +3 -1
- package/src/ui/shared/__tests__/home-page-branding.test.tsx +1 -1
- package/src/ui/shared/__tests__/media-gallery.test.ts +1 -0
- package/src/ui/shared/__tests__/navigation-labels.test.ts +2 -2
- package/src/ui/shared/__tests__/post-footer.test.ts +15 -0
- package/src/ui/shared/collection-management-labels.ts +33 -2
- package/src/ui/shared/navigation-labels.ts +2 -4
- package/src/ui/shared/post-article-attributes.ts +46 -0
- package/dist/app-DZDlmh7C.js +0 -6
- package/dist/client/_assets/client-Cevfpm8H.css +0 -2
- package/dist/client/_assets/client-auth-v3yvhbgZ.js +0 -4736
- package/src/client/tiptap/wrapping-input-rules.ts +0 -102
|
@@ -891,7 +891,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
891
891
|
if (requestId !== this._openEditRequestId) return;
|
|
892
892
|
}
|
|
893
893
|
|
|
894
|
-
if (post.collectionIds?.length) {
|
|
894
|
+
if (!post.replyToId && post.collectionIds?.length) {
|
|
895
895
|
this._collectionIds = post.collectionIds;
|
|
896
896
|
}
|
|
897
897
|
|
|
@@ -1008,6 +1008,9 @@ export class JantComposeDialog extends LitElement {
|
|
|
1008
1008
|
if (options?.restoreDraft !== false) {
|
|
1009
1009
|
await this.restoreLocalDraft({ expectedReplyToId: id });
|
|
1010
1010
|
}
|
|
1011
|
+
// Collection membership belongs to the existing Thread. Reply compose
|
|
1012
|
+
// must not restore or submit stale per-compose Collection state.
|
|
1013
|
+
this._collectionIds = [];
|
|
1011
1014
|
|
|
1012
1015
|
this.closest("dialog")?.showModal();
|
|
1013
1016
|
await this.updateComplete;
|
|
@@ -1371,9 +1374,10 @@ export class JantComposeDialog extends LitElement {
|
|
|
1371
1374
|
: this._visibility
|
|
1372
1375
|
: undefined,
|
|
1373
1376
|
rating: editorData.rating,
|
|
1374
|
-
collectionIds: isRoot ? [...this._collectionIds] : [],
|
|
1377
|
+
collectionIds: isRoot && !this._replyToId ? [...this._collectionIds] : [],
|
|
1375
1378
|
attachments: orderedAttachments,
|
|
1376
1379
|
replyToId: isRoot ? (this._replyToId ?? undefined) : undefined,
|
|
1380
|
+
quietReply: isRoot ? this._quietReply || undefined : undefined,
|
|
1377
1381
|
replyThreadRootId: isRoot
|
|
1378
1382
|
? (this._replyThreadRootId ?? undefined)
|
|
1379
1383
|
: undefined,
|
|
@@ -1441,7 +1445,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
1441
1445
|
status,
|
|
1442
1446
|
visibility: this._visibilityLocked ? undefined : this._visibility,
|
|
1443
1447
|
rating: editorData.rating,
|
|
1444
|
-
collectionIds: [...this._collectionIds],
|
|
1448
|
+
collectionIds: this._replyToId ? [] : [...this._collectionIds],
|
|
1445
1449
|
attachments: orderedAttachments,
|
|
1446
1450
|
editPostId: this._editPostId ?? this._draftSourceId ?? undefined,
|
|
1447
1451
|
replyToId: this._replyToId ?? undefined,
|
|
@@ -2437,15 +2441,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
2437
2441
|
this._handleConfirmSave();
|
|
2438
2442
|
} else if ((ke.metaKey || ke.ctrlKey) && ke.key === "Enter") {
|
|
2439
2443
|
e.preventDefault();
|
|
2440
|
-
|
|
2441
|
-
this._doneAttachedPanel();
|
|
2442
|
-
return;
|
|
2443
|
-
}
|
|
2444
|
-
if (!this._canPublish()) {
|
|
2445
|
-
this._focusBlockedSubmitField("published");
|
|
2446
|
-
return;
|
|
2447
|
-
}
|
|
2448
|
-
void this._submit("published");
|
|
2444
|
+
this._publishFromShortcut();
|
|
2449
2445
|
} else if (
|
|
2450
2446
|
(ke.metaKey || ke.ctrlKey) &&
|
|
2451
2447
|
!ke.altKey &&
|
|
@@ -2471,6 +2467,18 @@ export class JantComposeDialog extends LitElement {
|
|
|
2471
2467
|
}
|
|
2472
2468
|
};
|
|
2473
2469
|
|
|
2470
|
+
private _publishFromShortcut() {
|
|
2471
|
+
if (this._attachedPanelOpen) {
|
|
2472
|
+
this._doneAttachedPanel();
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
if (!this._canPublish()) {
|
|
2476
|
+
this._focusBlockedSubmitField("published");
|
|
2477
|
+
return;
|
|
2478
|
+
}
|
|
2479
|
+
void this._submit("published");
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2474
2482
|
private _handleAltPanelOpen = (e: Event) => {
|
|
2475
2483
|
const detail = (e as CustomEvent<{ index: number }>).detail;
|
|
2476
2484
|
this._altPanelIndex = detail.index;
|
|
@@ -2500,7 +2508,10 @@ export class JantComposeDialog extends LitElement {
|
|
|
2500
2508
|
private _handleFullscreenClose = (
|
|
2501
2509
|
e: CustomEvent<ComposeFullscreenCloseDetail>,
|
|
2502
2510
|
) => {
|
|
2503
|
-
const
|
|
2511
|
+
const editors = Array.from(
|
|
2512
|
+
this.querySelectorAll<JantComposeEditor>("jant-compose-editor"),
|
|
2513
|
+
);
|
|
2514
|
+
const editor = editors[e.detail.editorIndex ?? 0] ?? this._editor;
|
|
2504
2515
|
if (editor) {
|
|
2505
2516
|
editor.setEditorState(
|
|
2506
2517
|
e.detail.json as import("@tiptap/core").JSONContent,
|
|
@@ -2511,9 +2522,16 @@ export class JantComposeDialog extends LitElement {
|
|
|
2511
2522
|
// Adopt any in-flight inline image uploads from the fullscreen editor
|
|
2512
2523
|
// so blob: placeholder URLs get replaced when uploads complete.
|
|
2513
2524
|
editor.adoptPendingUploads();
|
|
2514
|
-
|
|
2525
|
+
if (e.detail.intent !== "publish") {
|
|
2526
|
+
this.updateComplete.then(() =>
|
|
2527
|
+
editor.focusSelection(e.detail.selection),
|
|
2528
|
+
);
|
|
2529
|
+
}
|
|
2515
2530
|
}
|
|
2516
2531
|
this._replyExpanded = e.detail.replyExpanded;
|
|
2532
|
+
if (e.detail.intent === "publish") {
|
|
2533
|
+
this._publishFromShortcut();
|
|
2534
|
+
}
|
|
2517
2535
|
};
|
|
2518
2536
|
|
|
2519
2537
|
private _buildFullscreenReplyContext(): ComposeFullscreenReplyContext | null {
|
|
@@ -2530,6 +2548,11 @@ export class JantComposeDialog extends LitElement {
|
|
|
2530
2548
|
e: CustomEvent<ComposeFullscreenOpenDetail>,
|
|
2531
2549
|
) => {
|
|
2532
2550
|
e.detail.replyContext = this._buildFullscreenReplyContext();
|
|
2551
|
+
const editors = Array.from(
|
|
2552
|
+
this.querySelectorAll<JantComposeEditor>("jant-compose-editor"),
|
|
2553
|
+
);
|
|
2554
|
+
const editorIndex = editors.indexOf(e.target as JantComposeEditor);
|
|
2555
|
+
e.detail.editorIndex = editorIndex >= 0 ? editorIndex : 0;
|
|
2533
2556
|
};
|
|
2534
2557
|
|
|
2535
2558
|
private _handleAttachedPanelOpen = (e: Event) => {
|
|
@@ -2551,6 +2574,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
2551
2574
|
placeholder: this.labels.attachedTextPlaceholder,
|
|
2552
2575
|
content,
|
|
2553
2576
|
toolbarMode: "compose",
|
|
2577
|
+
tableControlLabels: this.labels.tableControls,
|
|
2554
2578
|
});
|
|
2555
2579
|
this._focusAttachedEditorBoundary(content);
|
|
2556
2580
|
});
|
|
@@ -2638,6 +2662,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
2638
2662
|
const allDraftItems = (posts as Record<string, unknown>[]).map(
|
|
2639
2663
|
(p): DraftItem => ({
|
|
2640
2664
|
id: p.id as string,
|
|
2665
|
+
slug: p.slug as string,
|
|
2641
2666
|
format: p.format as ComposeFormat,
|
|
2642
2667
|
title:
|
|
2643
2668
|
((p.format as ComposeFormat) === "quote"
|
|
@@ -2744,7 +2769,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
2744
2769
|
this._visibility = post.visibility ?? "public";
|
|
2745
2770
|
this._visibilityLocked = Boolean(post.replyToId);
|
|
2746
2771
|
|
|
2747
|
-
if (post.collectionIds?.length) {
|
|
2772
|
+
if (!post.replyToId && post.collectionIds?.length) {
|
|
2748
2773
|
this._collectionIds = post.collectionIds;
|
|
2749
2774
|
}
|
|
2750
2775
|
|
|
@@ -3168,7 +3193,9 @@ export class JantComposeDialog extends LitElement {
|
|
|
3168
3193
|
return;
|
|
3169
3194
|
}
|
|
3170
3195
|
|
|
3171
|
-
this._collectionIds =
|
|
3196
|
+
this._collectionIds = draft.replyToId
|
|
3197
|
+
? []
|
|
3198
|
+
: [...(draft.collectionIds ?? [])];
|
|
3172
3199
|
this._slug = draft.slug ?? "";
|
|
3173
3200
|
this._slugTaken = false;
|
|
3174
3201
|
this._slugCheckLoading = false;
|
|
@@ -3309,7 +3336,9 @@ export class JantComposeDialog extends LitElement {
|
|
|
3309
3336
|
|
|
3310
3337
|
// Restore metadata
|
|
3311
3338
|
this._format = draft.format;
|
|
3312
|
-
this._collectionIds =
|
|
3339
|
+
this._collectionIds = this._replyToId
|
|
3340
|
+
? []
|
|
3341
|
+
: [...(draft.collectionIds ?? [])];
|
|
3313
3342
|
this._slug = draft.slug ?? "";
|
|
3314
3343
|
this._publishedAtInput = draft.publishedAtInput ?? "";
|
|
3315
3344
|
this._publishedAtTimeMinutes = draft.publishedAtTimeMinutes ?? null;
|
|
@@ -3426,6 +3455,8 @@ export class JantComposeDialog extends LitElement {
|
|
|
3426
3455
|
|
|
3427
3456
|
private _renderDraftItem(draft: DraftItem) {
|
|
3428
3457
|
const preview = this._getDraftPreview(draft);
|
|
3458
|
+
const menuId = `draft-actions-${draft.id}`;
|
|
3459
|
+
const menuOpen = this._draftMenuOpenId === draft.id;
|
|
3429
3460
|
|
|
3430
3461
|
return html`
|
|
3431
3462
|
<div class="compose-draft-item" @click=${() => this._loadDraft(draft.id)}>
|
|
@@ -3442,7 +3473,7 @@ export class JantComposeDialog extends LitElement {
|
|
|
3442
3473
|
</div>
|
|
3443
3474
|
</div>
|
|
3444
3475
|
<div class="relative">
|
|
3445
|
-
${
|
|
3476
|
+
${menuOpen
|
|
3446
3477
|
? html`<div
|
|
3447
3478
|
class="compose-dropdown-backdrop"
|
|
3448
3479
|
@click=${(e: Event) => {
|
|
@@ -3454,6 +3485,10 @@ export class JantComposeDialog extends LitElement {
|
|
|
3454
3485
|
<button
|
|
3455
3486
|
type="button"
|
|
3456
3487
|
class="compose-draft-more"
|
|
3488
|
+
aria-label=${this.labels.draftActions}
|
|
3489
|
+
aria-haspopup="menu"
|
|
3490
|
+
aria-expanded=${menuOpen ? "true" : "false"}
|
|
3491
|
+
aria-controls=${menuId}
|
|
3457
3492
|
@click=${(e: Event) => {
|
|
3458
3493
|
e.stopPropagation();
|
|
3459
3494
|
this._draftMenuOpenId =
|
|
@@ -3466,12 +3501,34 @@ export class JantComposeDialog extends LitElement {
|
|
|
3466
3501
|
<circle cx="12" cy="8" r="1.2" />
|
|
3467
3502
|
</svg>
|
|
3468
3503
|
</button>
|
|
3469
|
-
${
|
|
3504
|
+
${menuOpen
|
|
3470
3505
|
? html`
|
|
3471
|
-
<div
|
|
3506
|
+
<div
|
|
3507
|
+
id=${menuId}
|
|
3508
|
+
class="compose-dropdown compose-dropdown-right"
|
|
3509
|
+
role="menu"
|
|
3510
|
+
>
|
|
3511
|
+
<a
|
|
3512
|
+
class="compose-dropdown-item"
|
|
3513
|
+
href=${publicPath(`/preview/${draft.slug}`)}
|
|
3514
|
+
target="_blank"
|
|
3515
|
+
rel="noopener noreferrer"
|
|
3516
|
+
role="menuitem"
|
|
3517
|
+
@click=${(e: Event) => {
|
|
3518
|
+
e.stopPropagation();
|
|
3519
|
+
this._draftMenuOpenId = null;
|
|
3520
|
+
}}
|
|
3521
|
+
>
|
|
3522
|
+
${this.labels.previewDraft}
|
|
3523
|
+
</a>
|
|
3524
|
+
<div
|
|
3525
|
+
class="compose-dropdown-separator"
|
|
3526
|
+
role="separator"
|
|
3527
|
+
></div>
|
|
3472
3528
|
<button
|
|
3473
3529
|
type="button"
|
|
3474
3530
|
class="compose-dropdown-item compose-dropdown-item-danger"
|
|
3531
|
+
role="menuitem"
|
|
3475
3532
|
@click=${(e: Event) => {
|
|
3476
3533
|
e.stopPropagation();
|
|
3477
3534
|
this._deleteDraft(draft.id);
|
|
@@ -5254,6 +5311,12 @@ export class JantComposeDialog extends LitElement {
|
|
|
5254
5311
|
"jant-compose-editor",
|
|
5255
5312
|
);
|
|
5256
5313
|
editors[this._focusedThreadIndex]?.focusInput();
|
|
5314
|
+
const threadLayout = this.querySelector<HTMLElement>(
|
|
5315
|
+
".compose-thread-compose-layout",
|
|
5316
|
+
);
|
|
5317
|
+
if (threadLayout) {
|
|
5318
|
+
threadLayout.scrollTop = threadLayout.scrollHeight;
|
|
5319
|
+
}
|
|
5257
5320
|
});
|
|
5258
5321
|
}
|
|
5259
5322
|
|
|
@@ -5535,11 +5598,12 @@ export class JantComposeDialog extends LitElement {
|
|
|
5535
5598
|
: html`<div
|
|
5536
5599
|
class=${classMap({
|
|
5537
5600
|
"compose-action-row": true,
|
|
5601
|
+
"compose-action-row-without-collection": !!this._replyToId,
|
|
5538
5602
|
"compose-action-row-overlay-open":
|
|
5539
5603
|
this._showPublishPanel || this._showCollection,
|
|
5540
5604
|
})}
|
|
5541
5605
|
>
|
|
5542
|
-
${this._renderCollectionSelector()}
|
|
5606
|
+
${this._replyToId ? nothing : this._renderCollectionSelector()}
|
|
5543
5607
|
${this._renderPublishButton()}
|
|
5544
5608
|
</div>
|
|
5545
5609
|
${this._renderQuickActionsRow()}`}
|
|
@@ -1006,6 +1006,7 @@ export class JantComposeEditor extends LitElement {
|
|
|
1006
1006
|
rehost: (src) => this.#rehostInlineImage(src),
|
|
1007
1007
|
},
|
|
1008
1008
|
imageNodeLabels: getInlineImageNodeLabels(this.labels),
|
|
1009
|
+
tableControlLabels: this.labels.tableControls,
|
|
1009
1010
|
});
|
|
1010
1011
|
this._lastEditorSelection = this._readEditorSelection();
|
|
1011
1012
|
|
|
@@ -1709,6 +1710,16 @@ export class JantComposeEditor extends LitElement {
|
|
|
1709
1710
|
this._lastFocusedField = target;
|
|
1710
1711
|
}
|
|
1711
1712
|
|
|
1713
|
+
private _handleTitleKeydown(e: globalThis.KeyboardEvent) {
|
|
1714
|
+
if (e.isComposing || e.keyCode === 229) return;
|
|
1715
|
+
if (e.key !== "Enter" || e.metaKey || e.ctrlKey || e.altKey) {
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
e.preventDefault();
|
|
1720
|
+
this._editor?.commands.focus("start");
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1712
1723
|
private _toggleEmojiPicker() {
|
|
1713
1724
|
if (this._showEmojiPicker) {
|
|
1714
1725
|
this.closeEmojiPicker();
|
|
@@ -1974,13 +1985,7 @@ export class JantComposeEditor extends LitElement {
|
|
|
1974
1985
|
.value=${this._title}
|
|
1975
1986
|
@input=${(e: Event) => this._onInput("_title", e)}
|
|
1976
1987
|
@focus=${(e: Event) => this._onFieldFocus(e)}
|
|
1977
|
-
@keydown=${
|
|
1978
|
-
if (e.isComposing || e.keyCode === 229) return;
|
|
1979
|
-
if (e.key === "Enter") {
|
|
1980
|
-
e.preventDefault();
|
|
1981
|
-
this._editor?.commands.focus("start");
|
|
1982
|
-
}
|
|
1983
|
-
}}
|
|
1988
|
+
@keydown=${this._handleTitleKeydown}
|
|
1984
1989
|
class="compose-input compose-note-title"
|
|
1985
1990
|
placeholder=${this.labels.titlePlaceholder}
|
|
1986
1991
|
/>
|
|
@@ -2053,6 +2058,7 @@ export class JantComposeEditor extends LitElement {
|
|
|
2053
2058
|
.value=${this._title}
|
|
2054
2059
|
@input=${(e: Event) => this._onInput("_title", e)}
|
|
2055
2060
|
@focus=${(e: Event) => this._onFieldFocus(e)}
|
|
2061
|
+
@keydown=${this._handleTitleKeydown}
|
|
2056
2062
|
@blur=${() => {
|
|
2057
2063
|
this._showLinkTitleValidation = true;
|
|
2058
2064
|
}}
|
|
@@ -23,7 +23,8 @@ import { createTiptapEditor } from "../tiptap/create-editor.js";
|
|
|
23
23
|
import { uploadAndInsertInlineImage } from "../tiptap/inline-image-upload.js";
|
|
24
24
|
import { getInlineImageNodeLabels } from "./inline-image-issues.js";
|
|
25
25
|
|
|
26
|
-
const ESCAPE_OVERLAY_SELECTOR =
|
|
26
|
+
const ESCAPE_OVERLAY_SELECTOR =
|
|
27
|
+
".tiptap-slash-menu, .tiptap-link-input, .tiptap-table-size-picker, .tiptap-table-options:not([hidden])";
|
|
27
28
|
|
|
28
29
|
export class JantComposeFullscreen extends LitElement {
|
|
29
30
|
static properties = {
|
|
@@ -45,6 +46,7 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
45
46
|
private _editor: Editor | null = null;
|
|
46
47
|
private _content: JSONContent | null = null;
|
|
47
48
|
private _selection: ComposeEditorSelection | null = null;
|
|
49
|
+
private _editorIndex = 0;
|
|
48
50
|
private _fileInput: HTMLInputElement | null = null;
|
|
49
51
|
#inlineImageUploadPromises = new Set<Promise<void>>();
|
|
50
52
|
|
|
@@ -130,6 +132,7 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
130
132
|
this._showTitle = e.detail.showTitle || e.detail.title.trim().length > 0;
|
|
131
133
|
this._replyContext = e.detail.replyContext ?? null;
|
|
132
134
|
this._replyExpanded = e.detail.replyContext?.expanded ?? false;
|
|
135
|
+
this._editorIndex = e.detail.editorIndex ?? 0;
|
|
133
136
|
this._open = true;
|
|
134
137
|
this.updateComplete.then(() => {
|
|
135
138
|
const dialog = this.querySelector<HTMLDialogElement>(
|
|
@@ -161,6 +164,7 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
161
164
|
uploadInlineImage: (file) => this._uploadAndInsertImage(file),
|
|
162
165
|
},
|
|
163
166
|
imageNodeLabels: getInlineImageNodeLabels(this.labels),
|
|
167
|
+
tableControlLabels: this.labels.tableControls,
|
|
164
168
|
});
|
|
165
169
|
|
|
166
170
|
const selection = this._selection;
|
|
@@ -189,9 +193,18 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
189
193
|
};
|
|
190
194
|
|
|
191
195
|
private _onDocumentKeydown = (e: globalThis.KeyboardEvent) => {
|
|
192
|
-
if (!this._open
|
|
193
|
-
// Let IME consume
|
|
196
|
+
if (!this._open) return;
|
|
197
|
+
// Let IME consume keys during composition (e.g. CJK candidate selection).
|
|
194
198
|
if (e.isComposing || e.keyCode === 229) return;
|
|
199
|
+
|
|
200
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
e.stopPropagation();
|
|
203
|
+
this._publish();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (e.key !== "Escape") return;
|
|
195
208
|
if (this._hasActiveEscapeOverlay()) return;
|
|
196
209
|
|
|
197
210
|
e.preventDefault();
|
|
@@ -210,7 +223,7 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
210
223
|
).some((el) => getComputedStyle(el).display !== "none");
|
|
211
224
|
}
|
|
212
225
|
|
|
213
|
-
private _finishClose() {
|
|
226
|
+
private _finishClose(intent?: "publish") {
|
|
214
227
|
const json = this._editor?.getJSON() ?? this._content;
|
|
215
228
|
const selection = this._editor
|
|
216
229
|
? {
|
|
@@ -238,6 +251,8 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
238
251
|
showTitle: this._showTitle || this._title.trim().length > 0,
|
|
239
252
|
selection,
|
|
240
253
|
replyExpanded: this._replyExpanded,
|
|
254
|
+
intent,
|
|
255
|
+
editorIndex: this._editorIndex,
|
|
241
256
|
},
|
|
242
257
|
}),
|
|
243
258
|
);
|
|
@@ -248,6 +263,11 @@ export class JantComposeFullscreen extends LitElement {
|
|
|
248
263
|
this._finishClose();
|
|
249
264
|
}
|
|
250
265
|
|
|
266
|
+
private _publish() {
|
|
267
|
+
if (!this._open) return;
|
|
268
|
+
this._finishClose("publish");
|
|
269
|
+
}
|
|
270
|
+
|
|
251
271
|
private _revealTitle() {
|
|
252
272
|
this._showTitle = true;
|
|
253
273
|
this.updateComplete.then(() => {
|