Browse Source

extract FadingIndexStack into HomePageStack

appflowy 3 years ago
parent
commit
0bd768415e

+ 21 - 2
app_flowy/lib/home/application/edit_pannel/edit_pannel_bloc.dart

@@ -5,8 +5,6 @@ import 'package:freezed_annotation/freezed_annotation.dart';
 // ignore: import_of_legacy_library_into_null_safe
 import 'package:flutter_bloc/flutter_bloc.dart';
 
-part 'edit_pannel_event.dart';
-part 'edit_pannel_state.dart';
 part 'edit_pannel_bloc.freezed.dart';
 
 class EditPannelBloc extends Bloc<EditPannelEvent, EditPannelState> {
@@ -26,3 +24,24 @@ class EditPannelBloc extends Bloc<EditPannelEvent, EditPannelState> {
     );
   }
 }
+
+@freezed
+abstract class EditPannelEvent with _$EditPannelEvent {
+  const factory EditPannelEvent.startEdit(EditPannelContext context) =
+      _StartEdit;
+
+  const factory EditPannelEvent.endEdit(EditPannelContext context) = _EndEdit;
+}
+
+@freezed
+abstract class EditPannelState implements _$EditPannelState {
+  const factory EditPannelState({
+    required bool isEditing,
+    required Option<EditPannelContext> editContext,
+  }) = _EditPannelState;
+
+  factory EditPannelState.initial() => EditPannelState(
+        isEditing: false,
+        editContext: none(),
+      );
+}

+ 0 - 9
app_flowy/lib/home/application/edit_pannel/edit_pannel_event.dart

@@ -1,9 +0,0 @@
-part of 'edit_pannel_bloc.dart';
-
-@freezed
-abstract class EditPannelEvent with _$EditPannelEvent {
-  const factory EditPannelEvent.startEdit(EditPannelContext context) =
-      _StartEdit;
-
-  const factory EditPannelEvent.endEdit(EditPannelContext context) = _EndEdit;
-}

+ 0 - 14
app_flowy/lib/home/application/edit_pannel/edit_pannel_state.dart

@@ -1,14 +0,0 @@
-part of 'edit_pannel_bloc.dart';
-
-@freezed
-abstract class EditPannelState implements _$EditPannelState {
-  const factory EditPannelState({
-    required bool isEditing,
-    required Option<EditPannelContext> editContext,
-  }) = _EditPannelState;
-
-  factory EditPannelState.initial() => EditPannelState(
-        isEditing: false,
-        editContext: none(),
-      );
-}

+ 0 - 12
app_flowy/lib/home/application/home_bloc.dart

@@ -1,6 +1,4 @@
 import 'package:app_flowy/home/domain/edit_context.dart';
