| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 | 
							- export './app/header/header.dart';
 
- export './app/menu_app.dart';
 
- import 'dart:io' show Platform;
 
- import 'package:app_flowy/plugins/trash/menu.dart';
 
- import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
 
- import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
 
- import 'package:flowy_infra/notifier.dart';
 
- import 'package:flowy_infra/size.dart';
 
- import 'package:flowy_infra/theme.dart';
 
- import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
 
- import 'package:flowy_infra_ui/widget/spacing.dart';
 
- import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfilePB;
 
- import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
 
- import 'package:flowy_sdk/protobuf/flowy-folder/workspace.pb.dart';
 
- import 'package:flutter/material.dart';
 
- import 'package:flutter_bloc/flutter_bloc.dart';
 
- import 'package:styled_widget/styled_widget.dart';
 
- import 'package:expandable/expandable.dart';
 
- import 'package:flowy_infra/time/duration.dart';
 
- import 'package:app_flowy/startup/startup.dart';
 
- import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
 
- import 'package:app_flowy/workspace/application/home/home_bloc.dart';
 
- import 'package:app_flowy/core/frameless_window.dart';
 
- // import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
 
- import 'package:flowy_infra/image.dart';
 
- import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 
- import '../navigation.dart';
 
- import 'app/menu_app.dart';
 
- import 'app/create_button.dart';
 
- import 'menu_user.dart';
 
