refactor: create separate BLoCs for each screen with comprehensive tests

- Created 8 separate BLoCs (Home, Library, BookDetails, AddBook, Scanner, Categories, Wishlist, Settings)
- Each BLoC has its own event, state, and bloc files
- Added 70 comprehensive tests covering all BLoC functionality
- All tests passing (70/70)
- Fixed linting issues and updated deprecated APIs
- Improved code organization and maintainability
This commit is contained in:
Yuriy Panov
2026-02-04 14:40:00 +06:00
parent 3004f712f3
commit 310463e89a
177 changed files with 9718 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'scanner_event.dart';
import 'scanner_state.dart';
class ScannerBloc extends Bloc<ScannerEvent, ScannerState> {
ScannerBloc() : super(ScannerState.initial()) {
on<StartScanning>(_onStartScanning);
on<StopScanning>(_onStopScanning);
on<BookDetected>(_onBookDetected);
on<ClearDetectedBook>(_onClearDetectedBook);
}
void _onStartScanning(StartScanning event, Emitter<ScannerState> emit) {
emit(state.copyWith(
isScanning: true,
isProcessing: false,
errorMessage: null,
));
}
void _onStopScanning(StopScanning event, Emitter<ScannerState> emit) {
emit(state.copyWith(isScanning: false));
}
void _onBookDetected(BookDetected event, Emitter<ScannerState> emit) {
emit(state.copyWith(
detectedBookData: event.bookData,
isProcessing: true,
isScanning: false,
));
}
void _onClearDetectedBook(ClearDetectedBook event, Emitter<ScannerState> emit) {
emit(state.copyWith(
isScanning: false,
clearDetectedBookData: true,
isProcessing: false,
));
}
}

View File

@@ -0,0 +1,20 @@
abstract class ScannerEvent {
const ScannerEvent();
}
class StartScanning extends ScannerEvent {
const StartScanning();
}
class StopScanning extends ScannerEvent {
const StopScanning();
}
class BookDetected extends ScannerEvent {
final Map<String, dynamic> bookData;
const BookDetected(this.bookData);
}
class ClearDetectedBook extends ScannerEvent {
const ClearDetectedBook();
}

View File

@@ -0,0 +1,42 @@
import 'package:equatable/equatable.dart';
class ScannerState extends Equatable {
final bool isScanning;
final bool isProcessing;
final Map<String, dynamic>? detectedBookData;
final String? errorMessage;
const ScannerState({
this.isScanning = false,
this.isProcessing = false,
this.detectedBookData,
this.errorMessage,
});
factory ScannerState.initial() {
return const ScannerState();
}
ScannerState copyWith({
bool? isScanning,
bool? isProcessing,
Map<String, dynamic>? detectedBookData,
String? errorMessage,
bool clearDetectedBookData = false,
}) {
return ScannerState(
isScanning: isScanning ?? this.isScanning,
isProcessing: isProcessing ?? this.isProcessing,
detectedBookData: clearDetectedBookData ? null : (detectedBookData ?? this.detectedBookData),
errorMessage: errorMessage ?? this.errorMessage,
);
}
@override
List<Object?> get props => [
isScanning,
isProcessing,
detectedBookData,
errorMessage,
];
}