Skip to content

Commit bfa9e00

Browse files
Merge pull request #14 from strvcom/mu/refactor/sealed_classes
2 parents 596bb64 + 5b33352 commit bfa9e00

18 files changed

Lines changed: 91 additions & 146 deletions

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ For the purpose of Fraud prevention, user safety, and compliance the dedicated A
564564
# Todos
565565
- Fix Riverpod async gaps - analytics manager (keep live)
566566
- Revisit Google and Apple logins - Providers, Cancellation exception, separating Credentials from Sign In. USe Firebase directly for Apple on Android.
567-
- Refactor Sealed classes - private classes, use generated `when` function instead of switch.
568567

569568
<!-- ################################################## -->
570569
<!-- ########## Authors ########## -->

lib/common/data/entity/exception/custom_exception.dart

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ part 'custom_exception.freezed.dart';
1616
sealed class CustomException with _$CustomException implements Exception {
1717
const CustomException._();
1818

19-
const factory CustomException.general() = CustomExceptionGeneral;
20-
const factory CustomException.withMessage({String? message}) = CustomExceptionWithMessage;
21-
const factory CustomException.unauthenticated() = CustomExceptionUnauthenticated;
22-
const factory CustomException.notConnectedToTheInternet() = CustomExceptionNotConnectedToTheInternet;
23-
const factory CustomException.decodingFailed() = CustomExceptionDecodingFailed;
19+
const factory CustomException.general() = _General;
20+
const factory CustomException.withMessage({String? message}) = _WithMessage;
21+
const factory CustomException.unauthenticated() = _Unauthenticated;
22+
const factory CustomException.notConnectedToTheInternet() = _NotConnectedToTheInternet;
23+
const factory CustomException.decodingFailed() = _DecodingFailed;
2424

2525
// Note: Mapped Firebase exception with error code `credential-already-in-use`.
26-
const factory CustomException.signInCancelled() = CustomExceptionSignInCancelled;
27-
const factory CustomException.credentialAlreadyInUse({required AuthCredential? credential}) = CustomExceptionCredentialAlreadyInUse;
26+
const factory CustomException.signInCancelled() = _SignInCancelled;
27+
const factory CustomException.credentialAlreadyInUse({required AuthCredential? credential}) = _CredentialAlreadyInUse;
2828

2929
factory CustomException.fromErrorObject({required Object? error}) {
3030
Flogger.e('[CustomException] Received error $error, ');
@@ -78,21 +78,17 @@ sealed class CustomException with _$CustomException implements Exception {
7878
}
7979
}
8080

81-
String getMessage({required BuildContext context}) {
82-
return switch (this) {
83-
CustomExceptionWithMessage(message: final message) => message ?? context.locale.customExceptionGeneralMessage,
84-
CustomExceptionUnauthenticated() => context.locale.customExceptionUnauthenticatedMessage,
85-
CustomExceptionNotConnectedToTheInternet() => context.locale.customExceptionInternetConnectionMessage,
86-
_ => context.locale.customExceptionGeneralMessage,
87-
};
88-
}
81+
String getMessage({required BuildContext context}) => maybeWhen(
82+
withMessage: (message) => message ?? context.locale.customExceptionGeneralMessage,
83+
unauthenticated: () => context.locale.customExceptionUnauthenticatedMessage,
84+
notConnectedToTheInternet: () => context.locale.customExceptionInternetConnectionMessage,
85+
orElse: () => context.locale.customExceptionGeneralMessage,
86+
);
8987

90-
String getDetails({required BuildContext context}) {
91-
return switch (this) {
92-
CustomExceptionNotConnectedToTheInternet() => context.locale.customExceptionInternetConnectionDetails,
93-
_ => context.locale.customExceptionGeneralDetails,
94-
};
95-
}
88+
String getDetails({required BuildContext context}) => maybeWhen(
89+
notConnectedToTheInternet: () => context.locale.customExceptionInternetConnectionDetails,
90+
orElse: () => context.locale.customExceptionGeneralDetails,
91+
);
9692

9793
Future<void> showErrorSnackbar({
9894
required BuildContext context,

lib/common/data/entity/exception/validator_exception.dart

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,10 @@ part 'validator_exception.freezed.dart';
77
sealed class ValidatorException with _$ValidatorException implements Exception {
88
const ValidatorException._();
99

10-
const factory ValidatorException.generalIsEmpty(String Function(BuildContext) getText) = ValidatorExceptionGeneralIsEmpty;
11-
const factory ValidatorException.generalIsTooShort(String Function(BuildContext) getText) = ValidatorExceptionGeneralIsTooShort;
12-
const factory ValidatorException.generalIsTooLong(String Function(BuildContext) getText) = ValidatorExceptionGeneralIsTooLong;
13-
const factory ValidatorException.generalIsInvalid(String Function(BuildContext) getText) = ValidatorExceptionGeneralIsInvalid;
10+
const factory ValidatorException.generalIsEmpty(String Function(BuildContext) getText) = _GeneralIsEmpty;
11+
const factory ValidatorException.generalIsTooShort(String Function(BuildContext) getText) = _GeneralIsTooShort;
12+
const factory ValidatorException.generalIsTooLong(String Function(BuildContext) getText) = _GeneralIsTooLong;
13+
const factory ValidatorException.generalIsInvalid(String Function(BuildContext) getText) = _GeneralIsInvalid;
1414

15-
String getMessage({required BuildContext context}) {
16-
return switch (this) {
17-
ValidatorExceptionGeneralIsEmpty(getText: final getText) => getText(context),
18-
ValidatorExceptionGeneralIsTooShort(getText: final getText) => getText(context),
19-
ValidatorExceptionGeneralIsTooLong(getText: final getText) => getText(context),
20-
ValidatorExceptionGeneralIsInvalid(getText: final getText) => getText(context),
21-
};
22-
}
15+
String getMessage({required BuildContext context}) => getText(context);
2316
}

lib/common/data/entity/notification_payload_entity.dart

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ enum NotificationType {
1616
NotificationType.values.firstWhereOrNull((e) => e.value == value) ?? NotificationType.unknown;
1717
}
1818

19-
@Freezed(fromJson: true, toJson: true)
19+
@Freezed(fromJson: true)
2020
sealed class NotificationPayloadEntity with _$NotificationPayloadEntity {
2121
const NotificationPayloadEntity._();
2222

@@ -25,24 +25,18 @@ sealed class NotificationPayloadEntity with _$NotificationPayloadEntity {
2525
required int id,
2626
required String title,
2727
required String body,
28-
@Default(NotificationType.sample) NotificationType type,
29-
}) = NotificationPayloadEntitySample;
28+
}) = _Sample;
3029

31-
// Subtitle: unknown
32-
const factory NotificationPayloadEntity.unknown({
33-
@Default(-1) int id,
34-
@Default('') String title,
35-
@Default('') String body,
36-
@Default(NotificationType.unknown) NotificationType type,
37-
}) = NotificationPayloadEntityUnknown;
30+
// Title: Unknown
31+
const factory NotificationPayloadEntity.unknown() = _Unknown;
3832

3933
factory NotificationPayloadEntity.fromJson(Map<String, dynamic> json) {
4034
switch (NotificationType.fromString(json['type'] as String?)) {
4135
case NotificationType.sample:
42-
return NotificationPayloadEntitySample.fromJson(json);
36+
return _Sample.fromJson(json);
4337

4438
case NotificationType.unknown:
45-
return const NotificationPayloadEntityUnknown();
39+
return const _Unknown();
4640
}
4741
}
4842
}

