From bd396cb4d6e5987c2c9bac9322f8a53a5e472042 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Mon, 13 Jan 2025 23:40:07 +0700 Subject: [PATCH] ui: deleting wallpapers after deleting user and chats (#5524) * ui: deleting wallpapers after deleting user and chats * ios * change * change * change * fix deleting wallpapers --- apps/ios/Shared/Model/ChatModel.swift | 22 +++++++++++++++- .../Views/UserSettings/UserProfilesView.swift | 2 ++ apps/ios/SimpleXChat/ImageUtils.swift | 15 ++++++++--- .../chat/simplex/common/model/ChatModel.kt | 6 ++++- .../simplex/common/views/helpers/Utils.kt | 25 +++++++++++++++++++ .../views/usersettings/UserProfilesView.kt | 2 ++ 6 files changed, 67 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 6b6b0ac03f..67ecd429d4 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -857,7 +857,10 @@ final class ChatModel: ObservableObject { func removeChat(_ id: String) { withAnimation { - chats.removeAll(where: { $0.id == id }) + if let i = getChatIndex(id) { + let chat = chats.remove(at: i) + removeWallpaperFilesFromChat(chat) + } } } @@ -895,6 +898,23 @@ final class ChatModel: ObservableObject { _ = upsertGroupMember(groupInfo, updatedMember) } } + + func removeWallpaperFilesFromChat(_ chat: Chat) { + if case let .direct(contact) = chat.chatInfo { + removeWallpaperFilesFromTheme(contact.uiThemes) + } else if case let .group(groupInfo) = chat.chatInfo { + removeWallpaperFilesFromTheme(groupInfo.uiThemes) + } + } + + func removeWallpaperFilesFromAllChats(_ user: User) { + // Currently, only removing everything from currently active user is supported. Inactive users are TODO + if user.userId == currentUser?.userId { + chats.forEach { + removeWallpaperFilesFromChat($0) + } + } + } } struct ShowingInvitation { diff --git a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift index 7cd86ef1ef..781ea4bc34 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift @@ -298,6 +298,7 @@ struct UserProfilesView: View { private func removeUser(_ user: User, _ delSMPQueues: Bool, viewPwd: String?) async { do { if user.activeUser { + ChatModel.shared.removeWallpaperFilesFromAllChats(user) if let newActive = m.users.first(where: { u in !u.user.activeUser && !u.user.hidden }) { try await changeActiveUserAsync_(newActive.user.userId, viewPwd: nil) try await deleteUser() @@ -323,6 +324,7 @@ struct UserProfilesView: View { func deleteUser() async throws { try await apiDeleteUser(user.userId, delSMPQueues, viewPwd: viewPwd) + removeWallpaperFilesFromTheme(user.uiThemes) await MainActor.run { withAnimation { m.removeUser(user) } } } } diff --git a/apps/ios/SimpleXChat/ImageUtils.swift b/apps/ios/SimpleXChat/ImageUtils.swift index 89cc45c4f5..be43158bc1 100644 --- a/apps/ios/SimpleXChat/ImageUtils.swift +++ b/apps/ios/SimpleXChat/ImageUtils.swift @@ -267,17 +267,26 @@ public func saveWallpaperFile(image: UIImage) -> String? { public func removeWallpaperFile(fileName: String? = nil) { do { - try FileManager.default.contentsOfDirectory(atPath: getWallpaperDirectory().path).forEach { - if URL(fileURLWithPath: $0).lastPathComponent == fileName { try FileManager.default.removeItem(atPath: $0) } + try FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: getWallpaperDirectory().path), includingPropertiesForKeys: nil, options: []).forEach { url in + if url.lastPathComponent == fileName { + try FileManager.default.removeItem(at: url) + } } } catch { - logger.error("FileUtils.removeWallpaperFile error: \(error.localizedDescription)") + logger.error("FileUtils.removeWallpaperFile error: \(error)") } if let fileName { WallpaperType.cachedImages.removeValue(forKey: fileName) } } +public func removeWallpaperFilesFromTheme(_ theme: ThemeModeOverrides?) { + if let theme { + removeWallpaperFile(fileName: theme.light?.wallpaper?.imageFile) + removeWallpaperFile(fileName: theme.dark?.wallpaper?.imageFile) + } +} + public func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String { uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)", fullPath: fullPath) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 96f12b9ce9..d051fc3a53 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -546,7 +546,11 @@ object ChatModel { } fun removeChat(rhId: Long?, id: String) { - chats.removeAll { it.id == id && it.remoteHostId == rhId } + val i = getChatIndex(rhId, id) + if (i != -1) { + val chat = chats.removeAt(i) + removeWallpaperFilesFromChat(chat) + } } suspend fun upsertGroupMember(rhId: Long?, groupInfo: GroupInfo, member: GroupMember): Boolean { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt index 39611361e3..99dda186dc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt @@ -10,6 +10,7 @@ import androidx.compose.ui.unit.* import chat.simplex.common.model.* import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.ThemeModeOverrides import chat.simplex.common.ui.theme.ThemeOverrides import chat.simplex.common.views.chatlist.connectIfOpenedViaUri import chat.simplex.res.MR @@ -316,6 +317,30 @@ fun removeWallpaperFile(fileName: String? = null) { WallpaperType.cachedImages.remove(fileName) } +fun removeWallpaperFilesFromTheme(theme: ThemeModeOverrides?) { + if (theme != null) { + removeWallpaperFile(theme.light?.wallpaper?.imageFile) + removeWallpaperFile(theme.dark?.wallpaper?.imageFile) + } +} + +fun removeWallpaperFilesFromChat(chat: Chat) { + if (chat.chatInfo is ChatInfo.Direct) { + removeWallpaperFilesFromTheme(chat.chatInfo.contact.uiThemes) + } else if (chat.chatInfo is ChatInfo.Group) { + removeWallpaperFilesFromTheme(chat.chatInfo.groupInfo.uiThemes) + } +} + +fun removeWallpaperFilesFromAllChats(user: User) { + // Currently, only removing everything from currently active user is supported. Inactive users are TODO + if (user.userId == chatModel.currentUser.value?.userId) { + chatModel.chats.value.forEach { + removeWallpaperFilesFromChat(it) + } + } +} + fun createTmpFileAndDelete(onCreated: (File) -> T): T { val tmpFile = File(tmpDir, UUID.randomUUID().toString()) tmpFile.deleteOnExit() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt index ad732cd699..d7ddb6b950 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt @@ -347,6 +347,7 @@ private suspend fun doRemoveUser(m: ChatModel, user: User, users: List, de try { when { user.activeUser -> { + removeWallpaperFilesFromAllChats(user) val newActive = users.firstOrNull { u -> !u.activeUser && !u.hidden } if (newActive != null) { m.controller.changeActiveUser_(user.remoteHostId, newActive.userId, null) @@ -366,6 +367,7 @@ private suspend fun doRemoveUser(m: ChatModel, user: User, users: List, de m.controller.apiDeleteUser(user, delSMPQueues, viewPwd) } } + removeWallpaperFilesFromTheme(user.uiThemes) m.removeUser(user) ntfManager.cancelNotificationsForUser(user.userId) } catch (e: Exception) {