Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add avatar upload #53

Merged
merged 6 commits into from
Oct 12, 2024
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
10 changes: 9 additions & 1 deletion app/lib/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:chuckle_chest/shared/widgets/_widgets.dart';
import 'package:chuckle_chest/shared/widgets/client_provider.dart';
import 'package:cperson_repository/cperson_repository.dart';
import 'package:cplatform_client/cplatform_client.dart';
import 'package:cstorage_client/cstorage_client.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -47,6 +48,7 @@ class _ChuckleChestAppState extends State<ChuckleChestApp> {
late CPlatformClient platformClient;
late CAuthClient authClient;
late CPersonClient personClient;
late CStorageClient storageClient;

late CAuthRepository authRepository;
late CChestRepository chestRepository;
Expand Down Expand Up @@ -77,6 +79,7 @@ class _ChuckleChestAppState extends State<ChuckleChestApp> {
peopleTable: peopleTable,
avatarsTable: avatarsTable,
);
storageClient = CStorageClient(supabaseClient: supabaseClient);

authRepository = CAuthRepository(
authClient: CAuthClient(authClient: supabaseClient.auth),
Expand All @@ -86,7 +89,11 @@ class _ChuckleChestAppState extends State<ChuckleChestApp> {
gemClient: gemClient,
platformClient: platformClient,
);
personRepository = CPersonRepository(personClient: personClient);
personRepository = CPersonRepository(
personClient: personClient,
storageClient: storageClient,
platformClient: platformClient,
);

appRouter = CAppRouter(authRepository: authRepository);

Expand All @@ -103,6 +110,7 @@ class _ChuckleChestAppState extends State<ChuckleChestApp> {
CClientProvider.value(value: chestClient),
CClientProvider.value(value: gemClient),
CClientProvider.value(value: personClient),
CClientProvider.value(value: storageClient),
],
child: MultiRepositoryProvider(
providers: [
Expand Down
4 changes: 4 additions & 0 deletions app/lib/app/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ class CAppRouter extends _$CAppRouter implements AutoRouteGuard {
path: 'edit-person',
page: CEditPersonRoute.page,
),
AutoRoute(
path: 'edit-avatar',
page: CEditAvatarRoute.page,
),
],
),
],
Expand Down
67 changes: 61 additions & 6 deletions app/lib/app/router.gr.dart

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

