From 9b9d462f368fed4c73dfbe804bafa6616bdc901e Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 22 Jul 2021 11:23:15 +0800 Subject: [PATCH] combine event and state into bloc & add watch bloc of workspace --- .../lib/home/application/app/app_bloc.dart | 25 +- .../application/app/app_bloc.freezed.dart | 46 +- .../lib/home/application/app/app_event.dart | 8 - .../lib/home/application/app/app_state.dart | 16 - .../home/application/app/app_watch_bloc.dart | 56 ++ .../app/app_watch_bloc.freezed.dart | 683 ++++++++++++++++++ app_flowy/lib/home/application/home_bloc.dart | 34 +- .../lib/home/application/home_event.dart | 15 - .../lib/home/application/home_state.dart | 18 - .../lib/home/application/menu/menu_bloc.dart | 50 +- .../application/menu/menu_bloc.freezed.dart | 168 ----- .../lib/home/application/menu/menu_event.dart | 11 - .../lib/home/application/menu/menu_state.dart | 18 - .../lib/home/application/menu/menu_watch.dart | 64 ++ .../application/menu/menu_watch.freezed.dart | 682 +++++++++++++++++ app_flowy/lib/home/domain/i_app.dart | 2 + app_flowy/lib/home/domain/i_workspace.dart | 5 +- .../home/infrastructure/deps_resolver.dart | 26 +- .../lib/home/infrastructure/i_app_impl.dart | 7 + .../home/infrastructure/i_workspace_impl.dart | 16 +- .../home/infrastructure/repos/app_repo.dart | 20 +- .../infrastructure/repos/workspace_repo.dart | 27 +- .../widgets/app/app_list_widget.dart | 79 +- .../presentation/widgets/app/app_widget.dart | 23 +- .../presentation/widgets/menu/app_list.dart | 29 + .../menu/{home_menu.dart => menu.dart} | 44 +- .../{hom_menu_size.dart => menu_size.dart} | 0 .../presentation/widgets/menu/prelude.dart | 4 +- .../home/presentation/widgets/prelude.dart | 2 +- ...widget_task.dart => application_task.dart} | 6 +- app_flowy/lib/startup/tasks/prelude.dart | 2 +- .../flowy_infra_ui/example/pubspec.lock | 8 +- .../packages/flowy_infra_ui/pubspec.lock | 8 +- app_flowy/pubspec.lock | 2 +- app_flowy/pubspec.yaml | 2 +- rust-lib/dart-ffi/Cargo.toml | 8 +- 36 files changed, 1823 insertions(+), 391 deletions(-) delete mode 100644 app_flowy/lib/home/application/app/app_event.dart delete mode 100644 app_flowy/lib/home/application/app/app_state.dart create mode 100644 app_flowy/lib/home/application/app/app_watch_bloc.dart create mode 100644 app_flowy/lib/home/application/app/app_watch_bloc.freezed.dart delete mode 100644 app_flowy/lib/home/application/home_event.dart delete mode 100644 app_flowy/lib/home/application/home_state.dart delete mode 100644 app_flowy/lib/home/application/menu/menu_event.dart delete mode 100644 app_flowy/lib/home/application/menu/menu_state.dart create mode 100644 app_flowy/lib/home/application/menu/menu_watch.dart create mode 100644 app_flowy/lib/home/application/menu/menu_watch.freezed.dart create mode 100644 app_flowy/lib/home/presentation/widgets/menu/app_list.dart rename app_flowy/lib/home/presentation/widgets/menu/{home_menu.dart => menu.dart} (81%) rename app_flowy/lib/home/presentation/widgets/menu/{hom_menu_size.dart => menu_size.dart} (100%) rename app_flowy/lib/startup/tasks/{app_widget_task.dart => application_task.dart} (90%) diff --git a/app_flowy/lib/home/application/app/app_bloc.dart b/app_flowy/lib/home/application/app/app_bloc.dart index e8409cbbd1..b2e555d9e1 100644 --- a/app_flowy/lib/home/application/app/app_bloc.dart +++ b/app_flowy/lib/home/application/app/app_bloc.dart @@ -1,13 +1,10 @@ import 'package:app_flowy/home/domain/i_app.dart'; -import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:dartz/dartz.dart'; -part 'app_event.dart'; -part 'app_state.dart'; part 'app_bloc.freezed.dart'; class AppBloc extends Bloc { @@ -31,3 +28,25 @@ class AppBloc extends Bloc { ); } } + +@freezed +abstract class AppEvent with _$AppEvent { + const factory AppEvent.initial() = _Initial; + const factory AppEvent.viewsReceived( + Either, WorkspaceError> appsOrFail) = ViewsReceived; +} + +@freezed +abstract class AppState implements _$AppState { + const factory AppState({ + required bool isLoading, + required Option> views, + required Either successOrFailure, + }) = _AppState; + + factory AppState.initial() => AppState( + isLoading: false, + views: none(), + successOrFailure: left(unit), + ); +} diff --git a/app_flowy/lib/home/application/app/app_bloc.freezed.dart b/app_flowy/lib/home/application/app/app_bloc.freezed.dart index d2f1df5b62..82645f0456 100644 --- a/app_flowy/lib/home/application/app/app_bloc.freezed.dart +++ b/app_flowy/lib/home/application/app/app_bloc.freezed.dart @@ -288,11 +288,11 @@ class _$AppStateTearOff { _AppState call( {required bool isLoading, - required Option> apps, + required Option> views, required Either successOrFailure}) { return _AppState( isLoading: isLoading, - apps: apps, + views: views, successOrFailure: successOrFailure, ); } @@ -304,7 +304,7 @@ const $AppState = _$AppStateTearOff(); /// @nodoc mixin _$AppState { bool get isLoading => throw _privateConstructorUsedError; - Option> get apps => throw _privateConstructorUsedError; + Option> get views => throw _privateConstructorUsedError; Either get successOrFailure => throw _privateConstructorUsedError; @@ -319,7 +319,7 @@ abstract class $AppStateCopyWith<$Res> { _$AppStateCopyWithImpl<$Res>; $Res call( {bool isLoading, - Option> apps, + Option> views, Either successOrFailure}); } @@ -334,7 +334,7 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> { @override $Res call({ Object? isLoading = freezed, - Object? apps = freezed, + Object? views = freezed, Object? successOrFailure = freezed, }) { return _then(_value.copyWith( @@ -342,10 +342,10 @@ class _$AppStateCopyWithImpl<$Res> implements $AppStateCopyWith<$Res> { ? _value.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool, - apps: apps == freezed - ? _value.apps - : apps // ignore: cast_nullable_to_non_nullable - as Option>, + views: views == freezed + ? _value.views + : views // ignore: cast_nullable_to_non_nullable + as Option>, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -361,7 +361,7 @@ abstract class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res> { @override $Res call( {bool isLoading, - Option> apps, + Option> views, Either successOrFailure}); } @@ -377,7 +377,7 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res> @override $Res call({ Object? isLoading = freezed, - Object? apps = freezed, + Object? views = freezed, Object? successOrFailure = freezed, }) { return _then(_AppState( @@ -385,10 +385,10 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res> ? _value.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool, - apps: apps == freezed - ? _value.apps - : apps // ignore: cast_nullable_to_non_nullable - as Option>, + views: views == freezed + ? _value.views + : views // ignore: cast_nullable_to_non_nullable + as Option>, successOrFailure: successOrFailure == freezed ? _value.successOrFailure : successOrFailure // ignore: cast_nullable_to_non_nullable @@ -402,19 +402,19 @@ class __$AppStateCopyWithImpl<$Res> extends _$AppStateCopyWithImpl<$Res> class _$_AppState implements _AppState { const _$_AppState( {required this.isLoading, - required this.apps, + required this.views, required this.successOrFailure}); @override final bool isLoading; @override - final Option> apps; + final Option> views; @override final Either successOrFailure; @override String toString() { - return 'AppState(isLoading: $isLoading, apps: $apps, successOrFailure: $successOrFailure)'; + return 'AppState(isLoading: $isLoading, views: $views, successOrFailure: $successOrFailure)'; } @override @@ -424,8 +424,8 @@ class _$_AppState implements _AppState { (identical(other.isLoading, isLoading) || const DeepCollectionEquality() .equals(other.isLoading, isLoading)) && - (identical(other.apps, apps) || - const DeepCollectionEquality().equals(other.apps, apps)) && + (identical(other.views, views) || + const DeepCollectionEquality().equals(other.views, views)) && (identical(other.successOrFailure, successOrFailure) || const DeepCollectionEquality() .equals(other.successOrFailure, successOrFailure))); @@ -435,7 +435,7 @@ class _$_AppState implements _AppState { int get hashCode => runtimeType.hashCode ^ const DeepCollectionEquality().hash(isLoading) ^ - const DeepCollectionEquality().hash(apps) ^ + const DeepCollectionEquality().hash(views) ^ const DeepCollectionEquality().hash(successOrFailure); @JsonKey(ignore: true) @@ -447,13 +447,13 @@ class _$_AppState implements _AppState { abstract class _AppState implements AppState { const factory _AppState( {required bool isLoading, - required Option> apps, + required Option> views, required Either successOrFailure}) = _$_AppState; @override bool get isLoading => throw _privateConstructorUsedError; @override - Option> get apps => throw _privateConstructorUsedError; + Option> get views => throw _privateConstructorUsedError; @override Either get successOrFailure => throw _privateConstructorUsedError; diff --git a/app_flowy/lib/home/application/app/app_event.dart b/app_flowy/lib/home/application/app/app_event.dart deleted file mode 100644 index 12ec504279..0000000000 --- a/app_flowy/lib/home/application/app/app_event.dart +++ /dev/null @@ -1,8 +0,0 @@ -part of 'app_bloc.dart'; - -@freezed -abstract class AppEvent with _$AppEvent { - const factory AppEvent.initial() = _Initial; - const factory AppEvent.viewsReceived( - Either, WorkspaceError> appsOrFail) = ViewsReceived; -} diff --git a/app_flowy/lib/home/application/app/app_state.dart b/app_flowy/lib/home/application/app/app_state.dart deleted file mode 100644 index 00033369c5..0000000000 --- a/app_flowy/lib/home/application/app/app_state.dart +++ /dev/null @@ -1,16 +0,0 @@ -part of 'app_bloc.dart'; - -@freezed -abstract class AppState implements _$AppState { - const factory AppState({ - required bool isLoading, - required Option> apps, - required Either successOrFailure, - }) = _AppState; - - factory AppState.initial() => AppState( - isLoading: false, - apps: none(), - successOrFailure: left(unit), - ); -} diff --git a/app_flowy/lib/home/application/app/app_watch_bloc.dart b/app_flowy/lib/home/application/app/app_watch_bloc.dart new file mode 100644 index 0000000000..2edbb151dc --- /dev/null +++ b/app_flowy/lib/home/application/app/app_watch_bloc.dart @@ -0,0 +1,56 @@ +import 'package:app_flowy/home/domain/i_app.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:dartz/dartz.dart'; + +part 'app_watch_bloc.freezed.dart'; + +class AppWatchBloc extends Bloc { + final IAppWatch watcher; + AppWatchBloc(this.watcher) : super(const AppWatchState.initial()); + + @override + Stream mapEventToState( + AppWatchEvent event, + ) async* { + yield* event.map(started: (_) { + watcher.startWatching( + addViewCallback: (viewsOrFail) => _handleViewsOrFail(viewsOrFail), + ); + }, viewsReceived: (ViewsReceived value) async* { + yield value.viewsOrFail.fold( + (views) => AppWatchState.loadViews(views), + (error) => AppWatchState.loadFail(error), + ); + }); + } + + void _handleViewsOrFail(Either, WorkspaceError> viewsOrFail) { + viewsOrFail.fold( + (views) => add(AppWatchEvent.viewsReceived(left(views))), + (error) => add(AppWatchEvent.viewsReceived(right(error))), + ); + } +} + +@freezed +abstract class AppWatchEvent with _$AppWatchEvent { + const factory AppWatchEvent.started() = _Started; + const factory AppWatchEvent.viewsReceived( + Either, WorkspaceError> viewsOrFail) = ViewsReceived; +} + +@freezed +abstract class AppWatchState implements _$AppWatchState { + const factory AppWatchState.initial() = _Initial; + + const factory AppWatchState.loadViews( + List views, + ) = _LoadViews; + + const factory AppWatchState.loadFail( + WorkspaceError error, + ) = _LoadFail; +} diff --git a/app_flowy/lib/home/application/app/app_watch_bloc.freezed.dart b/app_flowy/lib/home/application/app/app_watch_bloc.freezed.dart new file mode 100644 index 0000000000..e3dc21be5c --- /dev/null +++ b/app_flowy/lib/home/application/app/app_watch_bloc.freezed.dart @@ -0,0 +1,683 @@ +// 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 'app_watch_bloc.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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 _$AppWatchEventTearOff { + const _$AppWatchEventTearOff(); + + _Started started() { + return const _Started(); + } + + ViewsReceived viewsReceived(Either, WorkspaceError> viewsOrFail) { + return ViewsReceived( + viewsOrFail, + ); + } +} + +/// @nodoc +const $AppWatchEvent = _$AppWatchEventTearOff(); + +/// @nodoc +mixin _$AppWatchEvent { + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> viewsOrFail) + viewsReceived, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> viewsOrFail)? + viewsReceived, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(ViewsReceived value) viewsReceived, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(ViewsReceived value)? viewsReceived, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $AppWatchEventCopyWith<$Res> { + factory $AppWatchEventCopyWith( + AppWatchEvent value, $Res Function(AppWatchEvent) then) = + _$AppWatchEventCopyWithImpl<$Res>; +} + +/// @nodoc +class _$AppWatchEventCopyWithImpl<$Res> + implements $AppWatchEventCopyWith<$Res> { + _$AppWatchEventCopyWithImpl(this._value, this._then); + + final AppWatchEvent _value; + // ignore: unused_field + final $Res Function(AppWatchEvent) _then; +} + +/// @nodoc +abstract class _$StartedCopyWith<$Res> { + factory _$StartedCopyWith(_Started value, $Res Function(_Started) then) = + __$StartedCopyWithImpl<$Res>; +} + +/// @nodoc +class __$StartedCopyWithImpl<$Res> extends _$AppWatchEventCopyWithImpl<$Res> + implements _$StartedCopyWith<$Res> { + __$StartedCopyWithImpl(_Started _value, $Res Function(_Started) _then) + : super(_value, (v) => _then(v as _Started)); + + @override + _Started get _value => super._value as _Started; +} + +/// @nodoc + +class _$_Started implements _Started { + const _$_Started(); + + @override + String toString() { + return 'AppWatchEvent.started()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || (other is _Started); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> viewsOrFail) + viewsReceived, + }) { + return started(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> viewsOrFail)? + viewsReceived, + required TResult orElse(), + }) { + if (started != null) { + return started(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(ViewsReceived value) viewsReceived, + }) { + return started(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(ViewsReceived value)? viewsReceived, + required TResult orElse(), + }) { + if (started != null) { + return started(this); + } + return orElse(); + } +} + +abstract class _Started implements AppWatchEvent { + const factory _Started() = _$_Started; +} + +/// @nodoc +abstract class $ViewsReceivedCopyWith<$Res> { + factory $ViewsReceivedCopyWith( + ViewsReceived value, $Res Function(ViewsReceived) then) = + _$ViewsReceivedCopyWithImpl<$Res>; + $Res call({Either, WorkspaceError> viewsOrFail}); +} + +/// @nodoc +class _$ViewsReceivedCopyWithImpl<$Res> + extends _$AppWatchEventCopyWithImpl<$Res> + implements $ViewsReceivedCopyWith<$Res> { + _$ViewsReceivedCopyWithImpl( + ViewsReceived _value, $Res Function(ViewsReceived) _then) + : super(_value, (v) => _then(v as ViewsReceived)); + + @override + ViewsReceived get _value => super._value as ViewsReceived; + + @override + $Res call({ + Object? viewsOrFail = freezed, + }) { + return _then(ViewsReceived( + viewsOrFail == freezed + ? _value.viewsOrFail + : viewsOrFail // ignore: cast_nullable_to_non_nullable + as Either, WorkspaceError>, + )); + } +} + +/// @nodoc + +class _$ViewsReceived implements ViewsReceived { + const _$ViewsReceived(this.viewsOrFail); + + @override + final Either, WorkspaceError> viewsOrFail; + + @override + String toString() { + return 'AppWatchEvent.viewsReceived(viewsOrFail: $viewsOrFail)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is ViewsReceived && + (identical(other.viewsOrFail, viewsOrFail) || + const DeepCollectionEquality() + .equals(other.viewsOrFail, viewsOrFail))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(viewsOrFail); + + @JsonKey(ignore: true) + @override + $ViewsReceivedCopyWith get copyWith => + _$ViewsReceivedCopyWithImpl(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> viewsOrFail) + viewsReceived, + }) { + return viewsReceived(viewsOrFail); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> viewsOrFail)? + viewsReceived, + required TResult orElse(), + }) { + if (viewsReceived != null) { + return viewsReceived(viewsOrFail); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(ViewsReceived value) viewsReceived, + }) { + return viewsReceived(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(ViewsReceived value)? viewsReceived, + required TResult orElse(), + }) { + if (viewsReceived != null) { + return viewsReceived(this); + } + return orElse(); + } +} + +abstract class ViewsReceived implements AppWatchEvent { + const factory ViewsReceived(Either, WorkspaceError> viewsOrFail) = + _$ViewsReceived; + + Either, WorkspaceError> get viewsOrFail => + throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $ViewsReceivedCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +class _$AppWatchStateTearOff { + const _$AppWatchStateTearOff(); + + _Initial initial() { + return const _Initial(); + } + + _LoadViews loadViews(List views) { + return _LoadViews( + views, + ); + } + + _LoadFail loadFail(WorkspaceError error) { + return _LoadFail( + error, + ); + } +} + +/// @nodoc +const $AppWatchState = _$AppWatchStateTearOff(); + +/// @nodoc +mixin _$AppWatchState { + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List views) loadViews, + required TResult Function(WorkspaceError error) loadFail, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List views)? loadViews, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadViews value) loadViews, + required TResult Function(_LoadFail value) loadFail, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadViews value)? loadViews, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $AppWatchStateCopyWith<$Res> { + factory $AppWatchStateCopyWith( + AppWatchState value, $Res Function(AppWatchState) then) = + _$AppWatchStateCopyWithImpl<$Res>; +} + +/// @nodoc +class _$AppWatchStateCopyWithImpl<$Res> + implements $AppWatchStateCopyWith<$Res> { + _$AppWatchStateCopyWithImpl(this._value, this._then); + + final AppWatchState _value; + // ignore: unused_field + final $Res Function(AppWatchState) _then; +} + +/// @nodoc +abstract class _$InitialCopyWith<$Res> { + factory _$InitialCopyWith(_Initial value, $Res Function(_Initial) then) = + __$InitialCopyWithImpl<$Res>; +} + +/// @nodoc +class __$InitialCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res> + implements _$InitialCopyWith<$Res> { + __$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then) + : super(_value, (v) => _then(v as _Initial)); + + @override + _Initial get _value => super._value as _Initial; +} + +/// @nodoc + +class _$_Initial implements _Initial { + const _$_Initial(); + + @override + String toString() { + return 'AppWatchState.initial()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || (other is _Initial); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List views) loadViews, + required TResult Function(WorkspaceError error) loadFail, + }) { + return initial(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List views)? loadViews, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (initial != null) { + return initial(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadViews value) loadViews, + required TResult Function(_LoadFail value) loadFail, + }) { + return initial(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadViews value)? loadViews, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (initial != null) { + return initial(this); + } + return orElse(); + } +} + +abstract class _Initial implements AppWatchState { + const factory _Initial() = _$_Initial; +} + +/// @nodoc +abstract class _$LoadViewsCopyWith<$Res> { + factory _$LoadViewsCopyWith( + _LoadViews value, $Res Function(_LoadViews) then) = + __$LoadViewsCopyWithImpl<$Res>; + $Res call({List views}); +} + +/// @nodoc +class __$LoadViewsCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res> + implements _$LoadViewsCopyWith<$Res> { + __$LoadViewsCopyWithImpl(_LoadViews _value, $Res Function(_LoadViews) _then) + : super(_value, (v) => _then(v as _LoadViews)); + + @override + _LoadViews get _value => super._value as _LoadViews; + + @override + $Res call({ + Object? views = freezed, + }) { + return _then(_LoadViews( + views == freezed + ? _value.views + : views // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +class _$_LoadViews implements _LoadViews { + const _$_LoadViews(this.views); + + @override + final List views; + + @override + String toString() { + return 'AppWatchState.loadViews(views: $views)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _LoadViews && + (identical(other.views, views) || + const DeepCollectionEquality().equals(other.views, views))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(views); + + @JsonKey(ignore: true) + @override + _$LoadViewsCopyWith<_LoadViews> get copyWith => + __$LoadViewsCopyWithImpl<_LoadViews>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List views) loadViews, + required TResult Function(WorkspaceError error) loadFail, + }) { + return loadViews(views); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List views)? loadViews, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (loadViews != null) { + return loadViews(views); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadViews value) loadViews, + required TResult Function(_LoadFail value) loadFail, + }) { + return loadViews(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadViews value)? loadViews, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (loadViews != null) { + return loadViews(this); + } + return orElse(); + } +} + +abstract class _LoadViews implements AppWatchState { + const factory _LoadViews(List views) = _$_LoadViews; + + List get views => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$LoadViewsCopyWith<_LoadViews> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$LoadFailCopyWith<$Res> { + factory _$LoadFailCopyWith(_LoadFail value, $Res Function(_LoadFail) then) = + __$LoadFailCopyWithImpl<$Res>; + $Res call({WorkspaceError error}); +} + +/// @nodoc +class __$LoadFailCopyWithImpl<$Res> extends _$AppWatchStateCopyWithImpl<$Res> + implements _$LoadFailCopyWith<$Res> { + __$LoadFailCopyWithImpl(_LoadFail _value, $Res Function(_LoadFail) _then) + : super(_value, (v) => _then(v as _LoadFail)); + + @override + _LoadFail get _value => super._value as _LoadFail; + + @override + $Res call({ + Object? error = freezed, + }) { + return _then(_LoadFail( + error == freezed + ? _value.error + : error // ignore: cast_nullable_to_non_nullable + as WorkspaceError, + )); + } +} + +/// @nodoc + +class _$_LoadFail implements _LoadFail { + const _$_LoadFail(this.error); + + @override + final WorkspaceError error; + + @override + String toString() { + return 'AppWatchState.loadFail(error: $error)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _LoadFail && + (identical(other.error, error) || + const DeepCollectionEquality().equals(other.error, error))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(error); + + @JsonKey(ignore: true) + @override + _$LoadFailCopyWith<_LoadFail> get copyWith => + __$LoadFailCopyWithImpl<_LoadFail>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List views) loadViews, + required TResult Function(WorkspaceError error) loadFail, + }) { + return loadFail(error); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List views)? loadViews, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (loadFail != null) { + return loadFail(error); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadViews value) loadViews, + required TResult Function(_LoadFail value) loadFail, + }) { + return loadFail(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadViews value)? loadViews, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (loadFail != null) { + return loadFail(this); + } + return orElse(); + } +} + +abstract class _LoadFail implements AppWatchState { + const factory _LoadFail(WorkspaceError error) = _$_LoadFail; + + WorkspaceError get error => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$LoadFailCopyWith<_LoadFail> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/app_flowy/lib/home/application/home_bloc.dart b/app_flowy/lib/home/application/home_bloc.dart index f7eeb22332..2a9844ecf1 100644 --- a/app_flowy/lib/home/application/home_bloc.dart +++ b/app_flowy/lib/home/application/home_bloc.dart @@ -4,9 +4,6 @@ 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'; - -part 'home_event.dart'; -part 'home_state.dart'; part 'home_bloc.freezed.dart'; class HomeBloc extends Bloc { @@ -40,3 +37,34 @@ class HomeBloc extends Bloc { return super.close(); } } + +@freezed +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; +} + +@freezed +abstract class HomeState implements _$HomeState { + const factory HomeState({ + required bool isLoading, + required bool forceCollapse, + required PageContext pageContext, + required Option editContext, + }) = _HomeState; + + factory HomeState.initial() => HomeState( + isLoading: false, + forceCollapse: false, + pageContext: const BlankPageContext(), + editContext: none(), + ); +} diff --git a/app_flowy/lib/home/application/home_event.dart b/app_flowy/lib/home/application/home_event.dart deleted file mode 100644 index 76bc5662d8..0000000000 --- a/app_flowy/lib/home/application/home_event.dart +++ /dev/null @@ -1,15 +0,0 @@ -part of 'home_bloc.dart'; - -@freezed -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; -} diff --git a/app_flowy/lib/home/application/home_state.dart b/app_flowy/lib/home/application/home_state.dart deleted file mode 100644 index cc08000edf..0000000000 --- a/app_flowy/lib/home/application/home_state.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of 'home_bloc.dart'; - -@freezed -abstract class HomeState implements _$HomeState { - const factory HomeState({ - required bool isLoading, - required bool forceCollapse, - required PageContext pageContext, - required Option editContext, - }) = _HomeState; - - factory HomeState.initial() => HomeState( - isLoading: false, - forceCollapse: false, - pageContext: const BlankPageContext(), - editContext: none(), - ); -} diff --git a/app_flowy/lib/home/application/menu/menu_bloc.dart b/app_flowy/lib/home/application/menu/menu_bloc.dart index 6894f65e16..d21cf056bf 100644 --- a/app_flowy/lib/home/application/menu/menu_bloc.dart +++ b/app_flowy/lib/home/application/menu/menu_bloc.dart @@ -7,8 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -part 'menu_event.dart'; -part 'menu_state.dart'; + part 'menu_bloc.freezed.dart'; class MenuBloc extends Bloc { @@ -21,12 +20,7 @@ class MenuBloc extends Bloc { ) async* { yield* event.map( initial: (value) async* { - iWorkspaceImpl.startWatching(addAppCallback: (appsOrFail) { - appsOrFail.fold( - (apps) => add(MenuEvent.appsReceived(left(apps))), - (error) => add(MenuEvent.appsReceived(right(error))), - ); - }); + yield* _fetchApps(); }, collapse: (e) async* { final isCollapse = state.isCollapse; @@ -38,12 +32,6 @@ class MenuBloc extends Bloc { createApp: (CreateApp event) async* { yield* _performActionOnCreateApp(event); }, - appsReceived: (AppsReceived value) async* { - yield value.appsOrFail.fold( - (apps) => state.copyWith(apps: some(apps)), - (error) => state.copyWith(successOrFailure: right(error)), - ); - }, ); } @@ -64,8 +52,36 @@ class MenuBloc extends Bloc { }); } - @override - Future close() { - return super.close(); + Stream _fetchApps() async* { + final appsOrFail = await iWorkspaceImpl.getApps(); + yield appsOrFail.fold( + (apps) => state.copyWith(apps: some(apps)), + (error) => state.copyWith(successOrFailure: right(error)), + ); } } + +@freezed +abstract class MenuEvent with _$MenuEvent { + const factory MenuEvent.initial() = _Initial; + const factory MenuEvent.collapse() = Collapse; + const factory MenuEvent.openPage(PageContext context) = OpenPage; + const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp; +} + +@freezed +abstract class MenuState implements _$MenuState { + const factory MenuState({ + required bool isCollapse, + required Option pageContext, + required Option> apps, + required Either successOrFailure, + }) = _MenuState; + + factory MenuState.initial() => MenuState( + isCollapse: false, + pageContext: none(), + apps: none(), + successOrFailure: left(unit), + ); +} diff --git a/app_flowy/lib/home/application/menu/menu_bloc.freezed.dart b/app_flowy/lib/home/application/menu/menu_bloc.freezed.dart index a01f9875c6..0d50d0a4e1 100644 --- a/app_flowy/lib/home/application/menu/menu_bloc.freezed.dart +++ b/app_flowy/lib/home/application/menu/menu_bloc.freezed.dart @@ -36,12 +36,6 @@ class _$MenuEventTearOff { desc: desc, ); } - - AppsReceived appsReceived(Either, WorkspaceError> appsOrFail) { - return AppsReceived( - appsOrFail, - ); - } } /// @nodoc @@ -55,8 +49,6 @@ mixin _$MenuEvent { required TResult Function() collapse, required TResult Function(PageContext context) openPage, required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -65,8 +57,6 @@ mixin _$MenuEvent { TResult Function()? collapse, TResult Function(PageContext context)? openPage, TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -76,7 +66,6 @@ mixin _$MenuEvent { required TResult Function(Collapse value) collapse, required TResult Function(OpenPage value) openPage, required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, }) => throw _privateConstructorUsedError; @optionalTypeArgs @@ -85,7 +74,6 @@ mixin _$MenuEvent { TResult Function(Collapse value)? collapse, TResult Function(OpenPage value)? openPage, TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, required TResult orElse(), }) => throw _privateConstructorUsedError; @@ -147,8 +135,6 @@ class _$_Initial implements _Initial { required TResult Function() collapse, required TResult Function(PageContext context) openPage, required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, }) { return initial(); } @@ -160,8 +146,6 @@ class _$_Initial implements _Initial { TResult Function()? collapse, TResult Function(PageContext context)? openPage, TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, required TResult orElse(), }) { if (initial != null) { @@ -177,7 +161,6 @@ class _$_Initial implements _Initial { required TResult Function(Collapse value) collapse, required TResult Function(OpenPage value) openPage, required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, }) { return initial(this); } @@ -189,7 +172,6 @@ class _$_Initial implements _Initial { TResult Function(Collapse value)? collapse, TResult Function(OpenPage value)? openPage, TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, required TResult orElse(), }) { if (initial != null) { @@ -244,8 +226,6 @@ class _$Collapse implements Collapse { required TResult Function() collapse, required TResult Function(PageContext context) openPage, required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, }) { return collapse(); } @@ -257,8 +237,6 @@ class _$Collapse implements Collapse { TResult Function()? collapse, TResult Function(PageContext context)? openPage, TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, required TResult orElse(), }) { if (collapse != null) { @@ -274,7 +252,6 @@ class _$Collapse implements Collapse { required TResult Function(Collapse value) collapse, required TResult Function(OpenPage value) openPage, required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, }) { return collapse(this); } @@ -286,7 +263,6 @@ class _$Collapse implements Collapse { TResult Function(Collapse value)? collapse, TResult Function(OpenPage value)? openPage, TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, required TResult orElse(), }) { if (collapse != null) { @@ -366,8 +342,6 @@ class _$OpenPage implements OpenPage { required TResult Function() collapse, required TResult Function(PageContext context) openPage, required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, }) { return openPage(context); } @@ -379,8 +353,6 @@ class _$OpenPage implements OpenPage { TResult Function()? collapse, TResult Function(PageContext context)? openPage, TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, required TResult orElse(), }) { if (openPage != null) { @@ -396,7 +368,6 @@ class _$OpenPage implements OpenPage { required TResult Function(Collapse value) collapse, required TResult Function(OpenPage value) openPage, required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, }) { return openPage(this); } @@ -408,7 +379,6 @@ class _$OpenPage implements OpenPage { TResult Function(Collapse value)? collapse, TResult Function(OpenPage value)? openPage, TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, required TResult orElse(), }) { if (openPage != null) { @@ -504,8 +474,6 @@ class _$CreateApp implements CreateApp { required TResult Function() collapse, required TResult Function(PageContext context) openPage, required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, }) { return createApp(name, desc); } @@ -517,8 +485,6 @@ class _$CreateApp implements CreateApp { TResult Function()? collapse, TResult Function(PageContext context)? openPage, TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, required TResult orElse(), }) { if (createApp != null) { @@ -534,7 +500,6 @@ class _$CreateApp implements CreateApp { required TResult Function(Collapse value) collapse, required TResult Function(OpenPage value) openPage, required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, }) { return createApp(this); } @@ -546,7 +511,6 @@ class _$CreateApp implements CreateApp { TResult Function(Collapse value)? collapse, TResult Function(OpenPage value)? openPage, TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, required TResult orElse(), }) { if (createApp != null) { @@ -566,138 +530,6 @@ abstract class CreateApp implements MenuEvent { throw _privateConstructorUsedError; } -/// @nodoc -abstract class $AppsReceivedCopyWith<$Res> { - factory $AppsReceivedCopyWith( - AppsReceived value, $Res Function(AppsReceived) then) = - _$AppsReceivedCopyWithImpl<$Res>; - $Res call({Either, WorkspaceError> appsOrFail}); -} - -/// @nodoc -class _$AppsReceivedCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res> - implements $AppsReceivedCopyWith<$Res> { - _$AppsReceivedCopyWithImpl( - AppsReceived _value, $Res Function(AppsReceived) _then) - : super(_value, (v) => _then(v as AppsReceived)); - - @override - AppsReceived get _value => super._value as AppsReceived; - - @override - $Res call({ - Object? appsOrFail = freezed, - }) { - return _then(AppsReceived( - appsOrFail == freezed - ? _value.appsOrFail - : appsOrFail // ignore: cast_nullable_to_non_nullable - as Either, WorkspaceError>, - )); - } -} - -/// @nodoc - -class _$AppsReceived implements AppsReceived { - const _$AppsReceived(this.appsOrFail); - - @override - final Either, WorkspaceError> appsOrFail; - - @override - String toString() { - return 'MenuEvent.appsReceived(appsOrFail: $appsOrFail)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other is AppsReceived && - (identical(other.appsOrFail, appsOrFail) || - const DeepCollectionEquality() - .equals(other.appsOrFail, appsOrFail))); - } - - @override - int get hashCode => - runtimeType.hashCode ^ const DeepCollectionEquality().hash(appsOrFail); - - @JsonKey(ignore: true) - @override - $AppsReceivedCopyWith get copyWith => - _$AppsReceivedCopyWithImpl(this, _$identity); - - @override - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function() collapse, - required TResult Function(PageContext context) openPage, - required TResult Function(String name, String? desc) createApp, - required TResult Function(Either, WorkspaceError> appsOrFail) - appsReceived, - }) { - return appsReceived(appsOrFail); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function()? collapse, - TResult Function(PageContext context)? openPage, - TResult Function(String name, String? desc)? createApp, - TResult Function(Either, WorkspaceError> appsOrFail)? - appsReceived, - required TResult orElse(), - }) { - if (appsReceived != null) { - return appsReceived(appsOrFail); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Initial value) initial, - required TResult Function(Collapse value) collapse, - required TResult Function(OpenPage value) openPage, - required TResult Function(CreateApp value) createApp, - required TResult Function(AppsReceived value) appsReceived, - }) { - return appsReceived(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Initial value)? initial, - TResult Function(Collapse value)? collapse, - TResult Function(OpenPage value)? openPage, - TResult Function(CreateApp value)? createApp, - TResult Function(AppsReceived value)? appsReceived, - required TResult orElse(), - }) { - if (appsReceived != null) { - return appsReceived(this); - } - return orElse(); - } -} - -abstract class AppsReceived implements MenuEvent { - const factory AppsReceived(Either, WorkspaceError> appsOrFail) = - _$AppsReceived; - - Either, WorkspaceError> get appsOrFail => - throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $AppsReceivedCopyWith get copyWith => - throw _privateConstructorUsedError; -} - /// @nodoc class _$MenuStateTearOff { const _$MenuStateTearOff(); diff --git a/app_flowy/lib/home/application/menu/menu_event.dart b/app_flowy/lib/home/application/menu/menu_event.dart deleted file mode 100644 index 994a898728..0000000000 --- a/app_flowy/lib/home/application/menu/menu_event.dart +++ /dev/null @@ -1,11 +0,0 @@ -part of 'menu_bloc.dart'; - -@freezed -abstract class MenuEvent with _$MenuEvent { - const factory MenuEvent.initial() = _Initial; - const factory MenuEvent.collapse() = Collapse; - const factory MenuEvent.openPage(PageContext context) = OpenPage; - const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp; - const factory MenuEvent.appsReceived( - Either, WorkspaceError> appsOrFail) = AppsReceived; -} diff --git a/app_flowy/lib/home/application/menu/menu_state.dart b/app_flowy/lib/home/application/menu/menu_state.dart deleted file mode 100644 index ac13206d6e..0000000000 --- a/app_flowy/lib/home/application/menu/menu_state.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of 'menu_bloc.dart'; - -@freezed -abstract class MenuState implements _$MenuState { - const factory MenuState({ - required bool isCollapse, - required Option pageContext, - required Option> apps, - required Either successOrFailure, - }) = _MenuState; - - factory MenuState.initial() => MenuState( - isCollapse: false, - pageContext: none(), - apps: none(), - successOrFailure: left(unit), - ); -} diff --git a/app_flowy/lib/home/application/menu/menu_watch.dart b/app_flowy/lib/home/application/menu/menu_watch.dart new file mode 100644 index 0000000000..b2e0d12fb1 --- /dev/null +++ b/app_flowy/lib/home/application/menu/menu_watch.dart @@ -0,0 +1,64 @@ +import 'package:app_flowy/home/domain/i_workspace.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:dartz/dartz.dart'; + +part 'menu_watch.freezed.dart'; + +class MenuWatchBloc extends Bloc { + final IWorkspaceWatch watcher; + MenuWatchBloc(this.watcher) : super(const MenuWatchState.initial()); + + @override + Stream mapEventToState(MenuWatchEvent event) async* { + yield* event.map( + started: (_) async* { + watcher.startWatching( + addAppCallback: (appsOrFail) => _handleAppsOrFail(appsOrFail), + ); + }, + appsReceived: (e) async* { + yield e.appsOrFail.fold( + (apps) => MenuWatchState.loadApps(apps), + (error) => MenuWatchState.loadFail(error), + ); + }, + ); + } + + @override + Future close() async { + await watcher.stopWatching(); + return super.close(); + } + + void _handleAppsOrFail(Either, WorkspaceError> appsOrFail) { + appsOrFail.fold( + (apps) => add(MenuWatchEvent.appsReceived(left(apps))), + (error) => add(MenuWatchEvent.appsReceived(right(error))), + ); + } +} + +@freezed +abstract class MenuWatchEvent with _$MenuWatchEvent { + const factory MenuWatchEvent.started() = _Started; + const factory MenuWatchEvent.appsReceived( + Either, WorkspaceError> appsOrFail) = AppsReceived; +} + +@freezed +abstract class MenuWatchState with _$MenuWatchState { + const factory MenuWatchState.initial() = _Initial; + + const factory MenuWatchState.loadApps( + List apps, + ) = _LoadApps; + + const factory MenuWatchState.loadFail( + WorkspaceError error, + ) = _LoadFail; +} diff --git a/app_flowy/lib/home/application/menu/menu_watch.freezed.dart b/app_flowy/lib/home/application/menu/menu_watch.freezed.dart new file mode 100644 index 0000000000..31d0ed42a0 --- /dev/null +++ b/app_flowy/lib/home/application/menu/menu_watch.freezed.dart @@ -0,0 +1,682 @@ +// 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 'menu_watch.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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 _$MenuWatchEventTearOff { + const _$MenuWatchEventTearOff(); + + _Started started() { + return const _Started(); + } + + AppsReceived appsReceived(Either, WorkspaceError> appsOrFail) { + return AppsReceived( + appsOrFail, + ); + } +} + +/// @nodoc +const $MenuWatchEvent = _$MenuWatchEventTearOff(); + +/// @nodoc +mixin _$MenuWatchEvent { + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> appsOrFail) + appsReceived, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> appsOrFail)? + appsReceived, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(AppsReceived value) appsReceived, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(AppsReceived value)? appsReceived, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $MenuWatchEventCopyWith<$Res> { + factory $MenuWatchEventCopyWith( + MenuWatchEvent value, $Res Function(MenuWatchEvent) then) = + _$MenuWatchEventCopyWithImpl<$Res>; +} + +/// @nodoc +class _$MenuWatchEventCopyWithImpl<$Res> + implements $MenuWatchEventCopyWith<$Res> { + _$MenuWatchEventCopyWithImpl(this._value, this._then); + + final MenuWatchEvent _value; + // ignore: unused_field + final $Res Function(MenuWatchEvent) _then; +} + +/// @nodoc +abstract class _$StartedCopyWith<$Res> { + factory _$StartedCopyWith(_Started value, $Res Function(_Started) then) = + __$StartedCopyWithImpl<$Res>; +} + +/// @nodoc +class __$StartedCopyWithImpl<$Res> extends _$MenuWatchEventCopyWithImpl<$Res> + implements _$StartedCopyWith<$Res> { + __$StartedCopyWithImpl(_Started _value, $Res Function(_Started) _then) + : super(_value, (v) => _then(v as _Started)); + + @override + _Started get _value => super._value as _Started; +} + +/// @nodoc + +class _$_Started implements _Started { + const _$_Started(); + + @override + String toString() { + return 'MenuWatchEvent.started()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || (other is _Started); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> appsOrFail) + appsReceived, + }) { + return started(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> appsOrFail)? + appsReceived, + required TResult orElse(), + }) { + if (started != null) { + return started(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(AppsReceived value) appsReceived, + }) { + return started(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(AppsReceived value)? appsReceived, + required TResult orElse(), + }) { + if (started != null) { + return started(this); + } + return orElse(); + } +} + +abstract class _Started implements MenuWatchEvent { + const factory _Started() = _$_Started; +} + +/// @nodoc +abstract class $AppsReceivedCopyWith<$Res> { + factory $AppsReceivedCopyWith( + AppsReceived value, $Res Function(AppsReceived) then) = + _$AppsReceivedCopyWithImpl<$Res>; + $Res call({Either, WorkspaceError> appsOrFail}); +} + +/// @nodoc +class _$AppsReceivedCopyWithImpl<$Res> + extends _$MenuWatchEventCopyWithImpl<$Res> + implements $AppsReceivedCopyWith<$Res> { + _$AppsReceivedCopyWithImpl( + AppsReceived _value, $Res Function(AppsReceived) _then) + : super(_value, (v) => _then(v as AppsReceived)); + + @override + AppsReceived get _value => super._value as AppsReceived; + + @override + $Res call({ + Object? appsOrFail = freezed, + }) { + return _then(AppsReceived( + appsOrFail == freezed + ? _value.appsOrFail + : appsOrFail // ignore: cast_nullable_to_non_nullable + as Either, WorkspaceError>, + )); + } +} + +/// @nodoc + +class _$AppsReceived implements AppsReceived { + const _$AppsReceived(this.appsOrFail); + + @override + final Either, WorkspaceError> appsOrFail; + + @override + String toString() { + return 'MenuWatchEvent.appsReceived(appsOrFail: $appsOrFail)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is AppsReceived && + (identical(other.appsOrFail, appsOrFail) || + const DeepCollectionEquality() + .equals(other.appsOrFail, appsOrFail))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(appsOrFail); + + @JsonKey(ignore: true) + @override + $AppsReceivedCopyWith get copyWith => + _$AppsReceivedCopyWithImpl(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() started, + required TResult Function(Either, WorkspaceError> appsOrFail) + appsReceived, + }) { + return appsReceived(appsOrFail); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? started, + TResult Function(Either, WorkspaceError> appsOrFail)? + appsReceived, + required TResult orElse(), + }) { + if (appsReceived != null) { + return appsReceived(appsOrFail); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Started value) started, + required TResult Function(AppsReceived value) appsReceived, + }) { + return appsReceived(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Started value)? started, + TResult Function(AppsReceived value)? appsReceived, + required TResult orElse(), + }) { + if (appsReceived != null) { + return appsReceived(this); + } + return orElse(); + } +} + +abstract class AppsReceived implements MenuWatchEvent { + const factory AppsReceived(Either, WorkspaceError> appsOrFail) = + _$AppsReceived; + + Either, WorkspaceError> get appsOrFail => + throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $AppsReceivedCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +class _$MenuWatchStateTearOff { + const _$MenuWatchStateTearOff(); + + _Initial initial() { + return const _Initial(); + } + + _LoadApps loadApps(List apps) { + return _LoadApps( + apps, + ); + } + + _LoadFail loadFail(WorkspaceError error) { + return _LoadFail( + error, + ); + } +} + +/// @nodoc +const $MenuWatchState = _$MenuWatchStateTearOff(); + +/// @nodoc +mixin _$MenuWatchState { + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List apps) loadApps, + required TResult Function(WorkspaceError error) loadFail, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List apps)? loadApps, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadApps value) loadApps, + required TResult Function(_LoadFail value) loadFail, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadApps value)? loadApps, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $MenuWatchStateCopyWith<$Res> { + factory $MenuWatchStateCopyWith( + MenuWatchState value, $Res Function(MenuWatchState) then) = + _$MenuWatchStateCopyWithImpl<$Res>; +} + +/// @nodoc +class _$MenuWatchStateCopyWithImpl<$Res> + implements $MenuWatchStateCopyWith<$Res> { + _$MenuWatchStateCopyWithImpl(this._value, this._then); + + final MenuWatchState _value; + // ignore: unused_field + final $Res Function(MenuWatchState) _then; +} + +/// @nodoc +abstract class _$InitialCopyWith<$Res> { + factory _$InitialCopyWith(_Initial value, $Res Function(_Initial) then) = + __$InitialCopyWithImpl<$Res>; +} + +/// @nodoc +class __$InitialCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res> + implements _$InitialCopyWith<$Res> { + __$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then) + : super(_value, (v) => _then(v as _Initial)); + + @override + _Initial get _value => super._value as _Initial; +} + +/// @nodoc + +class _$_Initial implements _Initial { + const _$_Initial(); + + @override + String toString() { + return 'MenuWatchState.initial()'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || (other is _Initial); + } + + @override + int get hashCode => runtimeType.hashCode; + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List apps) loadApps, + required TResult Function(WorkspaceError error) loadFail, + }) { + return initial(); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List apps)? loadApps, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (initial != null) { + return initial(); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadApps value) loadApps, + required TResult Function(_LoadFail value) loadFail, + }) { + return initial(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadApps value)? loadApps, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (initial != null) { + return initial(this); + } + return orElse(); + } +} + +abstract class _Initial implements MenuWatchState { + const factory _Initial() = _$_Initial; +} + +/// @nodoc +abstract class _$LoadAppsCopyWith<$Res> { + factory _$LoadAppsCopyWith(_LoadApps value, $Res Function(_LoadApps) then) = + __$LoadAppsCopyWithImpl<$Res>; + $Res call({List apps}); +} + +/// @nodoc +class __$LoadAppsCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res> + implements _$LoadAppsCopyWith<$Res> { + __$LoadAppsCopyWithImpl(_LoadApps _value, $Res Function(_LoadApps) _then) + : super(_value, (v) => _then(v as _LoadApps)); + + @override + _LoadApps get _value => super._value as _LoadApps; + + @override + $Res call({ + Object? apps = freezed, + }) { + return _then(_LoadApps( + apps == freezed + ? _value.apps + : apps // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +class _$_LoadApps implements _LoadApps { + const _$_LoadApps(this.apps); + + @override + final List apps; + + @override + String toString() { + return 'MenuWatchState.loadApps(apps: $apps)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _LoadApps && + (identical(other.apps, apps) || + const DeepCollectionEquality().equals(other.apps, apps))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(apps); + + @JsonKey(ignore: true) + @override + _$LoadAppsCopyWith<_LoadApps> get copyWith => + __$LoadAppsCopyWithImpl<_LoadApps>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List apps) loadApps, + required TResult Function(WorkspaceError error) loadFail, + }) { + return loadApps(apps); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List apps)? loadApps, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (loadApps != null) { + return loadApps(apps); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadApps value) loadApps, + required TResult Function(_LoadFail value) loadFail, + }) { + return loadApps(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadApps value)? loadApps, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (loadApps != null) { + return loadApps(this); + } + return orElse(); + } +} + +abstract class _LoadApps implements MenuWatchState { + const factory _LoadApps(List apps) = _$_LoadApps; + + List get apps => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$LoadAppsCopyWith<_LoadApps> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$LoadFailCopyWith<$Res> { + factory _$LoadFailCopyWith(_LoadFail value, $Res Function(_LoadFail) then) = + __$LoadFailCopyWithImpl<$Res>; + $Res call({WorkspaceError error}); +} + +/// @nodoc +class __$LoadFailCopyWithImpl<$Res> extends _$MenuWatchStateCopyWithImpl<$Res> + implements _$LoadFailCopyWith<$Res> { + __$LoadFailCopyWithImpl(_LoadFail _value, $Res Function(_LoadFail) _then) + : super(_value, (v) => _then(v as _LoadFail)); + + @override + _LoadFail get _value => super._value as _LoadFail; + + @override + $Res call({ + Object? error = freezed, + }) { + return _then(_LoadFail( + error == freezed + ? _value.error + : error // ignore: cast_nullable_to_non_nullable + as WorkspaceError, + )); + } +} + +/// @nodoc + +class _$_LoadFail implements _LoadFail { + const _$_LoadFail(this.error); + + @override + final WorkspaceError error; + + @override + String toString() { + return 'MenuWatchState.loadFail(error: $error)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _LoadFail && + (identical(other.error, error) || + const DeepCollectionEquality().equals(other.error, error))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ const DeepCollectionEquality().hash(error); + + @JsonKey(ignore: true) + @override + _$LoadFailCopyWith<_LoadFail> get copyWith => + __$LoadFailCopyWithImpl<_LoadFail>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function() initial, + required TResult Function(List apps) loadApps, + required TResult Function(WorkspaceError error) loadFail, + }) { + return loadFail(error); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function()? initial, + TResult Function(List apps)? loadApps, + TResult Function(WorkspaceError error)? loadFail, + required TResult orElse(), + }) { + if (loadFail != null) { + return loadFail(error); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(_Initial value) initial, + required TResult Function(_LoadApps value) loadApps, + required TResult Function(_LoadFail value) loadFail, + }) { + return loadFail(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(_Initial value)? initial, + TResult Function(_LoadApps value)? loadApps, + TResult Function(_LoadFail value)? loadFail, + required TResult orElse(), + }) { + if (loadFail != null) { + return loadFail(this); + } + return orElse(); + } +} + +abstract class _LoadFail implements MenuWatchState { + const factory _LoadFail(WorkspaceError error) = _$_LoadFail; + + WorkspaceError get error => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + _$LoadFailCopyWith<_LoadFail> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/app_flowy/lib/home/domain/i_app.dart b/app_flowy/lib/home/domain/i_app.dart index 57fc2d3a57..53a9d54eda 100644 --- a/app_flowy/lib/home/domain/i_app.dart +++ b/app_flowy/lib/home/domain/i_app.dart @@ -13,7 +13,9 @@ abstract class IApp { required String name, String? desc, required ViewType viewType}); +} +abstract class IAppWatch { void startWatching( {AppAddViewCallback? addViewCallback, AppUpdatedCallback? updatedCallback}); diff --git a/app_flowy/lib/home/domain/i_workspace.dart b/app_flowy/lib/home/domain/i_workspace.dart index aa8ce916d7..5656ee5b98 100644 --- a/app_flowy/lib/home/domain/i_workspace.dart +++ b/app_flowy/lib/home/domain/i_workspace.dart @@ -9,9 +9,10 @@ abstract class IWorkspace { Future> createApp( {required String name, String? desc}); - Future, WorkspaceError>> getApps( - {required String workspaceId}); + Future, WorkspaceError>> getApps(); +} +abstract class IWorkspaceWatch { void startWatching( {WorkspaceAddAppCallback? addAppCallback, WorkspaceUpdatedCallback? updatedCallback}); diff --git a/app_flowy/lib/home/infrastructure/deps_resolver.dart b/app_flowy/lib/home/infrastructure/deps_resolver.dart index a0543a5a90..8043e963d6 100644 --- a/app_flowy/lib/home/infrastructure/deps_resolver.dart +++ b/app_flowy/lib/home/infrastructure/deps_resolver.dart @@ -1,4 +1,5 @@ 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/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'; @@ -7,21 +8,34 @@ import 'package:get_it/get_it.dart'; class HomeDepsResolver { static Future resolve(GetIt getIt) async { - getIt.registerFactoryParam( - (workspaceId, _) => WorkspaceRepository(workspaceId: workspaceId)); - + //App getIt.registerFactoryParam( (appId, _) => AppRepository(appId: appId)); - - //Interface implementation + getIt.registerFactoryParam( + (appId, _) => AppWatchRepository(appId: appId)); getIt.registerFactoryParam( (appId, _) => IAppImpl(repo: getIt(param1: appId))); + getIt.registerFactoryParam((appId, _) => + IAppWatchImpl(repo: getIt(param1: appId))); + + //workspace + getIt.registerFactoryParam( + (workspaceId, _) => WorkspaceRepo(workspaceId: workspaceId)); + getIt.registerFactoryParam( + (workspaceId, _) => WorkspaceWatchRepo(workspaceId: workspaceId)); getIt.registerFactoryParam((workspacId, _) => - IWorkspaceImpl(repo: getIt(param1: workspacId))); + IWorkspaceImpl(repo: getIt(param1: workspacId))); + getIt.registerFactoryParam((workspacId, _) => + IWorkspaceWatchImpl( + repo: getIt(param1: workspacId))); //Bloc getIt.registerFactoryParam( (workspaceId, _) => MenuBloc(getIt(param1: workspaceId))); + getIt.registerFactoryParam((workspaceId, _) => + MenuWatchBloc(getIt(param1: workspaceId))); + + // AppWatchBloc } } diff --git a/app_flowy/lib/home/infrastructure/i_app_impl.dart b/app_flowy/lib/home/infrastructure/i_app_impl.dart index 084f7ca202..88a2ea8955 100644 --- a/app_flowy/lib/home/infrastructure/i_app_impl.dart +++ b/app_flowy/lib/home/infrastructure/i_app_impl.dart @@ -25,6 +25,13 @@ class IAppImpl extends IApp { required ViewType viewType}) { return repo.createView(appId, name, desc ?? "", viewType); } +} + +class IAppWatchImpl extends IAppWatch { + AppWatchRepository repo; + IAppWatchImpl({ + required this.repo, + }); @override void startWatching( diff --git a/app_flowy/lib/home/infrastructure/i_workspace_impl.dart b/app_flowy/lib/home/infrastructure/i_workspace_impl.dart index 8460646128..ff2afabccc 100644 --- a/app_flowy/lib/home/infrastructure/i_workspace_impl.dart +++ b/app_flowy/lib/home/infrastructure/i_workspace_impl.dart @@ -7,7 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; export 'package:app_flowy/home/domain/i_workspace.dart'; class IWorkspaceImpl extends IWorkspace { - WorkspaceRepository repo; + WorkspaceRepo repo; IWorkspaceImpl({ required this.repo, }); @@ -19,17 +19,21 @@ class IWorkspaceImpl extends IWorkspace { } @override - Future, WorkspaceError>> getApps( - {required String workspaceId}) { - return repo - .getWorkspace(workspaceId: workspaceId, readApps: true) - .then((result) { + Future, WorkspaceError>> getApps() { + return repo.getWorkspace(readApps: true).then((result) { return result.fold( (workspace) => left(workspace.apps.items), (error) => right(error), ); }); } +} + +class IWorkspaceWatchImpl extends IWorkspaceWatch { + WorkspaceWatchRepo repo; + IWorkspaceWatchImpl({ + required this.repo, + }); @override void startWatching( diff --git a/app_flowy/lib/home/infrastructure/repos/app_repo.dart b/app_flowy/lib/home/infrastructure/repos/app_repo.dart index 7a589e356e..740f0751ec 100644 --- a/app_flowy/lib/home/infrastructure/repos/app_repo.dart +++ b/app_flowy/lib/home/infrastructure/repos/app_repo.dart @@ -13,9 +13,6 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pbenum.dart'; import 'package:flowy_sdk/rust_stream.dart'; class AppRepository { - StreamSubscription? _subscription; - AppAddViewCallback? _addViewCallback; - AppUpdatedCallback? _updatedCallback; String appId; AppRepository({ required this.appId, @@ -52,6 +49,19 @@ class AppRepository { ); }); } +} + +class AppWatchRepository { + StreamSubscription? _subscription; + AppAddViewCallback? _addViewCallback; + AppUpdatedCallback? _updatedCallback; + String appId; + late AppRepository _repo; + AppWatchRepository({ + required this.appId, + }) { + _repo = AppRepository(appId: appId); + } void startWatching( {AppAddViewCallback? addViewCallback, @@ -76,7 +86,7 @@ class AppRepository { if (_addViewCallback == null) { return; } - getViews(appId: appId).then((result) { + _repo.getViews(appId: appId).then((result) { result.fold( (views) => _addViewCallback!(left(views)), (error) => _addViewCallback!(right(error)), @@ -87,7 +97,7 @@ class AppRepository { if (_updatedCallback == null) { return; } - getAppDesc().then((result) { + _repo.getAppDesc().then((result) { result.fold( (app) => _updatedCallback!(app.name, app.desc), (error) => Log.error(error), diff --git a/app_flowy/lib/home/infrastructure/repos/workspace_repo.dart b/app_flowy/lib/home/infrastructure/repos/workspace_repo.dart index 2bf615fe54..ed61e622e4 100644 --- a/app_flowy/lib/home/infrastructure/repos/workspace_repo.dart +++ b/app_flowy/lib/home/infrastructure/repos/workspace_repo.dart @@ -12,12 +12,9 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_query.pb.dart'; import 'package:flowy_sdk/rust_stream.dart'; -class WorkspaceRepository { - StreamSubscription? _subscription; - WorkspaceAddAppCallback? _addAppCallback; - WorkspaceUpdatedCallback? _updatedCallback; +class WorkspaceRepo { String workspaceId; - WorkspaceRepository({ + WorkspaceRepo({ required this.workspaceId, }); @@ -39,7 +36,7 @@ class WorkspaceRepository { } Future> getWorkspace( - {required String workspaceId, bool readApps = false}) { + {bool readApps = false}) { final request = QueryWorkspaceRequest.create() ..workspaceId = workspaceId ..readApps = readApps; @@ -51,6 +48,20 @@ class WorkspaceRepository { ); }); } +} + +class WorkspaceWatchRepo { + StreamSubscription? _subscription; + WorkspaceAddAppCallback? _addAppCallback; + WorkspaceUpdatedCallback? _updatedCallback; + final String workspaceId; + late WorkspaceRepo _repo; + + WorkspaceWatchRepo({ + required this.workspaceId, + }) { + _repo = WorkspaceRepo(workspaceId: workspaceId); + } void startWatching( {WorkspaceAddAppCallback? addAppCallback, @@ -76,7 +87,7 @@ class WorkspaceRepository { if (_updatedCallback == null) { return; } - getWorkspace(workspaceId: workspaceId).then((result) { + _repo.getWorkspace().then((result) { result.fold( (workspace) => _updatedCallback!(workspace.name, workspace.desc), (error) => Log.error(error), @@ -87,7 +98,7 @@ class WorkspaceRepository { if (_addAppCallback == null) { return; } - getWorkspace(workspaceId: workspaceId, readApps: true).then((result) { + _repo.getWorkspace(readApps: true).then((result) { result.fold( (workspace) => _addAppCallback!(left(workspace.apps.items)), (error) => _addAppCallback!(right(error)), diff --git a/app_flowy/lib/home/presentation/widgets/app/app_list_widget.dart b/app_flowy/lib/home/presentation/widgets/app/app_list_widget.dart index 1491d430e0..0db1b2504c 100644 --- a/app_flowy/lib/home/presentation/widgets/app/app_list_widget.dart +++ b/app_flowy/lib/home/presentation/widgets/app/app_list_widget.dart @@ -10,39 +10,44 @@ import 'package:flowy_infra_ui/widget/error_page.dart'; import 'app_widget.dart'; +// class AppList extends StatelessWidget { +// const AppList({Key? key}) : super(key: key); +// @override +// Widget build(BuildContext context) { +// return MultiBlocProvider( +// providers: [ +// BlocProvider( +// create: (context) => getIt()..add(const AppEvent.initial()), +// ), +// ], +// child: BlocBuilder( +// buildWhen: (p, c) => p.apps != c.apps, +// builder: (context, state) { +// Log.info('AppList build'); +// if (state.isLoading) { +// return const Center( +// child: CircularProgressIndicator.adaptive(), +// ); +// } + +// return state.apps.fold( +// () => state.successOrFailure.fold( +// (_) => const Text('You have no apps, create one?'), +// (error) => FlowyErrorPage(error.toString()), +// ), +// (apps) => _buildBody(apps), +// ); +// }, +// ), +// ); +// } + class AppList extends StatelessWidget { - const AppList({Key? key}) : super(key: key); + final List apps; + const AppList({required this.apps, Key? key}) : super(key: key); + @override Widget build(BuildContext context) { - return MultiBlocProvider( - providers: [ - BlocProvider( - create: (context) => getIt()..add(const AppEvent.initial()), - ), - ], - child: BlocBuilder( - buildWhen: (p, c) => p.apps != c.apps, - builder: (context, state) { - Log.info('AppList build'); - if (state.isLoading) { - return const Center( - child: CircularProgressIndicator.adaptive(), - ); - } - - return state.apps.fold( - () => state.successOrFailure.fold( - (_) => const Text('You have no apps, create one?'), - (error) => FlowyErrorPage(error.toString()), - ), - (apps) => _buildBody(apps), - ); - }, - ), - ); - } - - Widget _buildBody(List apps) { return ExpandableTheme( data: const ExpandableThemeData( iconColor: Colors.blue, @@ -55,4 +60,18 @@ class AppList extends StatelessWidget { ), )); } + + // Widget _buildBody(List apps) { + // return ExpandableTheme( + // data: const ExpandableThemeData( + // iconColor: Colors.blue, + // useInkWell: true, + // ), + // child: Expanded( + // child: ListView( + // physics: const BouncingScrollPhysics(), + // children: apps.map((app) => AppWidget(app)).toList(), + // ), + // )); + // } } diff --git a/app_flowy/lib/home/presentation/widgets/app/app_widget.dart b/app_flowy/lib/home/presentation/widgets/app/app_widget.dart index e1543d52e2..7fc0b5dfc1 100644 --- a/app_flowy/lib/home/presentation/widgets/app/app_widget.dart +++ b/app_flowy/lib/home/presentation/widgets/app/app_widget.dart @@ -1,7 +1,9 @@ -// ignore: import_of_legacy_library_into_null_safe -import 'package:app_flowy/home/presentation/widgets/menu/hom_menu_size.dart'; +import 'package:app_flowy/home/application/app/app_bloc.dart'; +import 'package:app_flowy/home/presentation/widgets/menu/menu_size.dart'; +import 'package:app_flowy/startup/startup.dart'; import 'package:expandable/expandable.dart'; import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra_ui/widget/error_page.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'; @@ -13,6 +15,22 @@ class AppWidget extends StatelessWidget { @override Widget build(BuildContext context) { + // return MultiBlocProvider( + // providers: [ + // BlocProvider(create: (context) => getIt()), + // ], + // child: BlocBuilder( + // builder: (context, state) { + // // final child = state.map( + // // initial: (_) => const CircularProgressIndicator.adaptive(), + // // loadViews: (s) => ViewList(s.views), + // // successOrFailure: (s) => FlowyErrorPage(s.error), + // // ); + + // return expandableWrapper(context, Container()); + // }, + // ), + // ); return Container(); } @@ -38,6 +56,7 @@ class AppWidget extends StatelessWidget { padding: EdgeInsets.only(left: Sizes.iconMed), child: child, ), + collapsed: const Text("close"), ), ], ), diff --git a/app_flowy/lib/home/presentation/widgets/menu/app_list.dart b/app_flowy/lib/home/presentation/widgets/menu/app_list.dart new file mode 100644 index 0000000000..412d5d5952 --- /dev/null +++ b/app_flowy/lib/home/presentation/widgets/menu/app_list.dart @@ -0,0 +1,29 @@ +import 'package:expandable/expandable.dart'; +import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart'; +import 'package:app_flowy/home/presentation/widgets/app/app_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:dartz/dartz.dart'; + +class AppList extends StatelessWidget { + final Option> apps; + const AppList({required this.apps, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return apps.fold(() { + return const Text('You have no apps, create one?'); + }, (apps) { + return ExpandableTheme( + data: const ExpandableThemeData( + iconColor: Colors.blue, + useInkWell: true, + ), + child: Expanded( + child: ListView( + physics: const BouncingScrollPhysics(), + children: apps.map((app) => AppWidget(app)).toList(), + ), + )); + }); + } +} diff --git a/app_flowy/lib/home/presentation/widgets/menu/home_menu.dart b/app_flowy/lib/home/presentation/widgets/menu/menu.dart similarity index 81% rename from app_flowy/lib/home/presentation/widgets/menu/home_menu.dart rename to app_flowy/lib/home/presentation/widgets/menu/menu.dart index 057738775e..cdd2ca3e4d 100644 --- a/app_flowy/lib/home/presentation/widgets/menu/home_menu.dart +++ b/app_flowy/lib/home/presentation/widgets/menu/menu.dart @@ -1,7 +1,9 @@ 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/presentation/home_sizes.dart'; import 'package:app_flowy/startup/startup.dart'; -import 'package:app_flowy/startup/tasks/app_widget_task.dart'; +import 'package:app_flowy/startup/tasks/application_task.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/text_style.dart'; @@ -9,12 +11,13 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/styled_text_input.dart'; import 'package:flowy_infra_ui/widget/buttons/ok_cancel_button.dart'; import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart'; +import 'package:flowy_infra_ui/widget/error_page.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../home_sizes.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:textstyle_extensions/textstyle_extensions.dart'; +import 'app_list.dart'; class HomeMenu extends StatelessWidget { final Function(Option) pageContextChanged; @@ -30,9 +33,15 @@ class HomeMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocProvider( - create: (context) => - getIt(param1: workspaceId)..add(const MenuEvent.initial()), + return MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => getIt(param1: workspaceId) + ..add(const MenuEvent.initial())), + BlocProvider( + create: (context) => getIt(param1: workspaceId) + ..add(const MenuWatchEvent.started())), + ], child: MultiBlocListener( listeners: [ BlocListener( @@ -58,16 +67,29 @@ class HomeMenu extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ const MenuTopBar(), - Expanded(child: Container()), - NewAppButton( - createAppCallback: (appName) => context - .read() - .add(MenuEvent.createApp(appName, desc: "")), - ), + _renderAppList(context), + _renderNewButton(context), ], ).padding(horizontal: Insets.sm), ); } + + Widget _renderAppList(BuildContext context) { + return BlocBuilder( + builder: (context, state) => state.map( + initial: (_) => AppList(apps: context.read().state.apps), + loadApps: (event) => AppList(apps: some(event.apps)), + loadFail: (error) => FlowyErrorPage(error.toString()), + ), + ); + } + + Widget _renderNewButton(BuildContext context) { + return NewAppButton( + createAppCallback: (appName) => + context.read().add(MenuEvent.createApp(appName, desc: "")), + ); + } } class MenuTopBar extends StatelessWidget { diff --git a/app_flowy/lib/home/presentation/widgets/menu/hom_menu_size.dart b/app_flowy/lib/home/presentation/widgets/menu/menu_size.dart similarity index 100% rename from app_flowy/lib/home/presentation/widgets/menu/hom_menu_size.dart rename to app_flowy/lib/home/presentation/widgets/menu/menu_size.dart diff --git a/app_flowy/lib/home/presentation/widgets/menu/prelude.dart b/app_flowy/lib/home/presentation/widgets/menu/prelude.dart index d3156898d5..c541cb3e36 100644 --- a/app_flowy/lib/home/presentation/widgets/menu/prelude.dart +++ b/app_flowy/lib/home/presentation/widgets/menu/prelude.dart @@ -1,2 +1,2 @@ -export 'home_menu.dart'; -export 'hom_menu_size.dart'; +export 'menu.dart'; +export 'menu_size.dart'; diff --git a/app_flowy/lib/home/presentation/widgets/prelude.dart b/app_flowy/lib/home/presentation/widgets/prelude.dart index e2f412551a..8a9f575646 100644 --- a/app_flowy/lib/home/presentation/widgets/prelude.dart +++ b/app_flowy/lib/home/presentation/widgets/prelude.dart @@ -2,4 +2,4 @@ export './blank_page.dart'; export './edit_pannel/edit_pannel.dart'; export './edit_pannel/pannel_animation.dart'; export './home_top_bar.dart'; -export './menu/home_menu.dart'; +export 'menu/menu.dart'; diff --git a/app_flowy/lib/startup/tasks/app_widget_task.dart b/app_flowy/lib/startup/tasks/application_task.dart similarity index 90% rename from app_flowy/lib/startup/tasks/app_widget_task.dart rename to app_flowy/lib/startup/tasks/application_task.dart index e18ef9a0a8..416310e470 100644 --- a/app_flowy/lib/startup/tasks/app_widget_task.dart +++ b/app_flowy/lib/startup/tasks/application_task.dart @@ -12,16 +12,16 @@ class AppWidgetTask extends LaunchTask { @override Future initialize(LaunchContext context) { final widget = context.getIt().create(); - final app = AppWidget(child: widget); + final app = ApplicationWidget(child: widget); runApp(app); return Future(() => {}); } } -class AppWidget extends StatelessWidget { +class ApplicationWidget extends StatelessWidget { final Widget child; - const AppWidget({ + const ApplicationWidget({ Key? key, required this.child, }) : super(key: key); diff --git a/app_flowy/lib/startup/tasks/prelude.dart b/app_flowy/lib/startup/tasks/prelude.dart index d4474f0342..2e82179a7b 100644 --- a/app_flowy/lib/startup/tasks/prelude.dart +++ b/app_flowy/lib/startup/tasks/prelude.dart @@ -1,2 +1,2 @@ -export 'app_widget_task.dart'; +export 'application_task.dart'; export 'rust_sdk_init_task.dart'; diff --git a/app_flowy/packages/flowy_infra_ui/example/pubspec.lock b/app_flowy/packages/flowy_infra_ui/example/pubspec.lock index c2685ea99f..76f4d31c6c 100644 --- a/app_flowy/packages/flowy_infra_ui/example/pubspec.lock +++ b/app_flowy/packages/flowy_infra_ui/example/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" + version: "2.7.0" boolean_selector: dependency: transitive description: @@ -35,7 +35,7 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: @@ -176,7 +176,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" nested: dependency: transitive description: @@ -258,7 +258,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.4.1" textstyle_extensions: dependency: transitive description: diff --git a/app_flowy/packages/flowy_infra_ui/pubspec.lock b/app_flowy/packages/flowy_infra_ui/pubspec.lock index 98f80cfe2a..e05bfcbe05 100644 --- a/app_flowy/packages/flowy_infra_ui/pubspec.lock +++ b/app_flowy/packages/flowy_infra_ui/pubspec.lock @@ -14,7 +14,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" + version: "2.7.0" boolean_selector: dependency: transitive description: @@ -35,7 +35,7 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: @@ -162,7 +162,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" nested: dependency: transitive description: @@ -244,7 +244,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.4.1" textstyle_extensions: dependency: "direct main" description: diff --git a/app_flowy/pubspec.lock b/app_flowy/pubspec.lock index 32fbd6766c..42a36033ed 100644 --- a/app_flowy/pubspec.lock +++ b/app_flowy/pubspec.lock @@ -203,7 +203,7 @@ packages: name: expandable url: "https://pub.dartlang.org" source: hosted - version: "4.1.4" + version: "5.0.1" fake_async: dependency: transitive description: diff --git a/app_flowy/pubspec.yaml b/app_flowy/pubspec.yaml index 1b89074a0a..9a3afb20c1 100644 --- a/app_flowy/pubspec.yaml +++ b/app_flowy/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: ref: e48abe7c3e9ebfe0b81622167c5201d4e783bb81 sized_context: ^1.0.0+1 styled_widget: '>=0.3.1' - expandable: ^4.1.4 + expandable: ^5.0.1 # The following adds the Cupertino Icons font to your application. diff --git a/rust-lib/dart-ffi/Cargo.toml b/rust-lib/dart-ffi/Cargo.toml index fc345df327..6feb76f4cc 100644 --- a/rust-lib/dart-ffi/Cargo.toml +++ b/rust-lib/dart-ffi/Cargo.toml @@ -7,11 +7,11 @@ edition = "2018" [lib] name = "dart_ffi" # this value will change depending on the target os -# for iOS it would be `rlib` -# for Macos it would be `rlib` +# for iOS it would be `cdylib` +# for Macos it would be `cdylib` # for android it would be `c-dylib` -# default rlib -crate-type = ["rlib"] +# default cdylib +crate-type = ["cdylib"] [dependencies]