| |
| |
| |
| |
| |
| |
|
|
| import type { SlideContent } from '@/lib/types/stage'; |
| import type { PPTElement } from '@/lib/types/slides'; |
| import type { StageStore, APIResult, CreateElementParams } from './stage-api-types'; |
| import { generateId, getScene } from './stage-api-defaults'; |
|
|
| |
| |
| |
| |
| |
| |
| export function createElementAPI(store: StageStore) { |
| return { |
| |
| |
| |
| |
| |
| |
| |
| add(sceneId: string, element: CreateElementParams): APIResult<string> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
| const elementId = generateId(element.type); |
|
|
| const newElement: PPTElement = { |
| ...element, |
| id: elementId, |
| rotate: element.rotate ?? 0, |
| } as PPTElement; |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: [...content.canvas.elements, newElement], |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: elementId }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| addBatch(sceneId: string, elements: CreateElementParams[]): APIResult<string[]> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
| const elementIds: string[] = []; |
|
|
| const newElements: PPTElement[] = elements.map((el) => { |
| const elementId = generateId(el.type); |
| elementIds.push(elementId); |
|
|
| return { |
| ...el, |
| id: elementId, |
| rotate: el.rotate ?? 0, |
| } as PPTElement; |
| }); |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: [...content.canvas.elements, ...newElements], |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: elementIds }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| delete(sceneId: string, elementId: string): APIResult<boolean> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: content.canvas.elements.filter((el) => el.id !== elementId), |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: true }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| deleteBatch(sceneId: string, elementIds: string[]): APIResult<boolean> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
| const elementIdSet = new Set(elementIds); |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: content.canvas.elements.filter((el) => !elementIdSet.has(el.id)), |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: true }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| update(sceneId: string, elementId: string, updates: Partial<PPTElement>): APIResult<boolean> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: content.canvas.elements.map((el) => |
| el.id === elementId ? { ...el, ...updates } : el, |
| ), |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: true }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| get(sceneId: string, elementId: string): APIResult<PPTElement> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
| const element = content.canvas.elements.find((el) => el.id === elementId); |
|
|
| if (!element) { |
| return { success: false, error: `Element not found: ${elementId}` }; |
| } |
|
|
| return { success: true, data: element }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| list(sceneId: string): APIResult<PPTElement[]> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
| return { success: true, data: [...content.canvas.elements] }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| move(sceneId: string, elementId: string, deltaX: number, deltaY: number): APIResult<boolean> { |
| try { |
| const state = store.getState(); |
| const scene = getScene(state.scenes, sceneId); |
|
|
| if (!scene) { |
| return { success: false, error: `Scene not found: ${sceneId}` }; |
| } |
|
|
| if (scene.type !== 'slide') { |
| return { success: false, error: `Scene is not a slide: ${sceneId}` }; |
| } |
|
|
| const content = scene.content as SlideContent; |
|
|
| const newScenes = state.scenes.map((s) => { |
| if (s.id === sceneId) { |
| return { |
| ...s, |
| content: { |
| ...content, |
| canvas: { |
| ...content.canvas, |
| elements: content.canvas.elements.map((el) => { |
| if (el.id === elementId) { |
| return { |
| ...el, |
| left: el.left + deltaX, |
| top: el.top + deltaY, |
| }; |
| } |
| return el; |
| }), |
| }, |
| }, |
| updatedAt: Date.now(), |
| }; |
| } |
| return s; |
| }); |
|
|
| store.setState({ scenes: newScenes }); |
|
|
| return { success: true, data: true }; |
| } catch (error) { |
| return { success: false, error: String(error) }; |
| } |
| }, |
| }; |
| } |
|
|