feat(templates): state management and our standard template
This commit is contained in:
parent
d7136c6e2f
commit
59aabb6950
2 changed files with 100 additions and 0 deletions
12
src/lib/presets.ts
Normal file
12
src/lib/presets.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { parseTemplate } from './data/parse';
|
||||||
|
|
||||||
|
const templateModules = import.meta.glob('../../data/templates/*.xml', {
|
||||||
|
query: '?raw',
|
||||||
|
import: 'default',
|
||||||
|
eager: true
|
||||||
|
});
|
||||||
|
|
||||||
|
export const presets = Object.entries(templateModules).map(([path, xml]) => {
|
||||||
|
const filename = path.split('/').pop()!.replace('.xml', '');
|
||||||
|
return parseTemplate(xml as string, `preset:${filename}`);
|
||||||
|
});
|
||||||
88
src/lib/state.svelte.ts
Normal file
88
src/lib/state.svelte.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { getAllCharacters, saveCharacter, deleteCharacter } from './storage';
|
||||||
|
import { isBlankCharacter } from './utils/blank';
|
||||||
|
import type { Character, Template } from './types';
|
||||||
|
|
||||||
|
let characters = $state<Character[]>([]);
|
||||||
|
let activeId = $state<string | null>(null);
|
||||||
|
let saveStatus = $state<'idle' | 'saving' | 'saved'>('idle');
|
||||||
|
let saveTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
let statusTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
export const roster = {
|
||||||
|
get characters() { return characters; },
|
||||||
|
get active() { return characters.find((c) => c.id === activeId) ?? null; },
|
||||||
|
get saveStatus() { return saveStatus; },
|
||||||
|
|
||||||
|
async load() {
|
||||||
|
const all = await getAllCharacters();
|
||||||
|
const kept: Character[] = [];
|
||||||
|
for (const char of all) {
|
||||||
|
if (isBlankCharacter(char)) {
|
||||||
|
await deleteCharacter(char.id);
|
||||||
|
} else {
|
||||||
|
kept.push(char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
characters = kept;
|
||||||
|
|
||||||
|
const stored = localStorage.getItem('activeCharacterId');
|
||||||
|
if (stored && characters.some((c) => c.id === stored)) {
|
||||||
|
activeId = stored;
|
||||||
|
} else if (characters.length) {
|
||||||
|
activeId = characters[0].id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async create(template: Template) {
|
||||||
|
const char: Character = {
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
template: $state.snapshot(template),
|
||||||
|
data: {}
|
||||||
|
};
|
||||||
|
characters.push(char);
|
||||||
|
activeId = char.id;
|
||||||
|
localStorage.setItem('activeCharacterId', char.id);
|
||||||
|
await saveCharacter($state.snapshot(char));
|
||||||
|
return char;
|
||||||
|
},
|
||||||
|
|
||||||
|
async remove(id: string) {
|
||||||
|
characters = characters.filter((c) => c.id !== id);
|
||||||
|
await deleteCharacter(id);
|
||||||
|
if (activeId === id) {
|
||||||
|
activeId = characters[0]?.id ?? null;
|
||||||
|
if (activeId) localStorage.setItem('activeCharacterId', activeId);
|
||||||
|
else localStorage.removeItem('activeCharacterId');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async duplicate(id: string) {
|
||||||
|
const source = characters.find((c) => c.id === id);
|
||||||
|
if (!source) return;
|
||||||
|
const copy: Character = {
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
template: $state.snapshot(source.template),
|
||||||
|
data: $state.snapshot(source.data)
|
||||||
|
};
|
||||||
|
characters.push(copy);
|
||||||
|
activeId = copy.id;
|
||||||
|
localStorage.setItem('activeCharacterId', copy.id);
|
||||||
|
await saveCharacter($state.snapshot(copy));
|
||||||
|
},
|
||||||
|
|
||||||
|
setActive(id: string) {
|
||||||
|
activeId = id;
|
||||||
|
localStorage.setItem('activeCharacterId', id);
|
||||||
|
},
|
||||||
|
|
||||||
|
scheduleSave(char: Character) {
|
||||||
|
if (saveTimer) clearTimeout(saveTimer);
|
||||||
|
saveTimer = setTimeout(async () => {
|
||||||
|
saveStatus = 'saving';
|
||||||
|
await saveCharacter($state.snapshot(char));
|
||||||
|
saveStatus = 'saved';
|
||||||
|
if (statusTimer) clearTimeout(statusTimer);
|
||||||
|
statusTimer = setTimeout(() => { saveStatus = 'idle'; }, 1500);
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue