diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt index 3727f02d30..f03060618d 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -177,7 +177,7 @@ class ChatModel(val controller: ChatController) { // clear preview val i = getChatIndex(cInfo.id) if (i >= 0) { - chats[i] = chats[i].copy(chatItems = arrayListOf(), chatStats = Chat.ChatStats()) + chats[i] = chats[i].copy(chatItems = arrayListOf(), chatStats = Chat.ChatStats(), chatInfo = cInfo) } // clear current chat if (chatId.value == cInfo.id) { @@ -269,6 +269,7 @@ interface SomeChat { val apiId: Long val ready: Boolean val createdAt: Instant + val updatedAt: Instant } @Serializable @@ -320,6 +321,7 @@ sealed class ChatInfo: SomeChat, NamedChat { override val apiId get() = contact.apiId override val ready get() = contact.ready override val createdAt get() = contact.createdAt + override val updatedAt get() = contact.updatedAt override val displayName get() = contact.displayName override val fullName get() = contact.fullName override val image get() = contact.image @@ -337,6 +339,7 @@ sealed class ChatInfo: SomeChat, NamedChat { override val apiId get() = groupInfo.apiId override val ready get() = groupInfo.ready override val createdAt get() = groupInfo.createdAt + override val updatedAt get() = groupInfo.updatedAt override val displayName get() = groupInfo.displayName override val fullName get() = groupInfo.fullName override val image get() = groupInfo.image @@ -354,6 +357,7 @@ sealed class ChatInfo: SomeChat, NamedChat { override val apiId get() = contactRequest.apiId override val ready get() = contactRequest.ready override val createdAt get() = contactRequest.createdAt + override val updatedAt get() = contactRequest.updatedAt override val displayName get() = contactRequest.displayName override val fullName get() = contactRequest.fullName override val image get() = contactRequest.image @@ -371,6 +375,7 @@ sealed class ChatInfo: SomeChat, NamedChat { override val apiId get() = contactConnection.apiId override val ready get() = contactConnection.ready override val createdAt get() = contactConnection.createdAt + override val updatedAt get() = contactConnection.updatedAt override val displayName get() = contactConnection.displayName override val fullName get() = contactConnection.fullName override val image get() = contactConnection.image @@ -389,7 +394,8 @@ class Contact( val profile: Profile, val activeConn: Connection, val viaGroup: Long? = null, - override val createdAt: Instant + override val createdAt: Instant, + override val updatedAt: Instant ): SomeChat, NamedChat { override val chatType get() = ChatType.Direct override val id get() = "@$contactId" @@ -405,7 +411,8 @@ class Contact( localDisplayName = "alice", profile = Profile.sampleData, activeConn = Connection.sampleData, - createdAt = Clock.System.now() + createdAt = Clock.System.now(), + updatedAt = Clock.System.now() ) } } @@ -451,7 +458,8 @@ class GroupInfo ( val groupId: Long, override val localDisplayName: String, val groupProfile: GroupProfile, - override val createdAt: Instant + override val createdAt: Instant, + override val updatedAt: Instant ): SomeChat, NamedChat { override val chatType get() = ChatType.Group override val id get() = "#$groupId" @@ -466,7 +474,8 @@ class GroupInfo ( groupId = 1, localDisplayName = "team", groupProfile = GroupProfile.sampleData, - createdAt = Clock.System.now() + createdAt = Clock.System.now(), + updatedAt = Clock.System.now() ) } } @@ -538,7 +547,7 @@ class UserContactRequest ( override val localDisplayName: String, val profile: Profile, override val createdAt: Instant, - val updatedAt: Instant + override val updatedAt: Instant ): SomeChat, NamedChat { override val chatType get() = ChatType.ContactRequest override val id get() = "<@$contactRequestId" @@ -566,7 +575,7 @@ class PendingContactConnection( val pccConnStatus: ConnStatus, val viaContactUri: Boolean, override val createdAt: Instant, - val updatedAt: Instant + override val updatedAt: Instant ): SomeChat, NamedChat { override val chatType get() = ChatType.ContactConnection override val id get () = ":$pccConnId" diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index 088341544c..776e8967f1 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -275,11 +275,11 @@ open class ChatController(private val ctrl: ChatCtrl, private val ntfManager: Nt return false } - suspend fun apiClearChat(type: ChatType, id: Long): Boolean { + suspend fun apiClearChat(type: ChatType, id: Long): ChatInfo? { val r = sendCmd(CC.ApiClearChat(type, id)) - if (r is CR.ChatCleared) return true + if (r is CR.ChatCleared) return r.chatInfo Log.e(TAG, "apiClearChat bad response: ${r.responseType} ${r.details}") - return false + return null } suspend fun apiUpdateProfile(profile: Profile): Profile? { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index 242bb8b029..7e083d4d5c 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -60,9 +60,9 @@ fun clearChatDialog(chatInfo: ChatInfo, chatModel: ChatModel, close: () -> Unit) confirmText = generalGetString(R.string.clear_verb), onConfirm = { withApi { - val r = chatModel.controller.apiClearChat(chatInfo.chatType, chatInfo.apiId) - if (r) { - chatModel.clearChat(chatInfo) + val updatedChatInfo = chatModel.controller.apiClearChat(chatInfo.chatType, chatInfo.apiId) + if (updatedChatInfo != null) { + chatModel.clearChat(updatedChatInfo) close() } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt index 2c19940e56..be1e79fb72 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt @@ -163,9 +163,9 @@ fun clearChatDialog(chatInfo: ChatInfo, chatModel: ChatModel) { confirmText = generalGetString(R.string.clear_verb), onConfirm = { withApi { - val r = chatModel.controller.apiClearChat(chatInfo.chatType, chatInfo.apiId) - if (r) { - chatModel.clearChat(chatInfo) + val updatedChatInfo = chatModel.controller.apiClearChat(chatInfo.chatType, chatInfo.apiId) + if (updatedChatInfo != null) { + chatModel.clearChat(updatedChatInfo) } } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt index d99a51f05e..72fbaf4c40 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatPreviewView.kt @@ -63,7 +63,7 @@ fun ChatPreviewView(chat: Chat) { Text(stringResource(R.string.contact_connection_pending), color = HighOrLowlight) } } - val ts = chat.chatItems.lastOrNull()?.timestampText ?: getTimestampText(chat.chatInfo.createdAt) + val ts = chat.chatItems.lastOrNull()?.timestampText ?: getTimestampText(chat.chatInfo.updatedAt) Column( Modifier.fillMaxHeight(), verticalArrangement = Arrangement.Top diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 797e5051a0..aaca8ce3cb 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -190,6 +190,7 @@ final class ChatModel: ObservableObject { if let chat = getChat(cInfo.id) { chat.chatItems = [] chat.chatStats = ChatStats() + chat.chatInfo = cInfo } // clear current chat if chatId == cInfo.id { diff --git a/apps/ios/Shared/Model/Shared/ChatTypes.swift b/apps/ios/Shared/Model/Shared/ChatTypes.swift index 9a3b36d05b..57d7b747fd 100644 --- a/apps/ios/Shared/Model/Shared/ChatTypes.swift +++ b/apps/ios/Shared/Model/Shared/ChatTypes.swift @@ -168,6 +168,15 @@ enum ChatInfo: Identifiable, Decodable, NamedChat { } } + var updatedAt: Date { + switch self { + case let .direct(contact): return contact.updatedAt + case let .group(groupInfo): return groupInfo.updatedAt + case let .contactRequest(contactRequest): return contactRequest.updatedAt + case let .contactConnection(contactConnection): return contactConnection.updatedAt + } + } + struct SampleData { var direct: ChatInfo var group: ChatInfo @@ -201,6 +210,7 @@ struct Contact: Identifiable, Decodable, NamedChat { var activeConn: Connection var viaGroup: Int64? var createdAt: Date + var updatedAt: Date var id: ChatId { get { "@\(contactId)" } } var apiId: Int64 { get { contactId } } @@ -214,7 +224,8 @@ struct Contact: Identifiable, Decodable, NamedChat { localDisplayName: "alice", profile: Profile.sampleData, activeConn: Connection.sampleData, - createdAt: .now + createdAt: .now, + updatedAt: .now ) } @@ -350,6 +361,7 @@ struct GroupInfo: Identifiable, Decodable, NamedChat { var localDisplayName: GroupName var groupProfile: GroupProfile var createdAt: Date + var updatedAt: Date var id: ChatId { get { "#\(groupId)" } } var apiId: Int64 { get { groupId } } @@ -362,7 +374,8 @@ struct GroupInfo: Identifiable, Decodable, NamedChat { groupId: 1, localDisplayName: "team", groupProfile: GroupProfile.sampleData, - createdAt: .now + createdAt: .now, + updatedAt: .now ) } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index e3a480c928..d2349e505b 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -286,17 +286,17 @@ func apiDeleteChat(type: ChatType, id: Int64) async throws { throw r } -func apiClearChat(type: ChatType, id: Int64) async throws { +func apiClearChat(type: ChatType, id: Int64) async throws -> ChatInfo { let r = await chatSendCmd(.apiClearChat(type: type, id: id), bgTask: false) - if case .chatCleared = r { return } + if case let .chatCleared(updatedChatInfo) = r { return updatedChatInfo } throw r } func clearChat(_ chat: Chat) async { do { let cInfo = chat.chatInfo - try await apiClearChat(type: cInfo.chatType, id: cInfo.apiId) - DispatchQueue.main.async { ChatModel.shared.clearChat(cInfo) } + let updatedChatInfo = try await apiClearChat(type: cInfo.chatType, id: cInfo.apiId) + DispatchQueue.main.async { ChatModel.shared.clearChat(updatedChatInfo) } } catch { logger.error("clearChat apiClearChat error: \(responseError(error))") } diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index fc61520166..eec99991d6 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -29,7 +29,7 @@ struct ChatPreviewView: View { .foregroundColor(chat.chatInfo.ready ? .primary : .secondary) .frame(maxHeight: .infinity, alignment: .topLeading) Spacer() - (cItem?.timestampText ?? formatTimestampText(chat.chatInfo.createdAt)) + (cItem?.timestampText ?? formatTimestampText(chat.chatInfo.updatedAt)) .font(.subheadline) .frame(minWidth: 60, alignment: .trailing) .foregroundColor(.secondary) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index f0f11da579..7664421024 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -97,16 +97,16 @@ 648010AB281ADD15009009B9 /* CIFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648010AA281ADD15009009B9 /* CIFileView.swift */; }; 649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; }; 649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; }; - 64A6907228364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906D28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; - 64A6907328364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906D28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; - 64A6907428364D610076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906E28364D610076573F /* libgmpxx.a */; }; - 64A6907528364D610076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906E28364D610076573F /* libgmpxx.a */; }; - 64A6907628364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906F28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; - 64A6907728364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6906F28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; - 64A6907828364D610076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907028364D610076573F /* libgmp.a */; }; - 64A6907928364D610076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907028364D610076573F /* libgmp.a */; }; - 64A6907A28364D610076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907128364D610076573F /* libffi.a */; }; - 64A6907B28364D610076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907128364D610076573F /* libffi.a */; }; + 64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; + 64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */; }; + 64A6908328376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; }; + 64A6908428376BBA0076573F /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907D28376BB90076573F /* libffi.a */; }; + 64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; }; + 64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907E28376BB90076573F /* libgmpxx.a */; }; + 64A6908728376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; }; + 64A6908828376BBA0076573F /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6907F28376BB90076573F /* libgmp.a */; }; + 64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; + 64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */; }; 64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; }; 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; }; 64DAE1512809D9F5000DA960 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DAE1502809D9F5000DA960 /* FileUtils.swift */; }; @@ -213,11 +213,11 @@ 6493D667280ED77F007A76FB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeImageView.swift; sourceTree = ""; }; 649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = ""; }; - 64A6906D28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a"; sourceTree = ""; }; - 64A6906E28364D610076573F /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 64A6906F28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a"; sourceTree = ""; }; - 64A6907028364D610076573F /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 64A6907128364D610076573F /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a"; sourceTree = ""; }; + 64A6907D28376BB90076573F /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 64A6907E28376BB90076573F /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 64A6907F28376BB90076573F /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a"; sourceTree = ""; }; 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = ""; }; 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = ""; }; 64DAE1502809D9F5000DA960 /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = ""; }; @@ -228,14 +228,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 64A6908928376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, + 64A6908528376BBA0076573F /* libgmpxx.a in Frameworks */, + 64A6908728376BBA0076573F /* libgmp.a in Frameworks */, 5C8F01CD27A6F0D8007D2C8D /* CodeScanner in Frameworks */, - 64A6907828364D610076573F /* libgmp.a in Frameworks */, - 64A6907428364D610076573F /* libgmpxx.a in Frameworks */, - 64A6907A28364D610076573F /* libffi.a in Frameworks */, - 64A6907628364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, 5C764E83279C748B000C6508 /* libz.tbd in Frameworks */, 5C764E82279C748B000C6508 /* libiconv.tbd in Frameworks */, - 64A6907228364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, + 64A6908328376BBA0076573F /* libffi.a in Frameworks */, + 64A6908128376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -250,13 +250,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 64A6907728364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, - 64A6907528364D610076573F /* libgmpxx.a in Frameworks */, 5CDCAD5F28187D6900503DA2 /* libiconv.tbd in Frameworks */, + 64A6908628376BBA0076573F /* libgmpxx.a in Frameworks */, + 64A6908A28376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a in Frameworks */, 5CDCAD6128187D8000503DA2 /* libz.tbd in Frameworks */, - 64A6907B28364D610076573F /* libffi.a in Frameworks */, - 64A6907928364D610076573F /* libgmp.a in Frameworks */, - 64A6907328364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, + 64A6908228376BBA0076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a in Frameworks */, + 64A6908828376BBA0076573F /* libgmp.a in Frameworks */, + 64A6908428376BBA0076573F /* libffi.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -305,11 +305,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 64A6907128364D610076573F /* libffi.a */, - 64A6907028364D610076573F /* libgmp.a */, - 64A6906E28364D610076573F /* libgmpxx.a */, - 64A6906F28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */, - 64A6906D28364D610076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */, + 64A6907D28376BB90076573F /* libffi.a */, + 64A6907F28376BB90076573F /* libgmp.a */, + 64A6907E28376BB90076573F /* libgmpxx.a */, + 64A6908028376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC-ghc8.10.7.a */, + 64A6907C28376BB90076573F /* libHSsimplex-chat-2.1.0-KOac7DFCSQz9HzISDnAYtC.a */, ); path = Libraries; sourceTree = ""; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index a2e75dc4b0..54f7e156d0 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -407,10 +407,13 @@ processChatCommand = \case cancelFile user fileInfo withFilesFolder $ \filesFolder -> deleteFile filesFolder fileInfo void $ withStore $ \st -> deleteDirectChatItemLocal st userId ct itemId CIDMInternal - let latestItem = if not $ null ciIdsAndFileInfo then Just (last ciIdsAndFileInfo) else Nothing - forM_ latestItem $ \(_, latestItemTs, _) -> - withStore $ \st -> updateContactTs st user ct latestItemTs - pure $ CRChatCleared (AChatInfo SCTDirect (DirectChat ct)) + ct' <- case ciIdsAndFileInfo of + [] -> pure ct + _ -> do + let (_, lastItemTs, _) = last ciIdsAndFileInfo + withStore (\st -> updateContactTs st user ct lastItemTs) + pure (ct :: Contact) {updatedAt = lastItemTs} + pure $ CRChatCleared (AChatInfo SCTDirect (DirectChat ct')) CTGroup -> do gInfo <- withStore $ \st -> getGroupInfo st user chatId ciIdsAndFileInfo <- withStore $ \st -> getGroupChatItemIdsAndFileInfo st user chatId @@ -420,10 +423,13 @@ processChatCommand = \case cancelFile user fileInfo withFilesFolder $ \filesFolder -> deleteFile filesFolder fileInfo void $ withStore $ \st -> deleteGroupChatItemInternal st user gInfo itemId - let latestItem = if not $ null ciIdsAndFileInfo then Just (last ciIdsAndFileInfo) else Nothing - forM_ latestItem $ \(_, latestItemTs, _, _) -> - withStore $ \st -> updateGroupTs st user gInfo latestItemTs - pure $ CRChatCleared (AChatInfo SCTGroup (GroupChat gInfo)) + gInfo' <- case ciIdsAndFileInfo of + [] -> pure gInfo + _ -> do + let (_, lastItemTs, _, _) = last ciIdsAndFileInfo + withStore (\st -> updateGroupTs st user gInfo lastItemTs) + pure (gInfo :: GroupInfo) {updatedAt = lastItemTs} + pure $ CRChatCleared (AChatInfo SCTGroup (GroupChat gInfo')) CTContactConnection -> pure $ chatCmdError "not supported" CTContactRequest -> pure $ chatCmdError "not supported" APIAcceptContact connReqId -> withUser $ \user@User {userId} -> withChatLock $ do