diff --git a/app_flowy/lib/workspace/application/app/app_bloc.dart b/app_flowy/lib/workspace/application/app/app_bloc.dart index b417244367..09c96b8e8d 100644 --- a/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -25,10 +25,16 @@ class AppBloc extends Bloc { }, createView: (CreateView value) async* { final viewOrFailed = await appManager.createView(name: value.name, desc: value.desc, viewType: value.viewType); - yield viewOrFailed.fold((view) => state, (error) { - Log.error(error); - return state.copyWith(successOrFailure: right(error)); - }); + yield viewOrFailed.fold( + (view) => state.copyWith( + selectedView: view, + successOrFailure: left(unit), + ), + (error) { + Log.error(error); + return state.copyWith(successOrFailure: right(error)); + }, + ); }, didReceiveViews: (e) async* { yield state.copyWith(views: e.views); @@ -75,12 +81,14 @@ class AppState with _$AppState { const factory AppState({ required bool isLoading, required List? views, + View? selectedView, required Either successOrFailure, }) = _AppState; factory AppState.initial() => AppState( isLoading: false, views: null, + selectedView: null, successOrFailure: left(unit), ); } diff --git a/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart b/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart index 6a0a3f6bd0..921b64c57c 100644 --- a/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart +++ b/app_flowy/lib/workspace/application/app/app_bloc.freezed.dart @@ -447,10 +447,12 @@ class _$AppStateTearOff { _AppState call( {required bool isLoading, required List? views, + View? selectedView, required Either successOrFailure}) { return _AppState( isLoading: isLoading, views: views, + selectedView: selectedView, successOrFailure: successOrFailure, ); } @@ -463,6 +465,7 @@ const $AppState = _$AppStateTearOff(); mixin _$AppState { bool get isLoading => throw _privateConstructorUsedError; List? get views => throw _privateConstructorUsedError; + View? get selectedView => throw _privateConstructorUsedError; Either get successOrFailure => throw _privateConstructorUsedError; @@ -478,6 +481,7 @@ abstract class $AppStateCopyWith<$Res> { $Res call( {bool isLoading, List? views, + View? selectedView, Either successOrFailure}); } @@ -493,6 +497,7 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> { $Res call({ Object? isLoading = freezed, Object? views = freezed, + Object? selectedView = freezed, Object? successOrFailure = freezed, }) { return _then(_value.copyWith( @@ -504,6 +509,10 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> { ? _value.views : views // ignore: cast_nullable_to_non_nullable as List?, + selectedView: selectedView == freezed + ? _value.selectedView + : selectedView // ignore: cast_nullable_to_non_nullable + as View?, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -520,6 +529,7 @@ abstract class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res> { $Res call( {bool isLoading, List? views, + View? selectedView, Either successOrFailure}); } @@ -536,6 +546,7 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res> $Res call({ Object? isLoading = freezed, Object? views = freezed, + Object? selectedView = freezed, Object? successOrFailure = freezed, }) { return _then(_AppState( @@ -547,6 +558,10 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res> ? _value.views : views // ignore: cast_nullable_to_non_nullable as List?, + selectedView: selectedView == freezed + ? _value.selectedView + : selectedView // ignore: cast_nullable_to_non_nullable + as View?, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -561,6 +576,7 @@ class _$_AppState implements _AppState { const _$_AppState( {required this.isLoading, required this.views, + this.selectedView, required this.successOrFailure}); @override @@ -568,11 +584,13 @@ class _$_AppState implements _AppState { @override final List? views; @override + final View? selectedView; + @override final Either successOrFailure; @override String toString() { - return 'AppState(isLoading: $isLoading, views: $views, successOrFailure: $successOrFailure)'; + return 'AppState(isLoading: $isLoading, views: $views, selectedView: $selectedView, successOrFailure: $successOrFailure)'; } @override @@ -584,6 +602,9 @@ class _$_AppState implements _AppState { .equals(other.isLoading, isLoading)) && (identical(other.views, views) || const DeepCollectionEquality().equals(other.views, views)) && + (identical(other.selectedView, selectedView) || + const DeepCollectionEquality() + .equals(other.selectedView, selectedView)) && (identical(other.successOrFailure, successOrFailure) || const DeepCollectionEquality() .equals(other.successOrFailure, successOrFailure))); @@ -594,6 +615,7 @@ class _$_AppState implements _AppState { runtimeType.hashCode ^ const DeepCollectionEquality().hash(isLoading) ^ const DeepCollectionEquality().hash(views) ^ + const DeepCollectionEquality().hash(selectedView) ^ const DeepCollectionEquality().hash(successOrFailure); @JsonKey(ignore: true) @@ -606,6 +628,7 @@ abstract class _AppState implements AppState { const factory _AppState( {required bool isLoading, required List? views, + View? selectedView, required Either successOrFailure}) = _$_AppState; @override @@ -613,6 +636,8 @@ abstract class _AppState implements AppState { @override List? get views => throw _privateConstructorUsedError; @override + View? get selectedView => throw _privateConstructorUsedError; + @override Either get successOrFailure => throw _privateConstructorUsedError; @override 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 f5ecc47ca1..3ca0606f63 100644 --- a/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart +++ b/app_flowy/lib/workspace/application/menu/menu_bloc.freezed.dart @@ -24,7 +24,7 @@ class _$MenuEventTearOff { return const Collapse(); } - OpenPage openPage(HomeStackContext context) { + OpenPage openPage(HomeStackContext context) { return OpenPage( context, ); @@ -53,7 +53,7 @@ mixin _$MenuEvent { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -63,7 +63,7 @@ mixin _$MenuEvent { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -145,7 +145,7 @@ class _$_Initial implements _Initial { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -158,7 +158,7 @@ class _$_Initial implements _Initial { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -242,7 +242,7 @@ class _$Collapse implements Collapse { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -255,7 +255,7 @@ class _$Collapse implements Collapse { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -304,7 +304,7 @@ abstract class Collapse implements MenuEvent { abstract class $OpenPageCopyWith<$Res> { factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) = _$OpenPageCopyWithImpl<$Res>; - $Res call({HomeStackContext context}); + $Res call({HomeStackContext context}); } /// @nodoc @@ -324,7 +324,7 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> context == freezed ? _value.context : context // ignore: cast_nullable_to_non_nullable - as HomeStackContext, + as HomeStackContext, )); } } @@ -335,7 +335,7 @@ class _$OpenPage implements OpenPage { const _$OpenPage(this.context); @override - final HomeStackContext context; + final HomeStackContext context; @override String toString() { @@ -364,7 +364,7 @@ class _$OpenPage implements OpenPage { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -377,7 +377,7 @@ class _$OpenPage implements OpenPage { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -419,9 +419,9 @@ class _$OpenPage implements OpenPage { } abstract class OpenPage implements MenuEvent { - const factory OpenPage(HomeStackContext context) = _$OpenPage; + const factory OpenPage(HomeStackContext context) = _$OpenPage; - HomeStackContext get context => throw _privateConstructorUsedError; + HomeStackContext get context => throw _privateConstructorUsedError; @JsonKey(ignore: true) $OpenPageCopyWith get copyWith => throw _privateConstructorUsedError; @@ -502,7 +502,7 @@ class _$CreateApp implements CreateApp { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -515,7 +515,7 @@ class _$CreateApp implements CreateApp { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -633,7 +633,7 @@ class _$ReceiveApps implements ReceiveApps { TResult when({ required TResult Function() initial, required TResult Function() collapse, - required TResult Function(HomeStackContext context) openPage, + required TResult Function(HomeStackContext context) openPage, required TResult Function(String name, String? desc) createApp, required TResult Function(Either, WorkspaceError> appsOrFail) didReceiveApps, @@ -646,7 +646,7 @@ class _$ReceiveApps implements ReceiveApps { TResult maybeWhen({ TResult Function()? initial, TResult Function()? collapse, - TResult Function(HomeStackContext context)? openPage, + TResult Function(HomeStackContext context)? openPage, TResult Function(String name, String? desc)? createApp, TResult Function(Either, WorkspaceError> appsOrFail)? didReceiveApps, @@ -706,7 +706,7 @@ class _$MenuStateTearOff { {required bool isCollapse, required Option> apps, required Either successOrFailure, - required HomeStackContext context}) { + required HomeStackContext context}) { return _MenuState( isCollapse: isCollapse, apps: apps, @@ -725,7 +725,7 @@ mixin _$MenuState { Option> get apps => throw _privateConstructorUsedError; Either get successOrFailure => throw _privateConstructorUsedError; - HomeStackContext get context => throw _privateConstructorUsedError; + HomeStackContext get context => throw _privateConstructorUsedError; @JsonKey(ignore: true) $MenuStateCopyWith get copyWith => @@ -740,7 +740,7 @@ abstract class $MenuStateCopyWith<$Res> { {bool isCollapse, Option> apps, Either successOrFailure, - HomeStackContext context}); + HomeStackContext context}); } /// @nodoc @@ -774,7 +774,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> { context: context == freezed ? _value.context : context // ignore: cast_nullable_to_non_nullable - as HomeStackContext, + as HomeStackContext, )); } } @@ -789,7 +789,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> { {bool isCollapse, Option> apps, Either successOrFailure, - HomeStackContext context}); + HomeStackContext context}); } /// @nodoc @@ -824,7 +824,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res> context: context == freezed ? _value.context : context // ignore: cast_nullable_to_non_nullable - as HomeStackContext, + as HomeStackContext, )); } } @@ -845,7 +845,7 @@ class _$_MenuState implements _MenuState { @override final Either successOrFailure; @override - final HomeStackContext context; + final HomeStackContext context; @override String toString() { @@ -887,7 +887,7 @@ abstract class _MenuState implements MenuState { {required bool isCollapse, required Option> apps, required Either successOrFailure, - required HomeStackContext context}) = _$_MenuState; + required HomeStackContext context}) = _$_MenuState; @override bool get isCollapse => throw _privateConstructorUsedError; @@ -897,7 +897,7 @@ abstract class _MenuState implements MenuState { Either get successOrFailure => throw _privateConstructorUsedError; @override - HomeStackContext get context => throw _privateConstructorUsedError; + HomeStackContext get context => throw _privateConstructorUsedError; @override @JsonKey(ignore: true) _$MenuStateCopyWith<_MenuState> get copyWith => 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 e46be42423..52ffd0e3dc 100644 --- a/app_flowy/lib/workspace/domain/page_stack/page_stack.dart +++ b/app_flowy/lib/workspace/domain/page_stack/page_stack.dart @@ -1,4 +1,3 @@ -import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:app_flowy/startup/startup.dart'; diff --git a/app_flowy/lib/workspace/presentation/stack_page/trash/widget/sizes.dart b/app_flowy/lib/workspace/presentation/stack_page/trash/widget/sizes.dart index ff960d28f9..d3c7d90bdc 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/trash/widget/sizes.dart +++ b/app_flowy/lib/workspace/presentation/stack_page/trash/widget/sizes.dart @@ -5,5 +5,6 @@ class TrashSizes { static double get lashModifyWidth => 230 * scale; static double get createTimeWidth => 230 * scale; static double get padding => 100 * scale; - static double get totalWidth => TrashSizes.fileNameWidth + TrashSizes.lashModifyWidth + TrashSizes.createTimeWidth; + static double get totalWidth => + TrashSizes.fileNameWidth + TrashSizes.lashModifyWidth + TrashSizes.createTimeWidth + TrashSizes.padding; } diff --git a/app_flowy/lib/workspace/presentation/widgets/dialogs.dart b/app_flowy/lib/workspace/presentation/widgets/dialogs.dart index c8a2975f36..06f1682f31 100644 --- a/app_flowy/lib/workspace/presentation/widgets/dialogs.dart +++ b/app_flowy/lib/workspace/presentation/widgets/dialogs.dart @@ -54,7 +54,7 @@ class _CreateTextFieldDialog extends State { ], FlowyFormTextInput( hintText: widget.value, - textStyle: const TextStyle(fontSize: 28, fontWeight: FontWeight.w400), + textStyle: const TextStyle(fontSize: 24, fontWeight: FontWeight.w400), autoFocus: true, onChanged: (text) { newValue = text; diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart b/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart index fb82f53bfb..6ab378e410 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/menu.dart @@ -2,7 +2,6 @@ import 'package:app_flowy/workspace/presentation/widgets/menu/widget/top_bar.dar import 'package:dartz/dartz.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart'; -import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/create_button.dart b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/create_button.dart index dfbc28e4f0..290bb66751 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/create_button.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/create_button.dart @@ -3,19 +3,10 @@ import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; import 'package:flowy_infra_ui/style_widget/extension.dart'; -import 'package:app_flowy/startup/tasks/application_task.dart'; -import 'package:flowy_infra/text_style.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flowy_infra_ui/style_widget/text_input.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; // ignore: implementation_imports -import 'package:provider/src/provider.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; class NewAppButton extends StatelessWidget { final Function(String)? press; @@ -41,64 +32,14 @@ class NewAppButton extends StatelessWidget { } Future _showCreateAppDialog(BuildContext context) async { - await CreateAppDialog( - confirm: (appName) { - if (appName.isNotEmpty && press != null) { - press!(appName); + return TextFieldDialog( + title: 'New App', + value: "", + confirm: (newValue) { + if (newValue.isNotEmpty && press != null) { + press!(newValue); } }, ).show(context); } } - -class CreateAppDialog extends StatefulWidget { - final void Function()? cancel; - final void Function(String) confirm; - - const CreateAppDialog({required this.confirm, this.cancel, Key? key}) : super(key: key); - - @override - State createState() => _CreateAppDialogState(); -} - -class _CreateAppDialogState extends State { - String appName = ""; - - @override - Widget build(BuildContext context) { - final theme = context.watch(); - return StyledDialog( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ...[ - Text('Create App'.toUpperCase(), style: TextStyles.T1.textColor(theme.shader4)), - VSpace(Insets.sm * 1.5), - // Container(color: theme.greyWeak.withOpacity(.35), height: 1), - VSpace(Insets.m * 1.5), - ], - FlowyFormTextInput( - hintText: "App name", - onChanged: (text) { - appName = text; - }, - ), - SizedBox(height: Insets.l), - SizedBox( - height: 40, - child: OkCancelButton( - onOkPressed: () { - widget.confirm(appName); - }, - onCancelPressed: () { - if (widget.cancel != null) { - widget.cancel!(); - } - }, - ), - ) - ], - ), - ); - } -} 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 b650d449f3..10d04b0652 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 @@ -1,6 +1,7 @@ import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/header.dart'; import 'package:expandable/expandable.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:app_flowy/startup/startup.dart'; @@ -9,23 +10,6 @@ import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'section/section.dart'; - -class MenuAppSizes { - static double expandedIconSize = 16; - static double expandedIconPadding = 6; - static double scale = 1; - static double get expandedPadding => expandedIconSize * scale + expandedIconPadding; -} - -class MenuAppContext { - final App app; - final viewList = ViewListNotifier(); - - MenuAppContext(this.app); - - Key valueKey() => ValueKey("${app.id}${app.version}"); -} - // [[diagram: MenuApp]] // ┌────────┐ // ┌────▶│AppBloc │────────────────┐ @@ -61,18 +45,25 @@ class MenuApp extends MenuItem { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider(create: (context) { - final appBloc = getIt(param1: appCtx.app.id); - appBloc.add(const AppEvent.initial()); - return appBloc; - }), + BlocProvider( + create: (context) { + final appBloc = getIt(param1: appCtx.app.id); + appBloc.add(const AppEvent.initial()); + return appBloc; + }, + ), ], - child: BlocBuilder( - builder: (context, state) { - appCtx.viewList.items = state.views ?? List.empty(growable: false); - final child = _renderViewSection(appCtx.viewList); - return expandableWrapper(context, child); - }, + child: BlocListener( + listenWhen: (p, c) => p.selectedView != c.selectedView, + listener: (context, state) => appCtx.viewList.selectView = state.selectedView, + child: BlocBuilder( + buildWhen: (p, c) => p.views != c.views, + builder: (context, state) { + appCtx.viewList.views = state.views; + final child = _renderViewSection(appCtx.viewList); + return expandableWrapper(context, child); + }, + ), ), ); } @@ -109,7 +100,7 @@ class MenuApp extends MenuItem { ChangeNotifierProvider.value(value: viewListNotifier), ], child: Consumer(builder: (context, ViewListNotifier notifier, child) { - return ViewSection(notifier.items).padding(vertical: 8); + return const ViewSection().padding(vertical: 8); }), ); } @@ -117,3 +108,39 @@ class MenuApp extends MenuItem { @override MenuItemType get type => MenuItemType.app; } + +class MenuAppSizes { + static double expandedIconSize = 16; + static double expandedIconPadding = 6; + static double scale = 1; + static double get expandedPadding => expandedIconSize * scale + expandedIconPadding; +} + +class ViewListNotifier extends ChangeNotifier { + List _views = []; + View? _selectedView; + ViewListNotifier(); + + set views(List? items) { + _views = items ?? List.empty(growable: false); + notifyListeners(); + } + + set selectView(View? view) { + _selectedView = view; + notifyListeners(); + } + + get selectedView => _selectedView; + + List get views => _views; +} + +class MenuAppContext { + final App app; + final viewList = ViewListNotifier(); + + MenuAppContext(this.app); + + Key valueKey() => ValueKey("${app.id}${app.version}"); +} diff --git a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/item.dart b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/item.dart index 83c792edd7..b7c72ccd50 100644 --- a/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/item.dart +++ b/app_flowy/lib/workspace/presentation/widgets/menu/widget/app/section/item.dart @@ -45,10 +45,7 @@ class ViewSectionItem extends StatelessWidget { child: BlocBuilder( builder: (context, state) { return InkWell( - onTap: () { - onSelected(context.read().state.view); - getIt().setStack(state.view.stackContext()); - }, + onTap: () => onSelected(context.read().state.view), child: FlowyHover( config: HoverDisplayConfig(hoverColor: theme.bg3), builder: (_, onHover) => _render(context, onHover, state), 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 8492081887..c05d27ffe5 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 @@ -1,3 +1,7 @@ +import 'package:app_flowy/startup/startup.dart'; +import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; +import 'package:app_flowy/workspace/domain/view_ext.dart'; +import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -5,50 +9,69 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'item.dart'; - -class ViewListNotifier extends ChangeNotifier { - List? views; - ViewListNotifier(); - - set items(List items) { - views = items; - notifyListeners(); - } - - List get items => views ?? []; -} +import 'package:async/async.dart'; class ViewSectionNotifier with ChangeNotifier { List innerViews; View? _selectedView; + CancelableOperation? _notifyListenerOperation; ViewSectionNotifier(this.innerViews); set views(List views) => innerViews = views; List get views => innerViews; + set setViews(List views) { + if (innerViews != views) { + innerViews = views; + _notifyListeners(); + } + } - void setSelectedView(View view) { - _selectedView = view; - notifyListeners(); + set selectView(View? view) { + if (_selectedView == view) { + return; + } + + if (view != null) { + _selectedView = view; + + WidgetsBinding.instance?.addPostFrameCallback((_) { + getIt().setStack(view.stackContext()); + }); + + _notifyListeners(); + } else { + // WidgetsBinding.instance?.addPostFrameCallback((_) { + // getIt().setStack(BlankStackContext()); + // }); + } } View? get selectedView => _selectedView; void update(ViewListNotifier notifier) { - innerViews = notifier.items; - notifyListeners(); + setViews = notifier.views; + selectView = notifier.selectedView; + } + + void _notifyListeners() { + _notifyListenerOperation?.cancel(); + _notifyListenerOperation = CancelableOperation.fromFuture( + Future.delayed(const Duration(milliseconds: 30), () {}), + ).then((_) { + notifyListeners(); + }); } } class ViewSection extends StatelessWidget { - final List views; - const ViewSection(this.views, {Key? key}) : super(key: key); + const ViewSection({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // The ViewListNotifier will be updated after ViewListData changed passed by parent widget return ChangeNotifierProxyProvider( create: (_) { - final views = Provider.of(context, listen: false).items; + final views = Provider.of(context, listen: false).views; return ViewSectionNotifier(views); }, update: (_, notifier, controller) => controller!..update(notifier), @@ -63,7 +86,9 @@ class ViewSection extends StatelessWidget { (view) => ViewSectionItem( view: view, isSelected: _isViewSelected(context, view.id), - onSelected: (view) => context.read().setSelectedView(view), + onSelected: (view) { + context.read().selectView = view; + }, ).padding(vertical: 4), );