feat: add a pinned icon after page name

This commit is contained in:
Lucas.Xu 2024-06-17 18:01:05 +08:00
parent 1fd34bc58a
commit a668e0bd09
3 changed files with 95 additions and 42 deletions

View File

@ -2,6 +2,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_menu_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_more_actions.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart';
@ -36,9 +37,6 @@ class FavoriteMenu extends StatelessWidget {
FavoriteMenuBloc()..add(const FavoriteMenuEvent.initial()),
child: BlocBuilder<FavoriteMenuBloc, FavoriteMenuState>(
builder: (context, state) {
if (state.views.isEmpty) {
return const SizedBox.shrink();
}
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -52,7 +50,10 @@ class FavoriteMenu extends StatelessWidget {
},
),
const VSpace(12),
_buildViews(context, state),
_FavoriteGroups(
minWidth: minWidth,
state: state,
),
],
);
},
@ -60,8 +61,67 @@ class FavoriteMenu extends StatelessWidget {
),
);
}
}
Widget _buildViews(BuildContext context, FavoriteMenuState state) {
class _FavoriteGroupedViews extends StatelessWidget {
const _FavoriteGroupedViews({
required this.views,
});
final List<ViewPB> views;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: views
.map(
(e) => ViewItem(
key: ValueKey(e.id),
view: e,
spaceType: FolderSpaceType.favorite,
level: 0,
onSelected: (_, view) {
context.read<TabsBloc>().openPlugin(view);
PopoverContainer.maybeOf(context)?.close();
},
isFeedback: false,
isDraggable: false,
shouldRenderChildren: false,
extendBuilder: (view) => view.isPinned
? [
const HSpace(4.0),
const FlowySvg(
FlowySvgs.favorite_pin_s,
blendMode: null,
),
]
: [],
leftIconBuilder: (_, __) => const HSpace(4.0),
rightIconsBuilder: (_, view) => [
FavoriteMoreActions(view: view),
const HSpace(6.0),
FavoritePinAction(view: view),
const HSpace(4.0),
],
),
)
.toList(),
);
}
}
class _FavoriteGroups extends StatelessWidget {
const _FavoriteGroups({
required this.minWidth,
required this.state,
});
final double minWidth;
final FavoriteMenuState state;
@override
Widget build(BuildContext context) {
final today = _buildGroups(
context,
state.todayViews,
@ -131,41 +191,11 @@ class FavoriteMenu extends StatelessWidget {
),
),
const VSpace(2),
_buildGroupedViews(context, views),
_FavoriteGroupedViews(views: views),
const VSpace(8),
],
];
}
Widget _buildGroupedViews(BuildContext context, List<ViewPB> views) {
return Column(
mainAxisSize: MainAxisSize.min,
children: views
.map(
(e) => ViewItem(
key: ValueKey(e.id),
view: e,
spaceType: FolderSpaceType.favorite,
level: 0,
onSelected: (_, view) {
context.read<TabsBloc>().openPlugin(view);
PopoverContainer.maybeOf(context)?.close();
},
isFeedback: false,
isDraggable: false,
shouldRenderChildren: false,
leftIconBuilder: (_, __) => const HSpace(4.0),
rightIconsBuilder: (_, view) => [
FavoriteMoreActions(view: view),
const HSpace(6.0),
FavoritePinAction(view: view),
const HSpace(4.0),
],
),
)
.toList(),
);
}
}
class _FavoriteSearchField extends StatefulWidget {

View File

@ -60,6 +60,7 @@ class ViewItem extends StatelessWidget {
this.rightIconsBuilder,
this.shouldLoadChildViews = true,
this.isExpandedNotifier,
this.extendBuilder,
});
final ViewPB view;
@ -113,6 +114,8 @@ class ViewItem extends StatelessWidget {
final bool shouldLoadChildViews;
final PropertyValueNotifier<bool>? isExpandedNotifier;
final List<Widget> Function(ViewPB view)? extendBuilder;
@override
Widget build(BuildContext context) {
return BlocProvider(
@ -148,6 +151,7 @@ class ViewItem extends StatelessWidget {
leftIconBuilder: leftIconBuilder,
rightIconsBuilder: rightIconsBuilder,
isExpandedNotifier: isExpandedNotifier,
extendBuilder: extendBuilder,
);
},
),
@ -181,6 +185,7 @@ class InnerViewItem extends StatefulWidget {
required this.leftIconBuilder,
required this.rightIconsBuilder,
this.isExpandedNotifier,
required this.extendBuilder,
});
final ViewPB view;
@ -210,6 +215,7 @@ class InnerViewItem extends StatefulWidget {
final ViewItemRightIconsBuilder? rightIconsBuilder;
final PropertyValueNotifier<bool>? isExpandedNotifier;
final List<Widget> Function(ViewPB view)? extendBuilder;
@override
State<InnerViewItem> createState() => _InnerViewItemState();
@ -247,6 +253,7 @@ class _InnerViewItemState extends State<InnerViewItem> {
isHovered: widget.isHovered,
leftIconBuilder: widget.leftIconBuilder,
rightIconsBuilder: widget.rightIconsBuilder,
extendBuilder: widget.extendBuilder,
);
// if the view is expanded and has child views, render its child views
@ -270,6 +277,7 @@ class _InnerViewItemState extends State<InnerViewItem> {
isHovered: widget.isHovered,
leftIconBuilder: widget.leftIconBuilder,
rightIconsBuilder: widget.rightIconsBuilder,
extendBuilder: widget.extendBuilder,
);
}).toList();
@ -315,6 +323,7 @@ class _InnerViewItemState extends State<InnerViewItem> {
isFeedback: true,
leftIconBuilder: widget.leftIconBuilder,
rightIconsBuilder: widget.rightIconsBuilder,
extendBuilder: widget.extendBuilder,
),
);
},
@ -389,6 +398,7 @@ class SingleInnerViewItem extends StatefulWidget {
this.isHovered,
required this.leftIconBuilder,
required this.rightIconsBuilder,
required this.extendBuilder,
});
final ViewPB view;
@ -413,6 +423,8 @@ class SingleInnerViewItem extends StatefulWidget {
final ViewItemLeftIconBuilder? leftIconBuilder;
final ViewItemRightIconsBuilder? rightIconsBuilder;
final List<Widget> Function(ViewPB view)? extendBuilder;
@override
State<SingleInnerViewItem> createState() => _SingleInnerViewItemState();
}
@ -453,6 +465,10 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
}
Widget _buildViewItem(bool onHover, [bool isSelected = false]) {
final name = FlowyText.regular(
widget.view.name,
overflow: TextOverflow.ellipsis,
);
final children = [
const HSpace(2),
// expand icon or placeholder
@ -462,12 +478,16 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
_buildViewIconButton(),
const HSpace(6),
// title
Expanded(
child: FlowyText.regular(
widget.view.name,
overflow: TextOverflow.ellipsis,
),
),
widget.extendBuilder != null
? Expanded(
child: Row(
children: [
name,
...widget.extendBuilder!(widget.view),
],
),
)
: Expanded(child: name),
];
// hover action

View File

@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.64912 1.71521C2.64912 1.43942 2.84766 1.2002 3.16 1.2002H8.855C9.125 1.2002 9.36707 1.40199 9.36707 1.71021C9.36707 1.89847 9.20994 2.20021 8.855 2.20021L8.01019 2.20277L8.00984 4.46598C8.00984 4.53315 8.05692 4.59785 8.10288 4.64382L10.1752 7.02856C10.223 7.07629 10.25 7.14117 10.25 7.20834L10.2495 7.61027C10.25 7.89027 10.025 8.11628 9.75 8.11628L6.51011 8.11753L6.51 11.2002C6.50999 11.4763 6.28614 11.7002 6.01 11.7002H5.99949C5.72355 11.7002 5.49977 11.4761 5.49949 11.2002L5.49613 8.11681L2.255 8.11631C1.96831 8.11631 1.75 7.89027 1.75 7.61027L1.75046 7.20898C1.75048 7.14179 1.77659 7.07678 1.82409 7.02928L3.90196 4.64452C3.94951 4.59697 4.00575 4.53192 4.00575 4.46474L4.00593 2.20171L3.16 2.20021C2.89258 2.20171 2.64912 1.9824 2.64912 1.71521Z" fill="#4DA594"/>
</svg>

After

Width:  |  Height:  |  Size: 891 B