diff --git a/app_flowy/lib/user/presentation/skip_log_in_screen.dart b/app_flowy/lib/user/presentation/skip_log_in_screen.dart index f8a62f3a89..2ed3ff27d3 100644 --- a/app_flowy/lib/user/presentation/skip_log_in_screen.dart +++ b/app_flowy/lib/user/presentation/skip_log_in_screen.dart @@ -1,4 +1,3 @@ -import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/user/domain/i_auth.dart'; import 'package:app_flowy/user/presentation/widgets/background.dart'; import 'package:app_flowy/workspace/domain/i_user.dart'; @@ -10,7 +9,6 @@ import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart'; -import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/app_flowy/lib/user/presentation/splash_screen.dart b/app_flowy/lib/user/presentation/splash_screen.dart index 1ef5b0eced..1c137cb3b6 100644 --- a/app_flowy/lib/user/presentation/splash_screen.dart +++ b/app_flowy/lib/user/presentation/splash_screen.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/user/application/splash_bloc.dart'; import 'package:app_flowy/user/domain/auth_state.dart'; import 'package:app_flowy/user/domain/i_splash.dart'; -import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace-infra/errors.pb.dart'; import 'package:flutter/material.dart'; diff --git a/app_flowy/lib/workspace/application/menu/menu_bloc.dart b/app_flowy/lib/workspace/application/menu/menu_bloc.dart index 5962b9d2a9..b6dac402f9 100644 --- a/app_flowy/lib/workspace/application/menu/menu_bloc.dart +++ b/app_flowy/lib/workspace/application/menu/menu_bloc.dart @@ -52,7 +52,7 @@ class MenuBloc extends Bloc { } Stream _performActionOnOpenPage(OpenPage e) async* { - yield state.copyWith(context: e.context); + yield state.copyWith(stackContext: e.context); } Stream _performActionOnCreateApp(CreateApp event) async* { @@ -101,13 +101,13 @@ class MenuState with _$MenuState { required bool isCollapse, required Option> apps, required Either successOrFailure, - required HomeStackContext context, + required HomeStackContext stackContext, }) = _MenuState; factory MenuState.initial() => MenuState( isCollapse: false, apps: none(), successOrFailure: left(unit), - context: BlankStackContext(), + stackContext: BlankStackContext(), ); } diff --git a/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart b/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart index 43c4bf0e64..3aa13660bc 100644 --- a/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart +++ b/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart @@ -859,12 +859,12 @@ class _$MenuStateTearOff { {required bool isCollapse, required Option> apps, required Either successOrFailure, - required HomeStackContext context}) { + required HomeStackContext stackContext}) { return _MenuState( isCollapse: isCollapse, apps: apps, successOrFailure: successOrFailure, - context: context, + stackContext: stackContext, ); } } @@ -878,7 +878,7 @@ mixin _$MenuState { Option> get apps => throw _privateConstructorUsedError; Either get successOrFailure => throw _privateConstructorUsedError; - HomeStackContext get context => + HomeStackContext get stackContext => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -894,7 +894,7 @@ abstract class $MenuStateCopyWith<$Res> { {bool isCollapse, Option> apps, Either successOrFailure, - HomeStackContext context}); + HomeStackContext stackContext}); } /// @nodoc @@ -910,7 +910,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> { Object? isCollapse = freezed, Object? apps = freezed, Object? successOrFailure = freezed, - Object? context = freezed, + Object? stackContext = freezed, }) { return _then(_value.copyWith( isCollapse: isCollapse == freezed @@ -925,9 +925,9 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> { ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable as Either, - context: context == freezed - ? _value.context - : context // ignore: cast_nullable_to_non_nullable + stackContext: stackContext == freezed + ? _value.stackContext + : stackContext // ignore: cast_nullable_to_non_nullable as HomeStackContext, )); } @@ -943,7 +943,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> { {bool isCollapse, Option> apps, Either successOrFailure, - HomeStackContext context}); + HomeStackContext stackContext}); } /// @nodoc @@ -960,7 +960,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res> Object? isCollapse = freezed, Object? apps = freezed, Object? successOrFailure = freezed, - Object? context = freezed, + Object? stackContext = freezed, }) { return _then(_MenuState( isCollapse: isCollapse == freezed @@ -975,9 +975,9 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res> ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable as Either, - context: context == freezed - ? _value.context - : context // ignore: cast_nullable_to_non_nullable + stackContext: stackContext == freezed + ? _value.stackContext + : stackContext // ignore: cast_nullable_to_non_nullable as HomeStackContext, )); } @@ -990,7 +990,7 @@ class _$_MenuState implements _MenuState { {required this.isCollapse, required this.apps, required this.successOrFailure, - required this.context}); + required this.stackContext}); @override final bool isCollapse; @@ -999,11 +999,11 @@ class _$_MenuState implements _MenuState { @override final Either successOrFailure; @override - final HomeStackContext context; + final HomeStackContext stackContext; @override String toString() { - return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, context: $context)'; + return 'MenuState(isCollapse: $isCollapse, apps: $apps, successOrFailure: $successOrFailure, stackContext: $stackContext)'; } @override @@ -1018,8 +1018,9 @@ class _$_MenuState implements _MenuState { (identical(other.successOrFailure, successOrFailure) || const DeepCollectionEquality() .equals(other.successOrFailure, successOrFailure)) && - (identical(other.context, context) || - const DeepCollectionEquality().equals(other.context, context))); + (identical(other.stackContext, stackContext) || + const DeepCollectionEquality() + .equals(other.stackContext, stackContext))); } @override @@ -1028,7 +1029,7 @@ class _$_MenuState implements _MenuState { const DeepCollectionEquality().hash(isCollapse) ^ const DeepCollectionEquality().hash(apps) ^ const DeepCollectionEquality().hash(successOrFailure) ^ - const DeepCollectionEquality().hash(context); + const DeepCollectionEquality().hash(stackContext); @JsonKey(ignore: true) @override @@ -1041,7 +1042,7 @@ abstract class _MenuState implements MenuState { {required bool isCollapse, required Option> apps, required Either successOrFailure, - required HomeStackContext context}) = _$_MenuState; + required HomeStackContext stackContext}) = _$_MenuState; @override bool get isCollapse => throw _privateConstructorUsedError; @@ -1051,7 +1052,7 @@ abstract class _MenuState implements MenuState { Either get successOrFailure => throw _privateConstructorUsedError; @override - HomeStackContext get context => + HomeStackContext get stackContext => throw _privateConstructorUsedError; @override @JsonKey(ignore: true) diff --git a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart b/app_flowy/lib/workspace/domain/page_stack/page_stack.dart index d83f2a9bc0..d01b77ba59 100644 --- a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart +++ b/app_flowy/lib/workspace/domain/page_stack/page_stack.dart @@ -82,7 +82,7 @@ class HomeStackManager { PublishNotifier get collapsedNotifier => _notifier.collapsedNotifier; - void switchStack(HomeStackContext context) { + void setStack(HomeStackContext context) { _notifier.context = context; } diff --git a/app_flowy/lib/workspace/presentation/home/home_screen.dart b/app_flowy/lib/workspace/presentation/home/home_screen.dart index f78487b2d5..a80f0cfc22 100644 --- a/app_flowy/lib/workspace/presentation/home/home_screen.dart +++ b/app_flowy/lib/workspace/presentation/home/home_screen.dart @@ -5,7 +5,6 @@ import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart'; import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart'; import 'package:app_flowy/workspace/presentation/widgets/prelude.dart'; import 'package:app_flowy/startup/startup.dart'; -import 'package:flowy_infra/notifier.dart'; import 'package:flowy_log/flowy_log.dart'; import 'package:flowy_infra_ui/style_widget/container.dart'; import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart'; @@ -30,6 +29,17 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { View? initialView; + @override + void initState() { + super.initState(); + } + + @override + void didUpdateWidget(covariant HomeScreen oldWidget) { + initialView = null; + super.didUpdateWidget(oldWidget); + } + @override Widget build(BuildContext context) { return MultiBlocProvider( @@ -54,6 +64,10 @@ class _HomeScreenState extends State { child: BlocBuilder( buildWhen: (previous, current) => previous != current, builder: (context, state) { + final collapasedNotifier = getIt().collapsedNotifier; + collapasedNotifier.addPublishListener((isCollapsed) { + context.read().add(HomeEvent.forceCollapse(isCollapsed)); + }); return FlowyContainer( Theme.of(context).colorScheme.surface, // Colors.white, @@ -93,22 +107,15 @@ class _HomeScreenState extends State { } Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context}) { - final homeBloc = context.read(); - - final collapasedNotifier = getIt().collapsedNotifier; - collapasedNotifier.addPublishListener((isCollapsed) { - homeBloc.add(HomeEvent.forceCollapse(isCollapsed)); - }); - if (initialView == null && widget.workspaceSetting.hasLatestView()) { initialView = widget.workspaceSetting.latestView; - getIt().switchStack(initialView!.stackContext()); + getIt().setStack(initialView!.stackContext()); } HomeMenu homeMenu = HomeMenu( user: widget.user, workspaceSetting: widget.workspaceSetting, - collapsedNotifier: collapasedNotifier, + collapsedNotifier: getIt().collapsedNotifier, ); return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu)); diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart b/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart index 840951f722..a6118057ea 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart @@ -69,9 +69,9 @@ class HomeMenu extends StatelessWidget { child: MultiBlocListener( listeners: [ BlocListener( - listenWhen: (p, c) => p.context != c.context, + listenWhen: (p, c) => p.stackContext != c.stackContext, listener: (context, state) { - getIt().switchStack(state.context); + getIt().setStack(state.stackContext); }, ), BlocListener( @@ -92,58 +92,60 @@ class HomeMenu extends StatelessWidget { color: Theme.of(context).colorScheme.background, child: ChangeNotifierProvider( create: (_) => MenuSharedState(view: workspaceSetting.hasLatestView() ? workspaceSetting.latestView : null), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - _renderTopBar(context), - const VSpace(16), - _renderApps(context), - ], - ).padding(horizontal: Insets.l), - ), - const VSpace(20), - _renderTrash(context).padding(horizontal: Insets.l), - const VSpace(20), - _renderNewAppButton(context), - ], - ), + child: Consumer(builder: (context, MenuSharedState sharedState, child) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + const MenuTopBar(), + const VSpace(16), + _renderApps(context), + ], + ).padding(horizontal: Insets.l), + ), + const VSpace(20), + _renderTrash(context).padding(horizontal: Insets.l), + const VSpace(20), + _renderNewAppButton(context), + ], + ); + }), ), ); } - Widget _renderTopBar(BuildContext context) { - return const MenuTopBar(); - } - Widget _renderApps(BuildContext context) { - final apps = context.read().state.apps; - List menuItems = []; - menuItems.add(MenuUser(user)); - List appWidgets = apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList()); - menuItems.addAll(appWidgets); - return ExpandableTheme( data: ExpandableThemeData(useInkWell: true, animationDuration: Durations.medium), child: Expanded( child: ScrollConfiguration( behavior: const ScrollBehavior().copyWith(scrollbars: false), - child: ListView.separated( - itemCount: menuItems.length, - separatorBuilder: (context, index) { - if (index == 0) { - return const VSpace(29); - } else { - return VSpace(MenuAppSizes.appVPadding); - } - }, - physics: StyledScrollPhysics(), - itemBuilder: (BuildContext context, int index) { - return menuItems[index]; + child: BlocSelector>( + selector: (state) { + List menuItems = []; + menuItems.add(MenuUser(user)); + List appWidgets = + state.apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(app)).toList()); + menuItems.addAll(appWidgets); + return menuItems; }, + builder: (context, menuItems) => ListView.separated( + itemCount: menuItems.length, + separatorBuilder: (context, index) { + if (index == 0) { + return const VSpace(29); + } else { + return VSpace(MenuAppSizes.appVPadding); + } + }, + physics: StyledScrollPhysics(), + itemBuilder: (BuildContext context, int index) { + return menuItems[index]; + }, + ), ), ), ), @@ -174,28 +176,4 @@ class MenuSharedState extends ChangeNotifier { selectedView.value = view; }); } - - // void addForcedOpenViewListener(void Function(View) callback) { - // super.addListener(() { - // if (_forcedOpenView != null) { - // callback(_forcedOpenView!); - // } - // }); - // } - - // void addSelectedViewListener(void Function(View?) callback) { - // super.addListener(() { - // callback(_view); - // }); - // } - - // set forcedOpenView(View? view) { - // if (_forcedOpenView != view) { - // _forcedOpenView = view; - - // selectedView = view; - // notifyListeners(); - // } - // } - } diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/menu_app.dart b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/menu_app.dart index 700481f01e..3042ff3c9c 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/menu_app.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/menu_app.dart @@ -8,7 +8,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/app/app_bloc.dart'; import 'package:provider/provider.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'section/section.dart'; class MenuApp extends StatefulWidget { @@ -20,7 +19,13 @@ class MenuApp extends StatefulWidget { } class _MenuAppState extends State { - final notifier = AppDataNotifier(); + late AppDataNotifier notifier; + + @override + void initState() { + notifier = AppDataNotifier(); + super.initState(); + } @override Widget build(BuildContext context) { @@ -120,7 +125,7 @@ class AppDataNotifier extends ChangeNotifier { set selectedView(View? view) { _selectedView = view; - if (view != null) { + if (view != null && _views.isNotEmpty) { final isExpanded = _views.contains(view); if (expandController.expanded == false && expandController.expanded != isExpanded) { // Workaround: Delay 150 milliseconds to make the smooth animation while expanding diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/section.dart b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/section.dart index ae8d25c0fc..26f6c3fd56 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/section.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/section.dart @@ -109,7 +109,7 @@ class ViewSectionNotifier with ChangeNotifier { if (view != null) { WidgetsBinding.instance?.addPostFrameCallback((_) { - getIt().switchStack(view.stackContext()); + getIt().setStack(view.stackContext()); }); } else { // do nothing diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart b/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart index 4249b25fde..a4de334e12 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/widget/menu_trash.dart @@ -19,7 +19,7 @@ class MenuTrash extends StatelessWidget { child: InkWell( onTap: () { Provider.of(context, listen: false).selectedView.value = null; - getIt().switchStack(TrashStackContext()); + getIt().setStack(TrashStackContext()); }, child: _render(context), ), diff --git a/rust-lib/flowy-workspace/src/services/view_controller.rs b/rust-lib/flowy-workspace/src/services/view_controller.rs index 17169babab..a9aedfd5da 100644 --- a/rust-lib/flowy-workspace/src/services/view_controller.rs +++ b/rust-lib/flowy-workspace/src/services/view_controller.rs @@ -145,7 +145,7 @@ impl ViewController { let duplicate_params = CreateViewParams { belong_to_id: view.belong_to_id.clone(), - name: format!("{}_copy", &view.name), + name: format!("{} (copy)", &view.name), desc: view.desc.clone(), thumbnail: "".to_owned(), view_type: view.view_type.clone(),