navigation.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
  2. import 'package:app_flowy/workspace/presentation/widgets/home_top_bar.dart';
  3. import 'package:flowy_infra_ui/style_widget/text_button.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:provider/provider.dart';
  6. import 'package:styled_widget/styled_widget.dart';
  7. typedef NaviAction = void Function();
  8. abstract class NaviItem {
  9. String get identifier;
  10. String get title;
  11. NaviAction get action;
  12. }
  13. class NavigationNotifier with ChangeNotifier {
  14. HomeStackNotifier pageStackNotifier;
  15. NavigationNotifier(this.pageStackNotifier);
  16. void update(HomeStackNotifier notifier) {
  17. pageStackNotifier = notifier;
  18. notifyListeners();
  19. }
  20. List<NaviItem> get naviItems {
  21. List<NaviItem> items = [
  22. ViewNaviItemImpl(pageStackNotifier.context),
  23. // ViewNaviItemImpl(pageStackNotifier.view),
  24. // ViewNaviItemImpl(pageStackNotifier.view),
  25. // ViewNaviItemImpl(pageStackNotifier.view),
  26. // ViewNaviItemImpl(pageStackNotifier.view),
  27. // ViewNaviItemImpl(pageStackNotifier.view)
  28. ];
  29. return items;
  30. }
  31. }
  32. class FlowyNavigation extends StatelessWidget {
  33. const FlowyNavigation({Key? key}) : super(key: key);
  34. @override
  35. Widget build(BuildContext context) {
  36. return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
  37. create: (_) => NavigationNotifier(
  38. Provider.of<HomeStackNotifier>(
  39. context,
  40. listen: false,
  41. ),
  42. ),
  43. update: (_, notifier, controller) => controller!..update(notifier),
  44. child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
  45. return Row(children: _renderChildren(notifier.naviItems));
  46. }),
  47. );
  48. }
  49. List<Widget> _renderChildren(List<NaviItem> items) {
  50. if (items.isEmpty) {
  51. return [];
  52. }
  53. List<NaviItem> newItems = _filter(items);
  54. Widget last = NaviItemWidget(newItems.removeLast());
  55. List<Widget> widgets = List.empty(growable: true);
  56. widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList());
  57. widgets.add(last);
  58. return widgets;
  59. }
  60. List<NaviItem> _filter(List<NaviItem> items) {
  61. final length = items.length;
  62. if (length > 4) {
  63. final first = items[0];
  64. final ellipsisItems = items.getRange(1, length - 2).toList();
  65. final last = items.getRange(length - 2, length).toList();
  66. return [
  67. first,
  68. EllipsisNaviItem(items: ellipsisItems),
  69. ...last,
  70. ];
  71. } else {
  72. return items;
  73. }
  74. }
  75. }
  76. class NaviItemWidget extends StatelessWidget {
  77. final NaviItem item;
  78. const NaviItemWidget(this.item, {Key? key}) : super(key: key);
  79. @override
  80. Widget build(BuildContext context) {
  81. return SizedBox(
  82. height: 30,
  83. child: FlowyTextButton(
  84. item.title,
  85. fontSize: 14,
  86. onPressed: () {
  87. debugPrint('show app document');
  88. },
  89. ),
  90. );
  91. }
  92. }
  93. class NaviItemDivider extends StatelessWidget {
  94. final Widget child;
  95. const NaviItemDivider({Key? key, required this.child}) : super(key: key);
  96. @override
  97. Widget build(BuildContext context) {
  98. return Row(
  99. children: [child, const Text('/').padding(horizontal: 2)],
  100. );
  101. }
  102. }
  103. class EllipsisNaviItem extends NaviItem {
  104. final List<NaviItem> items;
  105. EllipsisNaviItem({
  106. required this.items,
  107. });
  108. @override
  109. NaviAction get action => throw UnimplementedError();
  110. @override
  111. String get identifier => "Ellipsis";
  112. @override
  113. String get title => "...";
  114. }