Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/lib/app/bootstrap/dependencies_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class _CAppDependenciesProviderState extends State<CAppDependenciesProvider> {
final invitationsTable = CInvitationsTable(supabaseClient);
final userRolesTable = CUserRolesTable(supabaseClient);
final gemShareTokensTable = CGemShareTokensTable(supabaseClient);
final gemLikesTable = CGemLikesTable(supabaseClient);

platformClient = CPlatformClient();
authClient = CAuthClient(authClient: supabaseClient.auth);
Expand All @@ -105,6 +106,7 @@ class _CAppDependenciesProviderState extends State<CAppDependenciesProvider> {
gemsTable: gemsTable,
linesTable: linesTable,
gemShareTokensTable: gemShareTokensTable,
gemLikesTable: gemLikesTable,
supabaseClient: supabaseClient,
);
personClient = CPersonClient(
Expand Down
4 changes: 4 additions & 0 deletions app/lib/app/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ class CAppRouter extends RootStackRouter implements AutoRouteGuard {
path: 'collections/randomly-selected',
page: CRandomCollectionRoute.page,
),
AutoRoute(
path: 'collections/favourites',
page: CFavouritesCollectionRoute.page,
),
AutoRoute(
path: 'people/edit-person',
page: CEditPersonRoute.page,
Expand Down
16 changes: 16 additions & 0 deletions app/lib/app/routes.gr.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/lib/localization/arb/intl_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"collectionView_shareSheet_createLinkButton": "Link erstellen",
"collectionView_shareSheet_deleteLinkButton": "Link löschen",
"collectionView_shareSheet_shareLinkButton": "Link teilen",
"collectionsPage_collection_favourites": "Deine Favoriten",
"collectionsPage_collection_random": "Zufällig ausgewählt",
"collectionsPage_collection_recents": "Zuletzt hinzugefügt",
"collectionsPage_noGemsMessage": "Erstelle eine neue Gemme, um loszulegen.",
Expand Down
1 change: 1 addition & 0 deletions app/lib/localization/arb/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"collectionView_shareSheet_createLinkButton": "Create a share link",
"collectionView_shareSheet_deleteLinkButton": "Delete the link",
"collectionView_shareSheet_shareLinkButton": "Share the link",
"collectionsPage_collection_favourites": "Your favourites",
"collectionsPage_collection_random": "Randomly selected",
"collectionsPage_collection_recents": "Recently added",
"collectionsPage_noGemsMessage": "Create a new gem to get started.",
Expand Down
6 changes: 6 additions & 0 deletions app/lib/localization/generated/localizations.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ abstract class CAppL10n {
/// **'Share the link'**
String get collectionView_shareSheet_shareLinkButton;

/// No description provided for @collectionsPage_collection_favourites.
///
/// In en, this message translates to:
/// **'Your favourites'**
String get collectionsPage_collection_favourites;

/// No description provided for @collectionsPage_collection_random.
///
/// In en, this message translates to:
Expand Down
3 changes: 3 additions & 0 deletions app/lib/localization/generated/localizations_de.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class CAppL10nDe extends CAppL10n {
@override
String get collectionView_shareSheet_shareLinkButton => 'Link teilen';

@override
String get collectionsPage_collection_favourites => 'Deine Favoriten';

@override
String get collectionsPage_collection_random => 'Zufällig ausgewählt';

Expand Down
3 changes: 3 additions & 0 deletions app/lib/localization/generated/localizations_en.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class CAppL10nEn extends CAppL10n {
@override
String get collectionView_shareSheet_shareLinkButton => 'Share the link';

@override
String get collectionsPage_collection_favourites => 'Your favourites';

@override
String get collectionsPage_collection_random => 'Randomly selected';

Expand Down
1 change: 1 addition & 0 deletions app/lib/pages/_pages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export 'create_gem/page.dart';
export 'demo/page.dart';
export 'edit_gem/page.dart';
export 'edit_person/page.dart';
export 'favourites_collection/page.dart';
export 'gem/page.dart';
export 'get_started/page.dart';
export 'home/page.dart';
Expand Down
30 changes: 18 additions & 12 deletions app/lib/pages/chest/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,24 @@ class CChestPage extends StatelessWidget implements AutoRouteWrapper {
authRepository: context.read(),
),
child: BlocProvider(
create: (context) =>
CChestPeopleFetchCubit(personRepository: context.read())
..fetchChestPeople(
chestID: context.read<CCurrentChestCubit>().state.id,
),
child: BlocListener<CChestPeopleFetchCubit, CChestPeopleFetchState>(
listener: (context, _) =>
context.read<CAppSettingsCubit>().updateLastViewedChest(
context.read<CCurrentChestCubit>().state.id,
),
listenWhen: (_, state) => state.succeeded,
child: this,
create: (context) => CGemLikesCubit(
gemRepository: context.read(),
chestID: context.read<CCurrentChestCubit>().state.id,
)..fetchLikedGemIDs(),
child: BlocProvider(
create: (context) =>
CChestPeopleFetchCubit(personRepository: context.read())
..fetchChestPeople(
chestID: context.read<CCurrentChestCubit>().state.id,
),
child: BlocListener<CChestPeopleFetchCubit, CChestPeopleFetchState>(
listener: (context, _) =>
context.read<CAppSettingsCubit>().updateLastViewedChest(
context.read<CCurrentChestCubit>().state.id,
),
listenWhen: (_, state) => state.succeeded,
child: this,
),
),
),
);
Expand Down
1 change: 1 addition & 0 deletions app/lib/pages/collections/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class CCollectionsPage extends StatelessWidget implements AutoRouteWrapper {
const SizedBox(height: 8),
const CRecentsCollectionTile(),
const CRandomCollectionTile(),
const CFavouritesCollectionTile(),
],
),
),
Expand Down
1 change: 1 addition & 0 deletions app/lib/pages/collections/widgets/_widgets.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'favourites_collection_tile.dart';
export 'random_collection_tile.dart';
export 'recents_collection_tile.dart';
export 'year_collections_section.dart';
24 changes: 24 additions & 0 deletions app/lib/pages/collections/widgets/favourites_collection_tile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:auto_route/auto_route.dart';
import 'package:chuckle_chest/app/routes.dart';
import 'package:chuckle_chest/localization/l10n.dart';
import 'package:flutter/material.dart';

/// {@template CFavouritesCollectionTile}
///
/// The tile for the favourites collection on the collections page.
///
/// {@endtemplate}
class CFavouritesCollectionTile extends StatelessWidget {
/// {@macro CFavouritesCollectionTile}
const CFavouritesCollectionTile({super.key});

@override
Widget build(BuildContext context) {
return ListTile(
minVerticalPadding: 16,
leading: const Icon(Icons.favorite_rounded),
title: Text(context.cAppL10n.collectionsPage_collection_favourites),
onTap: () => context.router.push(const CFavouritesCollectionRoute()),
);
}
}
1 change: 1 addition & 0 deletions app/lib/pages/demo/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CDemoPage extends StatelessWidget implements AutoRouteWrapper {
body: CCollectionView<CDemoCubit, CDemoState, BobsNothing, CSharedGem>(
gemTokens: cubit.gemTokens,
userRole: CUserRole.viewer,
isShared: true,
gemFromState: (state) => state.gem,
gemTokenFromState: (state) => state.gemID,
triggerFetchGem: (context, token) => cubit.emitGemWithToken(token),
Expand Down
1 change: 1 addition & 0 deletions app/lib/pages/favourites_collection/logic/_logic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'favourite_gem_ids_fetch_cubit.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:bloc/bloc.dart';
import 'package:cgem_repository/cgem_repository.dart';
import 'package:mallard_bloc/mallard_bloc.dart';

/// The state for the [CFavouriteGemIDsFetchCubit].
typedef CFavouriteGemIDsFetchState =
TaskBlocState<List<String>, CGemIDsFetchException>;

/// {@template CFavouriteGemIDsFetchCubit}
///
/// The cubit for handling fetching the IDs of the liked gems.
///
/// {@endtemplate}
class CFavouriteGemIDsFetchCubit extends Cubit<CFavouriteGemIDsFetchState>
with TaskCubitMixin {
/// {@macro CFavouriteGemIDsFetchCubit}
CFavouriteGemIDsFetchCubit({
required this.gemRepository,
required this.chestID,
}) : super(TaskBlocState.initial());

/// The repository this cubit uses to fetch the gem IDs.
final CGemRepository gemRepository;

/// The ID of the chest to fetch the liked gems from.
final String chestID;

/// Fetches the IDs of the liked gems.
Future<void> fetchLikedGemIDs() =>
request(gemRepository.fetchLikedGemIDs(chestID: chestID));
}
81 changes: 81 additions & 0 deletions app/lib/pages/favourites_collection/page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'package:auto_route/auto_route.dart';
import 'package:cgem_repository/cgem_repository.dart';
import 'package:chuckle_chest/pages/favourites_collection/logic/_logic.dart';
import 'package:chuckle_chest/shared/_shared.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mallard_bloc/mallard_bloc.dart';

/// {@template CFavouritesCollectionPage}
///
/// The page for displaying a collection of the gems the user has liked.
///
/// It fetches the IDs of the liked gems and then displays them in a
/// [CCollectionView] which allow the user to view the gems one by one.
///
/// {@endtemplate}
@RoutePage()
class CFavouritesCollectionPage extends StatelessWidget
implements AutoRouteWrapper {
/// {@macro CFavouritesCollectionPage}
const CFavouritesCollectionPage({super.key});

@override
Widget wrappedRoute(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => CFavouriteGemIDsFetchCubit(
gemRepository: context.read(),
chestID: context.read<CCurrentChestCubit>().state.id,
)..fetchLikedGemIDs(),
),
BlocProvider(
create: (context) => CGemFetchCubit(gemRepository: context.read()),
),
],
child: this,
);
}

@override
Widget build(BuildContext context) {
return BlocBuilder<CFavouriteGemIDsFetchCubit, CFavouriteGemIDsFetchState>(
builder: (context, state) => Scaffold(
body: switch (state.status) {
TaskBlocStatus.initial => const Center(
child: CCradleLoadingIndicator(),
),
TaskBlocStatus.inProgress => const Center(
child: CCradleLoadingIndicator(),
),
TaskBlocStatus.failed => const Center(
child: Icon(Icons.error_rounded),
),
TaskBlocStatus.succeeded =>
CCollectionView<
CGemFetchCubit,
CGemFetchState,
CGemFetchException,
CGem
>(
gemTokens: state.success!,
userRole: context.read<CCurrentChestCubit>().state.userRole,
gemFromState: (state) => state.gem,
gemTokenFromState: (state) => state.gemID,
triggerFetchGem: (context, token) =>
context.read<CGemFetchCubit>().fetchGem(gemID: token),
onFetchFailed: (failure) => switch (failure) {
CGemFetchException.notFound => const CErrorSnackBar(
message: "We couldn't find that gem.",
).show(context),
CGemFetchException.unknown => const CErrorSnackBar().show(
context,
),
},
),
},
),
);
}
}
1 change: 1 addition & 0 deletions app/lib/pages/shared_gem/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class CSharedGemPage extends StatelessWidget implements AutoRouteWrapper {
>(
gemTokens: [shareToken ?? ''],
userRole: CUserRole.viewer,
isShared: true,
gemFromState: (state) => state.gem,
gemTokenFromState: (state) => shareToken ?? '',
triggerFetchGem: (context, token) => context
Expand Down
1 change: 1 addition & 0 deletions app/lib/shared/logic/_logic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export 'current_chest_cubit.dart';
export 'current_user_cubit.dart';
export 'gem_fetch_cubit.dart';
export 'gem_fetch_from_share_token.dart';
export 'gem_likes_cubit.dart';
export 'invitation_accept_cubit.dart';
export 'request_cubit.dart';
export 'signout_cubit.dart';
Expand Down
Loading
Loading