page_stack.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import 'package:flowy_infra/notifier.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:provider/provider.dart';
  4. import 'package:app_flowy/startup/startup.dart';
  5. import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
  6. import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
  7. import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
  8. typedef NavigationCallback = void Function(String id);
  9. abstract class NavigationItem {
  10. Widget get naviTitle;
  11. String get identifier;
  12. NavigationCallback get action => (id) {
  13. getIt<HomeStackManager>().setStackWithId(id);
  14. };
  15. }
  16. enum HomeStackType {
  17. blank,
  18. doc,
  19. trash,
  20. }
  21. List<HomeStackType> pages = HomeStackType.values.toList();
  22. abstract class HomeStackContext<T, S> with NavigationItem {
  23. List<NavigationItem> get navigationItems;
  24. @override
  25. Widget get naviTitle;
  26. Widget? Function(BuildContext context) get buildNavigationActions;
  27. @override
  28. String get identifier;
  29. ValueNotifier<T> get isUpdated;
  30. HomeStackType get type;
  31. Widget buildWidget();
  32. void dispose();
  33. }
  34. class HomeStackNotifier extends ChangeNotifier {
  35. HomeStackContext stackContext;
  36. PublishNotifier<bool> collapsedNotifier = PublishNotifier();
  37. Widget get titleWidget => stackContext.naviTitle;
  38. HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
  39. set context(HomeStackContext context) {
  40. stackContext.isUpdated.removeListener(notifyListeners);
  41. stackContext.dispose();
  42. stackContext = context;
  43. stackContext.isUpdated.addListener(notifyListeners);
  44. notifyListeners();
  45. }
  46. HomeStackContext get context => stackContext;
  47. }
  48. // HomeStack is initialized as singleton to controll the page stack.
  49. class HomeStackManager {
  50. final HomeStackNotifier _notifier = HomeStackNotifier();
  51. HomeStackManager();
  52. Widget title() {
  53. return _notifier.context.naviTitle;
  54. }
  55. PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
  56. void switchStack(HomeStackContext context) {
  57. _notifier.context = context;
  58. }
  59. void setStackWithId(String id) {}
  60. Widget stackTopBar() {
  61. return MultiProvider(
  62. providers: [
  63. ChangeNotifierProvider.value(value: _notifier),
  64. ],
  65. child: Selector<HomeStackNotifier, Widget>(
  66. selector: (context, notifier) => notifier.titleWidget,
  67. builder: (context, widget, child) {
  68. return const HomeTopBar();
  69. },
  70. ),
  71. );
  72. }
  73. Widget stackWidget() {
  74. return MultiProvider(
  75. providers: [
  76. ChangeNotifierProvider.value(value: _notifier),
  77. ],
  78. child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
  79. return FadingIndexedStack(
  80. index: pages.indexOf(notifier.context.type),
  81. children: HomeStackType.values.map((viewType) {
  82. if (viewType == notifier.context.type) {
  83. return notifier.context.buildWidget();
  84. } else {
  85. return const BlankStackPage();
  86. }
  87. }).toList(),
  88. );
  89. }),
  90. );
  91. }
  92. }