ソースを参照

fix: favorite selection and context menu doesn't work (#3114)

Mihir 1 年間 前
コミット
890f7573f3

+ 47 - 0
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();
+      },
+    );
   });
 }

+ 1 - 0
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) {

+ 1 - 0
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<TabsBloc>().add(
                         TabsEvent.openPlugin(

+ 27 - 3
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<ViewBloc, ViewState>(
         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<SingleInnerViewItem> createState() => _SingleInnerViewItemState();
@@ -209,6 +230,10 @@ class SingleInnerViewItem extends StatefulWidget {
 class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
   @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<SingleInnerViewItem> {
       buildWhenOnHover: () => !widget.showActions,
       builder: (_, onHover) => _buildViewItem(onHover),
       isSelected: () =>
-          widget.isDraggable &&
-          (widget.showActions ||
-              getIt<MenuSharedState>().latestOpenView?.id == widget.view.id),
+          widget.showActions ||
+          getIt<MenuSharedState>().latestOpenView?.id == widget.view.id,
     );
   }