lib/common/provider/notifications_service.dart

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ class NotificationsService extends _$NotificationsService {
5353
}
5454

5555
static void handleNotificationOpen(NotificationPayloadEntity notification) {
56-
switch (notification) {
57-
case NotificationPayloadEntitySample():
56+
notification.when(
57+
sample: (id, title, body) {
5858
Flogger.d('[Notifications] Handle open of Sample notification');
59-
// TODO(strv): [Notifications] Handle Notification open action here
60-
61-
case NotificationPayloadEntityUnknown():
62-
// Do nothing
63-
}
59+
// TODO(strv): [Notifications] Handle Notification open action here
60+
},
61+
unknown: () {
62+
// Do nothing
63+
},
64+
);
6465
}
6566

6667
static Future<void> handleAppOpenNotification() async {
@@ -74,14 +75,18 @@ class NotificationsService extends _$NotificationsService {
7475
}
7576

7677
static Future<void> showNotification(NotificationPayloadEntity notification) async {
77-
if (notification is NotificationPayloadEntityUnknown) return;
78-
7978
Flogger.i('[Notifications] New local notification to display: $notification');
79+
final notificationData = notification.when(sample: (id, title, body) => (id: id, title: title, body: body), unknown: () => null);
80+
81+
if (notificationData == null) {
82+
return;
83+
}
84+
8085
await _flutterLocalNotifications.cancelAll();
8186
await _flutterLocalNotifications.show(
82-
notification.id,
83-
notification.title,
84-
notification.body,
87+
notificationData.id,
88+
notificationData.title,
89+
notificationData.body,
8590
defaultNotificationDetails,
8691
payload: jsonEncode(notification),
8792
);

lib/common/usecase/authentication/sign_in_with_auth_credential_use_case.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ FutureOr<UserEntity> signInWithAuthCredentialUseCase(
2626
Flogger.d('[Authentication] Anonymous user was linked with google credential');
2727
} on Exception catch (error) {
2828
final customException = CustomException.fromErrorObject(error: error);
29-
final credentialIsAlreadyInUse = switch (customException) {
30-
CustomExceptionCredentialAlreadyInUse(credential: final credential) => credential,
31-
_ => null,
32-
};
29+
final credentialIsAlreadyInUse = customException.whenOrNull(
30+
credentialAlreadyInUse: (credential) => credential,
31+
);
3332

3433
if (credentialIsAlreadyInUse != null) {
3534
await FirebaseAuth.instance.signInWithCredential(credentialIsAlreadyInUse);

lib/common/validator/controller/text_validator_controller_general.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,5 @@ class TextValidatorControllerGeneral extends TextValidatorController {
6464
notifyListeners();
6565
}
6666

67-
bool get isValid => _state is TextFieldValidatorStateValid;
68-
69-
bool get isInvalid => _state is TextFieldValidatorStateInvalid;
67+
bool get isValid => _state.isValid;
7068
}

lib/common/validator/text_field_validator_state.dart

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,19 @@ part 'text_field_validator_state.freezed.dart';
88
sealed class TextFieldValidatorState with _$TextFieldValidatorState {
99
const TextFieldValidatorState._();
1010

11-
const factory TextFieldValidatorState.initial() = TextFieldValidatorStateInitial;
12-
const factory TextFieldValidatorState.valid() = TextFieldValidatorStateValid;
13-
const factory TextFieldValidatorState.invalid({required ValidatorException exception}) = TextFieldValidatorStateInvalid;
11+
const factory TextFieldValidatorState.initial() = _Initial;
12+
const factory TextFieldValidatorState.valid() = _Valid;
13+
const factory TextFieldValidatorState.invalid({required ValidatorException exception}) = _Invalid;
1414

15-
bool get isValid {
16-
return switch (this) {
17-
TextFieldValidatorStateValid() => true,
18-
_ => false,
19-
};
20-
}
15+
bool get isValid => maybeWhen(
16+
valid: () => true,
17+
orElse: () => false,
18+
);
2119

22-
bool get hasError {
23-
return switch (this) {
24-
TextFieldValidatorStateInvalid() => true,
25-
_ => false,
26-
};
27-
}
20+
bool get hasError => maybeWhen(
21+
invalid: (_) => true,
22+
orElse: () => false,
23+
);
2824

29-
String? getErrorMessage(BuildContext context) {
30-
return switch (this) {
31-
TextFieldValidatorStateInvalid(exception: final exception) => exception.getMessage(context: context),
32-
_ => null,
33-
};
34-
}
25+
String? getErrorMessage(BuildContext context) => whenOrNull(invalid: (exception) => exception.getMessage(context: context));
3526
}

lib/core/analytics/analytics_material_page.dart

Lines changed: 0 additions & 20 deletions
This file was deleted.

lib/core/analytics/analytics_screen_view.dart

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)