1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
import type { Bookmark } from "@/timeline";
import {
EMPTY_PREVIEW_OVERLAY_SOURCE_RESULT,
type PreviewOverlayDefinition,
type PreviewOverlaySourceResult,
} from "@/preview/overlays";
import { getBookmarksActiveAtTime } from "./utils";
export const bookmarkNotesPreviewOverlay: PreviewOverlayDefinition = {
id: "bookmark-notes",
label: "Show bookmark notes",
defaultVisible: true,
};
function BookmarkNotesOverlay({
bookmarks,
}: {
bookmarks: Array<{ time: number; note: string; color?: string }>;
}) {
return (
<div className="flex flex-col gap-1.5" aria-live="polite">
{bookmarks.map((bookmark) => (
<div
key={bookmark.time}
className="flex max-w-[min(200px,50vw)] px-2.5 py-1.5 text-left text-white text-xs shadow-md backdrop-blur-sm"
style={{
backgroundColor: "rgb(0 0 0 / 0.5)",
borderLeft: bookmark.color
? `3px solid ${bookmark.color}`
: "3px solid var(--primary)",
}}
>
{bookmark.note}
</div>
))}
</div>
);
}
export function getBookmarkPreviewOverlaySource({
bookmarks,
time,
isVisible,
}: {
bookmarks: Bookmark[];
time: number;
isVisible: boolean;
}): PreviewOverlaySourceResult {
const bookmarksWithNotes = getBookmarksActiveAtTime({
bookmarks,
time,
}).flatMap((bookmark) => {
if (bookmark.note == null || bookmark.note.trim() === "") {
return [];
}
return [
{
time: bookmark.time,
note: bookmark.note,
color: bookmark.color,
},
];
});
if (!isVisible || bookmarksWithNotes.length === 0) {
return {
...EMPTY_PREVIEW_OVERLAY_SOURCE_RESULT,
definitions: [bookmarkNotesPreviewOverlay],
};
}
return {
definitions: [bookmarkNotesPreviewOverlay],
instances: [
{
id: bookmarkNotesPreviewOverlay.id,
mount: { kind: "hud", anchor: "top-left", order: 0 },
plane: "over-interaction",
pointerEvents: "none",
render: () => <BookmarkNotesOverlay bookmarks={bookmarksWithNotes} />,
},
],
};
}
|