| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | 
							- import 'package:app_flowy/workspace/presentation/widgets/menu/widget/top_bar.dart';
 
- import 'package:dartz/dartz.dart';
 
- import 'package:flowy_infra/size.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/user_profile.pb.dart';
 
- import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.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/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 Function(HomeStackContext) pageContextChanged;
 
-   final Function(bool) isCollapseChanged;
 
-   final UserProfile user;
 
-   final String workspaceId;
 
-   const HomeMenu({
 
-     Key? key,
 
-     required this.pageContextChanged,
 
-     required this.isCollapseChanged,
 
-     required this.user,
 
-     required this.workspaceId,
 
-   }) : super(key: key);
 
-   @override
 
-   Widget build(BuildContext context) {
 
-     return MultiBlocProvider(
 
-       providers: [
 
-         BlocProvider<MenuBloc>(
 
-             create: (context) => getIt<MenuBloc>(param1: user, param2: workspaceId)..add(const MenuEvent.initial())),
 
-       ],
 
-       child: MultiBlocListener(
 
-         listeners: [
 
-           BlocListener<MenuBloc, MenuState>(
 
-             listenWhen: (p, c) => p.context != c.context,
 
-             listener: (context, state) => pageContextChanged(state.context),
 
-           ),
 
-           BlocListener<MenuBloc, MenuState>(
 
-             listenWhen: (p, c) => p.isCollapse != c.isCollapse,
 
-             listener: (context, state) => isCollapseChanged(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
 
-     return Container(
 
-       color: Theme.of(context).colorScheme.background,
 
-       child: Column(
 
-         mainAxisAlignment: MainAxisAlignment.start,
 
-         children: [
 
-           Expanded(
 
-             child: Column(
 
-               mainAxisAlignment: MainAxisAlignment.start,
 
-               children: [
 
-                 _renderTopBar(context),
 
-                 const VSpace(32),
 
-                 _renderMenuList(context),
 
-               ],
 
-             ).padding(horizontal: Insets.l),
 
-           ),
 
-           const VSpace(20),
 
-           _renderTrash(context).padding(horizontal: Insets.l),
 
-           const VSpace(20),
 
-           _renderNewAppButton(context),
 
-         ],
 
-       ),
 
-     );
 
-   }
 
-   Widget _renderMenuList(BuildContext context) {
 
-     return MenuList(
 
-       menuItems: buildMenuItems(context.read<MenuBloc>().state.apps),
 
-     );
 
-   }
 
-   Widget _renderTrash(BuildContext context) {
 
-     return const MenuTrash();
 
-   }
 
-   Widget _renderNewAppButton(BuildContext context) {
 
-     return NewAppButton(
 
-       press: (appName) => context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
 
-     );
 
-   }
 
-   Widget _renderTopBar(BuildContext context) {
 
-     return const MenuTopBar();
 
-   }
 
-   List<MenuItem> buildMenuItems(Option<List<App>> apps) {
 
-     List<MenuItem> items = [];
 
-     items.add(MenuUser(user));
 
-     List<MenuItem> appWidgets =
 
-         apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList());
 
-     items.addAll(appWidgets);
 
-     return items;
 
-   }
 
- }
 
- enum MenuItemType {
 
-   userProfile,
 
-   dashboard,
 
-   favorites,
 
-   app,
 
- }
 
- abstract class MenuItem extends StatelessWidget {
 
-   const MenuItem({Key? key}) : super(key: key);
 
-   MenuItemType get type;
 
- }
 
- class MenuList extends StatelessWidget {
 
-   final List<MenuItem> menuItems;
 
-   const MenuList({required this.menuItems, Key? key}) : super(key: key);
 
-   @override
 
-   Widget build(BuildContext context) {
 
-     return ExpandableTheme(
 
-       data: ExpandableThemeData(useInkWell: true, animationDuration: Durations.medium),
 
-       child: Expanded(
 
-         child: ScrollConfiguration(
 
-           behavior: const ScrollBehavior().copyWith(scrollbars: false),
 
-           child: ListView.separated(
 
-             itemCount: menuItems.length,
 
-             separatorBuilder: (context, index) {
 
-               if (index == 0) {
 
-                 return const VSpace(29);
 
-               } else {
 
-                 return const VSpace(24);
 
-               }
 
-             },
 
-             physics: StyledScrollPhysics(),
 
-             itemBuilder: (BuildContext context, int index) {
 
-               return menuItems[index];
 
-             },
 
-           ),
 
-         ),
 
-       ),
 
-     );
 
-   }
 
- }
 
 
  |