Files
spritesheet-generator/src/composables/useProjectManager.ts
2026-01-02 01:46:23 +01:00

127 lines
3.6 KiB
TypeScript

import { useRouter } from 'vue-router';
import { toRef } from 'vue';
import { useLayers, createEmptyLayer } from '@/composables/useLayers';
import { useSettingsStore } from '@/stores/useSettingsStore';
import { useProjectStore, type Project } from '@/stores/useProjectStore';
import { useExportLayers } from '@/composables/useExportLayers';
export const useProjectManager = () => {
const router = useRouter();
const settingsStore = useSettingsStore();
const projectStore = useProjectStore();
const { layers, columns, activeLayerId } = useLayers();
const { generateProjectJSON, loadProjectData } = useExportLayers(
layers,
columns,
toRef(settingsStore, 'negativeSpacingEnabled'),
activeLayerId,
toRef(settingsStore, 'backgroundColor'),
toRef(settingsStore, 'manualCellSizeEnabled'),
toRef(settingsStore, 'manualCellWidth'),
toRef(settingsStore, 'manualCellHeight')
);
const createProject = (config: { width: number; height: number; columns: number; rows: number }) => {
// 1. Reset Settings
settingsStore.setManualCellSize(config.width, config.height);
settingsStore.manualCellSizeEnabled = true;
// 2. Reset Layers
const newLayer = createEmptyLayer('Base');
layers.value = [newLayer];
activeLayerId.value = newLayer.id;
// 3. Set Columns
columns.value = config.columns;
// 4. Reset Project Store
projectStore.currentProject = null;
// 5. Navigate to Editor
router.push('/editor');
};
const openProject = async (project: Project) => {
try {
if (project.data) {
await loadProjectData(project.data);
}
projectStore.currentProject = project;
router.push({ name: 'editor', params: { id: project.id } });
} catch (e) {
console.error('Failed to open project', e);
alert('Failed to open project data');
}
};
const saveProject = async (name: string) => {
try {
const data = await generateProjectJSON();
if (projectStore.currentProject) {
// Update existing project (even if name changed)
await projectStore.updateProject(projectStore.currentProject.id, name, data);
} else {
// Create new project if none exists
await projectStore.createProject(name, data);
// After creating, we should update route to include ID so subsequent saves update it
const newProject = projectStore.currentProject as Project | null;
if (newProject) {
router.replace({ name: 'editor', params: { id: newProject.id } });
}
}
} catch (e) {
console.error(e);
alert('Failed to save project');
throw e;
}
};
const saveAsProject = async (name: string) => {
try {
const data = await generateProjectJSON();
// Always create new
await projectStore.createProject(name, data);
// Navigate to new project
if (projectStore.currentProject) {
router.push({ name: 'editor', params: { id: projectStore.currentProject.id } });
}
} catch (e) {
console.error(e);
alert('Failed to save project as new');
throw e;
}
};
const closeProject = () => {
// Reset Layers
const newLayer = createEmptyLayer('Base');
layers.value = [newLayer];
activeLayerId.value = newLayer.id;
// Reset columns
columns.value = 4;
// Reset Project Store
projectStore.currentProject = null;
// Navigate Home
router.push('/');
};
const closeEditor = () => {
closeProject();
};
return {
createProject,
openProject,
saveProject,
saveAsProject,
closeEditor,
closeProject,
loadProjectData,
};
};