156 lines
5.4 KiB
Dart
Raw Normal View History

2021-07-28 18:19:16 +08:00
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:flowy_infra_ui/style_widget/text_button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
typedef NaviAction = void Function();
class NavigationNotifier with ChangeNotifier {
HomeStackNotifier homeStackNotifier;
NavigationNotifier(this.homeStackNotifier);
2021-07-28 18:19:16 +08:00
2021-10-10 15:58:57 +08:00
void update(HomeStackNotifier notifier) {
homeStackNotifier = notifier;
2021-07-28 18:19:16 +08:00
notifyListeners();
}
List<NavigationItem> get naviItems => homeStackNotifier.context.navigationItems;
2021-07-28 18:19:16 +08:00
}
// [[Navigation]]
// ┌───────────────────────┐
// 2.notify listeners ┌──────│DefaultHomeStackContext│
// ┌────────────────┐ ┌───────────┐ ┌────────────────┐ │ └───────────────────────┘
// │HomeStackNotifie│◀──────────│ HomeStack │◀──│HomeStackContext│◀─ impl
// └────────────────┘ └───────────┘ └────────────────┘ │ ┌───────────────────┐
// │ ▲ └───────│ DocStackContext │
// │ │ └───────────────────┘
// 3.notify change 1.set context
// │ │
// ▼ │
// ┌───────────────────┐ ┌──────────────────┐
// │NavigationNotifier │ │ ViewSectionItem │
// └───────────────────┘ └──────────────────┘
// │
// │
// ▼
// ┌─────────────────┐
// │ FlowyNavigation │ 4.render navigation items
// └─────────────────┘
2021-10-10 15:58:57 +08:00
class FlowyNavigation extends StatelessWidget {
const FlowyNavigation({Key? key}) : super(key: key);
2021-07-28 18:19:16 +08:00
@override
Widget build(BuildContext context) {
2021-10-10 15:58:57 +08:00
return ChangeNotifierProxyProvider<HomeStackNotifier, NavigationNotifier>(
2021-07-28 18:19:16 +08:00
create: (_) => NavigationNotifier(
Provider.of<HomeStackNotifier>(context, listen: false),
2021-07-28 18:19:16 +08:00
),
update: (_, notifier, controller) => controller!..update(notifier),
child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
return Row(children: _renderChildren(notifier.naviItems));
}),
);
}
List<Widget> _renderChildren(List<NavigationItem> items) {
2021-07-28 18:19:16 +08:00
if (items.isEmpty) {
return [];
}
List<NavigationItem> newItems = _filter(items);
2021-07-28 18:19:16 +08:00
Widget last = NaviItemWidget(newItems.removeLast());
List<Widget> widgets = List.empty(growable: true);
2021-10-10 15:58:57 +08:00
widgets.addAll(newItems.map((item) => NaviItemDivider(child: NaviItemWidget(item))).toList());
2021-07-28 18:19:16 +08:00
widgets.add(last);
return widgets;
}
List<NavigationItem> _filter(List<NavigationItem> items) {
2021-07-28 18:19:16 +08:00
final length = items.length;
if (length > 4) {
final first = items[0];
final ellipsisItems = items.getRange(1, length - 2).toList();
final last = items.getRange(length - 2, length).toList();
return [
first,
EllipsisNaviItem(items: ellipsisItems),
...last,
];
} else {
return items;
}
}
}
2021-10-11 09:05:53 +08:00
class IconNaviItemWidget extends StatelessWidget {
final NavigationItem item;
const IconNaviItemWidget(this.item, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 24,
child: FlowyTextButton(
item.title,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
fontSize: 12,
onPressed: () {
debugPrint('show app document');
},
),
);
}
}
2021-07-28 18:19:16 +08:00
class NaviItemWidget extends StatelessWidget {
final NavigationItem item;
2021-07-28 18:19:16 +08:00
const NaviItemWidget(this.item, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 24,
2021-07-28 18:19:16 +08:00
child: FlowyTextButton(
item.title,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
fontSize: 12,
2021-07-28 18:19:16 +08:00
onPressed: () {
debugPrint('show app document');
},
),
);
}
}
class NaviItemDivider extends StatelessWidget {
final Widget child;
const NaviItemDivider({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
children: [child, const Text('/').padding(horizontal: 2)],
);
}
}
class EllipsisNaviItem extends NavigationItem {
final List<NavigationItem> items;
2021-07-28 18:19:16 +08:00
EllipsisNaviItem({
required this.items,
});
@override
String get title => "...";
2021-07-28 18:19:16 +08:00
@override
NavigationCallback get action => (id) {};
2021-07-28 18:19:16 +08:00
@override
String get identifier => "Ellipsis";
2021-07-28 18:19:16 +08:00
}