Created
June 17, 2021 13:02
-
-
Save lukaspili/3452095688971497cebd0ba6a54c511a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:io'; | |
import 'package:esc_pos_printer/esc_pos_printer.dart'; | |
import 'package:esc_pos_utils/esc_pos_utils.dart'; | |
import 'package:flutter/services.dart'; | |
import 'package:freezed_annotation/freezed_annotation.dart'; | |
import 'package:hooks_riverpod/hooks_riverpod.dart'; | |
import 'package:image/image.dart' as image; | |
import 'package:mimosushi_forecast/data/data.dart'; | |
import 'package:mimosushi_forecast/presentation/presentation.dart'; | |
import 'package:ping_discover_network/ping_discover_network.dart'; | |
import 'package:wifi_info_flutter/wifi_info_flutter.dart'; | |
part 'printer_repository.freezed.dart'; | |
@freezed | |
abstract class PrinterRepositoryData with _$PrinterRepositoryData { | |
const factory PrinterRepositoryData({ | |
@nullable Printer printer, | |
@Default(const []) List<Printer> printers, | |
@Default(const Task.idle()) Task searchTask, | |
@Default(const Task.idle()) Task printTask, | |
}) = _PrinterRepositoryData; | |
} | |
class PrinterRepository extends StateNotifier<PrinterRepositoryData> { | |
static final pod = StateNotifierProvider((ref) => PrinterRepository(ref.read)); | |
static final _port = 9100; | |
// static final _port = 1400; | |
PrinterRepository(this.read) : super(const PrinterRepositoryData()); | |
final Reader read; | |
final WifiInfo wifiInfo = WifiInfo(); | |
void search() async { | |
if (state.searchTask is Loading) return; | |
final permission = await wifiInfo.requestLocationServiceAuthorization(requestAlwaysLocationUsage: false); | |
if (permission != LocationAuthorizationStatus.authorizedWhenInUse && permission != LocationAuthorizationStatus.authorizedAlways) { | |
state = state.copyWith( | |
searchTask: const Task.failed(AppError.fetchFailed('You must accept location permission to search printers on Wifi')), | |
); | |
return; | |
} | |
state = state.copyWith(searchTask: const Task.loading()); | |
final ip = await wifiInfo.getWifiIP(); | |
if (ip.isBlank || ip == 'error') { | |
state = state.copyWith( | |
searchTask: const Task.failed(AppError.fetchFailed('Not connected to Wifi')), | |
); | |
return; | |
} | |
debugPrint('[search printers] local ip: ${ip}'); | |
final printers = <Printer>[]; | |
try { | |
final subnet = ip.substring(0, ip.lastIndexOf('.')); | |
final stream = NetworkAnalyzer.discover2(subnet, _port); | |
await stream.forEach((address) async { | |
if (address.exists) { | |
// addresses.add(address.ip); | |
String name; | |
try { | |
final internetAddress = await InternetAddress(address.ip).reverse(); | |
name = internetAddress.host.isNotBlank ? internetAddress.host : null; | |
} catch (e) {} | |
printers.add(Printer( | |
name: name.isNotBlank ? name : '', | |
ip: address.ip, | |
)); | |
} | |
}); | |
} catch (e) { | |
state = state.copyWith( | |
searchTask: const Task.failed(AppError.fetchFailed('Failed to scan local network')), | |
); | |
} | |
debugPrint('[search printers] results: ${printers}'); | |
state = state.copyWith( | |
printers: printers, | |
searchTask: const Task.successful(), | |
); | |
} | |
void select(Printer printer) { | |
state = state.copyWith(printer: printer); | |
// read(AutomaticPrintService.pod).printActiveForecast(); | |
} | |
Future<bool> printForecast(Forecast forecast) async { | |
if (state.printer == null) { | |
state = state.copyWith(printTask: Task.failed(AppError('Aucune imprimante connectée'))); | |
return false; | |
} | |
if (state.printTask is Loading) { | |
state = state.copyWith(printTask: Task.failed(AppError('Une impression est déjà en cours'))); | |
return false; | |
} | |
final paper = PaperSize.mm80; | |
final profile = await CapabilityProfile.load(); | |
final printer = NetworkPrinter(paper, profile); | |
try { | |
final PosPrintResult connection = await printer.connect(state.printer.ip, port: _port); | |
debugPrint('[print] connection to printer: ${connection.msg}'); | |
if (connection != PosPrintResult.success) { | |
state = state.copyWith(printTask: Task.failed(AppError.operationFailed(connection.msg))); | |
return false; | |
} | |
state = state.copyWith(printTask: const Task.loading()); | |
if (!Configuration.skipPrinting) { | |
final data = await rootBundle.load(Assets.printer.logoPrint.path); | |
final bytes = data.buffer.asUint8List(); | |
printer.image(image.decodeImage(bytes)); | |
printer.text( | |
'MIMO SUSHI FORECAST', | |
styles: PosStyles( | |
align: PosAlign.center, | |
height: PosTextSize.size2, | |
width: PosTextSize.size2, | |
), | |
linesAfter: 1, | |
); | |
printer.text( | |
Format.forecastPrintDate(forecast.date), | |
styles: const PosStyles(align: PosAlign.center), | |
); | |
printer.text( | |
Format.servingPeriod(forecast.servingPeriod), | |
styles: const PosStyles(align: PosAlign.center, bold: true), | |
linesAfter: 1, | |
); | |
printer.hr(); | |
forecast.products.forEach((fProduct) { | |
printer.row([ | |
PosColumn( | |
text: fProduct.product.name, | |
width: 10, | |
styles: const PosStyles(width: PosTextSize.size2), | |
), | |
PosColumn( | |
text: fProduct.quantity.toString(), | |
width: 2, | |
styles: const PosStyles(width: PosTextSize.size2, align: PosAlign.right), | |
), | |
]); | |
}); | |
printer.hr(); | |
printer.feed(1); | |
printer.cut(); | |
} | |
debugPrint('[print] finished'); | |
} catch (e, s) { | |
debugPrint('[print] error: ${e}'); | |
debugPrint('[print] error: ${s}'); | |
state = state.copyWith(printTask: Task.failed(AppError.operationFailed(e.toString()))); | |
return false; | |
} finally { | |
try { | |
await printer.disconnect(); | |
} catch (e, s) { | |
debugPrint('[print] disconnect error: ${e}'); | |
debugPrint('[print] disconnect error: ${s}'); | |
} | |
} | |
await read(AutomaticPrintService.pod).markForecastPrinted(forecast); | |
state = state.copyWith(printTask: const Task.successful()); | |
return true; | |
} | |
void resetPrintTask() { | |
state = state.copyWith(printTask: const Task.idle()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment