cb_prestige_qr/lib/features/scan/presentation/manager/scan_controller.dart
2026-04-27 10:58:43 +06:30

100 lines
2.5 KiB
Dart

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:cb_prestige_qr/features/scan/scan_providers.dart';
part 'scan_controller.g.dart';
class ScanState {
const ScanState({
this.isScanning = true,
this.isProcessing = false,
this.isSubmitting = false,
this.scannedValue,
this.errorMessage,
});
final bool isScanning;
final bool isProcessing;
final bool isSubmitting;
final String? scannedValue;
final String? errorMessage;
static const _sentinel = Object();
ScanState copyWith({
bool? isScanning,
bool? isProcessing,
bool? isSubmitting,
Object? scannedValue = _sentinel,
Object? errorMessage = _sentinel,
}) {
return ScanState(
isScanning: isScanning ?? this.isScanning,
isProcessing: isProcessing ?? this.isProcessing,
isSubmitting: isSubmitting ?? this.isSubmitting,
scannedValue: identical(scannedValue, _sentinel)
? this.scannedValue
: scannedValue as String?,
errorMessage: identical(errorMessage, _sentinel)
? this.errorMessage
: errorMessage as String?,
);
}
}
@riverpod
class ScanController extends _$ScanController {
@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,
);
} catch (e) {
state = state.copyWith(
isProcessing: false,
isScanning: true,
scannedValue: null,
errorMessage: e.toString(),
);
}
}
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,
);
} catch (e) {
state = state.copyWith(isSubmitting: false, errorMessage: e.toString());
rethrow;
}
}
void resumeScanning() {
state = const ScanState(
isScanning: true,
isProcessing: false,
isSubmitting: false,
scannedValue: null,
errorMessage: null,
);
}
}