From 0efa181ae6d72c8fb124f2dc846d9aaf4f37c404 Mon Sep 17 00:00:00 2001 From: squidrye Date: Thu, 5 Oct 2023 08:23:59 +0530 Subject: [PATCH] feat: working read view overlay logic --- .../workspace/application/panes/panes.dart | 11 +- .../panes/panes_cubit/panes_cubit.dart | 5 +- .../panes/panes_cubit/panes_state.dart | 2 +- .../application/panes/panes_service.dart | 92 ++-------- .../application/tabs/tabs_controller.dart | 173 ++++++++++++------ .../application/tabs/tabs_service.dart | 3 + .../presentation/home/home_stack.dart | 135 +++++++------- .../home/menu/menu_shared_state.dart | 19 +- .../home/tabs/draggable_tab_item.dart | 4 +- 9 files changed, 218 insertions(+), 226 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_service.dart diff --git a/frontend/appflowy_flutter/lib/workspace/application/panes/panes.dart b/frontend/appflowy_flutter/lib/workspace/application/panes/panes.dart index 29df2e2c7a26..2896ad1b6ec3 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/panes/panes.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/panes/panes.dart @@ -8,16 +8,14 @@ class PaneNode extends Equatable { final Axis? axis; final String paneId; final TabsController tabs; - final List encoding; PaneNode({ required this.paneId, required this.children, - this.encoding = const [], this.parent, this.axis, TabsController? tabs, - }) : tabs = tabs ?? TabsController(encoding: "[]"); + }) : tabs = tabs ?? TabsController(); PaneNode copyWith({ PaneNode? parent, @@ -25,7 +23,6 @@ class PaneNode extends Equatable { Axis? axis, String? paneId, TabsController? tabs, - List? encoding, }) { return PaneNode( parent: parent ?? this.parent, @@ -33,15 +30,9 @@ class PaneNode extends Equatable { children: children ?? this.children, paneId: paneId ?? this.paneId, tabs: tabs ?? this.tabs, - encoding: encoding ?? this.encoding, ); } @override List get props => [paneId, axis, children, parent, tabs]; - - @override - String toString() { - return '${(paneId, axis)} => post ${encoding} \n'; - } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_cubit.dart b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_cubit.dart index 7d2dad466e76..5585219c9117 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_cubit.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_cubit.dart @@ -61,12 +61,13 @@ class PanesCubit extends Cubit { setActivePane(state.root.children.last); } - void closePane({required String paneId}) { + void closePane({required String paneId, bool move = false}) { emit( state.copyWith( root: panesService.closePaneHandler( node: state.root, targetPaneId: paneId, + move: move, ), count: state.count - 1, ), @@ -126,6 +127,6 @@ class PanesCubit extends Cubit { count: state.count + 1, ), ); - closePane(paneId: from.paneId); + closePane(paneId: from.paneId, move: true); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_state.dart b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_state.dart index 6ebbaa66f0b8..ce5481a73d96 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_state.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_cubit/panes_state.dart @@ -14,7 +14,7 @@ class PanesState extends Equatable { factory PanesState.initial() { final pane = PaneNode( - tabs: TabsController(encoding: '[]'), + tabs: TabsController(), children: const [], paneId: nanoid(), axis: null, diff --git a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_service.dart b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_service.dart index 30f29466d6fa..7b141310442b 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/panes/panes_service.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/panes/panes_service.dart @@ -1,7 +1,6 @@ import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/application/panes/panes.dart'; import 'package:appflowy/workspace/application/tabs/tabs_controller.dart'; -import 'package:appflowy_backend/log.dart'; import 'package:flutter/material.dart'; import 'package:nanoid/nanoid.dart'; @@ -26,18 +25,13 @@ class PanesService { children: const [], axis: axis, tabs: null, - encoding: node.encoding, ); - final oldChildEncoding = [direction == Direction.front ? 0 : 1]; - final newChildEncoding = [direction == Direction.front ? 1 : 0]; + final oldChildNode = node.copyWith( + paneId: nanoid(), parent: newHolderNode, axis: null, - tabs: TabsController( - pageManagers: node.tabs.pageManagers, - encoding: oldChildEncoding.toString(), - ), - encoding: [direction == Direction.front ? 0 : 1], + tabs: TabsController(pageManagers: node.tabs.pageManagers), ); final newChildNode = fromNode?.copyWith( @@ -45,19 +39,14 @@ class PanesService { paneId: nanoid(), children: const [], axis: null, - tabs: TabsController( - pageManagers: fromNode.tabs.pageManagers, - encoding: newChildEncoding.toString()), - encoding: newChildEncoding, + tabs: TabsController(pageManagers: fromNode.tabs.pageManagers), ) ?? PaneNode( paneId: nanoid(), children: const [], parent: newHolderNode, axis: null, - tabs: TabsController(encoding: newChildEncoding.toString()) - ..openPlugin(plugin: plugin!), - encoding: newChildEncoding, + tabs: TabsController()..openPlugin(plugin: plugin!, newPane: true), ); final ret = newHolderNode.copyWith( children: direction == Direction.front @@ -78,40 +67,31 @@ class PanesService { if (node.axis == axis) { for (int i = 0; i < node.children.length; i++) { if (node.children[i].paneId == targetPaneId) { - final encode = node.encoding.toString() + - (direction == Direction.front ? "${i + 1}" : "$i"); final newNode = fromNode?.copyWith( - paneId: nanoid(), parent: node.parent, - tabs: TabsController( - pageManagers: fromNode.tabs.pageManagers, - encoding: encode, - ), + tabs: TabsController(pageManagers: fromNode.tabs.pageManagers), ) ?? PaneNode( paneId: nanoid(), children: const [], parent: node.parent, - tabs: TabsController(encoding: encode) - ..openPlugin(plugin: plugin!), + tabs: TabsController()..openPlugin(plugin: plugin!), ); if (direction == Direction.front) { - node = node.copyWith( - children: insertAndEncode(node.children, i + 1, newNode), - ); + if (i == node.children.length) { + node.children.add(newNode); + } else { + node.children.insert(i + 1, newNode); + } } else { - node = node.copyWith( - children: insertAndEncode(node.children, i, newNode), - ); + node.children.insert(i, newNode); } final ret = node.copyWith( paneId: nanoid(), - tabs: TabsController(encoding: node.tabs.encoding), children: node.children .map( (e) => e.copyWith( tabs: TabsController( - encoding: e.tabs.encoding, pageManagers: e.tabs.pageManagers, ), ), @@ -144,6 +124,7 @@ class PanesService { PaneNode closePaneHandler({ required PaneNode node, required String targetPaneId, + required bool move, }) { if (node.paneId == targetPaneId) { return node; @@ -151,16 +132,16 @@ class PanesService { for (var i = 0; i < node.children.length; i++) { final element = node.children[i]; if (element.paneId == targetPaneId) { - element.tabs.closeAllViews(); - node = node.copyWith(children: removeAndEncode(node.children, i)); + if (!move) { + element.tabs.closeAllViews(); + } + node.children.remove(element); if (node.children.length == 1) { final ret = node.children.first.copyWith( paneId: nanoid(), parent: node.parent, - encoding: node.parent == null ? [] : [...node.parent!.encoding, 0], tabs: TabsController( pageManagers: node.children.first.tabs.pageManagers, - encoding: "[]", ), ); return ret; @@ -171,7 +152,6 @@ class PanesService { .map( (e) => e.copyWith( tabs: TabsController( - encoding: e.tabs.encoding, pageManagers: e.tabs.pageManagers, ), ), @@ -188,44 +168,10 @@ class PanesService { return closePaneHandler( node: childNode, targetPaneId: targetPaneId, + move: move, ); }).toList(); return node.copyWith(children: newChildren); } } - -List insertAndEncode(List list, int index, PaneNode node) { - if (index <= 0) index = 0; - if (index >= list.length) index = list.length - 1; - - List ret = [...list, node]; - for (int i = ret.length - 1; i > index; i--) { - ret[i] = ret[i - 1].copyWith( - encoding: node.parent == null ? [i] : [...node.parent!.encoding, i], - ); - } - ret[index] = node.copyWith( - encoding: node.parent == null ? [index] : [...node.parent!.encoding, index], - ); - return ret; -} - -List removeAndEncode(List list, int index) { - List ret = []; - for (int i = 0; i < list.length; i++) { - if (i < index) { - ret.add(list[i]); - } - if (i > index) { - ret.add( - list[i].copyWith( - encoding: list[i].parent == null - ? [i - 1] - : [...list[i].parent!.encoding, i - 1], - ), - ); - } - } - return ret; -} diff --git a/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_controller.dart b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_controller.dart index 6b8f52f5c7b3..dd0c2bd54be1 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_controller.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_controller.dart @@ -17,41 +17,58 @@ class TabsController extends ChangeNotifier { int get pages => pageManagers.length; PageManager get currentPageManager => pageManagers[currentIndex]; final MenuSharedState menuSharedState; - final String encoding; - TabsController({ int? currentIndex, List? pageManagers, - required this.encoding, - }) : pageManagers = pageManagers ?? [PageManager("${encoding}0")], + }) : pageManagers = pageManagers ?? [PageManager()], menuSharedState = getIt(), currentIndex = currentIndex ?? 0; + bool _dispose = false; + + @override + void notifyListeners() { + if (!_dispose) { + super.notifyListeners(); + } + } + + @override + void dispose() { + if (!_dispose) { + super.dispose(); + } + _dispose = true; + } + void closeAllViews() { final pageManagersCopy = List.from(pageManagers); for (final page in pageManagersCopy) { closeView(page.plugin.id, closePaneSubRoutine: true); } pageManagers = pageManagersCopy; - notifyListeners(); } void openView(Plugin plugin) { final selectExistingPlugin = _selectPluginIfOpen(plugin.id); - final length = pageManagers.length; if (!selectExistingPlugin) { // check if view is already open final openPlugins = menuSharedState.openPlugins; + if (openPlugins.containsKey(plugin.id)) { - pageManagers.add(PageManager("$encoding$length") + pageManagers.add(PageManager() ..setPlugin(plugin) ..setReadOnlyStatus(true)); } else { - pageManagers.add(PageManager("$menuSharedState$length") + pageManagers.add(PageManager() ..setPlugin(plugin) ..setReadOnlyStatus(false)); } - openPlugins[plugin.id] = [...?openPlugins[plugin.id], "$encoding$length"]; + openPlugins.update( + plugin.id, + (value) => value + 1, + ifAbsent: () => 1, + ); menuSharedState.openPlugins = openPlugins; } currentIndex = pageManagers.length - 1; @@ -63,7 +80,8 @@ class TabsController extends ChangeNotifier { void closeView( String pluginId, { bool closePaneSubRoutine = false, - }) async { + bool move = false, + }) { // Avoid closing the only open tab unless it is part of subroutine to close pane if (pageManagers.length == 1 && (!closePaneSubRoutine)) { return; @@ -73,23 +91,21 @@ class TabsController extends ChangeNotifier { return pm.plugin.id == pluginId; }); + if (!pm.readOnly && openPlugins.containsKey(pluginId) && !move) { + _updateWriteStatus( + pluginId, + getIt().state.root, + )?.setReadOnlyStatus(false); + } + openPlugins.update( pluginId, - (value) => value..remove(pm.notifier.position), + (value) => value - 1, ); - if (openPlugins[pluginId]?.isEmpty ?? false) { + if (openPlugins[pluginId] == 0) { openPlugins.remove(pluginId); } - - if (!pm.readOnly && openPlugins.containsKey(pluginId)) { - final newPath = openPlugins[pluginId]!.first; - _getPluginOnPath( - newPath, - getIt().state.root, - 1, - ).setReadOnlyStatus(false); - } menuSharedState.openPlugins = openPlugins; pageManagers.removeWhere((pm) => pm.plugin.id == pluginId); @@ -129,32 +145,75 @@ class TabsController extends ChangeNotifier { /// If the plugin is already open in a tab, then that tab /// will become selected. /// - void openPlugin({required Plugin plugin, bool newPane = false}) async { + void openPlugin({ + required Plugin plugin, + bool newPane = false, + int? index, + }) { final selectExistingPlugin = _selectPluginIfOpen(plugin.id); if (!selectExistingPlugin) { final openPlugins = menuSharedState.openPlugins; //remove current plugin path from state store + if (openPlugins.containsKey(plugin.id)) { - openPlugins.update( - plugin.id, - (value) => - value..remove(pageManagers[currentIndex].notifier.position), - ); - } - if (openPlugins.containsKey(plugin.id)) { - pageManagers[currentIndex] - ..setPlugin(plugin) - ..setReadOnlyStatus(true); + if (index != null) { + if (index >= pageManagers.length) { + pageManagers.add(PageManager() + ..setPlugin(plugin) + ..setReadOnlyStatus(true)); + } else { + pageManagers.insert( + index, + PageManager() + ..setPlugin(plugin) + ..setReadOnlyStatus(true)); + } + } else { + if (openPlugins.containsKey(pageManagers[currentIndex].plugin.id)) { + openPlugins.update( + pageManagers[currentIndex].plugin.id, (value) => value - 1); + + if (openPlugins[pageManagers[currentIndex].plugin.id] == 0) { + openPlugins.remove(pageManagers[currentIndex].plugin.id); + } + } + pageManagers[currentIndex] + ..setPlugin(plugin) + ..setReadOnlyStatus(true); + } } else { - pageManagers[currentIndex] - ..setPlugin(plugin) - ..setReadOnlyStatus(false); + if (index != null) { + if (index >= pageManagers.length) { + pageManagers.add(PageManager() + ..setPlugin(plugin) + ..setReadOnlyStatus(false)); + } else { + pageManagers.insert( + index, + PageManager() + ..setPlugin(plugin) + ..setReadOnlyStatus(false)); + } + } else { + if (openPlugins.containsKey(pageManagers[currentIndex].plugin.id)) { + openPlugins.update( + pageManagers[currentIndex].plugin.id, (value) => value - 1); + + if (openPlugins[pageManagers[currentIndex].plugin.id] == 0) { + openPlugins.remove(pageManagers[currentIndex].plugin.id); + } + } + pageManagers[currentIndex] + ..setPlugin(plugin) + ..setReadOnlyStatus(false); + } } - openPlugins[plugin.id] = [ - ...?openPlugins[plugin.id], - "$encoding$currentIndex", - ]; + openPlugins.update( + plugin.id, + (value) => value + 1, + ifAbsent: () => 1, + ); menuSharedState.openPlugins = openPlugins; } setLatestOpenView(); @@ -173,7 +232,7 @@ class TabsController extends ChangeNotifier { required PageManager from, required PageManager to, required TabDraggableHoverPosition position, - }) async { + }) { final selectExistingPlugin = _selectPluginIfOpen(from.plugin.id); if (!selectExistingPlugin) { @@ -183,22 +242,14 @@ class TabsController extends ChangeNotifier { case TabDraggableHoverPosition.left: { final index = pageManagers.indexOf(to); - final newPm = PageManager("$encoding$index") - ..setPlugin(from.plugin); - pageManagers.insert(index, newPm); + openPlugin(plugin: from.plugin, index: index); currentIndex = index; break; } case TabDraggableHoverPosition.right: { final index = pageManagers.indexOf(to); - final newPm = PageManager("$encoding${index + 1}") - ..setPlugin(from.plugin); - if (index + 1 == pageManagers.length) { - pageManagers.add(newPm); - } else { - pageManagers.insert(index + 1, newPm); - } + openPlugin(plugin: from.plugin, index: index); currentIndex = index + 1; break; } @@ -219,15 +270,19 @@ class TabsController extends ChangeNotifier { } } - PageManager _getPluginOnPath(String encoding, PaneNode node, int index) { - if (index == encoding.length - 2) { - return node.tabs.pageManagers[int.parse(encoding[encoding.length - 1])]; + PageManager? _updateWriteStatus(String pluginId, PaneNode node) { + for (final page in node.tabs.pageManagers) { + Log.warn(page.plugin.id); + if (page.plugin.id == pluginId && page.readOnly) { + return page; + } } - - return _getPluginOnPath( - encoding, - node.children[int.parse(encoding[index])], - index + 1, - ); + for (int i = 0; i < node.children.length; i++) { + final result = _updateWriteStatus(pluginId, node.children[i]); + if (result != null) { + return result; + } + } + return null; } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_service.dart b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_service.dart new file mode 100644 index 000000000000..d9044ae2ca0b --- /dev/null +++ b/frontend/appflowy_flutter/lib/workspace/application/tabs/tabs_service.dart @@ -0,0 +1,3 @@ +class TabService { + //TODO(squidrye): modularize reusable parts from tab controller +} diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart index 8b0c94f0c87e..b897c408497c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart @@ -21,6 +21,7 @@ import 'package:provider/provider.dart'; import 'package:time/time.dart'; import 'home_layout.dart'; +import 'menu/menu_shared_state.dart'; typedef NavigationCallback = void Function(String id); @@ -61,7 +62,7 @@ class HomeStack extends StatelessWidget { //TODO(squidrye): Remove before merge void _printTree(PaneNode node, [String prefix = '']) { - print('$prefix${node.encoding}'); + print('$prefix${node} ${getIt().openPlugins}'); for (var child in node.children) { _printTree(child, '$prefix └─ '); } @@ -88,19 +89,6 @@ class _PageStackState extends State @override Widget build(BuildContext context) { super.build(context); - if (widget.pageManager.readOnly) { - return Stack( - children: [ - AbsorbPointer( - child: Opacity( - opacity: 0.5, - child: _buildWidgetStack(context), - ), - ), - Positioned(child: _buildReadOnlyBanner()) - ], - ); - } return _buildWidgetStack(context); } @@ -112,29 +100,7 @@ class _PageStackState extends State onDeleted: (view, index) { widget.delegate.didDeleteStackWidget(view, index); }, - ), - ), - ); - } - - Widget _buildReadOnlyBanner() { - final colorScheme = Theme.of(context).colorScheme; - return ConstrainedBox( - constraints: const BoxConstraints(minHeight: 20), - child: Container( - width: double.infinity, - color: colorScheme.primary, - child: FittedBox( - alignment: Alignment.center, - fit: BoxFit.scaleDown, - child: Row( - children: [ - FlowyText.medium( - LocaleKeys.readOnlyViewText.tr(), - fontSize: 14, - ), - ], - ), + context: context, ), ), ); @@ -203,17 +169,15 @@ abstract mixin class NavigationItem { class PageNotifier extends ChangeNotifier { Plugin _plugin; bool _readOnly; - String position; Widget get titleWidget => _plugin.widgetBuilder.leftBarItem; Widget tabBarWidget(String pluginId) => _plugin.widgetBuilder.tabBarItem(pluginId); - PageNotifier({Plugin? plugin, bool? readOnly, required String encoding}) + PageNotifier({Plugin? plugin, bool? readOnly}) : _plugin = plugin ?? makePlugin(pluginType: PluginType.blank), - _readOnly = readOnly ?? false, - position = encoding; + _readOnly = readOnly ?? false; /// This is the only place where the plugin is set. /// No need compare the old plugin with the new plugin. Just set it. @@ -243,7 +207,7 @@ class PageManager { PageNotifier get notifier => _notifier; - PageManager(String encoding) : _notifier = PageNotifier(encoding: encoding); + PageManager() : _notifier = PageNotifier(); Widget title() { return _notifier.plugin.widgetBuilder.leftBarItem; @@ -281,32 +245,75 @@ class PageManager { ); } - Widget stackWidget({required Function(ViewPB, int?) onDeleted}) { + Widget _buildWidgetStack({required Function(ViewPB, int?) onDeleted}) { + return FadingIndexedStack( + index: getIt().indexOf(notifier.plugin.pluginType), + children: getIt().supportPluginTypes.map( + (pluginType) { + if (pluginType == notifier.plugin.pluginType) { + final builder = notifier.plugin.widgetBuilder; + final pluginWidget = builder.buildWidget( + context: PluginContext(onDeleted: onDeleted), + shrinkWrap: false, + ); + + return Padding( + padding: builder.contentPadding, + child: pluginWidget, + ); + } + + return const BlankPage(); + }, + ).toList(), + ); + } + + Widget _buildReadOnlyBanner(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + return ConstrainedBox( + constraints: const BoxConstraints(minHeight: 20), + child: Container( + width: double.infinity, + color: colorScheme.primary, + child: FittedBox( + alignment: Alignment.center, + fit: BoxFit.scaleDown, + child: Row( + children: [ + FlowyText.medium( + LocaleKeys.readOnlyViewText.tr(), + fontSize: 14, + ), + ], + ), + ), + ), + ); + } + + Widget stackWidget({ + required Function(ViewPB, int?) onDeleted, + required BuildContext context, + }) { return MultiProvider( providers: [ChangeNotifierProvider.value(value: _notifier)], child: Consumer( builder: (_, PageNotifier notifier, __) { - return FadingIndexedStack( - index: getIt().indexOf(notifier.plugin.pluginType), - children: getIt().supportPluginTypes.map( - (pluginType) { - if (pluginType == notifier.plugin.pluginType) { - final builder = notifier.plugin.widgetBuilder; - final pluginWidget = builder.buildWidget( - context: PluginContext(onDeleted: onDeleted), - shrinkWrap: false, - ); - - return Padding( - padding: builder.contentPadding, - child: pluginWidget, - ); - } - - return const BlankPage(); - }, - ).toList(), - ); + if (notifier.readOnly) { + return Stack( + children: [ + AbsorbPointer( + child: Opacity( + opacity: 0.5, + child: _buildWidgetStack(onDeleted: onDeleted), + ), + ), + Positioned(child: _buildReadOnlyBanner(context)) + ], + ); + } + return _buildWidgetStack(onDeleted: onDeleted); }, ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart index 2e327f48f855..86c8235c5242 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_shared_state.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; class MenuSharedState { final ValueNotifier _latestOpenView = ValueNotifier(null); - final ValueNotifier>> _openPlugins = - ValueNotifier>>({}); + final ValueNotifier> _openPlugins = + ValueNotifier>({}); MenuSharedState({ViewPB? view}) { _latestOpenView.value = view; @@ -32,24 +32,13 @@ class MenuSharedState { _latestOpenView.removeListener(listener); } - VoidCallback addPluginListListener( - void Function(Map>) callback, - ) { - listener() { - callback(_openPlugins.value); - } - - _openPlugins.addListener(listener); - return listener; - } - void removePluginListListener(VoidCallback listener) { _openPlugins.removeListener(listener); } - Map> get openPlugins => _openPlugins.value; + Map get openPlugins => _openPlugins.value; - set openPlugins(Map> value) { + set openPlugins(Map value) { _openPlugins.value = value; } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/tabs/draggable_tab_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/tabs/draggable_tab_item.dart index 05103e1856d6..70acd4c26205 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/tabs/draggable_tab_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/tabs/draggable_tab_item.dart @@ -113,9 +113,9 @@ class _DraggabletabItemState extends State { final fromTab = from.draggable as TabNode; final plugin = (from.draggable as TabNode).pageManager.plugin; if (fromTab.tabs != to.tabs) { - fromTab.tabs.closeView(plugin.id); + fromTab.tabs.closeView(plugin.id, move: true); } else { - to.tabs.closeView(plugin.id); + to.tabs.closeView(plugin.id, move: true); } to.tabs.move( from: fromTab.pageManager,