- class HomeMenu extends StatelessWidget {
 
-   final PublishNotifier<bool> _collapsedNotifier;
 
-   final UserProfilePB user;
 
-   final WorkspaceSettingPB workspaceSetting;
 
-   const HomeMenu({
 
-     Key? key,
 
-     required this.user,
 
-     required this.workspaceSetting,
 
-     required PublishNotifier<bool> collapsedNotifier,
 
-   })  : _collapsedNotifier = collapsedNotifier,
 
-         super(key: key);
 
-   @override
 
-   Widget build(BuildContext context) {
 
-     return MultiBlocProvider(
 
-       providers: [
 
-         BlocProvider<MenuBloc>(
 
-           create: (context) {
 
-             final menuBloc = MenuBloc(
 
-               user: user,
 
-               workspace: workspaceSetting.workspace,
 
-             );
 
-             menuBloc.add(const MenuEvent.initial());
 
-             return menuBloc;
 
-           },
 
-         ),
 
-       ],
 
-       child: MultiBlocListener(
 
-         listeners: [
 
-           BlocListener<MenuBloc, MenuState>(
 
-             listenWhen: (p, c) => p.plugin.id != c.plugin.id,
 
-             listener: (context, state) {
 
-               getIt<HomeStackManager>().setPlugin(state.plugin);
 
-             },
 
-           ),
 
-           BlocListener<HomeBloc, HomeState>(
 
-             listenWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
 
-             listener: (context, state) {
 
-               _collapsedNotifier.value = state.isMenuCollapsed;
 
-             },
 
-           )
 
-         ],
 
-         child: BlocBuilder<MenuBloc, MenuState>(
 
-           builder: (context, state) => _renderBody(context),
 
-         ),
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderBody(BuildContext context) {
 
-     // nested column: https://siddharthmolleti.com/flutter-box-constraints-nested-column-s-row-s-3dfacada7361
 
-     final theme = context.watch<AppTheme>();
 
-     return Container(
 
-       color: theme.bg1,
 
-       child: Column(
 
-         mainAxisAlignment: MainAxisAlignment.start,
 
-         children: [
 
-           Expanded(
 
-             child: Column(
 
-               mainAxisAlignment: MainAxisAlignment.start,
 
-               children: [
 
-                 const MenuTopBar(),
 
-                 const VSpace(10),
 
-                 _renderApps(context),
 
-               ],
 
-             ).padding(horizontal: Insets.l),
 
-           ),
 
-           const VSpace(20),
 
-           const MenuTrash().padding(horizontal: Insets.l),
 
-           const VSpace(20),
 
-           _renderNewAppButton(context),
 
-         ],
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderApps(BuildContext context) {
 
-     return ExpandableTheme(
 
-       data: ExpandableThemeData(
 
-           useInkWell: true, animationDuration: Durations.medium),
 
-       child: Expanded(
 
-         child: ScrollConfiguration(
 
-           behavior: const ScrollBehavior().copyWith(scrollbars: false),
 
-           child: BlocSelector<MenuBloc, MenuState, List<Widget>>(
 
-             selector: (state) => state.apps
 
-                 .map((app) => MenuApp(app, key: ValueKey(app.id)))
 
-                 .toList(),
 
-             builder: (context, menuItems) {
 
-               return ReorderableListView.builder(
 
-                 itemCount: menuItems.length,
 
-                 buildDefaultDragHandles: false,
 
-                 header: Padding(
 
-                   padding:
 
-                       EdgeInsets.only(bottom: 20.0 - MenuAppSizes.appVPadding),
 
-                   child: MenuUser(user),
 
-                 ),
 
-                 onReorder: (oldIndex, newIndex) {
 
-                   // Moving item1 from index 0 to index 1
 
-                   //  expect:   oldIndex: 0, newIndex: 1
 
-                   //  receive:  oldIndex: 0, newIndex: 2
 
-                   //  Workaround: if newIndex > oldIndex, we just minus one
 
-                   int index = newIndex > oldIndex ? newIndex - 1 : newIndex;
 
-                   context
 
-                       .read<MenuBloc>()
 
-                       .add(MenuEvent.moveApp(oldIndex, index));
 
-                 },
 
-                 physics: StyledScrollPhysics(),
 
-                 itemBuilder: (BuildContext context, int index) {
 
-                   return ReorderableDragStartListener(
 
-                     key: ValueKey(menuItems[index].key),
 
-                     index: index,
 
-                     child: Padding(
 
-                       padding: EdgeInsets.symmetric(
 
-                           vertical: MenuAppSizes.appVPadding / 2),
 
-                       child: menuItems[index],
 
-                     ),
 
-                   );
 
-                 },
 
-               );
 
-             },
 
-           ),
 
-         ),
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderNewAppButton(BuildContext context) {
 
-     return NewAppButton(
 
-       press: (appName) =>
 
-           context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
 
-     );
 
-   }
 
- }
 
- class MenuSharedState {
 
-   final ValueNotifier<ViewPB?> _latestOpenView = ValueNotifier<ViewPB?>(null);
 
-   MenuSharedState({ViewPB? view}) {
 
-     _latestOpenView.value = view;
 
-   }
 
-   ViewPB? get latestOpenView => _latestOpenView.value;
 
-   set latestOpenView(ViewPB? view) {
 
-     if (_latestOpenView.value != view) {
 
-       _latestOpenView.value = view;
 
-     }
 
-   }
 
-   VoidCallback addLatestViewListener(void Function(ViewPB?) callback) {
 
-     listener() {
 
-       callback(_latestOpenView.value);
 
-     }
 
-     _latestOpenView.addListener(listener);
 
-     return listener;
 
-   }
 
-   void removeLatestViewListener(VoidCallback listener) {
 
-     _latestOpenView.removeListener(listener);
 
-   }
 
- }
 
- class MenuTopBar extends StatelessWidget {
 
-   const MenuTopBar({Key? key}) : super(key: key);
 
-   Widget renderIcon(BuildContext context) {
 
-     if (Platform.isMacOS) {
 
-       return Container();
 
-     }
 
-     final theme = context.watch<AppTheme>();
 
-     return (theme.isDark
 
-         ? svgWithSize("flowy_logo_dark_mode", const Size(92, 17))
 
-         : svgWithSize("flowy_logo_with_text", const Size(92, 17)));
 
-   }
 
-   @override
 
-   Widget build(BuildContext context) {
 
-     final theme = context.watch<AppTheme>();
 
-     return BlocBuilder<MenuBloc, MenuState>(
 
-       builder: (context, state) {
 
-         return SizedBox(
 
-           height: HomeSizes.topBarHeight,
 
-           child: MoveWindowDetector(
 
-               child: Row(
 
-             children: [
 
-               renderIcon(context),
 
-               const Spacer(),
 
-               Tooltip(
 
-                   richMessage: sidebarTooltipTextSpan(),
 
-                   child: FlowyIconButton(
 
-                     width: 28,
 
-                     onPressed: () => context
 
-                         .read<HomeBloc>()
 
-                         .add(const HomeEvent.collapseMenu()),
 
-                     iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
 
-                     icon: svgWidget("home/hide_menu", color: theme.iconColor),
 
-                   ))
 
-             ],
 
-           )),
 
-         );
 
-       },
 
-     );
 
-   }
 
- }
 
 
  |