mirror of
https://github.com/MultiMote/niimblue
synced 2026-01-19 19:37:11 +03:00
Merge branch 'main' of https://github.com/MultiMote/niimblue
This commit is contained in:
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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": "Сохранить (заменить)",
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user