Skip to content

Commit

Permalink
Introduce Riverpod (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
jogboms authored Jul 3, 2023
2 parents edf33f8 + 7611663 commit f88a6a4
Show file tree
Hide file tree
Showing 125 changed files with 2,126 additions and 2,292 deletions.
17 changes: 2 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,9 @@

---

TailorMade is what actually started out as an experiment with [Flutter](https://flutter.io/), [~flutter_redux~](https://github.com/brianegan/flutter_redux) [ReBLoC](https://github.com/redbrogdon/rebloc) and [Firebase Cloud Functions](https://github.com/flutter/plugins/tree/master/packages/cloud_functions) but instead turned out to be a valuable tool for managing a Fashion designer's daily routine. It is clean, easy on the eyes and overall has a very smooth feel. It also handles offline use cases with Firebase Cloud. Logo, Design & Concept by Me.
TailorMade is what actually started out as an experiment with [Flutter](https://flutter.io/) and [Firebase Cloud Functions](https://github.com/flutter/plugins/tree/master/packages/cloud_functions) but instead turned out to be a valuable tool for managing a Fashion designer's daily routine. It is clean, easy on the eyes and overall has a very smooth feel. It also handles offline use cases with Firebase Cloud. Logo, Design & Concept by Me.

## Tools

- Firebase Auth
- Firebase Cloud Firestore
- Firebase Cloud Functions
- Firebase Storage
- Google SignIn
- RxDart
- ReBLoC
- Built Value & Collection
- Equatable
- Injector

For a full description of OSS used, see pubspec.yaml
> For a full description of OSS used, see pubspec.yaml
## UI Shots

Expand Down
2 changes: 2 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ analyzer:
unused_result: error
unused_shown_name: error
invalid_annotation_target: ignore
plugins:
- custom_lint
language:
strict-casts: true
strict-raw-types: true
Expand Down
3 changes: 2 additions & 1 deletion l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
"bannedUserMessage": "This account has been disabled by administration",
"loadingMessage": "Loading...",
"tryAgainMessage": "Do try again after some time",
"popupBlockedByBrowserMessage": "The auto-login popup was blocked by your browser. Try the continue button"
"popupBlockedByBrowserMessage": "The auto-login popup was blocked by your browser. Try the continue button",
"continueWithGoogle": "Continue with Google"
}
1 change: 0 additions & 1 deletion lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ export 'core/environment.dart';
export 'core/error_handling/error_boundary.dart';
export 'core/error_handling/error_reporter.dart';
export 'core/error_handling/handle_uncaught_error.dart';
export 'core/group_by.dart';
7 changes: 0 additions & 7 deletions lib/core/group_by.dart

This file was deleted.

17 changes: 16 additions & 1 deletion lib/data/repositories/accounts/accounts_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class AccountsImpl extends Accounts {
static const String collectionName = 'accounts';

@override
Future<void> signInWithGoogle() => firebase.auth.signInWithGoogle();
Future<void> signIn() => firebase.auth.signInWithGoogle();

@override
Stream<String?> get onAuthStateChanged => firebase.auth.onAuthStateChanged;
Expand Down Expand Up @@ -44,6 +44,21 @@ class AccountsImpl extends Accounts {
return account.uid;
}

@override
Future<AccountEntity> fetch() async {
final String? id = firebase.auth.getUser;
if (id == null) {
throw const AuthException.userNotFound();
}

final AccountEntity? account = await getAccount(id);
if (account == null) {
throw const AuthException.userNotFound();
}

return account;
}

@override
Future<AccountEntity?> getAccount(String userId) async {
final MapDocumentSnapshot doc = await collection.fetchOne(userId).get();
Expand Down
5 changes: 4 additions & 1 deletion lib/data/repositories/accounts/accounts_mock_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:tailor_made/domain.dart';

class AccountsMockImpl extends Accounts {
@override
Future<void> signInWithGoogle() async {
Future<void> signIn() async {
return;
}

Expand All @@ -21,6 +21,9 @@ class AccountsMockImpl extends Accounts {
return;
}

@override
Future<AccountEntity> fetch() async => (await getAccount('1'))!;

@override
Future<AccountEntity?> getAccount(String userId) async {
return const AccountEntity(
Expand Down
3 changes: 3 additions & 0 deletions lib/domain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ export 'domain/repositories/measures.dart';
export 'domain/repositories/payments.dart';
export 'domain/repositories/settings.dart';
export 'domain/repositories/stats.dart';
export 'domain/use_cases/fetch_account_use_case.dart';
export 'domain/use_cases/sign_in_use_case.dart';
export 'domain/use_cases/sign_out_use_case.dart';
1 change: 1 addition & 0 deletions lib/domain/entities.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export 'entities/account_entity.dart';
export 'entities/auth_exception.dart';
export 'entities/contact_entity.dart';
export 'entities/create_contact_data.dart';
export 'entities/create_image_data.dart';
Expand Down
65 changes: 65 additions & 0 deletions lib/domain/entities/auth_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
sealed class AuthException {
const factory AuthException.unknown(Exception exception) = AuthExceptionUnknown;

const factory AuthException.canceled() = AuthExceptionCanceled;

const factory AuthException.failed() = AuthExceptionFailed;

const factory AuthException.networkUnavailable() = AuthExceptionNetworkUnavailable;

const factory AuthException.popupBlockedByBrowser() = AuthExceptionPopupBlockedByBrowser;

const factory AuthException.invalidEmail({String? email}) = AuthExceptionInvalidEmail;

const factory AuthException.userDisabled({String? email}) = AuthExceptionUserDisabled;

const factory AuthException.userNotFound({String? email}) = AuthExceptionUserNotFound;

const factory AuthException.tooManyRequests({String? email}) = AuthExceptionTooManyRequests;
}

class AuthExceptionUnknown implements AuthException {
const AuthExceptionUnknown(this.exception);

final Exception exception;
}

class AuthExceptionCanceled implements AuthException {
const AuthExceptionCanceled();
}

class AuthExceptionFailed implements AuthException {
const AuthExceptionFailed();
}

class AuthExceptionNetworkUnavailable implements AuthException {
const AuthExceptionNetworkUnavailable();
}

class AuthExceptionPopupBlockedByBrowser implements AuthException {
const AuthExceptionPopupBlockedByBrowser();
}

class AuthExceptionInvalidEmail implements AuthException {
const AuthExceptionInvalidEmail({this.email});

final String? email;
}

class AuthExceptionUserDisabled implements AuthException {
const AuthExceptionUserDisabled({this.email});

final String? email;
}

class AuthExceptionUserNotFound implements AuthException {
const AuthExceptionUserNotFound({this.email});

final String? email;
}

class AuthExceptionTooManyRequests implements AuthException {
const AuthExceptionTooManyRequests({this.email});

final String? email;
}
4 changes: 3 additions & 1 deletion lib/domain/repositories/accounts.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import '../entities.dart';

abstract class Accounts {
Future<void> signInWithGoogle();
Future<void> signIn();

Stream<String?> get onAuthStateChanged;

Future<void>? signOut();

Future<void> signUp(AccountEntity account);

Future<AccountEntity> fetch();

Future<AccountEntity?> getAccount(String userId);

Future<bool> updateAccount(
Expand Down
10 changes: 10 additions & 0 deletions lib/domain/use_cases/fetch_account_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import '../entities/account_entity.dart';
import '../repositories/accounts.dart';

class FetchAccountUseCase {
const FetchAccountUseCase({required Accounts accounts}) : _accounts = accounts;

final Accounts _accounts;

Future<AccountEntity> call() => _accounts.fetch();
}
41 changes: 41 additions & 0 deletions lib/domain/use_cases/sign_in_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'dart:async';

import 'package:rxdart/transformers.dart';
import 'package:tailor_made/core.dart';

import '../entities/account_entity.dart';
import '../entities/auth_exception.dart';
import '../repositories/accounts.dart';

class SignInUseCase {
const SignInUseCase({required Accounts accounts}) : _accounts = accounts;

final Accounts _accounts;

Future<AccountEntity> call() async {
final Completer<AccountEntity> completer = Completer<AccountEntity>();

late StreamSubscription<void> sub;
sub = _accounts.onAuthStateChanged.whereType<String>().listen(
(_) {
completer.complete(_accounts.fetch());
sub.cancel();
},
onError: (Object error, StackTrace stackTrace) {
completer.completeError(error, stackTrace);
sub.cancel();
},
);

try {
await _accounts.signIn();
} on AuthException catch (error, stackTrace) {
if (error is AuthExceptionFailed) {
AppLog.e(error, stackTrace);
}
rethrow;
}

return completer.future;
}
}
29 changes: 29 additions & 0 deletions lib/domain/use_cases/sign_out_use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'dart:async';

import '../repositories/accounts.dart';

class SignOutUseCase {
const SignOutUseCase({required Accounts accounts}) : _accounts = accounts;

final Accounts _accounts;

Future<void> call() async {
final Completer<void> completer = Completer<void>();

late StreamSubscription<void> sub;
sub = _accounts.onAuthStateChanged.where((String? id) => id == null).listen(
(_) {
completer.complete();
sub.cancel();
},
onError: (Object error, StackTrace st) {
completer.completeError(error, st);
sub.cancel();
},
);

await _accounts.signOut();

return completer.future;
}
}
29 changes: 19 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'dart:async' as async;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:registry/registry.dart';
import 'package:universal_io/io.dart' as io;

import 'core.dart';
Expand Down Expand Up @@ -72,6 +74,9 @@ void main(List<String> args) async {
..set<Payments>(repository.payments)
..set<Measures>(repository.measures)
..set<Stats>(repository.stats)
..factory((RegistryFactory di) => FetchAccountUseCase(accounts: di()))
..factory((RegistryFactory di) => SignInUseCase(accounts: di()))
..factory((RegistryFactory di) => SignOutUseCase(accounts: di()))
..set<ContactsCoordinator>(ContactsCoordinator(navigatorKey))
..set<GalleryCoordinator>(GalleryCoordinator(navigatorKey))
..set<SharedCoordinator>(SharedCoordinator(navigatorKey))
Expand All @@ -81,16 +86,20 @@ void main(List<String> args) async {
..set<TasksCoordinator>(TasksCoordinator(navigatorKey));

runApp(
ErrorBoundary(
isReleaseMode: !environment.isDebugging,
errorViewBuilder: (_) => const AppCrashErrorView(),
onException: AppLog.e,
onCrash: errorReporter.reportCrash,
child: App(
registry: registry,
navigatorKey: navigatorKey,
store: storeFactory(registry),
navigatorObservers: <NavigatorObserver>[navigationObserver],
ProviderScope(
overrides: <Override>[
registryProvider.overrideWithValue(registry),
],
child: ErrorBoundary(
isReleaseMode: !environment.isDebugging,
errorViewBuilder: (_) => const AppCrashErrorView(),
onException: AppLog.e,
onCrash: errorReporter.reportCrash,
child: App(
registry: registry,
navigatorKey: navigatorKey,
navigatorObservers: <NavigatorObserver>[navigationObserver],
),
),
),
);
Expand Down
2 changes: 1 addition & 1 deletion lib/presentation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export 'presentation/app.dart';
export 'presentation/constants.dart';
export 'presentation/coordinator.dart';
export 'presentation/mixins.dart';
export 'presentation/rebloc.dart';
export 'presentation/registry.dart';
export 'presentation/state.dart';
export 'presentation/theme.dart';
export 'presentation/utils.dart';
export 'presentation/widgets.dart';
Loading

0 comments on commit f88a6a4

Please sign in to comment.