From 890f7573f3b38ffaad4ec5e2add1c310cdd1af99 Mon Sep 17 00:00:00 2001 From: Mihir <84044317+squidrye@users.noreply.github.com> Date: Sun, 6 Aug 2023 10:01:47 +0530 Subject: [PATCH] fix: favorite selection and context menu doesn't work (#3114) --- .../sidebar/sidebar_favorites_test.dart | 47 +++++++++++++++++++ .../menu/sidebar/folder/favorite_folder.dart | 1 + .../menu/sidebar/folder/personal_folder.dart | 1 + .../home/menu/view/view_item.dart | 30 ++++++++++-- 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/frontend/appflowy_flutter/integration_test/sidebar/sidebar_favorites_test.dart b/frontend/appflowy_flutter/integration_test/sidebar/sidebar_favorites_test.dart index fd531d0e4f..963cd7e455 100644 --- a/frontend/appflowy_flutter/integration_test/sidebar/sidebar_favorites_test.dart +++ b/frontend/appflowy_flutter/integration_test/sidebar/sidebar_favorites_test.dart @@ -2,6 +2,8 @@ import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; +import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -171,5 +173,50 @@ void main() { ); }, ); + + testWidgets( + 'view selection is synced between favorites and personal folder', + (tester) async { + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + await tester.createNewPageWithName(); + await tester.favoriteViewByName(gettingStated); + expect( + find.byWidgetPredicate( + (widget) => + widget is FlowyHover && + widget.isSelected != null && + widget.isSelected!(), + ), + findsNWidgets(2), + ); + }, + ); + + testWidgets( + 'context menu opens up for favorites', + (tester) async { + await tester.initializeAppFlowy(); + await tester.tapGoButton(); + + await tester.createNewPageWithName(); + await tester.favoriteViewByName(gettingStated); + await tester.hoverOnPageName( + gettingStated, + layout: ViewLayoutPB.Document, + useLast: false, + onHover: () async { + await tester.tapPageOptionButton(); + await tester.pumpAndSettle(); + expect( + find.byType(PopoverContainer), + findsOneWidget, + ); + }, + ); + await tester.pumpAndSettle(); + }, + ); }); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart index 32ffefbe47..d854022f48 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/favorite_folder.dart @@ -50,6 +50,7 @@ class FavoriteFolder extends StatelessWidget { categoryType: FolderCategoryType.favorite, isDraggable: false, isFirstChild: view.id == views.first.id, + isFeedback: false, view: view, level: 0, onSelected: (view) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart index 798ebe7078..86e060b7dd 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/personal_folder.dart @@ -50,6 +50,7 @@ class PersonalFolder extends StatelessWidget { view: view, level: 0, leftPadding: 16, + isFeedback: false, onSelected: (view) { getIt().add( TabsEvent.openPlugin( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 7266ac6b55..49b577459e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -30,6 +30,7 @@ class ViewItem extends StatelessWidget { required this.onSelected, this.isFirstChild = false, this.isDraggable = true, + required this.isFeedback, }); final ViewPB view; @@ -54,12 +55,19 @@ class ViewItem extends StatelessWidget { // it should be false when it's rendered as feedback widget inside DraggableItem final bool isDraggable; + // identify if the view item is rendered as feedback widget inside DraggableItem + final bool isFeedback; + @override Widget build(BuildContext context) { return BlocProvider( create: (_) => ViewBloc(view: view)..add(const ViewEvent.initial()), child: BlocBuilder( builder: (context, state) { + // don't remove this code. it's related to the backend service. + view.childViews + ..clear() + ..addAll(state.childViews); return InnerViewItem( view: state.view, parentView: parentView, @@ -72,6 +80,7 @@ class ViewItem extends StatelessWidget { onSelected: onSelected, isFirstChild: isFirstChild, isDraggable: isDraggable, + isFeedback: isFeedback, ); }, ), @@ -93,6 +102,7 @@ class InnerViewItem extends StatelessWidget { required this.showActions, required this.onSelected, this.isFirstChild = false, + required this.isFeedback, }); final ViewPB view; @@ -103,6 +113,8 @@ class InnerViewItem extends StatelessWidget { final bool isDraggable; final bool isExpanded; final bool isFirstChild; + // identify if the view item is rendered as feedback widget inside DraggableItem + final bool isFeedback; final int level; final double leftPadding; @@ -117,10 +129,12 @@ class InnerViewItem extends StatelessWidget { parentView: parentView, level: level, showActions: showActions, + categoryType: categoryType, onSelected: onSelected, isExpanded: isExpanded, isDraggable: isDraggable, leftPadding: leftPadding, + isFeedback: isFeedback, ); // if the view is expanded and has child views, render its child views @@ -136,6 +150,7 @@ class InnerViewItem extends StatelessWidget { onSelected: onSelected, isDraggable: isDraggable, leftPadding: leftPadding, + isFeedback: isFeedback, ); }).toList(); @@ -163,6 +178,7 @@ class InnerViewItem extends StatelessWidget { onSelected: onSelected, isDraggable: false, leftPadding: leftPadding, + isFeedback: true, ); }, ); @@ -187,13 +203,17 @@ class SingleInnerViewItem extends StatefulWidget { required this.level, required this.leftPadding, this.isDraggable = true, + required this.categoryType, required this.showActions, required this.onSelected, + required this.isFeedback, }); final ViewPB view; final ViewPB? parentView; final bool isExpanded; + // identify if the view item is rendered as feedback widget inside DraggableItem + final bool isFeedback; final int level; final double leftPadding; @@ -201,6 +221,7 @@ class SingleInnerViewItem extends StatefulWidget { final bool isDraggable; final bool showActions; final void Function(ViewPB) onSelected; + final FolderCategoryType categoryType; @override State createState() => _SingleInnerViewItemState(); @@ -209,6 +230,10 @@ class SingleInnerViewItem extends StatefulWidget { class _SingleInnerViewItemState extends State { @override Widget build(BuildContext context) { + if (widget.isFeedback) { + return _buildViewItem(false); + } + return FlowyHover( style: HoverStyle( hoverColor: Theme.of(context).colorScheme.secondary, @@ -216,9 +241,8 @@ class _SingleInnerViewItemState extends State { buildWhenOnHover: () => !widget.showActions, builder: (_, onHover) => _buildViewItem(onHover), isSelected: () => - widget.isDraggable && - (widget.showActions || - getIt().latestOpenView?.id == widget.view.id), + widget.showActions || + getIt().latestOpenView?.id == widget.view.id, ); }