소스 검색

config navigation widget

appflowy 3 년 전
부모
커밋
23ac4d0249

+ 42 - 27
app_flowy/lib/workspace/domain/page_stack/page_stack.dart

@@ -1,57 +1,72 @@
-import 'package:app_flowy/workspace/domain/page_stack/page_stack_bloc.dart';
-import 'package:app_flowy/workspace/presentation/doc/doc_page.dart';
 import 'package:equatable/equatable.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'package:app_flowy/workspace/presentation/doc/doc_page.dart';
 import 'package:app_flowy/workspace/presentation/widgets/blank_page.dart';
 import 'package:app_flowy/workspace/presentation/widgets/fading_index_stack.dart';
 import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
 
 abstract class HomeStackView extends Equatable {
   final ViewType type;
   final String title;
-  const HomeStackView({required this.type, required this.title});
+  final String identifier;
+  const HomeStackView(
+      {required this.type, required this.title, required this.identifier});
+}
+
+class PageStackNotifier extends ChangeNotifier {
+  HomeStackView? innerView;
+
+  PageStackNotifier({
+    this.innerView,
+  });
+
+  set view(HomeStackView view) {
+    innerView = view;
+    notifyListeners();
+  }
+
+  HomeStackView get view {
+    return innerView ?? const AnnouncementStackView();
+  }
 }
 
 // HomePageStack is initialized as singleton to controll the page stack.
 class HomePageStack {
-  final PageStackBloc _bloc = PageStackBloc();
+  final PageStackNotifier _notifier = PageStackNotifier();
   HomePageStack();
 
   String title() {
-    return _bloc.state.stackView.title;
+    return _notifier.view.title;
   }
 
   void setStackView(HomeStackView? stackView) {
-    _bloc.add(PageStackEvent.setStackView(
-        stackView ?? const AnnouncementStackView()));
+    _notifier.view = stackView ?? const AnnouncementStackView();
   }
 
   Widget stackTopBar() {
-    return BlocProvider<PageStackBloc>(
-      create: (context) => _bloc,
-      child: BlocBuilder<PageStackBloc, PageStackState>(
-        builder: (context, state) {
-          return HomeTopBar(
-            view: state.stackView,
-          );
-        },
-      ),
+    return MultiProvider(
+      providers: [
+        ChangeNotifierProvider(create: (_) => _notifier),
+      ],
+      child: Consumer(builder: (ctx, PageStackNotifier notifier, child) {
+        return HomeTopBar(view: notifier.view);
+      }),
     );
   }
 
   Widget stackWidget() {
-    return BlocProvider<PageStackBloc>(
-      create: (context) => _bloc,
-      child: BlocBuilder<PageStackBloc, PageStackState>(
-        builder: (context, state) {
-          return FadingIndexedStack(
-            index: pages.indexOf(state.stackView.type),
-            children: _buildStackWidget(state.stackView),
-          );
-        },
-      ),
+    return MultiProvider(
+      providers: [
+        ChangeNotifierProvider(create: (_) => _notifier),
+      ],
+      child: Consumer(builder: (ctx, PageStackNotifier notifier, child) {
+        return FadingIndexedStack(
+          index: pages.indexOf(notifier.view.type),
+          children: _buildStackWidget(notifier.view),
+        );
+      }),
     );
   }
 }

+ 0 - 35
app_flowy/lib/workspace/domain/page_stack/page_stack_bloc.dart

@@ -1,35 +0,0 @@
-import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
-import 'package:app_flowy/workspace/presentation/widgets/blank_page.dart';
-import 'package:freezed_annotation/freezed_annotation.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-part 'page_stack_bloc.freezed.dart';
-
-class PageStackBloc extends Bloc<PageStackEvent, PageStackState> {
-  PageStackBloc() : super(PageStackState.initial());
-
-  @override
-  Stream<PageStackState> mapEventToState(
-    PageStackEvent event,
-  ) async* {
-    yield* event.map(setStackView: (NewPageContext value) async* {
-      yield state.copyWith(stackView: value.newStackView);
-    });
-  }
-}
-
-@freezed
-abstract class PageStackEvent with _$PageStackEvent {
-  const factory PageStackEvent.setStackView(HomeStackView newStackView) =
-      NewPageContext;
-}
-
-@freezed
-abstract class PageStackState implements _$PageStackState {
-  const factory PageStackState({
-    required HomeStackView stackView,
-  }) = _PageStackState;
-
-  factory PageStackState.initial() => const PageStackState(
-        stackView: AnnouncementStackView(),
-      );
-}

+ 0 - 337
app_flowy/lib/workspace/domain/page_stack/page_stack_bloc.freezed.dart

@@ -1,337 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
-
-part of 'page_stack_bloc.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity<T>(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
-    'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
-
-/// @nodoc
-class _$PageStackEventTearOff {
-  const _$PageStackEventTearOff();
-
-  NewPageContext setStackView(HomeStackView newStackView) {
-    return NewPageContext(
-      newStackView,
-    );
-  }
-}
-
-/// @nodoc
-const $PageStackEvent = _$PageStackEventTearOff();
-
-/// @nodoc
-mixin _$PageStackEvent {
-  HomeStackView get newStackView => throw _privateConstructorUsedError;
-
-  @optionalTypeArgs
-  TResult when<TResult extends Object?>({
-    required TResult Function(HomeStackView newStackView) setStackView,
-  }) =>
-      throw _privateConstructorUsedError;
-  @optionalTypeArgs
-  TResult maybeWhen<TResult extends Object?>({
-    TResult Function(HomeStackView newStackView)? setStackView,
-    required TResult orElse(),
-  }) =>
-      throw _privateConstructorUsedError;
-  @optionalTypeArgs
-  TResult map<TResult extends Object?>({
-    required TResult Function(NewPageContext value) setStackView,
-  }) =>
-      throw _privateConstructorUsedError;
-  @optionalTypeArgs
-  TResult maybeMap<TResult extends Object?>({
-    TResult Function(NewPageContext value)? setStackView,
-    required TResult orElse(),
-  }) =>
-      throw _privateConstructorUsedError;
-
-  @JsonKey(ignore: true)
-  $PageStackEventCopyWith<PageStackEvent> get copyWith =>
-      throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $PageStackEventCopyWith<$Res> {
-  factory $PageStackEventCopyWith(
-          PageStackEvent value, $Res Function(PageStackEvent) then) =
-      _$PageStackEventCopyWithImpl<$Res>;
-  $Res call({HomeStackView newStackView});
-}
-
-/// @nodoc
-class _$PageStackEventCopyWithImpl<$Res>
-    implements $PageStackEventCopyWith<$Res> {
-  _$PageStackEventCopyWithImpl(this._value, this._then);
-
-  final PageStackEvent _value;
-  // ignore: unused_field
-  final $Res Function(PageStackEvent) _then;
-
-  @override
-  $Res call({
-    Object? newStackView = freezed,
-  }) {
-    return _then(_value.copyWith(
-      newStackView: newStackView == freezed
-          ? _value.newStackView
-          : newStackView // ignore: cast_nullable_to_non_nullable
-              as HomeStackView,
-    ));
-  }
-}
-
-/// @nodoc
-abstract class $NewPageContextCopyWith<$Res>
-    implements $PageStackEventCopyWith<$Res> {
-  factory $NewPageContextCopyWith(
-          NewPageContext value, $Res Function(NewPageContext) then) =
-      _$NewPageContextCopyWithImpl<$Res>;
-  @override
-  $Res call({HomeStackView newStackView});
-}
-
-/// @nodoc
-class _$NewPageContextCopyWithImpl<$Res>
-    extends _$PageStackEventCopyWithImpl<$Res>
-    implements $NewPageContextCopyWith<$Res> {
-  _$NewPageContextCopyWithImpl(
-      NewPageContext _value, $Res Function(NewPageContext) _then)
-      : super(_value, (v) => _then(v as NewPageContext));
-
-  @override
-  NewPageContext get _value => super._value as NewPageContext;
-
-  @override
-  $Res call({
-    Object? newStackView = freezed,
-  }) {
-    return _then(NewPageContext(
-      newStackView == freezed
-          ? _value.newStackView
-          : newStackView // ignore: cast_nullable_to_non_nullable
-              as HomeStackView,
-    ));
-  }
-}
-
-/// @nodoc
-
-class _$NewPageContext implements NewPageContext {
-  const _$NewPageContext(this.newStackView);
-
-  @override
-  final HomeStackView newStackView;
-
-  @override
-  String toString() {
-    return 'PageStackEvent.setStackView(newStackView: $newStackView)';
-  }
-
-  @override
-  bool operator ==(dynamic other) {
-    return identical(this, other) ||
-        (other is NewPageContext &&
-            (identical(other.newStackView, newStackView) ||
-                const DeepCollectionEquality()
-                    .equals(other.newStackView, newStackView)));
-  }
-
-  @override
-  int get hashCode =>
-      runtimeType.hashCode ^ const DeepCollectionEquality().hash(newStackView);
-
-  @JsonKey(ignore: true)
-  @override
-  $NewPageContextCopyWith<NewPageContext> get copyWith =>
-      _$NewPageContextCopyWithImpl<NewPageContext>(this, _$identity);
-
-  @override
-  @optionalTypeArgs
-  TResult when<TResult extends Object?>({
-    required TResult Function(HomeStackView newStackView) setStackView,
-  }) {
-    return setStackView(newStackView);
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult maybeWhen<TResult extends Object?>({
-    TResult Function(HomeStackView newStackView)? setStackView,
-    required TResult orElse(),
-  }) {
-    if (setStackView != null) {
-      return setStackView(newStackView);
-    }
-    return orElse();
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult map<TResult extends Object?>({
-    required TResult Function(NewPageContext value) setStackView,
-  }) {
-    return setStackView(this);
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult maybeMap<TResult extends Object?>({
-    TResult Function(NewPageContext value)? setStackView,
-    required TResult orElse(),
-  }) {
-    if (setStackView != null) {
-      return setStackView(this);
-    }
-    return orElse();
-  }
-}
-
-abstract class NewPageContext implements PageStackEvent {
-  const factory NewPageContext(HomeStackView newStackView) = _$NewPageContext;
-
-  @override
-  HomeStackView get newStackView => throw _privateConstructorUsedError;
-  @override
-  @JsonKey(ignore: true)
-  $NewPageContextCopyWith<NewPageContext> get copyWith =>
-      throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-class _$PageStackStateTearOff {
-  const _$PageStackStateTearOff();
-
-  _PageStackState call({required HomeStackView stackView}) {
-    return _PageStackState(
-      stackView: stackView,
-    );
-  }
-}
-
-/// @nodoc
-const $PageStackState = _$PageStackStateTearOff();
-
-/// @nodoc
-mixin _$PageStackState {
-  HomeStackView get stackView => throw _privateConstructorUsedError;
-
-  @JsonKey(ignore: true)
-  $PageStackStateCopyWith<PageStackState> get copyWith =>
-      throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $PageStackStateCopyWith<$Res> {
-  factory $PageStackStateCopyWith(
-          PageStackState value, $Res Function(PageStackState) then) =
-      _$PageStackStateCopyWithImpl<$Res>;
-  $Res call({HomeStackView stackView});
-}
-
-/// @nodoc
-class _$PageStackStateCopyWithImpl<$Res>
-    implements $PageStackStateCopyWith<$Res> {
-  _$PageStackStateCopyWithImpl(this._value, this._then);
-
-  final PageStackState _value;
-  // ignore: unused_field
-  final $Res Function(PageStackState) _then;
-
-  @override
-  $Res call({
-    Object? stackView = freezed,
-  }) {
-    return _then(_value.copyWith(
-      stackView: stackView == freezed
-          ? _value.stackView
-          : stackView // ignore: cast_nullable_to_non_nullable
-              as HomeStackView,
-    ));
-  }
-}
-
-/// @nodoc
-abstract class _$PageStackStateCopyWith<$Res>
-    implements $PageStackStateCopyWith<$Res> {
-  factory _$PageStackStateCopyWith(
-          _PageStackState value, $Res Function(_PageStackState) then) =
-      __$PageStackStateCopyWithImpl<$Res>;
-  @override
-  $Res call({HomeStackView stackView});
-}
-
-/// @nodoc
-class __$PageStackStateCopyWithImpl<$Res>
-    extends _$PageStackStateCopyWithImpl<$Res>
-    implements _$PageStackStateCopyWith<$Res> {
-  __$PageStackStateCopyWithImpl(
-      _PageStackState _value, $Res Function(_PageStackState) _then)
-      : super(_value, (v) => _then(v as _PageStackState));
-
-  @override
-  _PageStackState get _value => super._value as _PageStackState;
-
-  @override
-  $Res call({
-    Object? stackView = freezed,
-  }) {
-    return _then(_PageStackState(
-      stackView: stackView == freezed
-          ? _value.stackView
-          : stackView // ignore: cast_nullable_to_non_nullable
-              as HomeStackView,
-    ));
-  }
-}
-
-/// @nodoc
-
-class _$_PageStackState implements _PageStackState {
-  const _$_PageStackState({required this.stackView});
-
-  @override
-  final HomeStackView stackView;
-
-  @override
-  String toString() {
-    return 'PageStackState(stackView: $stackView)';
-  }
-
-  @override
-  bool operator ==(dynamic other) {
-    return identical(this, other) ||
-        (other is _PageStackState &&
-            (identical(other.stackView, stackView) ||
-                const DeepCollectionEquality()
-                    .equals(other.stackView, stackView)));
-  }
-
-  @override
-  int get hashCode =>
-      runtimeType.hashCode ^ const DeepCollectionEquality().hash(stackView);
-
-  @JsonKey(ignore: true)
-  @override
-  _$PageStackStateCopyWith<_PageStackState> get copyWith =>
-      __$PageStackStateCopyWithImpl<_PageStackState>(this, _$identity);
-}
-
-abstract class _PageStackState implements PageStackState {
-  const factory _PageStackState({required HomeStackView stackView}) =
-      _$_PageStackState;
-
-  @override
-  HomeStackView get stackView => throw _privateConstructorUsedError;
-  @override
-  @JsonKey(ignore: true)
-  _$PageStackStateCopyWith<_PageStackState> get copyWith =>
-      throw _privateConstructorUsedError;
-}

+ 1 - 0
app_flowy/lib/workspace/presentation/doc/doc_page.dart

@@ -60,6 +60,7 @@ class DocPageStackView extends HomeStackView {
       : super(
           type: view.viewType,
           title: view.name,
+          identifier: view.id,
         );
 
   @override

+ 137 - 0
app_flowy/lib/workspace/presentation/home/navigation_list.dart

@@ -0,0 +1,137 @@
+import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/workspace/presentation/widgets/home_top_bar.dart';
+import 'package:flowy_infra_ui/style_widget/text.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();
+
+abstract class NaviItem {
+  String get identifier;
+  String get title;
+  NaviAction get action;
+}
+
+class NavigationNotifier extends ChangeNotifier {
+  PageStackNotifier pageStackNotifier;
+  NavigationNotifier(this.pageStackNotifier);
+
+  void update(PageStackNotifier notifier) {
+    pageStackNotifier = notifier;
+    notifyListeners();
+  }
+
+  List<NaviItem> get naviItems {
+    List<NaviItem> items = [
+      ViewNaviItemImpl(pageStackNotifier.view),
+      ViewNaviItemImpl(pageStackNotifier.view),
+      ViewNaviItemImpl(pageStackNotifier.view),
+      ViewNaviItemImpl(pageStackNotifier.view),
+      ViewNaviItemImpl(pageStackNotifier.view),
+      ViewNaviItemImpl(pageStackNotifier.view)
+    ];
+    return items;
+  }
+}
+
+class StyledNavigationList extends StatelessWidget {
+  const StyledNavigationList({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return ChangeNotifierProxyProvider<PageStackNotifier, NavigationNotifier>(
+      create: (_) => NavigationNotifier(
+        Provider.of<PageStackNotifier>(
+          context,
+          listen: false,
+        ),
+      ),
+      update: (_, notifier, controller) => controller!..update(notifier),
+      child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
+        return Row(children: _renderChildren(notifier.naviItems));
+      }),
+    );
+  }
+
+  List<Widget> _renderChildren(List<NaviItem> items) {
+    if (items.isEmpty) {
+      return [];
+    }
+
+    List<NaviItem> newItems = _filter(items);
+    Widget last = NaviItemWidget(newItems.removeLast());
+
+    List<Widget> widgets = List.empty(growable: true);
+    widgets.addAll(newItems
+        .map((item) => NaviItemDivider(child: NaviItemWidget(item)))
+        .toList());
+    widgets.add(last);
+
+    return widgets;
+  }
+
+  List<NaviItem> _filter(List<NaviItem> items) {
+    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;
+    }
+  }
+}
+
+class NaviItemWidget extends StatelessWidget {
+  final NaviItem item;
+  const NaviItemWidget(this.item, {Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return SizedBox(
+      height: 30,
+      child: FlowyTextButton(
+        item.title,
+        fontSize: 14,
+        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 NaviItem {
+  final List<NaviItem> items;
+  EllipsisNaviItem({
+    required this.items,
+  });
+
+  @override
+  NaviAction get action => throw UnimplementedError();
+
+  @override
+  String get identifier => "Ellipsis";
+
+  @override
+  String get title => "...";
+}

+ 1 - 1
app_flowy/lib/workspace/presentation/widgets/blank_page.dart

@@ -3,7 +3,7 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flutter/material.dart';
 
 class AnnouncementStackView extends HomeStackView {
-  const AnnouncementStackView() : super(type: ViewType.Blank, title: 'Blank');
+  const AnnouncementStackView() : super(type: ViewType.Blank, title: 'Blank', identifier: "Announcement");
 
   @override
   List<Object> get props => [];

+ 24 - 5
app_flowy/lib/workspace/presentation/widgets/home_top_bar.dart

@@ -1,12 +1,14 @@
+import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/workspace/domain/image.dart';
 import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
+import 'package:app_flowy/workspace/presentation/home/navigation_list.dart';
 import 'package:flowy_infra_ui/widget/rounded_button.dart';
 import 'package:flowy_infra_ui/widget/spacing.dart';
+import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pbenum.dart';
 import 'package:flutter/material.dart';
 import 'package:flowy_infra_ui/style_widget/icon_button.dart';
-// import 'package:flowy_infra_ui/style_widget/styled_navigation_list.dart';
 import 'package:flowy_infra_ui/style_widget/extension.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 
@@ -21,13 +23,15 @@ class HomeTopBar extends StatelessWidget {
       child: Row(
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
-          HomeTitle(title: view.title, type: view.type),
+          _renderNavigationList(view),
           const Spacer(),
           _renderShareButton(),
           _renderMoreButton(),
         ],
       )
-          .padding(horizontal: HomeInsets.topBarTitlePadding)
+          .padding(
+            horizontal: HomeInsets.topBarTitlePadding,
+          )
           .bottomBorder(color: Colors.grey.shade300),
     );
   }
@@ -55,8 +59,8 @@ class HomeTopBar extends StatelessWidget {
     );
   }
 
-  Widget _renderNavigationList() {
-    return Container();
+  Widget _renderNavigationList(HomeStackView view) {
+    return const StyledNavigationList();
   }
 }
 
@@ -87,3 +91,18 @@ class HomeTitle extends StatelessWidget {
     );
   }
 }
+
+class ViewNaviItemImpl extends NaviItem {
+  final HomeStackView view;
+
+  ViewNaviItemImpl(this.view);
+
+  @override
+  NaviAction get action => () => getIt<HomePageStack>().setStackView(view);
+
+  @override
+  String get identifier => view.identifier;
+
+  @override
+  String get title => view.title;
+}

+ 0 - 104
app_flowy/packages/flowy_infra_ui/lib/style_widget/navigation_list.dart

@@ -1,104 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-
-typedef NaviAction = void Function(String);
-
-abstract class NaviItem {
-  String get identifier;
-  NaviAction get action;
-}
-
-class StyledNavigationController extends ChangeNotifier {
-  List<NaviItem> naviItems;
-  StyledNavigationController({this.naviItems = const []});
-}
-
-class StyledNavigationList extends StatelessWidget {
-  const StyledNavigationList({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return MultiProvider(
-      providers: [
-        ChangeNotifierProvider(create: (_) => StyledNavigationController()),
-      ],
-      child: Consumer(builder: (ctx, StyledNavigationController ctrl, child) {
-        return Row(
-          children: _buildNaviItemWidget(ctrl.naviItems),
-        );
-      }),
-    );
-  }
-
-  List<Widget> _buildNaviItemWidget(List<NaviItem> items) {
-    if (items.isEmpty) {
-      return [];
-    }
-
-    List<NaviItem> newItems = _filter(items);
-    Widget last = NaviItemWidget(newItems.removeLast());
-
-    List<Widget> widgets = newItems
-        .map((item) => NaviItemDivider(child: NaviItemWidget(item)))
-        .toList();
-
-    widgets.add(last);
-
-    return widgets;
-  }
-
-  List<NaviItem> _filter(List<NaviItem> items) {
-    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;
-    }
-  }
-}
-
-class NaviItemWidget extends StatelessWidget {
-  final NaviItem item;
-  const NaviItemWidget(this.item, {Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      child: null,
-    );
-  }
-}
-
-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('/')],
-    );
-  }
-}
-
-class EllipsisNaviItem extends NaviItem {
-  final List<NaviItem> items;
-  EllipsisNaviItem({
-    required this.items,
-  });
-
-  @override
-  // TODO: implement action
-  NaviAction get action => throw UnimplementedError();
-
-  @override
-  // TODO: implement identifier
-  String get identifier => throw UnimplementedError();
-}