123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import 'dart:io';
- import 'package:appflowy/generated/locale_keys.g.dart';
- import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
- import 'package:appflowy/workspace/presentation/home/home_stack.dart';
- import 'package:easy_localization/easy_localization.dart';
- import 'package:flowy_infra/image.dart';
- import 'package:flowy_infra/size.dart';
- import 'package:flowy_infra_ui/style_widget/icon_button.dart';
- import 'package:flowy_infra_ui/style_widget/text.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'package:provider/provider.dart';
- import 'package:styled_widget/styled_widget.dart';
- typedef NaviAction = void Function();
- class NavigationNotifier with ChangeNotifier {
- List<NavigationItem> navigationItems;
- NavigationNotifier({required this.navigationItems});
- void update(HomeStackNotifier notifier) {
- bool shouldNotify = false;
- if (navigationItems != notifier.plugin.widgetBuilder.navigationItems) {
- navigationItems = notifier.plugin.widgetBuilder.navigationItems;
- shouldNotify = true;
- }
- if (shouldNotify) {
- notifyListeners();
- }
- }
- }
- class FlowyNavigation extends StatelessWidget {
- const FlowyNavigation({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
- create: (_) {
- final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
- return NavigationNotifier(
- navigationItems: notifier.plugin.widgetBuilder.navigationItems,
- );
- },
- update: (_, notifier, controller) => controller!..update(notifier),
- child: Expanded(
- child: Row(
- children: [
- _renderCollapse(context),
- Selector<NavigationNotifier, List<NavigationItem>>(
- selector: (context, notifier) => notifier.navigationItems,
- builder: (ctx, items, child) => Expanded(
- child: Row(
- children: _renderNavigationItems(items),
- // crossAxisAlignment: WrapCrossAlignment.start,
- ),
- ),
- ),
- ],
- ),
- ),
- );
- }
- Widget _renderCollapse(BuildContext context) {
- return BlocBuilder<HomeSettingBloc, HomeSettingState>(
- buildWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
- builder: (context, state) {
- if (state.isMenuCollapsed) {
- return RotationTransition(
- turns: const AlwaysStoppedAnimation(180 / 360),
- child: Tooltip(
- richMessage: sidebarTooltipTextSpan(
- context,
- LocaleKeys.sideBar_openSidebar.tr(),
- ),
- child: FlowyIconButton(
- width: 24,
- hoverColor: Colors.transparent,
- onPressed: () {
- context
- .read<HomeSettingBloc>()
- .add(const HomeSettingEvent.collapseMenu());
- },
- iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
- icon: svgWidget(
- "home/hide_menu",
- color: Theme.of(context).iconTheme.color,
- ),
- ),
- ),
- );
- } else {
- return Container();
- }
- },
- );
- }
- List<Widget> _renderNavigationItems(List<NavigationItem> items) {
- if (items.isEmpty) {
- return [];
- }
- List<NavigationItem> newItems = _filter(items);
- Widget last = NaviItemWidget(newItems.removeLast());
- List<Widget> widgets = List.empty(growable: true);
- // widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList());
- for (final item in newItems) {
- widgets.add(NaviItemWidget(item));
- widgets.add(const Text('/'));
- }
- widgets.add(last);
- return widgets;
- }
- List<NavigationItem> _filter(List<NavigationItem> items) {
- final length = items.length;
- if (length > 4) {
- final first = items[0];
- final ellipsisItems = items.getRange(1, length - 2).toList();
- final last = items.getRange(length - 2, length).toList();
- return [
- first,
- EllipsisNaviItem(items: ellipsisItems),
- ...last,
- ];
- } else {
- return items;
- }
- }
- }
- class NaviItemWidget extends StatelessWidget {
- final NavigationItem item;
- const NaviItemWidget(this.item, {Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return Expanded(
- child: item.leftBarItem.padding(horizontal: 2, vertical: 2),
- );
- }
- }
- class NaviItemDivider extends StatelessWidget {
- final Widget child;
- const NaviItemDivider({Key? key, required this.child}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- return Row(
- children: [child, const Text('/')],
- );
- }
- }
- class EllipsisNaviItem extends NavigationItem {
- final List<NavigationItem> items;
- EllipsisNaviItem({
- required this.items,
- });
- @override
- Widget get leftBarItem => FlowyText.medium(
- '...',
- fontSize: FontSizes.s16,
- );
- @override
- NavigationCallback get action => (id) {};
- }
- TextSpan sidebarTooltipTextSpan(BuildContext context, String hintText) =>
- TextSpan(
- children: [
- TextSpan(
- text: "$hintText\n",
- ),
- TextSpan(
- text: Platform.isMacOS ? "⌘+\\" : "Ctrl+\\",
- ),
- ],
- );
|