From 51ab1b6798f0aa10de413e27b44404fa3e49df84 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Tue, 5 Jul 2022 10:12:09 +0800 Subject: [PATCH 1/7] feat: add widget to update username --- .../app_flowy/assets/translations/en.json | 1 + .../presentation/home/menu/menu_user.dart | 2 +- .../settings/settings_dialog.dart | 19 +++++--- .../settings/widgets/settings_menu.dart | 10 ++++ .../widgets/settings_settings_view.dart | 48 +++++++++++++++++++ 5 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index a6f9b4d3ae..de2f8f7039 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -141,6 +141,7 @@ "menu": { "appearance": "Appearance", "language": "Language", + "settings": "Settings", "open": "Open Settings" }, "appearance": { diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart index 6b75c9ef3f..e819a0ed40 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart @@ -74,7 +74,7 @@ class MenuUser extends StatelessWidget { showDialog( context: context, builder: (context) { - return const SettingsDialog(); + return SettingsDialog(user); }, ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart index 8c7bb8f494..3d0f59bdd8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart @@ -2,13 +2,16 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_appearance_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_language_view.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_settings_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu.dart'; +import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class SettingsDialog extends StatefulWidget { - const SettingsDialog({Key? key}) : super(key: key); + final UserProfile user; + SettingsDialog(this.user, {Key? key}) : super(key: ValueKey(user.id)); @override State createState() => _SettingsDialogState(); @@ -17,10 +20,14 @@ class SettingsDialog extends StatefulWidget { class _SettingsDialogState extends State { int _selectedViewIndex = 0; - final List settingsViews = const [ - SettingsAppearanceView(), - SettingsLanguageView(), - ]; + Widget getSettingsView(int index, UserProfile user) { + final List settingsViews = [ + const SettingsAppearanceView(), + const SettingsLanguageView(), + SettingsSettingsView(user), + ]; + return settingsViews[index]; + } @override Widget build(BuildContext context) { @@ -59,7 +66,7 @@ class _SettingsDialogState extends State { const VerticalDivider(), const SizedBox(width: 10), Expanded( - child: settingsViews[_selectedViewIndex], + child: getSettingsView(_selectedViewIndex, widget.user), ) ], ), diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart index 241c337705..6900328f60 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -34,6 +34,16 @@ class SettingsMenu extends StatelessWidget { icon: Icons.translate, changeSelectedIndex: changeSelectedIndex, ), + const SizedBox( + height: 10, + ), + SettingsMenuElement( + index: 2, + currentIndex: currentIndex, + label: LocaleKeys.settings_menu_settings.tr(), + icon: Icons.account_box_outlined, + changeSelectedIndex: changeSelectedIndex, + ), ], ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart new file mode 100644 index 0000000000..6b33022577 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart @@ -0,0 +1,48 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:flutter/material.dart'; +import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; + +class SettingsSettingsView extends StatelessWidget { + final UserProfile user; + SettingsSettingsView(this.user, {Key? key}) : super(key: ValueKey(user.id)); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => getIt(param1: user)..add(const MenuUserEvent.initial()), + child: BlocBuilder( + builder: (context, state) => SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [UserNameInput()], + ), + ), + ), + ); + } +} + +class UserNameInput extends StatefulWidget { + const UserNameInput({ + Key? key, + }) : super(key: key); + + @override + State createState() => _UserNameInputState(); +} + +class _UserNameInputState extends State { + @override + Widget build(BuildContext context) { + return TextField( + decoration: const InputDecoration( + labelText: 'Name', + ), + onSubmitted: (val) { + context.read().add(MenuUserEvent.updateUserName(val)); + debugPrint("Value $val submitted"); + }); + } +} From f24e154b4fb5cb4776040c945c9fc5e89ef4d085 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Sat, 9 Jul 2022 22:00:17 +0800 Subject: [PATCH 2/7] refactor: create SettingsUserViewBloc --- .../app_flowy/assets/translations/en.json | 2 +- .../app_flowy/lib/startup/deps_resolver.dart | 6 ++ .../workspace/application/user/prelude.dart | 1 + .../application/user/settings_user_bloc.dart | 79 +++++++++++++++++++ .../settings/settings_dialog.dart | 4 +- .../settings/widgets/settings_menu.dart | 2 +- ...ings_view.dart => settings_user_view.dart} | 25 +++--- 7 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/user/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart rename frontend/app_flowy/lib/workspace/presentation/settings/widgets/{settings_settings_view.dart => settings_user_view.dart} (51%) diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index de2f8f7039..656c28be2e 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -141,7 +141,7 @@ "menu": { "appearance": "Appearance", "language": "Language", - "settings": "Settings", + "user": "User", "open": "Open Settings" }, "appearance": { diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 0cf248e7e4..ed382f9b83 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -5,6 +5,7 @@ import 'package:app_flowy/workspace/application/app/prelude.dart'; import 'package:app_flowy/workspace/application/doc/prelude.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; import 'package:app_flowy/workspace/application/trash/prelude.dart'; +import 'package:app_flowy/workspace/application/user/prelude.dart'; import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; @@ -101,6 +102,11 @@ void _resolveFolderDeps(GetIt getIt) { (user, _) => MenuUserBloc(user), ); + //User + getIt.registerFactoryParam( + (user, _) => SettingsUserViewBloc(user), + ); + // App getIt.registerFactoryParam( (app, _) => AppBloc( diff --git a/frontend/app_flowy/lib/workspace/application/user/prelude.dart b/frontend/app_flowy/lib/workspace/application/user/prelude.dart new file mode 100644 index 0000000000..f698497db9 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/user/prelude.dart @@ -0,0 +1 @@ +export 'settings_user_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart b/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart new file mode 100644 index 0000000000..5a4954c068 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart @@ -0,0 +1,79 @@ +import 'package:app_flowy/user/application/user_listener.dart'; +import 'package:app_flowy/user/application/user_service.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:dartz/dartz.dart'; + +part 'settings_user_bloc.freezed.dart'; + +class SettingsUserViewBloc extends Bloc { + final UserService _userService; + final UserListener _userListener; + final UserProfile userProfile; + + SettingsUserViewBloc(this.userProfile) + : _userListener = UserListener(userProfile: userProfile), + _userService = UserService(userId: userProfile.id), + super(SettingsUserState.initial(userProfile)) { + on((event, emit) async { + await event.when( + initial: () async { + _userListener.start(onProfileUpdated: _profileUpdated); + await _initUser(); + }, + didReceiveUserProfile: (UserProfile newUserProfile) { + emit(state.copyWith(userProfile: newUserProfile)); + }, + updateUserName: (String name) { + _userService.updateUserProfile(name: name).then((result) { + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }); + }, + ); + }); + } + + @override + Future close() async { + await _userListener.stop(); + super.close(); + } + + Future _initUser() async { + final result = await _userService.initUser(); + result.fold((l) => null, (error) => Log.error(error)); + } + + void _profileUpdated(Either userProfileOrFailed) { + userProfileOrFailed.fold( + (newUserProfile) => add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)), + (err) => Log.error(err), + ); + } +} + +@freezed +class SettingsUserEvent with _$SettingsUserEvent { + const factory SettingsUserEvent.initial() = _Initial; + const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName; + const factory SettingsUserEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile; +} + +@freezed +class SettingsUserState with _$SettingsUserState { + const factory SettingsUserState({ + required UserProfile userProfile, + required Either successOrFailure, + }) = _SettingsUserState; + + factory SettingsUserState.initial(UserProfile userProfile) => SettingsUserState( + userProfile: userProfile, + successOrFailure: left(unit), + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart index 3d0f59bdd8..72bb0bf7ac 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart @@ -2,7 +2,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_appearance_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_language_view.dart'; -import 'package:app_flowy/workspace/presentation/settings/widgets/settings_settings_view.dart'; +import 'package:app_flowy/workspace/presentation/settings/widgets/settings_user_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu.dart'; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; import 'package:easy_localization/easy_localization.dart'; @@ -24,7 +24,7 @@ class _SettingsDialogState extends State { final List settingsViews = [ const SettingsAppearanceView(), const SettingsLanguageView(), - SettingsSettingsView(user), + SettingsUserView(user), ]; return settingsViews[index]; } diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart index 6900328f60..a27d9861c4 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_menu.dart @@ -40,7 +40,7 @@ class SettingsMenu extends StatelessWidget { SettingsMenuElement( index: 2, currentIndex: currentIndex, - label: LocaleKeys.settings_menu_settings.tr(), + label: LocaleKeys.settings_menu_user.tr(), icon: Icons.account_box_outlined, changeSelectedIndex: changeSelectedIndex, ), diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart similarity index 51% rename from frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart rename to frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart index 6b33022577..b72df8f272 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_settings_view.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart @@ -1,22 +1,22 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:flutter/material.dart'; -import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart'; +import 'package:app_flowy/workspace/application/user/settings_user_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; -class SettingsSettingsView extends StatelessWidget { +class SettingsUserView extends StatelessWidget { final UserProfile user; - SettingsSettingsView(this.user, {Key? key}) : super(key: ValueKey(user.id)); + SettingsUserView(this.user, {Key? key}) : super(key: ValueKey(user.id)); @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => getIt(param1: user)..add(const MenuUserEvent.initial()), - child: BlocBuilder( + return BlocProvider( + create: (context) => getIt(param1: user)..add(const SettingsUserEvent.initial()), + child: BlocBuilder( builder: (context, state) => SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: const [UserNameInput()], + children: const [_UserNameInput()], ), ), ), @@ -24,16 +24,11 @@ class SettingsSettingsView extends StatelessWidget { } } -class UserNameInput extends StatefulWidget { - const UserNameInput({ +class _UserNameInput extends StatelessWidget { + const _UserNameInput({ Key? key, }) : super(key: key); - @override - State createState() => _UserNameInputState(); -} - -class _UserNameInputState extends State { @override Widget build(BuildContext context) { return TextField( @@ -41,7 +36,7 @@ class _UserNameInputState extends State { labelText: 'Name', ), onSubmitted: (val) { - context.read().add(MenuUserEvent.updateUserName(val)); + context.read().add(SettingsUserEvent.updateUserName(val)); debugPrint("Value $val submitted"); }); } From db165f70061433f291170f4d4cd406593cd0a285 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Sat, 9 Jul 2022 23:32:29 +0800 Subject: [PATCH 3/7] refactor: remove updateUserName from MenuUserBloc --- .../lib/workspace/application/menu/menu_user_bloc.dart | 9 --------- 1 file changed, 9 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart index 7433c758b0..d590621e2d 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart @@ -34,14 +34,6 @@ class MenuUserBloc extends Bloc { didReceiveUserProfile: (UserProfile newUserProfile) { emit(state.copyWith(userProfile: newUserProfile)); }, - updateUserName: (String name) { - _userService.updateUserProfile(name: name).then((result) { - result.fold( - (l) => null, - (err) => Log.error(err), - ); - }); - }, ); }); } @@ -74,7 +66,6 @@ class MenuUserBloc extends Bloc { class MenuUserEvent with _$MenuUserEvent { const factory MenuUserEvent.initial() = _Initial; const factory MenuUserEvent.fetchWorkspaces() = _FetchWorkspaces; - const factory MenuUserEvent.updateUserName(String name) = _UpdateUserName; const factory MenuUserEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile; } From 29ce17178375e3f19b5ca65d8313aa5bc6fbf059 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Sun, 10 Jul 2022 11:31:26 +0800 Subject: [PATCH 4/7] feat: show name on _UserNameInput --- .../settings/widgets/settings_user_view.dart | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart index b72df8f272..f347dbed7b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart @@ -16,28 +16,36 @@ class SettingsUserView extends StatelessWidget { builder: (context, state) => SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: const [_UserNameInput()], + children: [_renderUserNameInput(context)], ), ), ), ); } + + Widget _renderUserNameInput(BuildContext context) { + String name = context.read().state.userProfile.name; + debugPrint(name); + return _UserNameInput(name); + } } class _UserNameInput extends StatelessWidget { - const _UserNameInput({ + final String name; + const _UserNameInput( + this.name, { Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return TextField( + controller: TextEditingController()..text = name, decoration: const InputDecoration( labelText: 'Name', ), onSubmitted: (val) { context.read().add(SettingsUserEvent.updateUserName(val)); - debugPrint("Value $val submitted"); }); } } From a8b560ed935820e7a3df75c6c4998db73182e701 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Fri, 15 Jul 2022 09:09:56 +0800 Subject: [PATCH 5/7] debug: rerender username properly --- .../lib/workspace/presentation/home/menu/menu_user.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart index e819a0ed40..4bc2ce29c2 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart @@ -67,6 +67,7 @@ class MenuUser extends StatelessWidget { Widget _renderSettingsButton(BuildContext context) { final theme = context.watch(); + final userProfile = context.read().state.userProfile; return Tooltip( message: LocaleKeys.settings_menu_open.tr(), child: IconButton( @@ -74,7 +75,7 @@ class MenuUser extends StatelessWidget { showDialog( context: context, builder: (context) { - return SettingsDialog(user); + return SettingsDialog(userProfile); }, ); }, From da80efecd17b320b3c7f6c730b1110ed590e49e7 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Fri, 22 Jul 2022 00:01:39 +0800 Subject: [PATCH 6/7] feat: add SettingDialogBloc --- .../app_flowy/lib/startup/deps_resolver.dart | 6 ++ .../application/settings/prelude.dart | 1 + .../settings/settings_dialog_bloc.dart | 67 +++++++++++++ .../settings/settings_dialog.dart | 98 +++++++++---------- .../settings/widgets/settings_user_view.dart | 1 - 5 files changed, 122 insertions(+), 51 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/settings/prelude.dart create mode 100644 frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index ed382f9b83..bafbb46919 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -10,6 +10,7 @@ import 'package:app_flowy/workspace/application/workspace/prelude.dart'; import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart'; import 'package:app_flowy/workspace/application/view/prelude.dart'; import 'package:app_flowy/workspace/application/menu/prelude.dart'; +import 'package:app_flowy/workspace/application/settings/prelude.dart'; import 'package:app_flowy/user/application/prelude.dart'; import 'package:app_flowy/user/presentation/router.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; @@ -102,6 +103,11 @@ void _resolveFolderDeps(GetIt getIt) { (user, _) => MenuUserBloc(user), ); + //Settings + getIt.registerFactoryParam( + (user, _) => SettingsDialogBloc(user), + ); + //User getIt.registerFactoryParam( (user, _) => SettingsUserViewBloc(user), diff --git a/frontend/app_flowy/lib/workspace/application/settings/prelude.dart b/frontend/app_flowy/lib/workspace/application/settings/prelude.dart new file mode 100644 index 0000000000..3917b54aaf --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/settings/prelude.dart @@ -0,0 +1 @@ +export 'settings_dialog_bloc.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart b/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart new file mode 100644 index 0000000000..1dd73638b2 --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart @@ -0,0 +1,67 @@ +import 'package:app_flowy/user/application/user_listener.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:dartz/dartz.dart'; + +part 'settings_dialog_bloc.freezed.dart'; + +class SettingsDialogBloc extends Bloc { + final UserListener _userListener; + final UserProfile userProfile; + + SettingsDialogBloc(this.userProfile) + : _userListener = UserListener(userProfile: userProfile), + super(SettingsDialogState.initial(userProfile)) { + on((event, emit) async { + await event.when( + initial: () async { + _userListener.start(onProfileUpdated: _profileUpdated); + }, + didReceiveUserProfile: (UserProfile newUserProfile) { + emit(state.copyWith(userProfile: newUserProfile)); + }, + setViewIndex: (int viewIndex) { + emit(state.copyWith(viewIndex: viewIndex)); + }, + ); + }); + } + + @override + Future close() async { + await _userListener.stop(); + super.close(); + } + + void _profileUpdated(Either userProfileOrFailed) { + userProfileOrFailed.fold( + (newUserProfile) => add(SettingsDialogEvent.didReceiveUserProfile(newUserProfile)), + (err) => Log.error(err), + ); + } +} + +@freezed +class SettingsDialogEvent with _$SettingsDialogEvent { + const factory SettingsDialogEvent.initial() = _Initial; + const factory SettingsDialogEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile; + const factory SettingsDialogEvent.setViewIndex(int index) = _SetViewIndex; +} + +@freezed +class SettingsDialogState with _$SettingsDialogState { + const factory SettingsDialogState({ + required UserProfile userProfile, + required Either successOrFailure, + required int viewIndex, + }) = _SettingsDialogState; + + factory SettingsDialogState.initial(UserProfile userProfile) => SettingsDialogState( + userProfile: userProfile, + successOrFailure: left(unit), + viewIndex: 0, + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart index 72bb0bf7ac..ae4d3f5e52 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart @@ -1,25 +1,21 @@ +import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_appearance_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_language_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_user_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu.dart'; +import 'package:app_flowy/workspace/application/settings/settings_dialog_bloc.dart'; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; -class SettingsDialog extends StatefulWidget { +class SettingsDialog extends StatelessWidget { final UserProfile user; SettingsDialog(this.user, {Key? key}) : super(key: ValueKey(user.id)); - @override - State createState() => _SettingsDialogState(); -} - -class _SettingsDialogState extends State { - int _selectedViewIndex = 0; - Widget getSettingsView(int index, UserProfile user) { final List settingsViews = [ const SettingsAppearanceView(), @@ -31,47 +27,49 @@ class _SettingsDialogState extends State { @override Widget build(BuildContext context) { - return ChangeNotifierProvider.value( - value: Provider.of(context, listen: true), - child: AlertDialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - title: Text( - LocaleKeys.settings_title.tr(), - style: const TextStyle( - fontWeight: FontWeight.bold, - ), - ), - content: ConstrainedBox( - constraints: const BoxConstraints( - maxHeight: 600, - minWidth: 600, - maxWidth: 1000, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: 200, - child: SettingsMenu( - changeSelectedIndex: (index) { - setState(() { - _selectedViewIndex = index; - }); - }, - currentIndex: _selectedViewIndex, - ), - ), - const VerticalDivider(), - const SizedBox(width: 10), - Expanded( - child: getSettingsView(_selectedViewIndex, widget.user), - ) - ], - ), - ), - ), - ); + return BlocProvider( + create: (context) => getIt(param1: user)..add(const SettingsDialogEvent.initial()), + child: BlocBuilder( + builder: (context, state) => ChangeNotifierProvider.value( + value: Provider.of(context, listen: true), + child: AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + title: Text( + LocaleKeys.settings_title.tr(), + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + content: ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 600, + minWidth: 600, + maxWidth: 1000, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 200, + child: SettingsMenu( + changeSelectedIndex: (index) { + context.read().add(SettingsDialogEvent.setViewIndex(index)); + }, + currentIndex: context.read().state.viewIndex, + ), + ), + const VerticalDivider(), + const SizedBox(width: 10), + Expanded( + child: getSettingsView(context.read().state.viewIndex, + context.read().state.userProfile), + ) + ], + ), + ), + ), + ))); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart index f347dbed7b..6cc56ccf74 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart @@ -25,7 +25,6 @@ class SettingsUserView extends StatelessWidget { Widget _renderUserNameInput(BuildContext context) { String name = context.read().state.userProfile.name; - debugPrint(name); return _UserNameInput(name); } } From 1a887979c4991db4fc2ae95c91327debb8b50015 Mon Sep 17 00:00:00 2001 From: Ian Su Date: Fri, 22 Jul 2022 00:54:11 +0800 Subject: [PATCH 7/7] fix: fix merge from main --- .../workspace/application/menu/menu_user_bloc.dart | 8 ++++++++ .../application/settings/settings_dialog_bloc.dart | 12 ++++++------ .../application/user/settings_user_bloc.dart | 12 ++++++------ .../presentation/settings/settings_dialog.dart | 6 +++--- .../settings/widgets/settings_user_view.dart | 4 ++-- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart index e6cadcfe3a..0f30bb9d45 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_user_bloc.dart @@ -34,6 +34,14 @@ class MenuUserBloc extends Bloc { didReceiveUserProfile: (UserProfilePB newUserProfile) { emit(state.copyWith(userProfile: newUserProfile)); }, + updateUserName: (String name) { + _userService.updateUserProfile(name: name).then((result) { + result.fold( + (l) => null, + (err) => Log.error(err), + ); + }); + }, ); }); } diff --git a/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart b/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart index 1dd73638b2..3c40f767b1 100644 --- a/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/settings/settings_dialog_bloc.dart @@ -10,7 +10,7 @@ part 'settings_dialog_bloc.freezed.dart'; class SettingsDialogBloc extends Bloc { final UserListener _userListener; - final UserProfile userProfile; + final UserProfilePB userProfile; SettingsDialogBloc(this.userProfile) : _userListener = UserListener(userProfile: userProfile), @@ -20,7 +20,7 @@ class SettingsDialogBloc extends Bloc initial: () async { _userListener.start(onProfileUpdated: _profileUpdated); }, - didReceiveUserProfile: (UserProfile newUserProfile) { + didReceiveUserProfile: (UserProfilePB newUserProfile) { emit(state.copyWith(userProfile: newUserProfile)); }, setViewIndex: (int viewIndex) { @@ -36,7 +36,7 @@ class SettingsDialogBloc extends Bloc super.close(); } - void _profileUpdated(Either userProfileOrFailed) { + void _profileUpdated(Either userProfileOrFailed) { userProfileOrFailed.fold( (newUserProfile) => add(SettingsDialogEvent.didReceiveUserProfile(newUserProfile)), (err) => Log.error(err), @@ -47,19 +47,19 @@ class SettingsDialogBloc extends Bloc @freezed class SettingsDialogEvent with _$SettingsDialogEvent { const factory SettingsDialogEvent.initial() = _Initial; - const factory SettingsDialogEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile; + const factory SettingsDialogEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile; const factory SettingsDialogEvent.setViewIndex(int index) = _SetViewIndex; } @freezed class SettingsDialogState with _$SettingsDialogState { const factory SettingsDialogState({ - required UserProfile userProfile, + required UserProfilePB userProfile, required Either successOrFailure, required int viewIndex, }) = _SettingsDialogState; - factory SettingsDialogState.initial(UserProfile userProfile) => SettingsDialogState( + factory SettingsDialogState.initial(UserProfilePB userProfile) => SettingsDialogState( userProfile: userProfile, successOrFailure: left(unit), viewIndex: 0, diff --git a/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart b/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart index 5a4954c068..7435778471 100644 --- a/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/user/settings_user_bloc.dart @@ -12,7 +12,7 @@ part 'settings_user_bloc.freezed.dart'; class SettingsUserViewBloc extends Bloc { final UserService _userService; final UserListener _userListener; - final UserProfile userProfile; + final UserProfilePB userProfile; SettingsUserViewBloc(this.userProfile) : _userListener = UserListener(userProfile: userProfile), @@ -24,7 +24,7 @@ class SettingsUserViewBloc extends Bloc { _userListener.start(onProfileUpdated: _profileUpdated); await _initUser(); }, - didReceiveUserProfile: (UserProfile newUserProfile) { + didReceiveUserProfile: (UserProfilePB newUserProfile) { emit(state.copyWith(userProfile: newUserProfile)); }, updateUserName: (String name) { @@ -50,7 +50,7 @@ class SettingsUserViewBloc extends Bloc { result.fold((l) => null, (error) => Log.error(error)); } - void _profileUpdated(Either userProfileOrFailed) { + void _profileUpdated(Either userProfileOrFailed) { userProfileOrFailed.fold( (newUserProfile) => add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)), (err) => Log.error(err), @@ -62,17 +62,17 @@ class SettingsUserViewBloc extends Bloc { class SettingsUserEvent with _$SettingsUserEvent { const factory SettingsUserEvent.initial() = _Initial; const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName; - const factory SettingsUserEvent.didReceiveUserProfile(UserProfile newUserProfile) = _DidReceiveUserProfile; + const factory SettingsUserEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile; } @freezed class SettingsUserState with _$SettingsUserState { const factory SettingsUserState({ - required UserProfile userProfile, + required UserProfilePB userProfile, required Either successOrFailure, }) = _SettingsUserState; - factory SettingsUserState.initial(UserProfile userProfile) => SettingsUserState( + factory SettingsUserState.initial(UserProfilePB userProfile) => SettingsUserState( userProfile: userProfile, successOrFailure: left(unit), ); diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart index ae4d3f5e52..eaf09d770f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/settings_dialog.dart @@ -6,17 +6,17 @@ import 'package:app_flowy/workspace/presentation/settings/widgets/settings_langu import 'package:app_flowy/workspace/presentation/settings/widgets/settings_user_view.dart'; import 'package:app_flowy/workspace/presentation/settings/widgets/settings_menu.dart'; import 'package:app_flowy/workspace/application/settings/settings_dialog_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; +import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; class SettingsDialog extends StatelessWidget { - final UserProfile user; + final UserProfilePB user; SettingsDialog(this.user, {Key? key}) : super(key: ValueKey(user.id)); - Widget getSettingsView(int index, UserProfile user) { + Widget getSettingsView(int index, UserProfilePB user) { final List settingsViews = [ const SettingsAppearanceView(), const SettingsLanguageView(), diff --git a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart index 6cc56ccf74..f8f094d1b0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart +++ b/frontend/app_flowy/lib/workspace/presentation/settings/widgets/settings_user_view.dart @@ -2,10 +2,10 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:flutter/material.dart'; import 'package:app_flowy/workspace/application/user/settings_user_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfile; +import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart'; class SettingsUserView extends StatelessWidget { - final UserProfile user; + final UserProfilePB user; SettingsUserView(this.user, {Key? key}) : super(key: ValueKey(user.id)); @override