diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space.dart index f13afb74acc3..2571c1490bb5 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space.dart @@ -15,6 +15,7 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_ import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; @@ -75,6 +76,8 @@ class _Space extends StatefulWidget { class _SpaceState extends State<_Space> { final ValueNotifier isHovered = ValueNotifier(false); + final PropertyValueNotifier isExpandedNotifier = + PropertyValueNotifier(false); @override Widget build(BuildContext context) { @@ -93,12 +96,14 @@ class _SpaceState extends State<_Space> { space: currentSpace, onAdded: () => _showCreatePagePopup(context, currentSpace), onCreateNewSpace: () => _showCreateSpaceDialog(context), + onCollapseAllPages: () => isExpandedNotifier.value = true, ), MouseRegion( onEnter: (_) => isHovered.value = true, onExit: (_) => isHovered.value = false, child: _Pages( key: ValueKey(currentSpace.id), + isExpandedNotifier: isExpandedNotifier, space: currentSpace, isHovered: isHovered, ), @@ -156,10 +161,12 @@ class _Pages extends StatelessWidget { super.key, required this.space, required this.isHovered, + required this.isExpandedNotifier, }); final ViewPB space; final ValueNotifier isHovered; + final PropertyValueNotifier isExpandedNotifier; @override Widget build(BuildContext context) { @@ -183,6 +190,7 @@ class _Pages extends StatelessWidget { leftPadding: HomeSpaceViewSizes.leftPadding, isFeedback: false, isHovered: isHovered, + isExpandedNotifier: isExpandedNotifier, onSelected: (viewContext, view) { if (HardwareKeyboard.instance.isControlPressed) { context.read().openTab(view); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart index 80fb84e5af36..5ccf8bb916df 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart @@ -22,12 +22,14 @@ class SidebarSpaceHeader extends StatefulWidget { required this.space, required this.onAdded, required this.onCreateNewSpace, + required this.onCollapseAllPages, required this.isExpanded, }); final ViewPB space; final VoidCallback onAdded; final VoidCallback onCreateNewSpace; + final VoidCallback onCollapseAllPages; final bool isExpanded; @override @@ -156,6 +158,7 @@ class _SidebarSpaceHeaderState extends State { widget.onCreateNewSpace(); break; case SpaceMoreActionType.collapseAllPages: + widget.onCollapseAllPages(); break; case SpaceMoreActionType.delete: _showDeleteSpaceDialog(context); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart index 94e4cfbb69b1..00b0bc3307eb 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart @@ -71,6 +71,7 @@ class SpaceMorePopup extends StatelessWidget { SpaceMoreActionType.manage, SpaceMoreActionType.divider, SpaceMoreActionType.addNewSpace, + SpaceMoreActionType.collapseAllPages, SpaceMoreActionType.divider, SpaceMoreActionType.delete, ]; @@ -155,7 +156,7 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell { height: 34, padding: const EdgeInsets.symmetric(vertical: 2.0), child: Opacity( - opacity: disable ? 0.5 : 1.0, + opacity: disable ? 0.3 : 1.0, child: FlowyButton( disable: disable, margin: const EdgeInsets.symmetric(horizontal: 6), 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 6b74be1e4f63..b94f306422aa 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 @@ -19,6 +19,7 @@ import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; @@ -58,6 +59,7 @@ class ViewItem extends StatelessWidget { this.leftIconBuilder, this.rightIconsBuilder, this.shouldLoadChildViews = true, + this.isExpandedNotifier, }); final ViewPB view; @@ -109,6 +111,7 @@ class ViewItem extends StatelessWidget { final ViewItemRightIconsBuilder? rightIconsBuilder; final bool shouldLoadChildViews; + final PropertyValueNotifier? isExpandedNotifier; @override Widget build(BuildContext context) { @@ -144,6 +147,7 @@ class ViewItem extends StatelessWidget { shouldRenderChildren: shouldRenderChildren, leftIconBuilder: leftIconBuilder, rightIconsBuilder: rightIconsBuilder, + isExpandedNotifier: isExpandedNotifier, ); }, ), @@ -153,7 +157,7 @@ class ViewItem extends StatelessWidget { bool _isDragging = false; -class InnerViewItem extends StatelessWidget { +class InnerViewItem extends StatefulWidget { const InnerViewItem({ super.key, required this.view, @@ -176,6 +180,7 @@ class InnerViewItem extends StatelessWidget { this.shouldRenderChildren = true, required this.leftIconBuilder, required this.rightIconsBuilder, + this.isExpandedNotifier, }); final ViewPB view; @@ -204,46 +209,67 @@ class InnerViewItem extends StatelessWidget { final ViewItemLeftIconBuilder? leftIconBuilder; final ViewItemRightIconsBuilder? rightIconsBuilder; + final PropertyValueNotifier? isExpandedNotifier; + + @override + State createState() => _InnerViewItemState(); +} + +class _InnerViewItemState extends State { + @override + void initState() { + super.initState(); + widget.isExpandedNotifier?.addListener(_collapseAllPages); + } + + @override + void dispose() { + widget.isExpandedNotifier?.removeListener(_collapseAllPages); + super.dispose(); + } + @override Widget build(BuildContext context) { Widget child = SingleInnerViewItem( - view: view, - parentView: parentView, - level: level, - showActions: showActions, - spaceType: spaceType, - onSelected: onSelected, - onTertiarySelected: onTertiarySelected, - isExpanded: isExpanded, - isDraggable: isDraggable, - leftPadding: leftPadding, - isFeedback: isFeedback, - height: height, - isPlaceholder: isPlaceholder, - isHovered: isHovered, - leftIconBuilder: leftIconBuilder, - rightIconsBuilder: rightIconsBuilder, + view: widget.view, + parentView: widget.parentView, + level: widget.level, + showActions: widget.showActions, + spaceType: widget.spaceType, + onSelected: widget.onSelected, + onTertiarySelected: widget.onTertiarySelected, + isExpanded: widget.isExpanded, + isDraggable: widget.isDraggable, + leftPadding: widget.leftPadding, + isFeedback: widget.isFeedback, + height: widget.height, + isPlaceholder: widget.isPlaceholder, + isHovered: widget.isHovered, + leftIconBuilder: widget.leftIconBuilder, + rightIconsBuilder: widget.rightIconsBuilder, ); // if the view is expanded and has child views, render its child views - if (isExpanded && shouldRenderChildren && childViews.isNotEmpty) { - final children = childViews.map((childView) { + if (widget.isExpanded && + widget.shouldRenderChildren && + widget.childViews.isNotEmpty) { + final children = widget.childViews.map((childView) { return ViewItem( - key: ValueKey('${spaceType.name} ${childView.id}'), - parentView: view, - spaceType: spaceType, - isFirstChild: childView.id == childViews.first.id, + key: ValueKey('${widget.spaceType.name} ${childView.id}'), + parentView: widget.view, + spaceType: widget.spaceType, + isFirstChild: childView.id == widget.childViews.first.id, view: childView, - level: level + 1, - onSelected: onSelected, - onTertiarySelected: onTertiarySelected, - isDraggable: isDraggable, - leftPadding: leftPadding, - isFeedback: isFeedback, - isPlaceholder: isPlaceholder, - isHovered: isHovered, - leftIconBuilder: leftIconBuilder, - rightIconsBuilder: rightIconsBuilder, + level: widget.level + 1, + onSelected: widget.onSelected, + onTertiarySelected: widget.onTertiarySelected, + isDraggable: widget.isDraggable, + leftPadding: widget.leftPadding, + isFeedback: widget.isFeedback, + isPlaceholder: widget.isPlaceholder, + isHovered: widget.isHovered, + leftIconBuilder: widget.leftIconBuilder, + rightIconsBuilder: widget.rightIconsBuilder, ); }).toList(); @@ -257,15 +283,15 @@ class InnerViewItem extends StatelessWidget { } // wrap the child with DraggableItem if isDraggable is true - if ((isDraggable || isPlaceholder) && - !isReferencedDatabaseView(view, parentView)) { + if ((widget.isDraggable || widget.isPlaceholder) && + !isReferencedDatabaseView(widget.view, widget.parentView)) { child = DraggableViewItem( - isFirstChild: isFirstChild, - view: view, + isFirstChild: widget.isFirstChild, + view: widget.view, onDragging: (isDragging) { _isDragging = isDragging; }, - onMove: isPlaceholder + onMove: widget.isPlaceholder ? (from, to) => _moveViewCrossSection(context, from, to) : null, feedback: (context) { @@ -278,17 +304,17 @@ class InnerViewItem extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), child: ViewItem( - view: view, - parentView: parentView, - spaceType: spaceType, - level: level, - onSelected: onSelected, - onTertiarySelected: onTertiarySelected, + view: widget.view, + parentView: widget.parentView, + spaceType: widget.spaceType, + level: widget.level, + onSelected: widget.onSelected, + onTertiarySelected: widget.onTertiarySelected, isDraggable: false, - leftPadding: leftPadding, + leftPadding: widget.leftPadding, isFeedback: true, - leftIconBuilder: leftIconBuilder, - rightIconsBuilder: rightIconsBuilder, + leftIconBuilder: widget.leftIconBuilder, + rightIconsBuilder: widget.rightIconsBuilder, ), ); }, @@ -305,18 +331,24 @@ class InnerViewItem extends StatelessWidget { return child; } + void _collapseAllPages() { + if (widget.isExpandedNotifier?.value == true) { + context.read().add(const ViewEvent.collapseAllPages()); + } + } + void _moveViewCrossSection( BuildContext context, ViewPB from, ViewPB to, ) { - if (isReferencedDatabaseView(view, parentView)) { + if (isReferencedDatabaseView(widget.view, widget.parentView)) { return; } - final fromSection = spaceType == FolderSpaceType.public + final fromSection = widget.spaceType == FolderSpaceType.public ? ViewSectionPB.Private : ViewSectionPB.Public; - final toSection = spaceType == FolderSpaceType.public + final toSection = widget.spaceType == FolderSpaceType.public ? ViewSectionPB.Public : ViewSectionPB.Private; context.read().add( @@ -331,7 +363,7 @@ class InnerViewItem extends StatelessWidget { context.read().add( ViewEvent.updateViewVisibility( from, - spaceType == FolderSpaceType.public, + widget.spaceType == FolderSpaceType.public, ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart index b8cafe87a687..b1bef7cceb61 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart @@ -1,10 +1,9 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; class SettingsMenuElement extends StatelessWidget { const SettingsMenuElement({ @@ -28,7 +27,7 @@ class SettingsMenuElement extends StatelessWidget { isSelected: () => page == selectedPage, resetHoverOnRebuild: false, style: HoverStyle( - hoverColor: AFThemeExtension.of(context).greySelect, + hoverColor: AFThemeExtension.of(context).greyHover, borderRadius: BorderRadius.circular(4), ), builder: (_, isHovering) => ListTile( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart index e4bf942c6af0..f9f46cfba937 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart @@ -103,7 +103,7 @@ class _MoreViewActionsState extends State { FlowySvgs.three_dots_s, size: const Size.square(18), color: isHovering - ? Theme.of(context).colorScheme.onSecondary + ? Theme.of(context).colorScheme.onSurface : Theme.of(context).iconTheme.color, ), ), diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart index 81142383c1e9..ab83df54969f 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart @@ -117,10 +117,10 @@ class DefaultColorScheme extends FlowyColorScheme { hint: const Color(0xFF59647a), primary: _darkMain2, onPrimary: _darkShader1, - hoverBG1: _darkMain1, + hoverBG1: const Color(0x1AFFFFFF), hoverBG2: _darkMain1, hoverBG3: _darkShader3, - hoverFG: _darkShader1, + hoverFG: const Color(0xE5FFFFFF), questionBubbleBG: _darkShader3, progressBarBGColor: _darkShader3, toolbarColor: _darkInput,