| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | 
							- import 'package:app_flowy/workspace/presentation/widgets/menu/widget/top_bar.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-data-model/protobuf.dart' show UserProfile;
 
- import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
 
- import 'package:flowy_sdk/protobuf/flowy-folder-data-model/workspace.pb.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';
 
- 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/domain/page_stack/page_stack.dart';
 
- import 'package:app_flowy/workspace/presentation/widgets/menu/widget/menu_user.dart';
 
- import 'widget/app/menu_app.dart';
 
- import 'widget/app/create_button.dart';
 
- import 'widget/menu_trash.dart';
 
- // [[diagram: HomeMenu's widget structure]]
 
- //                                                                                    get user profile or modify user
 
- //                                                                                   ┌──────┐
 
- //                 ┌──────────┐                                                  ┌──▶│IUser │
 
- //              ┌─▶│MenuTopBar│                     ┌────────┐  ┌─────────────┐  │   └──────┘
 
- //              │  └──────────┘                 ┌───│MenuUser│─▶│MenuUserBloc │──┤
 
- // ┌──────────┐ │                               │   └────────┘  └─────────────┘  │   ┌─────────────┐
 
- // │ HomeMenu │─┤                               │                                └──▶│IUserListener│
 
- // └──────────┘ │                               │                                    └─────────────┘
 
- //              │                               │                                    listen workspace changes or user
 
- //              │                         impl  │                                    profile changes
 
- //              │  ┌──────────┐    ┌─────────┐  │
 
- //              └─▶│ MenuList │───▶│MenuItem │◀─┤
 
- //                 └──────────┘    └─────────┘  │                  ┌────────┐
 
- //                                              │               ┌─▶│AppBloc │  fetch app's views or modify view
 
- //                                              │               │  └────────┘
 
- //                                              │   ┌────────┐  │
 
- //                                              └───│MenuApp │──┤
 
- //                                                  └────────┘
 
- class HomeMenu extends StatelessWidget {
 
-   final PublishNotifier<bool> _collapsedNotifier;
 
-   final UserProfile user;
 
-   final CurrentWorkspaceSetting 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 = getIt<MenuBloc>(param1: user, param2: workspaceSetting.workspace.id);
 
-             menuBloc.add(const MenuEvent.initial());
 
-             return menuBloc;
 
-           },
 
-         ),
 
-       ],
 
-       child: MultiBlocListener(
 
-         listeners: [
 
-           BlocListener<MenuBloc, MenuState>(
 
-             listenWhen: (p, c) => p.stackContext != c.stackContext,
 
-             listener: (context, state) {
 
-               getIt<HomeStackManager>().setStack(state.stackContext);
 
-             },
 
-           ),
 
-           BlocListener<MenuBloc, MenuState>(
 
-             listenWhen: (p, c) => p.isCollapse != c.isCollapse,
 
-             listener: (context, state) {
 
-               _collapsedNotifier.value = state.isCollapse;
 
-             },
 
-           )
 
-         ],
 
-         child: BlocBuilder<MenuBloc, MenuState>(
 
-           builder: (context, state) => _renderBody(context),
 
-         ),
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderBody(BuildContext context) {
 
-     // nested cloumn: https://siddharthmolleti.com/flutter-box-constraints-nested-column-s-row-s-3dfacada7361
 
-     final theme = context.watch<AppTheme>();
 
-     return Container(
 
-       color: theme.bg1,
 
-       child: ChangeNotifierProvider(
 
-         create: (_) => MenuSharedState(view: workspaceSetting.hasLatestView() ? workspaceSetting.latestView : null),
 
-         child: Consumer(builder: (context, MenuSharedState sharedState, child) {
 
-           return 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),
 
-               _renderTrash(context).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) {
 
-               List<Widget> menuItems = [];
 
-               menuItems.add(MenuUser(user));
 
-               List<MenuApp> appWidgets =
 
-                   state.apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList());
 
-               menuItems.addAll(appWidgets);
 
-               return menuItems;
 
-             },
 
-             builder: (context, menuItems) => ListView.separated(
 
-               itemCount: menuItems.length,
 
-               separatorBuilder: (context, index) {
 
-                 if (index == 0) {
 
-                   return const VSpace(20);
 
-                 } else {
 
-                   return VSpace(MenuAppSizes.appVPadding);
 
-                 }
 
-               },
 
-               physics: StyledScrollPhysics(),
 
-               itemBuilder: (BuildContext context, int index) {
 
-                 return menuItems[index];
 
-               },
 
-             ),
 
-           ),
 
-         ),
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderTrash(BuildContext context) {
 
-     return const MenuTrash();
 
-   }
 
-   Widget _renderNewAppButton(BuildContext context) {
 
-     return NewAppButton(
 
-       press: (appName) => context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
 
-     );
 
-   }
 
- }
 
- class MenuSharedState extends ChangeNotifier {
 
-   PublishNotifier<View> forcedOpenView = PublishNotifier();
 
-   ValueNotifier<View?> selectedView = ValueNotifier<View?>(null);
 
-   MenuSharedState({View? view}) {
 
-     if (view != null) {
 
-       selectedView.value = view;
 
-     }
 
-     forcedOpenView.addPublishListener((view) {
 
-       selectedView.value = view;
 
-     });
 
-   }
 
- }
 
 
  |