image processing during saving
This commit is contained in:
@@ -23,6 +23,7 @@ export default function EditStoryPage() {
|
||||
const [story, setStory] = useState<Story | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [processingImages, setProcessingImages] = useState(false);
|
||||
const [resetingPosition, setResetingPosition] = useState(false);
|
||||
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||
|
||||
@@ -41,6 +42,25 @@ export default function EditStoryPage() {
|
||||
|
||||
const [coverImage, setCoverImage] = useState<File | null>(null);
|
||||
|
||||
// Helper function to detect external images in HTML content
|
||||
const hasExternalImages = (htmlContent: string): boolean => {
|
||||
if (!htmlContent) return false;
|
||||
|
||||
// Create a temporary DOM element to parse HTML
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = htmlContent;
|
||||
|
||||
const images = tempDiv.querySelectorAll('img');
|
||||
for (let i = 0; i < images.length; i++) {
|
||||
const img = images[i];
|
||||
const src = img.getAttribute('src');
|
||||
if (src && (src.startsWith('http://') || src.startsWith('https://'))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const loadStory = async () => {
|
||||
try {
|
||||
@@ -163,7 +183,7 @@ export default function EditStoryPage() {
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
if (!validateForm() || !story) {
|
||||
return;
|
||||
}
|
||||
@@ -185,7 +205,34 @@ export default function EditStoryPage() {
|
||||
tagNames: formData.tags,
|
||||
};
|
||||
|
||||
const updatedStory = await storyApi.updateStory(storyId, updateData);
|
||||
await storyApi.updateStory(storyId, updateData);
|
||||
|
||||
// Process external images if present (download and replace URLs)
|
||||
if (hasExternalImages(formData.contentHtml)) {
|
||||
try {
|
||||
setProcessingImages(true);
|
||||
const imageResult = await storyApi.processContentImages(storyId, formData.contentHtml);
|
||||
|
||||
// If images were processed and content was updated, save the updated content
|
||||
if (imageResult.processedContent !== formData.contentHtml) {
|
||||
await storyApi.updateStory(storyId, {
|
||||
title: formData.title,
|
||||
summary: formData.summary || undefined,
|
||||
contentHtml: imageResult.processedContent,
|
||||
sourceUrl: formData.sourceUrl || undefined,
|
||||
volume: formData.seriesName && formData.volume ? parseInt(formData.volume) : undefined,
|
||||
...(formData.seriesId ? { seriesId: formData.seriesId } : { seriesName: formData.seriesName }),
|
||||
...(formData.authorId ? { authorId: formData.authorId } : { authorName: formData.authorName }),
|
||||
tagNames: formData.tags,
|
||||
});
|
||||
}
|
||||
} catch (imageError) {
|
||||
console.warn('Failed to process images, continuing with original content:', imageError);
|
||||
// Don't fail the entire save if image processing fails
|
||||
} finally {
|
||||
setProcessingImages(false);
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a new cover image, upload it separately
|
||||
if (coverImage) {
|
||||
@@ -199,6 +246,7 @@ export default function EditStoryPage() {
|
||||
setErrors({ submit: errorMessage });
|
||||
} finally {
|
||||
setSaving(false);
|
||||
setProcessingImages(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -448,28 +496,28 @@ export default function EditStoryPage() {
|
||||
type="button"
|
||||
variant="ghost"
|
||||
onClick={handleDelete}
|
||||
disabled={saving}
|
||||
disabled={saving || processingImages}
|
||||
className="text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
|
||||
>
|
||||
Delete Story
|
||||
</Button>
|
||||
|
||||
|
||||
<div className="flex gap-4">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
onClick={() => router.push(`/stories/${storyId}`)}
|
||||
disabled={saving}
|
||||
disabled={saving || processingImages}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
loading={saving}
|
||||
loading={saving || processingImages}
|
||||
disabled={!formData.title || !formData.authorName || !formData.contentHtml}
|
||||
>
|
||||
Save Changes
|
||||
{processingImages ? 'Processing images...' : 'Save Changes'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user