Skip to content

Commit

Permalink
More riverpod (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
jogboms committed Jul 4, 2023
2 parents af85ace + 74eb2c0 commit a0a62d5
Show file tree
Hide file tree
Showing 33 changed files with 781 additions and 703 deletions.
8 changes: 4 additions & 4 deletions lib/data/repositories/measures/measures_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class MeasuresImpl extends Measures {
Future<bool> create(
List<BaseMeasureEntity> measures,
String userId, {
required MeasureGroup groupName,
required String unitValue,
required MeasureGroup group,
required String unit,
}) async {
await firebase.db.batchAction((_) {
for (final BaseMeasureEntity measure in measures) {
Expand All @@ -40,8 +40,8 @@ class MeasuresImpl extends Measures {
final ReferenceEntity reference = measure.reference;
final MapDocumentReference ref = collection.db.doc(reference.path);
_.update(ref, <String, String?>{
'group': groupName.displayName,
'unit': unitValue,
'group': group.displayName,
'unit': unit,
});
break;
case DefaultMeasureEntity():
Expand Down
4 changes: 2 additions & 2 deletions lib/data/repositories/measures/measures_mock_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ class MeasuresMockImpl extends Measures {
Future<bool> create(
List<BaseMeasureEntity> measures,
String userId, {
required MeasureGroup groupName,
required String unitValue,
required MeasureGroup group,
required String unit,
}) async =>
true;

Expand Down
4 changes: 2 additions & 2 deletions lib/domain/repositories/measures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ abstract class Measures {
Future<bool> create(
List<BaseMeasureEntity> measures,
String userId, {
required MeasureGroup groupName,
required String unitValue,
required MeasureGroup group,
required String unit,
});

Future<bool> deleteGroup(List<MeasureEntity> measures, String userId);
Expand Down
1 change: 0 additions & 1 deletion lib/presentation.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export 'presentation/app.dart';
export 'presentation/constants.dart';
export 'presentation/registry.dart';
export 'presentation/state.dart';
export 'presentation/theme.dart';
export 'presentation/utils.dart';
Expand Down
54 changes: 25 additions & 29 deletions lib/presentation/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:registry/registry.dart';
import 'package:tailor_made/core.dart';

import 'registry.dart';
import 'routing.dart';
import 'screens/splash/splash.dart';
import 'theme.dart';
Expand Down Expand Up @@ -34,35 +33,32 @@ class _AppState extends State<App> {

@override
Widget build(BuildContext context) {
return RegistryProvider(
registry: widget.registry,
child: _Banner(
key: Key(_bannerMessage),
visible: !_environment.isProduction,
message: _bannerMessage,
child: MaterialApp(
debugShowCheckedModeBanner: false,
color: Colors.white,
return _Banner(
key: Key(_bannerMessage),
visible: !_environment.isProduction,
message: _bannerMessage,
child: MaterialApp(
debugShowCheckedModeBanner: false,
color: Colors.white,
navigatorKey: _navigatorKey,
navigatorObservers: widget.navigatorObservers ?? <NavigatorObserver>[],
theme: themeBuilder(ThemeData.light()),
darkTheme: themeBuilder(ThemeData.dark()),
onGenerateTitle: (BuildContext context) => context.l10n.appName,
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
L10n.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: L10n.supportedLocales,
builder: (_, Widget? child) => SnackBarProvider(
navigatorKey: _navigatorKey,
navigatorObservers: widget.navigatorObservers ?? <NavigatorObserver>[],
theme: themeBuilder(ThemeData.light()),
darkTheme: themeBuilder(ThemeData.dark()),
onGenerateTitle: (BuildContext context) => context.l10n.appName,
localizationsDelegates: const <LocalizationsDelegate<dynamic>>[
L10n.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: L10n.supportedLocales,
builder: (_, Widget? child) => SnackBarProvider(
navigatorKey: _navigatorKey,
child: child!,
),
onGenerateRoute: (RouteSettings settings) => _PageRoute<Object>(
builder: (_) => widget.home ?? const SplashPage(isColdStart: true),
settings: RouteSettings(name: AppRoutes.start, arguments: settings.arguments),
),
child: child!,
),
onGenerateRoute: (RouteSettings settings) => _PageRoute<Object>(
builder: (_) => widget.home ?? const SplashPage(isColdStart: true),
settings: RouteSettings(name: AppRoutes.start, arguments: settings.arguments),
),
),
);
Expand Down
25 changes: 0 additions & 25 deletions lib/presentation/registry.dart

This file was deleted.

2 changes: 1 addition & 1 deletion lib/presentation/screens/contacts/contacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class _ContactsPageState extends State<ContactsPage> {
),
onWillPop: () async {
final SearchContactQueryState queryState = ref.read(searchContactQueryStateProvider.notifier);
if (queryState.isSearching) {
if (queryState.isSearching()) {
queryState.setState('');
return false;
}
Expand Down
33 changes: 10 additions & 23 deletions lib/presentation/screens/contacts/contacts_create.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:registry/registry.dart';
import 'package:tailor_made/core.dart';
import 'package:tailor_made/domain.dart';
import 'package:tailor_made/presentation.dart';

import '../../routing.dart';
import 'providers/contact_provider.dart';
import 'widgets/contact_form.dart';

class ContactsCreatePage extends StatefulWidget {
Expand Down Expand Up @@ -58,18 +58,11 @@ class _ContactsCreatePageState extends State<ContactsCreatePage> {
],
),
body: Consumer(
builder: (BuildContext context, WidgetRef ref, Widget? child) => ref.watch(accountProvider).when(
skipLoadingOnReload: true,
data: (AccountEntity data) => ContactForm(
key: _formKey,
contact: _contact,
onHandleSubmit: (CreateContactData contact) => _handleSubmit(contact, data.uid),
userId: data.uid,
),
error: ErrorView.new,
loading: () => child!,
),
child: const Center(child: LoadingSpinner()),
builder: (BuildContext context, WidgetRef ref, _) => ContactForm(
key: _formKey,
contact: _contact,
onHandleSubmit: (CreateContactData contact) => _handleSubmit(ref.read(contactProvider), contact),
),
),
);
}
Expand All @@ -78,7 +71,6 @@ class _ContactsCreatePageState extends State<ContactsCreatePage> {
final Contact? selectedContact = await _contactPicker.selectContact();
final String? fullName = selectedContact?.fullName;
final String? phoneNumber = selectedContact?.phoneNumbers?.firstOrNull;

if (selectedContact == null || fullName == null || phoneNumber == null) {
return;
}
Expand All @@ -91,31 +83,26 @@ class _ContactsCreatePageState extends State<ContactsCreatePage> {
);
}

void _handleSubmit(CreateContactData contact, String userId) async {
void _handleSubmit(ContactProvider contactProvider, CreateContactData contact) async {
final AppSnackBar snackBar = AppSnackBar.of(context);
if (contact.measurements.isEmpty) {
snackBar.info(AppStrings.leavingEmptyMeasures);
return;
}

final Registry registry = context.registry;
final Contacts contacts = registry.get();
final AppRouter router = context.router;
snackBar.loading();

final AppRouter router = context.router;
try {
contact = contact.copyWith(
fullname: contact.fullname,
phone: contact.phone,
imageUrl: contact.imageUrl,
location: contact.location,
);

// TODO(Jogboms): move this out of here
final ContactEntity snap = await contacts.create(userId, contact);
final ContactEntity result = await contactProvider.create(contact: contact);
snackBar.success('Successfully Added');

router.toContact(snap.id, replace: true);
router.toContact(result.id, replace: true);
} catch (error, stackTrace) {
AppLog.e(error, stackTrace);
snackBar.error(error.toString());
Expand Down
38 changes: 9 additions & 29 deletions lib/presentation/screens/contacts/contacts_edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tailor_made/core.dart';
import 'package:tailor_made/domain.dart';

import '../../registry.dart';
import '../../state.dart';
import '../../widgets.dart';
import 'providers/contact_provider.dart';
import 'widgets/contact_form.dart';

class ContactsEditPage extends StatefulWidget {
Expand Down Expand Up @@ -38,55 +37,36 @@ class _ContactsEditPageState extends State<ContactsEditPage> {
],
),
body: Consumer(
builder: (BuildContext context, WidgetRef ref, Widget? child) => ref.watch(accountProvider).when(
skipLoadingOnReload: true,
data: (AccountEntity data) => ContactForm(
key: _formKey,
contact: _contact,
onHandleSubmit: (CreateContactData contact) => _handleSubmit(contact, data.uid),
userId: data.uid,
),
error: ErrorView.new,
loading: () => child!,
),
child: const Center(child: LoadingSpinner()),
builder: (BuildContext context, WidgetRef ref, _) => ContactForm(
key: _formKey,
contact: _contact,
onHandleSubmit: (CreateContactData contact) => _handleSubmit(ref.read(contactProvider), contact),
),
),
);
}

void _handleSelectContact() async {
final CreateContactData contact = _contact;
final Contact? selectedContact = await _contactPicker.selectContact();
final String? fullName = selectedContact?.fullName;
final String? phoneNumber = selectedContact?.phoneNumbers?.firstOrNull;

if (selectedContact == null || fullName == null || phoneNumber == null) {
return;
}

_formKey.currentState?.updateContact(
contact.copyWith(
_contact.copyWith(
fullname: fullName,
phone: phoneNumber,
),
);
}

void _handleSubmit(CreateContactData contact, String userId) async {
void _handleSubmit(ContactProvider contactProvider, CreateContactData contact) async {
final AppSnackBar snackBar = AppSnackBar.of(context)..loading();

try {
// TODO(Jogboms): move this out of here
await context.registry.get<Contacts>().update(
userId,
reference: widget.contact.reference,
fullname: contact.fullname,
phone: contact.phone,
location: contact.location,
imageUrl: contact.imageUrl,
measurements: contact.measurements,
);

await contactProvider.update(reference: widget.contact.reference, contact: contact);
snackBar.success('Successfully Updated');
} catch (error, stackTrace) {
AppLog.e(error, stackTrace);
Expand Down
61 changes: 61 additions & 0 deletions lib/presentation/screens/contacts/providers/contact_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:flutter/foundation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:tailor_made/domain.dart';

import '../../../state.dart';

part 'contact_provider.g.dart';

@riverpod
ContactProvider contact(ContactRef ref) {
return ContactProvider(
fetchAccount: () => ref.read(accountProvider.future),
contacts: ref.read(registryProvider).get(),
);
}

class ContactProvider {
const ContactProvider({
required AsyncValueGetter<AccountEntity> fetchAccount,
required Contacts contacts,
}) : _fetchAccount = fetchAccount,
_contacts = contacts;

final AsyncValueGetter<AccountEntity> _fetchAccount;
final Contacts _contacts;

Future<ContactEntity> create({
required CreateContactData contact,
}) async {
final String userId = (await _fetchAccount()).uid;
return _contacts.create(userId, contact);
}

Future<void> update({
required ReferenceEntity reference,
required CreateContactData contact,
}) async {
final String userId = (await _fetchAccount()).uid;
await _contacts.update(
userId,
reference: reference,
fullname: contact.fullname,
phone: contact.phone,
location: contact.location,
imageUrl: contact.imageUrl,
measurements: contact.measurements,
);
}

Future<void> modifyMeasurements({
required ReferenceEntity reference,
required Map<String, double> measurements,
}) async {
final String userId = (await _fetchAccount()).uid;
await _contacts.update(
userId,
reference: reference,
measurements: measurements,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '../../../utils.dart';

part 'filtered_contacts_state_provider.g.dart';

@Riverpod(dependencies: <Object>[account, contacts, SearchContactQueryState, SearchContactSortState])
@Riverpod(dependencies: <Object>[contacts])
Future<FilteredContactsState> filteredContacts(FilteredContactsRef ref) async {
final List<ContactEntity> items = await ref.watch(contactsProvider.future);
final String query = ref.watch(searchContactQueryStateProvider).trim().toLowerCase();
Expand Down Expand Up @@ -44,7 +44,7 @@ class SearchContactQueryState extends _$SearchContactQueryState with StateNotifi
@override
String build() => '';

bool get isSearching => state.length > 1;
bool isSearching() => state.length > 1;
}

@riverpod
Expand Down
Loading

0 comments on commit a0a62d5

Please sign in to comment.