diff --git a/services/studio/FlatRender.StudioSvc/Application/Services/StudioService.cs b/services/studio/FlatRender.StudioSvc/Application/Services/StudioService.cs index a9839af..608225b 100644 --- a/services/studio/FlatRender.StudioSvc/Application/Services/StudioService.cs +++ b/services/studio/FlatRender.StudioSvc/Application/Services/StudioService.cs @@ -122,22 +122,23 @@ public class StudioService(StudioDbContext db) SELECT new_id, old_id FROM ins;", savedProjectId, originalProjectId); - // 2. content elements (skip repeater children for now) + // 2. content elements — incl. repeater children flattened via repeater_item_key await db.Database.ExecuteSqlRawAsync(@" INSERT INTO studio.saved_scene_contents (saved_scene_id, key, title, localized_title, hint, type, value, font_face, font_face_name, font_size, default_font_size, default_font_face, justify, position_in_container, direction_layer_value, is_text_box, - ai_input_type, mapped_list, thumbnail, sort, status, created_at, updated_at) + ai_input_type, mapped_list, thumbnail, sort, repeater_item_key, + repeater_index, status, created_at, updated_at) SELECT sm.new_id, ce.key, ce.title, ce.localized_title, ce.hint, ce.type::text, ce.default_value, ce.font_face, ce.font_face_name, ce.font_size, ce.default_font_size, ce.default_font_face, ce.justify::text, ce.position_in_container, ce.direction_layer_value, ce.is_text_box, - ce.ai_input_type::text, ce.mapped_list, ce.thumbnail, ce.sort, 'default', - now(), now() + ce.ai_input_type::text, ce.mapped_list, ce.thumbnail, ce.sort, + ri.repeat_item_key, ri.sort, 'default', now(), now() FROM content.scene_content_elements ce JOIN _scene_map sm ON sm.old_id = ce.scene_id - WHERE ce.repeater_item_id IS NULL;"); + LEFT JOIN content.repeater_items ri ON ri.id = ce.repeater_item_id;"); // 3. colour elements await db.Database.ExecuteSqlRawAsync(@" @@ -148,6 +149,41 @@ public class StudioService(StudioDbContext db) FROM content.scene_color_elements ce JOIN _scene_map sm ON sm.old_id = ce.scene_id;"); + // 3b. characters — studio's `key` is a uuid; store the original character id + await db.Database.ExecuteSqlRawAsync(@" + INSERT INTO studio.saved_scene_characters (saved_scene_id, key, name, icon) + SELECT sm.new_id, ch.id, ch.name, ch.icon + FROM content.scene_characters ch + JOIN _scene_map sm ON sm.old_id = ch.scene_id;"); + + // 3c. character controllers (correlate the new character by scene + original id) + await db.Database.ExecuteSqlRawAsync(@" + INSERT INTO studio.saved_scene_character_controllers + (saved_scene_character_id, name, key, value, sort) + SELECT sc.id, cc.name, cc.key, cc.default_value, cc.sort + FROM content.scene_character_controllers cc + JOIN content.scene_characters cch ON cch.id = cc.scene_character_id + JOIN _scene_map sm ON sm.old_id = cch.scene_id + JOIN studio.saved_scene_characters sc + ON sc.saved_scene_id = sm.new_id AND sc.key = cch.id;"); + + // 3d. colour presets + await db.Database.ExecuteSqlRawAsync(@" + INSERT INTO studio.saved_scene_color_presets (saved_scene_id, is_selected, sort) + SELECT sm.new_id, false, cp.sort + FROM content.scene_color_presets cp + JOIN _scene_map sm ON sm.old_id = cp.scene_id;"); + + // 3e. colour preset items (correlate the new preset by scene + sort) + await db.Database.ExecuteSqlRawAsync(@" + INSERT INTO studio.saved_scene_color_preset_items (preset_id, element_key, value, sort) + SELECT sp.id, ci.element_key, ci.value, ci.sort + FROM content.scene_color_preset_items ci + JOIN content.scene_color_presets cp ON cp.id = ci.preset_id + JOIN _scene_map sm ON sm.old_id = cp.scene_id + JOIN studio.saved_scene_color_presets sp + ON sp.saved_scene_id = sm.new_id AND sp.sort = cp.sort;"); + // 4. shared (project-level) colours — frshare frd_* controls await db.Database.ExecuteSqlRawAsync(@" INSERT INTO studio.saved_shared_colors