-import 'package:app_flowy/home/domain/page_context.dart';
-import 'package:app_flowy/home/presentation/widgets/blank_page.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'package:dartz/dartz.dart';
@@ -14,9 +12,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
     HomeEvent event,
   ) async* {
     yield* event.map(
-      setPage: (e) async* {
-        yield state.copyWith(pageContext: e.context);
-      },
       showLoading: (e) async* {
         yield state.copyWith(isLoading: e.isLoading);
       },
@@ -42,11 +37,6 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
 abstract class HomeEvent with _$HomeEvent {
   const factory HomeEvent.showLoading(bool isLoading) = _ShowLoading;
   const factory HomeEvent.forceCollapse(bool forceCollapse) = _ForceCollapse;
-
-  //page
-  const factory HomeEvent.setPage(PageContext context) = SetCurrentPage;
-
-  //edit pannel
   const factory HomeEvent.setEditPannel(EditPannelContext editContext) =
       _ShowEditPannel;
   const factory HomeEvent.dismissEditPannel() = _DismissEditPannel;
@@ -57,14 +47,12 @@ abstract class HomeState implements _$HomeState {
   const factory HomeState({
     required bool isLoading,
     required bool forceCollapse,
-    required PageContext pageContext,
     required Option<EditPannelContext> editContext,
   }) = _HomeState;
 
   factory HomeState.initial() => HomeState(
         isLoading: false,
         forceCollapse: false,
-        pageContext: const BlankPageContext(),
         editContext: none(),
       );
 }

+ 1 - 179
app_flowy/lib/home/application/home_bloc.freezed.dart

@@ -28,12 +28,6 @@ class _$HomeEventTearOff {
     );
   }
 
-  SetCurrentPage setPage(PageContext context) {
-    return SetCurrentPage(
-      context,
-    );
-  }
-
   _ShowEditPannel setEditPannel(EditPannelContext editContext) {
     return _ShowEditPannel(
       editContext,
@@ -54,7 +48,6 @@ mixin _$HomeEvent {
   TResult when<TResult extends Object?>({
     required TResult Function(bool isLoading) showLoading,
     required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
     required TResult Function(EditPannelContext editContext) setEditPannel,
     required TResult Function() dismissEditPannel,
   }) =>
@@ -63,7 +56,6 @@ mixin _$HomeEvent {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(bool isLoading)? showLoading,
     TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
     TResult Function(EditPannelContext editContext)? setEditPannel,
     TResult Function()? dismissEditPannel,
     required TResult orElse(),
@@ -73,7 +65,6 @@ mixin _$HomeEvent {
   TResult map<TResult extends Object?>({
     required TResult Function(_ShowLoading value) showLoading,
     required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
     required TResult Function(_ShowEditPannel value) setEditPannel,
     required TResult Function(_DismissEditPannel value) dismissEditPannel,
   }) =>
@@ -82,7 +73,6 @@ mixin _$HomeEvent {
   TResult maybeMap<TResult extends Object?>({
     TResult Function(_ShowLoading value)? showLoading,
     TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
     TResult Function(_ShowEditPannel value)? setEditPannel,
     TResult Function(_DismissEditPannel value)? dismissEditPannel,
     required TResult orElse(),
@@ -172,7 +162,6 @@ class _$_ShowLoading implements _ShowLoading {
   TResult when<TResult extends Object?>({
     required TResult Function(bool isLoading) showLoading,
     required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
     required TResult Function(EditPannelContext editContext) setEditPannel,
     required TResult Function() dismissEditPannel,
   }) {
@@ -184,7 +173,6 @@ class _$_ShowLoading implements _ShowLoading {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(bool isLoading)? showLoading,
     TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
     TResult Function(EditPannelContext editContext)? setEditPannel,
     TResult Function()? dismissEditPannel,
     required TResult orElse(),
@@ -200,7 +188,6 @@ class _$_ShowLoading implements _ShowLoading {
   TResult map<TResult extends Object?>({
     required TResult Function(_ShowLoading value) showLoading,
     required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
     required TResult Function(_ShowEditPannel value) setEditPannel,
     required TResult Function(_DismissEditPannel value) dismissEditPannel,
   }) {
@@ -212,7 +199,6 @@ class _$_ShowLoading implements _ShowLoading {
   TResult maybeMap<TResult extends Object?>({
     TResult Function(_ShowLoading value)? showLoading,
     TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
     TResult Function(_ShowEditPannel value)? setEditPannel,
     TResult Function(_DismissEditPannel value)? dismissEditPannel,
     required TResult orElse(),
@@ -300,7 +286,6 @@ class _$_ForceCollapse implements _ForceCollapse {
   TResult when<TResult extends Object?>({
     required TResult Function(bool isLoading) showLoading,
     required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
     required TResult Function(EditPannelContext editContext) setEditPannel,
     required TResult Function() dismissEditPannel,
   }) {
@@ -312,7 +297,6 @@ class _$_ForceCollapse implements _ForceCollapse {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(bool isLoading)? showLoading,
     TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
     TResult Function(EditPannelContext editContext)? setEditPannel,
     TResult Function()? dismissEditPannel,
     required TResult orElse(),
@@ -328,7 +312,6 @@ class _$_ForceCollapse implements _ForceCollapse {
   TResult map<TResult extends Object?>({
     required TResult Function(_ShowLoading value) showLoading,
     required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
     required TResult Function(_ShowEditPannel value) setEditPannel,
     required TResult Function(_DismissEditPannel value) dismissEditPannel,
   }) {
@@ -340,7 +323,6 @@ class _$_ForceCollapse implements _ForceCollapse {
   TResult maybeMap<TResult extends Object?>({
     TResult Function(_ShowLoading value)? showLoading,
     TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
     TResult Function(_ShowEditPannel value)? setEditPannel,
     TResult Function(_DismissEditPannel value)? dismissEditPannel,
     required TResult orElse(),
@@ -361,133 +343,6 @@ abstract class _ForceCollapse implements HomeEvent {
       throw _privateConstructorUsedError;
 }
 
-/// @nodoc
-abstract class $SetCurrentPageCopyWith<$Res> {
-  factory $SetCurrentPageCopyWith(
-          SetCurrentPage value, $Res Function(SetCurrentPage) then) =
-      _$SetCurrentPageCopyWithImpl<$Res>;
-  $Res call({PageContext context});
-}
-
-/// @nodoc
-class _$SetCurrentPageCopyWithImpl<$Res> extends _$HomeEventCopyWithImpl<$Res>
-    implements $SetCurrentPageCopyWith<$Res> {
-  _$SetCurrentPageCopyWithImpl(
-      SetCurrentPage _value, $Res Function(SetCurrentPage) _then)
-      : super(_value, (v) => _then(v as SetCurrentPage));
-
-  @override
-  SetCurrentPage get _value => super._value as SetCurrentPage;
-
-  @override
-  $Res call({
-    Object? context = freezed,
-  }) {
-    return _then(SetCurrentPage(
-      context == freezed
-          ? _value.context
-          : context // ignore: cast_nullable_to_non_nullable
-              as PageContext,
-    ));
-  }
-}
-
-/// @nodoc
-
-class _$SetCurrentPage implements SetCurrentPage {
-  const _$SetCurrentPage(this.context);
-
-  @override
-  final PageContext context;
-
-  @override
-  String toString() {
-    return 'HomeEvent.setPage(context: $context)';
-  }
-
-  @override
-  bool operator ==(dynamic other) {
-    return identical(this, other) ||
-        (other is SetCurrentPage &&
-            (identical(other.context, context) ||
-                const DeepCollectionEquality().equals(other.context, context)));
-  }
-
-  @override
-  int get hashCode =>
-      runtimeType.hashCode ^ const DeepCollectionEquality().hash(context);
-
-  @JsonKey(ignore: true)
-  @override
-  $SetCurrentPageCopyWith<SetCurrentPage> get copyWith =>
-      _$SetCurrentPageCopyWithImpl<SetCurrentPage>(this, _$identity);
-
-  @override
-  @optionalTypeArgs
-  TResult when<TResult extends Object?>({
-    required TResult Function(bool isLoading) showLoading,
-    required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
-    required TResult Function(EditPannelContext editContext) setEditPannel,
-    required TResult Function() dismissEditPannel,
-  }) {
-    return setPage(context);
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult maybeWhen<TResult extends Object?>({
-    TResult Function(bool isLoading)? showLoading,
-    TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
-    TResult Function(EditPannelContext editContext)? setEditPannel,
-    TResult Function()? dismissEditPannel,
-    required TResult orElse(),
-  }) {
-    if (setPage != null) {
-      return setPage(context);
-    }
-    return orElse();
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult map<TResult extends Object?>({
-    required TResult Function(_ShowLoading value) showLoading,
-    required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
-    required TResult Function(_ShowEditPannel value) setEditPannel,
-    required TResult Function(_DismissEditPannel value) dismissEditPannel,
-  }) {
-    return setPage(this);
-  }
-
-  @override
-  @optionalTypeArgs
-  TResult maybeMap<TResult extends Object?>({
-    TResult Function(_ShowLoading value)? showLoading,
-    TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
-    TResult Function(_ShowEditPannel value)? setEditPannel,
-    TResult Function(_DismissEditPannel value)? dismissEditPannel,
-    required TResult orElse(),
-  }) {
-    if (setPage != null) {
-      return setPage(this);
-    }
-    return orElse();
-  }
-}
-
-abstract class SetCurrentPage implements HomeEvent {
-  const factory SetCurrentPage(PageContext context) = _$SetCurrentPage;
-
-  PageContext get context => throw _privateConstructorUsedError;
-  @JsonKey(ignore: true)
-  $SetCurrentPageCopyWith<SetCurrentPage> get copyWith =>
-      throw _privateConstructorUsedError;
-}
-
 /// @nodoc
 abstract class _$ShowEditPannelCopyWith<$Res> {
   factory _$ShowEditPannelCopyWith(
@@ -555,7 +410,6 @@ class _$_ShowEditPannel implements _ShowEditPannel {
   TResult when<TResult extends Object?>({
     required TResult Function(bool isLoading) showLoading,
     required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
     required TResult Function(EditPannelContext editContext) setEditPannel,
     required TResult Function() dismissEditPannel,
   }) {
@@ -567,7 +421,6 @@ class _$_ShowEditPannel implements _ShowEditPannel {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(bool isLoading)? showLoading,
     TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
     TResult Function(EditPannelContext editContext)? setEditPannel,
     TResult Function()? dismissEditPannel,
     required TResult orElse(),
@@ -583,7 +436,6 @@ class _$_ShowEditPannel implements _ShowEditPannel {
   TResult map<TResult extends Object?>({
     required TResult Function(_ShowLoading value) showLoading,
     required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
     required TResult Function(_ShowEditPannel value) setEditPannel,
     required TResult Function(_DismissEditPannel value) dismissEditPannel,
   }) {
@@ -595,7 +447,6 @@ class _$_ShowEditPannel implements _ShowEditPannel {
   TResult maybeMap<TResult extends Object?>({
     TResult Function(_ShowLoading value)? showLoading,
     TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
     TResult Function(_ShowEditPannel value)? setEditPannel,
     TResult Function(_DismissEditPannel value)? dismissEditPannel,
     required TResult orElse(),
@@ -659,7 +510,6 @@ class _$_DismissEditPannel implements _DismissEditPannel {
   TResult when<TResult extends Object?>({
     required TResult Function(bool isLoading) showLoading,
     required TResult Function(bool forceCollapse) forceCollapse,
-    required TResult Function(PageContext context) setPage,
     required TResult Function(EditPannelContext editContext) setEditPannel,
     required TResult Function() dismissEditPannel,
   }) {
@@ -671,7 +521,6 @@ class _$_DismissEditPannel implements _DismissEditPannel {
   TResult maybeWhen<TResult extends Object?>({
     TResult Function(bool isLoading)? showLoading,
     TResult Function(bool forceCollapse)? forceCollapse,
-    TResult Function(PageContext context)? setPage,
     TResult Function(EditPannelContext editContext)? setEditPannel,
     TResult Function()? dismissEditPannel,
     required TResult orElse(),
@@ -687,7 +536,6 @@ class _$_DismissEditPannel implements _DismissEditPannel {
   TResult map<TResult extends Object?>({
     required TResult Function(_ShowLoading value) showLoading,
     required TResult Function(_ForceCollapse value) forceCollapse,
-    required TResult Function(SetCurrentPage value) setPage,
     required TResult Function(_ShowEditPannel value) setEditPannel,
     required TResult Function(_DismissEditPannel value) dismissEditPannel,
   }) {
@@ -699,7 +547,6 @@ class _$_DismissEditPannel implements _DismissEditPannel {
   TResult maybeMap<TResult extends Object?>({
     TResult Function(_ShowLoading value)? showLoading,
     TResult Function(_ForceCollapse value)? forceCollapse,
-    TResult Function(SetCurrentPage value)? setPage,
     TResult Function(_ShowEditPannel value)? setEditPannel,
     TResult Function(_DismissEditPannel value)? dismissEditPannel,
     required TResult orElse(),
@@ -722,12 +569,10 @@ class _$HomeStateTearOff {
   _HomeState call(
       {required bool isLoading,
       required bool forceCollapse,
-      required PageContext pageContext,
       required Option<EditPannelContext> editContext}) {
     return _HomeState(
       isLoading: isLoading,
       forceCollapse: forceCollapse,
-      pageContext: pageContext,
       editContext: editContext,
     );
   }
@@ -740,7 +585,6 @@ const $HomeState = _$HomeStateTearOff();
 mixin _$HomeState {
   bool get isLoading => throw _privateConstructorUsedError;
   bool get forceCollapse => throw _privateConstructorUsedError;
-  PageContext get pageContext => throw _privateConstructorUsedError;
   Option<EditPannelContext> get editContext =>
       throw _privateConstructorUsedError;
 
@@ -756,7 +600,6 @@ abstract class $HomeStateCopyWith<$Res> {
   $Res call(
       {bool isLoading,
       bool forceCollapse,
-      PageContext pageContext,
       Option<EditPannelContext> editContext});
 }
 
@@ -772,7 +615,6 @@ class _$HomeStateCopyWithImpl<$Res> implements $HomeStateCopyWith<$Res> {
   $Res call({
     Object? isLoading = freezed,
     Object? forceCollapse = freezed,
-    Object? pageContext = freezed,
     Object? editContext = freezed,
   }) {
     return _then(_value.copyWith(
@@ -784,10 +626,6 @@ class _$HomeStateCopyWithImpl<$Res> implements $HomeStateCopyWith<$Res> {
           ? _value.forceCollapse
           : forceCollapse // ignore: cast_nullable_to_non_nullable
               as bool,
-      pageContext: pageContext == freezed
-          ? _value.pageContext
-          : pageContext // ignore: cast_nullable_to_non_nullable
-              as PageContext,
       editContext: editContext == freezed
           ? _value.editContext
           : editContext // ignore: cast_nullable_to_non_nullable
@@ -805,7 +643,6 @@ abstract class _$HomeStateCopyWith<$Res> implements $HomeStateCopyWith<$Res> {
   $Res call(
       {bool isLoading,
       bool forceCollapse,
-      PageContext pageContext,
       Option<EditPannelContext> editContext});
 }
 
@@ -822,7 +659,6 @@ class __$HomeStateCopyWithImpl<$Res> extends _$HomeStateCopyWithImpl<$Res>
   $Res call({
     Object? isLoading = freezed,
     Object? forceCollapse = freezed,
-    Object? pageContext = freezed,
     Object? editContext = freezed,
   }) {
     return _then(_HomeState(
@@ -834,10 +670,6 @@ class __$HomeStateCopyWithImpl<$Res> extends _$HomeStateCopyWithImpl<$Res>
           ? _value.forceCollapse
           : forceCollapse // ignore: cast_nullable_to_non_nullable
               as bool,
-      pageContext: pageContext == freezed
-          ? _value.pageContext
-          : pageContext // ignore: cast_nullable_to_non_nullable
-              as PageContext,
       editContext: editContext == freezed
           ? _value.editContext
           : editContext // ignore: cast_nullable_to_non_nullable
@@ -852,7 +684,6 @@ class _$_HomeState implements _HomeState {
   const _$_HomeState(
       {required this.isLoading,
       required this.forceCollapse,
-      required this.pageContext,
       required this.editContext});
 
   @override
@@ -860,13 +691,11 @@ class _$_HomeState implements _HomeState {
   @override
   final bool forceCollapse;
   @override
-  final PageContext pageContext;
-  @override
   final Option<EditPannelContext> editContext;
 
   @override
   String toString() {
-    return 'HomeState(isLoading: $isLoading, forceCollapse: $forceCollapse, pageContext: $pageContext, editContext: $editContext)';
+    return 'HomeState(isLoading: $isLoading, forceCollapse: $forceCollapse, editContext: $editContext)';
   }
 
   @override
@@ -879,9 +708,6 @@ class _$_HomeState implements _HomeState {
             (identical(other.forceCollapse, forceCollapse) ||
                 const DeepCollectionEquality()
                     .equals(other.forceCollapse, forceCollapse)) &&
-            (identical(other.pageContext, pageContext) ||
-                const DeepCollectionEquality()
-                    .equals(other.pageContext, pageContext)) &&
             (identical(other.editContext, editContext) ||
                 const DeepCollectionEquality()
                     .equals(other.editContext, editContext)));
@@ -892,7 +718,6 @@ class _$_HomeState implements _HomeState {
       runtimeType.hashCode ^
       const DeepCollectionEquality().hash(isLoading) ^
       const DeepCollectionEquality().hash(forceCollapse) ^
-      const DeepCollectionEquality().hash(pageContext) ^
       const DeepCollectionEquality().hash(editContext);
 
   @JsonKey(ignore: true)
@@ -905,7 +730,6 @@ abstract class _HomeState implements HomeState {
   const factory _HomeState(
       {required bool isLoading,
       required bool forceCollapse,
-      required PageContext pageContext,
       required Option<EditPannelContext> editContext}) = _$_HomeState;
 
   @override
@@ -913,8 +737,6 @@ abstract class _HomeState implements HomeState {
   @override
   bool get forceCollapse => throw _privateConstructorUsedError;
   @override
-  PageContext get pageContext => throw _privateConstructorUsedError;
-  @override
   Option<EditPannelContext> get editContext =>
       throw _privateConstructorUsedError;
   @override

+ 3 - 4
app_flowy/lib/home/application/menu/menu_bloc.dart

@@ -1,6 +1,6 @@
 import 'dart:async';
 import 'package:app_flowy/home/domain/i_workspace.dart';
-import 'package:app_flowy/home/domain/page_context.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:dartz/dartz.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
 import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
@@ -36,7 +36,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
   }
 
   Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* {
-    yield state.copyWith(pageContext: some(e.context));
+    yield state.copyWith(pageContext: e.context);
   }
 
   Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
@@ -73,14 +73,13 @@ abstract class MenuEvent with _$MenuEvent {
 abstract class MenuState implements _$MenuState {
   const factory MenuState({
     required bool isCollapse,
-    required Option<PageContext> pageContext,
     required Option<List<App>> apps,
     required Either<Unit, WorkspaceError> successOrFailure,
+    PageContext? pageContext,
   }) = _MenuState;
 
   factory MenuState.initial() => MenuState(
         isCollapse: false,
-        pageContext: none(),
         apps: none(),
         successOrFailure: left(unit),
       );

+ 33 - 33
app_flowy/lib/home/application/menu/menu_bloc.freezed.dart

@@ -536,14 +536,14 @@ class _$MenuStateTearOff {
 
   _MenuState call(
       {required bool isCollapse,
-      required Option<PageContext> pageContext,
       required Option<List<App>> apps,
-      required Either<Unit, WorkspaceError> successOrFailure}) {
+      required Either<Unit, WorkspaceError> successOrFailure,
+      PageContext? pageContext}) {
     return _MenuState(
       isCollapse: isCollapse,
-      pageContext: pageContext,
       apps: apps,
       successOrFailure: successOrFailure,
+      pageContext: pageContext,
     );
   }
 }
@@ -554,10 +554,10 @@ const $MenuState = _$MenuStateTearOff();
 /// @nodoc
 mixin _$MenuState {
   bool get isCollapse => throw _privateConstructorUsedError;
-  Option<PageContext> get pageContext => throw _privateConstructorUsedError;
   Option<List<App>> get apps => throw _privateConstructorUsedError;
   Either<Unit, WorkspaceError> get successOrFailure =>
       throw _privateConstructorUsedError;
+  PageContext? get pageContext => throw _privateConstructorUsedError;
 
   @JsonKey(ignore: true)
   $MenuStateCopyWith<MenuState> get copyWith =>
@@ -570,9 +570,9 @@ abstract class $MenuStateCopyWith<$Res> {
       _$MenuStateCopyWithImpl<$Res>;
   $Res call(
       {bool isCollapse,
-      Option<PageContext> pageContext,
       Option<List<App>> apps,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, WorkspaceError> successOrFailure,
+      PageContext? pageContext});
 }
 
 /// @nodoc
@@ -586,19 +586,15 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
   @override
   $Res call({
     Object? isCollapse = freezed,
-    Object? pageContext = freezed,
     Object? apps = freezed,
     Object? successOrFailure = freezed,
+    Object? pageContext = freezed,
   }) {
     return _then(_value.copyWith(
       isCollapse: isCollapse == freezed
           ? _value.isCollapse
           : isCollapse // ignore: cast_nullable_to_non_nullable
               as bool,
-      pageContext: pageContext == freezed
-          ? _value.pageContext
-          : pageContext // ignore: cast_nullable_to_non_nullable
-              as Option<PageContext>,
       apps: apps == freezed
           ? _value.apps
           : apps // ignore: cast_nullable_to_non_nullable
@@ -607,6 +603,10 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
               as Either<Unit, WorkspaceError>,
+      pageContext: pageContext == freezed
+          ? _value.pageContext
+          : pageContext // ignore: cast_nullable_to_non_nullable
+              as PageContext?,
     ));
   }
 }
@@ -619,9 +619,9 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
   @override
   $Res call(
       {bool isCollapse,
-      Option<PageContext> pageContext,
       Option<List<App>> apps,
-      Either<Unit, WorkspaceError> successOrFailure});
+      Either<Unit, WorkspaceError> successOrFailure,
+      PageContext? pageContext});
 }
 
 /// @nodoc
@@ -636,19 +636,15 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
   @override
   $Res call({
     Object? isCollapse = freezed,
-    Object? pageContext = freezed,
     Object? apps = freezed,
     Object? successOrFailure = freezed,
+    Object? pageContext = freezed,
   }) {
     return _then(_MenuState(
       isCollapse: isCollapse == freezed
           ? _value.isCollapse
           : isCollapse // ignore: cast_nullable_to_non_nullable
               as bool,
-      pageContext: pageContext == freezed
-          ? _value.pageContext
-          : pageContext // ignore: cast_nullable_to_non_nullable
-              as Option<PageContext>,
       apps: apps == freezed
           ? _value.apps
           : apps // ignore: cast_nullable_to_non_nullable
@@ -657,6 +653,10 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
           ? _value.successOrFailure
           : successOrFailure // ignore: cast_nullable_to_non_nullable
               as Either<Unit, WorkspaceError>,
+      pageContext: pageContext == freezed
+          ? _value.pageContext
+          : pageContext // ignore: cast_nullable_to_non_nullable
+              as PageContext?,
     ));
   }
 }
@@ -666,22 +666,22 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
 class _$_MenuState implements _MenuState {
   const _$_MenuState(
       {required this.isCollapse,
-      required this.pageContext,
       required this.apps,
-      required this.successOrFailure});
+      required this.successOrFailure,
+      this.pageContext});
 
   @override
   final bool isCollapse;
   @override
-  final Option<PageContext> pageContext;
-  @override
   final Option<List<App>> apps;
   @override
   final Either<Unit, WorkspaceError> successOrFailure;
+  @override
+  final PageContext? pageContext;
 
   @override
   String toString() {
-    return 'MenuState(isCollapse: $isCollapse, pageContext: $pageContext, apps: $apps, successOrFailure: $successOrFailure)';
+    return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, pageContext: $pageContext)';
   }
 
   @override
@@ -691,23 +691,23 @@ class _$_MenuState implements _MenuState {
             (identical(other.isCollapse, isCollapse) ||
                 const DeepCollectionEquality()
                     .equals(other.isCollapse, isCollapse)) &&
-            (identical(other.pageContext, pageContext) ||
-                const DeepCollectionEquality()
-                    .equals(other.pageContext, pageContext)) &&
             (identical(other.apps, apps) ||
                 const DeepCollectionEquality().equals(other.apps, apps)) &&
             (identical(other.successOrFailure, successOrFailure) ||
                 const DeepCollectionEquality()
-                    .equals(other.successOrFailure, successOrFailure)));
+                    .equals(other.successOrFailure, successOrFailure)) &&
+            (identical(other.pageContext, pageContext) ||
+                const DeepCollectionEquality()
+                    .equals(other.pageContext, pageContext)));
   }
 
   @override
   int get hashCode =>
       runtimeType.hashCode ^
       const DeepCollectionEquality().hash(isCollapse) ^
-      const DeepCollectionEquality().hash(pageContext) ^
       const DeepCollectionEquality().hash(apps) ^
-      const DeepCollectionEquality().hash(successOrFailure);
+      const DeepCollectionEquality().hash(successOrFailure) ^
+      const DeepCollectionEquality().hash(pageContext);
 
   @JsonKey(ignore: true)
   @override
@@ -718,20 +718,20 @@ class _$_MenuState implements _MenuState {
 abstract class _MenuState implements MenuState {
   const factory _MenuState(
       {required bool isCollapse,
-      required Option<PageContext> pageContext,
       required Option<List<App>> apps,
-      required Either<Unit, WorkspaceError> successOrFailure}) = _$_MenuState;
+      required Either<Unit, WorkspaceError> successOrFailure,
+      PageContext? pageContext}) = _$_MenuState;
 
   @override
   bool get isCollapse => throw _privateConstructorUsedError;
   @override
-  Option<PageContext> get pageContext => throw _privateConstructorUsedError;
-  @override
   Option<List<App>> get apps => throw _privateConstructorUsedError;
   @override
   Either<Unit, WorkspaceError> get successOrFailure =>
       throw _privateConstructorUsedError;
   @override
+  PageContext? get pageContext => throw _privateConstructorUsedError;
+  @override
   @JsonKey(ignore: true)
   _$MenuStateCopyWith<_MenuState> get copyWith =>
       throw _privateConstructorUsedError;

+ 0 - 0
app_flowy/lib/home/application/view/view_bloc.dart


+ 5 - 0
app_flowy/lib/home/domain/i_page_stack.dart

@@ -0,0 +1,5 @@
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
+
+abstract class IPageStack {
+  void setPageContext(PageContext context);
+}

+ 0 - 0
app_flowy/lib/home/domain/i_view.dart


+ 0 - 19
app_flowy/lib/home/domain/page_context.dart

@@ -1,19 +0,0 @@
-import 'package:equatable/equatable.dart';
-import 'package:flutter/material.dart';
-
-abstract class HomeStackPage extends StatefulWidget {
-  final PageContext pageContext;
-  const HomeStackPage({Key? key, required this.pageContext}) : super(key: key);
-}
-
-enum PageType {
-  blank,
-}
-
-List<PageType> pages = PageType.values.toList();
-
-abstract class PageContext extends Equatable {
-  final PageType pageType;
-  final String pageTitle;
-  const PageContext(this.pageType, {required this.pageTitle});
-}

+ 84 - 0
app_flowy/lib/home/domain/page_stack/page_stack.dart

@@ -0,0 +1,84 @@
+import 'package:app_flowy/home/domain/page_stack/page_stack_bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter/material.dart';
+import 'package:app_flowy/home/presentation/widgets/blank_page.dart';
+import 'package:app_flowy/home/presentation/widgets/fading_index_stack.dart';
+import 'package:app_flowy/home/presentation/widgets/prelude.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+List<PageType> pages = PageType.values.toList();
+enum PageType {
+  blank,
+}
+
+abstract class PageContext extends Equatable {
+  final PageType pageType;
+  final String pageTitle;
+  const PageContext(this.pageType, {required this.pageTitle});
+}
+
+class HomePageStack {
+  final PageStackBloc _bloc = PageStackBloc();
+  HomePageStack();
+
+  String title() {
+    return _bloc.state.pageContext.pageTitle;
+  }
+
+  void setPageContext(PageContext? newContext) {
+    _bloc
+        .add(PageStackEvent.setContext(newContext ?? const BlankPageContext()));
+  }
+
+  Widget stackTopBar() {
+    return BlocProvider<PageStackBloc>(
+      create: (context) => _bloc,
+      child: BlocBuilder<PageStackBloc, PageStackState>(
+        builder: (context, state) {
+          return HomeTopBar(
+            title: state.pageContext.pageTitle,
+          );
+        },
+      ),
+    );
+  }
+
+  Widget stackWidget() {
+    return BlocProvider<PageStackBloc>(
+      create: (context) => _bloc,
+      child: BlocBuilder<PageStackBloc, PageStackState>(
+        builder: (context, state) {
+          final pageContext = state.pageContext;
+          return FadingIndexedStack(
+            index: pages.indexOf(pageContext.pageType),
+            children: buildPagesWidget(pageContext),
+          );
+        },
+      ),
+    );
+  }
+}
+
+List<Widget> buildPagesWidget(PageContext pageContext) {
+  return PageType.values.map((pageType) {
+    if (pageType == pageContext.pageType) {
+      return pageType.builder(pageContext);
+    } else {
+      return const BlankPage(context: BlankPageContext());
+    }
+  }).toList();
+}
+
+extension PageTypeExtension on PageType {
+  HomeStackPage builder(PageContext context) {
+    switch (this) {
+      case PageType.blank:
+        return BlankPage(context: context);
+    }
+  }
+}
+
+abstract class HomeStackPage extends StatefulWidget {
+  final PageContext pageContext;
+  const HomeStackPage({Key? key, required this.pageContext}) : super(key: key);
+}

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

@@ -0,0 +1,35 @@
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
+import 'package:app_flowy/home/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(setContext: (NewPageContext value) async* {
+      yield state.copyWith(pageContext: value.newContext);
+    });
+  }
+}
+
+@freezed
+abstract class PageStackEvent with _$PageStackEvent {
+  const factory PageStackEvent.setContext(PageContext newContext) =
+      NewPageContext;
+}
+
+@freezed
+abstract class PageStackState implements _$PageStackState {
+  const factory PageStackState({
+    required PageContext pageContext,
+  }) = _PageStackState;
+
+  factory PageStackState.initial() => const PageStackState(
+        pageContext: BlankPageContext(),
+      );
+}

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

@@ -0,0 +1,337 @@
+// 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
+
+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 setContext(PageContext newContext) {
+    return NewPageContext(
+      newContext,
+    );
+  }
+}
+
+/// @nodoc
+const $PageStackEvent = _$PageStackEventTearOff();
+
+/// @nodoc
+mixin _$PageStackEvent {
+  PageContext get newContext => throw _privateConstructorUsedError;
+
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function(PageContext newContext) setContext,
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function(PageContext newContext)? setContext,
+    required TResult orElse(),
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(NewPageContext value) setContext,
+  }) =>
+      throw _privateConstructorUsedError;
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(NewPageContext value)? setContext,
+    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({PageContext newContext});
+}
+
+/// @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? newContext = freezed,
+  }) {
+    return _then(_value.copyWith(
+      newContext: newContext == freezed
+          ? _value.newContext
+          : newContext // ignore: cast_nullable_to_non_nullable
+              as PageContext,
+    ));
+  }
+}
+
+/// @nodoc
+abstract class $NewPageContextCopyWith<$Res>
+    implements $PageStackEventCopyWith<$Res> {
+  factory $NewPageContextCopyWith(
+          NewPageContext value, $Res Function(NewPageContext) then) =
+      _$NewPageContextCopyWithImpl<$Res>;
+  @override
+  $Res call({PageContext newContext});
+}
+
+/// @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? newContext = freezed,
+  }) {
+    return _then(NewPageContext(
+      newContext == freezed
+          ? _value.newContext
+          : newContext // ignore: cast_nullable_to_non_nullable
+              as PageContext,
+    ));
+  }
+}
+
+/// @nodoc
+
+class _$NewPageContext implements NewPageContext {
+  const _$NewPageContext(this.newContext);
+
+  @override
+  final PageContext newContext;
+
+  @override
+  String toString() {
+    return 'PageStackEvent.setContext(newContext: $newContext)';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) ||
+        (other is NewPageContext &&
+            (identical(other.newContext, newContext) ||
+                const DeepCollectionEquality()
+                    .equals(other.newContext, newContext)));
+  }
+
+  @override
+  int get hashCode =>
+      runtimeType.hashCode ^ const DeepCollectionEquality().hash(newContext);
+
+  @JsonKey(ignore: true)
+  @override
+  $NewPageContextCopyWith<NewPageContext> get copyWith =>
+      _$NewPageContextCopyWithImpl<NewPageContext>(this, _$identity);
+
+  @override
+  @optionalTypeArgs
+  TResult when<TResult extends Object?>({
+    required TResult Function(PageContext newContext) setContext,
+  }) {
+    return setContext(newContext);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeWhen<TResult extends Object?>({
+    TResult Function(PageContext newContext)? setContext,
+    required TResult orElse(),
+  }) {
+    if (setContext != null) {
+      return setContext(newContext);
+    }
+    return orElse();
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult map<TResult extends Object?>({
+    required TResult Function(NewPageContext value) setContext,
+  }) {
+    return setContext(this);
+  }
+
+  @override
+  @optionalTypeArgs
+  TResult maybeMap<TResult extends Object?>({
+    TResult Function(NewPageContext value)? setContext,
+    required TResult orElse(),
+  }) {
+    if (setContext != null) {
+      return setContext(this);
+    }
+    return orElse();
+  }
+}
+
+abstract class NewPageContext implements PageStackEvent {
+  const factory NewPageContext(PageContext newContext) = _$NewPageContext;
+
+  @override
+  PageContext get newContext => throw _privateConstructorUsedError;
+  @override
+  @JsonKey(ignore: true)
+  $NewPageContextCopyWith<NewPageContext> get copyWith =>
+      throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+class _$PageStackStateTearOff {
+  const _$PageStackStateTearOff();
+
+  _PageStackState call({required PageContext pageContext}) {
+    return _PageStackState(
+      pageContext: pageContext,
+    );
+  }
+}
+
+/// @nodoc
+const $PageStackState = _$PageStackStateTearOff();
+
+/// @nodoc
+mixin _$PageStackState {
+  PageContext get pageContext => 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({PageContext pageContext});
+}
+
+/// @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? pageContext = freezed,
+  }) {
+    return _then(_value.copyWith(
+      pageContext: pageContext == freezed
+          ? _value.pageContext
+          : pageContext // ignore: cast_nullable_to_non_nullable
+              as PageContext,
+    ));
+  }
+}
+
+/// @nodoc
+abstract class _$PageStackStateCopyWith<$Res>
+    implements $PageStackStateCopyWith<$Res> {
+  factory _$PageStackStateCopyWith(
+          _PageStackState value, $Res Function(_PageStackState) then) =
+      __$PageStackStateCopyWithImpl<$Res>;
+  @override
+  $Res call({PageContext pageContext});
+}
+
+/// @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? pageContext = freezed,
+  }) {
+    return _then(_PageStackState(
+      pageContext: pageContext == freezed
+          ? _value.pageContext
+          : pageContext // ignore: cast_nullable_to_non_nullable
+              as PageContext,
+    ));
+  }
+}
+
+/// @nodoc
+
+class _$_PageStackState implements _PageStackState {
+  const _$_PageStackState({required this.pageContext});
+
+  @override
+  final PageContext pageContext;
+
+  @override
+  String toString() {
+    return 'PageStackState(pageContext: $pageContext)';
+  }
+
+  @override
+  bool operator ==(dynamic other) {
+    return identical(this, other) ||
+        (other is _PageStackState &&
+            (identical(other.pageContext, pageContext) ||
+                const DeepCollectionEquality()
+                    .equals(other.pageContext, pageContext)));
+  }
+
+  @override
+  int get hashCode =>
+      runtimeType.hashCode ^ const DeepCollectionEquality().hash(pageContext);
+
+  @JsonKey(ignore: true)
+  @override
+  _$PageStackStateCopyWith<_PageStackState> get copyWith =>
+      __$PageStackStateCopyWithImpl<_PageStackState>(this, _$identity);
+}
+
+abstract class _PageStackState implements PageStackState {
+  const factory _PageStackState({required PageContext pageContext}) =
+      _$_PageStackState;
+
+  @override
+  PageContext get pageContext => throw _privateConstructorUsedError;
+  @override
+  @JsonKey(ignore: true)
+  _$PageStackStateCopyWith<_PageStackState> get copyWith =>
+      throw _privateConstructorUsedError;
+}

+ 4 - 0
app_flowy/lib/home/infrastructure/deps_resolver.dart

@@ -2,6 +2,7 @@ import 'package:app_flowy/home/application/app/app_bloc.dart';
 import 'package:app_flowy/home/application/app/app_watch_bloc.dart';
 import 'package:app_flowy/home/application/menu/menu_bloc.dart';
 import 'package:app_flowy/home/application/menu/menu_watch.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/home/infrastructure/i_app_impl.dart';
 import 'package:app_flowy/home/infrastructure/i_workspace_impl.dart';
 import 'package:app_flowy/home/infrastructure/repos/app_repo.dart';
@@ -10,6 +11,9 @@ import 'package:get_it/get_it.dart';
 
 class HomeDepsResolver {
   static Future<void> resolve(GetIt getIt) async {
+    //
+    getIt.registerLazySingleton<HomePageStack>(() => HomePageStack());
+
     //App
     getIt.registerFactoryParam<AppRepository, String, void>(
         (appId, _) => AppRepository(appId: appId));

+ 35 - 56
app_flowy/lib/home/presentation/home_screen.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/home/application/home_bloc.dart';
 import 'package:app_flowy/home/application/watcher/home_watcher_bloc.dart';
-import 'package:app_flowy/home/domain/page_context.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/home/presentation/widgets/prelude.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:flowy_infra/flowy_logger.dart';
@@ -11,7 +11,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:styled_widget/styled_widget.dart';
 
 import 'home_layout.dart';
-import 'widgets/fading_index_stack.dart';
 
 class HomeScreen extends StatelessWidget {
   static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
@@ -70,12 +69,7 @@ class HomeScreen extends StatelessWidget {
     final homeBloc = context.read<HomeBloc>();
     Widget homeMenu = HomeMenu(
       pageContextChanged: (pageContext) {
-        pageContext.fold(
-          () => homeBloc.add(const HomeEvent.setPage(BlankPageContext())),
-          (pageContext) {
-            homeBloc.add(HomeEvent.setPage(pageContext));
-          },
-        );
+        getIt<HomePageStack>().setPageContext(pageContext);
       },
       isCollapseChanged: (isCollapse) {
         homeBloc.add(HomeEvent.forceCollapse(isCollapse));
@@ -142,25 +136,6 @@ class HomeScreen extends StatelessWidget {
   }
 }
 
-extension PageTypeExtension on PageType {
-  HomeStackPage builder(PageContext context) {
-    switch (this) {
-      case PageType.blank:
-        return BlankPage(context: context);
-    }
-  }
-}
-
-List<Widget> buildPagesWidget(PageContext pageContext) {
-  return PageType.values.map((pageType) {
-    if (pageType == pageContext.pageType) {
-      return pageType.builder(pageContext);
-    } else {
-      return const BlankPage(context: BlankPageContext());
-    }
-  }).toList();
-}
-
 class HomePage extends StatelessWidget {
   static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
   // final Size size;
@@ -171,40 +146,44 @@ class HomePage extends StatelessWidget {
     Log.info('HomePage build');
     return Column(
       mainAxisAlignment: MainAxisAlignment.start,
-      children: const [
-        HomeTopBar(),
-        HomeIndexStack(),
-      ],
-    );
-  }
-}
-
-class HomeIndexStack extends StatelessWidget {
-  const HomeIndexStack({Key? key}) : super(key: key);
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<HomeBloc, HomeState>(
-      buildWhen: (p, c) {
-        if (p.pageContext != c.pageContext) {
-          Log.info(
-              'PageContext switch from ${p.pageContext.pageType} to ${c.pageContext.pageType}');
-        }
-        return p.pageContext != c.pageContext;
-      },
-      builder: (context, state) {
-        final pageContext = context.read<HomeBloc>().state.pageContext;
-        return Expanded(
+      children: [
+        getIt<HomePageStack>().stackTopBar(),
+        Expanded(
           child: Container(
             color: Colors.white,
             child: FocusTraversalGroup(
-              child: FadingIndexedStack(
-                index: pages.indexOf(pageContext.pageType),
-                children: buildPagesWidget(pageContext),
-              ),
+              child: getIt<HomePageStack>().stackWidget(),
             ),
           ),
-        );
-      },
+        ),
+      ],
     );
   }
 }
+
+// class HomeIndexStack extends StatelessWidget {
+//   const HomeIndexStack({Key? key}) : super(key: key);
+//   @override
+//   Widget build(BuildContext context) {
+//     return BlocBuilder<HomeBloc, HomeState>(
+//       buildWhen: (p, c) {
+//         if (p.pageContext != c.pageContext) {
+//           Log.info(
+//               'PageContext switch from ${p.pageContext.pageType} to ${c.pageContext.pageType}');
+//         }
+//         return p.pageContext != c.pageContext;
+//       },
+//       builder: (context, state) {
+//         final pageContext = context.read<HomeBloc>().state.pageContext;
+//         return Expanded(
+//           child: Container(
+//             color: Colors.white,
+//             child: FocusTraversalGroup(
+//               child: getIt<FlowyHomeIndexStack>().indexStack(pageContext),
+//             ),
+//           ),
+//         );
+//       },
+//     );
+//   }
+// }

+ 109 - 0
app_flowy/lib/home/presentation/widgets/app/view_list.dart

@@ -1 +1,110 @@
+import 'package:flowy_infra/flowy_logger.dart';
+import 'package:flowy_infra/size.dart';
+import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:styled_widget/styled_widget.dart';
 
+class ViewList extends StatelessWidget {
+  final List<View> views;
+  const ViewList(this.views, {Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    Log.info('ViewList build');
+    if (views.isEmpty) {
+      return const SizedBox(
+        height: 30,
+      );
+    } else {
+      return Column(
+        children: buildViewWidgets(),
+      ).padding(vertical: Insets.sm);
+    }
+  }
+
+  List<ViewWidget> buildViewWidgets() {
+    var targetViews = views.map((view) {
+      return ViewWidget(
+        icon: const Icon(Icons.file_copy),
+        view: view,
+      );
+    }).toList(growable: true);
+    targetViews.addAll(_mockViewWidgets());
+    return targetViews;
+  }
+
+  // TODO: junlin - remove view mocker after integrate docs storage to db
+  List<ViewWidget> _mockViewWidgets() {
+    // Stub doc views
+    final docViews = _mockDocsViews();
+    return docViews.map((view) {
+      return ViewWidget(
+        icon: Icon(Icons.edit_sharp),
+        view: view,
+      );
+    }).toList(growable: false);
+  }
+
+  // TODO: junlin - remove view mocker after integrate docs storage to db
+  List<View> _mockDocsViews() {
+    // plain text doc
+    var plainTextView = View();
+    plainTextView.id = 'doc_plain_text_document';
+    plainTextView.name = 'Plain Text Doc';
+    // code blocks doc
+
+    return [plainTextView];
+  }
+
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(IterableProperty<View>('views', views));
+  }
+}
+
+class ViewWidget extends StatelessWidget {
+  final View view;
+  final Widget icon;
+  const ViewWidget({Key? key, required this.view, required this.icon})
+      : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return InkWell(
+        onTap: _handleTapOnView(context),
+        child: Container(
+          height: 30,
+          child: buildContent(),
+        ));
+  }
+
+  Row buildContent() {
+    return Row(
+      children: [
+        icon,
+        const SizedBox(
+          width: 4,
+        ),
+        Text(
+          view.name,
+          textAlign: TextAlign.start,
+          style: const TextStyle(fontSize: 15),
+        )
+      ],
+    );
+  }
+
+  Function() _handleTapOnView(BuildContext context) {
+    return () {
+      // if (view.id.startsWith('doc')) {
+      //   context.read<MenuBloc>().add(MenuEvent.openPage(DocPageContext(view)));
+      //   return;
+      // }
+
+      // context.read<MenuBloc>().add(MenuEvent.openPage(GridPageContext(view)));
+    };
+  }
+}

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

@@ -1,4 +1,4 @@
-import 'package:app_flowy/home/domain/page_context.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:flutter/material.dart';
 
 class BlankPageContext extends PageContext {

+ 1 - 1
app_flowy/lib/home/presentation/widgets/home_stack_page.dart

@@ -1,4 +1,4 @@
-import 'package:app_flowy/home/domain/page_context.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:flutter/material.dart';
 
 abstract class HomeStackPage extends StatefulWidget {

+ 6 - 7
app_flowy/lib/home/presentation/widgets/home_top_bar.dart

@@ -1,11 +1,9 @@
-import 'package:app_flowy/home/application/home_bloc.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
 import '../home_sizes.dart';
 
 class HomeTopBar extends StatelessWidget {
-  const HomeTopBar({Key? key}) : super(key: key);
+  final String title;
+  const HomeTopBar({Key? key, required this.title}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -15,7 +13,7 @@ class HomeTopBar extends StatelessWidget {
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.center,
         children: [
-          HomeTitle(),
+          HomeTitle(title: title),
         ],
       ),
     );
@@ -23,18 +21,19 @@ class HomeTopBar extends StatelessWidget {
 }
 
 class HomeTitle extends StatelessWidget {
+  final String title;
   final _editingController = TextEditingController(
     text: '',
   );
 
   HomeTitle({
     Key? key,
+    required this.title,
   }) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
-    _editingController.text =
-        context.read<HomeBloc>().state.pageContext.pageTitle;
+    _editingController.text = title;
 
     return Expanded(
       child: TextField(

+ 2 - 2
app_flowy/lib/home/presentation/widgets/menu/menu.dart

@@ -1,6 +1,6 @@
 import 'package:app_flowy/home/application/menu/menu_bloc.dart';
 import 'package:app_flowy/home/application/menu/menu_watch.dart';
-import 'package:app_flowy/home/domain/page_context.dart';
+import 'package:app_flowy/home/domain/page_stack/page_stack.dart';
 import 'package:app_flowy/home/presentation/home_sizes.dart';
 import 'package:app_flowy/startup/startup.dart';
 import 'package:app_flowy/startup/tasks/application_task.dart';
@@ -20,7 +20,7 @@ import 'package:textstyle_extensions/textstyle_extensions.dart';
 import 'app_list.dart';
 
 class HomeMenu extends StatelessWidget {
-  final Function(Option<PageContext>) pageContextChanged;
+  final Function(PageContext?) pageContextChanged;
   final Function(bool) isCollapseChanged;
   final String workspaceId;