Sign-in was clearing the staged file before it uploaded, and review only read the server URL, so a chosen logo disappeared after the upload step.
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { readPendingCommunityAvatarFile } from "../../../../lib/create/pendingCommunityAvatarUpload";
|
|
|
|
function trimmedAvatarUrl(url: string | null): string | null {
|
|
if (typeof url !== "string") return null;
|
|
const trimmed = url.trim();
|
|
return trimmed.length > 0 ? trimmed : null;
|
|
}
|
|
|
|
/**
|
|
* Logo src for review cards. Uses the uploaded URL when the draft has one,
|
|
* otherwise the guest file staged in IndexedDB.
|
|
*
|
|
* @param serverUrl `communityAvatarUrl` from create-flow state, if any.
|
|
* @returns A URL the Rule card can render, or `null` when there is no logo.
|
|
*
|
|
* @example
|
|
* const logoUrl = useCommunityAvatarDisplayUrl(state.communityAvatarUrl ?? null);
|
|
*/
|
|
export function useCommunityAvatarDisplayUrl(
|
|
serverUrl: string | null | undefined,
|
|
): string | null {
|
|
const resolvedServerUrl = trimmedAvatarUrl(serverUrl ?? null);
|
|
const [objectUrl, setObjectUrl] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (resolvedServerUrl) {
|
|
setObjectUrl((prev) => {
|
|
if (prev) URL.revokeObjectURL(prev);
|
|
return null;
|
|
});
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
let created: string | null = null;
|
|
void (async () => {
|
|
try {
|
|
const file = await readPendingCommunityAvatarFile();
|
|
if (cancelled || !file) return;
|
|
created = URL.createObjectURL(file);
|
|
if (cancelled) {
|
|
URL.revokeObjectURL(created);
|
|
created = null;
|
|
return;
|
|
}
|
|
setObjectUrl((prev) => {
|
|
if (prev && prev !== created) URL.revokeObjectURL(prev);
|
|
return created;
|
|
});
|
|
} catch {
|
|
// IndexedDB missing or blocked: the card keeps the placeholder.
|
|
}
|
|
})();
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
if (created) URL.revokeObjectURL(created);
|
|
};
|
|
}, [resolvedServerUrl]);
|
|
|
|
return resolvedServerUrl ?? objectUrl;
|
|
}
|