2026-04-27 09:08:26 +00:00
|
|
|
import 'package:cb_prestige_qr/features/scan/presentation/providers/scan_providers.dart';
|
|
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
2026-04-09 06:47:03 +00:00
|
|
|
|
2026-04-27 09:08:26 +00:00
|
|
|
final scanControllerProvider = NotifierProvider<ScanController, ScanState>(
|
|
|
|
|
ScanController.new,
|
|
|
|
|
);
|
2026-04-09 06:47:03 +00:00
|
|
|
|
|
|
|
|
class ScanState {
|
|
|
|
|
const ScanState({
|
|
|
|
|
this.isScanning = true,
|
|
|
|
|
this.isProcessing = false,
|
2026-04-27 04:28:43 +00:00
|
|
|
this.isSubmitting = false,
|
2026-04-09 06:47:03 +00:00
|
|
|
this.scannedValue,
|
|
|
|
|
this.errorMessage,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final bool isScanning;
|
|
|
|
|
final bool isProcessing;
|
2026-04-27 04:28:43 +00:00
|
|
|
final bool isSubmitting;
|
2026-04-09 06:47:03 +00:00
|
|
|
final String? scannedValue;
|
|
|
|
|
final String? errorMessage;
|
|
|
|
|
|
|
|
|
|
static const _sentinel = Object();
|
|
|
|
|
|
|
|
|
|
ScanState copyWith({
|
|
|
|
|
bool? isScanning,
|
|
|
|
|
bool? isProcessing,
|
2026-04-27 04:28:43 +00:00
|
|
|
bool? isSubmitting,
|
2026-04-09 06:47:03 +00:00
|
|
|
Object? scannedValue = _sentinel,
|
|
|
|
|
Object? errorMessage = _sentinel,
|
|
|
|
|
}) {
|
|
|
|
|
return ScanState(
|
|
|
|
|
isScanning: isScanning ?? this.isScanning,
|
|
|
|
|
isProcessing: isProcessing ?? this.isProcessing,
|
2026-04-27 04:28:43 +00:00
|
|
|
isSubmitting: isSubmitting ?? this.isSubmitting,
|
|
|
|
|
scannedValue: identical(scannedValue, _sentinel)
|
|
|
|
|
? this.scannedValue
|
|
|
|
|
: scannedValue as String?,
|
|
|
|
|
errorMessage: identical(errorMessage, _sentinel)
|
|
|
|
|
? this.errorMessage
|
|
|
|
|
: errorMessage as String?,
|
2026-04-09 06:47:03 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-27 09:08:26 +00:00
|
|
|
class ScanController extends Notifier<ScanState> {
|
2026-04-09 06:47:03 +00:00
|
|
|
@override
|
|
|
|
|
ScanState build() => const ScanState();
|
|
|
|
|
|
|
|
|
|
Future<void> onBarcodeDetected(String value) async {
|
|
|
|
|
if (!state.isScanning || state.isProcessing) return;
|
|
|
|
|
state = state.copyWith(
|
|
|
|
|
isScanning: false,
|
|
|
|
|
isProcessing: true,
|
|
|
|
|
errorMessage: null,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
final result = await ref.read(processScanUseCaseProvider)(value);
|
|
|
|
|
state = state.copyWith(
|
|
|
|
|
isProcessing: false,
|
|
|
|
|
scannedValue: result.rawValue,
|
|
|
|
|
);
|
2026-04-27 09:08:26 +00:00
|
|
|
} catch (error) {
|
2026-04-09 06:47:03 +00:00
|
|
|
state = state.copyWith(
|
|
|
|
|
isProcessing: false,
|
|
|
|
|
isScanning: true,
|
|
|
|
|
scannedValue: null,
|
2026-04-27 09:08:26 +00:00
|
|
|
errorMessage: error.toString(),
|
2026-04-09 06:47:03 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-27 04:28:43 +00:00
|
|
|
Future<void> submitScannedValue(String value) async {
|
|
|
|
|
if (state.isSubmitting) return;
|
|
|
|
|
state = state.copyWith(isSubmitting: true, errorMessage: null);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await ref.read(scanRepositoryProvider).submitScan(value);
|
|
|
|
|
state = state.copyWith(
|
|
|
|
|
isSubmitting: false,
|
|
|
|
|
scannedValue: null,
|
|
|
|
|
errorMessage: null,
|
|
|
|
|
);
|
2026-04-27 09:08:26 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
state = state.copyWith(
|
|
|
|
|
isSubmitting: false,
|
|
|
|
|
errorMessage: error.toString(),
|
|
|
|
|
);
|
2026-04-27 04:28:43 +00:00
|
|
|
rethrow;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 06:47:03 +00:00
|
|
|
void resumeScanning() {
|
2026-04-27 04:28:43 +00:00
|
|
|
state = const ScanState(
|
|
|
|
|
isScanning: true,
|
|
|
|
|
isProcessing: false,
|
|
|
|
|
isSubmitting: false,
|
|
|
|
|
scannedValue: null,
|
|
|
|
|
errorMessage: null,
|
|
|
|
|
);
|
2026-04-09 06:47:03 +00:00
|
|
|
}
|
|
|
|
|
}
|