1import type { ScopedProjectRef, ScopedThreadRef } from "@t3tools/contracts";
2import { scopedThreadKey } from "@t3tools/client-runtime/environment";
3
4import { type DraftId, useComposerDraftStore } from "../composerDraftStore";
5import { releaseDraftAttachments } from "./attachmentUploadQueue";
6
7export function releaseComposerDraftUploads(target: ScopedThreadRef | DraftId): void {
8 const draft = useComposerDraftStore.getState().getComposerDraft(target);
9 if (draft) {
10 releaseDraftAttachments([...draft.images, ...draft.files]);
11 }
12}
13
14/**
15 * Releases every upload a deleted project's drafts still hold. Draft-thread
16 * sessions carry their project ref, but drafts on the project's real threads
17 * live in `draftsByThreadKey` under scoped thread keys with no project in the
18 * key, so the caller passes the project's thread refs alongside.
19 */
20export function releaseProjectDraftUploads(
21 projectRef: ScopedProjectRef,
22 projectThreadRefs: ReadonlyArray<ScopedThreadRef> = [],
23): void {
24 const store = useComposerDraftStore.getState();
25 for (const [draftKey, session] of Object.entries(store.draftThreadsByThreadKey)) {
26 if (
27 session.environmentId === projectRef.environmentId &&
28 session.projectId === projectRef.projectId
29 ) {
30 const draft = store.draftsByThreadKey[draftKey];
31 releaseDraftAttachments(draft ? [...draft.images, ...draft.files] : []);
32 }
33 }
34 for (const threadRef of projectThreadRefs) {
35 const draft = store.draftsByThreadKey[scopedThreadKey(threadRef)];
36 if (draft) {
37 releaseDraftAttachments([...draft.images, ...draft.files]);
38 }
39 }
40}