194 lines
5.6 KiB
TypeScript
194 lines
5.6 KiB
TypeScript
import { ImageFile } from '../types';
|
|
import { supabase } from '@/integrations/supabase/client';
|
|
import { toast } from 'sonner';
|
|
import { translate } from '@/i18n';
|
|
import { Logger } from '../utils/logger';
|
|
|
|
/**
|
|
* Data Loading & Saving Handlers
|
|
* - Load/save presets
|
|
* - Load/save workflows
|
|
* - Load/save templates
|
|
* - Load/save quick actions
|
|
* - Load/save history
|
|
* - Load family versions
|
|
* - Load available images
|
|
*/
|
|
|
|
export const loadFamilyVersions = async (
|
|
parentImages: ImageFile[],
|
|
setImages: React.Dispatch<React.SetStateAction<ImageFile[]>>,
|
|
logger: Logger
|
|
) => {
|
|
|
|
try {
|
|
// Get all parent IDs and image IDs to find complete families
|
|
const imageIds = parentImages.map(img => img.realDatabaseId || img.id).filter(id => id && id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i));
|
|
|
|
if (imageIds.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// For each image, find its complete family tree
|
|
const allFamilyImages = new Set<string>();
|
|
|
|
for (const imageId of imageIds) {
|
|
// First, get the current image details to check if it has a parent
|
|
const { data: currentImage, error: currentError } = await supabase
|
|
.from('pictures')
|
|
.select('id, parent_id')
|
|
.eq('id', imageId)
|
|
.single();
|
|
|
|
if (currentError) {
|
|
console.error('🔧 [Wizard] Error loading current image:', currentError);
|
|
continue;
|
|
}
|
|
|
|
|
|
|
|
// Determine the root of the family tree
|
|
let rootId = currentImage.parent_id || imageId;
|
|
|
|
// Load all versions in this family (root + all children)
|
|
const { data: familyVersions, error: familyError } = await supabase
|
|
.from('pictures')
|
|
.select(`
|
|
id,
|
|
title,
|
|
image_url,
|
|
user_id,
|
|
parent_id,
|
|
description,
|
|
is_selected,
|
|
created_at
|
|
`)
|
|
.or(`id.eq.${rootId},parent_id.eq.${rootId}`)
|
|
.order('created_at', { ascending: true });
|
|
|
|
if (familyError) {
|
|
console.error('🔧 [Wizard] Error loading family versions:', familyError);
|
|
continue;
|
|
}
|
|
|
|
|
|
|
|
// Add all family members to our set (excluding the initial image)
|
|
familyVersions?.forEach(version => {
|
|
if (version.id !== imageId) {
|
|
allFamilyImages.add(version.id);
|
|
}
|
|
});
|
|
}
|
|
// Now fetch all the unique family images
|
|
if (allFamilyImages.size > 0) {
|
|
const { data: versions, error } = await supabase
|
|
.from('pictures')
|
|
.select(`
|
|
id,
|
|
title,
|
|
image_url,
|
|
user_id,
|
|
parent_id,
|
|
description,
|
|
is_selected,
|
|
created_at
|
|
`)
|
|
.in('id', Array.from(allFamilyImages))
|
|
.order('created_at', { ascending: true });
|
|
|
|
if (error) throw error;
|
|
|
|
const versionImages: ImageFile[] = versions?.map(version => ({
|
|
id: version.id,
|
|
src: version.image_url,
|
|
title: version.title,
|
|
userId: version.user_id,
|
|
selected: false, // Default to not selected in UI
|
|
isPreferred: version.is_selected || false,
|
|
isGenerated: true,
|
|
aiText: version.description || undefined
|
|
})) || [];
|
|
|
|
|
|
|
|
// Add versions to images, but also update existing images with correct selection status
|
|
setImages(prev => {
|
|
// Create a map of database selection status
|
|
const dbSelectionStatus = new Map();
|
|
|
|
// Check if this is a singleton family (only one version)
|
|
const isSingleton = versions?.length === 1;
|
|
|
|
versions?.forEach(version => {
|
|
// If explicitly selected in DB, OR if it's the only version in the family
|
|
const isPreferred = version.is_selected || (isSingleton && !version.parent_id);
|
|
dbSelectionStatus.set(version.id, isPreferred);
|
|
});
|
|
|
|
// Update existing images and add new ones
|
|
const existingIds = new Set(prev.map(img => img.id));
|
|
const updatedExisting = prev.map(img => {
|
|
if (dbSelectionStatus.has(img.id)) {
|
|
const dbSelected = dbSelectionStatus.get(img.id);
|
|
return { ...img, isPreferred: dbSelected };
|
|
}
|
|
return img;
|
|
});
|
|
|
|
// Add new images
|
|
const newImages = versionImages.filter(img => !existingIds.has(img.id)).map(img => {
|
|
if (dbSelectionStatus.has(img.id)) {
|
|
return { ...img, isPreferred: dbSelectionStatus.get(img.id) };
|
|
}
|
|
return img;
|
|
});
|
|
|
|
const finalImages = [...updatedExisting, ...newImages];
|
|
return finalImages;
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('🔧 [Wizard] Error loading family versions:', error);
|
|
toast.error(translate('Failed to load image versions'));
|
|
}
|
|
};
|
|
|
|
export const loadAvailableImages = async (
|
|
setAvailableImages: React.Dispatch<React.SetStateAction<ImageFile[]>>,
|
|
setLoadingImages: React.Dispatch<React.SetStateAction<boolean>>
|
|
) => {
|
|
setLoadingImages(true);
|
|
try {
|
|
// Load images from all users (public images)
|
|
const { data: pictures, error } = await supabase
|
|
.from('pictures')
|
|
.select(`
|
|
id,
|
|
title,
|
|
image_url,
|
|
user_id
|
|
`)
|
|
.order('created_at', { ascending: false })
|
|
.limit(50);
|
|
|
|
if (error) throw error;
|
|
|
|
const imageFiles: ImageFile[] = pictures?.map(picture => ({
|
|
id: picture.id,
|
|
src: picture.image_url,
|
|
title: picture.title,
|
|
userId: picture.user_id,
|
|
selected: false
|
|
})) || [];
|
|
|
|
setAvailableImages(imageFiles);
|
|
} catch (error) {
|
|
console.error('Error loading images:', error);
|
|
toast.error(translate('Failed to load images'));
|
|
} finally {
|
|
setLoadingImages(false);
|
|
}
|
|
};
|
|
|