Skip to content

Commit

Permalink
favourites_second
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamed3ly1997 committed May 27, 2024
1 parent dafe568 commit 22202e8
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 24 deletions.
13 changes: 12 additions & 1 deletion lib/core/router/routers_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:recipes/core/router/routes.dart';
import 'package:recipes/features/drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import 'package:recipes/features/home/presentation/screens/home.dart';
import 'package:recipes/features/drinks/presentation/screens/drinks_by_category.dart';
import 'package:recipes/features/on_boarding/presentation/screens/on_boarding_screen.dart';

import '../../features/drinks/presentation/screens/drinkDetails.dart';
import '../../features/favourites/presentation/screens/favourites.dart';
import 'custom_transition_page.dart';

final goRouterProvider = Provider((ref) => _router);
Expand Down Expand Up @@ -55,8 +57,17 @@ final GoRouter _router = GoRouter(
),
],
),
GoRoute(
path: Routes.favorites.name,
name: Routes.favorites.name,
pageBuilder: (context, state) {
return buildCustomTransitionPage(
state,
const FavoritesScreen(),
);
},
),
],
),
],
);

1 change: 1 addition & 0 deletions lib/core/router/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ enum Routes {
drinkDetails,
onBoarding,
drinksByCategory,
favorites,
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:recipes/features/drinks/presentation/riverpod/drink/drinks_provider.dart';
import 'package:recipes/features/drinks/presentation/riverpod/drink_details/selected_drink_provider.dart';
import 'package:recipes/features/drinks/presentation/screens/drinkDetails.dart';
import 'package:recipes/features/drinks/presentation/widgets/drink_item.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import '../../../../configs/configs.dart';
Expand Down Expand Up @@ -58,13 +57,7 @@ class DrinksByCategoryScreen extends ConsumerWidget {
.read(selectedDrinkProvider.notifier)
.state =
state.data![index].idDrink.toString();
/*
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
const DrinkDetailsScreen(),
),
);*/

context.goNamed(
Routes.drinkDetails.name,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';

abstract class FavoriteDrinksRepository {
void addFavorite(DrinkDetails drink);

void removeFavorite(String idDrink);

List<DrinkDetails> getFavorites();

bool isFavorite(String idDrink);
}
12 changes: 12 additions & 0 deletions lib/features/favourites/domain/use_cases/add_to_favourites.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import '../repositories/favourites_repository.dart';

class AddFavoriteUseCase {
final FavoriteDrinksRepository _repository;

AddFavoriteUseCase(this._repository);

void call(DrinkDetails drink) {
_repository.addFavorite(drink);
}
}
12 changes: 12 additions & 0 deletions lib/features/favourites/domain/use_cases/get_favourites.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import '../repositories/favourites_repository.dart';

class GetFavoritesUseCase {
final FavoriteDrinksRepository _repository;

GetFavoritesUseCase(this._repository);

List<DrinkDetails> call() {
return _repository.getFavorites();
}
}
11 changes: 11 additions & 0 deletions lib/features/favourites/domain/use_cases/is_favourite.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../repositories/favourites_repository.dart';

class IsFavoriteUseCase {
final FavoriteDrinksRepository _repository;

IsFavoriteUseCase(this._repository);

bool call(String idDrink) {
return _repository.isFavorite(idDrink);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../repositories/favourites_repository.dart';

class RemoveFavoriteUseCase {
final FavoriteDrinksRepository _repository;

RemoveFavoriteUseCase(this._repository);

void call(String idDrink) {
_repository.removeFavorite(idDrink);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import 'package:hive/hive.dart';
import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';

class FavoriteDrinksLocalDataSource {
abstract class FavoriteDrinksDataSource {
void addFavorite(DrinkDetails drink);
void removeFavorite(String idDrink);
List<DrinkDetails> getFavorites();
bool isFavorite(String idDrink);
}



class FavoriteDrinksLocalDataSource implements FavoriteDrinksDataSource {
final Box<DrinkDetails> _favoritesBox;

FavoriteDrinksLocalDataSource(this._favoritesBox);

@override
void addFavorite(DrinkDetails drink) {
_favoritesBox.put(drink.idDrink, drink);
}

@override
void removeFavorite(String idDrink) {
_favoritesBox.delete(idDrink);
}

@override
List<DrinkDetails> getFavorites() {
return _favoritesBox.values.toList();
}

@override
bool isFavorite(String idDrink) {
return _favoritesBox.containsKey(idDrink);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import '../../domain/repositories/favourites_repository.dart';
import '../data_sources/local_data_source.dart';

class FavoriteDrinksRepositoryImpl implements FavoriteDrinksRepository {
final FavoriteDrinksDataSource _localDataSource;

FavoriteDrinksRepositoryImpl(this._localDataSource);

@override
void addFavorite(DrinkDetails drink) {
_localDataSource.addFavorite(drink);
}

@override
void removeFavorite(String idDrink) {
_localDataSource.removeFavorite(idDrink);
}

@override
List<DrinkDetails> getFavorites() {
return _localDataSource.getFavorites();
}

@override
bool isFavorite(String idDrink) {
return _localDataSource.isFavorite(idDrink);
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import '../../infrastructure/data_sources/local_data_source.dart';
import '../../domain/use_cases/add_to_favourites.dart';
import '../../domain/use_cases/get_favourites.dart';
import '../../domain/use_cases/is_favourite.dart';
import '../../domain/use_cases/remove_from_favourites.dart';


class FavoriteDrinksNotifier extends StateNotifier<List<DrinkDetails>> {
final FavoriteDrinksLocalDataSource _localDataSource;
final AddFavoriteUseCase _addFavoriteUseCase;
final RemoveFavoriteUseCase _removeFavoriteUseCase;
final GetFavoritesUseCase _getFavoritesUseCase;
final IsFavoriteUseCase _isFavoriteUseCase;

FavoriteDrinksNotifier(this._localDataSource) : super(_localDataSource.getFavorites());
FavoriteDrinksNotifier(
this._addFavoriteUseCase,
this._removeFavoriteUseCase,
this._getFavoritesUseCase,
this._isFavoriteUseCase,
) : super(_getFavoritesUseCase());

void addFavorite(DrinkDetails drink) {
_localDataSource.addFavorite(drink);
state = _localDataSource.getFavorites();
_addFavoriteUseCase(drink);
state = _getFavoritesUseCase();
}

void removeFavorite(String idDrink) {
_localDataSource.removeFavorite(idDrink);
state = _localDataSource.getFavorites();
_removeFavoriteUseCase(idDrink);
state = _getFavoritesUseCase();
}

bool isFavorite(String idDrink) {
return _localDataSource.isFavorite(idDrink);
return _isFavoriteUseCase(idDrink);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,67 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive/hive.dart';

import '../../../drinks/infrastructure/dto/drink_details/drink_details_model.dart';
import '../../domain/repositories/favourites_repository.dart';
import '../../domain/use_cases/add_to_favourites.dart';
import '../../domain/use_cases/get_favourites.dart';
import '../../domain/use_cases/is_favourite.dart';
import '../../domain/use_cases/remove_from_favourites.dart';
import '../../infrastructure/data_sources/local_data_source.dart';
import '../../infrastructure/repositories/favourites_repository_impl.dart';
import 'favourites_notifier.dart';

// Initialize the Hive box provider
// Hive box provider
final favoritesBoxProvider = Provider<Box<DrinkDetails>>((ref) {
return Hive.box<DrinkDetails>('favorites');
});

// Initialize the local data source provider
// Data source provider
final favoriteDrinksLocalDataSourceProvider =
Provider<FavoriteDrinksLocalDataSource>((ref) {
Provider<FavoriteDrinksDataSource>((ref) {
final box = ref.watch(favoritesBoxProvider);
return FavoriteDrinksLocalDataSource(box);
});

// Initialize the notifier provider
// Repository provider
final favoriteDrinksRepositoryProvider =
Provider<FavoriteDrinksRepository>((ref) {
final dataSource = ref.watch(favoriteDrinksLocalDataSourceProvider);
return FavoriteDrinksRepositoryImpl(dataSource);
});

// Use case providers
final addFavoriteUseCaseProvider = Provider<AddFavoriteUseCase>((ref) {
final repository = ref.watch(favoriteDrinksRepositoryProvider);
return AddFavoriteUseCase(repository);
});

final removeFavoriteUseCaseProvider = Provider<RemoveFavoriteUseCase>((ref) {
final repository = ref.watch(favoriteDrinksRepositoryProvider);
return RemoveFavoriteUseCase(repository);
});

final getFavoritesUseCaseProvider = Provider<GetFavoritesUseCase>((ref) {
final repository = ref.watch(favoriteDrinksRepositoryProvider);
return GetFavoritesUseCase(repository);
});

final isFavoriteUseCaseProvider = Provider<IsFavoriteUseCase>((ref) {
final repository = ref.watch(favoriteDrinksRepositoryProvider);
return IsFavoriteUseCase(repository);
});

// Notifier provider
final favoriteDrinksNotifierProvider =
StateNotifierProvider<FavoriteDrinksNotifier, List<DrinkDetails>>((ref) {
final localDataSource = ref.watch(favoriteDrinksLocalDataSourceProvider);
return FavoriteDrinksNotifier(localDataSource);
final addFavoriteUseCase = ref.watch(addFavoriteUseCaseProvider);
final removeFavoriteUseCase = ref.watch(removeFavoriteUseCaseProvider);
final getFavoritesUseCase = ref.watch(getFavoritesUseCaseProvider);
final isFavoriteUseCase = ref.watch(isFavoriteUseCaseProvider);

return FavoriteDrinksNotifier(
addFavoriteUseCase,
removeFavoriteUseCase,
getFavoritesUseCase,
isFavoriteUseCase,
);
});
74 changes: 74 additions & 0 deletions lib/features/favourites/presentation/screens/favourites.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:go_router/go_router.dart';
import '../../../../core/router/routes.dart';
import '../../../drinks/presentation/riverpod/drink_details/selected_drink_provider.dart';
import '../riverpod/favourites_provider.dart';
import '../widgets/favourite_drink_item.dart';

class FavoritesScreen extends ConsumerWidget {
const FavoritesScreen({Key? key}) : super(key: key);

@override
Widget build(BuildContext context, WidgetRef ref) {
final favorites = ref.watch(favoriteDrinksNotifierProvider);

return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
elevation: 2,
title: const Text(
'Favorites',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
),
body: SingleChildScrollView(
child: favorites.isEmpty
? const Center(
child: Text(
'No favorites yet',
style: TextStyle(fontSize: 18),
),
)
: RefreshIndicator(
onRefresh: () async {
// ref.refresh(favoriteDrinksNotifierProvider);
},
child: StaggeredGrid.count(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(
favorites.length,
(index) {
return GestureDetector(
onTap: () {
ref.read(selectedDrinkProvider.notifier).state =
favorites[index].idDrink;

context.goNamed(
Routes.drinkDetails.name,
);
},
child: FavouriteDrinkItem(
drink: favorites[index],
),
);
},
),
),
),
),
);
}
}
Loading

0 comments on commit 22202e8

Please sign in to comment.