ソースを参照

[flutter]: update home page topbar title after the view name changed

appflowy 3 年 前
コミット
17f5a6ac9d

+ 30 - 13
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<HomeStackType> pages = HomeStackType.values.toList();
 
-abstract class HomeStackContext extends Equatable with NavigationItem {
+abstract class HomeStackContext<T> with NavigationItem {
   List<NavigationItem> get navigationItems;
 
   @override
-  Widget get titleWidget;
+  Widget get naviTitle;
 
   @override
   String get identifier;
 
+  ValueNotifier<T> 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<HomeStackNotifier, Widget>(
+        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();
             }

+ 13 - 12
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<NavigationItem> navigationItems;
+  NavigationNotifier({required this.navigationItems});
 
   void update(HomeStackNotifier notifier) {
-    homeStackNotifier = notifier;
+    navigationItems = notifier.context.navigationItems;
     notifyListeners();
   }
-
-  List<NavigationItem> get naviItems => homeStackNotifier.context.navigationItems;
 }
 
 // [[diagram: HomeStack navigation flow]]
@@ -45,12 +43,15 @@ class FlowyNavigation extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
-      create: (_) => NavigationNotifier(
-        Provider.of<HomeStackNotifier>(context, listen: false),
-      ),
+      create: (_) {
+        final notifier = Provider.of<HomeStackNotifier>(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) {};

+ 10 - 6
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 {
-  @override
-  String get identifier => "1";
+  final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
 
   @override
-  List<Object?> get props => ["1"];
+  String get identifier => "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<NavigationItem> get navigationItems => [this];
+
+  @override
+  ValueNotifier<bool> get isUpdated => _isUpdated;
+
+  @override
+  void dispose() {}
 }
 
 class BlankStackPage extends StatefulWidget {

+ 30 - 9
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<String> _isUpdated = ValueNotifier<String>("");
+
+  DocStackContext({required View view, Key? key}) : _view = view {
+    _listener = getIt<IViewListener>(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<Object?> get props => [_view.id];
-
-  @override
-  Widget render() {
+  Widget buildWidget() {
     return DocStackPage(_view, key: ValueKey(_view.id));
   }
 
   @override
-  List<NavigationItem> get navigationItems => makeNavigationItems();
+  List<NavigationItem> get navigationItems => _makeNavigationItems();
+
+  @override
+  ValueNotifier<String> get isUpdated => _isUpdated;
 
   // List<NavigationItem> get navigationItems => naviStacks.map((stack) {
   //       return NavigationItemImpl(context: stack);
   //     }).toList();
 
-  List<NavigationItem> makeNavigationItems() {
+  List<NavigationItem> _makeNavigationItems() {
     return [
       this,
     ];
   }
+
+  @override
+  void dispose() {
+    _listener.stop();
+  }
 }
 
 class DocStackPage extends StatefulWidget {

+ 10 - 5
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 {
-  @override
-  String get identifier => "TrashStackContext";
+  final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
 
   @override
-  List<Object?> get props => ["TrashStackContext"];
+  String get identifier => "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<NavigationItem> get navigationItems => [this];
+
+  @override
+  ValueNotifier<bool> get isUpdated => _isUpdated;
+
+  @override
+  void dispose() {}
 }
 
 class TrashStackPage extends StatefulWidget {

+ 2 - 8
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 {