From 2f2b69d1a6447a66438a314c7f92365dc07b282a Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 5 May 2022 21:15:01 +0800 Subject: [PATCH] fix: view title update issue --- .../lib/user/application/user_listener.dart | 40 +++++++-------- .../workspace/application/app/app_bloc.dart | 6 +-- .../application/app/app_listener.dart | 8 +-- .../workspace/application/doc/doc_bloc.dart | 31 ++++++------ .../workspace/application/home/home_bloc.dart | 4 +- .../application/menu/menu_user_bloc.dart | 4 +- .../workspace/application/view/view_bloc.dart | 16 ++---- .../application/view/view_listener.dart | 50 +++++++++++++------ .../application/workspace/welcome_bloc.dart | 2 +- .../presentation/plugins/doc/document.dart | 5 +- .../plugins/widgets/left_bar_item.dart | 29 ++++++++--- 11 files changed, 113 insertions(+), 82 deletions(-) diff --git a/frontend/app_flowy/lib/user/application/user_listener.dart b/frontend/app_flowy/lib/user/application/user_listener.dart index acacb19b02..6bfede73ce 100644 --- a/frontend/app_flowy/lib/user/application/user_listener.dart +++ b/frontend/app_flowy/lib/user/application/user_listener.dart @@ -12,17 +12,17 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user; import 'package:flowy_sdk/rust_stream.dart'; -typedef UserProfileDidUpdate = Either; -typedef AuthDidUpdate = Either; -typedef WorkspaceListDidUpdate = Either, FlowyError>; -typedef WorkspaceSettingDidUpdate = Either; +typedef UserProfileNotifyValue = Either; +typedef AuthNotifyValue = Either; +typedef WorkspaceListNotifyValue = Either, FlowyError>; +typedef WorkspaceSettingNotifyValue = Either; class UserListener { StreamSubscription? _subscription; - final _profileNotifier = PublishNotifier(); - final _authNotifier = PublishNotifier(); - final _workspaceListNotifier = PublishNotifier(); - final _workSettingNotifier = PublishNotifier(); + final _profileNotifier = PublishNotifier(); + final _authNotifier = PublishNotifier(); + final _workspaceListNotifier = PublishNotifier(); + final _workSettingNotifier = PublishNotifier(); FolderNotificationParser? _workspaceParser; UserNotificationParser? _userParser; @@ -32,32 +32,32 @@ class UserListener { }) : _user = user; void start({ - void Function(AuthDidUpdate)? authDidChange, - void Function(UserProfileDidUpdate)? profileDidUpdate, - void Function(WorkspaceListDidUpdate)? workspaceListDidUpdate, - void Function(WorkspaceSettingDidUpdate)? workspaceSettingDidUpdate, + void Function(AuthNotifyValue)? onAuthChanged, + void Function(UserProfileNotifyValue)? onProfileUpdated, + void Function(WorkspaceListNotifyValue)? onWorkspaceListUpdated, + void Function(WorkspaceSettingNotifyValue)? onWorkspaceSettingUpdated, }) { - if (authDidChange != null) { + if (onAuthChanged != null) { _authNotifier.addListener(() { - authDidChange(_authNotifier.currentValue!); + onAuthChanged(_authNotifier.currentValue!); }); } - if (profileDidUpdate != null) { + if (onProfileUpdated != null) { _profileNotifier.addListener(() { - profileDidUpdate(_profileNotifier.currentValue!); + onProfileUpdated(_profileNotifier.currentValue!); }); } - if (workspaceListDidUpdate != null) { + if (onWorkspaceListUpdated != null) { _workspaceListNotifier.addListener(() { - workspaceListDidUpdate(_workspaceListNotifier.currentValue!); + onWorkspaceListUpdated(_workspaceListNotifier.currentValue!); }); } - if (workspaceSettingDidUpdate != null) { + if (onWorkspaceSettingUpdated != null) { _workSettingNotifier.addListener(() { - workspaceSettingDidUpdate(_workSettingNotifier.currentValue!); + onWorkspaceSettingUpdated(_workSettingNotifier.currentValue!); }); } diff --git a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart index 4dd10675e0..663e630a6a 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -41,7 +41,7 @@ class AppBloc extends Bloc { void _startListening() { appListener.start( - viewsChanged: (result) { + onViewsChanged: (result) { result.fold( (views) { if (!isClosed) { @@ -51,7 +51,7 @@ class AppBloc extends Bloc { (error) => Log.error(error), ); }, - appUpdated: (app) { + onAppUpdated: (app) { if (!isClosed) { add(AppEvent.appDidUpdate(app)); } @@ -97,7 +97,7 @@ class AppBloc extends Bloc { @override Future close() async { - await appListener.close(); + await appListener.stop(); return super.close(); } diff --git a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart index 46b16bb080..c1696e55f2 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart @@ -24,9 +24,9 @@ class AppListener { required this.appId, }); - void start({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) { - _viewsChanged = viewsChanged; - _updated = appUpdated; + void start({ViewsDidChangeCallback? onViewsChanged, AppDidUpdateCallback? onAppUpdated}) { + _viewsChanged = onViewsChanged; + _updated = onAppUpdated; _parser = FolderNotificationParser(id: appId, callback: _bservableCallback); _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable)); } @@ -60,7 +60,7 @@ class AppListener { } } - Future close() async { + Future stop() async { _parser = null; await _subscription?.cancel(); _viewsChanged = null; diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart index 8d944c34ac..20d232f07b 100644 --- a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart @@ -59,7 +59,7 @@ class DocumentBloc extends Bloc { @override Future close() async { - await listener.close(); + await listener.stop(); if (_subscription != null) { await _subscription?.cancel(); @@ -70,21 +70,20 @@ class DocumentBloc extends Bloc { } Future _initial(Initial value, Emitter emit) async { - listener.deletedNotifier.addPublishListener((result) { - result.fold( - (view) => add(const DocumentEvent.deleted()), - (error) {}, - ); - }); - - listener.restoredNotifier.addPublishListener((result) { - result.fold( - (view) => add(const DocumentEvent.restore()), - (error) {}, - ); - }); - - listener.start(); + listener.start( + onViewDeleted: (result) { + result.fold( + (view) => add(const DocumentEvent.deleted()), + (error) {}, + ); + }, + onViewRestored: (result) { + result.fold( + (view) => add(const DocumentEvent.restore()), + (error) {}, + ); + }, + ); final result = await service.openDocument(docId: view.id); result.fold( (block) { diff --git a/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart b/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart index f401f0a0ca..796a0357b9 100644 --- a/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/home/home_bloc.dart @@ -20,10 +20,10 @@ class HomeBloc extends Bloc { await event.map( initial: (_Initial value) { _listener.start( - authDidChange: (result) { + onAuthChanged: (result) { _authDidChanged(result); }, - workspaceSettingDidUpdate: (result) { + onWorkspaceSettingUpdated: (result) { result.fold( (setting) => add(HomeEvent.didReceiveWorkspaceSetting(setting)), (r) => Log.error(r), 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 d0970cae21..0da347c364 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 @@ -20,8 +20,8 @@ class MenuUserBloc extends Bloc { await event.map( initial: (_) async { userListener.start( - profileDidUpdate: _profileUpdated, - workspaceListDidUpdate: _workspaceListUpdated, + onProfileUpdated: _profileUpdated, + onWorkspaceListUpdated: _workspaceListUpdated, ); await _initUser(); }, diff --git a/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart b/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart index 5b5a953922..c33f44a8c1 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_bloc.dart @@ -21,12 +21,9 @@ class ViewBloc extends Bloc { on((event, emit) async { await event.map( initial: (e) { - // TODO: Listener can be refactored to a stream. - listener.updatedNotifier.addPublishListener((result) { - // emit.forEach(stream, onData: onData) + listener.start(onViewUpdated: (result) { add(ViewEvent.viewDidUpdate(result)); }); - listener.start(); emit(state); }, setIsEditing: (e) { @@ -34,14 +31,12 @@ class ViewBloc extends Bloc { }, viewDidUpdate: (e) { e.result.fold( - (view) => - emit(state.copyWith(view: view, successOrFailure: left(unit))), + (view) => emit(state.copyWith(view: view, successOrFailure: left(unit))), (error) => emit(state.copyWith(successOrFailure: right(error))), ); }, rename: (e) async { - final result = - await service.updateView(viewId: view.id, name: e.newName); + final result = await service.updateView(viewId: view.id, name: e.newName); emit( result.fold( (l) => state.copyWith(successOrFailure: left(unit)), @@ -74,7 +69,7 @@ class ViewBloc extends Bloc { @override Future close() async { - await listener.close(); + await listener.stop(); return super.close(); } } @@ -86,8 +81,7 @@ class ViewEvent with _$ViewEvent { const factory ViewEvent.rename(String newName) = Rename; const factory ViewEvent.delete() = Delete; const factory ViewEvent.duplicate() = Duplicate; - const factory ViewEvent.viewDidUpdate(Either result) = - ViewDidUpdate; + const factory ViewEvent.viewDidUpdate(Either result) = ViewDidUpdate; } @freezed diff --git a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart index ee27d55139..9a2d913941 100644 --- a/frontend/app_flowy/lib/workspace/application/view/view_listener.dart +++ b/frontend/app_flowy/lib/workspace/application/view/view_listener.dart @@ -15,9 +15,9 @@ typedef RestoreViewNotifiedValue = Either; class ViewListener { StreamSubscription? _subscription; - PublishNotifier updatedNotifier = PublishNotifier(); - PublishNotifier deletedNotifier = PublishNotifier(); - PublishNotifier restoredNotifier = PublishNotifier(); + final PublishNotifier _updatedViewNotifier = PublishNotifier(); + final PublishNotifier _deletedNotifier = PublishNotifier(); + final PublishNotifier _restoredNotifier = PublishNotifier(); FolderNotificationParser? _parser; View view; @@ -25,7 +25,29 @@ class ViewListener { required this.view, }); - void start() { + void start({ + void Function(UpdateViewNotifiedValue)? onViewUpdated, + void Function(DeleteViewNotifyValue)? onViewDeleted, + void Function(RestoreViewNotifiedValue)? onViewRestored, + }) { + if (onViewUpdated != null) { + _updatedViewNotifier.addListener(() { + onViewUpdated(_updatedViewNotifier.currentValue!); + }); + } + + if (onViewDeleted != null) { + _deletedNotifier.addListener(() { + onViewDeleted(_deletedNotifier.currentValue!); + }); + } + + if (onViewRestored != null) { + _restoredNotifier.addListener(() { + onViewRestored(_restoredNotifier.currentValue!); + }); + } + _parser = FolderNotificationParser( id: view.id, callback: (ty, result) { @@ -40,20 +62,20 @@ class ViewListener { switch (ty) { case FolderNotification.ViewUpdated: result.fold( - (payload) => updatedNotifier.value = left(View.fromBuffer(payload)), - (error) => updatedNotifier.value = right(error), + (payload) => _updatedViewNotifier.value = left(View.fromBuffer(payload)), + (error) => _updatedViewNotifier.value = right(error), ); break; case FolderNotification.ViewDeleted: result.fold( - (payload) => deletedNotifier.value = left(View.fromBuffer(payload)), - (error) => deletedNotifier.value = right(error), + (payload) => _deletedNotifier.value = left(View.fromBuffer(payload)), + (error) => _deletedNotifier.value = right(error), ); break; case FolderNotification.ViewRestored: result.fold( - (payload) => restoredNotifier.value = left(View.fromBuffer(payload)), - (error) => restoredNotifier.value = right(error), + (payload) => _restoredNotifier.value = left(View.fromBuffer(payload)), + (error) => _restoredNotifier.value = right(error), ); break; default: @@ -61,11 +83,11 @@ class ViewListener { } } - Future close() async { + Future stop() async { _parser = null; await _subscription?.cancel(); - updatedNotifier.dispose(); - deletedNotifier.dispose(); - restoredNotifier.dispose(); + _updatedViewNotifier.dispose(); + _deletedNotifier.dispose(); + _restoredNotifier.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart b/frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart index 8ad83925b4..a743a3316f 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/welcome_bloc.dart @@ -17,7 +17,7 @@ class WelcomeBloc extends Bloc { (event, emit) async { await event.map(initial: (e) async { userListener.start( - workspaceListDidUpdate: (result) => add(WelcomeEvent.workspacesReveived(result)), + onWorkspaceListUpdated: (result) => add(WelcomeEvent.workspacesReveived(result)), ); // await _fetchWorkspaces(emit); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart index b0727bb73a..5dcf744083 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/doc/document.dart @@ -60,7 +60,7 @@ class DocumentPlugin implements Plugin { DocumentPlugin({required PluginType pluginType, required View view, Key? key}) : _view = view { _pluginType = pluginType; _listener = getIt(param1: view); - _listener?.updatedNotifier.addPublishListener((result) { + _listener?.start(onViewUpdated: (result) { result.fold( (newView) { _view = newView; @@ -69,12 +69,11 @@ class DocumentPlugin implements Plugin { (error) {}, ); }); - _listener?.start(); } @override void dispose() { - _listener?.close(); + _listener?.stop(); _listener = null; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart index 7c1e819cc5..e81fc3e45d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/widgets/left_bar_item.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/view/view_listener.dart'; import 'package:app_flowy/workspace/application/view/view_service.dart'; import 'package:flowy_infra/theme.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -16,12 +18,26 @@ class ViewLeftBarItem extends StatefulWidget { class _ViewLeftBarItemState extends State { final _controller = TextEditingController(); final _focusNode = FocusNode(); - late ViewService serviceService; + late ViewService _viewService; + late ViewListener _viewListener; + late View view; @override void initState() { - serviceService = ViewService(/*view: widget.view*/); + view = widget.view; + _viewService = ViewService(); _focusNode.addListener(_handleFocusChanged); + _viewListener = ViewListener(view: widget.view); + _viewListener.start(onViewUpdated: (result) { + result.fold( + (updatedView) { + if (mounted) { + setState(() => view = updatedView); + } + }, + (err) => Log.error(err), + ); + }); super.initState(); } @@ -30,12 +46,13 @@ class _ViewLeftBarItemState extends State { _controller.dispose(); _focusNode.removeListener(_handleFocusChanged); _focusNode.dispose(); + _viewListener.stop(); super.dispose(); } @override Widget build(BuildContext context) { - _controller.text = widget.view.name; + _controller.text = view.name; final theme = context.watch(); return IntrinsicWidth( @@ -63,12 +80,12 @@ class _ViewLeftBarItemState extends State { void _handleFocusChanged() { if (_controller.text.isEmpty) { - _controller.text = widget.view.name; + _controller.text = view.name; return; } - if (_controller.text != widget.view.name) { - serviceService.updateView(viewId: widget.view.id, name: _controller.text); + if (_controller.text != view.name) { + _viewService.updateView(viewId: view.id, name: _controller.text); } } }