1import {
2 SOURCE_CONTROL_MEDIA_ASSET,
3 type AssetResource,
4 type ChatFileAttachment,
5 type EnvironmentId,
6} from "@t3tools/contracts";
7import { videoMimeType } from "@t3tools/shared/video";
8
9import type { DraftComposerFileAttachment } from "./composerImages";
10import type { MediaActionsSource } from "./mediaActionsSource";
11
12export type MediaVideoPreviewSource = {
13 readonly type: "media";
14 readonly name: string;
15 readonly mimeType: string;
16 readonly sourceIdentifier?: string;
17 readonly srcFragment?: string;
18 readonly actionsSource?: MediaActionsSource;
19} & (
20 | { readonly uri: string }
21 | {
22 readonly environmentId: EnvironmentId;
23 readonly resource: Extract<
24 AssetResource,
25 {
26 readonly _tag:
27 | "attachment"
28 | "media-file"
29 | "draft-workspace-file"
30 | typeof SOURCE_CONTROL_MEDIA_ASSET;
31 }
32 >;
33 }
34);
35
36export function mediaVideoPreviewUri(
37 source: MediaVideoPreviewSource,
38 assetUrl: string | null,
39): string | null {
40 if ("uri" in source) return source.uri;
41 return assetUrl === null ? null : assetUrl + (source.srcFragment ?? "");
42}
43
44export function mediaVideoThumbnailKey(source: MediaVideoPreviewSource): string {
45 return JSON.stringify(
46 "uri" in source
47 ? ["media-video", source.uri]
48 : source.resource._tag === "attachment"
49 ? ["media-video", source.environmentId, "attachment", source.resource.attachmentId]
50 : source.resource._tag === "media-file"
51 ? [
52 "media-video",
53 "media-file",
54 source.environmentId,
55 source.resource.threadId,
56 source.resource.path,
57 source.srcFragment ?? "",
58 ]
59 : source.resource._tag === SOURCE_CONTROL_MEDIA_ASSET
60 ? [
61 "media-video",
62 SOURCE_CONTROL_MEDIA_ASSET,
63 source.environmentId,
64 source.resource.cwd,
65 source.resource.url,
66 source.resource.repository ?? "",
67 ]
68 : [
69 "media-video",
70 "draft-workspace-file",
71 source.environmentId,
72 source.resource.cwd,
73 source.resource.path,
74 source.srcFragment ?? "",
75 ],
76 );
77}
78
79export interface LocalVideoPreviewSource {
80 readonly type: "local";
81 readonly attachment: DraftComposerFileAttachment;
82 readonly sourceIdentifier?: string;
83}
84
85export type VideoPreviewSource = LocalVideoPreviewSource | MediaVideoPreviewSource;
86
87export function attachmentVideoPreviewSource(
88 environmentId: EnvironmentId,
89 attachment: ChatFileAttachment,
90 sourceIdentifier?: string,
91): MediaVideoPreviewSource {
92 const mimeType = videoMimeType(attachment) ?? attachment.mimeType;
93 const resource = {
94 _tag: "attachment" as const,
95 attachmentId: attachment.id,
96 fileName: attachment.name,
97 mimeType,
98 };
99 return {
100 type: "media",
101 name: attachment.name,
102 mimeType,
103 ...(sourceIdentifier ? { sourceIdentifier } : {}),
104 environmentId,
105 resource,
106 actionsSource: {
107 name: attachment.name,
108 mimeType,
109 ...(sourceIdentifier ? { sourceIdentifier } : {}),
110 environmentId,
111 resource,
112 },
113 };
114}