diff --git a/app/lib/ui/flow/setting/contact_support/contact_support_screen.dart b/app/lib/ui/flow/setting/contact_support/contact_support_screen.dart index aabc43aa..ee33ef6b 100644 --- a/app/lib/ui/flow/setting/contact_support/contact_support_screen.dart +++ b/app/lib/ui/flow/setting/contact_support/contact_support_screen.dart @@ -13,6 +13,7 @@ import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/app_text_dart.dart'; import 'package:style/text/app_text_field.dart'; import 'package:yourspace_flutter/domain/extenstions/context_extenstions.dart'; +import 'package:yourspace_flutter/ui/components/error_snakebar.dart'; import 'package:yourspace_flutter/ui/flow/setting/contact_support/contact_support_view_model.dart'; import '../../../components/app_page.dart'; @@ -33,6 +34,7 @@ class _ContactSupportScreenState extends ConsumerState { notifier = ref.watch(contactSupportViewStateProvider.notifier); final state = ref.watch(contactSupportViewStateProvider); _observePop(); + _observeError(); return AppPage( title: context.l10n.contact_support_title, @@ -206,4 +208,12 @@ class _ContactSupportScreenState extends ConsumerState { } }); } + + void _observeError() { + ref.listen(contactSupportViewStateProvider.select((state) => state.error), (previous, next) { + if (next != null) { + showErrorSnackBar(context, next.toString()); + } + }); + } } diff --git a/app/lib/ui/flow/setting/profile/profile_screen.dart b/app/lib/ui/flow/setting/profile/profile_screen.dart index 9e1a4cb0..dc697c6f 100644 --- a/app/lib/ui/flow/setting/profile/profile_screen.dart +++ b/app/lib/ui/flow/setting/profile/profile_screen.dart @@ -22,6 +22,7 @@ import 'package:yourspace_flutter/ui/flow/setting/profile/profile_view_model.dar import '../../../../gen/assets.gen.dart'; import '../../../components/action_bottom_sheet.dart'; import '../../../components/alert.dart'; +import '../../../components/error_snakebar.dart'; class ProfileScreen extends ConsumerStatefulWidget { const ProfileScreen({super.key}); @@ -40,6 +41,7 @@ class _ProfileScreenState extends ConsumerState { final state = ref.watch(editProfileViewStateProvider); _observePop(); _observeAccountDeleted(); + _observeError(); return AppPage( title: context.l10n.edit_profile_title, @@ -301,4 +303,12 @@ class _ProfileScreenState extends ConsumerState { } }); } + + void _observeError() { + ref.listen(editProfileViewStateProvider.select((state) => state.error), (previous, next) { + if (next != null) { + showErrorSnackBar(context, next.toString()); + } + }); + } } diff --git a/app/lib/ui/flow/setting/setting_screen.dart b/app/lib/ui/flow/setting/setting_screen.dart index 3f233969..e0c83acb 100644 --- a/app/lib/ui/flow/setting/setting_screen.dart +++ b/app/lib/ui/flow/setting/setting_screen.dart @@ -8,9 +8,9 @@ import 'package:style/extenstions/context_extenstions.dart'; import 'package:style/indicator/progress_indicator.dart'; import 'package:style/text/app_text_dart.dart'; import 'package:yourspace_flutter/domain/extenstions/context_extenstions.dart'; -import 'package:yourspace_flutter/domain/extenstions/widget_extensions.dart'; import 'package:yourspace_flutter/ui/app_route.dart'; import 'package:yourspace_flutter/ui/components/app_page.dart'; +import 'package:yourspace_flutter/ui/components/error_snakebar.dart'; import 'package:yourspace_flutter/ui/components/resume_detector.dart'; import 'package:yourspace_flutter/ui/flow/setting/setting_view_model.dart'; @@ -26,19 +26,12 @@ class SettingScreen extends ConsumerStatefulWidget { class _SettingScreenState extends ConsumerState { late SettingViewNotifier notifier; - @override - void initState() { - super.initState(); - runPostFrame(() { - notifier = ref.watch(settingViewStateProvider.notifier); - notifier.getUserSpace(); - }); - } - @override Widget build(BuildContext context) { + notifier = ref.watch(settingViewStateProvider.notifier); final state = ref.watch(settingViewStateProvider); _observeLogOut(); + _observeError(); return AppPage( title: context.l10n.settings_title, @@ -310,4 +303,12 @@ class _SettingScreenState extends ConsumerState { } }); } + + void _observeError() { + ref.listen(settingViewStateProvider.select((state) => state.error), (previous, next) { + if (next != null) { + showErrorSnackBar(context, next.toString()); + } + }); + } } diff --git a/app/lib/ui/flow/setting/setting_view_model.dart b/app/lib/ui/flow/setting/setting_view_model.dart index e0aa9555..d223597b 100644 --- a/app/lib/ui/flow/setting/setting_view_model.dart +++ b/app/lib/ui/flow/setting/setting_view_model.dart @@ -29,6 +29,7 @@ class SettingViewNotifier extends StateNotifier { SettingViewNotifier(this.spaceService, this.authService, this.userService, this.user) : super(const SettingViewState()) { getUser(); + getUserSpace(); } void getUser() { @@ -42,8 +43,8 @@ class SettingViewNotifier extends StateNotifier { try { state = state.copyWith(loading: state.spaces.isEmpty); final spaces = await spaceService.getUserSpaces(state.currentUser?.id ?? ''); - final nonNullSpaces = spaces.where((space) => space != null).cast().toList(); - state = state.copyWith(spaces: nonNullSpaces, loading: false); + final nonNullSpaces = spaces.where((space) => space != null).cast().toList(); + state = state.copyWith(spaces: nonNullSpaces, loading: false); } catch (error, stack) { logger.e( 'SettingViewNotifier: error while fetching user space', @@ -59,6 +60,7 @@ class SettingViewNotifier extends StateNotifier { await userService.signOut(); state = state.copyWith(signingOut: false, logOut: true); } catch (error, stack) { + state = state.copyWith(error: error); logger.e( 'SettingViewNotifier: error while sign out', error: error, @@ -77,5 +79,6 @@ class SettingViewState with _$SettingViewState { @Default('') String selectedSpaceName, @Default([]) List spaces, ApiUser? currentUser, + Object? error, }) = _SettingViewState; } diff --git a/app/lib/ui/flow/setting/setting_view_model.freezed.dart b/app/lib/ui/flow/setting/setting_view_model.freezed.dart index cec2d0bc..44202491 100644 --- a/app/lib/ui/flow/setting/setting_view_model.freezed.dart +++ b/app/lib/ui/flow/setting/setting_view_model.freezed.dart @@ -22,6 +22,7 @@ mixin _$SettingViewState { String get selectedSpaceName => throw _privateConstructorUsedError; List get spaces => throw _privateConstructorUsedError; ApiUser? get currentUser => throw _privateConstructorUsedError; + Object? get error => throw _privateConstructorUsedError; @JsonKey(ignore: true) $SettingViewStateCopyWith get copyWith => @@ -40,7 +41,8 @@ abstract class $SettingViewStateCopyWith<$Res> { bool logOut, String selectedSpaceName, List spaces, - ApiUser? currentUser}); + ApiUser? currentUser, + Object? error}); $ApiUserCopyWith<$Res>? get currentUser; } @@ -64,6 +66,7 @@ class _$SettingViewStateCopyWithImpl<$Res, $Val extends SettingViewState> Object? selectedSpaceName = null, Object? spaces = null, Object? currentUser = freezed, + Object? error = freezed, }) { return _then(_value.copyWith( loading: null == loading @@ -90,6 +93,7 @@ class _$SettingViewStateCopyWithImpl<$Res, $Val extends SettingViewState> ? _value.currentUser : currentUser // ignore: cast_nullable_to_non_nullable as ApiUser?, + error: freezed == error ? _value.error : error, ) as $Val); } @@ -120,7 +124,8 @@ abstract class _$$SettingViewStateImplCopyWith<$Res> bool logOut, String selectedSpaceName, List spaces, - ApiUser? currentUser}); + ApiUser? currentUser, + Object? error}); @override $ApiUserCopyWith<$Res>? get currentUser; @@ -143,6 +148,7 @@ class __$$SettingViewStateImplCopyWithImpl<$Res> Object? selectedSpaceName = null, Object? spaces = null, Object? currentUser = freezed, + Object? error = freezed, }) { return _then(_$SettingViewStateImpl( loading: null == loading @@ -169,6 +175,7 @@ class __$$SettingViewStateImplCopyWithImpl<$Res> ? _value.currentUser : currentUser // ignore: cast_nullable_to_non_nullable as ApiUser?, + error: freezed == error ? _value.error : error, )); } } @@ -182,7 +189,8 @@ class _$SettingViewStateImpl implements _SettingViewState { this.logOut = false, this.selectedSpaceName = '', final List spaces = const [], - this.currentUser}) + this.currentUser, + this.error}) : _spaces = spaces; @override @@ -208,10 +216,12 @@ class _$SettingViewStateImpl implements _SettingViewState { @override final ApiUser? currentUser; + @override + final Object? error; @override String toString() { - return 'SettingViewState(loading: $loading, signingOut: $signingOut, logOut: $logOut, selectedSpaceName: $selectedSpaceName, spaces: $spaces, currentUser: $currentUser)'; + return 'SettingViewState(loading: $loading, signingOut: $signingOut, logOut: $logOut, selectedSpaceName: $selectedSpaceName, spaces: $spaces, currentUser: $currentUser, error: $error)'; } @override @@ -227,7 +237,8 @@ class _$SettingViewStateImpl implements _SettingViewState { other.selectedSpaceName == selectedSpaceName) && const DeepCollectionEquality().equals(other._spaces, _spaces) && (identical(other.currentUser, currentUser) || - other.currentUser == currentUser)); + other.currentUser == currentUser) && + const DeepCollectionEquality().equals(other.error, error)); } @override @@ -238,7 +249,8 @@ class _$SettingViewStateImpl implements _SettingViewState { logOut, selectedSpaceName, const DeepCollectionEquality().hash(_spaces), - currentUser); + currentUser, + const DeepCollectionEquality().hash(error)); @JsonKey(ignore: true) @override @@ -255,7 +267,8 @@ abstract class _SettingViewState implements SettingViewState { final bool logOut, final String selectedSpaceName, final List spaces, - final ApiUser? currentUser}) = _$SettingViewStateImpl; + final ApiUser? currentUser, + final Object? error}) = _$SettingViewStateImpl; @override bool get loading; @@ -270,6 +283,8 @@ abstract class _SettingViewState implements SettingViewState { @override ApiUser? get currentUser; @override + Object? get error; + @override @JsonKey(ignore: true) _$$SettingViewStateImplCopyWith<_$SettingViewStateImpl> get copyWith => throw _privateConstructorUsedError; diff --git a/data/lib/api/auth/api_user_service.dart b/data/lib/api/auth/api_user_service.dart index 68bfc117..6367b5f9 100644 --- a/data/lib/api/auth/api_user_service.dart +++ b/data/lib/api/auth/api_user_service.dart @@ -104,12 +104,12 @@ class ApiUserService { return null; } - Stream getUserStream(String userId) { + Stream getUserStream(String userId) { return _userRef.doc(userId).snapshots().map((snapshot) { if (snapshot.exists) { return snapshot.data() as ApiUser; } else { - throw Exception('User not found'); + return null; } }); } diff --git a/data/lib/service/auth_service.dart b/data/lib/service/auth_service.dart index 6dc59023..8d39cb9d 100644 --- a/data/lib/service/auth_service.dart +++ b/data/lib/service/auth_service.dart @@ -55,12 +55,11 @@ class AuthService { return userService.getUser(_currentUser?.id ?? ''); } - Stream getUserStream() { + Stream getUserStream() { return userService.getUserStream(_currentUser?.id ?? ''); } Future deleteUser() { return userService.deleteUser(_currentUser?.id ?? ''); } - }