From bc7ed2498f5dd1723e2615007f4e7a82810d574a Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Wed, 4 Feb 2026 18:03:47 +0500 Subject: [PATCH] fix: resolve text preview error, add default panels --- src/components/panel/PanelPreview.svelte | 57 +++++++++++++++++------- src/lib/services/exportService.ts | 19 ++++---- src/lib/types/panel.ts | 2 +- src/routes/+page.svelte | 22 ++++++++- src/services/panelService.ts | 18 +++++--- src/stores/panelStore.ts | 50 +++++++++------------ 6 files changed, 105 insertions(+), 63 deletions(-) diff --git a/src/components/panel/PanelPreview.svelte b/src/components/panel/PanelPreview.svelte index 82888a4..c502788 100644 --- a/src/components/panel/PanelPreview.svelte +++ b/src/components/panel/PanelPreview.svelte @@ -1,5 +1,5 @@
-
{panel.texts[0]?.text || "Без названия"}
+
{panel.text?.text || "Без названия"}
@@ -65,23 +86,29 @@
+ {#if backgroundImage} {/if} - {#each panel.texts || [] as textItem (textItem.id)} - {@const textPosition = getTextPosition(textItem)} + + + + + {#if panel.text} + {@const textPosition = getTextPosition(panel.text)} + - {/each} + {/if}
diff --git a/src/lib/services/exportService.ts b/src/lib/services/exportService.ts index 948454d..cb8fc10 100644 --- a/src/lib/services/exportService.ts +++ b/src/lib/services/exportService.ts @@ -38,18 +38,17 @@ export class ExportService { ctx.drawImage(bgImage, 0, 0, 320, panel.height); // Рисуем текст - panel.texts.forEach((textItem) => { - ctx.font = `${textItem.fontSize}px ${textItem.fontFamily}`; - ctx.fillStyle = textItem.color; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; + const textItem = panel.text; + ctx.font = `${textItem.fontSize}px ${textItem.fontFamily}`; + ctx.fillStyle = textItem.color; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; - // Calculate position based on existing system - const x = 160; // Center of 320px panel - const y = panel.height / 2 + textItem.verticalOffset; + // Calculate position based on existing system + const x = 160; // Center of 320px panel + const y = panel.height / 2 + textItem.verticalOffset; - ctx.fillText(textItem.text, x, y); - }); + ctx.fillText(textItem.text, x, y); // Конвертируем в blob и сохраняем canvas.toBlob((blob) => { diff --git a/src/lib/types/panel.ts b/src/lib/types/panel.ts index 3c88aae..74aded8 100644 --- a/src/lib/types/panel.ts +++ b/src/lib/types/panel.ts @@ -14,7 +14,7 @@ export interface TextItem { export interface Panel { id: string; backgroundImage: string; - texts: TextItem[]; + text: TextItem; height: number; createdAt: Date; updatedAt: Date; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 91c009c..f7d1638 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -13,11 +13,31 @@ let backgroundImage = $state(undefined); onMount(async () => { + // Initialize with default texts for common Twitch panels + console.log("[INIT] Creating default texts..."); + const defaultTexts = [ + { id: crypto.randomUUID(), text: "About" }, + { id: crypto.randomUUID(), text: "Links" }, + ]; + texts = defaultTexts; + console.log("[INIT] Default texts created:", texts); + + // Load background image try { - backgroundImage = await imageService.loadDefaultBackground(); + console.log("[INIT] Loading default background..."); + const loadedBackground = await imageService.loadDefaultBackground(); + console.log("[INIT] Background loaded:", loadedBackground); + backgroundImage = loadedBackground; } catch (error) { + console.error("[INIT] Error loading background:", error); exportService.setErrorMessage("Не удалось загрузить фоновое изображение по умолчанию"); } + + // Create panels from texts (with or without background) + console.log("[INIT] Creating panels from texts..."); + const initialPanels = panelService.updatePanelsFromTexts(texts, [], backgroundImage || ""); + console.log("[INIT] Panels created:", initialPanels); + panels = initialPanels; }); function handleImageUpload(image: string) { diff --git a/src/services/panelService.ts b/src/services/panelService.ts index 6442cb7..e15ca18 100644 --- a/src/services/panelService.ts +++ b/src/services/panelService.ts @@ -18,7 +18,7 @@ export class PanelService { } isDuplicateText(texts: Array<{ id: string; text: string }>, text: string, excludeId?: string): boolean { - return texts.some(t => t.id !== excludeId && t.text === text); + return texts.some((t) => t.id !== excludeId && t.text === text); } addText(texts: Array<{ id: string; text: string }>, text: string): Array<{ id: string; text: string }> { @@ -28,20 +28,24 @@ export class PanelService { return [...texts, { id: crypto.randomUUID(), text }]; } - updateText(texts: Array<{ id: string; text: string }>, id: string, newText: string): Array<{ id: string; text: string }> { + updateText( + texts: Array<{ id: string; text: string }>, + id: string, + newText: string, + ): Array<{ id: string; text: string }> { if (!this.validateText(newText)) return texts; if (this.isDuplicateText(texts, newText, id)) return texts; - return texts.map(t => t.id === id ? { ...t, text: newText } : t); + return texts.map((t) => (t.id === id ? { ...t, text: newText } : t)); } deleteText(texts: Array<{ id: string; text: string }>, id: string): Array<{ id: string; text: string }> { - return texts.filter(t => t.id !== id); + return texts.filter((t) => t.id !== id); } updatePanelsFromTexts(texts: Array<{ id: string; text: string }>, panels: Panel[], backgroundImage: string): Panel[] { - return texts.map(textItem => { - const existingPanel = panels.find(p => p.texts[0]?.text === textItem.text); + return texts.map((textItem) => { + const existingPanel = panels.find((p) => p.text.text === textItem.text); if (existingPanel) { return updatePanelText(existingPanel, textItem.text); } @@ -50,7 +54,7 @@ export class PanelService { } updatePanelsBackground(panels: Panel[], newBackground: string): Panel[] { - return panels.map(panel => ({ + return panels.map((panel) => ({ ...panel, backgroundImage: newBackground, updatedAt: new Date(), diff --git a/src/stores/panelStore.ts b/src/stores/panelStore.ts index a04252a..2b1b1b0 100644 --- a/src/stores/panelStore.ts +++ b/src/stores/panelStore.ts @@ -4,11 +4,24 @@ import { type Panel, type TextItem } from "../lib/types/panel"; export const panelStore: Writable = writable(undefined); +// Panel creation should go through panelService.updatePanelsFromTexts() +// These functions are kept for backward compatibility but should be avoided export const createEmptyPanel = (height: number = 100): Panel => { + const defaultText: TextItem = { + id: uuidv4(), + text: "", + fontSize: 18, + fontFamily: "Arial", + color: "#ffffff", + textAlign: "center", + paddingX: 10, + verticalOffset: 0, + }; + return { id: uuidv4(), backgroundImage: "", - texts: [], + text: defaultText, height, createdAt: new Date(), updatedAt: new Date(), @@ -23,32 +36,16 @@ export const updatePanel = (panel: Panel, updates: Partial): Panel => { }; }; -export const addTextToPanel = (panel: Panel, text: string): Panel => { - const newText: TextItem = { - id: uuidv4(), - text, - fontSize: 18, - fontFamily: "Arial", - color: "#ffffff", - textAlign: "center", - paddingX: 10, - verticalOffset: 0, - }; - +export const updatePanelText = (panel: Panel, text: string): Panel => { return updatePanel(panel, { - texts: [...panel.texts, newText], + text: { ...panel.text, text }, }); }; -export const updateTextInPanel = (panel: Panel, textId: string, updates: Partial): Panel => { - const updatedTexts = panel.texts.map((text) => (text.id === textId ? { ...text, ...updates } : text)); - - return updatePanel(panel, { texts: updatedTexts }); -}; - -export const removeTextFromPanel = (panel: Panel, textId: string): Panel => { - const updatedTexts = panel.texts.filter((text) => text.id !== textId); - return updatePanel(panel, { texts: updatedTexts }); +export const updateTextProperties = (panel: Panel, updates: Partial): Panel => { + return updatePanel(panel, { + text: { ...panel.text, ...updates }, + }); }; export const createPanelFromText = (backgroundImage: string, text: string, height: number = 100): Panel => { @@ -66,14 +63,9 @@ export const createPanelFromText = (backgroundImage: string, text: string, heigh return { id: uuidv4(), backgroundImage, - texts: [newText], + text: newText, height, createdAt: new Date(), updatedAt: new Date(), }; }; - -export const updatePanelText = (panel: Panel, text: string): Panel => { - const updatedTexts = panel.texts.map((t) => ({ ...t, text })); - return updatePanel(panel, { texts: updatedTexts }); -};