Browse Source

[flutter]: config editor navigation items

appflowy 3 years ago
parent
commit
ae82e052f2

+ 26 - 7
app_flowy/lib/workspace/domain/page_stack/page_stack.dart

@@ -1,16 +1,36 @@
-import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
 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/fading_index_stack.dart';
 import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
 
-abstract class HomeStackContext extends Equatable {
+typedef NavigationCallback = void Function(String id);
+
+abstract class NavigationItem {
   String get title;
   String get identifier;
+
+  NavigationCallback get action => (id) {
+        getIt<HomeStack>().setStackWithId(id);
+      };
+}
+
+abstract class HomeStackContext extends Equatable with NavigationItem {
+  List<NavigationItem> get navigationItems;
+
+  @override
+  String get title;
+
+  @override
+  String get identifier;
+
   ViewType get type;
+
   Widget render();
 }
 
@@ -27,10 +47,7 @@ HomeStackContext stackCtxFromView(View view) {
 
 class HomeStackNotifier extends ChangeNotifier {
   HomeStackContext inner;
-
-  HomeStackNotifier({
-    HomeStackContext? context,
-  }) : inner = context ?? DefaultHomeStackContext();
+  HomeStackNotifier({HomeStackContext? context}) : inner = context ?? DefaultHomeStackContext();
 
   set context(HomeStackContext context) {
     inner = context;
@@ -40,7 +57,7 @@ class HomeStackNotifier extends ChangeNotifier {
   HomeStackContext get context => inner;
 }
 
-// HomePageStack is initialized as singleton to controll the page stack.
+// HomeStack is initialized as singleton to controll the page stack.
 class HomeStack {
   final HomeStackNotifier _notifier = HomeStackNotifier();
   HomeStack();
@@ -53,6 +70,8 @@ class HomeStack {
     _notifier.context = context;
   }
 
+  void setStackWithId(String id) {}
+
   Widget stackTopBar() {
     return MultiProvider(
       providers: [

+ 37 - 36
app_flowy/lib/workspace/presentation/home/navigation.dart

@@ -1,5 +1,4 @@
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/presentation/widgets/home_top_bar.dart';
 import 'package:flowy_infra_ui/style_widget/text_button.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
@@ -7,34 +6,38 @@ import 'package:styled_widget/styled_widget.dart';
 
 typedef NaviAction = void Function();
 
-abstract class NaviItem {
-  String get identifier;
-  String get title;
-  NaviAction get action;
-}
-
 class NavigationNotifier with ChangeNotifier {
-  HomeStackNotifier pageStackNotifier;
-  NavigationNotifier(this.pageStackNotifier);
+  HomeStackNotifier homeStackNotifier;
+  NavigationNotifier(this.homeStackNotifier);
 
   void update(HomeStackNotifier notifier) {
-    pageStackNotifier = notifier;
+    homeStackNotifier = notifier;
     notifyListeners();
   }
 
-  List<NaviItem> get naviItems {
-    List<NaviItem> items = [
-      ViewNaviItemImpl(pageStackNotifier.context),
-      // ViewNaviItemImpl(pageStackNotifier.view),
-      // ViewNaviItemImpl(pageStackNotifier.view),
-      // ViewNaviItemImpl(pageStackNotifier.view),
-      // ViewNaviItemImpl(pageStackNotifier.view),
-      // ViewNaviItemImpl(pageStackNotifier.view)
-    ];
-    return items;
-  }
+  List<NavigationItem> get naviItems => homeStackNotifier.context.navigationItems;
 }
 
+// [[Navigation]]
+//                                                                              ┌───────────────────────┐
+//                     2.notify listeners                                ┌──────│DefaultHomeStackContext│
+//  ┌────────────────┐           ┌───────────┐   ┌────────────────┐      │      └───────────────────────┘
+//  │HomeStackNotifie│◀──────────│ HomeStack │◀──│HomeStackContext│◀─ impl
+//  └────────────────┘           └───────────┘   └────────────────┘      │       ┌───────────────────┐
+//           │                         ▲                                 └───────│  DocStackContext  │
+//           │                         │                                         └───────────────────┘
+//    3.notify change            1.set context
+//           │                         │
+//           ▼                         │
+// ┌───────────────────┐     ┌──────────────────┐
+// │NavigationNotifier │     │ ViewSectionItem  │
+// └───────────────────┘     └──────────────────┘
+//           │
+//           │
+//           ▼
+//  ┌─────────────────┐
+//  │ FlowyNavigation │   4.render navigation items
+//  └─────────────────┘
 class FlowyNavigation extends StatelessWidget {
   const FlowyNavigation({Key? key}) : super(key: key);
 
@@ -42,10 +45,7 @@ class FlowyNavigation extends StatelessWidget {
   Widget build(BuildContext context) {
     return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
       create: (_) => NavigationNotifier(
-        Provider.of<HomeStackNotifier>(
-          context,
-          listen: false,
-        ),
+        Provider.of<HomeStackNotifier>(context, listen: false),
       ),
       update: (_, notifier, controller) => controller!..update(notifier),
       child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
@@ -54,12 +54,12 @@ class FlowyNavigation extends StatelessWidget {
     );
   }
 
-  List<Widget> _renderChildren(List<NaviItem> items) {
+  List<Widget> _renderChildren(List<NavigationItem> items) {
     if (items.isEmpty) {
       return [];
     }
 
-    List<NaviItem> newItems = _filter(items);
+    List<NavigationItem> newItems = _filter(items);
     Widget last = NaviItemWidget(newItems.removeLast());
 
     List<Widget> widgets = List.empty(growable: true);
@@ -69,7 +69,7 @@ class FlowyNavigation extends StatelessWidget {
     return widgets;
   }
 
-  List<NaviItem> _filter(List<NaviItem> items) {
+  List<NavigationItem> _filter(List<NavigationItem> items) {
     final length = items.length;
     if (length > 4) {
       final first = items[0];
@@ -87,16 +87,17 @@ class FlowyNavigation extends StatelessWidget {
 }
 
 class NaviItemWidget extends StatelessWidget {
-  final NaviItem item;
+  final NavigationItem item;
   const NaviItemWidget(this.item, {Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
     return SizedBox(
-      height: 30,
+      height: 24,
       child: FlowyTextButton(
         item.title,
-        fontSize: 14,
+        padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
+        fontSize: 12,
         onPressed: () {
           debugPrint('show app document');
         },
@@ -117,18 +118,18 @@ class NaviItemDivider extends StatelessWidget {
   }
 }
 
-class EllipsisNaviItem extends NaviItem {
-  final List<NaviItem> items;
+class EllipsisNaviItem extends NavigationItem {
+  final List<NavigationItem> items;
   EllipsisNaviItem({
     required this.items,
   });
 
   @override
-  NaviAction get action => throw UnimplementedError();
+  String get title => "...";
 
   @override
-  String get identifier => "Ellipsis";
+  NavigationCallback get action => (id) {};
 
   @override
-  String get title => "...";
+  String get identifier => "Ellipsis";
 }

+ 3 - 0
app_flowy/lib/workspace/presentation/stack_page/blank/blank_page.dart

@@ -19,6 +19,9 @@ class DefaultHomeStackContext extends HomeStackContext {
   Widget render() {
     return const AnnouncementStackPage();
   }
+
+  @override
+  List<NavigationItem> get navigationItems => [this];
 }
 
 class AnnouncementStackPage extends StatefulWidget {

+ 15 - 0
app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart

@@ -28,6 +28,21 @@ class DocStackContext extends HomeStackContext {
   Widget render() {
     return DocStackPage(_view, key: ValueKey(_view.id));
   }
+
+  @override
+  List<NavigationItem> get navigationItems => makeNavigationItems();
+
+  // List<NavigationItem> get navigationItems => naviStacks.map((stack) {
+  //       return NavigationItemImpl(context: stack);
+  //     }).toList();
+
+  List<NavigationItem> makeNavigationItems() {
+    return [
+      this,
+      this,
+      this,
+    ];
+  }
 }
 
 class DocStackPage extends StatefulWidget {

+ 0 - 16
app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart

@@ -1,4 +1,3 @@
-import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/domain/image.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
@@ -86,18 +85,3 @@ class HomeTitle extends StatelessWidget {
     );
   }
 }
-
-class ViewNaviItemImpl extends NaviItem {
-  final HomeStackContext view;
-
-  ViewNaviItemImpl(this.view);
-
-  @override
-  NaviAction get action => () => getIt<HomeStack>().setStack(view);
-
-  @override
-  String get identifier => view.identifier;
-
-  @override
-  String get title => view.title;
-}

+ 17 - 19
app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart

@@ -11,7 +11,7 @@ class FlowyHover extends StatefulWidget {
   const FlowyHover({
     Key? key,
     required this.builder,
-    this.config = const HoverDisplayConfig(),
+    required this.config,
   }) : super(key: key);
 
   @override
@@ -23,40 +23,39 @@ class _FlowyHoverState extends State<FlowyHover> {
 
   @override
   Widget build(BuildContext context) {
-    final hoverColor = _onHover ? widget.config.hoverColor : Theme.of(context).colorScheme.background;
-    final config = widget.config.copyWith(hoverColor: hoverColor);
-
     return MouseRegion(
       cursor: SystemMouseCursors.click,
       onEnter: (p) => setOnHover(true),
       onExit: (p) => setOnHover(false),
-      child: FlowyHoverBackground(config: config, child: widget.builder(context, _onHover)),
+      child: render(),
     );
   }
 
   void setOnHover(bool value) => setState(() => _onHover = value);
+
+  Widget render() {
+    if (_onHover) {
+      return FlowyHoverBackground(
+        config: widget.config,
+        child: widget.builder(context, _onHover),
+      );
+    } else {
+      return widget.builder(context, _onHover);
+    }
+  }
 }
 
 class HoverDisplayConfig {
   final Color borderColor;
   final double borderWidth;
-  final Color? hoverColor;
+  final Color hoverColor;
   final BorderRadius borderRadius;
 
   const HoverDisplayConfig(
       {this.borderColor = Colors.transparent,
       this.borderWidth = 0,
       this.borderRadius = const BorderRadius.all(Radius.circular(6)),
-      this.hoverColor});
-
-  HoverDisplayConfig copyWith({Color? hoverColor}) {
-    return HoverDisplayConfig(
-      borderColor: borderColor,
-      borderWidth: borderWidth,
-      borderRadius: borderRadius,
-      hoverColor: hoverColor,
-    );
-  }
+      required this.hoverColor});
 }
 
 class FlowyHoverBackground extends StatelessWidget {
@@ -67,12 +66,11 @@ class FlowyHoverBackground extends StatelessWidget {
   const FlowyHoverBackground({
     Key? key,
     required this.child,
-    this.config = const HoverDisplayConfig(),
+    required this.config,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
-    final color = config.hoverColor ?? Theme.of(context).colorScheme.background;
     final hoverBorder = Border.all(
       color: config.borderColor,
       width: config.borderWidth,
@@ -81,7 +79,7 @@ class FlowyHoverBackground extends StatelessWidget {
     return Container(
       decoration: BoxDecoration(
         border: hoverBorder,
-        color: color,
+        color: config.hoverColor,
         borderRadius: config.borderRadius,
       ),
       child: child,

+ 4 - 3
app_flowy/packages/flowy_infra_ui/lib/style_widget/text_button.dart

@@ -1,7 +1,9 @@
+import 'package:flowy_infra/theme.dart';
 import 'package:flowy_infra_ui/style_widget/hover.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
+import 'package:provider/provider.dart';
 
 class FlowyTextButton extends StatelessWidget {
   final String text;
@@ -17,12 +19,11 @@ class FlowyTextButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
     return InkWell(
       onTap: onPressed,
       child: FlowyHover(
-        config: HoverDisplayConfig(
-            borderRadius: BorderRadius.circular(8),
-            hoverColor: Colors.grey.shade300),
+        config: HoverDisplayConfig(borderRadius: BorderRadius.circular(6), hoverColor: theme.bg3),
         builder: (context, onHover) => _render(),
       ),
     );