update printer

This commit is contained in:
Efril 2026-03-01 19:37:23 +07:00
parent f7cafeb583
commit 5058f99fe0
4 changed files with 146 additions and 94 deletions

View File

@ -5,6 +5,7 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter_esc_pos_network/flutter_esc_pos_network.dart';
import 'package:injectable/injectable.dart' hide Order;
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
import 'package:synchronized/synchronized.dart';
import '../../../domain/order/order.dart';
import '../../../domain/outlet/outlet.dart';
@ -28,6 +29,13 @@ class PrinterRepository implements IPrinterRepository {
this._authLocalDataProvider,
);
final Map<String, Lock> _locks = {};
String? _connectedMac;
Lock _getLock(String address) {
return _locks.putIfAbsent(address, () => Lock());
}
@override
Future<Either<PrinterFailure, bool>> connectBluetooth(
String macAddress,
@ -213,33 +221,38 @@ class PrinterRepository implements IPrinterRepository {
Printer printer,
List<int> printData,
) async {
try {
log(printer.toString());
if (printer.type == 'Bluetooth') {
final connected = await connectBluetooth(printer.address);
if (printer.type == 'Bluetooth') {
return await _getLock(printer.address).synchronized(() async {
try {
bool isConnected = await PrintBluetoothThermal.connectionStatus;
connected.fold(
(f) {
return left(
PrinterFailure.dynamicErrorMessage(
'Printer cannot connect to bluetooth, Please connect in printer setting!',
),
// Hanya reconnect jika memang perlu
if (!isConnected || _connectedMac != printer.address) {
// Disconnect hanya jika terhubung ke printer LAIN
if (isConnected && _connectedMac != printer.address) {
await PrintBluetoothThermal.disconnect;
await Future.delayed(
const Duration(milliseconds: 300),
); // dari 1500ms
}
bool connected = await PrintBluetoothThermal.connect(
macPrinterAddress: printer.address,
);
},
(connect) async {
if (!connect) {
if (!connected) {
_connectedMac = null;
FirebaseCrashlytics.instance.recordError(
'Failed to connect to Bluetooth printer',
null,
reason: 'Failed to connect to Bluetooth print',
information: [
'function: printStruct(Printer printer, List<int> printValue,)',
'function: printStruct(Printer printer, List<int> printData)',
'Printer: ${printer.name}',
'macAddress: ${printer.address}',
'in: $_logName ',
'in: $_logName',
],
);
return left(
PrinterFailure.dynamicErrorMessage(
'Printer cannot connect to bluetooth, Please connect in printer setting!',
@ -247,33 +260,59 @@ class PrinterRepository implements IPrinterRepository {
);
}
log(
'Printer connected to bluetooth: ${printer.name}, ${printer.address}',
name: _logName,
_connectedMac = printer.address;
await Future.delayed(
const Duration(milliseconds: 300),
); // dari 1000ms
}
log(
'Printer connected to bluetooth: ${printer.name}, ${printer.address}',
name: _logName,
);
bool printResult = await _writeBytesChunked(printData);
// Hapus delay 1000ms setelah print tidak perlu untuk hasil cetak
log("Print result ${printer.name}: $printResult");
if (!printResult) {
FirebaseCrashlytics.instance.recordError(
'Failed to print to ${printer.name}',
null,
information: [
'function: await _writeBytesChunked(printData)',
'print: $printData',
'in: $_logName',
],
);
bool printResult = await _printBluetooth(printData);
if (!printResult) {
FirebaseCrashlytics.instance.recordError(
return left(
PrinterFailure.dynamicErrorMessage(
'Failed to print to ${printer.name}',
null,
information: [
'function: await printBluetooth(printData);',
'print: $printData',
'in: $_logName',
],
);
return left(
PrinterFailure.dynamicErrorMessage(
'Failed to print to ${printer.name}',
),
);
}
),
);
}
return right(printResult);
},
);
} else {
return right(printResult);
} catch (e, stackTrace) {
_connectedMac = null;
FirebaseCrashlytics.instance.recordError(
e,
stackTrace,
reason: 'Error printing ${printer.name}',
information: [
'Printer: ${printer.name}',
'MAC: ${printer.address}',
],
);
return left(
PrinterFailure.dynamicErrorMessage('Error printing struct'),
);
}
});
} else {
// Network printer tetap sama
try {
bool printResult = await _printNetwork(printer.address, printData);
if (!printResult) {
@ -282,7 +321,7 @@ class PrinterRepository implements IPrinterRepository {
null,
reason: 'Failed to connect to Network Printer',
information: [
'function: await printNetwork(printer.address, printData);',
'function: await _printNetwork(printer.address, printData)',
'Printer: ${printer.name}',
'ipAddress: ${printer.address}',
'print: $printData',
@ -290,59 +329,64 @@ class PrinterRepository implements IPrinterRepository {
],
);
}
return right(printResult);
}
return right(false);
} catch (e) {
log("Error printing struct", name: _logName, error: e);
return left(PrinterFailure.dynamicErrorMessage('Error printing struct'));
}
}
Future<bool> _printBluetooth(List<int> printData) async {
try {
bool isConnected = await PrintBluetoothThermal.connectionStatus;
if (!isConnected) {
log("Not connected to Bluetooth printer", name: _logName);
return false;
}
bool printResult = await PrintBluetoothThermal.writeBytes(printData);
if (printResult) {
log("Successfully printed via Bluetooth", name: _logName);
} else {
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
'Failed to print via Bluetooth',
null,
reason: 'Failed to print via Bluetooth',
information: [
'function: printBluetooth(List<int> printData)',
'printData: $printData',
'in: $_logName',
],
e,
stackTrace,
reason: 'Error printing ${printer.name}',
information: ['Printer: ${printer.name}', 'IP: ${printer.address}'],
);
return left(
PrinterFailure.dynamicErrorMessage('Error printing struct'),
);
log("Failed to print via Bluetooth", name: _logName);
}
return printResult;
} catch (e, stackTrace) {
FirebaseCrashlytics.instance.recordError(
e,
stackTrace,
reason: 'Error printing via Bluetooth',
information: [
'function: printBluetooth(List<int> printData)',
'Printer: Bluetooth printer',
'printData: $printData',
'in: $_logName',
],
);
log("Error printing via Bluetooth: $e", name: _logName);
return false;
}
}
// Future<bool> _printBluetooth(List<int> printData) async {
// try {
// bool isConnected = await PrintBluetoothThermal.connectionStatus;
// if (!isConnected) {
// log("Not connected to Bluetooth printer", name: _logName);
// return false;
// }
// bool printResult = await PrintBluetoothThermal.writeBytes(printData);
// if (printResult) {
// log("Successfully printed via Bluetooth", name: _logName);
// } else {
// FirebaseCrashlytics.instance.recordError(
// 'Failed to print via Bluetooth',
// null,
// reason: 'Failed to print via Bluetooth',
// information: [
// 'function: printBluetooth(List<int> printData)',
// 'printData: $printData',
// 'in: $_logName',
// ],
// );
// log("Failed to print via Bluetooth", name: _logName);
// }
// return printResult;
// } catch (e, stackTrace) {
// FirebaseCrashlytics.instance.recordError(
// e,
// stackTrace,
// reason: 'Error printing via Bluetooth',
// information: [
// 'function: printBluetooth(List<int> printData)',
// 'Printer: Bluetooth printer',
// 'printData: $printData',
// 'in: $_logName',
// ],
// );
// log("Error printing via Bluetooth: $e", name: _logName);
// return false;
// }
// }
Future<bool> _printNetwork(String ipAddress, List<int> printData) async {
try {
@ -979,4 +1023,15 @@ class PrinterRepository implements IPrinterRepository {
);
}
}
Future<bool> _writeBytesChunked(List<int> data, {int chunkSize = 512}) async {
for (int i = 0; i < data.length; i += chunkSize) {
final end = (i + chunkSize > data.length) ? data.length : i + chunkSize;
final chunk = data.sublist(i, end);
bool result = await PrintBluetoothThermal.writeBytes(chunk);
if (!result) return false;
await Future.delayed(const Duration(milliseconds: 30));
}
return true;
}
}

View File

@ -46,11 +46,7 @@ class CustomModalDialog extends StatelessWidget {
padding: const EdgeInsets.all(16),
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: AppColor.primaryGradient,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
color: AppColor.primary,
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
child: Row(

View File

@ -1230,7 +1230,7 @@ packages:
source: hosted
version: "1.4.1"
synchronized:
dependency: transitive
dependency: "direct main"
description:
name: synchronized
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0

View File

@ -43,6 +43,7 @@ dependencies:
flutter_esc_pos_network: ^1.0.3
esc_pos_utils_plus: ^2.0.4
table_calendar: ^3.1.2
synchronized: ^3.4.0
dev_dependencies:
flutter_test: