1
0
mirror of https://github.com/MultiMote/niimblue synced 2026-01-19 19:37:11 +03:00
This commit is contained in:
MultiMote
2024-11-06 11:07:18 +03:00
8 changed files with 73 additions and 39 deletions

View File

@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---

View File

@@ -25,6 +25,8 @@ Your browser must support Web Bluetooth API: [supported browsers](https://develo
For serial communication: [supported browsers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API#browser_compatibility).
In some systems you need to enable Chrome `Experimental Web Platform Features` (navigate to `chrome://flags`).
## Feedback needed!
I only have D110 and B1 printers. If you own other models, please write a comment [here](https://github.com/MultiMote/niimbluelib/issues/1) describing your model working or not.

View File

@@ -16,6 +16,11 @@
let savedLabels: ExportedLabelTemplate[] = [];
let selectedIndex: number = -1;
let title: string = "";
let usedSpace: number = 0;
const calcUsedSpace = () => {
usedSpace = LocalStoragePersistence.usedSpace();
}
const onLabelSelected = (index: number) => {
selectedIndex = index;
@@ -38,8 +43,21 @@
savedLabels = result;
title = "";
calcUsedSpace();
};
const saveLabels = (labels: ExportedLabelTemplate[]) => {
const {zodErrors, otherErrors} = LocalStoragePersistence.saveLabels(labels);
zodErrors.forEach((e) => Toasts.zodErrors(e, "Label save error"));
otherErrors.forEach((e) => Toasts.error(e));
if (zodErrors.length === 0 && otherErrors.length === 0) {
savedLabels = labels;
}
calcUsedSpace();
}
const onSaveReplaceClicked = () => {
if (selectedIndex === -1) {
return;
@@ -55,26 +73,14 @@
const result = [...savedLabels];
result[selectedIndex] = label;
const errors = LocalStoragePersistence.saveLabels(result);
errors.forEach((e) => Toasts.zodErrors(e, "Label save error"));
if (errors.length === 0) {
savedLabels = result;
}
saveLabels(result);
};
const onSaveClicked = () => {
const label = onRequestCurrentCanvas();
label.title = title;
const result = [...savedLabels, label];
console.log(result);
const errors = LocalStoragePersistence.saveLabels(result);
errors.forEach((e) => Toasts.zodErrors(e, "Label save error"));
if (errors.length === 0) {
savedLabels = result;
}
saveLabels(result);
};
const onLoadClicked = () => {
@@ -114,12 +120,9 @@
}
};
const reload = () => {
savedLabels = LocalStoragePersistence.loadLabels();
};
onMount(() => {
reload();
savedLabels = LocalStoragePersistence.loadLabels();
calcUsedSpace();
});
</script>
@@ -128,7 +131,9 @@
<MdIcon icon="sd_storage" />
</button>
<div class="dropdown-menu" bind:this={dropdownRef}>
<h6 class="dropdown-header">{$tr("params.saved_labels.menu_title")}</h6>
<h6 class="dropdown-header">
{$tr("params.saved_labels.menu_title")} - {usedSpace} {$tr("params.saved_labels.kb_used")}
</h6>
<div class="px-3">
<div class="p-1">

View File

@@ -94,6 +94,7 @@ export const translation_en = {
"params.variables.insert": "Insert variable",
"params.saved_labels.menu_title": "Save/load (browser storage)",
"params.saved_labels.kb_used": "kB used",
"params.saved_labels.save.json": "Export",
"params.saved_labels.save.browser": "Save",
"params.saved_labels.save.browser.replace": "Save (replace)",

View File

@@ -121,6 +121,7 @@ export const translation_ru: Record<TranslationKey, string> = {
"params.barcode.enable_caption": "Показывать надпись",
/* SavedLabelsMenu */
"params.saved_labels.menu_title": "Сохранить/загрузить (хранилище браузера)",
"params.saved_labels.kb_used": "кБ использовано",
"params.saved_labels.save.json": "Экспорт",
"params.saved_labels.save.browser": "Сохранить",
"params.saved_labels.save.browser.replace": "Сохранить (заменить)",

View File

@@ -1,5 +1,5 @@
import { fabric } from "fabric";
import type { ITextOptions, TextOptions } from "fabric/fabric-impl";
import type { ITextboxOptions, TextOptions } from "fabric/fabric-impl";
import { OBJECT_DEFAULTS, OBJECT_DEFAULTS_TEXT, OBJECT_DEFAULTS_VECTOR, OBJECT_SIZE_DEFAULTS } from "../defaults";
import Barcode from "../fabric-object/barcode.class";
import { QRCode } from "../fabric-object/qrcode.class";
@@ -116,8 +116,8 @@ export class ImageEditorObjectHelper {
}
}
static addText(canvas: fabric.Canvas, text?: string, options?: ITextOptions): fabric.IText {
const obj = new fabric.IText(text ?? "Text", {
static addText(canvas: fabric.Canvas, text?: string, options?: ITextboxOptions): fabric.Textbox {
const obj = new fabric.Textbox(text ?? "Text", {
...OBJECT_DEFAULTS_TEXT,
...options,
});

View File

@@ -14,6 +14,15 @@ import { z } from "zod";
import { FileUtils } from "./file_utils";
export class LocalStoragePersistence {
/** Result in kilobytes */
static usedSpace(): number {
let total = 0;
Object.keys(localStorage).forEach((key) => {
total += (localStorage[key].length + key.length) * 2;
});
return Math.floor(total / 1024);
}
static saveObject(key: string, data: any) {
if (data == null || data == undefined) {
localStorage.removeItem(key);
@@ -88,8 +97,10 @@ export class LocalStoragePersistence {
this.validateAndSaveObject("last_label_props", labelData, LabelPropsSchema);
}
static saveLabels(labels: ExportedLabelTemplate[]): z.ZodError[] {
const errors: z.ZodError[] = [];
static saveLabels(labels: ExportedLabelTemplate[]): {zodErrors: z.ZodError[], otherErrors: Error[]} {
const zodErrors: z.ZodError[] = [];
const otherErrors: Error[] = [];
Object.keys(localStorage).forEach((key) => {
if (key.startsWith("saved_label")) {
localStorage.removeItem(key);
@@ -111,13 +122,14 @@ export class LocalStoragePersistence {
this.validateAndSaveObject(`${basename}_${counter}`, label, ExportedLabelTemplateSchema);
} catch (e) {
console.error(e);
if (e instanceof z.ZodError) {
errors.push(e);
zodErrors.push(e);
} if (e instanceof Error) {
otherErrors.push(e);
}
}
});
return errors;
return {zodErrors, otherErrors};
}
/**
@@ -139,18 +151,20 @@ export class LocalStoragePersistence {
this.validateAndSaveObject(`saved_label_${item.timestamp}`, item, ExportedLabelTemplateSchema);
}
Object.keys(localStorage).sort().forEach((key) => {
if (key.startsWith("saved_label")) {
try {
const item = this.loadAndValidateObject(key, ExportedLabelTemplateSchema);
if (item != null) {
items.push(item);
Object.keys(localStorage)
.sort()
.forEach((key) => {
if (key.startsWith("saved_label")) {
try {
const item = this.loadAndValidateObject(key, ExportedLabelTemplateSchema);
if (item != null) {
items.push(item);
}
} catch (e) {
console.error(e);
}
} catch (e) {
console.error(e);
}
}
});
});
return items;
}

View File

@@ -3,6 +3,8 @@ import { z } from "zod";
export class Toasts {
static error(e: any) {
console.error(e);
Toastify({
text: `${e}`,
gravity: "bottom",
@@ -13,7 +15,6 @@ export class Toasts {
static zodErrors(e: any, prefix: string) {
if (e instanceof z.ZodError) {
console.error(e);
e.issues.forEach((i) => {
this.error(`${prefix} "${i.path.join("→")}" ${i.message}`);
});