11 changes: 10 additions & 1 deletion app/lib/localization/arb/intl_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"collectionsPage_section_title_other": "Sonstige",
"collectionsPage_section_title_years": "Springe zu Jahr",
"delete": "Löschen",
"editAvatarPage_pickPhotoButton": "Foto auswählen",
"editAvatarPage_title": "Bild Für {year} Bearbeiten",
"@editAvatarPage_title": {
"placeholders": {
"year": {
"type": "int"
}
}
},
"editGemPage_addNarrationButton": "Neue Erzählung",
"editGemPage_addQuoteButton": "Neues Zitat",
"editGemPage_dateTile_title": "Datum",
Expand All @@ -22,7 +31,7 @@
"editGemPage_helperMessage": "Tippe auf etwas, um es zu bearbeiten.",
"editGemPage_title_create": "Gemme erstellen",
"editGemPage_title_edit": "Gemme bearbeiten",
"editPersonPage_banner_message": "Änderungen werden beim nächsten Öffnen der App auf andere Benutzer übertragen.",
"editPersonPage_banner_message": "Das Schließen dieser Seite wird die App neu laden, wenn Änderungen vorgenommen wurden.",
"editPersonPage_dateOfBirthTile_title": "Geburtsdatum",
"editPersonPage_editNicknameDialog_title": "Spitzname bearbeiten",
"editPersonPage_nicknameTile_title": "Spitzname",
Expand Down
11 changes: 10 additions & 1 deletion app/lib/localization/arb/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"collectionsPage_section_title_other": "Other",
"collectionsPage_section_title_years": "Jump to year",
"delete": "Delete",
"editAvatarPage_pickPhotoButton": "Pick a photo",
"editAvatarPage_title": "Edit Photo for {year}",
"@editAvatarPage_title": {
"placeholders": {
"year": {
"type": "int"
}
}
},
"editGemPage_addNarrationButton": "Add a narration",
"editGemPage_addQuoteButton": "Add a quote",
"editGemPage_dateTile_title": "Date",
Expand All @@ -22,7 +31,7 @@
"editGemPage_helperMessage": "Tap anything to edit.",
"editGemPage_title_create": "Create a gem",
"editGemPage_title_edit": "Edit the gem",
"editPersonPage_banner_message": "Changes will propagate to other users next time they open the app.",
"editPersonPage_banner_message": "Closing this page will reload the app if changes have been made.",
"editPersonPage_dateOfBirthTile_title": "Date of birth",
"editPersonPage_editNicknameDialog_title": "Edit nickname",
"editPersonPage_nicknameTile_title": "Nickname",
Expand Down
14 changes: 13 additions & 1 deletion app/lib/localization/generated/localizations.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,18 @@ abstract class CAppL10n {
/// **'Delete'**
String get delete;

/// No description provided for @editAvatarPage_pickPhotoButton.
///
/// In en, this message translates to:
/// **'Pick a photo'**
String get editAvatarPage_pickPhotoButton;

/// No description provided for @editAvatarPage_title.
///
/// In en, this message translates to:
/// **'Edit Photo for {year}'**
String editAvatarPage_title(int year);

/// No description provided for @editGemPage_addNarrationButton.
///
/// In en, this message translates to:
Expand Down Expand Up @@ -230,7 +242,7 @@ abstract class CAppL10n {
/// No description provided for @editPersonPage_banner_message.
///
/// In en, this message translates to:
/// **'Changes will propagate to other users next time they open the app.'**
/// **'Closing this page will reload the app if changes have been made.'**
String get editPersonPage_banner_message;

/// No description provided for @editPersonPage_dateOfBirthTile_title.
Expand Down
10 changes: 9 additions & 1 deletion app/lib/localization/generated/localizations_de.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ class CAppL10nDe extends CAppL10n {
@override
String get delete => 'Löschen';

@override
String get editAvatarPage_pickPhotoButton => 'Foto auswählen';

@override
String editAvatarPage_title(int year) {
return 'Bild Für $year Bearbeiten';
}

@override
String get editGemPage_addNarrationButton => 'Neue Erzählung';

Expand Down Expand Up @@ -75,7 +83,7 @@ class CAppL10nDe extends CAppL10n {
String get editGemPage_title_edit => 'Gemme bearbeiten';

@override
String get editPersonPage_banner_message => 'Änderungen werden beim nächsten Öffnen der App auf andere Benutzer übertragen.';
String get editPersonPage_banner_message => 'Das Schließen dieser Seite wird die App neu laden, wenn Änderungen vorgenommen wurden.';

@override
String get editPersonPage_dateOfBirthTile_title => 'Geburtsdatum';
Expand Down
10 changes: 9 additions & 1 deletion app/lib/localization/generated/localizations_en.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ class CAppL10nEn extends CAppL10n {
@override
String get delete => 'Delete';

@override
String get editAvatarPage_pickPhotoButton => 'Pick a photo';

@override
String editAvatarPage_title(int year) {
return 'Edit Photo for $year';
}

@override
String get editGemPage_addNarrationButton => 'Add a narration';

Expand Down Expand Up @@ -75,7 +83,7 @@ class CAppL10nEn extends CAppL10n {
String get editGemPage_title_edit => 'Edit the gem';

@override
String get editPersonPage_banner_message => 'Changes will propagate to other users next time they open the app.';
String get editPersonPage_banner_message => 'Closing this page will reload the app if changes have been made.';

@override
String get editPersonPage_dateOfBirthTile_title => 'Date of birth';
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 @@ -2,6 +2,7 @@ export 'base/page.dart';
export 'chest/page.dart';
export 'collections/page.dart';
export 'create_gem/page.dart';
export 'edit_avatar/page.dart';
export 'edit_gem/page.dart';
export 'edit_person/page.dart';
export 'gem/page.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class _CYearCollectionCard extends StatelessWidget {
final people = context.read<CChestPeopleFetchCubit>().state.people;

final avatars = people
.map((p) => p.avatarURLForDate(DateTime(year)))
.map((p) => p.avatarURLForDate(DateTime(year))?.url)
.where((a) => a != null)
.toList()
.cast<String>()
Expand Down
2 changes: 1 addition & 1 deletion app/lib/pages/create_gem/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ class CCreateGemPage extends StatelessWidget implements AutoRouteWrapper {
}

@override
Widget build(BuildContext context) => const CEditGemPage(gem: null);
Widget build(BuildContext context) => const CEditGemPage(initialGem: null);
}
2 changes: 2 additions & 0 deletions app/lib/pages/edit_avatar/logic/_logic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'avatar_pick_cubit.dart';
export 'avatar_update_cubit.dart';
55 changes: 55 additions & 0 deletions app/lib/pages/edit_avatar/logic/avatar_pick_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:bloc/bloc.dart';
import 'package:bobs_jobs/bobs_jobs.dart';
import 'package:chuckle_chest/shared/logic/_logic.dart';
import 'package:cperson_repository/cperson_repository.dart';
import 'package:flutter/foundation.dart';

/// {@template CAvatarPickState}
///
/// The state for the [CAvatarPickCubit].
///
/// {@endtemplate}
class CAvatarPickState
extends CRequestCubitState<CAvatarPickException, BobsMaybe<Uint8List>> {
/// {@macro CAvatarPickState}
///
/// The initial state.
CAvatarPickState.initial() : super.initial();

/// {@macro CAvatarPickState}
///
/// The in progress state.
CAvatarPickState.inProgress() : super.inProgress();

/// {@macro CAvatarPickState}
///
/// The completed state.
CAvatarPickState.completed({required super.outcome}) : super.completed();

/// The image to be uploaded.
BobsMaybe<Uint8List> get image => success;
}

/// {@template CAvatarPickCubit}
///
/// A cubit for allowing the user to pick an avatar.
///
/// {@endtemplate}
class CAvatarPickCubit extends Cubit<CAvatarPickState> {
/// {@macro CAvatarPickCubit}
CAvatarPickCubit({required this.personRepository})
: super(CAvatarPickState.initial());

/// The repository this cubit uses to pick an avatar.
final CPersonRepository personRepository;

/// Allows the user to pick an image from their gallery.
Future<void> pickAvatar() async {
emit(CAvatarPickState.inProgress());

final result =
await personRepository.pickAvatar().run(isDebugMode: kDebugMode);

emit(CAvatarPickState.completed(outcome: result));
}
}
Loading