Files
brandly/src/electron/dao.ts
T

272 lines
8.1 KiB
TypeScript

import { getDB } from './database';
export function saveTemplateToDB(template: any) {
const db = getDB();
const tx = db.transaction(() => {
// 1. Save Project
db.prepare(`
INSERT OR REPLACE INTO projects (id, brand_id, name, is_template, format, duration)
VALUES (?, ?, ?, ?, ?, ?)
`).run(
template.id,
template.brandId || null,
template.name || template.id,
1,
template.format || 'video',
template.duration || 0
);
// 2. Save Layers
if (template.layers && Array.isArray(template.layers)) {
const insertLayer = db.prepare(`
INSERT OR REPLACE INTO timeline_layers (id, project_id, name, type, is_visible, is_locked, is_muted, opacity, volume)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const layer of template.layers) {
insertLayer.run(
layer.id,
template.id,
layer.name,
layer.type || 'visual',
layer.isVisible === false ? 0 : 1,
layer.isLocked ? 1 : 0,
layer.isMuted ? 1 : 0,
layer.opacity ?? 1,
layer.volume ?? 1
);
}
}
// 3. Save Elements
if (template.elements && Array.isArray(template.elements)) {
const insertElement = db.prepare(`
INSERT OR REPLACE INTO timeline_elements (
id, layer_id, type, content, start_frame, end_frame, x, y, w, h,
scale, rotation, opacity, color, font_family, font_size, text_align,
filter, chroma_key_enabled, chroma_key_color
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
for (const el of template.elements) {
insertElement.run(
el.id,
el.layerId,
el.type,
el.content || '',
el.startFrame || 0,
el.endFrame || 0,
el.x || 0,
el.y || 0,
el.w || null,
el.h || null,
el.scale ?? 1,
el.rotation ?? 0,
el.opacity ?? 1,
el.color || null,
el.fontFamily || null,
el.fontSize || null,
el.textAlign || null,
el.filter || null,
el.chromaKeyEnabled ? 1 : 0,
el.chromaKeyColor || null
);
}
}
});
tx();
}
export function getTemplatesFromDB() {
const db = getDB();
const projects = db.prepare('SELECT * FROM projects WHERE is_template = 1').all() as any[];
return projects.map(p => {
const layers = db.prepare('SELECT * FROM timeline_layers WHERE project_id = ?').all(p.id) as any[];
const elements = db.prepare(`
SELECT e.* FROM timeline_elements e
JOIN timeline_layers l ON l.id = e.layer_id
WHERE l.project_id = ?
`).all(p.id) as any[];
// Map DB rows back to application models
const mappedLayers = layers.map(l => ({
id: l.id,
name: l.name,
type: l.type,
isVisible: Boolean(l.is_visible),
isLocked: Boolean(l.is_locked),
isMuted: Boolean(l.is_muted),
opacity: l.opacity,
volume: l.volume
}));
const mappedElements = elements.map(e => ({
id: e.id,
layerId: e.layer_id,
type: e.type,
content: e.content,
startFrame: e.start_frame,
endFrame: e.end_frame,
x: e.x,
y: e.y,
w: e.w,
h: e.h,
scale: e.scale,
rotation: e.rotation,
opacity: e.opacity,
color: e.color,
fontFamily: e.font_family,
fontSize: e.font_size,
textAlign: e.text_align,
filter: e.filter,
chromaKeyEnabled: Boolean(e.chroma_key_enabled),
chromaKeyColor: e.chroma_key_color
}));
return {
id: p.id,
brandId: p.brand_id,
name: p.name,
format: p.format,
duration: p.duration,
layers: mappedLayers,
elements: mappedElements
};
});
}
export function deleteTemplateFromDB(templateId: string) {
const db = getDB();
db.prepare('DELETE FROM projects WHERE id = ?').run(templateId);
return true;
}
// ═══ Brand DAOs ═══
export function saveBrandToDB(brand: any) {
const db = getDB();
const tx = db.transaction(() => {
db.prepare('INSERT OR REPLACE INTO brands (id, name, tagline, industry) VALUES (?, ?, ?, ?)').run(
brand.id, brand.name || brand.id, brand.tagline || '', brand.industry || ''
);
if (brand.design) {
const d = brand.design;
db.prepare(`
INSERT OR REPLACE INTO brand_design (
brand_id, primary_color, secondary_color, text_color, base_font,
logo_url, frame_thickness, title_font, title_size, title_color,
subtitle_font, subtitle_size, subtitle_color, paragraph_font, paragraph_size, paragraph_color
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
brand.id,
d.primaryColor || '#000000',
d.secondaryColor || '#FFFFFF',
d.textColor || '#FFFFFF',
d.baseFont || 'Inter',
d.logoUrl || '',
d.frameThickness || 0,
d.titleFont || '', d.titleSize || null, d.titleColor || '',
d.subtitleFont || '', d.subtitleSize || null, d.subtitleColor || '',
d.paragraphFont || '', d.paragraphSize || null, d.paragraphColor || ''
);
}
});
tx();
return true;
}
export function getBrandsFromDB() {
const db = getDB();
const brands = db.prepare('SELECT * FROM brands').all() as any[];
return brands.map(b => {
const design = db.prepare('SELECT * FROM brand_design WHERE brand_id = ?').get(b.id) as any;
const mappedDesign = design ? {
primaryColor: design.primary_color,
secondaryColor: design.secondary_color,
textColor: design.text_color,
baseFont: design.base_font,
logoUrl: design.logo_url,
frameThickness: design.frame_thickness,
titleFont: design.title_font,
titleSize: design.title_size,
titleColor: design.title_color,
subtitleFont: design.subtitle_font,
subtitleSize: design.subtitle_size,
subtitleColor: design.subtitle_color,
paragraphFont: design.paragraph_font,
paragraphSize: design.paragraph_size,
paragraphColor: design.paragraph_color,
brandAssets: []
} : {};
const assets = db.prepare("SELECT * FROM brand_assets WHERE brand_id = ? AND source = 'uploaded'").all(b.id) as any[];
if (mappedDesign) {
mappedDesign.brandAssets = assets.map(a => ({
id: a.id,
type: a.type,
url: a.url,
path: a.path
}));
}
return {
id: b.id,
name: b.name,
tagline: b.tagline,
industry: b.industry,
design: mappedDesign
};
});
}
export function deleteBrandFromDB(brandId: string) {
const db = getDB();
db.prepare('DELETE FROM brands WHERE id = ?').run(brandId);
return true;
}
// ═══ Generated Media DAOs ═══
export function registerGeneratedMediaDB(brandId: string, type: 'video' | 'image', filePath: string) {
const db = getDB();
db.prepare(`
INSERT OR IGNORE INTO brand_assets (id, brand_id, type, source, path, name)
VALUES (?, ?, ?, ?, ?, ?)
`).run(filePath, brandId, type, 'generated', filePath, filePath);
return true;
}
export function renameGeneratedMediaDB(brandId: string, type: 'video' | 'image', filePath: string, newName: string) {
const db = getDB();
db.prepare('UPDATE brand_assets SET name = ? WHERE path = ? AND brand_id = ? AND source = ?').run(newName, filePath, brandId, 'generated');
return true;
}
export function getGeneratedMediaDB(brandId: string, type: 'video' | 'image') {
const db = getDB();
const media = db.prepare('SELECT * FROM brand_assets WHERE brand_id = ? AND type = ? AND source = ?').all(brandId, type, 'generated') as any[];
return media.map(m => ({
path: m.path,
name: m.name,
date: m.created_at
}));
}
// ═══ Content Mesh DAOs ═══
export function saveContentMeshDB(data: any) {
const db = getDB();
db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)').run('content_mesh', JSON.stringify(data));
return true;
}
export function getContentMeshDB() {
const db = getDB();
const record = db.prepare('SELECT value FROM settings WHERE key = ?').get('content_mesh') as any;
if (record) return JSON.parse(record.value);
return {};
}