fix: resolve image download errors, update export and image services

This commit is contained in:
2026-02-04 23:27:07 +05:00
parent c098c21077
commit 9b1d24def2
14 changed files with 251 additions and 377 deletions
-3
View File
@@ -1,6 +1,5 @@
<script lang="ts">
import Button from "$components/ui/Button.svelte";
import { ImageService } from "$lib/services/imageService";
import type { ImageCropResult } from "$lib/types/panel";
import { setLoading } from "$stores/uiStore";
import CropperJS from "cropperjs";
@@ -19,8 +18,6 @@
let isProcessing = $state(false);
let errorMessage = $state<string | undefined>(undefined);
let imageService = new ImageService();
onMount(() => {
initializeCropper();
return () => {
+1 -3
View File
@@ -1,12 +1,10 @@
<script lang="ts">
import Button from "$components/ui/Button.svelte";
import { ImageService } from "$lib/services/imageService";
import type { ImageUploadResult } from "$lib/types/panel";
import { handleError } from "$lib/utils/errorHandler";
import { clearError, setCurrentStep, setLoading, uiStore } from "$stores/uiStore";
import { onMount } from "svelte";
let imageService = new ImageService();
import { imageService } from "../../services/imageService";
interface Props {
onImageSelect: (image: string) => void;
+1 -1
View File
@@ -16,7 +16,7 @@
onTextAdd: (text: string) => void;
onTextUpdate: (id: string, newText: string) => void;
onTextDelete: (id: string) => void;
onDownload: (panel: any) => Promise<void>;
onDownload: (panel: any, konvaStage: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
+1 -1
View File
@@ -14,7 +14,7 @@
onTextUpdate: (id: string, newText: string) => void;
onTextDelete: (id: string) => void;
onUploadNewImage: () => void;
onDownload: (panel: any) => Promise<void>;
onDownload: (panel: any, konvaStage: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
+1 -1
View File
@@ -7,7 +7,7 @@
backgroundImage: string | undefined;
panels: any[];
onUploadNewImage: () => void;
onDownload: (panel: any) => Promise<void>;
onDownload: (panel: any, konvaStage: any) => Promise<void>;
onDownloadAll: () => Promise<void>;
}
+48 -5
View File
@@ -2,16 +2,27 @@
import Button from "$components/ui/Button.svelte";
import type { Panel, TextItem } from "$lib/types/panel";
import { setCurrentStep } from "$stores/uiStore";
import type { Stage as KonvaStage } from "konva/lib/Stage";
import { Image, Layer, Stage, Text } from "svelte-konva";
interface Props {
panel: Panel;
onDownload?: () => void;
onDownload?: (panel: Panel, konvaStage: KonvaStage) => void;
}
let { panel, onDownload }: Props = $props();
let backgroundImage: HTMLImageElement | undefined = $state(undefined);
let konvaStage: KonvaStage | null = $state(null);
let stageComponent: any = $state(null);
// Get the Konva stage after component mounts
$effect(() => {
if (stageComponent) {
// According to svelte-konva docs, access the node property to get the underlying Konva Stage
konvaStage = stageComponent.node;
}
});
function handleUploadNewImage() {
setCurrentStep("upload");
@@ -25,7 +36,6 @@
function loadImage(src: string) {
// Remove verbose logging - image data is too large for console
console.log("[PanelPreview] Loading background image");
const img = document.createElement("img");
img.onload = () => {
backgroundImage = img;
@@ -37,8 +47,41 @@
}
function handleDownload() {
if (onDownload) {
onDownload();
console.log("[PanelPreview] handleDownload called");
console.log("[PanelPreview] onDownload exists:", onDownload ? true : false);
console.log("[PanelPreview] konvaStage exists:", konvaStage ? true : false);
console.log("[PanelPreview] konvaStage value:", konvaStage);
console.log("[PanelPreview] stageComponent exists:", stageComponent ? true : false);
// Try different approaches to get the Konva stage for download
let stageToUse = konvaStage;
if (!stageToUse && stageComponent) {
console.log("[PanelPreview] konvaStage is null, trying to get stage from stageComponent");
// Try different properties that might contain the Konva stage
stageToUse = stageComponent.node || stageComponent.stage || stageComponent._stage || stageComponent;
// Check if this is actually a valid Konva stage
if (stageToUse && typeof stageToUse.toBlob === "function") {
console.log("[PanelPreview] Found valid Konva stage in stageComponent");
} else {
console.log("[PanelPreview] stageComponent itself might be the Konva stage");
// Maybe stageComponent IS the Konva stage - check if it has toBlob
if (typeof stageComponent.toBlob === "function") {
stageToUse = stageComponent;
console.log("[PanelPreview] ✅ stageComponent IS the Konva stage");
} else {
console.log("[PanelPreview] ❌ Could not find valid Konva stage");
}
}
}
if (onDownload && stageToUse) {
console.log("[PanelPreview] Calling onDownload with panel and stage");
onDownload(panel, stageToUse);
} else {
console.error("[PanelPreview] Cannot download - onDownload or valid stage is missing");
}
}
@@ -78,7 +121,7 @@
<!-- Превью с текстом -->
<div class="preview-section">
<div class="canvas-container">
<Stage width={320} height={panel.height}>
<Stage width={320} height={panel.height} bind:this={stageComponent}>
<!-- Background layer -->
<Layer>
{#if backgroundImage}
+4 -3
View File
@@ -1,11 +1,12 @@
<script lang="ts">
import type { Panel } from "$lib/types/panel";
import PanelPreview from "./PanelPreview.svelte";
import type { Stage as KonvaStage } from "konva/lib/Stage";
import Button from "../ui/Button.svelte";
import PanelPreview from "./PanelPreview.svelte";
interface Props {
panels: Panel[];
onDownload: (panel: Panel) => void;
onDownload: (panel: Panel, konvaStage: KonvaStage) => void;
onDownloadAll: () => void;
}
let { panels, onDownload, onDownloadAll }: Props = $props();
@@ -20,7 +21,7 @@
<div class="panels-list">
{#each panels as panel (panel.id)}
<div class="panel-item">
<PanelPreview {panel} onDownload={() => onDownload(panel)} />
<PanelPreview {panel} onDownload={(panel, konvaStage) => onDownload(panel, konvaStage)} />
</div>
{/each}
</div>