From ae82e052f2f7fd1691da6df42be0f6d935630fcb Mon Sep 17 00:00:00 2001 From: appflowy Date: Sun, 10 Oct 2021 17:01:30 +0800 Subject: [PATCH] [flutter]: config editor navigation items --- .../domain/page_stack/page_stack.dart | 33 ++++++-- .../presentation/home/navigation.dart | 75 ++++++++++--------- .../stack_page/blank/blank_page.dart | 3 + .../stack_page/doc/doc_stack_page.dart | 15 ++++ .../presentation/widgets/home_top_bar.dart | 16 ---- .../lib/style_widget/hover.dart | 36 +++++---- .../lib/style_widget/text_button.dart | 7 +- 7 files changed, 103 insertions(+), 82 deletions(-) diff --git a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart b/app_flowy/lib/workspace/domain/page_stack/page_stack.dart index 32acea368e..11789018b3 100644 --- a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart +++ b/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().setStackWithId(id); + }; +} + +abstract class HomeStackContext extends Equatable with NavigationItem { + List 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: [ diff --git a/app_flowy/lib/workspace/presentation/home/navigation.dart b/app_flowy/lib/workspace/presentation/home/navigation.dart index a461df57bd..8980371118 100644 --- a/app_flowy/lib/workspace/presentation/home/navigation.dart +++ b/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 get naviItems { - List items = [ - ViewNaviItemImpl(pageStackNotifier.context), - // ViewNaviItemImpl(pageStackNotifier.view), - // ViewNaviItemImpl(pageStackNotifier.view), - // ViewNaviItemImpl(pageStackNotifier.view), - // ViewNaviItemImpl(pageStackNotifier.view), - // ViewNaviItemImpl(pageStackNotifier.view) - ]; - return items; - } + List 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( create: (_) => NavigationNotifier( - Provider.of( - context, - listen: false, - ), + Provider.of(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 _renderChildren(List items) { + List _renderChildren(List items) { if (items.isEmpty) { return []; } - List newItems = _filter(items); + List newItems = _filter(items); Widget last = NaviItemWidget(newItems.removeLast()); List widgets = List.empty(growable: true); @@ -69,7 +69,7 @@ class FlowyNavigation extends StatelessWidget { return widgets; } - List _filter(List items) { + List _filter(List 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 items; +class EllipsisNaviItem extends NavigationItem { + final List items; EllipsisNaviItem({ required this.items, }); @override - NaviAction get action => throw UnimplementedError(); + String get title => "..."; + + @override + NavigationCallback get action => (id) {}; @override String get identifier => "Ellipsis"; - - @override - String get title => "..."; } diff --git a/app_flowy/lib/workspace/presentation/stack_page/blank/blank_page.dart b/app_flowy/lib/workspace/presentation/stack_page/blank/blank_page.dart index ed13ef094d..662a6a7a9c 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/blank/blank_page.dart +++ b/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 get navigationItems => [this]; } class AnnouncementStackPage extends StatefulWidget { diff --git a/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart b/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart index d8b4753968..240122c933 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/doc/doc_stack_page.dart +++ b/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 get navigationItems => makeNavigationItems(); + + // List get navigationItems => naviStacks.map((stack) { + // return NavigationItemImpl(context: stack); + // }).toList(); + + List makeNavigationItems() { + return [ + this, + this, + this, + ]; + } } class DocStackPage extends StatefulWidget { diff --git a/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart b/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart index 8db1f98c0b..7f790c78ac 100644 --- a/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart +++ b/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().setStack(view); - - @override - String get identifier => view.identifier; - - @override - String get title => view.title; -} diff --git a/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart b/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart index 49276bdd77..99893c98f0 100644 --- a/app_flowy/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/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 { @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, diff --git a/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_button.dart b/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_button.dart index 1abed0ac68..be4b83c83b 100644 --- a/app_flowy/packages/flowy_infra_ui/lib/style_widget/text_button.dart +++ b/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(); 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(), ), );