a6cbcc273e
Made-with: Cursor
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
import { ipcChannels } from '../../shared/ipc/contracts';
|
|
import type { AssetId } from '../../shared/types';
|
|
|
|
import { getDndApi } from './dndApi';
|
|
|
|
/**
|
|
* Возвращает `file://` URL для превью изображения. Пока загрузка или сменился id — `null`.
|
|
*/
|
|
export function useAssetUrl(assetId: AssetId | null | undefined): string | null {
|
|
const id = assetId ?? null;
|
|
const [entry, setEntry] = useState<{ assetId: AssetId; url: string | null } | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (id === null) {
|
|
return undefined;
|
|
}
|
|
let cancelled = false;
|
|
void getDndApi()
|
|
.invoke(ipcChannels.project.assetFileUrl, { assetId: id })
|
|
.then((r) => {
|
|
if (!cancelled) setEntry({ assetId: id, url: r.url });
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [id]);
|
|
|
|
if (id === null) {
|
|
return null;
|
|
}
|
|
if (entry?.assetId !== id) {
|
|
return null;
|
|
}
|
|
return entry.url;
|
|
}
|
|
|
|
/** @deprecated use `useAssetUrl` */
|
|
export function useAssetImageUrl(assetId: AssetId | null | undefined): string | null {
|
|
return useAssetUrl(assetId);
|
|
}
|