Hide IO toast on note change

This commit is contained in:
Abdo 2025-07-27 18:24:09 +03:00
parent aa493f8293
commit 986ca6e252
6 changed files with 49 additions and 30 deletions

View file

@ -17,12 +17,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { MaskEditorAPI } from "./tools/api"; import { MaskEditorAPI } from "./tools/api";
import { onResize } from "./tools/tool-zoom"; import { onResize } from "./tools/tool-zoom";
import { saveNeededStore } from "./store"; import { saveNeededStore } from "./store";
import { destroyToast, initToast } from "./toast-utils.svelte";
import type Toast from "./Toast.svelte";
export let mode: IOMode; export let mode: IOMode;
const iconSize = 80; const iconSize = 80;
let innerWidth = 0; let innerWidth = 0;
const startingTool = mode.kind === "add" ? "draw-rectangle" : "cursor"; const startingTool = mode.kind === "add" ? "draw-rectangle" : "cursor";
let canvas: fabric.Canvas | null = null; let canvas: fabric.Canvas | null = null;
let toast: Toast | null = null;
$: { $: {
globalThis.maskEditor = canvas ? new MaskEditorAPI(canvas) : null; globalThis.maskEditor = canvas ? new MaskEditorAPI(canvas) : null;
@ -67,11 +70,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onMount(() => { onMount(() => {
window.addEventListener("resize", resizeEvent); window.addEventListener("resize", resizeEvent);
toast = initToast();
}); });
onDestroy(() => { onDestroy(() => {
window.removeEventListener("resize", resizeEvent); window.removeEventListener("resize", resizeEvent);
unsubscribe(); unsubscribe();
destroyToast(toast);
}); });
const resizeEvent = () => { const resizeEvent = () => {

View file

@ -6,10 +6,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Icon from "$lib/components/Icon.svelte"; import Icon from "$lib/components/Icon.svelte";
import IconButton from "$lib/components/IconButton.svelte"; import IconButton from "$lib/components/IconButton.svelte";
import { mdiClose } from "$lib/components/icons"; import { mdiClose } from "$lib/components/icons";
import type { ToastProps } from "./types";
let { showToast, type, message }: ToastProps = $props();
export let type: "success" | "error" = "success";
export let message;
export let showToast = false;
const closeToast = () => { const closeToast = () => {
showToast = false; showToast = false;
}; };

View file

@ -6,11 +6,10 @@ import { addImageOcclusionNote, updateImageOcclusionNote } from "@generated/back
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { mount } from "svelte";
import type { IOAddingMode, IOMode } from "./lib"; import type { IOAddingMode, IOMode } from "./lib";
import { exportShapesToClozeDeletions } from "./shapes/to-cloze"; import { exportShapesToClozeDeletions } from "./shapes/to-cloze";
import { notesDataStore, tagsWritable } from "./store"; import { notesDataStore, tagsWritable } from "./store";
import Toast from "./Toast.svelte"; import { showToast } from "./toast-utils.svelte";
export const addOrUpdateNote = async function( export const addOrUpdateNote = async function(
mode: IOMode, mode: IOMode,
@ -54,24 +53,11 @@ export const addOrUpdateNote = async function(
// show toast message // show toast message
const showResult = (noteId: bigint | null, result: OpChanges, count: number) => { const showResult = (noteId: bigint | null, result: OpChanges, count: number) => {
const props = $state({
message: "",
type: "error" as "error" | "success",
showToast: true,
});
mount(Toast, {
target: document.body,
props,
});
if (result.note) { if (result.note) {
const msg = noteId ? tr.browsingCardsUpdated({ count: count }) : tr.importingCardsAdded({ count: count }); const msg = noteId ? tr.browsingCardsUpdated({ count: count }) : tr.importingCardsAdded({ count: count });
props.message = msg; showToast(msg, "success");
props.type = "success";
props.showToast = true;
} else { } else {
const msg = tr.notetypesErrorGeneratingCloze(); const msg = tr.notetypesErrorGeneratingCloze();
props.message = msg; showToast(msg, "error");
props.showToast = true;
} }
}; };

View file

@ -7,10 +7,9 @@ import * as tr from "@generated/ftl";
import { fabric } from "fabric"; import { fabric } from "fabric";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { mount } from "svelte";
import { optimumCssSizeForCanvas } from "./canvas-scale"; import { optimumCssSizeForCanvas } from "./canvas-scale";
import { hideAllGuessOne, notesDataStore, saveNeededStore, tagsWritable, textEditingState } from "./store"; import { hideAllGuessOne, notesDataStore, saveNeededStore, tagsWritable, textEditingState } from "./store";
import Toast from "./Toast.svelte"; import { showToast } from "./toast-utils.svelte";
import { addShapesToCanvasFromCloze } from "./tools/add-from-cloze"; import { addShapesToCanvasFromCloze } from "./tools/add-from-cloze";
import { enableSelectable, makeShapesRemainInCanvas, moveShapeToCanvasBoundaries } from "./tools/lib"; import { enableSelectable, makeShapesRemainInCanvas, moveShapeToCanvasBoundaries } from "./tools/lib";
import { modifiedPolygon } from "./tools/tool-polygon"; import { modifiedPolygon } from "./tools/tool-polygon";
@ -51,14 +50,7 @@ export const setupMaskEditorForEdit = async (
const clozeNoteResponse = await getImageOcclusionNote({ noteId: BigInt(noteId) }); const clozeNoteResponse = await getImageOcclusionNote({ noteId: BigInt(noteId) });
const kind = clozeNoteResponse.value?.case; const kind = clozeNoteResponse.value?.case;
if (!kind || kind === "error") { if (!kind || kind === "error") {
mount(Toast, { showToast(tr.notetypesErrorGettingImagecloze(), "error");
target: document.body,
props: {
message: tr.notetypesErrorGettingImagecloze(),
type: "error",
showToast: true,
},
});
throw "error getting cloze"; throw "error getting cloze";
} }

View file

@ -0,0 +1,30 @@
import { mount, unmount } from "svelte";
import Toast from "./Toast.svelte";
import type { ToastProps } from "./types";
const toastProps: ToastProps = $state({
showToast: false,
type: "success",
message: "",
});
export function initToast(): Toast {
return mount(Toast, {
target: document.body,
props: toastProps,
});
}
export function destroyToast(toast: Toast) {
unmount(toast);
}
export function showToast(message: string, type: "success" | "error") {
toastProps.message = message;
toastProps.type = type;
toastProps.showToast = true;
}
export function hideToast() {
toastProps.showToast = false;
}

View file

@ -9,3 +9,9 @@ export interface Size {
export type ConstructorParams<T> = { export type ConstructorParams<T> = {
[P in keyof T]?: T[P]; [P in keyof T]?: T[P];
}; };
export interface ToastProps {
message: string;
type: "success" | "error";
showToast: boolean;
}