From 17f5a6ac9d2763bb73ff1e131096496568f331a2 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 28 Oct 2021 21:55:22 +0800 Subject: [PATCH] [flutter]: update home page topbar title after the view name changed --- .../domain/page_stack/page_stack.dart | 43 +++++++++++++------ .../presentation/home/navigation.dart | 25 +++++------ .../stack_page/blank/blank_page.dart | 16 ++++--- .../stack_page/doc/doc_stack_page.dart | 39 +++++++++++++---- .../stack_page/trash/trash_page.dart | 15 ++++--- .../presentation/widgets/home_top_bar.dart | 10 +---- 6 files changed, 95 insertions(+), 53 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 4e2159d53a..e46be42423 100644 --- a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart +++ b/app_flowy/lib/workspace/domain/page_stack/page_stack.dart @@ -9,7 +9,7 @@ import 'package:app_flowy/workspace/presentation/widgets/prelude.dart'; typedef NavigationCallback = void Function(String id); abstract class NavigationItem { - Widget get titleWidget; + Widget get naviTitle; String get identifier; NavigationCallback get action => (id) { @@ -25,30 +25,44 @@ enum HomeStackType { List pages = HomeStackType.values.toList(); -abstract class HomeStackContext extends Equatable with NavigationItem { +abstract class HomeStackContext with NavigationItem { List get navigationItems; @override - Widget get titleWidget; + Widget get naviTitle; @override String get identifier; + ValueNotifier get isUpdated; + HomeStackType get type; - Widget render(); + Widget buildWidget(); + + void dispose(); } class HomeStackNotifier extends ChangeNotifier { - HomeStackContext inner; - HomeStackNotifier({HomeStackContext? context}) : inner = context ?? BlankStackContext(); + HomeStackContext stackContext; + Widget get titleWidget => stackContext.naviTitle; + + HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext(); set context(HomeStackContext context) { - inner = context; + notifyChange() { + notifyListeners(); + } + + stackContext.isUpdated.removeListener(notifyChange); + stackContext.dispose(); + + stackContext = context; + stackContext.isUpdated.addListener(notifyChange); notifyListeners(); } - HomeStackContext get context => inner; + HomeStackContext get context => stackContext; } // HomeStack is initialized as singleton to controll the page stack. @@ -57,7 +71,7 @@ class HomeStackManager { HomeStackManager(); Widget title() { - return _notifier.context.titleWidget; + return _notifier.context.naviTitle; } void setStack(HomeStackContext context) { @@ -71,9 +85,12 @@ class HomeStackManager { providers: [ ChangeNotifierProvider.value(value: _notifier), ], - child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) { - return HomeTopBar(view: notifier.context); - }), + child: Selector( + selector: (context, notifier) => notifier.titleWidget, + builder: (context, widget, child) { + return const HomeTopBar(); + }, + ), ); } @@ -87,7 +104,7 @@ class HomeStackManager { index: pages.indexOf(notifier.context.type), children: HomeStackType.values.map((viewType) { if (viewType == notifier.context.type) { - return notifier.context.render(); + return notifier.context.buildWidget(); } else { return const BlankStackPage(); } diff --git a/app_flowy/lib/workspace/presentation/home/navigation.dart b/app_flowy/lib/workspace/presentation/home/navigation.dart index 2e5f60aa10..9b48bb78c2 100644 --- a/app_flowy/lib/workspace/presentation/home/navigation.dart +++ b/app_flowy/lib/workspace/presentation/home/navigation.dart @@ -8,15 +8,13 @@ import 'package:styled_widget/styled_widget.dart'; typedef NaviAction = void Function(); class NavigationNotifier with ChangeNotifier { - HomeStackNotifier homeStackNotifier; - NavigationNotifier(this.homeStackNotifier); + List navigationItems; + NavigationNotifier({required this.navigationItems}); void update(HomeStackNotifier notifier) { - homeStackNotifier = notifier; + navigationItems = notifier.context.navigationItems; notifyListeners(); } - - List get naviItems => homeStackNotifier.context.navigationItems; } // [[diagram: HomeStack navigation flow]] @@ -45,12 +43,15 @@ class FlowyNavigation extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProxyProvider( - create: (_) => NavigationNotifier( - Provider.of(context, listen: false), - ), + create: (_) { + final notifier = Provider.of(context, listen: false); + return NavigationNotifier( + navigationItems: notifier.context.navigationItems, + ); + }, update: (_, notifier, controller) => controller!..update(notifier), child: Consumer(builder: (ctx, NavigationNotifier notifier, child) { - return Row(children: _renderChildren(notifier.naviItems)); + return Row(children: _renderChildren(notifier.navigationItems)); }), ); } @@ -96,7 +97,7 @@ class IconNaviItemWidget extends StatelessWidget { return SizedBox( height: 24, child: InkWell( - child: item.titleWidget, + child: item.naviTitle, onTap: () { debugPrint('show app document'); }, @@ -114,7 +115,7 @@ class NaviItemWidget extends StatelessWidget { return SizedBox( height: 24, child: InkWell( - child: item.titleWidget, + child: item.naviTitle, onTap: () { debugPrint('show app document'); }, @@ -142,7 +143,7 @@ class EllipsisNaviItem extends NavigationItem { }); @override - Widget get titleWidget => const FlowyText.medium('...'); + Widget get naviTitle => const FlowyText.medium('...'); @override NavigationCallback get action => (id) {}; 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 fb62352b5a..55bb2f4735 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 @@ -1,28 +1,32 @@ 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'; class BlankStackContext extends HomeStackContext { + final ValueNotifier _isUpdated = ValueNotifier(false); + @override String get identifier => "1"; @override - List get props => ["1"]; - - @override - Widget get titleWidget => const FlowyText.medium('Blank page', fontSize: 12); + Widget get naviTitle => const FlowyText.medium('Blank page', fontSize: 12); @override HomeStackType get type => HomeStackType.blank; @override - Widget render() { + Widget buildWidget() { return const BlankStackPage(); } @override List get navigationItems => [this]; + + @override + ValueNotifier get isUpdated => _isUpdated; + + @override + void dispose() {} } class BlankStackPage 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 788692a3e7..e332060d48 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 @@ -1,3 +1,5 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/domain/i_view.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'; @@ -7,36 +9,55 @@ import 'package:flutter/material.dart'; import 'doc_page.dart'; class DocStackContext extends HomeStackContext { - final View _view; - DocStackContext({required View view, Key? key}) : _view = view; + View _view; + late IViewListener _listener; + final ValueNotifier _isUpdated = ValueNotifier(""); + + DocStackContext({required View view, Key? key}) : _view = view { + _listener = getIt(param1: view); + _listener.start(updatedCallback: (result) { + result.fold( + (newView) { + _view = newView; + _isUpdated.value = _view.name; + }, + (error) {}, + ); + }); + } @override - Widget get titleWidget => FlowyText.medium(_view.name, fontSize: 12); + Widget get naviTitle => FlowyText.medium(_view.name, fontSize: 12); @override String get identifier => _view.id; @override HomeStackType get type => _view.stackType(); @override - List get props => [_view.id]; - - @override - Widget render() { + Widget buildWidget() { return DocStackPage(_view, key: ValueKey(_view.id)); } @override - List get navigationItems => makeNavigationItems(); + List get navigationItems => _makeNavigationItems(); + + @override + ValueNotifier get isUpdated => _isUpdated; // List get navigationItems => naviStacks.map((stack) { // return NavigationItemImpl(context: stack); // }).toList(); - List makeNavigationItems() { + List _makeNavigationItems() { return [ this, ]; } + + @override + void dispose() { + _listener.stop(); + } } class DocStackPage extends StatefulWidget { diff --git a/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart b/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart index 0df9d80490..a06e668038 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart +++ b/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart @@ -19,25 +19,30 @@ import 'package:styled_widget/styled_widget.dart'; import 'widget/trash_header.dart'; class TrashStackContext extends HomeStackContext { + final ValueNotifier _isUpdated = ValueNotifier(false); + @override String get identifier => "TrashStackContext"; @override - List get props => ["TrashStackContext"]; - - @override - Widget get titleWidget => const FlowyText.medium('Trash', fontSize: 12); + Widget get naviTitle => const FlowyText.medium('Trash', fontSize: 12); @override HomeStackType get type => HomeStackType.trash; @override - Widget render() { + Widget buildWidget() { return const TrashStackPage(key: ValueKey('TrashStackPage')); } @override List get navigationItems => [this]; + + @override + ValueNotifier get isUpdated => _isUpdated; + + @override + void dispose() {} } class TrashStackPage 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 2814d0e498..1202737f05 100644 --- a/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart +++ b/app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart @@ -1,5 +1,4 @@ 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'; import 'package:app_flowy/workspace/presentation/home/navigation.dart'; import 'package:flowy_infra/size.dart'; @@ -12,8 +11,7 @@ import 'package:flowy_infra_ui/style_widget/extension.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; class HomeTopBar extends StatelessWidget { - final HomeStackContext view; - const HomeTopBar({Key? key, required this.view}) : super(key: key); + const HomeTopBar({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -22,7 +20,7 @@ class HomeTopBar extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - _renderNavigation(view), + const FlowyNavigation(), const Spacer(), _renderShareButton(), // _renderMoreButton(), @@ -48,10 +46,6 @@ class HomeTopBar extends StatelessWidget { }, ); } - - Widget _renderNavigation(HomeStackContext view) { - return const FlowyNavigation(); - } } class HomeTitle extends StatelessWidget {