page_stack.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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> with NavigationItem {
  23. List<NavigationItem> get navigationItems;
  24. @override
  25. Widget get naviTitle;
  26. @override
  27. String get identifier;
  28. ValueNotifier<T> get isUpdated;
  29. HomeStackType get type;
  30. Widget buildWidget();
  31. void dispose();
  32. }
  33. class HomeStackNotifier extends ChangeNotifier {
  34. HomeStackContext stackContext;
  35. PublishNotifier<bool> collapsedNotifier = PublishNotifier();
  36. Widget get titleWidget => stackContext.naviTitle;
  37. HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
  38. set context(HomeStackContext context) {
  39. stackContext.isUpdated.removeListener(notifyListeners);
  40. stackContext.dispose();
  41. stackContext = context;
  42. stackContext.isUpdated.addListener(notifyListeners);
  43. notifyListeners();
  44. }
  45. HomeStackContext get context => stackContext;
  46. }
  47. // HomeStack is initialized as singleton to controll the page stack.
  48. class HomeStackManager {
  49. final HomeStackNotifier _notifier = HomeStackNotifier();
  50. HomeStackManager();
  51. Widget title() {
  52. return _notifier.context.naviTitle;
  53. }
  54. PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
  55. void switchStack(HomeStackContext context) {
  56. _notifier.context = context;
  57. }
  58. void setStackWithId(String id) {}
  59. Widget stackTopBar() {
  60. return MultiProvider(
  61. providers: [
  62. ChangeNotifierProvider.value(value: _notifier),
  63. ],
  64. child: Selector<HomeStackNotifier, Widget>(
  65. selector: (context, notifier) => notifier.titleWidget,
  66. builder: (context, widget, child) {
  67. return const HomeTopBar();
  68. },
  69. ),
  70. );
  71. }
  72. Widget stackWidget() {
  73. return MultiProvider(
  74. providers: [
  75. ChangeNotifierProvider.value(value: _notifier),
  76. ],
  77. child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
  78. return FadingIndexedStack(
  79. index: pages.indexOf(notifier.context.type),
  80. children: HomeStackType.values.map((viewType) {
  81. if (viewType == notifier.context.type) {
  82. return notifier.context.buildWidget();
  83. } else {
  84. return const BlankStackPage();
  85. }
  86. }).toList(),
  87. );
  88. }),
  89. );
  90. }
  91. }