mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: update home page topbar title after the view name changed
This commit is contained in:
parent
6c8ecc8296
commit
17f5a6ac9d
@ -9,7 +9,7 @@ import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
|
|||||||
typedef NavigationCallback = void Function(String id);
|
typedef NavigationCallback = void Function(String id);
|
||||||
|
|
||||||
abstract class NavigationItem {
|
abstract class NavigationItem {
|
||||||
Widget get titleWidget;
|
Widget get naviTitle;
|
||||||
String get identifier;
|
String get identifier;
|
||||||
|
|
||||||
NavigationCallback get action => (id) {
|
NavigationCallback get action => (id) {
|
||||||
@ -25,30 +25,44 @@ enum HomeStackType {
|
|||||||
|
|
||||||
List<HomeStackType> pages = HomeStackType.values.toList();
|
List<HomeStackType> pages = HomeStackType.values.toList();
|
||||||
|
|
||||||
abstract class HomeStackContext extends Equatable with NavigationItem {
|
abstract class HomeStackContext<T> with NavigationItem {
|
||||||
List<NavigationItem> get navigationItems;
|
List<NavigationItem> get navigationItems;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget get titleWidget;
|
Widget get naviTitle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get identifier;
|
String get identifier;
|
||||||
|
|
||||||
|
ValueNotifier<T> get isUpdated;
|
||||||
|
|
||||||
HomeStackType get type;
|
HomeStackType get type;
|
||||||
|
|
||||||
Widget render();
|
Widget buildWidget();
|
||||||
|
|
||||||
|
void dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeStackNotifier extends ChangeNotifier {
|
class HomeStackNotifier extends ChangeNotifier {
|
||||||
HomeStackContext inner;
|
HomeStackContext stackContext;
|
||||||
HomeStackNotifier({HomeStackContext? context}) : inner = context ?? BlankStackContext();
|
Widget get titleWidget => stackContext.naviTitle;
|
||||||
|
|
||||||
|
HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
|
||||||
|
|
||||||
set context(HomeStackContext context) {
|
set context(HomeStackContext context) {
|
||||||
inner = context;
|
notifyChange() {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
stackContext.isUpdated.removeListener(notifyChange);
|
||||||
|
stackContext.dispose();
|
||||||
|
|
||||||
|
stackContext = context;
|
||||||
|
stackContext.isUpdated.addListener(notifyChange);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
HomeStackContext get context => inner;
|
HomeStackContext get context => stackContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HomeStack is initialized as singleton to controll the page stack.
|
// HomeStack is initialized as singleton to controll the page stack.
|
||||||
@ -57,7 +71,7 @@ class HomeStackManager {
|
|||||||
HomeStackManager();
|
HomeStackManager();
|
||||||
|
|
||||||
Widget title() {
|
Widget title() {
|
||||||
return _notifier.context.titleWidget;
|
return _notifier.context.naviTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStack(HomeStackContext context) {
|
void setStack(HomeStackContext context) {
|
||||||
@ -71,9 +85,12 @@ class HomeStackManager {
|
|||||||
providers: [
|
providers: [
|
||||||
ChangeNotifierProvider.value(value: _notifier),
|
ChangeNotifierProvider.value(value: _notifier),
|
||||||
],
|
],
|
||||||
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
|
child: Selector<HomeStackNotifier, Widget>(
|
||||||
return HomeTopBar(view: notifier.context);
|
selector: (context, notifier) => notifier.titleWidget,
|
||||||
}),
|
builder: (context, widget, child) {
|
||||||
|
return const HomeTopBar();
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +104,7 @@ class HomeStackManager {
|
|||||||
index: pages.indexOf(notifier.context.type),
|
index: pages.indexOf(notifier.context.type),
|
||||||
children: HomeStackType.values.map((viewType) {
|
children: HomeStackType.values.map((viewType) {
|
||||||
if (viewType == notifier.context.type) {
|
if (viewType == notifier.context.type) {
|
||||||
return notifier.context.render();
|
return notifier.context.buildWidget();
|
||||||
} else {
|
} else {
|
||||||
return const BlankStackPage();
|
return const BlankStackPage();
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,13 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
typedef NaviAction = void Function();
|
typedef NaviAction = void Function();
|
||||||
|
|
||||||
class NavigationNotifier with ChangeNotifier {
|
class NavigationNotifier with ChangeNotifier {
|
||||||
HomeStackNotifier homeStackNotifier;
|
List<NavigationItem> navigationItems;
|
||||||
NavigationNotifier(this.homeStackNotifier);
|
NavigationNotifier({required this.navigationItems});
|
||||||
|
|
||||||
void update(HomeStackNotifier notifier) {
|
void update(HomeStackNotifier notifier) {
|
||||||
homeStackNotifier = notifier;
|
navigationItems = notifier.context.navigationItems;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<NavigationItem> get naviItems => homeStackNotifier.context.navigationItems;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [[diagram: HomeStack navigation flow]]
|
// [[diagram: HomeStack navigation flow]]
|
||||||
@ -45,12 +43,15 @@ class FlowyNavigation extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
|
return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
|
||||||
create: (_) => NavigationNotifier(
|
create: (_) {
|
||||||
Provider.of<HomeStackNotifier>(context, listen: false),
|
final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
|
||||||
),
|
return NavigationNotifier(
|
||||||
|
navigationItems: notifier.context.navigationItems,
|
||||||
|
);
|
||||||
|
},
|
||||||
update: (_, notifier, controller) => controller!..update(notifier),
|
update: (_, notifier, controller) => controller!..update(notifier),
|
||||||
child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
|
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(
|
return SizedBox(
|
||||||
height: 24,
|
height: 24,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: item.titleWidget,
|
child: item.naviTitle,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
debugPrint('show app document');
|
debugPrint('show app document');
|
||||||
},
|
},
|
||||||
@ -114,7 +115,7 @@ class NaviItemWidget extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 24,
|
height: 24,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: item.titleWidget,
|
child: item.naviTitle,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
debugPrint('show app document');
|
debugPrint('show app document');
|
||||||
},
|
},
|
||||||
@ -142,7 +143,7 @@ class EllipsisNaviItem extends NavigationItem {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget get titleWidget => const FlowyText.medium('...');
|
Widget get naviTitle => const FlowyText.medium('...');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
NavigationCallback get action => (id) {};
|
NavigationCallback get action => (id) {};
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.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';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class BlankStackContext extends HomeStackContext {
|
class BlankStackContext extends HomeStackContext {
|
||||||
|
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get identifier => "1";
|
String get identifier => "1";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => ["1"];
|
Widget get naviTitle => const FlowyText.medium('Blank page', fontSize: 12);
|
||||||
|
|
||||||
@override
|
|
||||||
Widget get titleWidget => const FlowyText.medium('Blank page', fontSize: 12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HomeStackType get type => HomeStackType.blank;
|
HomeStackType get type => HomeStackType.blank;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget render() {
|
Widget buildWidget() {
|
||||||
return const BlankStackPage();
|
return const BlankStackPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<NavigationItem> get navigationItems => [this];
|
List<NavigationItem> get navigationItems => [this];
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValueNotifier<bool> get isUpdated => _isUpdated;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlankStackPage extends StatefulWidget {
|
class BlankStackPage extends StatefulWidget {
|
||||||
|
@ -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/page_stack/page_stack.dart';
|
||||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -7,36 +9,55 @@ import 'package:flutter/material.dart';
|
|||||||
import 'doc_page.dart';
|
import 'doc_page.dart';
|
||||||
|
|
||||||
class DocStackContext extends HomeStackContext {
|
class DocStackContext extends HomeStackContext {
|
||||||
final View _view;
|
View _view;
|
||||||
DocStackContext({required View view, Key? key}) : _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
|
@override
|
||||||
Widget get titleWidget => FlowyText.medium(_view.name, fontSize: 12);
|
Widget get naviTitle => FlowyText.medium(_view.name, fontSize: 12);
|
||||||
@override
|
@override
|
||||||
String get identifier => _view.id;
|
String get identifier => _view.id;
|
||||||
@override
|
@override
|
||||||
HomeStackType get type => _view.stackType();
|
HomeStackType get type => _view.stackType();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [_view.id];
|
Widget buildWidget() {
|
||||||
|
|
||||||
@override
|
|
||||||
Widget render() {
|
|
||||||
return DocStackPage(_view, key: ValueKey(_view.id));
|
return DocStackPage(_view, key: ValueKey(_view.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<NavigationItem> get navigationItems => makeNavigationItems();
|
List<NavigationItem> get navigationItems => _makeNavigationItems();
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValueNotifier<String> get isUpdated => _isUpdated;
|
||||||
|
|
||||||
// List<NavigationItem> get navigationItems => naviStacks.map((stack) {
|
// List<NavigationItem> get navigationItems => naviStacks.map((stack) {
|
||||||
// return NavigationItemImpl(context: stack);
|
// return NavigationItemImpl(context: stack);
|
||||||
// }).toList();
|
// }).toList();
|
||||||
|
|
||||||
List<NavigationItem> makeNavigationItems() {
|
List<NavigationItem> _makeNavigationItems() {
|
||||||
return [
|
return [
|
||||||
this,
|
this,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_listener.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocStackPage extends StatefulWidget {
|
class DocStackPage extends StatefulWidget {
|
||||||
|
@ -19,25 +19,30 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
import 'widget/trash_header.dart';
|
import 'widget/trash_header.dart';
|
||||||
|
|
||||||
class TrashStackContext extends HomeStackContext {
|
class TrashStackContext extends HomeStackContext {
|
||||||
|
final ValueNotifier<bool> _isUpdated = ValueNotifier<bool>(false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get identifier => "TrashStackContext";
|
String get identifier => "TrashStackContext";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => ["TrashStackContext"];
|
Widget get naviTitle => const FlowyText.medium('Trash', fontSize: 12);
|
||||||
|
|
||||||
@override
|
|
||||||
Widget get titleWidget => const FlowyText.medium('Trash', fontSize: 12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HomeStackType get type => HomeStackType.trash;
|
HomeStackType get type => HomeStackType.trash;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget render() {
|
Widget buildWidget() {
|
||||||
return const TrashStackPage(key: ValueKey('TrashStackPage'));
|
return const TrashStackPage(key: ValueKey('TrashStackPage'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<NavigationItem> get navigationItems => [this];
|
List<NavigationItem> get navigationItems => [this];
|
||||||
|
|
||||||
|
@override
|
||||||
|
ValueNotifier<bool> get isUpdated => _isUpdated;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrashStackPage extends StatefulWidget {
|
class TrashStackPage extends StatefulWidget {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:app_flowy/workspace/domain/image.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';
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
|
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
|
||||||
import 'package:flowy_infra/size.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';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
|
|
||||||
class HomeTopBar extends StatelessWidget {
|
class HomeTopBar extends StatelessWidget {
|
||||||
final HomeStackContext view;
|
const HomeTopBar({Key? key}) : super(key: key);
|
||||||
const HomeTopBar({Key? key, required this.view}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -22,7 +20,7 @@ class HomeTopBar extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
_renderNavigation(view),
|
const FlowyNavigation(),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
_renderShareButton(),
|
_renderShareButton(),
|
||||||
// _renderMoreButton(),
|
// _renderMoreButton(),
|
||||||
@ -48,10 +46,6 @@ class HomeTopBar extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderNavigation(HomeStackContext view) {
|
|
||||||
return const FlowyNavigation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeTitle extends StatelessWidget {
|
class HomeTitle extends StatelessWidget {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user