From 4f0f4221fc7f6c6e1961bdc51179a96fea4626e4 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 18 Oct 2021 16:30:20 +0800 Subject: [PATCH] [flutter]: add restore & delete all api --- .../workspace/application/app/app_bloc.dart | 8 +- .../application/app/app_listen_bloc.dart | 62 -- .../app/app_listen_bloc.freezed.dart | 684 ------------------ .../application/trash/trash_bloc.dart | 19 +- app_flowy/lib/workspace/domain/i_trash.dart | 4 + .../infrastructure/deps_resolver.dart | 9 +- .../infrastructure/i_trash_impl.dart | 10 + .../infrastructure/repos/trash_repo.dart | 8 + .../src/entities/trash/trash_create.rs | 9 + rust-lib/flowy-workspace/src/macros.rs | 2 +- .../flowy-workspace/src/services/trash_can.rs | 28 +- .../src/services/workspace_controller.rs | 4 +- .../src/sql_tables/trash/trash_sql.rs | 20 +- .../src/sql_tables/trash/trash_table.rs | 18 + 14 files changed, 99 insertions(+), 786 deletions(-) delete mode 100644 app_flowy/lib/workspace/application/app/app_listen_bloc.dart delete mode 100644 app_flowy/lib/workspace/application/app/app_listen_bloc.freezed.dart diff --git a/app_flowy/lib/workspace/application/app/app_bloc.dart b/app_flowy/lib/workspace/application/app/app_bloc.dart index b5da6417c4..b417244367 100644 --- a/app_flowy/lib/workspace/application/app/app_bloc.dart +++ b/app_flowy/lib/workspace/application/app/app_bloc.dart @@ -9,9 +9,9 @@ import 'package:dartz/dartz.dart'; part 'app_bloc.freezed.dart'; class AppBloc extends Bloc { - final IApp iAppImpl; + final IApp appManager; final IAppListenr listener; - AppBloc({required this.iAppImpl, required this.listener}) : super(AppState.initial()); + AppBloc({required this.appManager, required this.listener}) : super(AppState.initial()); @override Stream mapEventToState( @@ -24,7 +24,7 @@ class AppBloc extends Bloc { yield* _fetchViews(); }, createView: (CreateView value) async* { - final viewOrFailed = await iAppImpl.createView(name: value.name, desc: value.desc, viewType: value.viewType); + 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)); @@ -52,7 +52,7 @@ class AppBloc extends Bloc { } Stream _fetchViews() async* { - final viewsOrFailed = await iAppImpl.getViews(); + final viewsOrFailed = await appManager.getViews(); yield viewsOrFailed.fold( (apps) => state.copyWith(views: apps), (error) { diff --git a/app_flowy/lib/workspace/application/app/app_listen_bloc.dart b/app_flowy/lib/workspace/application/app/app_listen_bloc.dart deleted file mode 100644 index c997855a53..0000000000 --- a/app_flowy/lib/workspace/application/app/app_listen_bloc.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:app_flowy/workspace/domain/i_app.dart'; -import 'package:flowy_log/flowy_log.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_listen_bloc.freezed.dart'; - -class AppListenBloc extends Bloc { - final IAppListenr listener; - AppListenBloc(this.listener) : super(const AppListenState.initial()); - - @override - Stream mapEventToState( - AppListenEvent event, - ) async* { - yield* event.map(started: (_) async* { - listener.start( - viewsChangeCallback: (viewsOrFail) => _handleViewsOrFail(viewsOrFail), - ); - }, didReceiveViews: (ViewsReceived value) async* { - yield value.viewsOrFail.fold( - (views) => AppListenState.didReceiveViews(views), - (error) => AppListenState.loadFail(error), - ); - }); - } - - void _handleViewsOrFail(Either, WorkspaceError> viewsOrFail) { - viewsOrFail.fold( - (views) => add(AppListenEvent.didReceiveViews(left(views))), - (error) => add(AppListenEvent.didReceiveViews(right(error))), - ); - } - - @override - Future close() async { - await listener.stop(); - return super.close(); - } -} - -@freezed -class AppListenEvent with _$AppListenEvent { - const factory AppListenEvent.started() = _Started; - const factory AppListenEvent.didReceiveViews(Either, WorkspaceError> viewsOrFail) = ViewsReceived; -} - -@freezed -class AppListenState with _$AppListenState { - const factory AppListenState.initial() = _Initial; - - const factory AppListenState.didReceiveViews( - List views, - ) = _LoadViews; - - const factory AppListenState.loadFail( - WorkspaceError error, - ) = _LoadFail; -} diff --git a/app_flowy/lib/workspace/application/app/app_listen_bloc.freezed.dart b/app_flowy/lib/workspace/application/app/app_listen_bloc.freezed.dart deleted file mode 100644 index f68ddf4352..0000000000 --- a/app_flowy/lib/workspace/application/app/app_listen_bloc.freezed.dart +++ /dev/null @@ -1,684 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target - -part of 'app_listen_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 _$AppListenEventTearOff { - const _$AppListenEventTearOff(); - - _Started started() { - return const _Started(); - } - - ViewsReceived didReceiveViews( - Either, WorkspaceError> viewsOrFail) { - return ViewsReceived( - viewsOrFail, - ); - } -} - -/// @nodoc -const $AppListenEvent = _$AppListenEventTearOff(); - -/// @nodoc -mixin _$AppListenEvent { - @optionalTypeArgs - TResult when({ - required TResult Function() started, - required TResult Function(Either, WorkspaceError> viewsOrFail) - didReceiveViews, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? started, - TResult Function(Either, WorkspaceError> viewsOrFail)? - didReceiveViews, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(_Started value) started, - required TResult Function(ViewsReceived value) didReceiveViews, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Started value)? started, - TResult Function(ViewsReceived value)? didReceiveViews, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AppListenEventCopyWith<$Res> { - factory $AppListenEventCopyWith( - AppListenEvent value, $Res Function(AppListenEvent) then) = - _$AppListenEventCopyWithImpl<$Res>; -} - -/// @nodoc -class _$AppListenEventCopyWithImpl<$Res> - implements $AppListenEventCopyWith<$Res> { - _$AppListenEventCopyWithImpl(this._value, this._then); - - final AppListenEvent _value; - // ignore: unused_field - final $Res Function(AppListenEvent) _then; -} - -/// @nodoc -abstract class _$StartedCopyWith<$Res> { - factory _$StartedCopyWith(_Started value, $Res Function(_Started) then) = - __$StartedCopyWithImpl<$Res>; -} - -/// @nodoc -class __$StartedCopyWithImpl<$Res> extends _$AppListenEventCopyWithImpl<$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 'AppListenEvent.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) - didReceiveViews, - }) { - return started(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? started, - TResult Function(Either, WorkspaceError> viewsOrFail)? - didReceiveViews, - 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) didReceiveViews, - }) { - return started(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Started value)? started, - TResult Function(ViewsReceived value)? didReceiveViews, - required TResult orElse(), - }) { - if (started != null) { - return started(this); - } - return orElse(); - } -} - -abstract class _Started implements AppListenEvent { - 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 _$AppListenEventCopyWithImpl<$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 'AppListenEvent.didReceiveViews(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) - didReceiveViews, - }) { - return didReceiveViews(viewsOrFail); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? started, - TResult Function(Either, WorkspaceError> viewsOrFail)? - didReceiveViews, - required TResult orElse(), - }) { - if (didReceiveViews != null) { - return didReceiveViews(viewsOrFail); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Started value) started, - required TResult Function(ViewsReceived value) didReceiveViews, - }) { - return didReceiveViews(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Started value)? started, - TResult Function(ViewsReceived value)? didReceiveViews, - required TResult orElse(), - }) { - if (didReceiveViews != null) { - return didReceiveViews(this); - } - return orElse(); - } -} - -abstract class ViewsReceived implements AppListenEvent { - const factory ViewsReceived(Either, WorkspaceError> viewsOrFail) = - _$ViewsReceived; - - Either, WorkspaceError> get viewsOrFail => - throw _privateConstructorUsedError; - @JsonKey(ignore: true) - $ViewsReceivedCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -class _$AppListenStateTearOff { - const _$AppListenStateTearOff(); - - _Initial initial() { - return const _Initial(); - } - - _LoadViews didReceiveViews(List views) { - return _LoadViews( - views, - ); - } - - _LoadFail loadFail(WorkspaceError error) { - return _LoadFail( - error, - ); - } -} - -/// @nodoc -const $AppListenState = _$AppListenStateTearOff(); - -/// @nodoc -mixin _$AppListenState { - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - required TResult Function(List views) didReceiveViews, - required TResult Function(WorkspaceError error) loadFail, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(List views)? didReceiveViews, - TResult Function(WorkspaceError error)? loadFail, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(_Initial value) initial, - required TResult Function(_LoadViews value) didReceiveViews, - required TResult Function(_LoadFail value) loadFail, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Initial value)? initial, - TResult Function(_LoadViews value)? didReceiveViews, - TResult Function(_LoadFail value)? loadFail, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $AppListenStateCopyWith<$Res> { - factory $AppListenStateCopyWith( - AppListenState value, $Res Function(AppListenState) then) = - _$AppListenStateCopyWithImpl<$Res>; -} - -/// @nodoc -class _$AppListenStateCopyWithImpl<$Res> - implements $AppListenStateCopyWith<$Res> { - _$AppListenStateCopyWithImpl(this._value, this._then); - - final AppListenState _value; - // ignore: unused_field - final $Res Function(AppListenState) _then; -} - -/// @nodoc -abstract class _$InitialCopyWith<$Res> { - factory _$InitialCopyWith(_Initial value, $Res Function(_Initial) then) = - __$InitialCopyWithImpl<$Res>; -} - -/// @nodoc -class __$InitialCopyWithImpl<$Res> extends _$AppListenStateCopyWithImpl<$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 'AppListenState.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) didReceiveViews, - required TResult Function(WorkspaceError error) loadFail, - }) { - return initial(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(List views)? didReceiveViews, - 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) didReceiveViews, - required TResult Function(_LoadFail value) loadFail, - }) { - return initial(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Initial value)? initial, - TResult Function(_LoadViews value)? didReceiveViews, - TResult Function(_LoadFail value)? loadFail, - required TResult orElse(), - }) { - if (initial != null) { - return initial(this); - } - return orElse(); - } -} - -abstract class _Initial implements AppListenState { - 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 _$AppListenStateCopyWithImpl<$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 'AppListenState.didReceiveViews(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) didReceiveViews, - required TResult Function(WorkspaceError error) loadFail, - }) { - return didReceiveViews(views); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(List views)? didReceiveViews, - TResult Function(WorkspaceError error)? loadFail, - required TResult orElse(), - }) { - if (didReceiveViews != null) { - return didReceiveViews(views); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(_Initial value) initial, - required TResult Function(_LoadViews value) didReceiveViews, - required TResult Function(_LoadFail value) loadFail, - }) { - return didReceiveViews(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Initial value)? initial, - TResult Function(_LoadViews value)? didReceiveViews, - TResult Function(_LoadFail value)? loadFail, - required TResult orElse(), - }) { - if (didReceiveViews != null) { - return didReceiveViews(this); - } - return orElse(); - } -} - -abstract class _LoadViews implements AppListenState { - 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 _$AppListenStateCopyWithImpl<$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 'AppListenState.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) didReceiveViews, - required TResult Function(WorkspaceError error) loadFail, - }) { - return loadFail(error); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - TResult Function(List views)? didReceiveViews, - 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) didReceiveViews, - required TResult Function(_LoadFail value) loadFail, - }) { - return loadFail(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(_Initial value)? initial, - TResult Function(_LoadViews value)? didReceiveViews, - TResult Function(_LoadFail value)? loadFail, - required TResult orElse(), - }) { - if (loadFail != null) { - return loadFail(this); - } - return orElse(); - } -} - -abstract class _LoadFail implements AppListenState { - 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/workspace/application/trash/trash_bloc.dart b/app_flowy/lib/workspace/application/trash/trash_bloc.dart index 8928131910..d9a86ccfe2 100644 --- a/app_flowy/lib/workspace/application/trash/trash_bloc.dart +++ b/app_flowy/lib/workspace/application/trash/trash_bloc.dart @@ -28,20 +28,27 @@ class TrashBloc extends Bloc { }, putback: (e) async* { final result = await iTrash.putback(e.trashId); - yield result.fold( - (l) => state.copyWith(successOrFailure: left(unit)), - (error) => state.copyWith(successOrFailure: right(error)), - ); + yield* _handleResult(result); }, delete: (e) async* { final result = await iTrash.deleteViews([e.trashId]); - result.fold((l) {}, (error) {}); + yield* _handleResult(result); + }, + deleteAll: (e) async* { + final result = await iTrash.deleteAll(); + yield* _handleResult(result); }, - deleteAll: (e) async* {}, restoreAll: (e) async* {}, ); } + Stream _handleResult(Either result) async* { + yield result.fold( + (l) => state.copyWith(successOrFailure: left(unit)), + (error) => state.copyWith(successOrFailure: right(error)), + ); + } + void _listenTrashUpdated(Either, WorkspaceError> trashOrFailed) { trashOrFailed.fold( (trash) { diff --git a/app_flowy/lib/workspace/domain/i_trash.dart b/app_flowy/lib/workspace/domain/i_trash.dart index 1c9c7313d3..13b3596aed 100644 --- a/app_flowy/lib/workspace/domain/i_trash.dart +++ b/app_flowy/lib/workspace/domain/i_trash.dart @@ -9,6 +9,10 @@ abstract class ITrash { Future> putback(String trashId); Future> deleteViews(List trashIds); + + Future> restoreAll(); + + Future> deleteAll(); } typedef TrashUpdatedCallback = void Function(Either, WorkspaceError> trashOrFailed); diff --git a/app_flowy/lib/workspace/infrastructure/deps_resolver.dart b/app_flowy/lib/workspace/infrastructure/deps_resolver.dart index 5459c7b832..42836d6b00 100644 --- a/app_flowy/lib/workspace/infrastructure/deps_resolver.dart +++ b/app_flowy/lib/workspace/infrastructure/deps_resolver.dart @@ -1,5 +1,4 @@ import 'package:app_flowy/workspace/application/app/app_bloc.dart'; -import 'package:app_flowy/workspace/application/app/app_listen_bloc.dart'; import 'package:app_flowy/workspace/application/doc/doc_bloc.dart'; import 'package:app_flowy/workspace/application/doc/doc_edit_bloc.dart'; import 'package:app_flowy/workspace/application/menu/menu_bloc.dart'; @@ -56,7 +55,7 @@ class HomeDepsResolver { (view, _) => IViewListenerImpl(repo: ViewListenerRepository(view: view))); getIt.registerFactoryParam( (view, _) => ViewBloc( - iViewImpl: getIt(param1: view), + viewManager: getIt(param1: view), listener: getIt(param1: view), ), ); @@ -80,12 +79,10 @@ class HomeDepsResolver { // App getIt.registerFactoryParam( (appId, _) => AppBloc( - iAppImpl: getIt(param1: appId), + appManager: getIt(param1: appId), listener: getIt(param1: appId), ), ); - getIt.registerFactoryParam( - (appId, _) => AppListenBloc(getIt(param1: appId))); // Doc getIt.registerFactoryParam((docId, _) => DocBloc(iDocImpl: getIt(param1: docId))); @@ -96,6 +93,6 @@ class HomeDepsResolver { getIt.registerLazySingleton(() => TrashListenerRepo()); getIt.registerFactory(() => ITrashImpl(repo: getIt())); getIt.registerFactory(() => ITrashListenerImpl(repo: getIt())); - getIt.registerFactory(() => TrashBloc(iTrash: getIt(), listener: getIt())); + getIt.registerFactory(() => TrashBloc(trasnManager: getIt(), listener: getIt())); } } diff --git a/app_flowy/lib/workspace/infrastructure/i_trash_impl.dart b/app_flowy/lib/workspace/infrastructure/i_trash_impl.dart index 19578defd0..6cc4949030 100644 --- a/app_flowy/lib/workspace/infrastructure/i_trash_impl.dart +++ b/app_flowy/lib/workspace/infrastructure/i_trash_impl.dart @@ -28,6 +28,16 @@ class ITrashImpl implements ITrash { Future> deleteViews(List trashIds) { return repo.deleteViews(trashIds); } + + @override + Future> deleteAll() { + return repo.deleteAll(); + } + + @override + Future> restoreAll() { + return repo.restoreAll(); + } } class ITrashListenerImpl extends ITrashListener { diff --git a/app_flowy/lib/workspace/infrastructure/repos/trash_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/trash_repo.dart index 46a4653303..77aea49d3f 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/trash_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/trash_repo.dart @@ -29,6 +29,14 @@ class TrashRepo { return WorkspaceEventDeleteTrash(trashIdentifiers).send(); } + + Future> restoreAll() { + return WorkspaceEventRestoreAll().send(); + } + + Future> deleteAll() { + return WorkspaceEventDeleteAll().send(); + } } class TrashListenerRepo { diff --git a/rust-lib/flowy-workspace/src/entities/trash/trash_create.rs b/rust-lib/flowy-workspace/src/entities/trash/trash_create.rs index 554ea490a0..bcbb8c8188 100644 --- a/rust-lib/flowy-workspace/src/entities/trash/trash_create.rs +++ b/rust-lib/flowy-workspace/src/entities/trash/trash_create.rs @@ -53,6 +53,15 @@ pub struct TrashIdentifier { pub ty: TrashType, } +impl std::convert::From<&Trash> for TrashIdentifier { + fn from(trash: &Trash) -> Self { + TrashIdentifier { + id: trash.id.clone(), + ty: trash.ty.clone(), + } + } +} + #[derive(PartialEq, ProtoBuf, Default, Debug, Clone)] pub struct Trash { #[pb(index = 1)] diff --git a/rust-lib/flowy-workspace/src/macros.rs b/rust-lib/flowy-workspace/src/macros.rs index 0df3b686a2..44bae654bb 100644 --- a/rust-lib/flowy-workspace/src/macros.rs +++ b/rust-lib/flowy-workspace/src/macros.rs @@ -23,7 +23,7 @@ macro_rules! impl_def_and_def_mut { impl $target { #[allow(dead_code)] - pub fn take_items(&mut self) -> Vec<$item> { ::std::mem::replace(&mut self.items, vec![]) } + pub fn into_inner(&mut self) -> Vec<$item> { ::std::mem::replace(&mut self.items, vec![]) } #[allow(dead_code)] pub fn push(&mut self, item: $item) { diff --git a/rust-lib/flowy-workspace/src/services/trash_can.rs b/rust-lib/flowy-workspace/src/services/trash_can.rs index 4dd07f17c0..d2ea823c34 100644 --- a/rust-lib/flowy-workspace/src/services/trash_can.rs +++ b/rust-lib/flowy-workspace/src/services/trash_can.rs @@ -42,7 +42,7 @@ impl TrashCan { pub fn trash_ids(&self, conn: &SqliteConnection) -> Result, WorkspaceError> { let ids = TrashTableSql::read_all(&*conn)? - .take_items() + .into_inner() .into_iter() .map(|item| item.id) .collect::>(); @@ -113,20 +113,16 @@ impl TrashCan { #[tracing::instrument(level = "debug", skip(self, trash), err)] pub async fn add>(&self, trash: Vec) -> Result<(), WorkspaceError> { let (tx, mut rx) = mpsc::channel::>(1); - let trash = trash.into_iter().map(|t| t.into()).collect::>(); - let mut items = vec![]; + let repeated_trash = trash.into_iter().map(|t| t.into()).collect::>(); + let identifiers = repeated_trash + .iter() + .map(|t| t.into()) + .collect::>(); let _ = thread::scope(|_s| { let conn = self.database.db_connection()?; conn.immediate_transaction::<_, WorkspaceError, _>(|| { - for t in &trash { - log::debug!("create trash: {:?}", t); - items.push(TrashIdentifier { - id: t.id.clone(), - ty: t.ty.clone(), - }); - let _ = TrashTableSql::create_trash(t.clone().into(), &*conn)?; - } - self.create_trash_on_server(trash); + let _ = TrashTableSql::create_trash(repeated_trash.clone(), &*conn)?; + self.create_trash_on_server(repeated_trash); notify_trash_num_changed(TrashTableSql::read_all(&conn)?); Ok(()) })?; @@ -134,7 +130,7 @@ impl TrashCan { }) .unwrap()?; - let _ = self.notify.send(TrashEvent::NewTrash(items.into(), tx)); + let _ = self.notify.send(TrashEvent::NewTrash(identifiers.into(), tx)); let _ = rx.recv().await.unwrap()?; Ok(()) @@ -185,10 +181,7 @@ impl TrashCan { match pool.get() { Ok(conn) => { let result = conn.immediate_transaction::<_, WorkspaceError, _>(|| { - for trash in &repeated_trash.items { - let _ = TrashTableSql::create_trash(trash.clone().into(), &*conn)?; - } - Ok(()) + TrashTableSql::create_trash(repeated_trash.items.clone(), &*conn) }); match result { @@ -214,7 +207,6 @@ impl TrashCan { #[tracing::instrument(skip(repeated_trash), fields(trash_count))] fn notify_trash_num_changed(repeated_trash: RepeatedTrash) { tracing::Span::current().record("trash_count", &repeated_trash.len()); - send_anonymous_dart_notification(WorkspaceNotification::TrashUpdated) .payload(repeated_trash) .send(); diff --git a/rust-lib/flowy-workspace/src/services/workspace_controller.rs b/rust-lib/flowy-workspace/src/services/workspace_controller.rs index 92e18a8595..279e62919b 100644 --- a/rust-lib/flowy-workspace/src/services/workspace_controller.rs +++ b/rust-lib/flowy-workspace/src/services/workspace_controller.rs @@ -274,13 +274,13 @@ impl WorkspaceController { log::debug!("Save {} workspace", workspaces.len()); for workspace in &workspaces.items { let mut m_workspace = workspace.clone(); - let apps = m_workspace.apps.take_items(); + let apps = m_workspace.apps.into_inner(); let workspace_table = WorkspaceTable::new(m_workspace, &user_id); let _ = workspace_sql.create_workspace(workspace_table, &*conn)?; log::debug!("Save {} apps", apps.len()); for mut app in apps { - let views = app.belongings.take_items(); + let views = app.belongings.into_inner(); match app_ctrl.save_app(app, &*conn) { Ok(_) => {}, Err(e) => log::error!("create app failed: {:?}", e), diff --git a/rust-lib/flowy-workspace/src/sql_tables/trash/trash_sql.rs b/rust-lib/flowy-workspace/src/sql_tables/trash/trash_sql.rs index 85c6acc3d7..23e003caf1 100644 --- a/rust-lib/flowy-workspace/src/sql_tables/trash/trash_sql.rs +++ b/rust-lib/flowy-workspace/src/sql_tables/trash/trash_sql.rs @@ -1,4 +1,8 @@ -use crate::{entities::trash::RepeatedTrash, errors::WorkspaceError, sql_tables::trash::TrashTable}; +use crate::{ + entities::trash::RepeatedTrash, + errors::WorkspaceError, + sql_tables::trash::{TrashTable, TrashTableChangeset}, +}; use crate::entities::trash::Trash; use flowy_database::{ @@ -10,8 +14,18 @@ use flowy_database::{ pub struct TrashTableSql {} impl TrashTableSql { - pub(crate) fn create_trash(trash_table: TrashTable, conn: &SqliteConnection) -> Result<(), WorkspaceError> { - diesel_insert_table!(trash_table, &trash_table, conn); + pub(crate) fn create_trash(repeated_trash: Vec, conn: &SqliteConnection) -> Result<(), WorkspaceError> { + for trash in repeated_trash { + let trash_table: TrashTable = trash.into(); + match diesel_record_count!(trash_table, &trash_table.id, conn) { + 0 => diesel_insert_table!(trash_table, &trash_table, conn), + _ => { + let changeset = TrashTableChangeset::from(trash_table); + diesel_update_table!(trash_table, changeset, conn) + }, + } + } + Ok(()) } diff --git a/rust-lib/flowy-workspace/src/sql_tables/trash/trash_table.rs b/rust-lib/flowy-workspace/src/sql_tables/trash/trash_table.rs index 2ec9c0af8a..8b682056d1 100644 --- a/rust-lib/flowy-workspace/src/sql_tables/trash/trash_table.rs +++ b/rust-lib/flowy-workspace/src/sql_tables/trash/trash_table.rs @@ -37,6 +37,24 @@ impl std::convert::From for TrashTable { } } +#[derive(AsChangeset, Identifiable, Clone, Default, Debug)] +#[table_name = "trash_table"] +pub(crate) struct TrashTableChangeset { + pub id: String, + pub name: Option, + pub modified_time: i64, +} + +impl std::convert::From for TrashTableChangeset { + fn from(trash: TrashTable) -> Self { + TrashTableChangeset { + id: trash.id, + name: Some(trash.name), + modified_time: trash.modified_time, + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, FromSqlRow, AsExpression)] #[repr(i32)] #[sql_type = "Integer"]