150 lines
5.6 KiB
Dart
150 lines
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
|
import 'package:cashumit/services/bluetooth_service.dart';
|
|
|
|
class ReceiptSpeedDial extends StatelessWidget {
|
|
final BluetoothService bluetoothService;
|
|
final Future<bool> Function() onCheckConnection;
|
|
final Future<void> Function() onPrint;
|
|
final VoidCallback onSettings;
|
|
final Future<void> Function() onReloadAccounts;
|
|
final bool hasItems;
|
|
final bool hasSourceAccount;
|
|
final bool hasDestinationAccount;
|
|
final Future<void> Function() onSendToFirefly;
|
|
final VoidCallback onPrintingStart;
|
|
final VoidCallback onPrintingEnd;
|
|
|
|
const ReceiptSpeedDial({
|
|
super.key,
|
|
required this.bluetoothService,
|
|
required this.onCheckConnection,
|
|
required this.onPrint,
|
|
required this.onSettings,
|
|
required this.onReloadAccounts,
|
|
required this.hasItems,
|
|
required this.hasSourceAccount,
|
|
required this.hasDestinationAccount,
|
|
required this.onSendToFirefly,
|
|
required this.onPrintingStart,
|
|
required this.onPrintingEnd,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SpeedDial(
|
|
icon: Icons.menu,
|
|
activeIcon: Icons.close,
|
|
spacing: 3,
|
|
spaceBetweenChildren: 4,
|
|
children: [
|
|
SpeedDialChild(
|
|
child: const Icon(Icons.send),
|
|
label: 'Kirim ke Firefly',
|
|
onTap: hasItems && hasSourceAccount && hasDestinationAccount
|
|
? onSendToFirefly
|
|
: () {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content:
|
|
Text('Pilih akun sumber dan tujuan terlebih dahulu'),
|
|
duration: Duration(seconds: 2),
|
|
),
|
|
);
|
|
},
|
|
backgroundColor: hasItems && hasSourceAccount && hasDestinationAccount
|
|
? Colors.blue
|
|
: Colors.grey,
|
|
),
|
|
SpeedDialChild(
|
|
child: const Icon(Icons.refresh),
|
|
label: 'Muat Ulang Akun',
|
|
onTap: onReloadAccounts,
|
|
backgroundColor: Colors.orange,
|
|
),
|
|
SpeedDialChild(
|
|
child: const Icon(Icons.settings),
|
|
label: 'Pengaturan',
|
|
onTap: onSettings,
|
|
backgroundColor: Colors.green,
|
|
),
|
|
SpeedDialChild(
|
|
child: bluetoothService.isPrinting
|
|
? const CircularProgressIndicator(
|
|
color: Colors.white, strokeWidth: 2)
|
|
: const Icon(Icons.receipt),
|
|
label: 'Cetak Struk',
|
|
onTap: bluetoothService.isPrinting
|
|
? null
|
|
: () async {
|
|
// Panggil callback untuk memulai printing status
|
|
onPrintingStart();
|
|
|
|
try {
|
|
// Periksa koneksi secara real-time
|
|
final isConnected = await onCheckConnection();
|
|
if (isConnected) {
|
|
await onPrint();
|
|
} else {
|
|
// Coba sambungkan kembali jika ada device yang tersimpan
|
|
if (bluetoothService.connectedDevice != null) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content:
|
|
Text('Mencoba menyambungkan ke printer...')),
|
|
);
|
|
try {
|
|
bool connectResult =
|
|
await bluetoothService.connectToDevice(
|
|
bluetoothService.connectedDevice!);
|
|
if (!connectResult) {
|
|
throw Exception('Gagal menyambungkan ke printer');
|
|
}
|
|
// Tunggu sebentar untuk memastikan koneksi stabil
|
|
await Future.delayed(
|
|
const Duration(milliseconds: 500));
|
|
// Periksa koneksi lagi
|
|
final isConnectedAfterConnect =
|
|
await onCheckConnection();
|
|
if (isConnectedAfterConnect) {
|
|
await onPrint();
|
|
} else {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content:
|
|
Text('Gagal menyambungkan ke printer')),
|
|
);
|
|
}
|
|
} catch (e) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content:
|
|
Text('Gagal menyambungkan ke printer: $e')),
|
|
);
|
|
}
|
|
} else {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(
|
|
content:
|
|
Text('Hubungkan printer terlebih dahulu')),
|
|
);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// Tangani error secara umum
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Terjadi kesalahan: $e')),
|
|
);
|
|
} finally {
|
|
// Pastikan printing status selalu diakhiri
|
|
onPrintingEnd();
|
|
}
|
|
},
|
|
backgroundColor: Colors.purple,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|