page_stack.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import 'package:equatable/equatable.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. Widget get titleWidget => stackContext.naviTitle;
  36. HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
  37. set context(HomeStackContext context) {
  38. notifyChange() {
  39. notifyListeners();
  40. }
  41. stackContext.isUpdated.removeListener(notifyChange);
  42. stackContext.dispose();
  43. stackContext = context;
  44. stackContext.isUpdated.addListener(notifyChange);
  45. notifyListeners();
  46. }
  47. HomeStackContext get context => stackContext;
  48. }
  49. // HomeStack is initialized as singleton to controll the page stack.
  50. class HomeStackManager {
  51. final HomeStackNotifier _notifier = HomeStackNotifier();
  52. HomeStackManager();
  53. Widget title() {
  54. return _notifier.context.naviTitle;
  55. }
  56. void setStack(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. }