57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
|
|
import {
|
|
parseImageGeneratorDraft,
|
|
serializeImageGeneratorDraft,
|
|
} from "@/lib/image-generator-draft";
|
|
|
|
export function useImageGeneratorDraft<Value>(
|
|
key: string,
|
|
initialValue: Value,
|
|
parse: (value: unknown) => Value | null,
|
|
) {
|
|
const [value, setValue] = useState(initialValue);
|
|
const [hydrated, setHydrated] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const timer = window.setTimeout(() => {
|
|
try {
|
|
const serialized = window.localStorage.getItem(key);
|
|
if (serialized) {
|
|
const parsed = parseImageGeneratorDraft(serialized, parse);
|
|
if (parsed) setValue(parsed);
|
|
}
|
|
} catch {
|
|
// A corrupt or unavailable browser draft should not block the generator.
|
|
}
|
|
setHydrated(true);
|
|
}, 0);
|
|
return () => window.clearTimeout(timer);
|
|
}, [key, parse]);
|
|
|
|
useEffect(() => {
|
|
if (!hydrated) return;
|
|
try {
|
|
window.localStorage.setItem(
|
|
key,
|
|
serializeImageGeneratorDraft(value),
|
|
);
|
|
} catch {
|
|
// Browser storage is optional; the current generator remains usable.
|
|
}
|
|
}, [hydrated, key, value]);
|
|
|
|
const reset = useCallback(() => {
|
|
try {
|
|
window.localStorage.removeItem(key);
|
|
} catch {
|
|
// Browser storage is optional.
|
|
}
|
|
setValue(initialValue);
|
|
}, [initialValue, key]);
|
|
|
|
return [value, setValue, reset] as const;
|
|
}
|