Explorar el Código

[flutter]: config menu trash ui

appflowy hace 3 años
padre
commit
0d5a16e447

+ 14 - 24
app_flowy/lib/workspace/domain/page_stack/page_stack.dart

@@ -1,18 +1,15 @@
 import 'package:equatable/equatable.dart';
-import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
-
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
-import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
 import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
 import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
 
 typedef NavigationCallback = void Function(String id);
 
 abstract class NavigationItem {
-  String get title;
+  Widget get titleWidget;
   String get identifier;
 
   NavigationCallback get action => (id) {
@@ -20,33 +17,28 @@ abstract class NavigationItem {
       };
 }
 
+enum HomeStackType {
+  blank,
+  doc,
+  trash,
+}
+
+List<HomeStackType> pages = HomeStackType.values.toList();
+
 abstract class HomeStackContext extends Equatable with NavigationItem {
   List<NavigationItem> get navigationItems;
 
   @override
-  String get title;
+  Widget get titleWidget;
 
   @override
   String get identifier;
 
-  ViewType get type;
+  HomeStackType get type;
 
   Widget render();
 }
 
-extension ViewStackContext on View {
-  HomeStackContext intoStackContext() {
-    switch (viewType) {
-      case ViewType.Blank:
-        return BlankStackContext();
-      case ViewType.Doc:
-        return DocStackContext(view: this);
-      default:
-        return BlankStackContext();
-    }
-  }
-}
-
 class HomeStackNotifier extends ChangeNotifier {
   HomeStackContext inner;
   HomeStackNotifier({HomeStackContext? context}) : inner = context ?? BlankStackContext();
@@ -64,8 +56,8 @@ class HomeStackManager {
   final HomeStackNotifier _notifier = HomeStackNotifier();
   HomeStackManager();
 
-  String title() {
-    return _notifier.context.title;
+  Widget title() {
+    return _notifier.context.titleWidget;
   }
 
   void setStack(HomeStackContext context) {
@@ -93,7 +85,7 @@ class HomeStackManager {
       child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
         return FadingIndexedStack(
           index: pages.indexOf(notifier.context.type),
-          children: ViewType.values.map((viewType) {
+          children: HomeStackType.values.map((viewType) {
             if (viewType == notifier.context.type) {
               return notifier.context.render();
             } else {
@@ -105,5 +97,3 @@ class HomeStackManager {
     );
   }
 }
-
-List<ViewType> pages = ViewType.values.toList();

+ 30 - 0
app_flowy/lib/workspace/domain/view_ext.dart

@@ -0,0 +1,30 @@
+import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
+import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
+import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
+
+extension ToHomeStackContext on View {
+  HomeStackContext stackContext() {
+    switch (viewType) {
+      case ViewType.Blank:
+        return BlankStackContext();
+      case ViewType.Doc:
+        return DocStackContext(view: this);
+      default:
+        return BlankStackContext();
+    }
+  }
+}
+
+extension ToHomeStackType on View {
+  HomeStackType stackType() {
+    switch (viewType) {
+      case ViewType.Blank:
+        return HomeStackType.blank;
+      case ViewType.Doc:
+        return HomeStackType.doc;
+      default:
+        return HomeStackType.blank;
+    }
+  }
+}

+ 10 - 13
app_flowy/lib/workspace/presentation/home/navigation.dart

@@ -1,4 +1,5 @@
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_infra_ui/style_widget/text_button.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
@@ -94,14 +95,12 @@ class IconNaviItemWidget extends StatelessWidget {
   Widget build(BuildContext context) {
     return SizedBox(
       height: 24,
-      child: FlowyTextButton(
-        item.title,
-        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
-        fontSize: 12,
-        onPressed: () {
+      child: InkWell(
+        child: item.titleWidget,
+        onTap: () {
           debugPrint('show app document');
         },
-      ),
+      ).padding(horizontal: 8, vertical: 2),
     );
   }
 }
@@ -114,14 +113,12 @@ class NaviItemWidget extends StatelessWidget {
   Widget build(BuildContext context) {
     return SizedBox(
       height: 24,
-      child: FlowyTextButton(
-        item.title,
-        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
-        fontSize: 12,
-        onPressed: () {
+      child: InkWell(
+        child: item.titleWidget,
+        onTap: () {
           debugPrint('show app document');
         },
-      ),
+      ).padding(horizontal: 8, vertical: 2),
     );
   }
 }
@@ -145,7 +142,7 @@ class EllipsisNaviItem extends NavigationItem {
   });
 
   @override
-  String get title => "...";
+  Widget get titleWidget => const FlowyText.medium('...');
 
   @override
   NavigationCallback get action => (id) {};

+ 5 - 4
app_flowy/lib/workspace/presentation/stack_page/blank/blank_page.dart

@@ -1,4 +1,5 @@
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
 
@@ -10,10 +11,10 @@ class BlankStackContext extends HomeStackContext {
   List<Object?> get props => ["1"];
 
   @override
-  String get title => "Blank page";
+  Widget get titleWidget => const FlowyText.medium('Blank page', fontSize: 12);
 
   @override
-  ViewType get type => ViewType.Blank;
+  HomeStackType get type => HomeStackType.blank;
 
   @override
   Widget render() {
@@ -28,10 +29,10 @@ class BlankStackPage extends StatefulWidget {
   const BlankStackPage({Key? key}) : super(key: key);
 
   @override
-  State<BlankStackPage> createState() => _AnnouncementPage();
+  State<BlankStackPage> createState() => _BlankStackPageState();
 }
 
-class _AnnouncementPage extends State<BlankStackPage> {
+class _BlankStackPageState extends State<BlankStackPage> {
   @override
   Widget build(BuildContext context) {
     return SizedBox.expand(

+ 4 - 2
app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart

@@ -1,6 +1,8 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/workspace/domain/view_ext.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flowy_log/flowy_log.dart';
 import 'package:flowy_infra_ui/widget/error_page.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
@@ -15,11 +17,11 @@ class DocStackContext extends HomeStackContext {
   DocStackContext({required View view, Key? key}) : _view = view;
 
   @override
-  String get title => _view.name;
+  Widget get titleWidget => FlowyText.medium(_view.name, fontSize: 12);
   @override
   String get identifier => _view.id;
   @override
-  ViewType get type => _view.viewType;
+  HomeStackType get type => _view.stackType();
 
   @override
   List<Object?> get props => [_view.id];

+ 47 - 0
app_flowy/lib/workspace/presentation/stack_page/trash_page.dart

@@ -0,0 +1,47 @@
+import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
+import 'package:flutter/material.dart';
+
+class TrashStackContext extends HomeStackContext {
+  @override
+  String get identifier => "TrashStackContext";
+
+  @override
+  List<Object?> get props => ["TrashStackContext"];
+
+  @override
+  Widget get titleWidget => const FlowyText.medium('Trash', fontSize: 12);
+
+  @override
+  HomeStackType get type => HomeStackType.trash;
+
+  @override
+  Widget render() {
+    return const TrashStackPage();
+  }
+
+  @override
+  List<NavigationItem> get navigationItems => [this];
+}
+
+class TrashStackPage extends StatefulWidget {
+  const TrashStackPage({Key? key}) : super(key: key);
+
+  @override
+  State<TrashStackPage> createState() => _TrashStackPageState();
+}
+
+class _TrashStackPageState extends State<TrashStackPage> {
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox.expand(
+      child: Container(
+        color: Colors.white,
+        child: Padding(
+          padding: const EdgeInsets.all(10),
+          child: Container(),
+        ),
+      ),
+    );
+  }
+}

+ 15 - 24
app_flowy/lib/workspace/presentation/widgets/menu/menu.dart

@@ -18,6 +18,7 @@ import 'package:app_flowy/workspace/presentation/widgets/menu/widget/menu_user.d
 
 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
@@ -101,6 +102,9 @@ class HomeMenu extends StatelessWidget {
               ],
             ).padding(horizontal: Insets.l),
           ),
+          const VSpace(20),
+          _renderTrash(context).padding(horizontal: Insets.l),
+          const VSpace(20),
           _renderNewAppButton(context),
         ],
       ),
@@ -112,10 +116,10 @@ class HomeMenu extends StatelessWidget {
       builder: (context, state) {
         return state.map(
           initial: (_) => MenuList(
-            menuItems: menuItemsWithApps(context.read<MenuBloc>().state.apps),
+            menuItems: buildMenuItems(context.read<MenuBloc>().state.apps),
           ),
           loadApps: (s) => MenuList(
-            menuItems: menuItemsWithApps(some(s.apps)),
+            menuItems: buildMenuItems(some(s.apps)),
           ),
           loadFail: (s) => FlowyErrorPage(s.error.toString()),
         );
@@ -123,6 +127,10 @@ class HomeMenu extends StatelessWidget {
     );
   }
 
+  Widget _renderTrash(BuildContext context) {
+    return const MenuTrash();
+  }
+
   Widget _renderNewAppButton(BuildContext context) {
     return NewAppButton(
       press: (appName) => context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
@@ -133,31 +141,14 @@ class HomeMenu extends StatelessWidget {
     return const MenuTopBar();
   }
 
-  List<MenuItem> menuItemsWithApps(Option<List<App>> someApps) {
-    return MenuItemBuilder().withUser(user).withApps(someApps).build();
-  }
-}
-
-class MenuItemBuilder {
-  List<MenuItem> items = [];
-
-  MenuItemBuilder();
-
-  MenuItemBuilder withUser(UserProfile user) {
+  List<MenuItem> buildMenuItems(Option<List<App>> apps) {
+    List<MenuItem> items = [];
     items.add(MenuUser(user));
-    return this;
-  }
 
-  MenuItemBuilder withApps(Option<List<App>> someApps) {
-    List<MenuItem> appWidgets = someApps.foldRight(
-      [],
-      (apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList(),
-    );
-    items.addAll(appWidgets);
-    return this;
-  }
+    List<MenuItem> appWidgets =
+        apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList());
 
-  List<MenuItem> build() {
+    items.addAll(appWidgets);
     return items;
   }
 }

+ 2 - 1
app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/item.dart

@@ -1,6 +1,7 @@
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/application/view/view_bloc.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/workspace/domain/view_ext.dart';
 import 'package:dartz/dartz.dart' as dartz;
 import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra/theme.dart';
@@ -44,7 +45,7 @@ class ViewSectionItem extends StatelessWidget {
           return InkWell(
             onTap: () {
               onSelected(context.read<ViewBloc>().state.view);
-              getIt<HomeStackManager>().setStack(state.view.intoStackContext());
+              getIt<HomeStackManager>().setStack(state.view.stackContext());
             },
             child: FlowyHover(
               config: HoverDisplayConfig(hoverColor: theme.bg3),

+ 33 - 0
app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart

@@ -0,0 +1,33 @@
+import 'package:app_flowy/startup/startup.dart';
+import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/workspace/presentation/stack_page/trash_page.dart';
+import 'package:flowy_infra/image.dart';
+import 'package:flowy_infra_ui/style_widget/text.dart';
+import 'package:flowy_infra_ui/widget/spacing.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+
+class MenuTrash extends StatelessWidget {
+  const MenuTrash({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 26,
+      child: InkWell(
+        onTap: () {
+          getIt<HomeStackManager>().setStack(TrashStackContext());
+        },
+        child: _render(context),
+      ),
+    );
+  }
+
+  Widget _render(BuildContext context) {
+    return Row(children: [
+      SizedBox(width: 16, height: 16, child: svg("home/trash")),
+      const HSpace(6),
+      const FlowyText.medium('Trash', fontSize: 12),
+    ]);
+  }
+}

+ 2 - 3
app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_user.dart

@@ -11,6 +11,8 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
 class MenuUser extends MenuItem {
   final UserProfile user;
   MenuUser(this.user, {Key? key}) : super(key: ValueKey(user.id));
+  @override
+  MenuItemType get type => MenuItemType.userProfile;
 
   @override
   Widget build(BuildContext context) {
@@ -60,7 +62,4 @@ class MenuUser extends MenuItem {
       },
     );
   }
-
-  @override
-  MenuItemType get type => MenuItemType.userProfile;
 }