diff --git a/app_flowy/lib/startup/tasks/sdk_task.dart b/app_flowy/lib/startup/tasks/sdk_task.dart index ce0dd1284b..df695241af 100644 --- a/app_flowy/lib/startup/tasks/sdk_task.dart +++ b/app_flowy/lib/startup/tasks/sdk_task.dart @@ -40,7 +40,7 @@ class ApplicationBlocObserver extends BlocObserver { @override // ignore: unnecessary_overrides void onTransition(Bloc bloc, Transition transition) { - // Log.debug("[current]: ${transition.currentState} \n[next]: ${transition.nextState}"); + Log.debug("[current]: ${transition.currentState} \n[next]: ${transition.nextState}"); super.onTransition(bloc, transition); } diff --git a/app_flowy/lib/workspace/application/trash/trash_bloc.dart b/app_flowy/lib/workspace/application/trash/trash_bloc.dart index 1991f6e225..8e9b0afdc5 100644 --- a/app_flowy/lib/workspace/application/trash/trash_bloc.dart +++ b/app_flowy/lib/workspace/application/trash/trash_bloc.dart @@ -28,7 +28,10 @@ class TrashBloc extends Bloc { }, putback: (e) async* { final result = await iTrash.putback(e.trashId); - result.fold((l) {}, (error) {}); + yield result.fold( + (l) => state.copyWith(successOrFailure: left(unit)), + (error) => state.copyWith(successOrFailure: right(error)), + ); }, delete: (e) async* { final result = await iTrash.delete(e.trashId); diff --git a/app_flowy/lib/workspace/application/view/view_bloc.dart b/app_flowy/lib/workspace/application/view/view_bloc.dart index b8a9b98cab..d9d95d5442 100644 --- a/app_flowy/lib/workspace/application/view/view_bloc.dart +++ b/app_flowy/lib/workspace/application/view/view_bloc.dart @@ -32,7 +32,7 @@ class ViewBloc extends Bloc { (error) => state.copyWith(successOrFailure: right(error)), ); }, delete: (e) async* { - final result = await iViewImpl.pushIntoTrash(); + final result = await iViewImpl.delete(); yield result.fold( (l) => state.copyWith(successOrFailure: left(unit)), (error) => state.copyWith(successOrFailure: right(error)), diff --git a/app_flowy/lib/workspace/application/view/view_edit_bloc.dart b/app_flowy/lib/workspace/application/view/view_edit_bloc.dart deleted file mode 100644 index 6bf9ec1dd8..0000000000 --- a/app_flowy/lib/workspace/application/view/view_edit_bloc.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:dartz/dartz.dart'; -import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:app_flowy/workspace/domain/i_view.dart'; - -part 'view_edit_bloc.freezed.dart'; - -class ViewEditBloc extends Bloc { - final IView iViewImpl; - - ViewEditBloc({ - required this.iViewImpl, - }) : super(ViewEditState.initial()); - - @override - Stream mapEventToState(ViewEditEvent event) async* { - yield* event.map(initial: (_) async* { - yield state; - }); - } -} - -@freezed -class ViewEditEvent with _$ViewEditEvent { - const factory ViewEditEvent.initial() = Initial; -} - -@freezed -class ViewEditState with _$ViewEditState { - const factory ViewEditState({ - required bool isLoading, - required Option view, - required Either successOrFailure, - }) = _ViewState; - - factory ViewEditState.initial() => ViewEditState( - isLoading: false, - view: none(), - successOrFailure: left(unit), - ); -} diff --git a/app_flowy/lib/workspace/application/view/view_edit_bloc.freezed.dart b/app_flowy/lib/workspace/application/view/view_edit_bloc.freezed.dart deleted file mode 100644 index d9c0ef7150..0000000000 --- a/app_flowy/lib/workspace/application/view/view_edit_bloc.freezed.dart +++ /dev/null @@ -1,332 +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 'view_edit_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 _$ViewEditEventTearOff { - const _$ViewEditEventTearOff(); - - Initial initial() { - return const Initial(); - } -} - -/// @nodoc -const $ViewEditEvent = _$ViewEditEventTearOff(); - -/// @nodoc -mixin _$ViewEditEvent { - @optionalTypeArgs - TResult when({ - required TResult Function() initial, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult map({ - required TResult Function(Initial value) initial, - }) => - throw _privateConstructorUsedError; - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Initial value)? initial, - required TResult orElse(), - }) => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ViewEditEventCopyWith<$Res> { - factory $ViewEditEventCopyWith( - ViewEditEvent value, $Res Function(ViewEditEvent) then) = - _$ViewEditEventCopyWithImpl<$Res>; -} - -/// @nodoc -class _$ViewEditEventCopyWithImpl<$Res> - implements $ViewEditEventCopyWith<$Res> { - _$ViewEditEventCopyWithImpl(this._value, this._then); - - final ViewEditEvent _value; - // ignore: unused_field - final $Res Function(ViewEditEvent) _then; -} - -/// @nodoc -abstract class $InitialCopyWith<$Res> { - factory $InitialCopyWith(Initial value, $Res Function(Initial) then) = - _$InitialCopyWithImpl<$Res>; -} - -/// @nodoc -class _$InitialCopyWithImpl<$Res> extends _$ViewEditEventCopyWithImpl<$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 'ViewEditEvent.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, - }) { - return initial(); - } - - @override - @optionalTypeArgs - TResult maybeWhen({ - TResult Function()? initial, - required TResult orElse(), - }) { - if (initial != null) { - return initial(); - } - return orElse(); - } - - @override - @optionalTypeArgs - TResult map({ - required TResult Function(Initial value) initial, - }) { - return initial(this); - } - - @override - @optionalTypeArgs - TResult maybeMap({ - TResult Function(Initial value)? initial, - required TResult orElse(), - }) { - if (initial != null) { - return initial(this); - } - return orElse(); - } -} - -abstract class Initial implements ViewEditEvent { - const factory Initial() = _$Initial; -} - -/// @nodoc -class _$ViewEditStateTearOff { - const _$ViewEditStateTearOff(); - - _ViewState call( - {required bool isLoading, - required Option view, - required Either successOrFailure}) { - return _ViewState( - isLoading: isLoading, - view: view, - successOrFailure: successOrFailure, - ); - } -} - -/// @nodoc -const $ViewEditState = _$ViewEditStateTearOff(); - -/// @nodoc -mixin _$ViewEditState { - bool get isLoading => throw _privateConstructorUsedError; - Option get view => throw _privateConstructorUsedError; - Either get successOrFailure => - throw _privateConstructorUsedError; - - @JsonKey(ignore: true) - $ViewEditStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ViewEditStateCopyWith<$Res> { - factory $ViewEditStateCopyWith( - ViewEditState value, $Res Function(ViewEditState) then) = - _$ViewEditStateCopyWithImpl<$Res>; - $Res call( - {bool isLoading, - Option view, - Either successOrFailure}); -} - -/// @nodoc -class _$ViewEditStateCopyWithImpl<$Res> - implements $ViewEditStateCopyWith<$Res> { - _$ViewEditStateCopyWithImpl(this._value, this._then); - - final ViewEditState _value; - // ignore: unused_field - final $Res Function(ViewEditState) _then; - - @override - $Res call({ - Object? isLoading = freezed, - Object? view = freezed, - Object? successOrFailure = freezed, - }) { - return _then(_value.copyWith( - isLoading: isLoading == freezed - ? _value.isLoading - : isLoading // ignore: cast_nullable_to_non_nullable - as bool, - view: view == freezed - ? _value.view - : view // ignore: cast_nullable_to_non_nullable - as Option, - successOrFailure: successOrFailure == freezed - ? _value.successOrFailure - : successOrFailure // ignore: cast_nullable_to_non_nullable - as Either, - )); - } -} - -/// @nodoc -abstract class _$ViewStateCopyWith<$Res> - implements $ViewEditStateCopyWith<$Res> { - factory _$ViewStateCopyWith( - _ViewState value, $Res Function(_ViewState) then) = - __$ViewStateCopyWithImpl<$Res>; - @override - $Res call( - {bool isLoading, - Option view, - Either successOrFailure}); -} - -/// @nodoc -class __$ViewStateCopyWithImpl<$Res> extends _$ViewEditStateCopyWithImpl<$Res> - implements _$ViewStateCopyWith<$Res> { - __$ViewStateCopyWithImpl(_ViewState _value, $Res Function(_ViewState) _then) - : super(_value, (v) => _then(v as _ViewState)); - - @override - _ViewState get _value => super._value as _ViewState; - - @override - $Res call({ - Object? isLoading = freezed, - Object? view = freezed, - Object? successOrFailure = freezed, - }) { - return _then(_ViewState( - isLoading: isLoading == freezed - ? _value.isLoading - : isLoading // ignore: cast_nullable_to_non_nullable - as bool, - view: view == freezed - ? _value.view - : view // ignore: cast_nullable_to_non_nullable - as Option, - successOrFailure: successOrFailure == freezed - ? _value.successOrFailure - : successOrFailure // ignore: cast_nullable_to_non_nullable - as Either, - )); - } -} - -/// @nodoc - -class _$_ViewState implements _ViewState { - const _$_ViewState( - {required this.isLoading, - required this.view, - required this.successOrFailure}); - - @override - final bool isLoading; - @override - final Option view; - @override - final Either successOrFailure; - - @override - String toString() { - return 'ViewEditState(isLoading: $isLoading, view: $view, successOrFailure: $successOrFailure)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other is _ViewState && - (identical(other.isLoading, isLoading) || - const DeepCollectionEquality() - .equals(other.isLoading, isLoading)) && - (identical(other.view, view) || - const DeepCollectionEquality().equals(other.view, view)) && - (identical(other.successOrFailure, successOrFailure) || - const DeepCollectionEquality() - .equals(other.successOrFailure, successOrFailure))); - } - - @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(isLoading) ^ - const DeepCollectionEquality().hash(view) ^ - const DeepCollectionEquality().hash(successOrFailure); - - @JsonKey(ignore: true) - @override - _$ViewStateCopyWith<_ViewState> get copyWith => - __$ViewStateCopyWithImpl<_ViewState>(this, _$identity); -} - -abstract class _ViewState implements ViewEditState { - const factory _ViewState( - {required bool isLoading, - required Option view, - required Either successOrFailure}) = _$_ViewState; - - @override - bool get isLoading => throw _privateConstructorUsedError; - @override - Option get view => throw _privateConstructorUsedError; - @override - Either get successOrFailure => - throw _privateConstructorUsedError; - @override - @JsonKey(ignore: true) - _$ViewStateCopyWith<_ViewState> get copyWith => - throw _privateConstructorUsedError; -} diff --git a/app_flowy/lib/workspace/domain/i_view.dart b/app_flowy/lib/workspace/domain/i_view.dart index 8d128bd2dd..972bad6fd6 100644 --- a/app_flowy/lib/workspace/domain/i_view.dart +++ b/app_flowy/lib/workspace/domain/i_view.dart @@ -7,7 +7,7 @@ typedef ViewUpdatedCallback = void Function(Either); abstract class IView { View get view; - Future> pushIntoTrash(); + Future> delete(); Future> rename(String newName); } diff --git a/app_flowy/lib/workspace/infrastructure/i_view_impl.dart b/app_flowy/lib/workspace/infrastructure/i_view_impl.dart index 6d774be988..43bf55ec90 100644 --- a/app_flowy/lib/workspace/infrastructure/i_view_impl.dart +++ b/app_flowy/lib/workspace/infrastructure/i_view_impl.dart @@ -13,8 +13,8 @@ class IViewImpl extends IView { View get view => repo.view; @override - Future> pushIntoTrash() { - return repo.updateView(isTrash: true).then((result) { + Future> delete() { + return repo.delete().then((result) { return result.fold( (_) => left(unit), (error) => right(error), diff --git a/app_flowy/lib/workspace/infrastructure/repos/app_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/app_repo.dart index 450bb997db..dc1d317fd8 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/app_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/app_repo.dart @@ -21,9 +21,7 @@ class AppRepository { }); Future> getAppDesc() { - final request = QueryAppRequest.create() - ..appId = appId - ..readBelongings = false; + final request = QueryAppRequest.create()..appId = appId; return WorkspaceEventReadApp(request).send(); } @@ -39,9 +37,7 @@ class AppRepository { } Future, WorkspaceError>> getViews() { - final request = QueryAppRequest.create() - ..appId = appId - ..readBelongings = true; + final request = QueryAppRequest.create()..appId = appId; return WorkspaceEventReadApp(request).send().then((result) { return result.fold( diff --git a/app_flowy/lib/workspace/infrastructure/repos/view_repo.dart b/app_flowy/lib/workspace/infrastructure/repos/view_repo.dart index 0cafc66980..9c46985a97 100644 --- a/app_flowy/lib/workspace/infrastructure/repos/view_repo.dart +++ b/app_flowy/lib/workspace/infrastructure/repos/view_repo.dart @@ -26,7 +26,7 @@ class ViewRepository { return WorkspaceEventReadView(request).send(); } - Future> updateView({String? name, String? desc, bool? isTrash}) { + Future> updateView({String? name, String? desc}) { final request = UpdateViewRequest.create()..viewId = view.id; if (name != null) { @@ -37,15 +37,11 @@ class ViewRepository { request.desc = desc; } - if (isTrash != null) { - request.isTrash = isTrash; - } - return WorkspaceEventUpdateView(request).send(); } Future> delete() { - final request = DeleteViewRequest.create()..viewId = view.id; + final request = DeleteViewRequest.create()..viewIds.add(view.id); return WorkspaceEventDeleteView(request).send(); } } diff --git a/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart b/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart index 559b657a82..6f7a691597 100644 --- a/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart +++ b/app_flowy/lib/workspace/presentation/stack_page/trash/trash_page.dart @@ -149,7 +149,9 @@ class _TrashStackPageState extends State { height: 42, child: TrashCell( object: object, - onRestore: () => context.read().add(TrashEvent.putback(object.id)), + onRestore: () { + context.read().add(TrashEvent.putback(object.id)); + }, onDelete: () => context.read().add(TrashEvent.delete(object.id)), ), ); diff --git a/rust-lib/flowy-workspace/src/handlers/trash_handler.rs b/rust-lib/flowy-workspace/src/handlers/trash_handler.rs index a769a140d4..655e013d36 100644 --- a/rust-lib/flowy-workspace/src/handlers/trash_handler.rs +++ b/rust-lib/flowy-workspace/src/handlers/trash_handler.rs @@ -1,16 +1,15 @@ use crate::{ - entities::{ - trash::{RepeatedTrash, TrashIdentifier}, - }, + entities::trash::{RepeatedTrash, TrashIdentifier}, errors::WorkspaceError, services::TrashCan, }; use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit}; -use std::{sync::Arc}; +use std::sync::Arc; #[tracing::instrument(skip(controller), err)] pub(crate) async fn read_trash_handler(controller: Unit>) -> DataResult { - let repeated_trash = controller.read_trash()?; + let conn = controller.database.db_connection()?; + let repeated_trash = controller.read_trash(&conn)?; data_result(repeated_trash) } diff --git a/rust-lib/flowy-workspace/src/services/trash_can.rs b/rust-lib/flowy-workspace/src/services/trash_can.rs index 090a225d6e..49aa7c19cf 100644 --- a/rust-lib/flowy-workspace/src/services/trash_can.rs +++ b/rust-lib/flowy-workspace/src/services/trash_can.rs @@ -41,7 +41,7 @@ impl TrashEvent { } pub struct TrashCan { - database: Arc, + pub database: Arc, notify: broadcast::Sender, } @@ -51,16 +51,36 @@ impl TrashCan { Self { database, notify: tx } } - pub fn read_trash(&self) -> Result { - let conn = self.database.db_connection()?; + + pub fn read_trash(&self, conn: &SqliteConnection) -> Result { let repeated_trash = TrashTableSql::read_all(&*conn)?; Ok(repeated_trash) } + pub fn trash_ids(&self, conn: &SqliteConnection) -> Result, WorkspaceError> { + let ids = TrashTableSql::read_all(&*conn)? + .take_items() + .into_iter() + .map(|item| item.id) + .collect::>(); + Ok(ids) + } + #[tracing::instrument(level = "debug", skip(self), fields(putback) err)] pub async fn putback(&self, trash_id: &str) -> WorkspaceResult<()> { let (tx, mut rx) = mpsc::channel::>(1); let trash_table = TrashTableSql::read(trash_id, &*self.database.db_connection()?)?; + let _ = thread::scope(|_s| { + let conn = self.database.db_connection()?; + let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| { + let _ = TrashTableSql::delete_trash(trash_id, &*conn)?; + let _ = self.notify_dart_trash_did_update(&conn)?; + Ok(()) + })?; + Ok::<(), WorkspaceError>(()) + }) + .unwrap()?; + tracing::Span::current().record( "putback", &format!("{:?}: {}", &trash_table.ty, trash_table.id).as_str(), @@ -70,12 +90,6 @@ impl TrashCan { .send(TrashEvent::Putback(trash_table.ty.into(), vec![trash_table.id], tx)); let _ = rx.recv().await.unwrap()?; - let conn = self.database.db_connection()?; - let _ = conn.immediate_transaction::<_, WorkspaceError, _>(|| { - let _ = TrashTableSql::delete_trash(trash_id, &*conn)?; - let _ = self.notify_dart_trash_did_update(&conn)?; - Ok(()) - })?; Ok(()) } @@ -122,10 +136,12 @@ impl TrashCan { if trash_type.as_ref().unwrap() != &t.ty { return Err(WorkspaceError::internal()); } - - ids.push(t.id.clone()); + let trash_id = t.id.clone(); + log::debug!("create trash: {:?}", t); let _ = TrashTableSql::create_trash(t.into(), &*conn)?; + ids.push(trash_id); } + let _ = self.notify_dart_trash_did_update(&conn)?; Ok(()) })?; Ok::<(), WorkspaceError>(()) diff --git a/rust-lib/flowy-workspace/src/services/view_controller.rs b/rust-lib/flowy-workspace/src/services/view_controller.rs index 9ede5fe3fe..2f083fec18 100644 --- a/rust-lib/flowy-workspace/src/services/view_controller.rs +++ b/rust-lib/flowy-workspace/src/services/view_controller.rs @@ -59,12 +59,12 @@ impl ViewController { pub(crate) async fn create_view(&self, params: CreateViewParams) -> Result { let view = self.create_view_on_server(params.clone()).await?; let conn = &*self.database.db_connection()?; + let trash_can = self.trash_can.clone(); // TODO: rollback anything created before if failed? conn.immediate_transaction::<_, WorkspaceError, _>(|| { let _ = self.save_view(view.clone(), conn)?; self.document.create(CreateDocParams::new(&view.id, params.data))?; - - let repeated_view = ViewTableSql::read_views(&view.belong_to_id, conn)?; + let repeated_view = read_belonging_view(&view.belong_to_id, trash_can, &conn)?; send_dart_notification(&view.belong_to_id, WorkspaceNotification::AppViewsChanged) .payload(repeated_view) .send(); @@ -112,7 +112,7 @@ impl ViewController { pub(crate) async fn read_views_belong_to(&self, belong_to_id: &str) -> Result { // TODO: read from server let conn = self.database.db_connection()?; - let repeated_view = ViewTableSql::read_views(belong_to_id, &*conn)?; + let repeated_view = read_belonging_view(belong_to_id, self.trash_can.clone(), &conn)?; Ok(repeated_view) } @@ -165,22 +165,22 @@ impl ViewController { Ok(()) } - #[tracing::instrument(skip(self), err)] - fn delete_view_on_server(&self, view_ids: Vec) -> Result<(), WorkspaceError> { - let token = self.user.token()?; - let server = self.server.clone(); - let params = DeleteViewParams { view_ids }; - spawn(async move { - match server.delete_view(&token, params).await { - Ok(_) => {}, - Err(e) => { - // TODO: retry? - log::error!("Delete view failed: {:?}", e); - }, - } - }); - Ok(()) - } + // #[tracing::instrument(skip(self), err)] + // fn delete_view_on_server(&self, view_ids: Vec) -> Result<(), + // WorkspaceError> { let token = self.user.token()?; + // let server = self.server.clone(); + // let params = DeleteViewParams { view_ids }; + // spawn(async move { + // match server.delete_view(&token, params).await { + // Ok(_) => {}, + // Err(e) => { + // // TODO: retry? + // log::error!("Delete view failed: {:?}", e); + // }, + // } + // }); + // Ok(()) + // } #[tracing::instrument(skip(self), err)] fn read_view_on_server(&self, params: ViewIdentifier) -> Result<(), WorkspaceError> { @@ -202,6 +202,7 @@ impl ViewController { let mut rx = self.trash_can.subscribe(); let database = self.database.clone(); let document = self.document.clone(); + let trash_can = self.trash_can.clone(); let _ = tokio::spawn(async move { loop { let mut stream = Box::pin(rx.recv().into_stream().filter_map(|result| async move { @@ -212,7 +213,9 @@ impl ViewController { })); let event: Option = stream.next().await; match event { - Some(event) => handle_trash_event(database.clone(), document.clone(), event), + Some(event) => { + handle_trash_event(database.clone(), document.clone(), trash_can.clone(), event).await + }, None => {}, } } @@ -220,7 +223,12 @@ impl ViewController { } } -fn handle_trash_event(database: Arc, document: Arc, event: TrashEvent) { +async fn handle_trash_event( + database: Arc, + document: Arc, + trash_can: Arc, + event: TrashEvent, +) { let db_result = database.db_connection(); match event { @@ -229,13 +237,13 @@ fn handle_trash_event(database: Arc, document: Arc(|| { for view_id in view_ids { - let _ = notify_view_num_did_change(&view_id, conn)?; + let _ = notify_view_num_did_change(&view_id, conn, trash_can.clone())?; } Ok(()) })?; Ok::<(), WorkspaceError>(()) }; - let _ = ret.send(result()); + let _ = ret.send(result()).await; }, TrashEvent::Delete(_, delete_ids, ret) => { let result = || { @@ -244,22 +252,34 @@ fn handle_trash_event(database: Arc, document: Arc(()) }; - let _ = ret.send(result()); + let _ = ret.send(result()).await; }, } } -fn notify_view_num_did_change(view_id: &str, conn: &SqliteConnection) -> WorkspaceResult<()> { +#[tracing::instrument(skip(conn, trash_can), err)] +fn notify_view_num_did_change(view_id: &str, conn: &SqliteConnection, trash_can: Arc) -> WorkspaceResult<()> { let view_table = ViewTableSql::read_view(view_id, conn)?; - let repeated_view = ViewTableSql::read_views(&view_table.belong_to_id, conn)?; + let repeated_view = read_belonging_view(&view_table.belong_to_id, trash_can, conn)?; send_dart_notification(&view_table.belong_to_id, WorkspaceNotification::AppViewsChanged) .payload(repeated_view) .send(); Ok(()) } + +fn read_belonging_view( + belong_to_id: &str, + trash_can: Arc, + conn: &SqliteConnection, +) -> WorkspaceResult { + let mut repeated_view = ViewTableSql::read_views(belong_to_id, conn)?; + let trash_ids = trash_can.trash_ids(conn)?; + repeated_view.retain(|view| !trash_ids.contains(&view.id)); + Ok(repeated_view) +} diff --git a/rust-lib/flowy-workspace/src/sql_tables/view/view_sql.rs b/rust-lib/flowy-workspace/src/sql_tables/view/view_sql.rs index d1145a1d4c..798b4672d8 100644 --- a/rust-lib/flowy-workspace/src/sql_tables/view/view_sql.rs +++ b/rust-lib/flowy-workspace/src/sql_tables/view/view_sql.rs @@ -35,29 +35,16 @@ impl ViewTableSql { .filter(view_table::id.eq(view_id)) .first::(conn)?; - let repeated_trash: Vec = trash_table::dsl::trash_table.select(trash_table::dsl::id).load(conn)?; - - if repeated_trash.contains(&view_table.id) { - return Err(WorkspaceError::not_found()); - } - Ok(view_table) } // belong_to_id will be the app_id or view_id. pub(crate) fn read_views(belong_to_id: &str, conn: &SqliteConnection) -> Result { - let mut view_tables = dsl::view_table + let view_tables = dsl::view_table .filter(view_table::belong_to_id.eq(belong_to_id)) .into_boxed() .load::(conn)?; - let repeated_trash: Vec = trash_table::dsl::trash_table.select(trash_table::dsl::id).load(conn)?; - - view_tables = view_tables - .into_iter() - .filter(|table| !repeated_trash.contains(&table.id)) - .collect::>(); - let views = view_tables .into_iter() .map(|view_table| view_table.into())