191 lines
6.3 KiB
TypeScript
191 lines
6.3 KiB
TypeScript
import { defineStore } from "pinia"
|
|
import {
|
|
Utils,
|
|
RequestCommandId,
|
|
ResponseCommandId,
|
|
NiimbotBluetoothClient,
|
|
NiimbotSerialClient
|
|
} from "@mmote/niimbluelib"
|
|
import { useToast } from "#imports"
|
|
|
|
export const useLabelPrinterStore = defineStore("labelPrinter", {
|
|
state: () => ({
|
|
client: null as NiimbotBluetoothClient | NiimbotSerialClient | null,
|
|
connected: false,
|
|
connectLoading: false,
|
|
transportLastUsed: "",
|
|
printProgress: 0,
|
|
info: {} as any
|
|
}),
|
|
|
|
actions: {
|
|
|
|
/** Logging Helper */
|
|
logger(...args: any[]) {
|
|
console.debug("[Printer]", ...args)
|
|
},
|
|
|
|
/** --- Client erzeugen --- */
|
|
newClient(transport: "ble" | "serial" = "serial") {
|
|
const toast = useToast()
|
|
|
|
// alten Client trennen
|
|
if (this.client) {
|
|
try { this.client.disconnect() } catch {}
|
|
}
|
|
|
|
// neuen Client erzeugen
|
|
this.client =
|
|
transport === "ble"
|
|
? new NiimbotBluetoothClient()
|
|
: new NiimbotSerialClient()
|
|
|
|
/** Events registrieren */
|
|
|
|
this.client.on("printerinfofetched", (e) => {
|
|
console.log("printerInfoFetched")
|
|
console.log(e.info)
|
|
this.info = e.info
|
|
})
|
|
|
|
this.client.on("connect", () => {
|
|
this.connected = true
|
|
toast.add({ title: "Drucker verbunden" })
|
|
this.logger("connected")
|
|
})
|
|
|
|
this.client.on("disconnect", () => {
|
|
this.connected = false
|
|
toast.add({ title: "Drucker getrennt" })
|
|
this.logger("disconnected")
|
|
})
|
|
|
|
this.client.on("printprogress", (e) => {
|
|
if (e.pagePrintProgress) this.printProgress = e.pagePrintProgress
|
|
this.logger(
|
|
`Page ${e.page}/${e.pagesTotal}, Page print ${e.pagePrintProgress}%, Page feed ${e.pageFeedProgress}%`
|
|
)
|
|
})
|
|
|
|
return this.client
|
|
},
|
|
|
|
/** --- Verbinden --- */
|
|
async connect(transport: "ble" | "serial" = "serial") {
|
|
const toast = useToast()
|
|
|
|
this.connectLoading = true
|
|
|
|
this.newClient(transport)
|
|
|
|
try {
|
|
await this.client!.connect()
|
|
this.transportLastUsed = transport
|
|
this.connectLoading = false
|
|
} catch (err) {
|
|
console.error("[Printer] Connect failed:", err)
|
|
toast.add({ title: "Verbindung fehlgeschlagen", color: "red" })
|
|
this.connectLoading = false
|
|
}
|
|
},
|
|
|
|
/** --- Trennen --- */
|
|
async disconnect({ forget = false } = {}) {
|
|
const toast = useToast()
|
|
this.logger("Disconnect requested…")
|
|
|
|
if (!this.client) return
|
|
|
|
try {
|
|
// Timer stoppen
|
|
try {
|
|
if (this.client.heartbeatTimer) {
|
|
clearInterval(this.client.heartbeatTimer)
|
|
this.client.heartbeatTimer = null
|
|
}
|
|
if (this.client.abstraction?.statusPollTimer) {
|
|
clearInterval(this.client.abstraction.statusPollTimer)
|
|
this.client.abstraction.statusPollTimer = null
|
|
}
|
|
} catch {}
|
|
|
|
await this.client.disconnect?.()
|
|
|
|
// Serial-Port schließen
|
|
const port = (this.client as any).port
|
|
if (port) {
|
|
try {
|
|
if (port.readable) port.readable.cancel?.()
|
|
if (port.writable) await port.writable.abort?.()
|
|
await port.close?.()
|
|
|
|
if (forget && navigator.serial?.forgetPort) {
|
|
await navigator.serial.forgetPort(port)
|
|
}
|
|
} catch (err) {
|
|
this.logger("Error closing port:", err)
|
|
}
|
|
}
|
|
|
|
// BLE GATT
|
|
if (
|
|
this.client instanceof NiimbotBluetoothClient &&
|
|
this.client.device?.gatt?.connected
|
|
) {
|
|
try {
|
|
this.client.device.gatt.disconnect()
|
|
} catch {}
|
|
}
|
|
|
|
this.connected = false
|
|
this.client = null
|
|
toast.add({ title: "Drucker getrennt" })
|
|
} catch (err) {
|
|
console.error("[Printer] Disconnect error", err)
|
|
toast.add({ title: "Fehler beim Trennen", color: "red" })
|
|
}
|
|
},
|
|
|
|
/** Hilfsfunktion: EncodedImage reparieren */
|
|
reviveEncodedImage(encoded: any) {
|
|
if (!encoded?.rowsData) return encoded
|
|
for (const row of encoded.rowsData) {
|
|
if (row.rowData && !(row.rowData instanceof Uint8Array)) {
|
|
row.rowData = new Uint8Array(Object.values(row.rowData))
|
|
}
|
|
}
|
|
return encoded
|
|
},
|
|
|
|
/** --- Drucken --- */
|
|
async print(encoded: any, options?: { density?: number; pages?: number }) {
|
|
const toast = useToast()
|
|
|
|
if (!this.client) throw new Error("Kein Drucker verbunden")
|
|
|
|
const fixed = this.reviveEncodedImage(encoded)
|
|
const taskName = this.client.getPrintTaskType() ?? "B1"
|
|
|
|
const task = this.client.abstraction.newPrintTask(taskName, {
|
|
totalPages: options?.pages ?? 1,
|
|
statusPollIntervalMs: 100,
|
|
statusTimeoutMs: 8000,
|
|
density: options?.density ?? 5
|
|
})
|
|
|
|
try {
|
|
this.printProgress = 0
|
|
await task.printInit()
|
|
await task.printPage(fixed, options?.pages ?? 1)
|
|
await task.waitForFinished()
|
|
toast.add({ title: "Druck abgeschlossen" })
|
|
} catch (e) {
|
|
console.error("[Printer] print error", e)
|
|
toast.add({ title: "Druckfehler", color: "red" })
|
|
} finally {
|
|
await task.printEnd()
|
|
}
|
|
}
|
|
}
|
|
})
|