feat: persist generation sources in post editor state and API
This commit is contained in:
parent
4d1f8298de
commit
4fd46f4d24
@ -31,6 +31,7 @@ export default function EditorShell({ onLogout: _onLogout, initialPostId, onBack
|
|||||||
genImageKeys,
|
genImageKeys,
|
||||||
generatedDraft,
|
generatedDraft,
|
||||||
imagePlaceholders,
|
imagePlaceholders,
|
||||||
|
generationSources,
|
||||||
// setters
|
// setters
|
||||||
setDraft,
|
setDraft,
|
||||||
setMeta,
|
setMeta,
|
||||||
@ -40,6 +41,7 @@ export default function EditorShell({ onLogout: _onLogout, initialPostId, onBack
|
|||||||
setActiveStep,
|
setActiveStep,
|
||||||
setGeneratedDraft,
|
setGeneratedDraft,
|
||||||
setImagePlaceholders,
|
setImagePlaceholders,
|
||||||
|
setGenerationSources,
|
||||||
// actions
|
// actions
|
||||||
savePost,
|
savePost,
|
||||||
deletePost,
|
deletePost,
|
||||||
@ -151,6 +153,7 @@ export default function EditorShell({ onLogout: _onLogout, initialPostId, onBack
|
|||||||
onChangePrompt={setPromptText}
|
onChangePrompt={setPromptText}
|
||||||
generatedDraft={generatedDraft}
|
generatedDraft={generatedDraft}
|
||||||
imagePlaceholders={imagePlaceholders}
|
imagePlaceholders={imagePlaceholders}
|
||||||
|
generationSources={generationSources}
|
||||||
onGeneratedDraft={(content) => {
|
onGeneratedDraft={(content) => {
|
||||||
setGeneratedDraft(content);
|
setGeneratedDraft(content);
|
||||||
void savePost({ generatedDraft: content });
|
void savePost({ generatedDraft: content });
|
||||||
@ -159,6 +162,10 @@ export default function EditorShell({ onLogout: _onLogout, initialPostId, onBack
|
|||||||
setImagePlaceholders(placeholders);
|
setImagePlaceholders(placeholders);
|
||||||
void savePost({ imagePlaceholders: placeholders });
|
void savePost({ imagePlaceholders: placeholders });
|
||||||
}}
|
}}
|
||||||
|
onGenerationSources={(sources) => {
|
||||||
|
setGenerationSources(sources);
|
||||||
|
void savePost({ generationSources: sources });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</StepContainer>
|
</StepContainer>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -14,8 +14,10 @@ export default function StepGenerate({
|
|||||||
onChangePrompt,
|
onChangePrompt,
|
||||||
generatedDraft,
|
generatedDraft,
|
||||||
imagePlaceholders,
|
imagePlaceholders,
|
||||||
|
generationSources,
|
||||||
onGeneratedDraft,
|
onGeneratedDraft,
|
||||||
onImagePlaceholders,
|
onImagePlaceholders,
|
||||||
|
onGenerationSources,
|
||||||
}: {
|
}: {
|
||||||
postClips: Clip[];
|
postClips: Clip[];
|
||||||
genImageKeys: string[];
|
genImageKeys: string[];
|
||||||
@ -24,13 +26,14 @@ export default function StepGenerate({
|
|||||||
onChangePrompt: (v: string) => void;
|
onChangePrompt: (v: string) => void;
|
||||||
generatedDraft: string;
|
generatedDraft: string;
|
||||||
imagePlaceholders: string[];
|
imagePlaceholders: string[];
|
||||||
|
generationSources: Array<{ title: string; url: string }>;
|
||||||
onGeneratedDraft: (content: string) => void;
|
onGeneratedDraft: (content: string) => void;
|
||||||
onImagePlaceholders: (placeholders: string[]) => void;
|
onImagePlaceholders: (placeholders: string[]) => void;
|
||||||
|
onGenerationSources: (sources: Array<{ title: string; url: string }>) => void;
|
||||||
}) {
|
}) {
|
||||||
const [generating, setGenerating] = useState(false);
|
const [generating, setGenerating] = useState(false);
|
||||||
const [error, setError] = useState<string>('');
|
const [error, setError] = useState<string>('');
|
||||||
const [useWebSearch, setUseWebSearch] = useState(false);
|
const [useWebSearch, setUseWebSearch] = useState(false);
|
||||||
const [sources, setSources] = useState<Array<{ title: string; url: string }>>([]);
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: 'grid', gap: 2 }}>
|
<Box sx={{ display: 'grid', gap: 2 }}>
|
||||||
<StepHeader
|
<StepHeader
|
||||||
@ -121,7 +124,7 @@ export default function StepGenerate({
|
|||||||
|
|
||||||
onGeneratedDraft(result.content);
|
onGeneratedDraft(result.content);
|
||||||
onImagePlaceholders(result.imagePlaceholders);
|
onImagePlaceholders(result.imagePlaceholders);
|
||||||
setSources(result.sources || []);
|
onGenerationSources(result.sources || []);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setError(err?.message || 'Generation failed');
|
setError(err?.message || 'Generation failed');
|
||||||
} finally {
|
} finally {
|
||||||
@ -149,11 +152,11 @@ export default function StepGenerate({
|
|||||||
{generatedDraft && (
|
{generatedDraft && (
|
||||||
<CollapsibleSection title="Generated Draft">
|
<CollapsibleSection title="Generated Draft">
|
||||||
<Stack spacing={2}>
|
<Stack spacing={2}>
|
||||||
{sources.length > 0 && (
|
{generationSources.length > 0 && (
|
||||||
<Alert severity="success">
|
<Alert severity="success">
|
||||||
<Typography variant="body2" sx={{ fontWeight: 'bold', mb: 0.5 }}>Sources ({sources.length}):</Typography>
|
<Typography variant="body2" sx={{ fontWeight: 'bold', mb: 0.5 }}>Sources ({generationSources.length}):</Typography>
|
||||||
<Stack spacing={0.5}>
|
<Stack spacing={0.5}>
|
||||||
{sources.map((source, idx) => (
|
{generationSources.map((source: { title: string; url: string }, idx: number) => (
|
||||||
<Typography key={idx} variant="caption" component="div">
|
<Typography key={idx} variant="caption" component="div">
|
||||||
{idx + 1}. <Link href={source.url} target="_blank" rel="noopener noreferrer">{source.title}</Link>
|
{idx + 1}. <Link href={source.url} target="_blank" rel="noopener noreferrer">{source.title}</Link>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@ -18,6 +18,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
const [genImageKeys, setGenImageKeys] = useState<string[]>([]);
|
const [genImageKeys, setGenImageKeys] = useState<string[]>([]);
|
||||||
const [generatedDraft, setGeneratedDraft] = useState<string>('');
|
const [generatedDraft, setGeneratedDraft] = useState<string>('');
|
||||||
const [imagePlaceholders, setImagePlaceholders] = useState<string[]>([]);
|
const [imagePlaceholders, setImagePlaceholders] = useState<string[]>([]);
|
||||||
|
const [generationSources, setGenerationSources] = useState<Array<{ title: string; url: string }>>([]);
|
||||||
const autoSaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const autoSaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -45,6 +46,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
if (Array.isArray(data.selectedImageKeys)) setGenImageKeys(data.selectedImageKeys);
|
if (Array.isArray(data.selectedImageKeys)) setGenImageKeys(data.selectedImageKeys);
|
||||||
if (data.generatedDraft) setGeneratedDraft(data.generatedDraft);
|
if (data.generatedDraft) setGeneratedDraft(data.generatedDraft);
|
||||||
if (Array.isArray(data.imagePlaceholders)) setImagePlaceholders(data.imagePlaceholders);
|
if (Array.isArray(data.imagePlaceholders)) setImagePlaceholders(data.imagePlaceholders);
|
||||||
|
if (Array.isArray(data.generationSources)) setGenerationSources(data.generationSources);
|
||||||
} catch {}
|
} catch {}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@ -64,6 +66,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
selectedImageKeys: genImageKeys.length > 0 ? genImageKeys : undefined,
|
selectedImageKeys: genImageKeys.length > 0 ? genImageKeys : undefined,
|
||||||
generatedDraft: generatedDraft || undefined,
|
generatedDraft: generatedDraft || undefined,
|
||||||
imagePlaceholders: imagePlaceholders.length > 0 ? imagePlaceholders : undefined,
|
imagePlaceholders: imagePlaceholders.length > 0 ? imagePlaceholders : undefined,
|
||||||
|
generationSources: generationSources.length > 0 ? generationSources : undefined,
|
||||||
...(overrides || {}),
|
...(overrides || {}),
|
||||||
};
|
};
|
||||||
const data = await savePostApi(payload);
|
const data = await savePostApi(payload);
|
||||||
@ -75,7 +78,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
setToast({ open: true, message: 'Post saved', severity: 'success' });
|
setToast({ open: true, message: 'Post saved', severity: 'success' });
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}, [postId, draft, meta, postStatus, promptText, genImageKeys, generatedDraft, imagePlaceholders]);
|
}, [postId, draft, meta, postStatus, promptText, genImageKeys, generatedDraft, imagePlaceholders, generationSources]);
|
||||||
|
|
||||||
const deletePost = async () => {
|
const deletePost = async () => {
|
||||||
if (!postId) return;
|
if (!postId) return;
|
||||||
@ -176,6 +179,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
genImageKeys,
|
genImageKeys,
|
||||||
generatedDraft,
|
generatedDraft,
|
||||||
imagePlaceholders,
|
imagePlaceholders,
|
||||||
|
generationSources,
|
||||||
// setters
|
// setters
|
||||||
setDraft,
|
setDraft,
|
||||||
setMeta,
|
setMeta,
|
||||||
@ -186,6 +190,7 @@ export function usePostEditor(initialPostId?: string | null) {
|
|||||||
setActiveStep,
|
setActiveStep,
|
||||||
setGeneratedDraft,
|
setGeneratedDraft,
|
||||||
setImagePlaceholders,
|
setImagePlaceholders,
|
||||||
|
setGenerationSources,
|
||||||
// actions
|
// actions
|
||||||
savePost,
|
savePost,
|
||||||
deletePost,
|
deletePost,
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export type SavePostPayload = {
|
|||||||
selectedImageKeys?: string[];
|
selectedImageKeys?: string[];
|
||||||
generatedDraft?: string;
|
generatedDraft?: string;
|
||||||
imagePlaceholders?: string[];
|
imagePlaceholders?: string[];
|
||||||
|
generationSources?: Array<{ title: string; url: string }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getPost(id: string) {
|
export async function getPost(id: string) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user