runable
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import '../../data/models/scan_item.dart';
|
||||
import '../../domain/usecases/get_scan_history_usecase.dart';
|
||||
import 'dependency_injection.dart';
|
||||
|
||||
/// State for the scanner functionality
|
||||
class ScannerState {
|
||||
final String? currentBarcode;
|
||||
final List<ScanItem> history;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
|
||||
const ScannerState({
|
||||
this.currentBarcode,
|
||||
this.history = const [],
|
||||
this.isLoading = false,
|
||||
this.error,
|
||||
});
|
||||
|
||||
ScannerState copyWith({
|
||||
String? currentBarcode,
|
||||
List<ScanItem>? history,
|
||||
bool? isLoading,
|
||||
String? error,
|
||||
}) {
|
||||
return ScannerState(
|
||||
currentBarcode: currentBarcode ?? this.currentBarcode,
|
||||
history: history ?? this.history,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error ?? this.error,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is ScannerState &&
|
||||
runtimeType == other.runtimeType &&
|
||||
currentBarcode == other.currentBarcode &&
|
||||
history == other.history &&
|
||||
isLoading == other.isLoading &&
|
||||
error == other.error;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
currentBarcode.hashCode ^
|
||||
history.hashCode ^
|
||||
isLoading.hashCode ^
|
||||
error.hashCode;
|
||||
}
|
||||
|
||||
/// Scanner state notifier
|
||||
class ScannerNotifier extends StateNotifier<ScannerState> {
|
||||
final GetScanHistoryUseCase _getScanHistoryUseCase;
|
||||
|
||||
ScannerNotifier(this._getScanHistoryUseCase) : super(const ScannerState()) {
|
||||
_loadHistory();
|
||||
}
|
||||
|
||||
/// Load scan history from local storage
|
||||
Future<void> _loadHistory() async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
|
||||
final result = await _getScanHistoryUseCase();
|
||||
result.fold(
|
||||
(failure) => state = state.copyWith(
|
||||
isLoading: false,
|
||||
error: failure.message,
|
||||
),
|
||||
(history) => state = state.copyWith(
|
||||
isLoading: false,
|
||||
history: history.map((entity) => ScanItem.fromEntity(entity)).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Update current scanned barcode
|
||||
void updateBarcode(String barcode) {
|
||||
if (barcode.trim().isEmpty) return;
|
||||
|
||||
state = state.copyWith(currentBarcode: barcode);
|
||||
|
||||
// Add to history if not already present
|
||||
final existingIndex = state.history.indexWhere((item) => item.barcode == barcode);
|
||||
if (existingIndex == -1) {
|
||||
final newScanItem = ScanItem(
|
||||
barcode: barcode,
|
||||
timestamp: DateTime.now(),
|
||||
);
|
||||
|
||||
final updatedHistory = [newScanItem, ...state.history];
|
||||
state = state.copyWith(history: updatedHistory);
|
||||
} else {
|
||||
// Move existing item to top
|
||||
final existingItem = state.history[existingIndex];
|
||||
final updatedHistory = List<ScanItem>.from(state.history);
|
||||
updatedHistory.removeAt(existingIndex);
|
||||
updatedHistory.insert(0, existingItem.copyWith(timestamp: DateTime.now()));
|
||||
state = state.copyWith(history: updatedHistory);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear current barcode
|
||||
void clearBarcode() {
|
||||
state = state.copyWith(currentBarcode: null);
|
||||
}
|
||||
|
||||
/// Refresh history from storage
|
||||
Future<void> refreshHistory() async {
|
||||
await _loadHistory();
|
||||
}
|
||||
|
||||
/// Add or update scan item in history
|
||||
void updateScanItem(ScanItem scanItem) {
|
||||
final existingIndex = state.history.indexWhere(
|
||||
(item) => item.barcode == scanItem.barcode,
|
||||
);
|
||||
|
||||
List<ScanItem> updatedHistory;
|
||||
if (existingIndex != -1) {
|
||||
// Update existing item
|
||||
updatedHistory = List<ScanItem>.from(state.history);
|
||||
updatedHistory[existingIndex] = scanItem;
|
||||
} else {
|
||||
// Add new item at the beginning
|
||||
updatedHistory = [scanItem, ...state.history];
|
||||
}
|
||||
|
||||
state = state.copyWith(history: updatedHistory);
|
||||
}
|
||||
|
||||
/// Clear error message
|
||||
void clearError() {
|
||||
state = state.copyWith(error: null);
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider for scanner state
|
||||
final scannerProvider = StateNotifierProvider<ScannerNotifier, ScannerState>(
|
||||
(ref) => ScannerNotifier(
|
||||
ref.watch(getScanHistoryUseCaseProvider),
|
||||
),
|
||||
);
|
||||
|
||||
/// Provider for current barcode (for easy access)
|
||||
final currentBarcodeProvider = Provider<String?>((ref) {
|
||||
return ref.watch(scannerProvider).currentBarcode;
|
||||
});
|
||||
|
||||
/// Provider for scan history (for easy access)
|
||||
final scanHistoryProvider = Provider<List<ScanItem>>((ref) {
|
||||
return ref.watch(scannerProvider).history;
|
||||
});
|
||||
|
||||
/// Provider for scanner loading state
|
||||
final scannerLoadingProvider = Provider<bool>((ref) {
|
||||
return ref.watch(scannerProvider).isLoading;
|
||||
});
|
||||
|
||||
/// Provider for scanner error state
|
||||
final scannerErrorProvider = Provider<String?>((ref) {
|
||||
return ref.watch(scannerProvider).error;
|
||||
});
|
||||
Reference in New Issue
Block a user