mirror of
https://github.com/MultiMote/niimblue
synced 2026-01-19 19:37:11 +03:00
Add ZPL import via Labelary API
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
import BarcodeParamsPanel from "./BarcodeParamsControls.svelte";
|
||||
import Dropdown from "bootstrap/js/dist/dropdown";
|
||||
import { FileUtils } from "../utils/file_utils";
|
||||
import ZplImportButton from "./ZplImportButton.svelte";
|
||||
|
||||
let htmlCanvas: HTMLCanvasElement;
|
||||
let fabricCanvas: fabric.Canvas;
|
||||
@@ -110,6 +111,25 @@
|
||||
);
|
||||
};
|
||||
|
||||
const zplImageReady = (img: Blob) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.readAsDataURL(img);
|
||||
reader.onload = (readerEvt: ProgressEvent<FileReader>) => {
|
||||
if (readerEvt?.target?.result) {
|
||||
fabric.Image.fromURL(readerEvt.target.result as string, (img: fabric.Image) => {
|
||||
img.set({ left: 0, top: 0, snapAngle: 10 });
|
||||
img.scaleToHeight(labelProps.size.width - 1).scaleToHeight(labelProps.size.height - 1);
|
||||
fabricCanvas.add(img);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
reader.onerror = (readerEvt: ProgressEvent<FileReader>) => {
|
||||
console.error(readerEvt);
|
||||
};
|
||||
};
|
||||
|
||||
const onObjectPicked = (objectType: OjectType) => {
|
||||
ImageEditorUtils.addObject(fabricCanvas, objectType);
|
||||
};
|
||||
@@ -245,9 +265,13 @@
|
||||
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button class="btn btn-secondary btn-sm" on:click={onLoadClicked}><FaIcon icon="folder-open" /></button>
|
||||
<button class="btn btn-secondary dropdown-toggle px-1" data-bs-toggle="dropdown"> </button>
|
||||
<button class="btn btn-secondary dropdown-toggle px-1" data-bs-toggle="dropdown" data-bs-auto-close="outside">
|
||||
</button>
|
||||
<div class="dropdown-menu px-2">
|
||||
<button class="btn btn-secondary btn-sm" on:click={onImportClicked}>Import JSON</button>
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<button class="btn btn-secondary btn-sm" on:click={onImportClicked}>Import JSON</button>
|
||||
<ZplImportButton {labelProps} onImageReady={zplImageReady} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
54
niimblue/src/lib/ZplImportButton.svelte
Normal file
54
niimblue/src/lib/ZplImportButton.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import type { LabelProps } from "../types";
|
||||
import { FileUtils } from "../utils/file_utils";
|
||||
import FaIcon from "./FaIcon.svelte";
|
||||
|
||||
export let labelProps: LabelProps;
|
||||
export let onImageReady: (img: Blob) => void;
|
||||
let state: "idle" | "processing" | "error" = "idle";
|
||||
|
||||
const onImportClicked = async () => {
|
||||
const mmToInchCoeff = 25.4;
|
||||
const dpmm = 8; // todo: may vary, make it configurable
|
||||
const widthInches = labelProps.size.width / dpmm / mmToInchCoeff;
|
||||
const heightInches = labelProps.size.height / dpmm / mmToInchCoeff;
|
||||
|
||||
const contents = await FileUtils.pickAndReadTextFile("zpl");
|
||||
|
||||
state = "processing";
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`http://api.labelary.com/v1/printers/${dpmm}dpmm/labels/${widthInches}x${heightInches}/0/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Accept": "image/png",
|
||||
"X-Quality": "bitonal",
|
||||
},
|
||||
body: contents,
|
||||
}
|
||||
);
|
||||
if (response.ok) {
|
||||
const img = await response.blob();
|
||||
onImageReady(img);
|
||||
state = "idle";
|
||||
} else {
|
||||
state = "error";
|
||||
}
|
||||
} catch (e) {
|
||||
state = "error";
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<button class="btn btn-secondary btn-sm" on:click={onImportClicked}
|
||||
>Import ZPL
|
||||
{#if state === "processing"}
|
||||
<FaIcon icon="sync" params={{ classes: ["fa-spin"] }}></FaIcon>
|
||||
{:else if state === "error"}
|
||||
<FaIcon icon="warning" params={{ classes: ["text-warning"] }}></FaIcon>
|
||||
{/if}
|
||||
</button>
|
||||
@@ -18,7 +18,12 @@ export class FileUtils {
|
||||
URL.revokeObjectURL(link.href);
|
||||
}
|
||||
|
||||
/** Open file picker and return file contents */
|
||||
/**
|
||||
* Open file picker and return file contents
|
||||
*
|
||||
* fixme: never ends if dialog closed
|
||||
*
|
||||
* */
|
||||
public static async pickAndReadTextFile(acceptExtension: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const input: HTMLInputElement = document.createElement("input");
|
||||
|
||||
Reference in New Issue
Block a user