page_stack.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import 'package:app_flowy/startup/startup.dart';
  4. import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
  5. import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
  6. import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
  7. typedef NavigationCallback = void Function(String id);
  8. abstract class NavigationItem {
  9. Widget get naviTitle;
  10. String get identifier;
  11. NavigationCallback get action => (id) {
  12. getIt<HomeStackManager>().setStackWithId(id);
  13. };
  14. }
  15. enum HomeStackType {
  16. blank,
  17. doc,
  18. trash,
  19. }
  20. List<HomeStackType> pages = HomeStackType.values.toList();
  21. abstract class HomeStackContext<T> with NavigationItem {
  22. List<NavigationItem> get navigationItems;
  23. @override
  24. Widget get naviTitle;
  25. @override
  26. String get identifier;
  27. ValueNotifier<T> get isUpdated;
  28. HomeStackType get type;
  29. Widget buildWidget();
  30. void dispose();
  31. }
  32. class HomeStackNotifier extends ChangeNotifier {
  33. HomeStackContext stackContext;
  34. Widget get titleWidget => stackContext.naviTitle;
  35. HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
  36. set context(HomeStackContext context) {
  37. notifyChange() {
  38. notifyListeners();
  39. }
  40. stackContext.isUpdated.removeListener(notifyChange);
  41. stackContext.dispose();
  42. stackContext = context;
  43. stackContext.isUpdated.addListener(notifyChange);
  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. void setStack(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. }