stash
This commit is contained in:
parent
ed04d98bf1
commit
aa94c92000
10 changed files with 873 additions and 296 deletions
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
<div v-if="error" class="alert alert-danger" role="alert">{{ error }}</div>
|
||||
|
||||
<div v-if="warnings.length" class="alert alert-warning" role="alert">
|
||||
<div v-for="(w, i) in warnings" :key="i">{{ w.message }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!usbSupported" class="alert alert-warning">
|
||||
This browser can't talk to USB label printers directly. Open this page in Chrome, Edge or
|
||||
Opera over https:// (or http://localhost) to print straight from here, or use one of the
|
||||
|
|
@ -244,7 +248,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<label-layout-preview :fields="fields" :value="selectedTemplate"
|
||||
<label-layout-preview :fields="fields" :value="selectedTemplate" :tape="tape"
|
||||
:recent-template-ids="recentTemplateIds"
|
||||
@input="selectedTemplate = $event"></label-layout-preview>
|
||||
</div>
|
||||
|
|
@ -260,6 +264,7 @@ import {markRaw, nextTick} from "vue";
|
|||
import {mapActions, mapGetters} from "vuex";
|
||||
import BaseLayout from "@/components/BaseLayout.vue";
|
||||
import LabelLayoutPreview from "@/components/LabelLayoutPreview.vue";
|
||||
import printerManager from "@/printerManager.js";
|
||||
|
||||
import {MultiPrinterBlob, canvasToBitmap, bitmapToCanvas} from "../../vendor/weblabel.js";
|
||||
import {tapeFromStatus, drawLabel, drawFallbackLabel, buildLabelContent, buildLabelFields, preloadQrEncoder} from "@/label.js";
|
||||
|
|
@ -319,6 +324,8 @@ export default {
|
|||
printedWidthPx: 0,
|
||||
// Each "text" leaf's effective font size (see label.js's drawLabel), shown beside the tape width so a too-small-to-render field reads as a suspiciously tiny number rather than silently absent.
|
||||
textSizesPx: [],
|
||||
// Scan-reliability messages from label.js's drawLabel/drawFallbackLabel (too few px per QR module, or too small in mm) - the label still rendered/prints fine, just flagged as a risk.
|
||||
warnings: [],
|
||||
|
||||
// One input per BASE_VARS entry; derived vars (userHandle/itemUrl/itemHandle) are calculated-only (see the `fields` computed), never stored here. Prefilled from query params but left editable.
|
||||
varValues: {
|
||||
|
|
@ -554,7 +561,7 @@ export default {
|
|||
},
|
||||
|
||||
async refreshDevices() {
|
||||
this.devices = (await navigator.usb.getDevices()).map((d) => markRaw(d));
|
||||
this.devices = (await printerManager.enumerateDevices()).map((d) => markRaw(d));
|
||||
/* A printer unplugged while open drops from the list: its handle is gone, so close the card rather than keep it open on a dead connection. */
|
||||
if (this.connected !== null && !this.devices.includes(this.connected)) {
|
||||
this.connected = null;
|
||||
|
|
@ -584,18 +591,32 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
// Only one open connection at a time: connecting a different printer disconnects the current one first.
|
||||
async connectToDevice(device) {
|
||||
await this.closeConnection();
|
||||
this.blob.setDevices([device]);
|
||||
await this.blob.open(device.vendorId, device.productId);
|
||||
this.connected = device;
|
||||
printerManager.savePreferredPrinter(device);
|
||||
const status = await this.blob.status();
|
||||
// Setting `tape` alone is enough to redraw - see the tape watcher above.
|
||||
this.tape = this.blob.can("print") ? tapeFromStatus(status) : null;
|
||||
},
|
||||
|
||||
connect(index) {
|
||||
this.guard(async () => {
|
||||
// Only one open connection at a time: connecting a different printer disconnects the current one first.
|
||||
await this.closeConnection();
|
||||
const device = this.devices[index];
|
||||
this.blob.setDevices([device]);
|
||||
await this.blob.open(device.vendorId, device.productId);
|
||||
this.connected = device;
|
||||
const status = await this.blob.status();
|
||||
// Setting `tape` alone is enough to redraw - see the tape watcher above.
|
||||
this.tape = this.blob.can("print") ? tapeFromStatus(status) : null;
|
||||
});
|
||||
this.guard(() => this.connectToDevice(this.devices[index]));
|
||||
},
|
||||
|
||||
// Auto-connects to the most-recently-used printer once it's paired and visible again (page
|
||||
// load, or plugged back in - see onUsbChange), mirroring cameraManager's preferred-camera
|
||||
// auto-select. Gated on "nothing connected yet" since a manual connect() to a different
|
||||
// paired printer shouldn't be silently overridden by a later device-list refresh.
|
||||
autoConnectPreferred() {
|
||||
if (this.connected) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const preferred = printerManager.findPreferredDevice(this.devices);
|
||||
return preferred ? this.connectToDevice(preferred) : Promise.resolve();
|
||||
},
|
||||
|
||||
disconnect() {
|
||||
|
|
@ -613,15 +634,16 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.resizeObserver.observe(canvas.parentElement);
|
||||
let textSizesPx;
|
||||
let textSizesPx, warnings;
|
||||
try {
|
||||
({textSizesPx} = drawLabel(canvas, this.tape, content, this.orientation));
|
||||
({textSizesPx, warnings} = drawLabel(canvas, this.tape, content, this.orientation));
|
||||
} catch (e) {
|
||||
this.error = e.message;
|
||||
return;
|
||||
}
|
||||
this.error = null;
|
||||
this.textSizesPx = textSizesPx;
|
||||
this.warnings = warnings;
|
||||
const bitmap = canvasToBitmap(canvas);
|
||||
bitmapToCanvas(canvas, bitmap);
|
||||
this.labelBitmap = bitmap;
|
||||
|
|
@ -640,13 +662,15 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.resizeObserver.observe(canvas.parentElement);
|
||||
let warnings;
|
||||
try {
|
||||
drawFallbackLabel(canvas, content, this.orientation);
|
||||
({warnings} = drawFallbackLabel(canvas, content, this.orientation));
|
||||
} catch (e) {
|
||||
this.error = e.message;
|
||||
return;
|
||||
}
|
||||
this.error = null;
|
||||
this.warnings = warnings;
|
||||
this.fallbackReady = true;
|
||||
this.fitZoom(canvas);
|
||||
},
|
||||
|
|
@ -700,7 +724,10 @@ export default {
|
|||
},
|
||||
|
||||
onUsbChange() {
|
||||
this.guard(() => this.refreshDevices());
|
||||
this.guard(async () => {
|
||||
await this.refreshDevices();
|
||||
await this.autoConnectPreferred();
|
||||
});
|
||||
},
|
||||
|
||||
// Works around Vue's refInFor array-collecting behavior for :ref in v-for, same as LabelLayoutPreview.vue's setTemplateCanvasRef.
|
||||
|
|
@ -779,7 +806,10 @@ export default {
|
|||
navigator.usb.addEventListener("connect", this.onUsbChange);
|
||||
navigator.usb.addEventListener("disconnect", this.onUsbChange);
|
||||
await qrReady;
|
||||
await this.guard(() => this.refreshDevices());
|
||||
await this.guard(async () => {
|
||||
await this.refreshDevices();
|
||||
await this.autoConnectPreferred();
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
if ("usb" in navigator) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue