Files
apskel-pos-flutter-v2/lib/presentation/app_widget.dart
T
efrilmandClaude Opus 5 7986164a17 fix: beri tiap tab pengaturan printer bloc sendiri
PrinterFormBloc dan PrinterLoaderBloc di-provide sekali secara global, sementara lima tab pengaturan printer hidup bersamaan di dalam TabBarView dan semuanya membaca-menulis state yang sama.

Karena created dan updated membangun entitas Printer sepenuhnya dari state itu (type, address, code, name, paper), tab yang terakhir menulis state akan menang, lalu tombol Simpan di tab mana pun menyimpan milik tab lain. Nilai awal state kebetulan type 'Bluetooth' — itu sebabnya printer kitchen tersimpan dengan alamat IP yang benar tapi tipe Bluetooth, dan cetakannya dikirim ke radio Bluetooth untuk mencari perangkat yang tidak pernah ada.

Provider global dihapus karena tidak ada tempat lain yang memakainya. Catatan: ini mencegah kerusakan baru, tidak memulihkan baris yang sudah terlanjur salah di SQLite — konfigurasi kelima tab perlu disimpan ulang.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-05 14:06:34 +07:00

88 lines
4.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../application/auth/auth_bloc.dart';
import '../application/auth/logout/logout_bloc.dart';
import '../application/category/category_loader/category_loader_bloc.dart';
import '../application/checkout/checkout_form/checkout_form_bloc.dart';
import '../application/customer/customer_loader/customer_loader_bloc.dart';
import '../application/order/order_form/order_form_bloc.dart';
import '../application/order/order_loader/order_loader_bloc.dart';
import '../application/outlet/outlet_loader/outlet_loader_bloc.dart';
import '../application/payment_method/payment_method_loader/payment_method_loader_bloc.dart';
import '../application/printer/bluetooth/bluetooth_connect/bluetooth_connect_bloc.dart';
import '../application/printer/bluetooth/bluetooth_loader/bluetooth_loader_bloc.dart';
import '../application/printer/print_struck/print_struck_bloc.dart';
import '../application/product/product_loader/product_loader_bloc.dart';
import '../application/sync/sync_setting/sync_setting_bloc.dart';
import '../application/table/table_form/table_form_bloc.dart';
import '../application/table/table_loader/table_loader_bloc.dart';
import '../application/void/void_form/void_form_bloc.dart';
import '../common/theme/theme.dart';
import '../common/constant/app_constant.dart';
import '../injection.dart';
import 'components/dialog/dialog.dart';
import 'router/app_router.dart';
import 'router/app_router_observer.dart';
class AppWidget extends StatefulWidget {
const AppWidget({super.key});
@override
State<AppWidget> createState() => _AppWidgetState();
}
class _AppWidgetState extends State<AppWidget> {
final _appRouter = getIt<AppRouter>();
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => getIt<AuthBloc>()),
BlocProvider(create: (context) => getIt<OutletLoaderBloc>()),
BlocProvider(create: (context) => getIt<CategoryLoaderBloc>()),
BlocProvider(create: (context) => getIt<ProductLoaderBloc>()),
BlocProvider(create: (context) => getIt<CheckoutFormBloc>()),
BlocProvider(create: (context) => getIt<TableLoaderBloc>()),
BlocProvider(create: (context) => getIt<TableFormBloc>()),
BlocProvider(create: (context) => getIt<PaymentMethodLoaderBloc>()),
BlocProvider(create: (context) => getIt<OrderFormBloc>()),
BlocProvider(create: (context) => getIt<OrderLoaderBloc>()),
BlocProvider(create: (context) => getIt<CustomerLoaderBloc>()),
BlocProvider(create: (context) => getIt<VoidFormBloc>()),
BlocProvider(create: (context) => getIt<BluetoothLoaderBloc>()),
BlocProvider(create: (context) => getIt<BluetoothConnectBloc>()),
// PrinterFormBloc dan PrinterLoaderBloc sengaja TIDAK global: tiap tab
// pengaturan printer memakai instance sendiri, lihat
// SettingPrinterSection.
BlocProvider(create: (context) => getIt<PrintStruckBloc>()),
BlocProvider(create: (context) => getIt<SyncSettingBloc>()),
BlocProvider(create: (context) => getIt<LogoutBloc>()),
],
child: MaterialApp.router(
debugShowCheckedModeBanner: false,
title: AppConstant.appName,
theme: ThemeApp.theme,
routerConfig: _appRouter.config(
navigatorObservers: () => <NavigatorObserver>[AppRouteObserver()],
),
// Satu listener untuk seluruh aplikasi: cetak bisa dipicu dari banyak
// halaman, dan `PrintStruckBloc` hidup di atas router jadi prosesnya
// tetap jalan walau kasir sudah pindah halaman.
builder: (context, child) => BlocListener<PrintStruckBloc, PrintStruckState>(
listenWhen: (previous, current) => previous.jobId != current.jobId,
listener: (_, __) {
// Dialog harus dibuka dari context di bawah Navigator, sementara
// builder ini berada di atasnya.
final navigatorContext = _appRouter.navigatorKey.currentContext;
if (navigatorContext == null) return;
showPrintProgressDialog(navigatorContext);
},
child: child ?? const SizedBox.shrink(),
),
),
);
}
}