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

This commit is contained in:
appflowy 2021-10-28 21:55:22 +08:00
parent 6c8ecc8296
commit 17f5a6ac9d
6 changed files with 95 additions and 53 deletions

View File

@ -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();
}

View File

@ -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) {};

View File

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

View File

@ -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 {

View File

@ -19,25 +19,30 @@ import 'package:styled_widget/styled_widget.dart';
import 'widget/trash_header.dart';
class TrashStackContext extends HomeStackContext {
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
@override
String get identifier => "TrashStackContext";
@override
List<Object?> 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<NavigationItem> get navigationItems => [this];
@override
ValueNotifier<bool> get isUpdated => _isUpdated;
@override
void dispose() {}
}
class TrashStackPage extends StatefulWidget {

View File

@ -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 {