@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
|
@@ -10,7 +10,7 @@ import type { Editor, JSONContent } from "@tiptap/core";
|
|
|
10
10
|
import type {
|
|
11
11
|
PostFormInitial,
|
|
12
12
|
PostFormLabels,
|
|
13
|
-
|
|
13
|
+
ThreadCollectionOption,
|
|
14
14
|
PostMediaItem,
|
|
15
15
|
PostSubmitDetail,
|
|
16
16
|
PostFormat,
|
|
@@ -116,7 +116,7 @@ export class JantPostForm extends LitElement {
|
|
|
116
116
|
|
|
117
117
|
declare labels: PostFormLabels;
|
|
118
118
|
declare initial: PostFormInitial;
|
|
119
|
-
declare collections:
|
|
119
|
+
declare collections: ThreadCollectionOption[];
|
|
120
120
|
declare media: PostMediaItem[];
|
|
121
121
|
declare action: string;
|
|
122
122
|
declare cancelHref: string;
|
|
@@ -191,7 +191,7 @@ export class JantPostForm extends LitElement {
|
|
|
191
191
|
});
|
|
192
192
|
}
|
|
193
193
|
if (typeof this.collections === "string") {
|
|
194
|
-
this.collections = parseJson<
|
|
194
|
+
this.collections = parseJson<ThreadCollectionOption[]>(
|
|
195
195
|
this.collections,
|
|
196
196
|
[],
|
|
197
197
|
);
|
|
@@ -27,6 +27,7 @@ import type { CollectionSubmitDetail } from "./collection-types.js";
|
|
|
27
27
|
|
|
28
28
|
interface PostMenuData {
|
|
29
29
|
id: string;
|
|
30
|
+
threadId: string;
|
|
30
31
|
pinned: boolean;
|
|
31
32
|
pinnedInCollection: boolean;
|
|
32
33
|
featured: boolean;
|
|
@@ -44,7 +45,7 @@ interface CollectionsResponse {
|
|
|
44
45
|
collections?: CollectionItem[];
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
interface
|
|
48
|
+
interface ThreadCollectionsResponse {
|
|
48
49
|
collectionIds?: string[];
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -78,6 +79,34 @@ export function removeLeadingFeedDivider(
|
|
|
78
79
|
firstDivider?.remove();
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
function findThreadRootArticle(threadId: string): HTMLElement | null {
|
|
83
|
+
return (
|
|
84
|
+
Array.from(
|
|
85
|
+
document.querySelectorAll<HTMLElement>("article[data-post-id]"),
|
|
86
|
+
).find((article) => article.dataset.postId === threadId) ?? null
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function readPostMenuData(article: HTMLElement): PostMenuData | null {
|
|
91
|
+
const id = article.dataset.postId;
|
|
92
|
+
if (!id) return null;
|
|
93
|
+
|
|
94
|
+
const threadId = article.dataset.threadRootId ?? id;
|
|
95
|
+
const threadRootArticle = findThreadRootArticle(threadId) ?? article;
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
id,
|
|
99
|
+
threadId,
|
|
100
|
+
pinned: article.hasAttribute("data-post-pinned"),
|
|
101
|
+
pinnedInCollection: threadRootArticle.hasAttribute(
|
|
102
|
+
"data-post-pinned-in-collection",
|
|
103
|
+
),
|
|
104
|
+
featured: article.hasAttribute("data-post-featured"),
|
|
105
|
+
visibility: article.dataset.postVisibility ?? "public",
|
|
106
|
+
isReply: threadId !== id || article.hasAttribute("data-post-reply"),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
81
110
|
export class JantPostMenu extends LitElement {
|
|
82
111
|
static properties = {
|
|
83
112
|
_open: { state: true },
|
|
@@ -89,7 +118,7 @@ export class JantPostMenu extends LitElement {
|
|
|
89
118
|
_collections: { state: true },
|
|
90
119
|
_collectionsLoading: { state: true },
|
|
91
120
|
_collectionSearch: { state: true },
|
|
92
|
-
|
|
121
|
+
_threadCollectionIds: { state: true },
|
|
93
122
|
_addCollectionPanelOpen: { state: true },
|
|
94
123
|
};
|
|
95
124
|
|
|
@@ -102,7 +131,7 @@ export class JantPostMenu extends LitElement {
|
|
|
102
131
|
declare _collections: CollectionItem[] | null;
|
|
103
132
|
declare _collectionsLoading: boolean;
|
|
104
133
|
declare _collectionSearch: string;
|
|
105
|
-
declare
|
|
134
|
+
declare _threadCollectionIds: string[];
|
|
106
135
|
declare _addCollectionPanelOpen: boolean;
|
|
107
136
|
declare _triggerEl: HTMLElement | null;
|
|
108
137
|
|
|
@@ -127,7 +156,7 @@ export class JantPostMenu extends LitElement {
|
|
|
127
156
|
this._collections = null;
|
|
128
157
|
this._collectionsLoading = false;
|
|
129
158
|
this._collectionSearch = "";
|
|
130
|
-
this.
|
|
159
|
+
this._threadCollectionIds = [];
|
|
131
160
|
this._addCollectionPanelOpen = false;
|
|
132
161
|
this._triggerEl = null;
|
|
133
162
|
}
|
|
@@ -246,25 +275,16 @@ export class JantPostMenu extends LitElement {
|
|
|
246
275
|
const article = trigger.closest<HTMLElement>("article[data-post]");
|
|
247
276
|
if (!article) return;
|
|
248
277
|
|
|
249
|
-
const
|
|
250
|
-
if (!
|
|
278
|
+
const menuData = readPostMenuData(article);
|
|
279
|
+
if (!menuData) return;
|
|
251
280
|
|
|
252
281
|
// Toggle: close if same post, open if different
|
|
253
|
-
if (this._open && this._data?.id ===
|
|
282
|
+
if (this._open && this._data?.id === menuData.id) {
|
|
254
283
|
this.#close();
|
|
255
284
|
return;
|
|
256
285
|
}
|
|
257
286
|
|
|
258
|
-
this._data =
|
|
259
|
-
id: postId,
|
|
260
|
-
pinned: article.hasAttribute("data-post-pinned"),
|
|
261
|
-
pinnedInCollection: article.hasAttribute(
|
|
262
|
-
"data-post-pinned-in-collection",
|
|
263
|
-
),
|
|
264
|
-
featured: article.hasAttribute("data-post-featured"),
|
|
265
|
-
visibility: article.dataset.postVisibility ?? "public",
|
|
266
|
-
isReply: article.hasAttribute("data-post-reply"),
|
|
267
|
-
};
|
|
287
|
+
this._data = menuData;
|
|
268
288
|
|
|
269
289
|
// Position relative to trigger
|
|
270
290
|
this._triggerEl = trigger;
|
|
@@ -472,19 +492,10 @@ export class JantPostMenu extends LitElement {
|
|
|
472
492
|
* relative to the post's menu trigger button.
|
|
473
493
|
*/
|
|
474
494
|
openCollectionsForPost(article: HTMLElement) {
|
|
475
|
-
const
|
|
476
|
-
if (!
|
|
477
|
-
|
|
478
|
-
this._data =
|
|
479
|
-
id: postId,
|
|
480
|
-
pinned: article.hasAttribute("data-post-pinned"),
|
|
481
|
-
pinnedInCollection: article.hasAttribute(
|
|
482
|
-
"data-post-pinned-in-collection",
|
|
483
|
-
),
|
|
484
|
-
featured: article.hasAttribute("data-post-featured"),
|
|
485
|
-
visibility: article.dataset.postVisibility ?? "public",
|
|
486
|
-
isReply: article.hasAttribute("data-post-reply"),
|
|
487
|
-
};
|
|
495
|
+
const menuData = readPostMenuData(article);
|
|
496
|
+
if (!menuData || menuData.isReply) return;
|
|
497
|
+
|
|
498
|
+
this._data = menuData;
|
|
488
499
|
|
|
489
500
|
const trigger = article.querySelector<HTMLElement>(
|
|
490
501
|
"[data-post-menu-trigger]",
|
|
@@ -650,7 +661,7 @@ export class JantPostMenu extends LitElement {
|
|
|
650
661
|
|
|
651
662
|
#toggleCollectionPin() {
|
|
652
663
|
if (!this._data) return;
|
|
653
|
-
const
|
|
664
|
+
const threadId = this._data.threadId;
|
|
654
665
|
const collectionId = document.querySelector<HTMLElement>(
|
|
655
666
|
"[data-collection-id]",
|
|
656
667
|
)?.dataset.collectionId;
|
|
@@ -659,9 +670,7 @@ export class JantPostMenu extends LitElement {
|
|
|
659
670
|
const newPinned = !this._data.pinnedInCollection;
|
|
660
671
|
|
|
661
672
|
// Optimistic update
|
|
662
|
-
const article =
|
|
663
|
-
`article[data-post-id="${postId}"]`,
|
|
664
|
-
);
|
|
673
|
+
const article = findThreadRootArticle(threadId);
|
|
665
674
|
if (article) {
|
|
666
675
|
if (newPinned) {
|
|
667
676
|
article.setAttribute("data-post-pinned-in-collection", "");
|
|
@@ -677,14 +686,14 @@ export class JantPostMenu extends LitElement {
|
|
|
677
686
|
this.#close();
|
|
678
687
|
|
|
679
688
|
const method = newPinned ? "PUT" : "DELETE";
|
|
680
|
-
fetch(`/api/collections/${collectionId}/
|
|
689
|
+
fetch(`/api/collections/${collectionId}/threads/${threadId}/pin`, {
|
|
690
|
+
method,
|
|
691
|
+
})
|
|
681
692
|
.then((res) => {
|
|
682
693
|
if (!res.ok) throw new Error();
|
|
683
694
|
})
|
|
684
695
|
.catch(() => {
|
|
685
|
-
const el =
|
|
686
|
-
`article[data-post-id="${postId}"]`,
|
|
687
|
-
);
|
|
696
|
+
const el = findThreadRootArticle(threadId);
|
|
688
697
|
if (el) {
|
|
689
698
|
if (newPinned) {
|
|
690
699
|
el.removeAttribute("data-post-pinned-in-collection");
|
|
@@ -754,7 +763,7 @@ export class JantPostMenu extends LitElement {
|
|
|
754
763
|
}
|
|
755
764
|
|
|
756
765
|
async #openCollectionPicker() {
|
|
757
|
-
if (!this._data) return;
|
|
766
|
+
if (!this._data || this._data.isReply) return;
|
|
758
767
|
const postId = this._data.id;
|
|
759
768
|
this._view = "collections";
|
|
760
769
|
this._collectionSearch = "";
|
|
@@ -776,18 +785,18 @@ export class JantPostMenu extends LitElement {
|
|
|
776
785
|
const collectionsData =
|
|
777
786
|
(await collectionsRes.json()) as CollectionsResponse;
|
|
778
787
|
const collections = collectionsData.collections ?? [];
|
|
779
|
-
let
|
|
788
|
+
let threadCollectionIds = this._threadCollectionIds;
|
|
780
789
|
|
|
781
790
|
if (postRes.ok) {
|
|
782
|
-
const postData = (await postRes.json()) as
|
|
783
|
-
|
|
791
|
+
const postData = (await postRes.json()) as ThreadCollectionsResponse;
|
|
792
|
+
threadCollectionIds = postData.collectionIds ?? [];
|
|
784
793
|
}
|
|
785
794
|
this.#collectionPickerOrder = getSelectedFirstOrder(
|
|
786
795
|
collections,
|
|
787
|
-
|
|
796
|
+
threadCollectionIds,
|
|
788
797
|
);
|
|
789
798
|
this._collections = collections;
|
|
790
|
-
this.
|
|
799
|
+
this._threadCollectionIds = threadCollectionIds;
|
|
791
800
|
} catch {
|
|
792
801
|
this._collections = this._collections ?? [];
|
|
793
802
|
showToast("Could not load collections.", "error");
|
|
@@ -800,23 +809,23 @@ export class JantPostMenu extends LitElement {
|
|
|
800
809
|
|
|
801
810
|
#toggleCollection(collectionId: string) {
|
|
802
811
|
if (!this._data) return;
|
|
803
|
-
const
|
|
804
|
-
const isSelected = this.
|
|
812
|
+
const threadId = this._data.threadId;
|
|
813
|
+
const isSelected = this._threadCollectionIds.includes(collectionId);
|
|
805
814
|
|
|
806
815
|
// Optimistic update
|
|
807
816
|
if (isSelected) {
|
|
808
|
-
this.
|
|
817
|
+
this._threadCollectionIds = this._threadCollectionIds.filter(
|
|
809
818
|
(id) => id !== collectionId,
|
|
810
819
|
);
|
|
811
820
|
} else {
|
|
812
|
-
this.
|
|
821
|
+
this._threadCollectionIds = [...this._threadCollectionIds, collectionId];
|
|
813
822
|
}
|
|
814
823
|
this.#collectionsDirty = true;
|
|
815
824
|
showToast(isSelected ? "Removed from collection." : "Added to collection.");
|
|
816
825
|
|
|
817
826
|
// Fire request in background, revert on failure
|
|
818
827
|
if (isSelected) {
|
|
819
|
-
fetch(`/api/collections/${collectionId}/
|
|
828
|
+
fetch(`/api/collections/${collectionId}/threads/${threadId}`, {
|
|
820
829
|
method: "DELETE",
|
|
821
830
|
})
|
|
822
831
|
.then((res) => {
|
|
@@ -825,19 +834,19 @@ export class JantPostMenu extends LitElement {
|
|
|
825
834
|
})
|
|
826
835
|
.catch(() => {
|
|
827
836
|
// Revert: re-add
|
|
828
|
-
if (!this.
|
|
829
|
-
this.
|
|
830
|
-
...this.
|
|
837
|
+
if (!this._threadCollectionIds.includes(collectionId)) {
|
|
838
|
+
this._threadCollectionIds = [
|
|
839
|
+
...this._threadCollectionIds,
|
|
831
840
|
collectionId,
|
|
832
841
|
];
|
|
833
842
|
}
|
|
834
843
|
showToast("Could not remove from collection. Try again.", "error");
|
|
835
844
|
});
|
|
836
845
|
} else {
|
|
837
|
-
fetch(`/api/collections/${collectionId}/
|
|
846
|
+
fetch(`/api/collections/${collectionId}/threads`, {
|
|
838
847
|
method: "POST",
|
|
839
848
|
headers: { "Content-Type": "application/json" },
|
|
840
|
-
body: JSON.stringify({
|
|
849
|
+
body: JSON.stringify({ threadId }),
|
|
841
850
|
})
|
|
842
851
|
.then((res) => {
|
|
843
852
|
if (!res.ok) {
|
|
@@ -849,7 +858,7 @@ export class JantPostMenu extends LitElement {
|
|
|
849
858
|
})
|
|
850
859
|
.catch(() => {
|
|
851
860
|
// Revert: remove
|
|
852
|
-
this.
|
|
861
|
+
this._threadCollectionIds = this._threadCollectionIds.filter(
|
|
853
862
|
(id) => id !== collectionId,
|
|
854
863
|
);
|
|
855
864
|
showToast("Could not add to collection. Try again.", "error");
|
|
@@ -920,14 +929,14 @@ export class JantPostMenu extends LitElement {
|
|
|
920
929
|
|
|
921
930
|
this._collections = [...(this._collections ?? []), newItem];
|
|
922
931
|
|
|
923
|
-
// Auto-add the
|
|
932
|
+
// Auto-add the thread to the newly created collection
|
|
924
933
|
if (this._data) {
|
|
925
|
-
await fetch(`/api/collections/${created.id}/
|
|
934
|
+
await fetch(`/api/collections/${created.id}/threads`, {
|
|
926
935
|
method: "POST",
|
|
927
936
|
headers: { "Content-Type": "application/json" },
|
|
928
|
-
body: JSON.stringify({
|
|
937
|
+
body: JSON.stringify({ threadId: this._data.threadId }),
|
|
929
938
|
});
|
|
930
|
-
this.
|
|
939
|
+
this._threadCollectionIds = [...this._threadCollectionIds, created.id];
|
|
931
940
|
}
|
|
932
941
|
|
|
933
942
|
await this.#refreshComposeCollections();
|
|
@@ -1193,7 +1202,7 @@ export class JantPostMenu extends LitElement {
|
|
|
1193
1202
|
? html`<div class="post-menu-picker-empty">Loading...</div>`
|
|
1194
1203
|
: filtered.length > 0
|
|
1195
1204
|
? filtered.map((c) => {
|
|
1196
|
-
const selected = this.
|
|
1205
|
+
const selected = this._threadCollectionIds.includes(c.id);
|
|
1197
1206
|
return html`
|
|
1198
1207
|
<button
|
|
1199
1208
|
type="button"
|
|
@@ -1492,19 +1501,22 @@ export class JantPostMenu extends LitElement {
|
|
|
1492
1501
|
<span class="post-menu-item-trailing">${this.#iconEdit()}</span>
|
|
1493
1502
|
</button>
|
|
1494
1503
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1504
|
+
${this._data.isReply
|
|
1505
|
+
? nothing
|
|
1506
|
+
: html`
|
|
1507
|
+
<button
|
|
1508
|
+
type="button"
|
|
1509
|
+
role="menuitem"
|
|
1510
|
+
class="post-menu-item"
|
|
1511
|
+
data-post-menu-open-collections
|
|
1512
|
+
@click=${() => this.#openCollectionPicker()}
|
|
1513
|
+
>
|
|
1514
|
+
<span class="post-menu-item-label">Add to collection</span>
|
|
1515
|
+
<span class="post-menu-item-trailing post-menu-item-chevron"
|
|
1516
|
+
>${this.#iconChevronRight()}</span
|
|
1517
|
+
>
|
|
1518
|
+
</button>
|
|
1519
|
+
`}
|
|
1508
1520
|
${this._data.isReply
|
|
1509
1521
|
? nothing
|
|
1510
1522
|
: html`
|
|
@@ -1562,7 +1574,7 @@ export class JantPostMenu extends LitElement {
|
|
|
1562
1574
|
>
|
|
1563
1575
|
</button>
|
|
1564
1576
|
`}
|
|
1565
|
-
${collectionId
|
|
1577
|
+
${collectionId && !this._data.isReply
|
|
1566
1578
|
? html`
|
|
1567
1579
|
<button
|
|
1568
1580
|
type="button"
|
|
@@ -3,18 +3,27 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { SystemNavKey } from "../../types/constants.js";
|
|
6
|
+
import type { CollectionFormLabels } from "./collection-types.js";
|
|
6
7
|
|
|
7
8
|
export interface NavManagerItem {
|
|
8
9
|
id: string;
|
|
9
|
-
type: "link" | "system" | "collection";
|
|
10
|
+
type: "link" | "system" | "collection" | "page";
|
|
10
11
|
systemKey?: SystemNavKey;
|
|
11
12
|
collectionId?: string;
|
|
13
|
+
postId?: string;
|
|
12
14
|
label: string;
|
|
13
15
|
displayLabel?: string;
|
|
14
16
|
url: string;
|
|
15
17
|
placement?: "header" | "more";
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
export interface NavManagerPage {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
slug: string;
|
|
24
|
+
updatedAt: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
export interface SystemNavConfig {
|
|
19
28
|
key: SystemNavKey;
|
|
20
29
|
label: string;
|
|
@@ -36,8 +45,9 @@ export interface NavManagerSuggestedLink {
|
|
|
36
45
|
url: string;
|
|
37
46
|
targetType: "page" | "collection" | "archive";
|
|
38
47
|
targetLabel: string;
|
|
39
|
-
navItemType: "link" | "collection";
|
|
48
|
+
navItemType: "link" | "collection" | "page";
|
|
40
49
|
collectionId?: string;
|
|
50
|
+
postId?: string;
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
export interface NavManagerLabels {
|
|
@@ -45,6 +55,7 @@ export interface NavManagerLabels {
|
|
|
45
55
|
navigationItems: string;
|
|
46
56
|
emptyState: string;
|
|
47
57
|
link: string;
|
|
58
|
+
page: string;
|
|
48
59
|
system: string;
|
|
49
60
|
toggleEdit: string;
|
|
50
61
|
label: string;
|
|
@@ -53,6 +64,7 @@ export interface NavManagerLabels {
|
|
|
53
64
|
delete: string;
|
|
54
65
|
remove: string;
|
|
55
66
|
confirmDeleteLink: string;
|
|
67
|
+
confirmDeletePage: string;
|
|
56
68
|
orderSaved: string;
|
|
57
69
|
labelRequired: string;
|
|
58
70
|
saveFailed: string;
|
|
@@ -68,12 +80,49 @@ export interface NavManagerLabels {
|
|
|
68
80
|
suggestedLinksDescription: string;
|
|
69
81
|
addSuggestedLink: string;
|
|
70
82
|
suggestedLinkAdded: string;
|
|
83
|
+
addPageToNavigation: string;
|
|
84
|
+
addPageDescription: string;
|
|
85
|
+
addPage: string;
|
|
86
|
+
searchPages: string;
|
|
87
|
+
recentPages: string;
|
|
88
|
+
searchingPages: string;
|
|
89
|
+
noMatchingPages: string;
|
|
90
|
+
noPages: string;
|
|
91
|
+
pageSearchFailed: string;
|
|
92
|
+
createNewPage: string;
|
|
93
|
+
createPage: string;
|
|
94
|
+
createPageDescription: string;
|
|
95
|
+
pageTitle: string;
|
|
96
|
+
pageAddress: string;
|
|
97
|
+
pageVisibilityHint: string;
|
|
98
|
+
titleRequired: string;
|
|
99
|
+
slugInvalid: string;
|
|
100
|
+
slugReserved: string;
|
|
101
|
+
slugTooLong: string;
|
|
102
|
+
slugUnavailable: string;
|
|
103
|
+
checkingAddress: string;
|
|
104
|
+
creatingPage: string;
|
|
105
|
+
createPageFailed: string;
|
|
106
|
+
pageCreated: string;
|
|
107
|
+
pageCreatedDescription: string;
|
|
108
|
+
addToNavigation: string;
|
|
109
|
+
editPage: string;
|
|
110
|
+
pageAdded: string;
|
|
111
|
+
back: string;
|
|
71
112
|
collection: string;
|
|
72
113
|
addCollection: string;
|
|
73
114
|
addCollectionToNavigation: string;
|
|
74
115
|
addCollectionDescription: string;
|
|
75
116
|
allCollectionsAdded: string;
|
|
76
117
|
noCollections: string;
|
|
118
|
+
createNewCollection: string;
|
|
119
|
+
createCollection: string;
|
|
120
|
+
creatingCollection: string;
|
|
121
|
+
createCollectionFailed: string;
|
|
122
|
+
collectionCreatedDescription: string;
|
|
123
|
+
editCollection: string;
|
|
124
|
+
collectionAdded: string;
|
|
125
|
+
collectionFormLabels: CollectionFormLabels;
|
|
77
126
|
confirmDeleteCollection: string;
|
|
78
127
|
headerSection: string;
|
|
79
128
|
moreSection: string;
|
|
@@ -621,7 +621,10 @@ function buildPostBody(
|
|
|
621
621
|
? detail.rating
|
|
622
622
|
: null
|
|
623
623
|
: detail.rating || undefined,
|
|
624
|
-
|
|
624
|
+
// Reply creation and Child edits must not reorganize their existing
|
|
625
|
+
// Thread as a side effect. Collection management stays on Thread-level
|
|
626
|
+
// organization surfaces; JSON.stringify omits this undefined field.
|
|
627
|
+
collectionIds: detail.replyToId ? undefined : detail.collectionIds,
|
|
625
628
|
attachments: attachments.length > 0 ? attachments : undefined,
|
|
626
629
|
replyToId: detail.replyToId || undefined,
|
|
627
630
|
quietReply: detail.quietReply || undefined,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isMediaVideoPlaybackPaused,
|
|
3
|
+
MEDIA_LIGHTBOX_TOGGLE_EVENT,
|
|
4
|
+
MEDIA_VIDEO_PLAYBACK_INTENT_EVENT,
|
|
5
|
+
setMediaVideoPlaybackPaused,
|
|
6
|
+
type MediaVideoPlaybackIntentDetail,
|
|
7
|
+
} from "./media-lightbox-events.js";
|
|
2
8
|
|
|
3
9
|
const FEED_VIDEO_PRELOAD_ROOT_MARGIN = "75% 0px";
|
|
4
10
|
const FEED_VIDEO_PLAY_THRESHOLD = 0.6;
|
|
@@ -72,6 +78,28 @@ function readMetrics(video: HTMLVideoElement): FeedVideoMetrics | undefined {
|
|
|
72
78
|
return videoMetrics.get(video);
|
|
73
79
|
}
|
|
74
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Decide whether a feed video is excluded from autoplay by explicit user
|
|
83
|
+
* intent.
|
|
84
|
+
*
|
|
85
|
+
* @param mediaId - Stable media ID from the rendered video
|
|
86
|
+
* @returns `true` when autoplay should leave this media paused
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* shouldSuppressFeedVideoAutoplay("med_123");
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export function shouldSuppressFeedVideoAutoplay(
|
|
94
|
+
mediaId: string | undefined,
|
|
95
|
+
): boolean {
|
|
96
|
+
return isMediaVideoPlaybackPaused(mediaId);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function isAutoplaySuppressed(video: HTMLVideoElement): boolean {
|
|
100
|
+
return shouldSuppressFeedVideoAutoplay(video.dataset.feedVideoId);
|
|
101
|
+
}
|
|
102
|
+
|
|
75
103
|
function getMuteButton(video: HTMLVideoElement): HTMLButtonElement | null {
|
|
76
104
|
return (
|
|
77
105
|
video
|
|
@@ -120,6 +148,11 @@ function pauseVideo(video: HTMLVideoElement | null): void {
|
|
|
120
148
|
}
|
|
121
149
|
|
|
122
150
|
function playVideo(video: HTMLVideoElement): void {
|
|
151
|
+
if (isAutoplaySuppressed(video)) {
|
|
152
|
+
pauseVideo(video);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
123
156
|
ensureVideoLoaded(video);
|
|
124
157
|
video.muted = soundEnabledVideo !== video;
|
|
125
158
|
video.playsInline = true;
|
|
@@ -159,12 +192,13 @@ function reevaluateAutoplay(): void {
|
|
|
159
192
|
for (const video of registeredVideos) {
|
|
160
193
|
const metrics = readMetrics(video);
|
|
161
194
|
if (!metrics) continue;
|
|
195
|
+
if (isAutoplaySuppressed(video)) continue;
|
|
162
196
|
if (metrics.intersectionRatio < FEED_VIDEO_PLAY_THRESHOLD) continue;
|
|
163
197
|
candidates.push({ video, ...metrics });
|
|
164
198
|
}
|
|
165
199
|
|
|
166
200
|
let winner: HTMLVideoElement | null = null;
|
|
167
|
-
if (preferredVideo?.isConnected) {
|
|
201
|
+
if (preferredVideo?.isConnected && !isAutoplaySuppressed(preferredVideo)) {
|
|
168
202
|
const preferredMetrics = readMetrics(preferredVideo);
|
|
169
203
|
if (
|
|
170
204
|
preferredMetrics &&
|
|
@@ -177,6 +211,8 @@ function reevaluateAutoplay(): void {
|
|
|
177
211
|
) {
|
|
178
212
|
preferredVideo = null;
|
|
179
213
|
}
|
|
214
|
+
} else if (preferredVideo && isAutoplaySuppressed(preferredVideo)) {
|
|
215
|
+
preferredVideo = null;
|
|
180
216
|
}
|
|
181
217
|
|
|
182
218
|
if (!winner) {
|
|
@@ -187,6 +223,7 @@ function reevaluateAutoplay(): void {
|
|
|
187
223
|
const currentMetrics = activeVideo ? readMetrics(activeVideo) : undefined;
|
|
188
224
|
if (
|
|
189
225
|
activeVideo &&
|
|
226
|
+
!isAutoplaySuppressed(activeVideo) &&
|
|
190
227
|
currentMetrics &&
|
|
191
228
|
currentMetrics.intersectionRatio > FEED_VIDEO_PAUSE_THRESHOLD
|
|
192
229
|
) {
|
|
@@ -313,6 +350,10 @@ function handleMuteToggle(event: Event): void {
|
|
|
313
350
|
return;
|
|
314
351
|
}
|
|
315
352
|
|
|
353
|
+
const mediaId = video.dataset.feedVideoId?.trim();
|
|
354
|
+
if (mediaId) {
|
|
355
|
+
setMediaVideoPlaybackPaused(mediaId, false);
|
|
356
|
+
}
|
|
316
357
|
preferredVideo = video;
|
|
317
358
|
|
|
318
359
|
const willEnableSound = soundEnabledVideo !== video || video.muted;
|
|
@@ -358,6 +399,25 @@ document.addEventListener(MEDIA_LIGHTBOX_TOGGLE_EVENT, (event: Event) => {
|
|
|
358
399
|
scheduleReevaluate();
|
|
359
400
|
});
|
|
360
401
|
|
|
402
|
+
document.addEventListener(MEDIA_VIDEO_PLAYBACK_INTENT_EVENT, (event: Event) => {
|
|
403
|
+
const detail = (event as CustomEvent<MediaVideoPlaybackIntentDetail>).detail;
|
|
404
|
+
const mediaId = detail?.mediaId?.trim();
|
|
405
|
+
if (!mediaId || typeof detail.paused !== "boolean") {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
for (const video of registeredVideos) {
|
|
410
|
+
if (video.dataset.feedVideoId?.trim() !== mediaId) continue;
|
|
411
|
+
if (detail.paused) {
|
|
412
|
+
pauseVideo(video);
|
|
413
|
+
if (activeVideo === video) activeVideo = null;
|
|
414
|
+
if (preferredVideo === video) preferredVideo = null;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
scheduleReevaluate();
|
|
419
|
+
});
|
|
420
|
+
|
|
361
421
|
document.addEventListener("visibilitychange", () => {
|
|
362
422
|
if (document.hidden) {
|
|
363
423
|
pauseVideo(activeVideo);
|