page_stack.dart 3.1 KB

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