Skip to content

Commit

Permalink
added printing ui feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
enoy19 committed Aug 27, 2023
1 parent 75959ad commit f2ca4b2
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 25 deletions.
10 changes: 9 additions & 1 deletion src/lib/components/PrintButton.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<script lang="ts">
import { ProgressRadial } from '@skeletonlabs/skeleton';
import { persisted } from 'svelte-local-storage-store';
let selectedPrinter = persisted('selectedPrinter', undefined);
export let printing = false;
export let printers: string[];
export let buttonLabel = 'Print';
export let buttonColor = 'variant-filled-primary';
export let progressRadialColor = 'fill-on-primary-token';
</script>

<div class="input-group input-group-divider grid-cols-[auto_1fr] mt-3">
Expand All @@ -14,5 +17,10 @@
<option value={printer}>{printer}</option>
{/each}
</select>
<button type="submit" class="btn {buttonColor} w-full">{buttonLabel}</button>
<button type="submit" class="btn {buttonColor} w-full" disabled={printing}>
<span>{buttonLabel}</span>
{#if printing}
<ProgressRadial width="w-6" fill={progressRadialColor} />
{/if}
</button>
</div>
30 changes: 28 additions & 2 deletions src/lib/components/printer/PrinterConfig.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { enhance } from '$app/forms';
import type { PrinterType } from '$lib/types';
import { confirmed } from '$lib/use/buttonConfirmed';
import { toastStore } from '@skeletonlabs/skeleton';
import type { ActionResult } from '@sveltejs/kit';
export let identifier: string;
export let dpmm: number;
Expand All @@ -12,15 +14,39 @@
export let formDeleteAction = '?/deletePrinter';
export let deleteHidden = false;
function handleFormResult(result: ActionResult, deletion: boolean) {
if (result.type === 'failure') {
const action = deletion ? 'delete' : 'save';
toastStore.trigger({
message: `[${result.status}] Failed to ${action} printer: ${result?.data?.message}`,
autohide: true,
background: 'variant-filled-error'
});
} else if (result.type === 'success') {
const action = deletion ? 'deleted' : 'saved';
toastStore.trigger({
message: `${identifier} ${action}`,
autohide: true,
background: 'variant-filled-success'
});
}
}
</script>

<div class="card w-full">
<form
method="post"
action={formAction}
use:enhance={() => {
return ({ update }) => {
use:enhance={({ submitter }) => {
const deletion =
(submitter && submitter.getAttribute('formaction') === formDeleteAction) || false;

return ({ result, update }) => {
update({ reset: false });
handleFormResult(result, deletion);
};
}}
>
Expand Down
61 changes: 42 additions & 19 deletions src/lib/labelary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,79 @@ import { renderZpl } from './render';
import type { Density, Variables } from './types';

export async function renderZplToPngBase64(
zpl: string,
zplTemplate: string,
variables: Variables,
density: Density,
widthMillimeter: number,
heightMillimeter: number,
labelIndex = 0
) {
const zpl = renderZpl(zplTemplate, variables);

const pngData = await renderZplToPng(zpl, density, widthMillimeter, heightMillimeter, labelIndex);
return arrayBufferToBase64(pngData);
}

export async function renderZplToPng(
zpl: string,
density: Density,
widthMillimeter: number,
heightMillimeter: number,
labelIndex = 0
) {
const formData = new FormData();

const fileContent = renderZpl(zpl, variables);
const fileBlob = new Blob([fileContent], { type: 'text/plain' });
const fileBlob = new Blob([zpl], { type: 'text/plain' });
formData.append('file', fileBlob, 'blob');
formData.append('_charset_', 'UTF-8');

const response = await fetch(
`https://api.labelary.com/v1/printers/${density}/labels/${millimetersToInches(
widthMillimeter
)}x${millimetersToInches(heightMillimeter)}/${labelIndex}/`,
{
method: 'POST',
body: formData,
headers: {
Accept: 'image/png'
}
const url = `https://api.labelary.com/v1/printers/${density}/labels/${millimetersToInches(
widthMillimeter
)}x${millimetersToInches(heightMillimeter)}/${labelIndex}/`;

const response = await fetch(url, {
method: 'POST',
body: formData,
headers: {
Accept: 'image/png'
}
);
});

if (!response.ok) {
const errorText = await response.text();
throw new Error(errorText);
}

return blobToBase64(await response.blob());
return blobToArrayBuffer(await response.blob());
}

function millimetersToInches(mm: number) {
return (mm / 25.4).toFixed(10);
}

async function blobToBase64(blob: Blob): Promise<string> {
async function blobToArrayBuffer(blob: Blob): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader();

reader.onloadend = () => {
const base64data = reader.result as string;
resolve(base64data.split(',')[1]);
if (reader.result instanceof ArrayBuffer) {
resolve(reader.result);
} else {
reject(new Error('blob read result is not array buffer'));
}
};

reader.onerror = () => reject(new Error('An error occurred reading the blob'));

reader.readAsDataURL(blob);
reader.readAsArrayBuffer(blob);
});
}

function arrayBufferToBase64(buffer: ArrayBuffer) {
let binary = '';
const data = new Uint8Array(buffer);
for (let i = 0; i < data.byteLength; i++) {
binary += String.fromCharCode(data[i]);
}
return window.btoa(binary);
}
19 changes: 18 additions & 1 deletion src/routes/p/[templateName]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
let variables: Variables = {};
let renderPromise: Promise<string>;
let csvFiles: FileList;
let printing = false;
$: zpl = renderZpl(template.zpl, variables);
Expand Down Expand Up @@ -53,6 +54,12 @@
autohide: true,
background: 'variant-filled-error'
});
} else if (result.type === 'success') {
toastStore.trigger({
message: `Print successful`,
autohide: true,
background: 'variant-filled-success'
});
}
}
Expand Down Expand Up @@ -84,14 +91,18 @@
method="post"
action="?/print"
use:enhance={() => {
printing = true;

return async ({ update, result }) => {
printing = false;

update({ reset: false });
handleFormResult(result);
};
}}
>
<input type="hidden" name="zpl" value={zpl} />
<PrintButton {printers} />
<PrintButton {printers} {printing} />
</form>
<hr class="my-3" />
<div class="mt-3">
Expand All @@ -108,7 +119,11 @@
method="post"
enctype="multipart/form-data"
use:enhance={() => {
printing = true;

return async ({ update, result }) => {
printing = false;

update({ reset: false });
handleFormResult(result);
};
Expand All @@ -128,6 +143,8 @@
csvFiles && csvFiles.length > 0 ? `: ${csvFiles.item(0)?.name}` : ''
}`}
buttonColor="variant-filled-warning"
progressRadialColor="fill-on-warning-token"
{printing}
/>
</form>
</div>
Expand Down
9 changes: 7 additions & 2 deletions src/routes/pdf/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
$: ({ printers } = data);
let pdfFiles: FileList;
let printing = false;
function handleFormResult(result: ActionResult) {
if (result.type === 'failure') {
Expand All @@ -18,7 +19,7 @@
autohide: true,
background: 'variant-filled-error'
});
} else {
} else if (result.type === 'success') {
toastStore.trigger({
message: `Print successful`,
autohide: true,
Expand All @@ -37,7 +38,11 @@
enctype="multipart/form-data"
action="?/print"
use:enhance={() => {
printing = true;

return async ({ update, result }) => {
printing = false;

update({ reset: false });
handleFormResult(result);
};
Expand All @@ -63,7 +68,7 @@
</ul>
</div>
{/if}
<PrintButton {printers} />
<PrintButton {printers} {printing} />
</form>
</div>
</div>

0 comments on commit f2ca4b2

Please sign in to comment.