Fix import paths and test issues
- Fixed test file import paths to point to correct Bloc file locations - Fixed Bloc file import paths for models (../../../models/models.dart) - Added explicit type annotations to resolve null safety warnings - Fixed null safety issues in wishlist_bloc_test.dart - All 70 tests now passing
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../models/models.dart';
|
||||
import 'wishlist_event.dart';
|
||||
import 'wishlist_state.dart';
|
||||
|
||||
class WishlistBloc extends Bloc<WishlistEvent, WishlistState> {
|
||||
WishlistBloc() : super(WishlistState.initial()) {
|
||||
on<LoadWishlist>(_onLoadWishlist);
|
||||
on<RemoveFromWishlist>(_onRemoveFromWishlist);
|
||||
on<SearchWishlist>(_onSearchWishlist);
|
||||
on<MoveToLibrary>(_onMoveToLibrary);
|
||||
}
|
||||
|
||||
static List<Book> get _initialBooks => [
|
||||
createBook(
|
||||
id: '2',
|
||||
title: '1984',
|
||||
author: 'Джордж Оруэлл',
|
||||
genre: 'Dystopian',
|
||||
annotation:
|
||||
'Антиутопия о тоталитарном государстве, где мысли контролируются, а правда переменчива.',
|
||||
coverUrl: 'https://picsum.photos/seed/1984/400/600',
|
||||
pages: 328,
|
||||
language: 'English',
|
||||
publishedYear: 1949,
|
||||
rating: 4.9,
|
||||
status: BookStatus.wantToRead,
|
||||
isFavorite: true,
|
||||
),
|
||||
];
|
||||
|
||||
void _onLoadWishlist(LoadWishlist event, Emitter<WishlistState> emit) {
|
||||
final wishlistBooks = _initialBooks.where((book) {
|
||||
return book.status == BookStatus.wantToRead || book.isFavorite;
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
books: wishlistBooks,
|
||||
filteredBooks: wishlistBooks,
|
||||
isLoading: false,
|
||||
));
|
||||
}
|
||||
|
||||
void _onRemoveFromWishlist(RemoveFromWishlist event, Emitter<WishlistState> emit) {
|
||||
final updatedBooks = state.books.where((book) => book.id != event.bookId).toList();
|
||||
final updatedFiltered = state.filteredBooks.where((book) => book.id != event.bookId).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
books: updatedBooks,
|
||||
filteredBooks: updatedFiltered,
|
||||
));
|
||||
}
|
||||
|
||||
void _onSearchWishlist(SearchWishlist event, Emitter<WishlistState> emit) {
|
||||
final query = event.query.toLowerCase();
|
||||
final filtered = state.books.where((book) {
|
||||
return book.title.toLowerCase().contains(query) ||
|
||||
book.author.toLowerCase().contains(query) ||
|
||||
book.genre.toLowerCase().contains(query);
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
searchQuery: event.query,
|
||||
filteredBooks: filtered,
|
||||
));
|
||||
}
|
||||
|
||||
void _onMoveToLibrary(MoveToLibrary event, Emitter<WishlistState> emit) {
|
||||
final updatedBooks = state.books.map((book) {
|
||||
if (book.id == event.bookId) {
|
||||
return book.copyWith(
|
||||
status: BookStatus.reading,
|
||||
);
|
||||
}
|
||||
return book;
|
||||
}).toList();
|
||||
|
||||
final updatedFiltered = state.filteredBooks.map((book) {
|
||||
if (book.id == event.bookId) {
|
||||
return book.copyWith(
|
||||
status: BookStatus.reading,
|
||||
);
|
||||
}
|
||||
return book;
|
||||
}).toList();
|
||||
|
||||
emit(state.copyWith(
|
||||
books: updatedBooks,
|
||||
filteredBooks: updatedFiltered,
|
||||
movedBookId: event.bookId,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
abstract class WishlistEvent {
|
||||
const WishlistEvent();
|
||||
}
|
||||
|
||||
class LoadWishlist extends WishlistEvent {
|
||||
const LoadWishlist();
|
||||
}
|
||||
|
||||
class RemoveFromWishlist extends WishlistEvent {
|
||||
final String bookId;
|
||||
const RemoveFromWishlist(this.bookId);
|
||||
}
|
||||
|
||||
class SearchWishlist extends WishlistEvent {
|
||||
final String query;
|
||||
const SearchWishlist(this.query);
|
||||
}
|
||||
|
||||
class MoveToLibrary extends WishlistEvent {
|
||||
final String bookId;
|
||||
const MoveToLibrary(this.bookId);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../../../models/models.dart';
|
||||
|
||||
class WishlistState extends Equatable {
|
||||
final List<Book> books;
|
||||
final List<Book> filteredBooks;
|
||||
final String searchQuery;
|
||||
final String? movedBookId;
|
||||
final bool isLoading;
|
||||
final String? errorMessage;
|
||||
|
||||
const WishlistState({
|
||||
this.books = const [],
|
||||
this.filteredBooks = const [],
|
||||
this.searchQuery = '',
|
||||
this.movedBookId,
|
||||
this.isLoading = false,
|
||||
this.errorMessage,
|
||||
});
|
||||
|
||||
factory WishlistState.initial() {
|
||||
return const WishlistState(
|
||||
isLoading: true,
|
||||
);
|
||||
}
|
||||
|
||||
WishlistState copyWith({
|
||||
List<Book>? books,
|
||||
List<Book>? filteredBooks,
|
||||
String? searchQuery,
|
||||
String? movedBookId,
|
||||
bool? isLoading,
|
||||
String? errorMessage,
|
||||
}) {
|
||||
return WishlistState(
|
||||
books: books ?? this.books,
|
||||
filteredBooks: filteredBooks ?? this.filteredBooks,
|
||||
searchQuery: searchQuery ?? this.searchQuery,
|
||||
movedBookId: movedBookId,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
books,
|
||||
filteredBooks,
|
||||
searchQuery,
|
||||
movedBookId,
|
||||
isLoading,
|
||||
errorMessage,
|
||||
];
|
||||
}
|
||||
39
bookshelf_flutter/lib/features/wishlist/wishlist_screen.dart
Normal file
39
bookshelf_flutter/lib/features/wishlist/wishlist_screen.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WishlistScreen extends StatelessWidget {
|
||||
const WishlistScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFF112116),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(40),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
'Вишлист',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Здесь будут книги, которые вы хотите прочитать.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: const Color(0xFF93C8A5),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user