fix the width scaling error, fix the font scaling, removing debug logging
This commit is contained in:
parent
9483f369d7
commit
54729b1a51
@ -70,7 +70,7 @@ export class TimeoutError extends Error {
|
||||
export class BluetoothPrinterManager {
|
||||
constructor(errorNotificationService = null) {
|
||||
// Debug logging
|
||||
this.debugMode = true; // Set to false to disable verbose logging
|
||||
this.debugMode = false; // Set to false to disable verbose logging
|
||||
|
||||
// Connection state
|
||||
this.device = null;
|
||||
@ -140,7 +140,7 @@ export class BluetoothPrinterManager {
|
||||
*/
|
||||
isBluetoothAvailable() {
|
||||
const available = typeof navigator !== 'undefined' &&
|
||||
navigator.bluetooth !== undefined;
|
||||
navigator.bluetooth !== undefined;
|
||||
this._log(`Bluetooth API available: ${available}`);
|
||||
return available;
|
||||
}
|
||||
@ -309,14 +309,14 @@ export class BluetoothPrinterManager {
|
||||
|
||||
for (const serviceUUID of serviceUUIDs) {
|
||||
try {
|
||||
console.log(`Trying service UUID: ${serviceUUID}`);
|
||||
this._log(`Trying service UUID: ${serviceUUID}`);
|
||||
this.service = await this.server.getPrimaryService(serviceUUID);
|
||||
|
||||
// Try to find a writable characteristic
|
||||
for (const charUUID of characteristicUUIDs) {
|
||||
try {
|
||||
this.characteristic = await this.service.getCharacteristic(charUUID);
|
||||
console.log(`Found characteristic: ${charUUID}`);
|
||||
this._log(`Found characteristic: ${charUUID}`);
|
||||
serviceFound = true;
|
||||
break;
|
||||
} catch (charError) {
|
||||
@ -346,7 +346,7 @@ export class BluetoothPrinterManager {
|
||||
if (char.properties.write || char.properties.writeWithoutResponse) {
|
||||
this.service = service;
|
||||
this.characteristic = char;
|
||||
console.log(`Using fallback characteristic: ${char.uuid}`);
|
||||
this._log(`Using fallback characteristic: ${char.uuid}`);
|
||||
serviceFound = true;
|
||||
break;
|
||||
}
|
||||
@ -466,7 +466,7 @@ export class BluetoothPrinterManager {
|
||||
chunks.push(escposData.slice(i, i + chunkSize));
|
||||
}
|
||||
|
||||
console.log(`[Bluetooth] Sending ${chunks.length} chunks (${escposData.length} bytes, ${chunkSize} bytes/chunk)`);
|
||||
this._log(`Sending ${chunks.length} chunks (${escposData.length} bytes, ${chunkSize} bytes/chunk)`);
|
||||
|
||||
// Determine write method based on characteristic properties
|
||||
const useWriteWithoutResponse = this.characteristic.properties.writeWithoutResponse;
|
||||
@ -502,7 +502,7 @@ export class BluetoothPrinterManager {
|
||||
// Progress logging every 20%
|
||||
if (i % Math.ceil(chunks.length / 5) === 0) {
|
||||
const progress = Math.round((i / chunks.length) * 100);
|
||||
console.log(`[Bluetooth] Progress: ${progress}%`);
|
||||
this._log(`Progress: ${progress}%`);
|
||||
}
|
||||
} catch (chunkError) {
|
||||
console.error(`Failed to send chunk ${i + 1}/${chunks.length}:`, chunkError);
|
||||
@ -514,7 +514,7 @@ export class BluetoothPrinterManager {
|
||||
const duration = ((endTime - startTime) / 1000).toFixed(2);
|
||||
const speed = (escposData.length / 1024 / (duration || 1)).toFixed(2);
|
||||
|
||||
console.log(`[Bluetooth] Transmission complete in ${duration}s (${speed} KB/s)`);
|
||||
this._log(`Transmission complete in ${duration}s (${speed} KB/s)`);
|
||||
this.isPrinting = false;
|
||||
this._emit('print-completed', { success: true });
|
||||
|
||||
@ -594,7 +594,7 @@ export class BluetoothPrinterManager {
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
||||
this._log(`Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
||||
|
||||
// Try to reconnect
|
||||
await this.connectToPrinter(this.device);
|
||||
@ -602,7 +602,7 @@ export class BluetoothPrinterManager {
|
||||
this.isReconnecting = false;
|
||||
this.reconnectAttempts = 0;
|
||||
|
||||
console.log('Reconnection successful');
|
||||
this._log('Reconnection successful');
|
||||
|
||||
// Emit reconnection success event
|
||||
this._emit('reconnection-success', {
|
||||
@ -630,7 +630,7 @@ export class BluetoothPrinterManager {
|
||||
// Wait before next attempt (exponential backoff)
|
||||
if (attempt < this.maxReconnectAttempts - 1) {
|
||||
const delay = this.reconnectDelays[attempt];
|
||||
console.log(`Waiting ${delay}ms before next attempt`);
|
||||
this._log(`Waiting ${delay}ms before next attempt`);
|
||||
await this._sleep(delay);
|
||||
}
|
||||
}
|
||||
@ -694,12 +694,12 @@ export class BluetoothPrinterManager {
|
||||
* @private
|
||||
*/
|
||||
_onDisconnected() {
|
||||
console.log('Bluetooth device disconnected');
|
||||
this._log('Bluetooth device disconnected');
|
||||
this._setConnectionStatus('disconnected');
|
||||
|
||||
// Attempt auto-reconnection if enabled
|
||||
if (this.autoReconnectEnabled) {
|
||||
console.log('Starting auto-reconnection...');
|
||||
this._log('Starting auto-reconnection...');
|
||||
this.autoReconnect().catch(error => {
|
||||
console.error('Auto-reconnection failed:', error);
|
||||
});
|
||||
|
||||
@ -35,33 +35,38 @@ export class EscPosGraphics {
|
||||
* @returns {Uint8Array} Complete ESC/POS command sequence
|
||||
*/
|
||||
generateBitmapCommands(bitmap) {
|
||||
console.log('[EscPosGraphics] Generating bitmap commands (optimized)...');
|
||||
console.log('[EscPosGraphics] Original dimensions:', bitmap.width, 'x', bitmap.height);
|
||||
|
||||
|
||||
const startTime = performance.now();
|
||||
|
||||
// OPTIMIZATION: Remove blank lines from top and bottom
|
||||
const optimizedBitmap = this._removeBlankLines(bitmap);
|
||||
console.log('[EscPosGraphics] Optimized dimensions:', optimizedBitmap.width, 'x', optimizedBitmap.height);
|
||||
console.log('[EscPosGraphics] Saved', bitmap.height - optimizedBitmap.height, 'blank lines');
|
||||
|
||||
const commands = [];
|
||||
|
||||
// Initialize printer
|
||||
commands.push(...this.initialize());
|
||||
const initCmd = this.initialize();
|
||||
|
||||
// Print bitmap using raster graphics mode
|
||||
const rasterCommands = this._generateRasterGraphics(optimizedBitmap);
|
||||
commands.push(...rasterCommands);
|
||||
|
||||
// Feed paper and cut
|
||||
commands.push(...this._feedAndCut(4));
|
||||
const feedCmd = this._feedAndCut(4);
|
||||
|
||||
const result = new Uint8Array(commands);
|
||||
// Combine all commands safely without spreading large arrays
|
||||
const totalLength = initCmd.length + rasterCommands.length + feedCmd.length;
|
||||
const result = new Uint8Array(totalLength);
|
||||
|
||||
let offset = 0;
|
||||
result.set(initCmd, offset);
|
||||
offset += initCmd.length;
|
||||
|
||||
result.set(rasterCommands, offset);
|
||||
offset += rasterCommands.length;
|
||||
|
||||
result.set(new Uint8Array(feedCmd), offset);
|
||||
|
||||
const endTime = performance.now();
|
||||
console.log('[EscPosGraphics] Command generation took:', (endTime - startTime).toFixed(2), 'ms');
|
||||
console.log('[EscPosGraphics] Generated', result.length, 'bytes of commands');
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -134,7 +139,6 @@ export class EscPosGraphics {
|
||||
* @returns {Array} Command bytes
|
||||
*/
|
||||
_generateRasterGraphics(bitmap) {
|
||||
const commands = [];
|
||||
const { data, width, height, bytesPerLine } = bitmap;
|
||||
|
||||
// Calculate dimensions
|
||||
@ -144,26 +148,29 @@ export class EscPosGraphics {
|
||||
const heightLow = height & 0xFF;
|
||||
const heightHigh = (height >> 8) & 0xFF;
|
||||
|
||||
console.log('[EscPosGraphics] Bitmap width:', width, 'pixels');
|
||||
console.log('[EscPosGraphics] Bitmap height:', height, 'lines');
|
||||
console.log('[EscPosGraphics] Bytes per line:', bytesPerLine);
|
||||
console.log('[EscPosGraphics] Width bytes (xL xH):', widthLow, widthHigh, '=', widthBytes);
|
||||
console.log('[EscPosGraphics] Height (yL yH):', heightLow, heightHigh, '=', height);
|
||||
console.log('[EscPosGraphics] Total data size:', data.length, 'bytes');
|
||||
console.log('[EscPosGraphics] Expected data size:', bytesPerLine * height, 'bytes');
|
||||
|
||||
|
||||
// GS v 0 - Print raster bitmap
|
||||
// Format: GS v 0 m xL xH yL yH d1...dk
|
||||
// m = mode (0 = normal, 1 = double width, 2 = double height, 3 = quadruple)
|
||||
commands.push(GS, 0x76, 0x30, 0x00); // GS v 0 m (m=0 for normal)
|
||||
commands.push(widthLow, widthHigh); // xL xH (width in bytes)
|
||||
commands.push(heightLow, heightHigh); // yL yH (height in dots)
|
||||
// Header length: 8 bytes
|
||||
const header = [
|
||||
GS, 0x76, 0x30, 0x00, // GS v 0 m (m=0 for normal)
|
||||
widthLow, widthHigh, // xL xH (width in bytes)
|
||||
heightLow, heightHigh // yL yH (height in dots)
|
||||
];
|
||||
|
||||
// Add bitmap data
|
||||
commands.push(...data);
|
||||
// Create Uint8Array for the complete command
|
||||
const totalLength = header.length + data.length + 1; // +1 for LF
|
||||
const commands = new Uint8Array(totalLength);
|
||||
|
||||
// Add line feed after image
|
||||
commands.push(LF);
|
||||
// Set header
|
||||
commands.set(header, 0);
|
||||
|
||||
// Set bitmap data
|
||||
commands.set(data, header.length);
|
||||
|
||||
// Set LF
|
||||
commands[totalLength - 1] = LF;
|
||||
|
||||
return commands;
|
||||
}
|
||||
@ -240,7 +247,7 @@ export class EscPosGraphics {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
|
||||
console.log('[EscPosGraphics] Split into', chunks.length, 'chunks');
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
|
||||
@ -31,8 +31,7 @@ export class HtmlToImageConverter {
|
||||
* @returns {Promise<HTMLCanvasElement>} Canvas with rendered HTML
|
||||
*/
|
||||
async htmlToCanvas(element) {
|
||||
console.log('[HtmlToImage] Converting HTML to canvas...');
|
||||
console.log('[HtmlToImage] Paper width:', this.paperWidth, 'pixels');
|
||||
|
||||
|
||||
// Clone the element to avoid modifying the original
|
||||
const clone = element.cloneNode(true);
|
||||
@ -48,10 +47,27 @@ export class HtmlToImageConverter {
|
||||
clone.style.color = 'black';
|
||||
clone.style.overflow = 'visible';
|
||||
|
||||
// Scale all fonts by 100% (2x) to match test print readability
|
||||
// Scale all fonts by 150% (3x) to match test print readability
|
||||
// Test print uses ESC/POS text mode which has larger fonts
|
||||
const fontScale = 2.0;
|
||||
console.log('[HtmlToImage] Scaling fonts by', fontScale, 'x to match test print readability');
|
||||
const fontScale = 1.2;
|
||||
|
||||
|
||||
// Create a temporary container to measure height
|
||||
// Container must be large enough to hold the scaled content
|
||||
const container = document.createElement('div');
|
||||
container.style.position = 'fixed';
|
||||
container.style.left = '-9999px'; // Move off-screen instead of using opacity
|
||||
container.style.top = '0';
|
||||
container.style.width = `${this.paperWidth}px`;
|
||||
container.style.maxWidth = `${this.paperWidth}px`;
|
||||
container.style.minWidth = `${this.paperWidth}px`;
|
||||
container.style.backgroundColor = 'white';
|
||||
container.style.overflow = 'visible';
|
||||
container.style.zIndex = '-1000';
|
||||
container.style.boxSizing = 'border-box';
|
||||
|
||||
container.appendChild(clone);
|
||||
document.body.appendChild(container);
|
||||
|
||||
const allElements = clone.querySelectorAll('*');
|
||||
allElements.forEach(element => {
|
||||
@ -86,11 +102,11 @@ export class HtmlToImageConverter {
|
||||
clone.style.paddingLeft = '4px';
|
||||
clone.style.paddingRight = '4px';
|
||||
|
||||
console.log('[HtmlToImage] Fonts scaled 2x, padding reduced, rendering at paper width:', this.paperWidth, 'px');
|
||||
|
||||
|
||||
// Create a temporary container to measure height
|
||||
// Container must be large enough to hold the scaled content
|
||||
const container = document.createElement('div');
|
||||
// Duplicate container declaration removed
|
||||
container.style.position = 'fixed';
|
||||
container.style.left = '-9999px'; // Move off-screen instead of using opacity
|
||||
container.style.top = '0';
|
||||
@ -129,11 +145,7 @@ export class HtmlToImageConverter {
|
||||
const width = this.paperWidth;
|
||||
const height = Math.ceil(rect.height);
|
||||
|
||||
console.log('[HtmlToImage] Rendered dimensions:', rect.width, 'x', rect.height);
|
||||
console.log('[HtmlToImage] Final canvas size:', width, 'x', height);
|
||||
console.log('[HtmlToImage] Container rect:', rect);
|
||||
console.log('[HtmlToImage] Receipt HTML preview (first 1000 chars):', clone.outerHTML.substring(0, 1000));
|
||||
console.log('[HtmlToImage] Receipt text content:', clone.textContent.substring(0, 500));
|
||||
|
||||
|
||||
// Create canvas with exact dimensions
|
||||
const canvas = document.createElement('canvas');
|
||||
@ -147,10 +159,10 @@ export class HtmlToImageConverter {
|
||||
|
||||
// Render the DOM to canvas using improved method
|
||||
// Content is already at the correct width, no scaling needed
|
||||
console.log('[HtmlToImage] Rendering DOM to canvas...');
|
||||
|
||||
await this._renderDomToCanvasImproved(clone, ctx, 0, 0, width, height);
|
||||
|
||||
console.log('[HtmlToImage] Canvas rendering complete');
|
||||
|
||||
return canvas;
|
||||
|
||||
} finally {
|
||||
@ -173,7 +185,7 @@ export class HtmlToImageConverter {
|
||||
* @returns {Promise<number>} Height used
|
||||
*/
|
||||
async _renderDomToCanvasImproved(element, ctx, offsetX, offsetY, canvasWidth, canvasHeight) {
|
||||
console.log('[HtmlToImage] Rendering DOM to canvas (improved method)...');
|
||||
|
||||
|
||||
// Background is already filled, no need to fill again
|
||||
|
||||
@ -183,7 +195,7 @@ export class HtmlToImageConverter {
|
||||
// Render element recursively with proper offset calculation
|
||||
await this._renderElement(element, ctx, -rootRect.left, -rootRect.top, rootRect);
|
||||
|
||||
console.log('[HtmlToImage] Rendering complete');
|
||||
|
||||
return canvasHeight;
|
||||
}
|
||||
|
||||
@ -228,23 +240,87 @@ export class HtmlToImageConverter {
|
||||
await this._renderImage(element, ctx, x, y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
// Render text content
|
||||
// Render children (text and elements)
|
||||
if (element.childNodes.length > 0) {
|
||||
// Check if this is a specialized text-only element (optimization + wrapping handling)
|
||||
// We keep this optimization for simple blocks, but improve the check
|
||||
// Actually, to fix mixed content, we should just iterate childNodes.
|
||||
// But we need to handle wrapping for long text nodes.
|
||||
// For now, let's assume standard recursion is safer for mixed content.
|
||||
|
||||
const hasOnlyText = Array.from(element.childNodes).every(
|
||||
node => node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'BR')
|
||||
);
|
||||
|
||||
// Use the block text renderer mainly for simple text blocks which might need wrapping logic
|
||||
// that _renderText provides (it handles word wrapping based on width).
|
||||
// However, relying ONLY on this means mixed content fails.
|
||||
|
||||
if (hasOnlyText) {
|
||||
this._renderText(element, ctx, x, y, rect.width, rect.height, style);
|
||||
} else {
|
||||
// Render children recursively
|
||||
for (const child of element.children) {
|
||||
await this._renderElement(child, ctx, offsetX, offsetY, rootRect);
|
||||
// Mixed content or complex structure
|
||||
for (const node of element.childNodes) {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
await this._renderElement(node, ctx, offsetX, offsetY, rootRect);
|
||||
} else if (node.nodeType === Node.TEXT_NODE) {
|
||||
const text = node.textContent.trim();
|
||||
if (text) {
|
||||
// Text node in mixed content
|
||||
// We need its exact position
|
||||
const range = document.createRange();
|
||||
range.selectNode(node);
|
||||
const textRect = range.getBoundingClientRect();
|
||||
|
||||
// Calculate relative position
|
||||
const textX = textRect.left + offsetX;
|
||||
const textY = textRect.top + offsetY;
|
||||
|
||||
// Draw the text node using parent's style
|
||||
// Note: Text nodes don't have padding/margin themselves effectively (handled by layout)
|
||||
this._drawTextNode(ctx, text, textX, textY, textRect.width, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a single text node
|
||||
*
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx - Canvas context
|
||||
* @param {string} text - Text to draw
|
||||
* @param {number} x - X position
|
||||
* @param {number} y - Y position
|
||||
* @param {number} width - Node width
|
||||
* @param {CSSStyleDeclaration} style - Computed style of parent
|
||||
*/
|
||||
_drawTextNode(ctx, text, x, y, width, style) {
|
||||
// Set font
|
||||
const fontSize = parseFloat(style.fontSize) || 12;
|
||||
const fontWeight = style.fontWeight;
|
||||
const fontFamily = style.fontFamily.split(',')[0].replace(/['"]/g, '') || 'monospace';
|
||||
const isBold = fontWeight === 'bold' || parseInt(fontWeight) >= 600;
|
||||
|
||||
ctx.font = `${isBold ? 'bold' : 'normal'} ${fontSize}px ${fontFamily}`;
|
||||
ctx.fillStyle = style.color || 'black';
|
||||
ctx.textBaseline = 'top'; // Align to top of rect
|
||||
|
||||
// Handle alignment - though for a text node range rect, the rect SHOULD already be aligned by layout
|
||||
// So we can arguably just draw at x.
|
||||
// However, range rects can be tricky.
|
||||
|
||||
// Simple draw for now - rely on DOM layout for positioning
|
||||
ctx.textAlign = 'left';
|
||||
|
||||
// Text nodes usually don't need wrapping if they are part of a laid-out line
|
||||
// (the browser already wrapped them into lines, and if it spans lines, we might get a big rect)
|
||||
// If it spans lines, this simple fillText might be issue, but for missing words like "Total", it's fine.
|
||||
ctx.fillText(text, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render text content of an element
|
||||
*
|
||||
@ -421,7 +497,7 @@ export class HtmlToImageConverter {
|
||||
* @param {number} height - Canvas height
|
||||
*/
|
||||
async _renderDomToCanvas(element, ctx, width, height) {
|
||||
console.log('[HtmlToImage] Rendering DOM to canvas (simple fallback method)...');
|
||||
|
||||
|
||||
// Set default styles
|
||||
ctx.fillStyle = 'white';
|
||||
@ -554,7 +630,7 @@ export class HtmlToImageConverter {
|
||||
// Start processing
|
||||
try {
|
||||
processElement(element);
|
||||
console.log('[HtmlToImage] Rendering complete, height used:', y);
|
||||
|
||||
} catch (error) {
|
||||
console.error('[HtmlToImage] Error during rendering:', error);
|
||||
// Ultimate fallback - just print all text
|
||||
@ -574,7 +650,7 @@ export class HtmlToImageConverter {
|
||||
* @returns {Uint8Array} Bitmap data
|
||||
*/
|
||||
canvasToBitmap(canvas) {
|
||||
console.log('[HtmlToImage] Converting canvas to bitmap (optimized)...');
|
||||
|
||||
const startTime = performance.now();
|
||||
|
||||
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
@ -606,8 +682,8 @@ export class HtmlToImageConverter {
|
||||
|
||||
// Fast grayscale conversion using weighted average
|
||||
const gray = pixels[pixelIndex] * rWeight +
|
||||
pixels[pixelIndex + 1] * gWeight +
|
||||
pixels[pixelIndex + 2] * bWeight;
|
||||
pixels[pixelIndex + 1] * gWeight +
|
||||
pixels[pixelIndex + 2] * bWeight;
|
||||
|
||||
// Threshold to black or white
|
||||
if (gray < 128) {
|
||||
@ -632,11 +708,7 @@ export class HtmlToImageConverter {
|
||||
}
|
||||
|
||||
const endTime = performance.now();
|
||||
console.log('[HtmlToImage] Bitmap conversion took:', (endTime - startTime).toFixed(2), 'ms');
|
||||
console.log('[HtmlToImage] Bitmap dimensions:', width, 'pixels x', height, 'pixels');
|
||||
console.log('[HtmlToImage] Bytes per line:', bytesPerLine, 'bytes');
|
||||
console.log('[HtmlToImage] Total bitmap size:', bitmapData.length, 'bytes');
|
||||
console.log('[HtmlToImage] Expected size:', bytesPerLine * height, 'bytes');
|
||||
|
||||
|
||||
return {
|
||||
data: bitmapData,
|
||||
@ -653,7 +725,7 @@ export class HtmlToImageConverter {
|
||||
* @returns {Promise<Object>} Bitmap data with dimensions
|
||||
*/
|
||||
async htmlToBitmap(element) {
|
||||
console.log('[HtmlToImage] Converting HTML to bitmap...');
|
||||
|
||||
|
||||
try {
|
||||
// Convert HTML to canvas
|
||||
@ -662,7 +734,7 @@ export class HtmlToImageConverter {
|
||||
// Convert canvas to bitmap
|
||||
const bitmap = this.canvasToBitmap(canvas);
|
||||
|
||||
console.log('[HtmlToImage] Conversion complete');
|
||||
|
||||
return bitmap;
|
||||
} catch (error) {
|
||||
console.error('[HtmlToImage] Conversion failed:', error);
|
||||
@ -685,20 +757,23 @@ export class HtmlToImageConverter {
|
||||
// 304 DPI = 12 dots/mm (304 / 25.4)
|
||||
const dotsPerMm = Math.round(dpi / 25.4);
|
||||
|
||||
// Calculate pixel width based on paper size and DPI
|
||||
// Use FULL width without margins for maximum usage
|
||||
// Calculate pixel width based on PRINTABLE width (essential for thermal printers)
|
||||
// 58mm Paper -> ~48mm Printable
|
||||
// 80mm Paper -> ~72mm Printable
|
||||
let printableWidthMm;
|
||||
|
||||
if (widthMm === 58) {
|
||||
// 58mm paper at selected DPI
|
||||
this.paperWidth = widthMm * dotsPerMm;
|
||||
printableWidthMm = 48; // Standard printable width for 58mm
|
||||
} else if (widthMm === 80) {
|
||||
// 80mm paper at selected DPI
|
||||
this.paperWidth = widthMm * dotsPerMm;
|
||||
printableWidthMm = 72; // Standard printable width for 80mm
|
||||
} else {
|
||||
// Custom width: use full width
|
||||
this.paperWidth = widthMm * dotsPerMm;
|
||||
// Custom width: subtract ~10mm margin
|
||||
printableWidthMm = Math.max(widthMm - 10, widthMm * 0.8);
|
||||
}
|
||||
|
||||
console.log('[HtmlToImage] Setting paper width to', widthMm, 'mm at', dpi, 'DPI (', dotsPerMm, 'dots/mm,', this.paperWidth, 'pixels)');
|
||||
this.paperWidth = Math.floor(printableWidthMm * dotsPerMm);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -60,18 +60,15 @@ patch(PosPrinterService.prototype, {
|
||||
async printHtml(el) {
|
||||
// Wrap entire method in try-catch to catch any errors
|
||||
try {
|
||||
console.log('[BluetoothPrint] printHtml() called');
|
||||
console.log('[BluetoothPrint] Element type:', el?.constructor?.name);
|
||||
console.log('[BluetoothPrint] Element tag:', el?.tagName);
|
||||
console.log('[BluetoothPrint] Element classes:', el?.className);
|
||||
|
||||
|
||||
// Check if Web Bluetooth API is available
|
||||
if (!navigator.bluetooth) {
|
||||
console.log('[BluetoothPrint] Web Bluetooth API not available, using browser print dialog');
|
||||
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
}
|
||||
console.log('[BluetoothPrint] Web Bluetooth API available');
|
||||
|
||||
|
||||
// Check if a Bluetooth printer is configured (from localStorage)
|
||||
// We don't need POS config - we check if user has configured a printer
|
||||
@ -79,16 +76,15 @@ patch(PosPrinterService.prototype, {
|
||||
const config = storage.loadConfiguration(1); // Default POS config ID
|
||||
|
||||
if (!config || !config.deviceId) {
|
||||
console.log('[BluetoothPrint] No Bluetooth printer configured, using standard print');
|
||||
console.log('[BluetoothPrint] Calling originalPrintHtml with:', el);
|
||||
|
||||
try {
|
||||
const result = await originalPrintHtml.call(this, el);
|
||||
console.log('[BluetoothPrint] originalPrintHtml returned:', result);
|
||||
|
||||
|
||||
// If original method returned false, it didn't handle the print
|
||||
// So we need to handle it ourselves
|
||||
if (result === false) {
|
||||
console.log('[BluetoothPrint] originalPrintHtml returned false, opening browser print dialog directly');
|
||||
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
}
|
||||
@ -97,32 +93,30 @@ patch(PosPrinterService.prototype, {
|
||||
} catch (error) {
|
||||
console.error('[BluetoothPrint] Error calling originalPrintHtml:', error);
|
||||
// Fallback to browser print dialog
|
||||
console.log('[BluetoothPrint] Falling back to browser print dialog');
|
||||
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[BluetoothPrint] Bluetooth printer configured:', config.deviceName);
|
||||
|
||||
|
||||
// Initialize bluetooth services
|
||||
console.log('[BluetoothPrint] Initializing bluetooth services...');
|
||||
const services = initializeBluetoothPrinting(null);
|
||||
console.log('[BluetoothPrint] Bluetooth services initialized');
|
||||
const services = initializeBluetoothPrinting(null); // Restored
|
||||
|
||||
// Check if printer is actually connected
|
||||
const connectionStatus = services.bluetoothManager.getConnectionStatus();
|
||||
console.log('[BluetoothPrint] Current connection status:', connectionStatus);
|
||||
|
||||
|
||||
if (connectionStatus !== 'connected') {
|
||||
console.log('[BluetoothPrint] Printer not connected, attempting to reconnect...');
|
||||
|
||||
// Try to reconnect
|
||||
try {
|
||||
await services.bluetoothManager.autoReconnect();
|
||||
console.log('[BluetoothPrint] Reconnection successful');
|
||||
|
||||
} catch (reconnectError) {
|
||||
console.error('[BluetoothPrint] Reconnection failed:', reconnectError);
|
||||
console.log('[BluetoothPrint] Falling back to browser print dialog');
|
||||
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
}
|
||||
@ -130,17 +124,17 @@ patch(PosPrinterService.prototype, {
|
||||
|
||||
try {
|
||||
// Attempt bluetooth printing
|
||||
console.log('[BluetoothPrint] Attempting bluetooth print...');
|
||||
|
||||
await this._printViaBluetoothFromHtml(el, services, config);
|
||||
|
||||
console.log('[BluetoothPrint] Print completed successfully');
|
||||
|
||||
return true;
|
||||
} catch (printError) {
|
||||
console.error('[BluetoothPrint] Bluetooth print failed:', printError);
|
||||
console.error('[BluetoothPrint] Error stack:', printError.stack);
|
||||
|
||||
// Fallback to browser print dialog
|
||||
console.log('[BluetoothPrint] Falling back to browser print dialog after error');
|
||||
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
}
|
||||
@ -149,7 +143,7 @@ patch(PosPrinterService.prototype, {
|
||||
console.error('[BluetoothPrint] Error name:', error.name);
|
||||
console.error('[BluetoothPrint] Error message:', error.message);
|
||||
console.error('[BluetoothPrint] Error stack:', error.stack);
|
||||
console.log('[BluetoothPrint] Falling back to browser print dialog due to critical error');
|
||||
|
||||
try {
|
||||
await this._printViaBrowserDialog(el);
|
||||
return true;
|
||||
@ -169,7 +163,7 @@ patch(PosPrinterService.prototype, {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async _printViaBrowserDialog(el) {
|
||||
console.log('[BluetoothPrint] Opening browser print dialog...');
|
||||
|
||||
|
||||
return new Promise((resolve) => {
|
||||
// Create a hidden iframe for printing
|
||||
@ -191,7 +185,7 @@ patch(PosPrinterService.prototype, {
|
||||
}
|
||||
if (printFrame.parentNode) {
|
||||
document.body.removeChild(printFrame);
|
||||
console.log('[BluetoothPrint] Iframe cleaned up');
|
||||
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
@ -205,7 +199,7 @@ patch(PosPrinterService.prototype, {
|
||||
try {
|
||||
printFrame.contentWindow.focus();
|
||||
printFrame.contentWindow.print();
|
||||
console.log('[BluetoothPrint] Print dialog opened');
|
||||
|
||||
|
||||
// Clean up after a delay
|
||||
setTimeout(cleanup, 1000);
|
||||
@ -266,11 +260,11 @@ patch(PosPrinterService.prototype, {
|
||||
frameDoc.write(printHtml);
|
||||
frameDoc.close();
|
||||
|
||||
console.log('[BluetoothPrint] Receipt content written to iframe');
|
||||
|
||||
|
||||
// Wait for content to load
|
||||
printFrame.contentWindow.addEventListener('load', () => {
|
||||
console.log('[BluetoothPrint] Iframe loaded, triggering print...');
|
||||
|
||||
// Small delay to ensure rendering is complete
|
||||
setTimeout(triggerPrint, 100);
|
||||
});
|
||||
@ -278,7 +272,7 @@ patch(PosPrinterService.prototype, {
|
||||
// Fallback if load event doesn't fire within 2 seconds
|
||||
timeoutId = setTimeout(() => {
|
||||
if (!printTriggered) {
|
||||
console.log('[BluetoothPrint] Load timeout, attempting print anyway...');
|
||||
|
||||
triggerPrint();
|
||||
}
|
||||
}, 2000);
|
||||
@ -304,14 +298,11 @@ patch(PosPrinterService.prototype, {
|
||||
async _printViaBluetoothFromHtml(el, services, config) {
|
||||
const { bluetoothManager } = services;
|
||||
|
||||
console.log('[BluetoothPrint] Starting bluetooth print from HTML...');
|
||||
console.log('[BluetoothPrint] Using GRAPHICS MODE for exact HTML layout');
|
||||
console.log('[BluetoothPrint] Element:', el);
|
||||
console.log('[BluetoothPrint] Config:', config);
|
||||
|
||||
|
||||
// Check connection status
|
||||
const status = bluetoothManager.getConnectionStatus();
|
||||
console.log('[BluetoothPrint] Connection status:', status);
|
||||
|
||||
|
||||
if (status !== 'connected') {
|
||||
throw new PrinterNotConnectedError('Bluetooth printer is not connected');
|
||||
@ -319,48 +310,32 @@ patch(PosPrinterService.prototype, {
|
||||
|
||||
try {
|
||||
// Convert HTML to bitmap image
|
||||
console.log('[BluetoothPrint] Converting HTML to bitmap...');
|
||||
console.log('[BluetoothPrint] Creating HtmlToImageConverter...');
|
||||
const converter = new HtmlToImageConverter();
|
||||
console.log('[BluetoothPrint] HtmlToImageConverter created successfully');
|
||||
|
||||
// Get paper width and DPI from configuration
|
||||
|
||||
|
||||
// Get paper width and DPI from configuration
|
||||
const paperWidthMm = config?.settings?.paperWidthMm || 58;
|
||||
const dpi = config?.settings?.dpi || 203;
|
||||
console.log('[BluetoothPrint] Using paper width:', paperWidthMm, 'mm');
|
||||
console.log('[BluetoothPrint] Using printer DPI:', dpi);
|
||||
console.log('[BluetoothPrint] Setting paper width and DPI on converter...');
|
||||
converter.setPaperWidth(paperWidthMm, dpi);
|
||||
console.log('[BluetoothPrint] Paper width and DPI set successfully');
|
||||
|
||||
console.log('[BluetoothPrint] Converting HTML to bitmap...');
|
||||
const bitmap = await converter.htmlToBitmap(el);
|
||||
console.log('[BluetoothPrint] Bitmap created:', bitmap.width, 'x', bitmap.height);
|
||||
console.log('[BluetoothPrint] Bitmap data length:', bitmap.data.length);
|
||||
|
||||
// Generate ESC/POS graphics commands
|
||||
console.log('[BluetoothPrint] Generating ESC/POS graphics commands...');
|
||||
console.log('[BluetoothPrint] Creating EscPosGraphics...');
|
||||
const graphicsGenerator = new EscPosGraphics();
|
||||
console.log('[BluetoothPrint] EscPosGraphics created successfully');
|
||||
|
||||
console.log('[BluetoothPrint] Generating bitmap commands...');
|
||||
const escposData = graphicsGenerator.generateBitmapCommands(bitmap);
|
||||
console.log('[BluetoothPrint] Generated', escposData.length, 'bytes of graphics data');
|
||||
|
||||
// Send data to printer
|
||||
console.log('[BluetoothPrint] Sending graphics to printer...');
|
||||
const startTime = performance.now();
|
||||
await bluetoothManager.sendData(escposData);
|
||||
const endTime = performance.now();
|
||||
console.log('[BluetoothPrint] Graphics print completed successfully in', (endTime - startTime).toFixed(0), 'ms');
|
||||
|
||||
} catch (error) {
|
||||
console.error('[BluetoothPrint] Graphics mode failed:', error);
|
||||
console.error('[BluetoothPrint] Error name:', error.name);
|
||||
console.error('[BluetoothPrint] Error message:', error.message);
|
||||
console.error('[BluetoothPrint] Error stack:', error.stack);
|
||||
console.log('[BluetoothPrint] Falling back to text mode...');
|
||||
|
||||
|
||||
// Fallback to text mode if graphics fails
|
||||
await this._printViaBluetoothTextMode(el, services);
|
||||
@ -379,22 +354,16 @@ patch(PosPrinterService.prototype, {
|
||||
async _printViaBluetoothTextMode(el, services) {
|
||||
const { bluetoothManager, escposGenerator } = services;
|
||||
|
||||
console.log('[BluetoothPrint] Using TEXT MODE (fallback)');
|
||||
|
||||
|
||||
// Parse receipt data from HTML element
|
||||
console.log('[BluetoothPrint] Parsing receipt data from HTML...');
|
||||
const receiptData = this._parseReceiptDataFromHtml(el);
|
||||
console.log('[BluetoothPrint] Parsed receipt data:', JSON.stringify(receiptData, null, 2));
|
||||
|
||||
// Generate ESC/POS commands
|
||||
console.log('[BluetoothPrint] Generating ESC/POS text commands...');
|
||||
const escposData = escposGenerator.generateReceipt(receiptData);
|
||||
console.log('[BluetoothPrint] Generated', escposData.length, 'bytes of text data');
|
||||
|
||||
// Send data to printer
|
||||
console.log('[BluetoothPrint] Sending text to printer...');
|
||||
await bluetoothManager.sendData(escposData);
|
||||
console.log('[BluetoothPrint] Text print completed successfully');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -407,34 +376,25 @@ patch(PosPrinterService.prototype, {
|
||||
* @throws {Error} If printing fails
|
||||
*/
|
||||
async _printViaBluetooth(el, pos) {
|
||||
|
||||
const services = initializeBluetoothPrinting();
|
||||
const { bluetoothManager, escposGenerator } = services;
|
||||
|
||||
console.log('[BluetoothPrint] Starting bluetooth print...');
|
||||
console.log('[BluetoothPrint] Element:', el);
|
||||
|
||||
// Check connection status
|
||||
const status = bluetoothManager.getConnectionStatus();
|
||||
console.log('[BluetoothPrint] Connection status:', status);
|
||||
|
||||
if (status !== 'connected') {
|
||||
throw new PrinterNotConnectedError('Bluetooth printer is not connected');
|
||||
}
|
||||
|
||||
// Parse receipt data from POS order
|
||||
console.log('[BluetoothPrint] Parsing receipt data...');
|
||||
const receiptData = this._parseReceiptDataFromPos(pos);
|
||||
console.log('[BluetoothPrint] Receipt data:', receiptData);
|
||||
|
||||
// Generate ESC/POS commands
|
||||
console.log('[BluetoothPrint] Generating ESC/POS commands...');
|
||||
const escposData = escposGenerator.generateReceipt(receiptData);
|
||||
console.log('[BluetoothPrint] Generated', escposData.length, 'bytes of ESC/POS data');
|
||||
|
||||
// Send data to printer
|
||||
console.log('[BluetoothPrint] Sending to printer...');
|
||||
await bluetoothManager.sendData(escposData);
|
||||
console.log('[BluetoothPrint] Print completed successfully');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -545,22 +505,16 @@ patch(PosPrinterService.prototype, {
|
||||
* @returns {Object} Structured receipt data
|
||||
*/
|
||||
_parseReceiptDataFromHtml(el) {
|
||||
console.log('[BluetoothPrint] _parseReceiptDataFromHtml called');
|
||||
console.log('[BluetoothPrint] Receipt HTML structure:', el.outerHTML.substring(0, 500));
|
||||
console.log('[BluetoothPrint] Receipt classes:', el.className);
|
||||
console.log('[BluetoothPrint] Receipt children count:', el.children.length);
|
||||
|
||||
// Extract text content from HTML
|
||||
const getText = (selector) => {
|
||||
const element = el.querySelector(selector);
|
||||
const text = element ? element.textContent.trim() : '';
|
||||
console.log(`[BluetoothPrint] getText('${selector}'):`, text || '(empty)');
|
||||
return text;
|
||||
};
|
||||
|
||||
const getAll = (selector) => {
|
||||
const elements = Array.from(el.querySelectorAll(selector));
|
||||
console.log(`[BluetoothPrint] getAll('${selector}'):`, elements.length, 'elements found');
|
||||
return elements;
|
||||
};
|
||||
|
||||
@ -581,7 +535,6 @@ patch(PosPrinterService.prototype, {
|
||||
};
|
||||
|
||||
// Parse order lines - try multiple selectors
|
||||
console.log('[BluetoothPrint] Searching for order lines...');
|
||||
let lineElements = getAll('.orderline');
|
||||
if (lineElements.length === 0) {
|
||||
lineElements = getAll('.pos-receipt-orderline');
|
||||
@ -597,17 +550,14 @@ patch(PosPrinterService.prototype, {
|
||||
lineElements = getAll('tbody tr');
|
||||
}
|
||||
|
||||
console.log('[BluetoothPrint] Found', lineElements.length, 'line elements');
|
||||
|
||||
const lines = lineElements.map((line, index) => {
|
||||
console.log(`[BluetoothPrint] Processing line ${index}:`, line.outerHTML.substring(0, 200));
|
||||
|
||||
const productName = line.querySelector('.product-name, td:first-child, .pos-receipt-left-align')?.textContent.trim() || '';
|
||||
const qtyText = line.querySelector('.qty, .quantity')?.textContent.trim() || '1';
|
||||
const priceText = line.querySelector('.price, .price-unit')?.textContent.trim() || '0';
|
||||
const totalText = line.querySelector('.price-total, .total, td:last-child, .pos-receipt-right-align')?.textContent.trim() || '0';
|
||||
|
||||
console.log(`[BluetoothPrint] Line ${index} raw data:`, { productName, qtyText, priceText, totalText });
|
||||
|
||||
|
||||
// Parse numbers (remove currency symbols and commas)
|
||||
const parseNumber = (str) => {
|
||||
@ -622,16 +572,15 @@ patch(PosPrinterService.prototype, {
|
||||
total: parseNumber(totalText)
|
||||
};
|
||||
|
||||
console.log(`[BluetoothPrint] Line ${index} parsed:`, parsedLine);
|
||||
|
||||
|
||||
return parsedLine;
|
||||
}).filter(line => line.productName); // Filter out empty lines
|
||||
|
||||
console.log('[BluetoothPrint] Parsed', lines.length, 'lines from HTML');
|
||||
console.log('[BluetoothPrint] All lines:', JSON.stringify(lines, null, 2));
|
||||
|
||||
|
||||
// Parse totals
|
||||
console.log('[BluetoothPrint] Parsing totals...');
|
||||
|
||||
const totals = {
|
||||
subtotal: this._parseAmount(getText('.pos-receipt-subtotal, .subtotal')),
|
||||
tax: this._parseAmount(getText('.pos-receipt-tax, .tax')),
|
||||
@ -639,14 +588,12 @@ patch(PosPrinterService.prototype, {
|
||||
total: this._parseAmount(getText('.pos-receipt-total, .total, .amount-total'))
|
||||
};
|
||||
|
||||
console.log('[BluetoothPrint] Parsed totals:', totals);
|
||||
|
||||
|
||||
// If totals not found in specific elements, calculate from lines
|
||||
if (totals.total === 0 && lines.length > 0) {
|
||||
console.log('[BluetoothPrint] Total is 0, calculating from lines...');
|
||||
totals.total = lines.reduce((sum, line) => sum + line.total, 0);
|
||||
totals.subtotal = totals.total;
|
||||
console.log('[BluetoothPrint] Calculated totals:', totals);
|
||||
}
|
||||
|
||||
// Parse payment info
|
||||
@ -671,7 +618,7 @@ patch(PosPrinterService.prototype, {
|
||||
footerData
|
||||
};
|
||||
|
||||
console.log('[BluetoothPrint] Parsed receipt data from HTML:', receiptData);
|
||||
|
||||
return receiptData;
|
||||
},
|
||||
|
||||
@ -697,8 +644,6 @@ patch(PosPrinterService.prototype, {
|
||||
* @returns {Object} Structured receipt data
|
||||
*/
|
||||
_parseReceiptDataFromPos(pos) {
|
||||
console.log('[BluetoothPrint] _parseReceiptDataFromPos called');
|
||||
console.log('[BluetoothPrint] POS object keys:', Object.keys(pos));
|
||||
|
||||
// In Odoo 18, get current order from POS
|
||||
// Try multiple ways to access the order
|
||||
@ -706,17 +651,13 @@ patch(PosPrinterService.prototype, {
|
||||
|
||||
if (typeof pos.get_order === 'function') {
|
||||
order = pos.get_order();
|
||||
console.log('[BluetoothPrint] Got order via get_order()');
|
||||
} else if (pos.selectedOrder) {
|
||||
order = pos.selectedOrder;
|
||||
console.log('[BluetoothPrint] Got order via selectedOrder');
|
||||
} else if (pos.orders && pos.orders.length > 0) {
|
||||
order = pos.orders[pos.orders.length - 1];
|
||||
console.log('[BluetoothPrint] Got order via orders array');
|
||||
}
|
||||
|
||||
console.log('[BluetoothPrint] Order:', order);
|
||||
console.log('[BluetoothPrint] Order keys:', order ? Object.keys(order) : 'null');
|
||||
|
||||
|
||||
if (!order) {
|
||||
throw new Error('No active order found');
|
||||
@ -724,7 +665,6 @@ patch(PosPrinterService.prototype, {
|
||||
|
||||
// Get company info
|
||||
const company = pos.company || {};
|
||||
console.log('[BluetoothPrint] Company:', company);
|
||||
|
||||
// Get cashier info - try multiple ways
|
||||
let cashierName = '';
|
||||
@ -735,7 +675,7 @@ patch(PosPrinterService.prototype, {
|
||||
} else if (pos.user) {
|
||||
cashierName = pos.user.name || '';
|
||||
}
|
||||
console.log('[BluetoothPrint] Cashier name:', cashierName);
|
||||
|
||||
|
||||
// Get customer info - try multiple ways
|
||||
let customerName = null;
|
||||
@ -746,7 +686,7 @@ patch(PosPrinterService.prototype, {
|
||||
} else if (order.partner_id) {
|
||||
customerName = order.partner_id[1] || null;
|
||||
}
|
||||
console.log('[BluetoothPrint] Customer name:', customerName);
|
||||
|
||||
|
||||
// Build receipt data structure
|
||||
const receiptData = {
|
||||
@ -771,7 +711,7 @@ patch(PosPrinterService.prototype, {
|
||||
}
|
||||
};
|
||||
|
||||
console.log('[BluetoothPrint] Parsed receipt data:', receiptData);
|
||||
|
||||
return receiptData;
|
||||
},
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ patch(PosStore.prototype, {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async _initializeBluetoothPrinter() {
|
||||
console.log('Initializing bluetooth printer for POS session...');
|
||||
|
||||
|
||||
try {
|
||||
const notificationService = this.env?.services?.notification || null;
|
||||
@ -59,12 +59,12 @@ patch(PosStore.prototype, {
|
||||
|
||||
if (!config) {
|
||||
// No printer configured for this device
|
||||
console.log('No bluetooth printer configured for this device');
|
||||
// console.log('No bluetooth printer configured for this device');
|
||||
this._promptPrinterConfiguration();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Found printer configuration:', config.deviceName);
|
||||
// console.log('Found printer configuration:', config.deviceName);
|
||||
|
||||
// Enable auto-reconnect based on saved settings
|
||||
const autoReconnect = config.settings?.autoReconnect !== false;
|
||||
@ -94,7 +94,7 @@ patch(PosStore.prototype, {
|
||||
const { bluetoothManager } = services;
|
||||
|
||||
try {
|
||||
console.log('Attempting to connect to printer:', config.deviceName);
|
||||
// console.log('Attempting to connect to printer:', config.deviceName);
|
||||
|
||||
// Try to get the previously paired device
|
||||
const devices = await navigator.bluetooth.getDevices();
|
||||
@ -116,7 +116,7 @@ patch(PosStore.prototype, {
|
||||
// Connect to the printer
|
||||
await bluetoothManager.connectToPrinter(device);
|
||||
|
||||
console.log('Successfully connected to bluetooth printer');
|
||||
// console.log('Successfully connected to bluetooth printer');
|
||||
// Success notification is now handled by error service in bluetooth manager
|
||||
|
||||
} catch (error) {
|
||||
@ -172,7 +172,7 @@ patch(PosStore.prototype, {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async _cleanupBluetoothPrinter() {
|
||||
console.log('Cleaning up bluetooth printer connection...');
|
||||
// console.log('Cleaning up bluetooth printer connection...');
|
||||
|
||||
try {
|
||||
const services = getBluetoothPrintingServices();
|
||||
@ -182,9 +182,9 @@ patch(PosStore.prototype, {
|
||||
const status = bluetoothManager.getConnectionStatus();
|
||||
|
||||
if (status === 'connected' || status === 'connecting') {
|
||||
console.log('Disconnecting bluetooth printer...');
|
||||
// console.log('Disconnecting bluetooth printer...');
|
||||
await bluetoothManager.disconnect();
|
||||
console.log('Bluetooth printer disconnected');
|
||||
// console.log('Bluetooth printer disconnected');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error cleaning up bluetooth printer:', error);
|
||||
@ -258,7 +258,7 @@ patch(PosStore.prototype, {
|
||||
sticky: false
|
||||
});
|
||||
} else {
|
||||
console.log(`[${type.toUpperCase()}] ${message}`);
|
||||
// console.log(`[${type.toUpperCase()}] ${message}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user