From c8945133dc7fab1fdb61fb66d6994b25d6721b9c Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 26 Apr 2022 14:43:42 +0800 Subject: [PATCH 1/6] fix: open latest view after launch --- .../app_flowy/lib/startup/deps_resolver.dart | 7 +- .../workspace/application/app/app_bloc.dart | 167 ++++++++++++------ .../presentation/home/home_screen.dart | 3 + .../presentation/home/menu/app/menu_app.dart | 90 +++------- .../home/menu/app/section/section.dart | 41 ++--- .../presentation/home/menu/menu.dart | 70 ++++---- .../presentation/plugins/trash/menu.dart | 2 +- 7 files changed, 207 insertions(+), 173 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index 5896d559a3..dc4a1b6fc7 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -14,6 +14,7 @@ import 'package:app_flowy/workspace/application/menu/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'; +import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; @@ -50,6 +51,8 @@ void _resolveUserDeps(GetIt getIt) { } void _resolveHomeDeps(GetIt getIt) { + getIt.registerSingleton(MenuSharedState()); + getIt.registerFactoryParam( (user, _) => UserListener(user: user), ); @@ -113,8 +116,8 @@ void _resolveFolderDeps(GetIt getIt) { getIt.registerFactoryParam( (app, _) => AppBloc( app: app, - service: AppService(), - listener: AppListener(appId: app.id), + appService: AppService(), + appListener: AppListener(appId: app.id), ), ); 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 73192436bf..c4b3c8e1ff 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -1,10 +1,14 @@ import 'package:app_flowy/plugin/plugin.dart'; +import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/app/app_listener.dart'; import 'package:app_flowy/workspace/application/app/app_service.dart'; +import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; +import 'package:expandable/expandable.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:dartz/dartz.dart'; @@ -13,71 +17,83 @@ part 'app_bloc.freezed.dart'; class AppBloc extends Bloc { final App app; - final AppService service; - final AppListener listener; + final AppService appService; + final AppListener appListener; - AppBloc({required this.app, required this.service, required this.listener}) : super(AppState.initial(app)) { + AppBloc({required this.app, required this.appService, required this.appListener}) : super(AppState.initial(app)) { on((event, emit) async { await event.map(initial: (e) async { - listener.start( - viewsChanged: _handleViewsChanged, - appUpdated: (app) => add(AppEvent.appDidUpdate(app)), - ); - await _fetchViews(emit); + _startListening(); + await _loadViews(emit); }, createView: (CreateView value) async { - final viewOrFailed = await service.createView( - appId: app.id, - name: value.name, - desc: value.desc, - dataType: value.dataType, - pluginType: value.pluginType, - ); - viewOrFailed.fold( - (view) => emit(state.copyWith( - latestCreatedView: view, - successOrFailure: left(unit), - )), - (error) { - Log.error(error); - emit(state.copyWith(successOrFailure: right(error))); - }, - ); - }, didReceiveViews: (e) async { - await handleDidReceiveViews(e.views, emit); + await _createView(value, emit); + }, didReceiveViewUpdated: (e) async { + await _didReceiveViewUpdated(e.views, emit); }, delete: (e) async { - final result = await service.delete(appId: app.id); - result.fold( - (unit) => emit(state.copyWith(successOrFailure: left(unit))), - (error) => emit(state.copyWith(successOrFailure: right(error))), - ); + await _deleteView(emit); }, rename: (e) async { - final result = await service.updateApp(appId: app.id, name: e.newName); - result.fold( - (l) => emit(state.copyWith(successOrFailure: left(unit))), - (error) => emit(state.copyWith(successOrFailure: right(error))), - ); + await _renameView(e, emit); }, appDidUpdate: (e) async { emit(state.copyWith(app: e.app)); }); }); } - @override - Future close() async { - await listener.close(); - return super.close(); + void _startListening() { + appListener.start( + viewsChanged: (result) { + result.fold( + (views) => add(AppEvent.didReceiveViewUpdated(views)), + (error) => Log.error(error), + ); + }, + appUpdated: (app) => add(AppEvent.appDidUpdate(app)), + ); } - void _handleViewsChanged(Either, FlowyError> result) { + Future _renameView(Rename e, Emitter emit) async { + final result = await appService.updateApp(appId: app.id, name: e.newName); result.fold( - (views) => add(AppEvent.didReceiveViews(views)), + (l) => emit(state.copyWith(successOrFailure: left(unit))), + (error) => emit(state.copyWith(successOrFailure: right(error))), + ); + } + + Future _deleteView(Emitter emit) async { + final result = await appService.delete(appId: app.id); + result.fold( + (unit) => emit(state.copyWith(successOrFailure: left(unit))), + (error) => emit(state.copyWith(successOrFailure: right(error))), + ); + } + + Future _createView(CreateView value, Emitter emit) async { + final viewOrFailed = await appService.createView( + appId: app.id, + name: value.name, + desc: value.desc, + dataType: value.dataType, + pluginType: value.pluginType, + ); + viewOrFailed.fold( + (view) => emit(state.copyWith( + latestCreatedView: view, + successOrFailure: left(unit), + )), (error) { Log.error(error); + emit(state.copyWith(successOrFailure: right(error))); }, ); } - Future handleDidReceiveViews(List views, Emitter emit) async { + @override + Future close() async { + await appListener.close(); + return super.close(); + } + + Future _didReceiveViewUpdated(List views, Emitter emit) async { final latestCreatedView = state.latestCreatedView; AppState newState = state.copyWith(views: views); if (latestCreatedView != null) { @@ -90,10 +106,10 @@ class AppBloc extends Bloc { emit(newState); } - Future _fetchViews(Emitter emit) async { - final viewsOrFailed = await service.getViews(appId: app.id); + Future _loadViews(Emitter emit) async { + final viewsOrFailed = await appService.getViews(appId: app.id); viewsOrFailed.fold( - (apps) => emit(state.copyWith(views: apps)), + (views) => emit(state.copyWith(views: views)), (error) { Log.error(error); emit(state.copyWith(successOrFailure: right(error))); @@ -113,7 +129,7 @@ class AppEvent with _$AppEvent { ) = CreateView; const factory AppEvent.delete() = Delete; const factory AppEvent.rename(String newName) = Rename; - const factory AppEvent.didReceiveViews(List views) = ReceiveViews; + const factory AppEvent.didReceiveViewUpdated(List views) = ReceiveViews; const factory AppEvent.appDidUpdate(App app) = AppDidUpdate; } @@ -121,17 +137,62 @@ class AppEvent with _$AppEvent { class AppState with _$AppState { const factory AppState({ required App app, - required bool isLoading, - required List? views, + required List views, View? latestCreatedView, required Either successOrFailure, }) = _AppState; factory AppState.initial(App app) => AppState( app: app, - isLoading: false, - views: null, - latestCreatedView: null, + views: [], successOrFailure: left(unit), ); } + +class AppViewDataNotifier extends ChangeNotifier { + List _views = []; + View? _selectedView; + ExpandableController expandController = ExpandableController(initialExpanded: false); + + AppViewDataNotifier() { + _setLatestView(getIt().latestOpenView); + getIt().addLatestViewListener((view) { + _setLatestView(view); + }); + } + + void _setLatestView(View? view) { + view?.freeze(); + _selectedView = view; + _expandIfNeed(); + } + + View? get selectedView => _selectedView; + + set views(List views) { + if (_views != views) { + _views = views; + _expandIfNeed(); + notifyListeners(); + } + } + + void _expandIfNeed() { + if (_selectedView == null) { + return; + } + + if (!_views.contains(_selectedView!)) { + return; + } + + if (expandController.expanded == false) { + // Workaround: Delay 150 milliseconds to make the smooth animation while expanding + Future.delayed(const Duration(milliseconds: 150), () { + expandController.expanded = true; + }); + } + } + + UnmodifiableListView get views => UnmodifiableListView(_views); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart b/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart index e9bb80dd30..cea29792cb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/home_screen.dart @@ -121,6 +121,9 @@ class _HomeScreenState extends State { collapsedNotifier: getIt().collapsedNotifier, ); + final latestView = widget.workspaceSetting.hasLatestView() ? widget.workspaceSetting.latestView : null; + getIt().latestOpenView = latestView; + return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu)); } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart index d028355ed1..a7167a1997 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/application/appearance.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; import 'package:expandable/expandable.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.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'; import 'package:app_flowy/startup/startup.dart'; @@ -19,11 +18,11 @@ class MenuApp extends StatefulWidget { } class _MenuAppState extends State { - late AppDataNotifier notifier; + late AppViewDataNotifier notifier; @override void initState() { - notifier = AppDataNotifier(); + notifier = AppViewDataNotifier(); super.initState(); } @@ -39,30 +38,34 @@ class _MenuAppState extends State { }, ), ], - child: BlocSelector( - selector: (state) { - final menuSharedState = Provider.of(context, listen: false); - if (state.latestCreatedView != null) { - menuSharedState.forcedOpenView.value = state.latestCreatedView!; - } - - notifier.views = state.views; - notifier.selectedView = menuSharedState.selectedView.value; - return notifier; - }, - builder: (context, notifier) => ChangeNotifierProvider.value( - value: notifier, - child: Consumer( - builder: (BuildContext context, AppDataNotifier notifier, Widget? child) { - return expandableWrapper(context, notifier); - }, + child: MultiBlocListener( + listeners: [ + BlocListener( + listenWhen: (p, c) => p.latestCreatedView != c.latestCreatedView, + listener: (context, state) => getIt().latestOpenView = state.latestCreatedView, ), + BlocListener( + listenWhen: (p, c) => p.views != c.views, + listener: (context, state) => notifier.views = state.views, + ), + ], + child: BlocBuilder( + builder: (context, state) { + return ChangeNotifierProvider.value( + value: notifier, + child: Consumer( + builder: (context, notifier, _) { + return expandableWrapper(context, notifier); + }, + ), + ); + }, ), ), ); } - ExpandableNotifier expandableWrapper(BuildContext context, AppDataNotifier notifier) { + ExpandableNotifier expandableWrapper(BuildContext context, AppViewDataNotifier notifier) { return ExpandableNotifier( controller: notifier.expandController, child: ScrollOnExpand( @@ -92,11 +95,11 @@ class _MenuAppState extends State { ); } - Widget _renderViewSection(AppDataNotifier notifier) { + Widget _renderViewSection(AppViewDataNotifier notifier) { return MultiProvider( providers: [ChangeNotifierProvider.value(value: notifier)], child: Consumer( - builder: (context, AppDataNotifier notifier, child) { + builder: (context, AppViewDataNotifier notifier, child) { return ViewSection(appData: notifier); }, ), @@ -119,44 +122,3 @@ class MenuAppSizes { static double scale = 1; static double get expandedPadding => iconSize * scale + headerPadding; } - -class AppDataNotifier extends ChangeNotifier { - List _views = []; - View? _selectedView; - ExpandableController expandController = ExpandableController(initialExpanded: false); - - AppDataNotifier(); - - set selectedView(View? view) { - _selectedView = view; - - if (view != null && _views.isNotEmpty) { - final isExpanded = _views.contains(view); - if (expandController.expanded == false && expandController.expanded != isExpanded) { - // Workaround: Delay 150 milliseconds to make the smooth animation while expanding - Future.delayed(const Duration(milliseconds: 150), () { - expandController.expanded = isExpanded; - }); - } - } - } - - View? get selectedView => _selectedView; - - set views(List? views) { - if (views == null) { - if (_views.isNotEmpty) { - _views = List.empty(growable: false); - notifyListeners(); - } - return; - } - - if (_views != views) { - _views = views; - notifyListeners(); - } - } - - List get views => _views; -} diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index 59324fa0a7..3eb28aef1e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/application/app/app_bloc.dart'; import 'package:app_flowy/workspace/application/view/view_ext.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; @@ -13,13 +14,13 @@ import 'package:styled_widget/styled_widget.dart'; import 'item.dart'; class ViewSection extends StatelessWidget { - final AppDataNotifier appData; + final AppViewDataNotifier appData; const ViewSection({Key? key, required this.appData}) : super(key: key); @override Widget build(BuildContext context) { // The ViewSectionNotifier will be updated after AppDataNotifier changed passed by parent widget - return ChangeNotifierProxyProvider( + return ChangeNotifierProxyProvider( create: (_) { return ViewSectionNotifier( context: context, @@ -29,7 +30,7 @@ class ViewSection extends StatelessWidget { }, update: (_, notifier, controller) => controller!..update(notifier), child: Consumer(builder: (context, ViewSectionNotifier notifier, child) { - return RenderSectionItems(views: notifier.views); + return _SectionItems(views: notifier.views); }), ); } @@ -63,16 +64,16 @@ class ViewSection extends StatelessWidget { // } } -class RenderSectionItems extends StatefulWidget { - const RenderSectionItems({Key? key, required this.views}) : super(key: key); +class _SectionItems extends StatefulWidget { + const _SectionItems({Key? key, required this.views}) : super(key: key); final List views; @override - State createState() => _RenderSectionItemsState(); + State<_SectionItems> createState() => _SectionItemsState(); } -class _RenderSectionItemsState extends State { +class _SectionItemsState extends State<_SectionItems> { List views = []; /// Maps the hasmap value of the section items to their index in the reorderable list. @@ -123,10 +124,7 @@ class _RenderSectionItemsState extends State { (view) => ViewSectionItem( view: view, isSelected: _isViewSelected(context, view.id), - onSelected: (view) { - context.read().selectedView = view; - Provider.of(context, listen: false).selectedView.value = view; - }, + onSelected: (view) => getIt().latestOpenView = view, ).padding(vertical: 4), ) .toList()[index], @@ -150,6 +148,7 @@ class ViewSectionNotifier with ChangeNotifier { List _views; View? _selectedView; Timer? _notifyListenerOperation; + VoidCallback? _latestViewDidChangeFn; ViewSectionNotifier({ required BuildContext context, @@ -157,16 +156,10 @@ class ViewSectionNotifier with ChangeNotifier { View? initialSelectedView, }) : _views = views, _selectedView = initialSelectedView { - final menuSharedState = Provider.of(context, listen: false); - // The forcedOpenView will be the view after creating the new view - menuSharedState.forcedOpenView.addPublishListener((forcedOpenView) { - selectedView = forcedOpenView; - }); - - menuSharedState.selectedView.addListener(() { - // Cancel the selected view of this section by setting the selectedView to null - // that will notify the listener to refresh the ViewSection UI - if (menuSharedState.selectedView.value != _selectedView) { + _latestViewDidChangeFn = getIt().addLatestViewListener((latestOpenView) { + if (_views.contains(latestOpenView)) { + selectedView = latestOpenView; + } else { selectedView = null; } }); @@ -199,7 +192,7 @@ class ViewSectionNotifier with ChangeNotifier { View? get selectedView => _selectedView; - void update(AppDataNotifier notifier) { + void update(AppViewDataNotifier notifier) { views = notifier.views; } @@ -216,6 +209,10 @@ class ViewSectionNotifier with ChangeNotifier { void dispose() { isDisposed = true; _notifyListenerOperation?.cancel(); + if (_latestViewDidChangeFn != null) { + getIt().removeLatestViewListener(_latestViewDidChangeFn!); + _latestViewDidChangeFn = null; + } super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart index 17d7326f0a..f353f533de 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart @@ -88,30 +88,24 @@ class _HomeMenuState extends State { final theme = context.watch(); return Container( color: theme.bg1, - child: ChangeNotifierProvider( - create: (_) => - MenuSharedState(view: widget.workspaceSetting.hasLatestView() ? widget.workspaceSetting.latestView : null), - child: Consumer(builder: (context, MenuSharedState sharedState, child) { - return Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - const MenuTopBar(), - const VSpace(10), - _renderApps(context), - ], - ).padding(horizontal: Insets.l), - ), - const VSpace(20), - _renderTrash(context).padding(horizontal: Insets.l), - const VSpace(20), - _renderNewAppButton(context), - ], - ); - }), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const MenuTopBar(), + const VSpace(10), + _renderApps(context), + ], + ).padding(horizontal: Insets.l), + ), + const VSpace(20), + _renderTrash(context).padding(horizontal: Insets.l), + const VSpace(20), + _renderNewAppButton(context), + ], ), ); } @@ -201,18 +195,32 @@ class _HomeMenuState extends State { } } -class MenuSharedState extends ChangeNotifier { - PublishNotifier forcedOpenView = PublishNotifier(); - ValueNotifier selectedView = ValueNotifier(null); +class MenuSharedState { + final ValueNotifier _latestOpenView = ValueNotifier(null); MenuSharedState({View? view}) { if (view != null) { - selectedView.value = view; + _latestOpenView.value = view; + } + } + + View? get latestOpenView => _latestOpenView.value; + + set latestOpenView(View? view) { + _latestOpenView.value = view; + } + + VoidCallback addLatestViewListener(void Function(View?) latestViewDidChange) { + onChanged() { + latestViewDidChange(_latestOpenView.value); } - forcedOpenView.addPublishListener((view) { - selectedView.value = view; - }); + _latestOpenView.addListener(onChanged); + return onChanged; + } + + void removeLatestViewListener(VoidCallback fn) { + _latestOpenView.removeListener(fn); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart index 770889c610..ec782db205 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/trash/menu.dart @@ -21,7 +21,7 @@ class MenuTrash extends StatelessWidget { height: 26, child: InkWell( onTap: () { - Provider.of(context, listen: false).selectedView.value = null; + getIt().latestOpenView = null; getIt().setPlugin(makePlugin(pluginType: DefaultPlugin.trash.type())); }, child: _render(context), From 0b1f0ed401ae823e3967104d5d889157a4c9a6a8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 26 Apr 2022 16:28:56 +0800 Subject: [PATCH 2/6] refactor: replace provider with bloc in ViewSection --- .../workspace/application/app/app_bloc.dart | 75 +++++++++++++---- .../menu/menu_view_section_bloc.dart | 82 +++++++++++++++++++ .../presentation/home/menu/app/menu_app.dart | 33 +++----- .../home/menu/app/section/section.dart | 43 +++++----- .../presentation/home/menu/menu.dart | 19 ++--- 5 files changed, 179 insertions(+), 73 deletions(-) create mode 100644 frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart 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 c4b3c8e1ff..5f97e7028e 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -43,11 +43,19 @@ class AppBloc extends Bloc { appListener.start( viewsChanged: (result) { result.fold( - (views) => add(AppEvent.didReceiveViewUpdated(views)), + (views) { + if (!isClosed) { + add(AppEvent.didReceiveViewUpdated(views)); + } + }, (error) => Log.error(error), ); }, - appUpdated: (app) => add(AppEvent.appDidUpdate(app)), + appUpdated: (app) { + if (!isClosed) { + add(AppEvent.appDidUpdate(app)); + } + }, ); } @@ -149,40 +157,73 @@ class AppState with _$AppState { ); } -class AppViewDataNotifier extends ChangeNotifier { - List _views = []; - View? _selectedView; +class AppViewDataContext extends ChangeNotifier { + final String appId; + final ValueNotifier> _viewsNotifier = ValueNotifier([]); + final ValueNotifier _selectedViewNotifier = ValueNotifier(null); ExpandableController expandController = ExpandableController(initialExpanded: false); - AppViewDataNotifier() { + AppViewDataContext({required this.appId}) { _setLatestView(getIt().latestOpenView); getIt().addLatestViewListener((view) { _setLatestView(view); }); } - void _setLatestView(View? view) { - view?.freeze(); - _selectedView = view; - _expandIfNeed(); + VoidCallback addSelectedViewChangeListener(void Function(View?) callback) { + listener() { + callback(_selectedViewNotifier.value); + } + + _selectedViewNotifier.addListener(listener); + return listener; } - View? get selectedView => _selectedView; + void removeSelectedViewListener(VoidCallback listener) { + _selectedViewNotifier.removeListener(listener); + } - set views(List views) { - if (_views != views) { - _views = views; + void _setLatestView(View? view) { + view?.freeze(); + + if (_selectedViewNotifier.value != view) { + _selectedViewNotifier.value = view; _expandIfNeed(); notifyListeners(); } } + View? get selectedView => _selectedViewNotifier.value; + + set views(List views) { + if (_viewsNotifier.value != views) { + _viewsNotifier.value = views; + _expandIfNeed(); + notifyListeners(); + } + } + + UnmodifiableListView get views => UnmodifiableListView(_viewsNotifier.value); + + VoidCallback addViewsChangeListener(void Function(UnmodifiableListView) callback) { + listener() { + callback(views); + } + + _viewsNotifier.addListener(listener); + return listener; + } + + void removeViewsListener(VoidCallback listener) { + _viewsNotifier.removeListener(listener); + } + void _expandIfNeed() { - if (_selectedView == null) { + if (_selectedViewNotifier.value == null) { return; } - if (!_views.contains(_selectedView!)) { + if (!_viewsNotifier.value.contains(_selectedViewNotifier.value)) { return; } @@ -193,6 +234,4 @@ class AppViewDataNotifier extends ChangeNotifier { }); } } - - UnmodifiableListView get views => UnmodifiableListView(_views); } diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart new file mode 100644 index 0000000000..583eeca4ed --- /dev/null +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart @@ -0,0 +1,82 @@ +import 'dart:async'; + +import 'package:app_flowy/workspace/application/app/app_bloc.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +part 'menu_view_section_bloc.freezed.dart'; + +class ViewSectionBloc extends Bloc { + void Function()? _viewsListener; + void Function()? _selectedViewlistener; + final AppViewDataContext appViewData; + + ViewSectionBloc({ + required this.appViewData, + }) : super(ViewSectionState.initial(appViewData)) { + on((event, emit) async { + await event.map( + initial: (e) async { + _startListening(); + }, + setSelectedView: (_SetSelectedView value) { + if (state.views.contains(value.view)) { + emit(state.copyWith(selectedView: value.view)); + } else { + emit(state.copyWith(selectedView: null)); + } + }, + didReceiveViewUpdated: (_DidReceiveViewUpdated value) { + emit(state.copyWith(views: value.views)); + }, + ); + }); + } + + void _startListening() { + _viewsListener = appViewData.addViewsChangeListener((views) { + if (!isClosed) { + add(ViewSectionEvent.didReceiveViewUpdated(views)); + } + }); + _selectedViewlistener = appViewData.addSelectedViewChangeListener((view) { + if (!isClosed) { + add(ViewSectionEvent.setSelectedView(view)); + } + }); + } + + @override + Future close() async { + if (_selectedViewlistener != null) { + appViewData.removeSelectedViewListener(_selectedViewlistener!); + } + + if (_viewsListener != null) { + appViewData.removeViewsListener(_viewsListener!); + } + + return super.close(); + } +} + +@freezed +class ViewSectionEvent with _$ViewSectionEvent { + const factory ViewSectionEvent.initial() = _Initial; + const factory ViewSectionEvent.setSelectedView(View? view) = _SetSelectedView; + const factory ViewSectionEvent.didReceiveViewUpdated(List views) = _DidReceiveViewUpdated; +} + +@freezed +class ViewSectionState with _$ViewSectionState { + const factory ViewSectionState({ + required List views, + View? selectedView, + }) = _ViewSectionState; + + factory ViewSectionState.initial(AppViewDataContext appViewData) => ViewSectionState( + views: appViewData.views, + selectedView: appViewData.selectedView, + ); +} diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart index a7167a1997..67b52481e7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/menu_app.dart @@ -18,11 +18,11 @@ class MenuApp extends StatefulWidget { } class _MenuAppState extends State { - late AppViewDataNotifier notifier; + late AppViewDataContext viewDataContext; @override void initState() { - notifier = AppViewDataNotifier(); + viewDataContext = AppViewDataContext(appId: widget.app.id); super.initState(); } @@ -46,16 +46,16 @@ class _MenuAppState extends State { ), BlocListener( listenWhen: (p, c) => p.views != c.views, - listener: (context, state) => notifier.views = state.views, + listener: (context, state) => viewDataContext.views = state.views, ), ], child: BlocBuilder( builder: (context, state) { return ChangeNotifierProvider.value( - value: notifier, - child: Consumer( - builder: (context, notifier, _) { - return expandableWrapper(context, notifier); + value: viewDataContext, + child: Consumer( + builder: (context, viewDataContext, _) { + return expandableWrapper(context, viewDataContext); }, ), ); @@ -65,9 +65,9 @@ class _MenuAppState extends State { ); } - ExpandableNotifier expandableWrapper(BuildContext context, AppViewDataNotifier notifier) { + ExpandableNotifier expandableWrapper(BuildContext context, AppViewDataContext viewDataContext) { return ExpandableNotifier( - controller: notifier.expandController, + controller: viewDataContext.expandController, child: ScrollOnExpand( scrollOnExpand: false, scrollOnCollapse: false, @@ -86,7 +86,7 @@ class _MenuAppState extends State { value: Provider.of(context, listen: true), child: MenuAppHeader(widget.app), ), - expanded: _renderViewSection(notifier), + expanded: ViewSection(appViewData: viewDataContext), collapsed: const SizedBox(), ), ], @@ -95,20 +95,9 @@ class _MenuAppState extends State { ); } - Widget _renderViewSection(AppViewDataNotifier notifier) { - return MultiProvider( - providers: [ChangeNotifierProvider.value(value: notifier)], - child: Consumer( - builder: (context, AppViewDataNotifier notifier, child) { - return ViewSection(appData: notifier); - }, - ), - ); - } - @override void dispose() { - notifier.dispose(); + viewDataContext.dispose(); super.dispose(); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index 3eb28aef1e..116f494887 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -3,35 +3,34 @@ import 'dart:developer'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/app/app_bloc.dart'; +import 'package:app_flowy/workspace/application/menu/menu_view_section_bloc.dart'; import 'package:app_flowy/workspace/application/view/view_ext.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:reorderables/reorderables.dart'; import 'package:styled_widget/styled_widget.dart'; import 'item.dart'; class ViewSection extends StatelessWidget { - final AppViewDataNotifier appData; - const ViewSection({Key? key, required this.appData}) : super(key: key); + final AppViewDataContext appViewData; + const ViewSection({Key? key, required this.appViewData}) : super(key: key); @override Widget build(BuildContext context) { - // The ViewSectionNotifier will be updated after AppDataNotifier changed passed by parent widget - return ChangeNotifierProxyProvider( - create: (_) { - return ViewSectionNotifier( - context: context, - views: appData.views, - initialSelectedView: appData.selectedView, - ); + return BlocProvider( + create: (context) { + final bloc = ViewSectionBloc(appViewData: appViewData); + bloc.add(const ViewSectionEvent.initial()); + return bloc; }, - update: (_, notifier, controller) => controller!..update(notifier), - child: Consumer(builder: (context, ViewSectionNotifier notifier, child) { - return _SectionItems(views: notifier.views); - }), + child: BlocBuilder( + builder: (context, state) { + return _SectionItems(views: state.views); + }, + ), ); } @@ -135,11 +134,12 @@ class _SectionItemsState extends State<_SectionItems> { } bool _isViewSelected(BuildContext context, String viewId) { - final view = context.read().selectedView; - if (view == null) { - return false; - } - return view.id == viewId; + // final view = context.read().selectedView; + // if (view == null) { + // return false; + // } + // return view.id == viewId; + return false; } } @@ -151,7 +151,6 @@ class ViewSectionNotifier with ChangeNotifier { VoidCallback? _latestViewDidChangeFn; ViewSectionNotifier({ - required BuildContext context, required List views, View? initialSelectedView, }) : _views = views, @@ -192,7 +191,7 @@ class ViewSectionNotifier with ChangeNotifier { View? get selectedView => _selectedView; - void update(AppViewDataNotifier notifier) { + void update(AppViewDataContext notifier) { views = notifier.views; } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart index f353f533de..49959ce0ce 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart @@ -13,7 +13,6 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:expandable/expandable.dart'; import 'package:flowy_infra/time/duration.dart'; @@ -199,9 +198,7 @@ class MenuSharedState { final ValueNotifier _latestOpenView = ValueNotifier(null); MenuSharedState({View? view}) { - if (view != null) { - _latestOpenView.value = view; - } + _latestOpenView.value = view; } View? get latestOpenView => _latestOpenView.value; @@ -210,17 +207,17 @@ class MenuSharedState { _latestOpenView.value = view; } - VoidCallback addLatestViewListener(void Function(View?) latestViewDidChange) { - onChanged() { - latestViewDidChange(_latestOpenView.value); + VoidCallback addLatestViewListener(void Function(View?) callback) { + listener() { + callback(_latestOpenView.value); } - _latestOpenView.addListener(onChanged); - return onChanged; + _latestOpenView.addListener(listener); + return listener; } - void removeLatestViewListener(VoidCallback fn) { - _latestOpenView.removeListener(fn); + void removeLatestViewListener(VoidCallback listener) { + _latestOpenView.removeListener(listener); } } From 25548ad9ebb02c45035bd56d3bd6f21e8a5fd2f8 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 26 Apr 2022 20:35:41 +0800 Subject: [PATCH 3/6] chore: add move view event --- .../app_flowy/lib/startup/deps_resolver.dart | 2 +- .../application/app/app_service.dart | 13 ++ .../menu/menu_view_section_bloc.dart | 49 +++- .../home/menu/app/section/item.dart | 15 +- .../home/menu/app/section/section.dart | 211 +++--------------- 5 files changed, 92 insertions(+), 198 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index dc4a1b6fc7..a5d6321fa0 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -116,7 +116,7 @@ void _resolveFolderDeps(GetIt getIt) { getIt.registerFactoryParam( (app, _) => AppBloc( app: app, - appService: AppService(), + appService: AppService(appId: app.id), appListener: AppListener(appId: app.id), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/app/app_service.dart b/frontend/app_flowy/lib/workspace/application/app/app_service.dart index 2ed3435b9f..af0be16497 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_service.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_service.dart @@ -54,4 +54,17 @@ class AppService { } return FolderEventUpdateApp(request).send(); } + + Future> moveView({ + required String viewId, + required int fromIndex, + required int toIndex, + }) { + UpdateAppPayload request = UpdateAppPayload.create()..appId = appId; + + if (name != null) { + request.name = name; + } + return FolderEventUpdateApp(request).send(); + } } diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart index 583eeca4ed..10f4058a97 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_view_section_bloc.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'package:app_flowy/workspace/application/app/app_bloc.dart'; +import 'package:app_flowy/workspace/application/app/app_service.dart'; +import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -10,51 +12,73 @@ part 'menu_view_section_bloc.freezed.dart'; class ViewSectionBloc extends Bloc { void Function()? _viewsListener; void Function()? _selectedViewlistener; - final AppViewDataContext appViewData; + final AppViewDataContext _appViewData; + late final AppService _appService; ViewSectionBloc({ - required this.appViewData, - }) : super(ViewSectionState.initial(appViewData)) { + required AppViewDataContext appViewData, + }) : _appService = AppService(appId: appViewData.appId), + _appViewData = appViewData, + super(ViewSectionState.initial(appViewData)) { on((event, emit) async { await event.map( initial: (e) async { _startListening(); }, setSelectedView: (_SetSelectedView value) { - if (state.views.contains(value.view)) { - emit(state.copyWith(selectedView: value.view)); - } else { - emit(state.copyWith(selectedView: null)); - } + _setSelectView(value, emit); }, didReceiveViewUpdated: (_DidReceiveViewUpdated value) { emit(state.copyWith(views: value.views)); }, + moveView: (_MoveView value) async { + await _moveView(value); + }, ); }); } void _startListening() { - _viewsListener = appViewData.addViewsChangeListener((views) { + _viewsListener = _appViewData.addViewsChangeListener((views) { if (!isClosed) { add(ViewSectionEvent.didReceiveViewUpdated(views)); } }); - _selectedViewlistener = appViewData.addSelectedViewChangeListener((view) { + _selectedViewlistener = _appViewData.addSelectedViewChangeListener((view) { if (!isClosed) { add(ViewSectionEvent.setSelectedView(view)); } }); } + void _setSelectView(_SetSelectedView value, Emitter emit) { + if (state.views.contains(value.view)) { + emit(state.copyWith(selectedView: value.view)); + } else { + emit(state.copyWith(selectedView: null)); + } + } + + Future _moveView(_MoveView value) async { + if (value.fromIndex < state.views.length) { + final viewId = state.views[value.fromIndex].id; + final result = await _appService.moveView( + viewId: viewId, + fromIndex: value.fromIndex, + toIndex: value.toIndex, + ); + result.fold((l) => null, (err) => Log.error(err)); + } + } + @override Future close() async { if (_selectedViewlistener != null) { - appViewData.removeSelectedViewListener(_selectedViewlistener!); + _appViewData.removeSelectedViewListener(_selectedViewlistener!); } if (_viewsListener != null) { - appViewData.removeViewsListener(_viewsListener!); + _appViewData.removeViewsListener(_viewsListener!); } return super.close(); @@ -65,6 +89,7 @@ class ViewSectionBloc extends Bloc { class ViewSectionEvent with _$ViewSectionEvent { const factory ViewSectionEvent.initial() = _Initial; const factory ViewSectionEvent.setSelectedView(View? view) = _SetSelectedView; + const factory ViewSectionEvent.moveView(int fromIndex, int toIndex) = _MoveView; const factory ViewSectionEvent.didReceiveViewUpdated(List views) = _DidReceiveViewUpdated; } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart index 290d2bd328..d2bc81472c 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart @@ -40,12 +40,15 @@ class ViewSectionItem extends StatelessWidget { ], child: BlocBuilder( builder: (context, state) { - return InkWell( - onTap: () => onSelected(context.read().state.view), - child: FlowyHover( - style: HoverStyle(hoverColor: theme.bg3), - builder: (_, onHover) => _render(context, onHover, state, theme.iconColor), - setSelected: () => state.isEditing || isSelected, + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: InkWell( + onTap: () => onSelected(context.read().state.view), + child: FlowyHover( + style: HoverStyle(hoverColor: theme.bg3), + builder: (_, onHover) => _render(context, onHover, state, theme.iconColor), + setSelected: () => state.isEditing || isSelected, + ), ), ); }, diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index 116f494887..1dc1393a6e 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -1,17 +1,14 @@ -import 'dart:async'; -import 'dart:developer'; - import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/app/app_bloc.dart'; import 'package:app_flowy/workspace/application/menu/menu_view_section_bloc.dart'; import 'package:app_flowy/workspace/application/view/view_ext.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.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'; import 'package:reorderables/reorderables.dart'; -import 'package:styled_widget/styled_widget.dart'; + import 'item.dart'; class ViewSection extends StatelessWidget { @@ -26,192 +23,48 @@ class ViewSection extends StatelessWidget { bloc.add(const ViewSectionEvent.initial()); return bloc; }, - child: BlocBuilder( - builder: (context, state) { - return _SectionItems(views: state.views); + child: BlocListener( + listenWhen: (p, c) => p.selectedView != c.selectedView, + listener: (context, state) { + if (state.selectedView != null) { + WidgetsBinding.instance?.addPostFrameCallback((_) { + getIt().setPlugin(state.selectedView!.plugin()); + }); + } }, + child: BlocBuilder( + builder: (context, state) { + return _reorderableColum(context, state); + }, + ), ), ); } - // Widget _renderSectionItems(BuildContext context, List views) { - // List viewWidgets = []; - // if (views.isNotEmpty) { - // viewWidgets = views - // .map( - // (view) => ViewSectionItem( - // view: view, - // isSelected: _isViewSelected(context, view.id), - // onSelected: (view) { - // context.read().selectedView = view; - // Provider.of(context, listen: false).selectedView.value = view; - // }, - // ).padding(vertical: 4), - // ) - // .toList(growable: false); - // } + ReorderableColumn _reorderableColum(BuildContext context, ViewSectionState state) { + final children = state.views.map((view) { + return ViewSectionItem( + key: ValueKey(view.id), + view: view, + isSelected: _isViewSelected(state, view.id), + onSelected: (view) => getIt().latestOpenView = view, + ); + }).toList(); - // return Column(children: viewWidgets); - // } - - // bool _isViewSelected(BuildContext context, String viewId) { - // final view = context.read().selectedView; - // if (view == null) { - // return false; - // } - // return view.id == viewId; - // } -} - -class _SectionItems extends StatefulWidget { - const _SectionItems({Key? key, required this.views}) : super(key: key); - - final List views; - - @override - State<_SectionItems> createState() => _SectionItemsState(); -} - -class _SectionItemsState extends State<_SectionItems> { - List views = []; - - /// Maps the hasmap value of the section items to their index in the reorderable list. - //TODO @gaganyadav80: Retain this map to persist the order of the items. - final Map _sectionItemIndex = {}; - - void _initItemList() { - views.addAll(widget.views); - - for (int i = 0; i < views.length; i++) { - if (_sectionItemIndex[views[i].id] == null) { - _sectionItemIndex[views[i].id] = i; - } - } - } - - @override - void initState() { - super.initState(); - _initItemList(); - } - - @override - Widget build(BuildContext context) { - if (views.isEmpty) { - _initItemList(); - } - - log("BUILD: Section items: ${views.length}"); return ReorderableColumn( needsLongPressDraggable: false, onReorder: (oldIndex, index) { - setState(() { - // int index = newIndex > oldIndex ? newIndex - 1 : newIndex; - View section = views.removeAt(oldIndex); - views.insert(index, section); - - _sectionItemIndex[section.id] = index; - }); + context.read().add(ViewSectionEvent.moveView(oldIndex, index)); }, - children: List.generate( - views.length, - (index) { - return Container( - key: ValueKey(views[index].id), - child: views - .map( - (view) => ViewSectionItem( - view: view, - isSelected: _isViewSelected(context, view.id), - onSelected: (view) => getIt().latestOpenView = view, - ).padding(vertical: 4), - ) - .toList()[index], - ); - }, - ), + children: children, ); } - bool _isViewSelected(BuildContext context, String viewId) { - // final view = context.read().selectedView; - // if (view == null) { - // return false; - // } - // return view.id == viewId; - return false; - } -} - -class ViewSectionNotifier with ChangeNotifier { - bool isDisposed = false; - List _views; - View? _selectedView; - Timer? _notifyListenerOperation; - VoidCallback? _latestViewDidChangeFn; - - ViewSectionNotifier({ - required List views, - View? initialSelectedView, - }) : _views = views, - _selectedView = initialSelectedView { - _latestViewDidChangeFn = getIt().addLatestViewListener((latestOpenView) { - if (_views.contains(latestOpenView)) { - selectedView = latestOpenView; - } else { - selectedView = null; - } - }); - } - - set views(List views) { - if (_views != views) { - _views = views; - _notifyListeners(); - } - } - - List get views => _views; - - set selectedView(View? view) { - if (_selectedView == view) { - return; - } - _selectedView = view; - _notifyListeners(); - - if (view != null) { - WidgetsBinding.instance?.addPostFrameCallback((_) { - getIt().setPlugin(view.plugin()); - }); - } else { - // do nothing - } - } - - View? get selectedView => _selectedView; - - void update(AppViewDataContext notifier) { - views = notifier.views; - } - - void _notifyListeners() { - _notifyListenerOperation?.cancel(); - _notifyListenerOperation = Timer(const Duration(milliseconds: 30), () { - if (!isDisposed) { - notifyListeners(); - } - }); - } - - @override - void dispose() { - isDisposed = true; - _notifyListenerOperation?.cancel(); - if (_latestViewDidChangeFn != null) { - getIt().removeLatestViewListener(_latestViewDidChangeFn!); - _latestViewDidChangeFn = null; - } - super.dispose(); + bool _isViewSelected(ViewSectionState state, String viewId) { + final view = state.selectedView; + if (view == null) { + return false; + } + return view.id == viewId; } } From 7f7801d04e752dc98822f2fac6745a5ca8cb363d Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 26 Apr 2022 21:20:02 +0800 Subject: [PATCH 4/6] chore: save view order --- .../application/app/app_service.dart | 40 ++- .../workspace/workspace_service.dart | 27 +- .../home/menu/app/section/section.dart | 1 - .../dart_event/flowy-folder/dart_event.dart | 17 + .../flowy-folder-data-model/view.pb.dart | 89 +++++ .../flowy-folder-data-model/view.pbenum.dart | 15 + .../flowy-folder-data-model/view.pbjson.dart | 24 ++ .../flowy-folder/event_map.pbenum.dart | 2 + .../flowy-folder/event_map.pbjson.dart | 3 +- .../rust-lib/flowy-folder/src/event_map.rs | 6 +- .../src/protobuf/model/event_map.rs | 14 +- .../src/protobuf/proto/event_map.proto | 1 + .../src/services/app/controller.rs | 13 + .../src/services/persistence/mod.rs | 2 + .../services/persistence/version_1/v1_impl.rs | 16 + .../services/persistence/version_2/v2_impl.rs | 22 ++ .../src/services/view/controller.rs | 14 + .../src/services/view/event_handler.rs | 22 ++ .../src/entities/view.rs | 48 +++ .../src/protobuf/model/view.rs | 318 +++++++++++++++++- .../src/protobuf/proto/view.proto | 10 + .../src/client_folder/folder_pad.rs | 15 + 22 files changed, 687 insertions(+), 32 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/app/app_service.dart b/frontend/app_flowy/lib/workspace/application/app/app_service.dart index af0be16497..52702726f4 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_service.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_service.dart @@ -1,16 +1,23 @@ import 'dart:async'; + import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; + import 'package:app_flowy/plugin/plugin.dart'; class AppService { - Future> getAppDesc({required String appId}) { - final request = AppId.create()..value = appId; + final String appId; + AppService({ + required this.appId, + }); - return FolderEventReadApp(request).send(); + Future> getAppDesc({required String appId}) { + final payload = AppId.create()..value = appId; + + return FolderEventReadApp(payload).send(); } Future> createView({ @@ -20,20 +27,20 @@ class AppService { required PluginDataType dataType, required PluginType pluginType, }) { - final request = CreateViewPayload.create() + final payload = CreateViewPayload.create() ..belongToId = appId ..name = name ..desc = desc ..dataType = dataType ..pluginType = pluginType; - return FolderEventCreateView(request).send(); + return FolderEventCreateView(payload).send(); } Future, FlowyError>> getViews({required String appId}) { - final request = AppId.create()..value = appId; + final payload = AppId.create()..value = appId; - return FolderEventReadApp(request).send().then((result) { + return FolderEventReadApp(payload).send().then((result) { return result.fold( (app) => left(app.belongings.items), (error) => right(error), @@ -47,12 +54,12 @@ class AppService { } Future> updateApp({required String appId, String? name}) { - UpdateAppPayload request = UpdateAppPayload.create()..appId = appId; + UpdateAppPayload payload = UpdateAppPayload.create()..appId = appId; if (name != null) { - request.name = name; + payload.name = name; } - return FolderEventUpdateApp(request).send(); + return FolderEventUpdateApp(payload).send(); } Future> moveView({ @@ -60,11 +67,12 @@ class AppService { required int fromIndex, required int toIndex, }) { - UpdateAppPayload request = UpdateAppPayload.create()..appId = appId; + final payload = MoveFolderItemPayload.create() + ..itemId = viewId + ..from = fromIndex + ..to = toIndex + ..ty = MoveFolderItemType.MoveView; - if (name != null) { - request.name = name; - } - return FolderEventUpdateApp(request).send(); + return FolderEventMoveItem(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart index 931fbf028b..e12b8174e5 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart @@ -3,22 +3,23 @@ import 'package:dartz/dartz.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart' show MoveFolderItemPayload, MoveItemType; import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; class WorkspaceService { Future> createApp({required String workspaceId, required String name, required String desc}) { - final request = CreateAppPayload.create() + final payload = CreateAppPayload.create() ..name = name ..workspaceId = workspaceId ..desc = desc; - return FolderEventCreateApp(request).send(); + return FolderEventCreateApp(payload).send(); } Future> getWorkspace({required String workspaceId}) { - final request = WorkspaceId.create()..value = workspaceId; - return FolderEventReadWorkspaces(request).send().then((result) { + final payload = WorkspaceId.create()..value = workspaceId; + return FolderEventReadWorkspaces(payload).send().then((result) { return result.fold( (workspaces) { assert(workspaces.items.length == 1); @@ -35,12 +36,26 @@ class WorkspaceService { } Future, FlowyError>> getApps({required String workspaceId}) { - final request = WorkspaceId.create()..value = workspaceId; - return FolderEventReadWorkspaceApps(request).send().then((result) { + final payload = WorkspaceId.create()..value = workspaceId; + return FolderEventReadWorkspaceApps(payload).send().then((result) { return result.fold( (apps) => left(apps.items), (error) => right(error), ); }); } + + Future> moveApp({ + required String appId, + required int fromIndex, + required int toIndex, + }) { + final payload = MoveFolderItemPayload.create() + ..itemId = appId + ..from = fromIndex + ..to = toIndex + ..ty = MoveItemType.MoveApp; + + return FolderEventMoveItem(payload).send(); + } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart index 1dc1393a6e..d9fd618e9a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/section.dart @@ -4,7 +4,6 @@ import 'package:app_flowy/workspace/application/menu/menu_view_section_bloc.dart import 'package:app_flowy/workspace/application/view/view_ext.dart'; import 'package:app_flowy/workspace/presentation/home/home_stack.dart'; import 'package:app_flowy/workspace/presentation/home/menu/menu.dart'; - import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:reorderables/reorderables.dart'; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart index 48549a5f28..653e24e47d 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart @@ -301,6 +301,23 @@ class FolderEventCloseView { } } +class FolderEventMoveItem { + MoveFolderItemPayload request; + FolderEventMoveItem(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = FolderEvent.MoveItem.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (bytes) => left(unit), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class FolderEventReadTrash { FolderEventReadTrash(); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart index 98882f444d..781a2fcdca 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pb.dart @@ -891,3 +891,92 @@ class UpdateViewParams extends $pb.GeneratedMessage { void clearThumbnail() => clearField(4); } +class MoveFolderItemPayload extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MoveFolderItemPayload', createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'itemId') + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'from', $pb.PbFieldType.O3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'to', $pb.PbFieldType.O3) + ..e(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ty', $pb.PbFieldType.OE, defaultOrMaker: MoveFolderItemType.MoveApp, valueOf: MoveFolderItemType.valueOf, enumValues: MoveFolderItemType.values) + ..hasRequiredFields = false + ; + + MoveFolderItemPayload._() : super(); + factory MoveFolderItemPayload({ + $core.String? itemId, + $core.int? from, + $core.int? to, + MoveFolderItemType? ty, + }) { + final _result = create(); + if (itemId != null) { + _result.itemId = itemId; + } + if (from != null) { + _result.from = from; + } + if (to != null) { + _result.to = to; + } + if (ty != null) { + _result.ty = ty; + } + return _result; + } + factory MoveFolderItemPayload.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MoveFolderItemPayload.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MoveFolderItemPayload clone() => MoveFolderItemPayload()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MoveFolderItemPayload copyWith(void Function(MoveFolderItemPayload) updates) => super.copyWith((message) => updates(message as MoveFolderItemPayload)) as MoveFolderItemPayload; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MoveFolderItemPayload create() => MoveFolderItemPayload._(); + MoveFolderItemPayload createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static MoveFolderItemPayload getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static MoveFolderItemPayload? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get itemId => $_getSZ(0); + @$pb.TagNumber(1) + set itemId($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasItemId() => $_has(0); + @$pb.TagNumber(1) + void clearItemId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get from => $_getIZ(1); + @$pb.TagNumber(2) + set from($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasFrom() => $_has(1); + @$pb.TagNumber(2) + void clearFrom() => clearField(2); + + @$pb.TagNumber(3) + $core.int get to => $_getIZ(2); + @$pb.TagNumber(3) + set to($core.int v) { $_setSignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasTo() => $_has(2); + @$pb.TagNumber(3) + void clearTo() => clearField(3); + + @$pb.TagNumber(4) + MoveFolderItemType get ty => $_getN(3); + @$pb.TagNumber(4) + set ty(MoveFolderItemType v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasTy() => $_has(3); + @$pb.TagNumber(4) + void clearTy() => clearField(4); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart index aa7b0105b1..9c499c50d1 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbenum.dart @@ -24,3 +24,18 @@ class ViewDataType extends $pb.ProtobufEnum { const ViewDataType._($core.int v, $core.String n) : super(v, n); } +class MoveFolderItemType extends $pb.ProtobufEnum { + static const MoveFolderItemType MoveApp = MoveFolderItemType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveApp'); + static const MoveFolderItemType MoveView = MoveFolderItemType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveView'); + + static const $core.List values = [ + MoveApp, + MoveView, + ]; + + static final $core.Map<$core.int, MoveFolderItemType> _byValue = $pb.ProtobufEnum.initByValue(values); + static MoveFolderItemType? valueOf($core.int value) => _byValue[value]; + + const MoveFolderItemType._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart index 0f1949754f..fd2504389f 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder-data-model/view.pbjson.dart @@ -19,6 +19,17 @@ const ViewDataType$json = const { /// Descriptor for `ViewDataType`. Decode as a `google.protobuf.EnumDescriptorProto`. final $typed_data.Uint8List viewDataTypeDescriptor = $convert.base64Decode('CgxWaWV3RGF0YVR5cGUSDQoJVGV4dEJsb2NrEAASCAoER3JpZBAB'); +@$core.Deprecated('Use moveFolderItemTypeDescriptor instead') +const MoveFolderItemType$json = const { + '1': 'MoveFolderItemType', + '2': const [ + const {'1': 'MoveApp', '2': 0}, + const {'1': 'MoveView', '2': 1}, + ], +}; + +/// Descriptor for `MoveFolderItemType`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List moveFolderItemTypeDescriptor = $convert.base64Decode('ChJNb3ZlRm9sZGVySXRlbVR5cGUSCwoHTW92ZUFwcBAAEgwKCE1vdmVWaWV3EAE='); @$core.Deprecated('Use viewDescriptor instead') const View$json = const { '1': 'View', @@ -142,3 +153,16 @@ const UpdateViewParams$json = const { /// Descriptor for `UpdateViewParams`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List updateViewParamsDescriptor = $convert.base64Decode('ChBVcGRhdGVWaWV3UGFyYW1zEhcKB3ZpZXdfaWQYASABKAlSBnZpZXdJZBIUCgRuYW1lGAIgASgJSABSBG5hbWUSFAoEZGVzYxgDIAEoCUgBUgRkZXNjEh4KCXRodW1ibmFpbBgEIAEoCUgCUgl0aHVtYm5haWxCDQoLb25lX29mX25hbWVCDQoLb25lX29mX2Rlc2NCEgoQb25lX29mX3RodW1ibmFpbA=='); +@$core.Deprecated('Use moveFolderItemPayloadDescriptor instead') +const MoveFolderItemPayload$json = const { + '1': 'MoveFolderItemPayload', + '2': const [ + const {'1': 'item_id', '3': 1, '4': 1, '5': 9, '10': 'itemId'}, + const {'1': 'from', '3': 2, '4': 1, '5': 5, '10': 'from'}, + const {'1': 'to', '3': 3, '4': 1, '5': 5, '10': 'to'}, + const {'1': 'ty', '3': 4, '4': 1, '5': 14, '6': '.MoveFolderItemType', '10': 'ty'}, + ], +}; + +/// Descriptor for `MoveFolderItemPayload`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List moveFolderItemPayloadDescriptor = $convert.base64Decode('ChVNb3ZlRm9sZGVySXRlbVBheWxvYWQSFwoHaXRlbV9pZBgBIAEoCVIGaXRlbUlkEhIKBGZyb20YAiABKAVSBGZyb20SDgoCdG8YAyABKAVSAnRvEiMKAnR5GAQgASgOMhMuTW92ZUZvbGRlckl0ZW1UeXBlUgJ0eQ=='); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart index 73484cead5..3647fc21d0 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart @@ -28,6 +28,7 @@ class FolderEvent extends $pb.ProtobufEnum { static const FolderEvent CopyLink = FolderEvent._(206, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CopyLink'); static const FolderEvent SetLatestView = FolderEvent._(207, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SetLatestView'); static const FolderEvent CloseView = FolderEvent._(208, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CloseView'); + static const FolderEvent MoveItem = FolderEvent._(209, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveItem'); static const FolderEvent ReadTrash = FolderEvent._(300, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadTrash'); static const FolderEvent PutbackTrash = FolderEvent._(301, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PutbackTrash'); static const FolderEvent DeleteTrash = FolderEvent._(302, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteTrash'); @@ -53,6 +54,7 @@ class FolderEvent extends $pb.ProtobufEnum { CopyLink, SetLatestView, CloseView, + MoveItem, ReadTrash, PutbackTrash, DeleteTrash, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart index 136849065b..4ea50bd446 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart @@ -30,6 +30,7 @@ const FolderEvent$json = const { const {'1': 'CopyLink', '2': 206}, const {'1': 'SetLatestView', '2': 207}, const {'1': 'CloseView', '2': 208}, + const {'1': 'MoveItem', '2': 209}, const {'1': 'ReadTrash', '2': 300}, const {'1': 'PutbackTrash', '2': 301}, const {'1': 'DeleteTrash', '2': 302}, @@ -39,4 +40,4 @@ const FolderEvent$json = const { }; /// Descriptor for `FolderEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAg=='); +final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARINCghNb3ZlSXRlbRDRARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAg=='); diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 906e9406ce..2d240499b8 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -62,7 +62,8 @@ pub fn create(folder: Arc) -> Module { .event(FolderEvent::DeleteView, delete_view_handler) .event(FolderEvent::DuplicateView, duplicate_view_handler) .event(FolderEvent::SetLatestView, set_latest_view_handler) - .event(FolderEvent::CloseView, close_view_handler); + .event(FolderEvent::CloseView, close_view_handler) + .event(FolderEvent::MoveItem, move_item_handler); module = module .event(FolderEvent::ReadTrash, read_trash_handler) @@ -131,6 +132,9 @@ pub enum FolderEvent { #[event(input = "ViewId")] CloseView = 208, + #[event(input = "MoveFolderItemPayload")] + MoveItem = 209, + #[event(output = "RepeatedTrash")] ReadTrash = 300, diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs index 6dc25807d6..138ba1ea92 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs @@ -43,6 +43,7 @@ pub enum FolderEvent { CopyLink = 206, SetLatestView = 207, CloseView = 208, + MoveItem = 209, ReadTrash = 300, PutbackTrash = 301, DeleteTrash = 302, @@ -75,6 +76,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { 206 => ::std::option::Option::Some(FolderEvent::CopyLink), 207 => ::std::option::Option::Some(FolderEvent::SetLatestView), 208 => ::std::option::Option::Some(FolderEvent::CloseView), + 209 => ::std::option::Option::Some(FolderEvent::MoveItem), 300 => ::std::option::Option::Some(FolderEvent::ReadTrash), 301 => ::std::option::Option::Some(FolderEvent::PutbackTrash), 302 => ::std::option::Option::Some(FolderEvent::DeleteTrash), @@ -104,6 +106,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { FolderEvent::CopyLink, FolderEvent::SetLatestView, FolderEvent::CloseView, + FolderEvent::MoveItem, FolderEvent::ReadTrash, FolderEvent::PutbackTrash, FolderEvent::DeleteTrash, @@ -137,7 +140,7 @@ impl ::protobuf::reflect::ProtobufValue for FolderEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xae\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ + \n\x0fevent_map.proto*\xbd\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ pace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorksp\ aces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspa\ ce\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\r\n\tCreateApp\x10\ @@ -145,10 +148,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10h\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\ \x12\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\ \x12\n\rDuplicateView\x10\xcd\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\ - \x12\n\rSetLatestView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\ - \x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\ - \x10\n\x0bDeleteTrash\x10\xae\x02\x12\x14\n\x0fRestoreAllTrash\x10\xaf\ - \x02\x12\x13\n\x0eDeleteAllTrash\x10\xb0\x02b\x06proto3\ + \x12\n\rSetLatestView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\r\ + \n\x08MoveItem\x10\xd1\x01\x12\x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\ + \x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0bDeleteTrash\x10\xae\x02\x12\ + \x14\n\x0fRestoreAllTrash\x10\xaf\x02\x12\x13\n\x0eDeleteAllTrash\x10\ + \xb0\x02b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto index 67f2606664..10fe665840 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto @@ -19,6 +19,7 @@ enum FolderEvent { CopyLink = 206; SetLatestView = 207; CloseView = 208; + MoveItem = 209; ReadTrash = 300; PutbackTrash = 301; DeleteTrash = 302; diff --git a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs index ce8cc321a6..d33f40b4c6 100644 --- a/frontend/rust-lib/flowy-folder/src/services/app/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/app/controller.rs @@ -95,6 +95,19 @@ impl AppController { Ok(()) } + pub(crate) async fn move_app(&self, app_id: &str, from: usize, to: usize) -> FlowyResult<()> { + let _ = self + .persistence + .begin_transaction(|transaction| { + let _ = transaction.move_app(app_id, from, to)?; + let app = transaction.read_app(app_id)?; + let _ = notify_apps_changed(&app.workspace_id, self.trash_controller.clone(), &transaction)?; + Ok(()) + }) + .await?; + Ok(()) + } + pub(crate) async fn read_local_apps(&self, ids: Vec) -> Result, FlowyError> { let apps = self .persistence diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs index 89b7245da9..b272168e33 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/mod.rs @@ -34,12 +34,14 @@ pub trait FolderPersistenceTransaction { fn read_app(&self, app_id: &str) -> FlowyResult; fn read_workspace_apps(&self, workspace_id: &str) -> FlowyResult>; fn delete_app(&self, app_id: &str) -> FlowyResult; + fn move_app(&self, app_id: &str, from: usize, to: usize) -> FlowyResult<()>; fn create_view(&self, view: View) -> FlowyResult<()>; fn read_view(&self, view_id: &str) -> FlowyResult; fn read_views(&self, belong_to_id: &str) -> FlowyResult>; fn update_view(&self, changeset: ViewChangeset) -> FlowyResult<()>; fn delete_view(&self, view_id: &str) -> FlowyResult<()>; + fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()>; fn create_trash(&self, trashes: Vec) -> FlowyResult<()>; fn read_trash(&self, trash_id: Option) -> FlowyResult; diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs index c301c5a972..4f5a2d181d 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_1/v1_impl.rs @@ -63,6 +63,10 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { Ok(App::from(table)) } + fn move_app(&self, _app_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { + Ok(()) + } + fn create_view(&self, view: View) -> FlowyResult<()> { let _ = ViewTableSql::create_view(view, &*self.0)?; Ok(()) @@ -89,6 +93,10 @@ impl<'a> FolderPersistenceTransaction for V1Transaction<'a> { Ok(()) } + fn move_view(&self, _view_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { + Ok(()) + } + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { let _ = TrashTableSql::create_trash(trashes, &*self.0)?; Ok(()) @@ -160,6 +168,10 @@ where (**self).delete_app(app_id) } + fn move_app(&self, _app_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { + Ok(()) + } + fn create_view(&self, view: View) -> FlowyResult<()> { (**self).create_view(view) } @@ -180,6 +192,10 @@ where (**self).delete_view(view_id) } + fn move_view(&self, _view_id: &str, _from: usize, _to: usize) -> FlowyResult<()> { + Ok(()) + } + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { (**self).create_trash(trashes) } diff --git a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs index 80fd0bb6bb..8dafda3c93 100644 --- a/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs +++ b/frontend/rust-lib/flowy-folder/src/services/persistence/version_2/v2_impl.rs @@ -83,6 +83,13 @@ impl FolderPersistenceTransaction for ClientFolderEditor { Ok(app) } + fn move_app(&self, app_id: &str, from: usize, to: usize) -> FlowyResult<()> { + if let Some(change) = self.folder.write().move_app(app_id, from, to)? { + let _ = self.apply_change(change)?; + } + Ok(()) + } + fn create_view(&self, view: View) -> FlowyResult<()> { if let Some(change) = self.folder.write().create_view(view)? { let _ = self.apply_change(change)?; @@ -118,6 +125,13 @@ impl FolderPersistenceTransaction for ClientFolderEditor { Ok(()) } + fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()> { + if let Some(change) = self.folder.write().move_view(view_id, from, to)? { + let _ = self.apply_change(change)?; + } + Ok(()) + } + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { if let Some(change) = self.folder.write().create_trash(trashes)? { let _ = self.apply_change(change)?; @@ -178,6 +192,10 @@ where (**self).delete_app(app_id) } + fn move_app(&self, app_id: &str, from: usize, to: usize) -> FlowyResult<()> { + (**self).move_app(app_id, from, to) + } + fn create_view(&self, view: View) -> FlowyResult<()> { (**self).create_view(view) } @@ -198,6 +216,10 @@ where (**self).delete_view(view_id) } + fn move_view(&self, view_id: &str, from: usize, to: usize) -> FlowyResult<()> { + (**self).move_view(view_id, from, to) + } + fn create_trash(&self, trashes: Vec) -> FlowyResult<()> { (**self).create_trash(trashes) } diff --git a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs index c48203b74b..603b76ec2c 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/controller.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/controller.rs @@ -154,6 +154,20 @@ impl ViewController { Ok(()) } + #[tracing::instrument(level = "debug", skip(self), err)] + pub(crate) async fn move_view(&self, view_id: &str, from: usize, to: usize) -> Result<(), FlowyError> { + let _ = self + .persistence + .begin_transaction(|transaction| { + let _ = transaction.move_view(view_id, from, to)?; + let view = transaction.read_view(view_id)?; + let _ = notify_views_changed(&view.belong_to_id, self.trash_controller.clone(), &transaction)?; + Ok(()) + }) + .await?; + Ok(()) + } + #[tracing::instrument(level = "debug", skip(self), err)] pub(crate) async fn duplicate_view(&self, view_id: &str) -> Result<(), FlowyError> { let view = self diff --git a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs index 4f692d723d..e7c91dda38 100644 --- a/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs +++ b/frontend/rust-lib/flowy-folder/src/services/view/event_handler.rs @@ -1,3 +1,4 @@ +use crate::services::AppController; use crate::{ entities::{ trash::Trash, @@ -8,6 +9,7 @@ use crate::{ errors::FlowyError, services::{TrashController, ViewController}, }; +use flowy_folder_data_model::entities::view::{MoveFolderItemParams, MoveFolderItemPayload, MoveFolderItemType}; use lib_dispatch::prelude::{data_result, AppData, Data, DataResult}; use std::{convert::TryInto, sync::Arc}; @@ -83,6 +85,26 @@ pub(crate) async fn close_view_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn move_item_handler( + data: Data, + view_controller: AppData>, + app_controller: AppData>, +) -> Result<(), FlowyError> { + let params: MoveFolderItemParams = data.into_inner().try_into()?; + match params.ty { + MoveFolderItemType::MoveApp => { + let _ = app_controller.move_app(¶ms.item_id, params.from, params.to).await?; + } + MoveFolderItemType::MoveView => { + let _ = view_controller + .move_view(¶ms.item_id, params.from, params.to) + .await?; + } + } + Ok(()) +} + #[tracing::instrument(level = "debug", skip(data, controller), err)] pub(crate) async fn duplicate_view_handler( data: Data, diff --git a/shared-lib/flowy-folder-data-model/src/entities/view.rs b/shared-lib/flowy-folder-data-model/src/entities/view.rs index 1d522a1500..c536d04f50 100644 --- a/shared-lib/flowy-folder-data-model/src/entities/view.rs +++ b/shared-lib/flowy-folder-data-model/src/entities/view.rs @@ -286,6 +286,54 @@ impl TryInto for UpdateViewPayload { } } +#[derive(ProtoBuf_Enum)] +pub enum MoveFolderItemType { + MoveApp = 0, + MoveView = 1, +} + +impl std::default::Default for MoveFolderItemType { + fn default() -> Self { + MoveFolderItemType::MoveApp + } +} + +#[derive(Default, ProtoBuf)] +pub struct MoveFolderItemPayload { + #[pb(index = 1)] + pub item_id: String, + + #[pb(index = 2)] + pub from: i32, + + #[pb(index = 3)] + pub to: i32, + + #[pb(index = 4)] + pub ty: MoveFolderItemType, +} + +pub struct MoveFolderItemParams { + pub item_id: String, + pub from: usize, + pub to: usize, + pub ty: MoveFolderItemType, +} + +impl TryInto for MoveFolderItemPayload { + type Error = ErrorCode; + + fn try_into(self) -> Result { + let view_id = ViewIdentify::parse(self.item_id)?.0; + Ok(MoveFolderItemParams { + item_id: view_id, + from: self.from as usize, + to: self.to as usize, + ty: self.ty, + }) + } +} + // impl<'de> Deserialize<'de> for ViewDataType { // fn deserialize(deserializer: D) -> Result>::Error> // where diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs index 9f19e18f0c..3b119c3bc1 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs +++ b/shared-lib/flowy-folder-data-model/src/protobuf/model/view.rs @@ -2777,6 +2777,266 @@ impl ::protobuf::reflect::ProtobufValue for UpdateViewParams { } } +#[derive(PartialEq,Clone,Default)] +pub struct MoveFolderItemPayload { + // message fields + pub item_id: ::std::string::String, + pub from: i32, + pub to: i32, + pub ty: MoveFolderItemType, + // special fields + pub unknown_fields: ::protobuf::UnknownFields, + pub cached_size: ::protobuf::CachedSize, +} + +impl<'a> ::std::default::Default for &'a MoveFolderItemPayload { + fn default() -> &'a MoveFolderItemPayload { + ::default_instance() + } +} + +impl MoveFolderItemPayload { + pub fn new() -> MoveFolderItemPayload { + ::std::default::Default::default() + } + + // string item_id = 1; + + + pub fn get_item_id(&self) -> &str { + &self.item_id + } + pub fn clear_item_id(&mut self) { + self.item_id.clear(); + } + + // Param is passed by value, moved + pub fn set_item_id(&mut self, v: ::std::string::String) { + self.item_id = v; + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_item_id(&mut self) -> &mut ::std::string::String { + &mut self.item_id + } + + // Take field + pub fn take_item_id(&mut self) -> ::std::string::String { + ::std::mem::replace(&mut self.item_id, ::std::string::String::new()) + } + + // int32 from = 2; + + + pub fn get_from(&self) -> i32 { + self.from + } + pub fn clear_from(&mut self) { + self.from = 0; + } + + // Param is passed by value, moved + pub fn set_from(&mut self, v: i32) { + self.from = v; + } + + // int32 to = 3; + + + pub fn get_to(&self) -> i32 { + self.to + } + pub fn clear_to(&mut self) { + self.to = 0; + } + + // Param is passed by value, moved + pub fn set_to(&mut self, v: i32) { + self.to = v; + } + + // .MoveFolderItemType ty = 4; + + + pub fn get_ty(&self) -> MoveFolderItemType { + self.ty + } + pub fn clear_ty(&mut self) { + self.ty = MoveFolderItemType::MoveApp; + } + + // Param is passed by value, moved + pub fn set_ty(&mut self, v: MoveFolderItemType) { + self.ty = v; + } +} + +impl ::protobuf::Message for MoveFolderItemPayload { + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { + while !is.eof()? { + let (field_number, wire_type) = is.read_tag_unpack()?; + match field_number { + 1 => { + ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.item_id)?; + }, + 2 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.from = tmp; + }, + 3 => { + if wire_type != ::protobuf::wire_format::WireTypeVarint { + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); + } + let tmp = is.read_int32()?; + self.to = tmp; + }, + 4 => { + ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.ty, 4, &mut self.unknown_fields)? + }, + _ => { + ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u32 { + let mut my_size = 0; + if !self.item_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.item_id); + } + if self.from != 0 { + my_size += ::protobuf::rt::value_size(2, self.from, ::protobuf::wire_format::WireTypeVarint); + } + if self.to != 0 { + my_size += ::protobuf::rt::value_size(3, self.to, ::protobuf::wire_format::WireTypeVarint); + } + if self.ty != MoveFolderItemType::MoveApp { + my_size += ::protobuf::rt::enum_size(4, self.ty); + } + my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); + self.cached_size.set(my_size); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { + if !self.item_id.is_empty() { + os.write_string(1, &self.item_id)?; + } + if self.from != 0 { + os.write_int32(2, self.from)?; + } + if self.to != 0 { + os.write_int32(3, self.to)?; + } + if self.ty != MoveFolderItemType::MoveApp { + os.write_enum(4, ::protobuf::ProtobufEnum::value(&self.ty))?; + } + os.write_unknown_fields(self.get_unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn get_cached_size(&self) -> u32 { + self.cached_size.get() + } + + fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { + &self.unknown_fields + } + + fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { + &mut self.unknown_fields + } + + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) + } + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) + } + fn into_any(self: ::std::boxed::Box) -> ::std::boxed::Box { + self + } + + fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { + Self::descriptor_static() + } + + fn new() -> MoveFolderItemPayload { + MoveFolderItemPayload::new() + } + + fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + let mut fields = ::std::vec::Vec::new(); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( + "item_id", + |m: &MoveFolderItemPayload| { &m.item_id }, + |m: &mut MoveFolderItemPayload| { &mut m.item_id }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "from", + |m: &MoveFolderItemPayload| { &m.from }, + |m: &mut MoveFolderItemPayload| { &mut m.from }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>( + "to", + |m: &MoveFolderItemPayload| { &m.to }, + |m: &mut MoveFolderItemPayload| { &mut m.to }, + )); + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + "ty", + |m: &MoveFolderItemPayload| { &m.ty }, + |m: &mut MoveFolderItemPayload| { &mut m.ty }, + )); + ::protobuf::reflect::MessageDescriptor::new_pb_name::( + "MoveFolderItemPayload", + fields, + file_descriptor_proto() + ) + }) + } + + fn default_instance() -> &'static MoveFolderItemPayload { + static instance: ::protobuf::rt::LazyV2 = ::protobuf::rt::LazyV2::INIT; + instance.get(MoveFolderItemPayload::new) + } +} + +impl ::protobuf::Clear for MoveFolderItemPayload { + fn clear(&mut self) { + self.item_id.clear(); + self.from = 0; + self.to = 0; + self.ty = MoveFolderItemType::MoveApp; + self.unknown_fields.clear(); + } +} + +impl ::std::fmt::Debug for MoveFolderItemPayload { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveFolderItemPayload { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Message(self) + } +} + #[derive(Clone,PartialEq,Eq,Debug,Hash)] pub enum ViewDataType { TextBlock = 0, @@ -2827,6 +3087,56 @@ impl ::protobuf::reflect::ProtobufValue for ViewDataType { } } +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum MoveFolderItemType { + MoveApp = 0, + MoveView = 1, +} + +impl ::protobuf::ProtobufEnum for MoveFolderItemType { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(MoveFolderItemType::MoveApp), + 1 => ::std::option::Option::Some(MoveFolderItemType::MoveView), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [MoveFolderItemType] = &[ + MoveFolderItemType::MoveApp, + MoveFolderItemType::MoveView, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("MoveFolderItemType", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for MoveFolderItemType { +} + +impl ::std::default::Default for MoveFolderItemType { + fn default() -> Self { + MoveFolderItemType::MoveApp + } +} + +impl ::protobuf::reflect::ProtobufValue for MoveFolderItemType { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + static file_descriptor_proto_data: &'static [u8] = b"\ \n\nview.proto\"\xf5\x02\n\x04View\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\ \x02id\x12\x20\n\x0cbelong_to_id\x18\x02\x20\x01(\tR\nbelongToId\x12\x12\ @@ -2862,8 +3172,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\x04name\x18\x02\x20\x01(\tH\0R\x04name\x12\x14\n\x04desc\x18\x03\x20\ \x01(\tH\x01R\x04desc\x12\x1e\n\tthumbnail\x18\x04\x20\x01(\tH\x02R\tthu\ mbnailB\r\n\x0bone_of_nameB\r\n\x0bone_of_descB\x12\n\x10one_of_thumbnai\ - l*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\x08\n\x04Grid\x10\x01\ - b\x06proto3\ + l\"y\n\x15MoveFolderItemPayload\x12\x17\n\x07item_id\x18\x01\x20\x01(\tR\ + \x06itemId\x12\x12\n\x04from\x18\x02\x20\x01(\x05R\x04from\x12\x0e\n\x02\ + to\x18\x03\x20\x01(\x05R\x02to\x12#\n\x02ty\x18\x04\x20\x01(\x0e2\x13.Mo\ + veFolderItemTypeR\x02ty*'\n\x0cViewDataType\x12\r\n\tTextBlock\x10\0\x12\ + \x08\n\x04Grid\x10\x01*/\n\x12MoveFolderItemType\x12\x0b\n\x07MoveApp\ + \x10\0\x12\x0c\n\x08MoveView\x10\x01b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto index 56e09c54e4..8b77c323b1 100644 --- a/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto +++ b/shared-lib/flowy-folder-data-model/src/protobuf/proto/view.proto @@ -54,7 +54,17 @@ message UpdateViewParams { oneof one_of_desc { string desc = 3; }; oneof one_of_thumbnail { string thumbnail = 4; }; } +message MoveFolderItemPayload { + string item_id = 1; + int32 from = 2; + int32 to = 3; + MoveFolderItemType ty = 4; +} enum ViewDataType { TextBlock = 0; Grid = 1; } +enum MoveFolderItemType { + MoveApp = 0; + MoveView = 1; +} diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs index fd79fb8af0..a45462e01b 100644 --- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs @@ -235,6 +235,21 @@ impl FolderPad { }) } + #[tracing::instrument(level = "trace", skip(self), err)] + pub fn move_view(&mut self, view_id: &str, _from: usize, to: usize) -> CollaborateResult> { + let view = self.read_view(view_id)?; + self.with_app(&view.belong_to_id, |app| { + match app.belongings.iter().position(|view| view.id == view_id) { + None => Ok(None), + Some(index) => { + let view = app.belongings.remove(index); + app.belongings.insert(to, view); + Ok(Some(())) + } + } + }) + } + pub fn create_trash(&mut self, trash: Vec) -> CollaborateResult> { self.with_trash(|t| { let mut new_trash = trash.into_iter().map(Arc::new).collect::>>(); From e8bb6f0a7fc6b94dc5d0a9d992a3142443ea9995 Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 27 Apr 2022 07:22:18 +0800 Subject: [PATCH 5/6] chore: save app order --- .../app_flowy/lib/startup/deps_resolver.dart | 1 - .../workspace/application/menu/menu_bloc.dart | 37 +- .../application/menu/menu_bloc.freezed.dart | 525 ++++++++++++------ .../workspace/workspace_service.dart | 20 +- .../presentation/home/menu/menu.dart | 65 +-- .../src/client_folder/folder_pad.rs | 15 + 6 files changed, 427 insertions(+), 236 deletions(-) diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart index a5d6321fa0..fb5cad590e 100644 --- a/frontend/app_flowy/lib/startup/deps_resolver.dart +++ b/frontend/app_flowy/lib/startup/deps_resolver.dart @@ -99,7 +99,6 @@ void _resolveFolderDeps(GetIt getIt) { getIt.registerFactoryParam( (user, workspaceId) => MenuBloc( workspaceId: workspaceId, - service: WorkspaceService(), listener: getIt(param1: user, param2: workspaceId), ), ); diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart index 6ee18986b5..558c84b83a 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.dart @@ -12,11 +12,13 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part 'menu_bloc.freezed.dart'; class MenuBloc extends Bloc { - final WorkspaceService service; + final WorkspaceService _workspaceService; final WorkspaceListener listener; final String workspaceId; - MenuBloc({required this.workspaceId, required this.service, required this.listener}) : super(MenuState.initial()) { + MenuBloc({required this.workspaceId, required this.listener}) + : _workspaceService = WorkspaceService(workspaceId: workspaceId), + super(MenuState.initial()) { on((event, emit) async { await event.map( initial: (e) async { @@ -30,15 +32,21 @@ class MenuBloc extends Bloc { openPage: (e) async { emit(state.copyWith(plugin: e.plugin)); }, - createApp: (CreateApp event) async { + createApp: (_CreateApp event) async { await _performActionOnCreateApp(event, emit); }, didReceiveApps: (e) async { emit(e.appsOrFail.fold( - (apps) => state.copyWith(apps: some(apps), successOrFailure: left(unit)), + (apps) => state.copyWith(apps: apps, successOrFailure: left(unit)), (err) => state.copyWith(successOrFailure: right(err)), )); }, + moveApp: (_MoveApp value) { + if (state.apps.length > value.fromIndex) { + final app = state.apps[value.fromIndex]; + _workspaceService.moveApp(appId: app.id, fromIndex: value.fromIndex, toIndex: value.toIndex); + } + }, ); }); } @@ -49,8 +57,8 @@ class MenuBloc extends Bloc { return super.close(); } - Future _performActionOnCreateApp(CreateApp event, Emitter emit) async { - final result = await service.createApp(workspaceId: workspaceId, name: event.name, desc: event.desc ?? ""); + Future _performActionOnCreateApp(_CreateApp event, Emitter emit) async { + final result = await _workspaceService.createApp(name: event.name, desc: event.desc ?? ""); result.fold( (app) => {}, (error) { @@ -62,9 +70,9 @@ class MenuBloc extends Bloc { // ignore: unused_element Future _fetchApps(Emitter emit) async { - final appsOrFail = await service.getApps(workspaceId: workspaceId); + final appsOrFail = await _workspaceService.getApps(); emit(appsOrFail.fold( - (apps) => state.copyWith(apps: some(apps)), + (apps) => state.copyWith(apps: apps), (error) { Log.error(error); return state.copyWith(successOrFailure: right(error)); @@ -83,24 +91,25 @@ class MenuBloc extends Bloc { @freezed class MenuEvent with _$MenuEvent { const factory MenuEvent.initial() = _Initial; - const factory MenuEvent.collapse() = Collapse; - const factory MenuEvent.openPage(Plugin plugin) = OpenPage; - const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp; - const factory MenuEvent.didReceiveApps(Either, FlowyError> appsOrFail) = ReceiveApps; + const factory MenuEvent.collapse() = _Collapse; + const factory MenuEvent.openPage(Plugin plugin) = _OpenPage; + const factory MenuEvent.createApp(String name, {String? desc}) = _CreateApp; + const factory MenuEvent.moveApp(int fromIndex, int toIndex) = _MoveApp; + const factory MenuEvent.didReceiveApps(Either, FlowyError> appsOrFail) = _ReceiveApps; } @freezed class MenuState with _$MenuState { const factory MenuState({ required bool isCollapse, - required Option> apps, + required List apps, required Either successOrFailure, required Plugin plugin, }) = _MenuState; factory MenuState.initial() => MenuState( isCollapse: false, - apps: none(), + apps: [], successOrFailure: left(unit), plugin: makePlugin(pluginType: DefaultPlugin.blank.type()), ); diff --git a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart index 4148412aee..633357d4cc 100644 --- a/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart +++ b/frontend/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart @@ -21,25 +21,32 @@ class _$MenuEventTearOff { return const _Initial(); } - Collapse collapse() { - return const Collapse(); + _Collapse collapse() { + return const _Collapse(); } - OpenPage openPage(Plugin plugin) { - return OpenPage( + _OpenPage openPage(Plugin plugin) { + return _OpenPage( plugin, ); } - CreateApp createApp(String name, {String? desc}) { - return CreateApp( + _CreateApp createApp(String name, {String? desc}) { + return _CreateApp( name, desc: desc, ); } - ReceiveApps didReceiveApps(Either, FlowyError> appsOrFail) { - return ReceiveApps( + _MoveApp moveApp(int fromIndex, int toIndex) { + return _MoveApp( + fromIndex, + toIndex, + ); + } + + _ReceiveApps didReceiveApps(Either, FlowyError> appsOrFail) { + return _ReceiveApps( appsOrFail, ); } @@ -56,6 +63,7 @@ mixin _$MenuEvent { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) => @@ -66,6 +74,7 @@ mixin _$MenuEvent { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) => throw _privateConstructorUsedError; @@ -75,6 +84,7 @@ mixin _$MenuEvent { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) => @@ -82,28 +92,31 @@ mixin _$MenuEvent { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) => throw _privateConstructorUsedError; @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -165,6 +178,7 @@ class _$_Initial implements _Initial { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) { @@ -178,6 +192,7 @@ class _$_Initial implements _Initial { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) { return initial?.call(); @@ -190,6 +205,7 @@ class _$_Initial implements _Initial { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) { @@ -203,10 +219,11 @@ class _$_Initial implements _Initial { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) { return initial(this); } @@ -215,10 +232,11 @@ class _$_Initial implements _Initial { @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) { return initial?.call(this); } @@ -227,10 +245,11 @@ class _$_Initial implements _Initial { @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) { if (initial != null) { @@ -245,25 +264,25 @@ abstract class _Initial implements MenuEvent { } /// @nodoc -abstract class $CollapseCopyWith<$Res> { - factory $CollapseCopyWith(Collapse value, $Res Function(Collapse) then) = - _$CollapseCopyWithImpl<$Res>; +abstract class _$CollapseCopyWith<$Res> { + factory _$CollapseCopyWith(_Collapse value, $Res Function(_Collapse) then) = + __$CollapseCopyWithImpl<$Res>; } /// @nodoc -class _$CollapseCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> - implements $CollapseCopyWith<$Res> { - _$CollapseCopyWithImpl(Collapse _value, $Res Function(Collapse) _then) - : super(_value, (v) => _then(v as Collapse)); +class __$CollapseCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> + implements _$CollapseCopyWith<$Res> { + __$CollapseCopyWithImpl(_Collapse _value, $Res Function(_Collapse) _then) + : super(_value, (v) => _then(v as _Collapse)); @override - Collapse get _value => super._value as Collapse; + _Collapse get _value => super._value as _Collapse; } /// @nodoc -class _$Collapse implements Collapse { - const _$Collapse(); +class _$_Collapse implements _Collapse { + const _$_Collapse(); @override String toString() { @@ -272,7 +291,7 @@ class _$Collapse implements Collapse { @override bool operator ==(dynamic other) { - return identical(this, other) || (other is Collapse); + return identical(this, other) || (other is _Collapse); } @override @@ -285,6 +304,7 @@ class _$Collapse implements Collapse { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) { @@ -298,6 +318,7 @@ class _$Collapse implements Collapse { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) { return collapse?.call(); @@ -310,6 +331,7 @@ class _$Collapse implements Collapse { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) { @@ -323,10 +345,11 @@ class _$Collapse implements Collapse { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) { return collapse(this); } @@ -335,10 +358,11 @@ class _$Collapse implements Collapse { @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) { return collapse?.call(this); } @@ -347,10 +371,11 @@ class _$Collapse implements Collapse { @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) { if (collapse != null) { @@ -360,31 +385,31 @@ class _$Collapse implements Collapse { } } -abstract class Collapse implements MenuEvent { - const factory Collapse() = _$Collapse; +abstract class _Collapse implements MenuEvent { + const factory _Collapse() = _$_Collapse; } /// @nodoc -abstract class $OpenPageCopyWith<$Res> { - factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) = - _$OpenPageCopyWithImpl<$Res>; +abstract class _$OpenPageCopyWith<$Res> { + factory _$OpenPageCopyWith(_OpenPage value, $Res Function(_OpenPage) then) = + __$OpenPageCopyWithImpl<$Res>; $Res call({Plugin plugin}); } /// @nodoc -class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> - implements $OpenPageCopyWith<$Res> { - _$OpenPageCopyWithImpl(OpenPage _value, $Res Function(OpenPage) _then) - : super(_value, (v) => _then(v as OpenPage)); +class __$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> + implements _$OpenPageCopyWith<$Res> { + __$OpenPageCopyWithImpl(_OpenPage _value, $Res Function(_OpenPage) _then) + : super(_value, (v) => _then(v as _OpenPage)); @override - OpenPage get _value => super._value as OpenPage; + _OpenPage get _value => super._value as _OpenPage; @override $Res call({ Object? plugin = freezed, }) { - return _then(OpenPage( + return _then(_OpenPage( plugin == freezed ? _value.plugin : plugin // ignore: cast_nullable_to_non_nullable @@ -395,8 +420,8 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> /// @nodoc -class _$OpenPage implements OpenPage { - const _$OpenPage(this.plugin); +class _$_OpenPage implements _OpenPage { + const _$_OpenPage(this.plugin); @override final Plugin plugin; @@ -409,7 +434,7 @@ class _$OpenPage implements OpenPage { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is OpenPage && + (other is _OpenPage && (identical(other.plugin, plugin) || const DeepCollectionEquality().equals(other.plugin, plugin))); } @@ -420,8 +445,8 @@ class _$OpenPage implements OpenPage { @JsonKey(ignore: true) @override - $OpenPageCopyWith get copyWith => - _$OpenPageCopyWithImpl(this, _$identity); + _$OpenPageCopyWith<_OpenPage> get copyWith => + __$OpenPageCopyWithImpl<_OpenPage>(this, _$identity); @override @optionalTypeArgs @@ -430,6 +455,7 @@ class _$OpenPage implements OpenPage { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) { @@ -443,6 +469,7 @@ class _$OpenPage implements OpenPage { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) { return openPage?.call(plugin); @@ -455,6 +482,7 @@ class _$OpenPage implements OpenPage { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) { @@ -468,10 +496,11 @@ class _$OpenPage implements OpenPage { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) { return openPage(this); } @@ -480,10 +509,11 @@ class _$OpenPage implements OpenPage { @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) { return openPage?.call(this); } @@ -492,10 +522,11 @@ class _$OpenPage implements OpenPage { @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) { if (openPage != null) { @@ -505,37 +536,38 @@ class _$OpenPage implements OpenPage { } } -abstract class OpenPage implements MenuEvent { - const factory OpenPage(Plugin plugin) = _$OpenPage; +abstract class _OpenPage implements MenuEvent { + const factory _OpenPage(Plugin plugin) = _$_OpenPage; Plugin get plugin => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $OpenPageCopyWith get copyWith => + _$OpenPageCopyWith<_OpenPage> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class $CreateAppCopyWith<$Res> { - factory $CreateAppCopyWith(CreateApp value, $Res Function(CreateApp) then) = - _$CreateAppCopyWithImpl<$Res>; +abstract class _$CreateAppCopyWith<$Res> { + factory _$CreateAppCopyWith( + _CreateApp value, $Res Function(_CreateApp) then) = + __$CreateAppCopyWithImpl<$Res>; $Res call({String name, String? desc}); } /// @nodoc -class _$CreateAppCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> - implements $CreateAppCopyWith<$Res> { - _$CreateAppCopyWithImpl(CreateApp _value, $Res Function(CreateApp) _then) - : super(_value, (v) => _then(v as CreateApp)); +class __$CreateAppCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> + implements _$CreateAppCopyWith<$Res> { + __$CreateAppCopyWithImpl(_CreateApp _value, $Res Function(_CreateApp) _then) + : super(_value, (v) => _then(v as _CreateApp)); @override - CreateApp get _value => super._value as CreateApp; + _CreateApp get _value => super._value as _CreateApp; @override $Res call({ Object? name = freezed, Object? desc = freezed, }) { - return _then(CreateApp( + return _then(_CreateApp( name == freezed ? _value.name : name // ignore: cast_nullable_to_non_nullable @@ -550,8 +582,8 @@ class _$CreateAppCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> /// @nodoc -class _$CreateApp implements CreateApp { - const _$CreateApp(this.name, {this.desc}); +class _$_CreateApp implements _CreateApp { + const _$_CreateApp(this.name, {this.desc}); @override final String name; @@ -566,7 +598,7 @@ class _$CreateApp implements CreateApp { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is CreateApp && + (other is _CreateApp && (identical(other.name, name) || const DeepCollectionEquality().equals(other.name, name)) && (identical(other.desc, desc) || @@ -581,8 +613,8 @@ class _$CreateApp implements CreateApp { @JsonKey(ignore: true) @override - $CreateAppCopyWith get copyWith => - _$CreateAppCopyWithImpl(this, _$identity); + _$CreateAppCopyWith<_CreateApp> get copyWith => + __$CreateAppCopyWithImpl<_CreateApp>(this, _$identity); @override @optionalTypeArgs @@ -591,6 +623,7 @@ class _$CreateApp implements CreateApp { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) { @@ -604,6 +637,7 @@ class _$CreateApp implements CreateApp { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) { return createApp?.call(name, desc); @@ -616,6 +650,7 @@ class _$CreateApp implements CreateApp { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) { @@ -629,10 +664,11 @@ class _$CreateApp implements CreateApp { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) { return createApp(this); } @@ -641,10 +677,11 @@ class _$CreateApp implements CreateApp { @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) { return createApp?.call(this); } @@ -653,10 +690,11 @@ class _$CreateApp implements CreateApp { @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) { if (createApp != null) { @@ -666,39 +704,208 @@ class _$CreateApp implements CreateApp { } } -abstract class CreateApp implements MenuEvent { - const factory CreateApp(String name, {String? desc}) = _$CreateApp; +abstract class _CreateApp implements MenuEvent { + const factory _CreateApp(String name, {String? desc}) = _$_CreateApp; String get name => throw _privateConstructorUsedError; String? get desc => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $CreateAppCopyWith get copyWith => + _$CreateAppCopyWith<_CreateApp> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class $ReceiveAppsCopyWith<$Res> { - factory $ReceiveAppsCopyWith( - ReceiveApps value, $Res Function(ReceiveApps) then) = - _$ReceiveAppsCopyWithImpl<$Res>; +abstract class _$MoveAppCopyWith<$Res> { + factory _$MoveAppCopyWith(_MoveApp value, $Res Function(_MoveApp) then) = + __$MoveAppCopyWithImpl<$Res>; + $Res call({int fromIndex, int toIndex}); +} + +/// @nodoc +class __$MoveAppCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> + implements _$MoveAppCopyWith<$Res> { + __$MoveAppCopyWithImpl(_MoveApp _value, $Res Function(_MoveApp) _then) + : super(_value, (v) => _then(v as _MoveApp)); + + @override + _MoveApp get _value => super._value as _MoveApp; + + @override + $Res call({ + Object? fromIndex = freezed, + Object? toIndex = freezed, + }) { + return _then(_MoveApp( + fromIndex == freezed + ? _value.fromIndex + : fromIndex // ignore: cast_nullable_to_non_nullable + as int, + toIndex == freezed + ? _value.toIndex + : toIndex // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc + +class _$_MoveApp implements _MoveApp { + const _$_MoveApp(this.fromIndex, this.toIndex); + + @override + final int fromIndex; + @override + final int toIndex; + + @override + String toString() { + return 'MenuEvent.moveApp(fromIndex: $fromIndex, toIndex: $toIndex)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _MoveApp && + (identical(other.fromIndex, fromIndex) || + const DeepCollectionEquality() + .equals(other.fromIndex, fromIndex)) && + (identical(other.toIndex, toIndex) || + const DeepCollectionEquality().equals(other.toIndex, toIndex))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ + const DeepCollectionEquality().hash(fromIndex) ^ + const DeepCollectionEquality().hash(toIndex); + + @JsonKey(ignore: true) + @override + _$MoveAppCopyWith<_MoveApp> get copyWith => + __$MoveAppCopyWithImpl<_MoveApp>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function() collapse, + required TResult Function(Plugin plugin) openPage, + required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, + required TResult Function(Either, FlowyError> appsOrFail) + didReceiveApps, + }) { + return moveApp(fromIndex, toIndex); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult Function()? initial, + TResult Function()? collapse, + TResult Function(Plugin plugin)? openPage, + TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, + TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, + }) { + return moveApp?.call(fromIndex, toIndex); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function()? collapse, + TResult Function(Plugin plugin)? openPage, + TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, + TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, + required TResult orElse(), + }) { + if (moveApp != null) { + return moveApp(fromIndex, toIndex); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, + }) { + return moveApp(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult Function(_Initial value)? initial, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, + }) { + return moveApp?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, + required TResult orElse(), + }) { + if (moveApp != null) { + return moveApp(this); + } + return orElse(); + } +} + +abstract class _MoveApp implements MenuEvent { + const factory _MoveApp(int fromIndex, int toIndex) = _$_MoveApp; + + int get fromIndex => throw _privateConstructorUsedError; + int get toIndex => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$MoveAppCopyWith<_MoveApp> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$ReceiveAppsCopyWith<$Res> { + factory _$ReceiveAppsCopyWith( + _ReceiveApps value, $Res Function(_ReceiveApps) then) = + __$ReceiveAppsCopyWithImpl<$Res>; $Res call({Either, FlowyError> appsOrFail}); } /// @nodoc -class _$ReceiveAppsCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> - implements $ReceiveAppsCopyWith<$Res> { - _$ReceiveAppsCopyWithImpl( - ReceiveApps _value, $Res Function(ReceiveApps) _then) - : super(_value, (v) => _then(v as ReceiveApps)); +class __$ReceiveAppsCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> + implements _$ReceiveAppsCopyWith<$Res> { + __$ReceiveAppsCopyWithImpl( + _ReceiveApps _value, $Res Function(_ReceiveApps) _then) + : super(_value, (v) => _then(v as _ReceiveApps)); @override - ReceiveApps get _value => super._value as ReceiveApps; + _ReceiveApps get _value => super._value as _ReceiveApps; @override $Res call({ Object? appsOrFail = freezed, }) { - return _then(ReceiveApps( + return _then(_ReceiveApps( appsOrFail == freezed ? _value.appsOrFail : appsOrFail // ignore: cast_nullable_to_non_nullable @@ -709,8 +916,8 @@ class _$ReceiveAppsCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> /// @nodoc -class _$ReceiveApps implements ReceiveApps { - const _$ReceiveApps(this.appsOrFail); +class _$_ReceiveApps implements _ReceiveApps { + const _$_ReceiveApps(this.appsOrFail); @override final Either, FlowyError> appsOrFail; @@ -723,7 +930,7 @@ class _$ReceiveApps implements ReceiveApps { @override bool operator ==(dynamic other) { return identical(this, other) || - (other is ReceiveApps && + (other is _ReceiveApps && (identical(other.appsOrFail, appsOrFail) || const DeepCollectionEquality() .equals(other.appsOrFail, appsOrFail))); @@ -735,8 +942,8 @@ class _$ReceiveApps implements ReceiveApps { @JsonKey(ignore: true) @override - $ReceiveAppsCopyWith get copyWith => - _$ReceiveAppsCopyWithImpl(this, _$identity); + _$ReceiveAppsCopyWith<_ReceiveApps> get copyWith => + __$ReceiveAppsCopyWithImpl<_ReceiveApps>(this, _$identity); @override @optionalTypeArgs @@ -745,6 +952,7 @@ class _$ReceiveApps implements ReceiveApps { required TResult Function() collapse, required TResult Function(Plugin plugin) openPage, required TResult Function(String name, String? desc) createApp, + required TResult Function(int fromIndex, int toIndex) moveApp, required TResult Function(Either, FlowyError> appsOrFail) didReceiveApps, }) { @@ -758,6 +966,7 @@ class _$ReceiveApps implements ReceiveApps { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, }) { return didReceiveApps?.call(appsOrFail); @@ -770,6 +979,7 @@ class _$ReceiveApps implements ReceiveApps { TResult Function()? collapse, TResult Function(Plugin plugin)? openPage, TResult Function(String name, String? desc)? createApp, + TResult Function(int fromIndex, int toIndex)? moveApp, TResult Function(Either, FlowyError> appsOrFail)? didReceiveApps, required TResult orElse(), }) { @@ -783,10 +993,11 @@ class _$ReceiveApps implements ReceiveApps { @optionalTypeArgs TResult map({ required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(ReceiveApps value) didReceiveApps, + required TResult Function(_Collapse value) collapse, + required TResult Function(_OpenPage value) openPage, + required TResult Function(_CreateApp value) createApp, + required TResult Function(_MoveApp value) moveApp, + required TResult Function(_ReceiveApps value) didReceiveApps, }) { return didReceiveApps(this); } @@ -795,10 +1006,11 @@ class _$ReceiveApps implements ReceiveApps { @optionalTypeArgs TResult? mapOrNull({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, }) { return didReceiveApps?.call(this); } @@ -807,10 +1019,11 @@ class _$ReceiveApps implements ReceiveApps { @optionalTypeArgs TResult maybeMap({ TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(ReceiveApps value)? didReceiveApps, + TResult Function(_Collapse value)? collapse, + TResult Function(_OpenPage value)? openPage, + TResult Function(_CreateApp value)? createApp, + TResult Function(_MoveApp value)? moveApp, + TResult Function(_ReceiveApps value)? didReceiveApps, required TResult orElse(), }) { if (didReceiveApps != null) { @@ -820,14 +1033,14 @@ class _$ReceiveApps implements ReceiveApps { } } -abstract class ReceiveApps implements MenuEvent { - const factory ReceiveApps(Either, FlowyError> appsOrFail) = - _$ReceiveApps; +abstract class _ReceiveApps implements MenuEvent { + const factory _ReceiveApps(Either, FlowyError> appsOrFail) = + _$_ReceiveApps; Either, FlowyError> get appsOrFail => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $ReceiveAppsCopyWith get copyWith => + _$ReceiveAppsCopyWith<_ReceiveApps> get copyWith => throw _privateConstructorUsedError; } @@ -837,7 +1050,7 @@ class _$MenuStateTearOff { _MenuState call( {required bool isCollapse, - required Option> apps, + required List apps, required Either successOrFailure, required Plugin plugin}) { return _MenuState( @@ -855,7 +1068,7 @@ const $MenuState = _$MenuStateTearOff(); /// @nodoc mixin _$MenuState { bool get isCollapse => throw _privateConstructorUsedError; - Option> get apps => throw _privateConstructorUsedError; + List get apps => throw _privateConstructorUsedError; Either get successOrFailure => throw _privateConstructorUsedError; Plugin get plugin => throw _privateConstructorUsedError; @@ -871,7 +1084,7 @@ abstract class $MenuStateCopyWith<$Res> { _$MenuStateCopyWithImpl<$Res>; $Res call( {bool isCollapse, - Option> apps, + List apps, Either successOrFailure, Plugin plugin}); } @@ -899,7 +1112,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> { apps: apps == freezed ? _value.apps : apps // ignore: cast_nullable_to_non_nullable - as Option>, + as List, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -920,7 +1133,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> { @override $Res call( {bool isCollapse, - Option> apps, + List apps, Either successOrFailure, Plugin plugin}); } @@ -949,7 +1162,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res> apps: apps == freezed ? _value.apps : apps // ignore: cast_nullable_to_non_nullable - as Option>, + as List, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -974,7 +1187,7 @@ class _$_MenuState implements _MenuState { @override final bool isCollapse; @override - final Option> apps; + final List apps; @override final Either successOrFailure; @override @@ -1018,14 +1231,14 @@ class _$_MenuState implements _MenuState { abstract class _MenuState implements MenuState { const factory _MenuState( {required bool isCollapse, - required Option> apps, + required List apps, required Either successOrFailure, required Plugin plugin}) = _$_MenuState; @override bool get isCollapse => throw _privateConstructorUsedError; @override - Option> get apps => throw _privateConstructorUsedError; + List get apps => throw _privateConstructorUsedError; @override Either get successOrFailure => throw _privateConstructorUsedError; diff --git a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart index e12b8174e5..fc3e05e629 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart @@ -1,15 +1,21 @@ import 'dart:async'; + import 'package:dartz/dartz.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart' show MoveFolderItemPayload, MoveItemType; -import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart' show MoveFolderItemPayload, MoveFolderItemType; +import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.dart'; + import 'package:app_flowy/generated/locale_keys.g.dart'; class WorkspaceService { - Future> createApp({required String workspaceId, required String name, required String desc}) { + final String workspaceId; + WorkspaceService({ + required this.workspaceId, + }); + Future> createApp({required String name, required String desc}) { final payload = CreateAppPayload.create() ..name = name ..workspaceId = workspaceId @@ -17,7 +23,7 @@ class WorkspaceService { return FolderEventCreateApp(payload).send(); } - Future> getWorkspace({required String workspaceId}) { + Future> getWorkspace() { final payload = WorkspaceId.create()..value = workspaceId; return FolderEventReadWorkspaces(payload).send().then((result) { return result.fold( @@ -35,7 +41,7 @@ class WorkspaceService { }); } - Future, FlowyError>> getApps({required String workspaceId}) { + Future, FlowyError>> getApps() { final payload = WorkspaceId.create()..value = workspaceId; return FolderEventReadWorkspaceApps(payload).send().then((result) { return result.fold( @@ -54,7 +60,7 @@ class WorkspaceService { ..itemId = appId ..from = fromIndex ..to = toIndex - ..ty = MoveItemType.MoveApp; + ..ty = MoveFolderItemType.MoveApp; return FolderEventMoveItem(payload).send(); } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart index 49959ce0ce..b8c116a45a 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/menu.dart @@ -26,7 +26,7 @@ import 'app/menu_app.dart'; import 'app/create_button.dart'; import 'menu_user.dart'; -class HomeMenu extends StatefulWidget { +class HomeMenu extends StatelessWidget { final PublishNotifier _collapsedNotifier; final UserProfile user; final CurrentWorkspaceSetting workspaceSetting; @@ -39,22 +39,13 @@ class HomeMenu extends StatefulWidget { }) : _collapsedNotifier = collapsedNotifier, super(key: key); - @override - State createState() => _HomeMenuState(); -} - -class _HomeMenuState extends State { - /// Maps the hashmap of the menu items to their index in reorderable list view. - //TODO @gaganyadav80: Retain this map to persist on app restarts. - final Map _menuItemIndex = {}; - @override Widget build(BuildContext context) { return MultiBlocProvider( providers: [ BlocProvider( create: (context) { - final menuBloc = getIt(param1: widget.user, param2: widget.workspaceSetting.workspace.id); + final menuBloc = getIt(param1: user, param2: workspaceSetting.workspace.id); menuBloc.add(const MenuEvent.initial()); return menuBloc; }, @@ -71,7 +62,7 @@ class _HomeMenuState extends State { BlocListener( listenWhen: (p, c) => p.isCollapse != c.isCollapse, listener: (context, state) { - widget._collapsedNotifier.value = state.isCollapse; + _collapsedNotifier.value = state.isCollapse; }, ) ], @@ -101,7 +92,7 @@ class _HomeMenuState extends State { ).padding(horizontal: Insets.l), ), const VSpace(20), - _renderTrash(context).padding(horizontal: Insets.l), + const MenuTrash().padding(horizontal: Insets.l), const VSpace(20), _renderNewAppButton(context), ], @@ -116,56 +107,18 @@ class _HomeMenuState extends State { child: ScrollConfiguration( behavior: const ScrollBehavior().copyWith(scrollbars: false), child: BlocSelector>( - selector: (state) { - List menuItems = []; - // menuItems.add(MenuUser(user)); - List appWidgets = - state.apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList()); - // menuItems.addAll(appWidgets); - for (int i = 0; i < appWidgets.length; i++) { - if (_menuItemIndex[appWidgets[i].key.hashCode] == null) { - _menuItemIndex[appWidgets[i].key.hashCode] = i; - } - - menuItems.insert(_menuItemIndex[appWidgets[i].key.hashCode]!, appWidgets[i]); - } - - return menuItems; - }, + selector: (state) => state.apps.map((app) => MenuApp(app)).toList(), builder: (context, menuItems) { return ReorderableListView.builder( itemCount: menuItems.length, buildDefaultDragHandles: false, header: Padding( padding: EdgeInsets.only(bottom: 20.0 - MenuAppSizes.appVPadding), - child: MenuUser(widget.user), + child: MenuUser(user), ), - onReorder: (oldIndex, newIndex) { - int index = newIndex > oldIndex ? newIndex - 1 : newIndex; - - Widget menu = menuItems.removeAt(oldIndex); - menuItems.insert(index, menu); - - final menuBloc = context.read(); - menuBloc.state.apps.forEach((a) { - var app = a.removeAt(oldIndex); - a.insert(index, app); - }); - - _menuItemIndex[menu.key.hashCode] = index; - }, + onReorder: (oldIndex, newIndex) => context.read().add(MenuEvent.moveApp(oldIndex, newIndex)), physics: StyledScrollPhysics(), itemBuilder: (BuildContext context, int index) { - //? @gaganyadav80: To mimic the ListView.separated behavior, we need to add a padding. - // EdgeInsets padding = EdgeInsets.zero; - // if (index == 0) { - // padding = EdgeInsets.only(bottom: MenuAppSizes.appVPadding / 2); - // } else if (index == menuItems.length - 1) { - // padding = EdgeInsets.only(top: MenuAppSizes.appVPadding / 2); - // } else { - // padding = EdgeInsets.symmetric(vertical: MenuAppSizes.appVPadding / 2); - // } - return ReorderableDragStartListener( key: ValueKey(menuItems[index].hashCode), index: index, @@ -183,10 +136,6 @@ class _HomeMenuState extends State { ); } - Widget _renderTrash(BuildContext context) { - return const MenuTrash(); - } - Widget _renderNewAppButton(BuildContext context) { return NewAppButton( press: (appName) => context.read().add(MenuEvent.createApp(appName, desc: "")), diff --git a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs index a45462e01b..f1eb3aba5d 100644 --- a/shared-lib/flowy-sync/src/client_folder/folder_pad.rs +++ b/shared-lib/flowy-sync/src/client_folder/folder_pad.rs @@ -169,6 +169,21 @@ impl FolderPad { }) } + #[tracing::instrument(level = "trace", skip(self), err)] + pub fn move_app(&mut self, app_id: &str, _from: usize, to: usize) -> CollaborateResult> { + let app = self.read_app(app_id)?; + self.with_workspace(&app.workspace_id, |workspace| { + match workspace.apps.iter().position(|app| app.id == app_id) { + None => Ok(None), + Some(index) => { + let app = workspace.apps.remove(index); + workspace.apps.insert(to, app); + Ok(Some(())) + } + } + }) + } + #[tracing::instrument(level = "trace", skip(self), fields(view_name=%view.name), err)] pub fn create_view(&mut self, view: View) -> CollaborateResult> { let app_id = view.belong_to_id.clone(); From b29f53c995ef7b0f4dc7ee4fe54719da67ef892c Mon Sep 17 00:00:00 2001 From: appflowy Date: Wed, 27 Apr 2022 07:58:40 +0800 Subject: [PATCH 6/6] chore: print duplicate event erorr --- .../workspace/application/app/app_service.dart | 2 +- .../workspace/workspace_service.dart | 2 +- .../dart_event/flowy-folder/dart_event.dart | 6 +++--- .../flowy-folder/event_map.pbenum.dart | 4 ++-- .../flowy-folder/event_map.pbjson.dart | 4 ++-- .../rust-lib/flowy-folder/src/event_map.rs | 4 ++-- .../src/protobuf/model/event_map.rs | 18 +++++++++--------- .../src/protobuf/proto/event_map.proto | 2 +- frontend/rust-lib/flowy-sdk/src/lib.rs | 1 + .../rust-lib/lib-dispatch/src/byte_trait.rs | 13 +++++++++++-- .../rust-lib/lib-dispatch/src/dispatcher.rs | 3 ++- 11 files changed, 35 insertions(+), 24 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/app/app_service.dart b/frontend/app_flowy/lib/workspace/application/app/app_service.dart index 52702726f4..d99bb6b524 100644 --- a/frontend/app_flowy/lib/workspace/application/app/app_service.dart +++ b/frontend/app_flowy/lib/workspace/application/app/app_service.dart @@ -73,6 +73,6 @@ class AppService { ..to = toIndex ..ty = MoveFolderItemType.MoveView; - return FolderEventMoveItem(payload).send(); + return FolderEventMoveFolderItem(payload).send(); } } diff --git a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart index fc3e05e629..54183497c9 100644 --- a/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart +++ b/frontend/app_flowy/lib/workspace/application/workspace/workspace_service.dart @@ -62,6 +62,6 @@ class WorkspaceService { ..to = toIndex ..ty = MoveFolderItemType.MoveApp; - return FolderEventMoveItem(payload).send(); + return FolderEventMoveFolderItem(payload).send(); } } diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart index 653e24e47d..21dbe0ed20 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-folder/dart_event.dart @@ -301,13 +301,13 @@ class FolderEventCloseView { } } -class FolderEventMoveItem { +class FolderEventMoveFolderItem { MoveFolderItemPayload request; - FolderEventMoveItem(this.request); + FolderEventMoveFolderItem(this.request); Future> send() { final request = FFIRequest.create() - ..event = FolderEvent.MoveItem.toString() + ..event = FolderEvent.MoveFolderItem.toString() ..payload = requestToBytes(this.request); return Dispatch.asyncRequest(request) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart index 3647fc21d0..9af4068b89 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbenum.dart @@ -28,7 +28,7 @@ class FolderEvent extends $pb.ProtobufEnum { static const FolderEvent CopyLink = FolderEvent._(206, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CopyLink'); static const FolderEvent SetLatestView = FolderEvent._(207, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SetLatestView'); static const FolderEvent CloseView = FolderEvent._(208, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CloseView'); - static const FolderEvent MoveItem = FolderEvent._(209, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveItem'); + static const FolderEvent MoveFolderItem = FolderEvent._(209, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MoveFolderItem'); static const FolderEvent ReadTrash = FolderEvent._(300, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadTrash'); static const FolderEvent PutbackTrash = FolderEvent._(301, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PutbackTrash'); static const FolderEvent DeleteTrash = FolderEvent._(302, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DeleteTrash'); @@ -54,7 +54,7 @@ class FolderEvent extends $pb.ProtobufEnum { CopyLink, SetLatestView, CloseView, - MoveItem, + MoveFolderItem, ReadTrash, PutbackTrash, DeleteTrash, diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart index 4ea50bd446..9f5d05b81c 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-folder/event_map.pbjson.dart @@ -30,7 +30,7 @@ const FolderEvent$json = const { const {'1': 'CopyLink', '2': 206}, const {'1': 'SetLatestView', '2': 207}, const {'1': 'CloseView', '2': 208}, - const {'1': 'MoveItem', '2': 209}, + const {'1': 'MoveFolderItem', '2': 209}, const {'1': 'ReadTrash', '2': 300}, const {'1': 'PutbackTrash', '2': 301}, const {'1': 'DeleteTrash', '2': 302}, @@ -40,4 +40,4 @@ const FolderEvent$json = const { }; /// Descriptor for `FolderEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARINCghNb3ZlSXRlbRDRARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAg=='); +final $typed_data.Uint8List folderEventDescriptor = $convert.base64Decode('CgtGb2xkZXJFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABIUChBSZWFkQ3VyV29ya3NwYWNlEAESEgoOUmVhZFdvcmtzcGFjZXMQAhITCg9EZWxldGVXb3Jrc3BhY2UQAxIRCg1PcGVuV29ya3NwYWNlEAQSFQoRUmVhZFdvcmtzcGFjZUFwcHMQBRINCglDcmVhdGVBcHAQZRINCglEZWxldGVBcHAQZhILCgdSZWFkQXBwEGcSDQoJVXBkYXRlQXBwEGgSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsBEg8KCkRlbGV0ZVZpZXcQzAESEgoNRHVwbGljYXRlVmlldxDNARINCghDb3B5TGluaxDOARISCg1TZXRMYXRlc3RWaWV3EM8BEg4KCUNsb3NlVmlldxDQARITCg5Nb3ZlRm9sZGVySXRlbRDRARIOCglSZWFkVHJhc2gQrAISEQoMUHV0YmFja1RyYXNoEK0CEhAKC0RlbGV0ZVRyYXNoEK4CEhQKD1Jlc3RvcmVBbGxUcmFzaBCvAhITCg5EZWxldGVBbGxUcmFzaBCwAg=='); diff --git a/frontend/rust-lib/flowy-folder/src/event_map.rs b/frontend/rust-lib/flowy-folder/src/event_map.rs index 2d240499b8..22eb2c10d5 100644 --- a/frontend/rust-lib/flowy-folder/src/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/event_map.rs @@ -63,7 +63,7 @@ pub fn create(folder: Arc) -> Module { .event(FolderEvent::DuplicateView, duplicate_view_handler) .event(FolderEvent::SetLatestView, set_latest_view_handler) .event(FolderEvent::CloseView, close_view_handler) - .event(FolderEvent::MoveItem, move_item_handler); + .event(FolderEvent::MoveFolderItem, move_item_handler); module = module .event(FolderEvent::ReadTrash, read_trash_handler) @@ -133,7 +133,7 @@ pub enum FolderEvent { CloseView = 208, #[event(input = "MoveFolderItemPayload")] - MoveItem = 209, + MoveFolderItem = 209, #[event(output = "RepeatedTrash")] ReadTrash = 300, diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs index 138ba1ea92..dab3bad371 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-folder/src/protobuf/model/event_map.rs @@ -43,7 +43,7 @@ pub enum FolderEvent { CopyLink = 206, SetLatestView = 207, CloseView = 208, - MoveItem = 209, + MoveFolderItem = 209, ReadTrash = 300, PutbackTrash = 301, DeleteTrash = 302, @@ -76,7 +76,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { 206 => ::std::option::Option::Some(FolderEvent::CopyLink), 207 => ::std::option::Option::Some(FolderEvent::SetLatestView), 208 => ::std::option::Option::Some(FolderEvent::CloseView), - 209 => ::std::option::Option::Some(FolderEvent::MoveItem), + 209 => ::std::option::Option::Some(FolderEvent::MoveFolderItem), 300 => ::std::option::Option::Some(FolderEvent::ReadTrash), 301 => ::std::option::Option::Some(FolderEvent::PutbackTrash), 302 => ::std::option::Option::Some(FolderEvent::DeleteTrash), @@ -106,7 +106,7 @@ impl ::protobuf::ProtobufEnum for FolderEvent { FolderEvent::CopyLink, FolderEvent::SetLatestView, FolderEvent::CloseView, - FolderEvent::MoveItem, + FolderEvent::MoveFolderItem, FolderEvent::ReadTrash, FolderEvent::PutbackTrash, FolderEvent::DeleteTrash, @@ -140,7 +140,7 @@ impl ::protobuf::reflect::ProtobufValue for FolderEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xbd\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ + \n\x0fevent_map.proto*\xc3\x03\n\x0bFolderEvent\x12\x13\n\x0fCreateWorks\ pace\x10\0\x12\x14\n\x10ReadCurWorkspace\x10\x01\x12\x12\n\x0eReadWorksp\ aces\x10\x02\x12\x13\n\x0fDeleteWorkspace\x10\x03\x12\x11\n\rOpenWorkspa\ ce\x10\x04\x12\x15\n\x11ReadWorkspaceApps\x10\x05\x12\r\n\tCreateApp\x10\ @@ -148,11 +148,11 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x10h\x12\x0f\n\nCreateView\x10\xc9\x01\x12\r\n\x08ReadView\x10\xca\x01\ \x12\x0f\n\nUpdateView\x10\xcb\x01\x12\x0f\n\nDeleteView\x10\xcc\x01\x12\ \x12\n\rDuplicateView\x10\xcd\x01\x12\r\n\x08CopyLink\x10\xce\x01\x12\ - \x12\n\rSetLatestView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\r\ - \n\x08MoveItem\x10\xd1\x01\x12\x0e\n\tReadTrash\x10\xac\x02\x12\x11\n\ - \x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0bDeleteTrash\x10\xae\x02\x12\ - \x14\n\x0fRestoreAllTrash\x10\xaf\x02\x12\x13\n\x0eDeleteAllTrash\x10\ - \xb0\x02b\x06proto3\ + \x12\n\rSetLatestView\x10\xcf\x01\x12\x0e\n\tCloseView\x10\xd0\x01\x12\ + \x13\n\x0eMoveFolderItem\x10\xd1\x01\x12\x0e\n\tReadTrash\x10\xac\x02\ + \x12\x11\n\x0cPutbackTrash\x10\xad\x02\x12\x10\n\x0bDeleteTrash\x10\xae\ + \x02\x12\x14\n\x0fRestoreAllTrash\x10\xaf\x02\x12\x13\n\x0eDeleteAllTras\ + h\x10\xb0\x02b\x06proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto index 10fe665840..80596900de 100644 --- a/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-folder/src/protobuf/proto/event_map.proto @@ -19,7 +19,7 @@ enum FolderEvent { CopyLink = 206; SetLatestView = 207; CloseView = 208; - MoveItem = 209; + MoveFolderItem = 209; ReadTrash = 300; PutbackTrash = 301; DeleteTrash = 302; diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index b426b40550..60e277babd 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -75,6 +75,7 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); filters.push(format!("flowy_sync={}", level)); + // filters.push(format!("lib_dispatch={}", level)); filters.push(format!("dart_ffi={}", "info")); filters.push(format!("flowy_database={}", "info")); diff --git a/frontend/rust-lib/lib-dispatch/src/byte_trait.rs b/frontend/rust-lib/lib-dispatch/src/byte_trait.rs index 3e3b2ef820..9f8c2a6545 100644 --- a/frontend/rust-lib/lib-dispatch/src/byte_trait.rs +++ b/frontend/rust-lib/lib-dispatch/src/byte_trait.rs @@ -47,8 +47,17 @@ where T: std::convert::TryFrom, { fn parse_from_bytes(bytes: Bytes) -> Result { - let data = T::try_from(bytes)?; - Ok(data) + match T::try_from(bytes) { + Ok(data) => Ok(data), + Err(e) => { + tracing::error!( + "Parse payload to {} failed with error: {:?}", + std::any::type_name::(), + e + ); + Err(e.into()) + } + } } } diff --git a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs index cde08be514..ae2b15e0a0 100644 --- a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs +++ b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs @@ -139,13 +139,14 @@ impl Service for DispatchService { // print_module_map_info(&module_map); match module_map.get(&request.event) { Some(module) => { + tracing::trace!("Handle event: {:?} by {:?}", &request.event, module.name); let fut = module.new_service(()); let service_fut = fut.await?.call(request); service_fut.await } None => { let msg = format!("Can not find the event handler. {:?}", request); - log::error!("{}", msg); + tracing::error!("{}", msg); Err(InternalError::HandleNotFound(msg).into()) } }