fix: remove the deleted workspace from local storage

This commit is contained in:
Lucas.Xu 2024-04-01 16:43:38 +08:00
parent 75e51fdeea
commit 2f6cfbdd79
3 changed files with 77 additions and 15 deletions

View File

@ -14,6 +14,9 @@ import 'package:appflowy_backend/rust_stream.dart';
import 'package:appflowy_result/appflowy_result.dart';
import 'package:flowy_infra/notifier.dart';
typedef DidUserWorkspaceUpdateCallback = void Function(
RepeatedUserWorkspacePB workspaces,
);
typedef UserProfileNotifyValue = FlowyResult<UserProfilePB, FlowyError>;
typedef AuthNotifyValue = FlowyResult<void, FlowyError>;
@ -27,14 +30,20 @@ class UserListener {
UserNotificationParser? _userParser;
StreamSubscription<SubscribeObject>? _subscription;
PublishNotifier<UserProfileNotifyValue>? _profileNotifier = PublishNotifier();
DidUserWorkspaceUpdateCallback? didUpdateUserWorkspaces;
void start({
void Function(UserProfileNotifyValue)? onProfileUpdated,
void Function(RepeatedUserWorkspacePB)? didUpdateUserWorkspaces,
}) {
if (onProfileUpdated != null) {
_profileNotifier?.addPublishListener(onProfileUpdated);
}
if (didUpdateUserWorkspaces != null) {
this.didUpdateUserWorkspaces = didUpdateUserWorkspaces;
}
_userParser = UserNotificationParser(
id: _userProfile.id.toString(),
callback: _userNotificationCallback,
@ -63,6 +72,14 @@ class UserListener {
(error) => _profileNotifier?.value = FlowyResult.failure(error),
);
break;
case user.UserNotification.DidUpdateUserWorkspaces:
result.map(
(r) {
final value = RepeatedUserWorkspacePB.fromBuffer(r);
didUpdateUserWorkspaces?.call(value);
},
);
break;
default:
break;
}
@ -108,6 +125,7 @@ class UserWorkspaceListener {
_settingChangedNotifier?.value = FlowyResult.failure(error),
);
break;
default:
break;
}

View File

@ -3,6 +3,7 @@ import 'package:appflowy/core/config/kv_keys.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/user_listener.dart';
import 'package:appflowy/user/application/user_service.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-error/code.pbenum.dart';
@ -22,11 +23,18 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
UserWorkspaceBloc({
required this.userProfile,
}) : _userService = UserBackendService(userId: userProfile.id),
_listener = UserListener(userProfile: userProfile),
super(UserWorkspaceState.initial()) {
on<UserWorkspaceEvent>(
(event, emit) async {
await event.when(
initial: () async {
_listener
..didUpdateUserWorkspaces = (workspaces) {
add(UserWorkspaceEvent.updateWorkspaces(workspaces));
}
..start();
final result = await _fetchWorkspaces();
final isCollabWorkspaceOn =
userProfile.authenticator != AuthenticatorPB.Local &&
@ -246,13 +254,30 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
),
);
},
updateWorkspaces: (workspaces) async {
if (!const DeepCollectionEquality()
.equals(workspaces.items, state.workspaces)) {
emit(
state.copyWith(
workspaces: workspaces.items,
),
);
}
},
);
},
);
}
@override
Future<void> close() {
_listener.stop();
return super.close();
}
final UserProfilePB userProfile;
final UserBackendService _userService;
final UserListener _listener;
Future<
(
@ -308,6 +333,9 @@ class UserWorkspaceEvent with _$UserWorkspaceEvent {
) = _UpdateWorkspaceIcon;
const factory UserWorkspaceEvent.leaveWorkspace(String workspaceId) =
LeaveWorkspace;
const factory UserWorkspaceEvent.updateWorkspaces(
RepeatedUserWorkspacePB workspaces,
) = UpdateWorkspaces;
}
enum UserWorkspaceActionType {

View File

@ -332,14 +332,24 @@ pub fn save_user_workspaces(
) -> FlowyResult<()> {
let user_workspaces = user_workspaces
.iter()
.flat_map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace)).ok())
.collect::<Vec<UserWorkspaceTable>>();
.map(|user_workspace| UserWorkspaceTable::try_from((uid, user_workspace)))
.collect::<Result<Vec<_>, _>>()?;
conn.immediate_transaction(|conn| {
for user_workspace in user_workspaces {
if let Err(err) = diesel::update(
let existing_ids = user_workspace_table::dsl::user_workspace_table
.select(user_workspace_table::id)
.load::<String>(conn)?;
let new_ids: Vec<String> = user_workspaces.iter().map(|w| w.id.clone()).collect();
let ids_to_delete: Vec<String> = existing_ids
.into_iter()
.filter(|id| !new_ids.contains(id))
.collect();
// insert or update the user workspaces
for user_workspace in &user_workspaces {
let affected_rows = diesel::update(
user_workspace_table::dsl::user_workspace_table
.filter(user_workspace_table::id.eq(user_workspace.id.clone())),
.filter(user_workspace_table::id.eq(&user_workspace.id)),
)
.set((
user_workspace_table::name.eq(&user_workspace.name),
@ -347,18 +357,24 @@ pub fn save_user_workspaces(
user_workspace_table::database_storage_id.eq(&user_workspace.database_storage_id),
user_workspace_table::icon.eq(&user_workspace.icon),
))
.execute(conn)
.and_then(|rows| {
if rows == 0 {
let _ = diesel::insert_into(user_workspace_table::table)
.values(user_workspace)
.execute(conn)?;
}
Ok(())
}) {
tracing::error!("Error saving user workspace: {:?}", err);
.execute(conn)?;
if affected_rows == 0 {
diesel::insert_into(user_workspace_table::table)
.values(user_workspace)
.execute(conn)?;
}
}
// delete the user workspaces that are not in the new list
if !ids_to_delete.is_empty() {
diesel::delete(
user_workspace_table::dsl::user_workspace_table
.filter(user_workspace_table::id.eq_any(ids_to_delete)),
)
.execute(conn)?;
}
Ok::<(), FlowyError>(())
})
}