diff --git a/apps/ios/Shared/AppDelegate.swift b/apps/ios/Shared/AppDelegate.swift index 0add3347ba..895891838e 100644 --- a/apps/ios/Shared/AppDelegate.swift +++ b/apps/ios/Shared/AppDelegate.swift @@ -62,7 +62,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { } } else if let checkMessages = ntfData["checkMessages"] as? Bool, checkMessages { logger.debug("AppDelegate: didReceiveRemoteNotification: checkMessages") - if isAppInactive() { + if appStateGroupDefault.get().inactive { receiveMessages(completionHandler) } else { completionHandler(.noData) diff --git a/apps/ios/Shared/Model/BGManager.swift b/apps/ios/Shared/Model/BGManager.swift index 6468d3b08a..d7267ff8b8 100644 --- a/apps/ios/Shared/Model/BGManager.swift +++ b/apps/ios/Shared/Model/BGManager.swift @@ -47,7 +47,7 @@ class BGManager { private func handleRefresh(_ task: BGAppRefreshTask) { logger.debug("BGManager.handleRefresh") schedule() - if isAppInactive() { + if appStateGroupDefault.get().inactive { let completeRefresh = completionHandler { task.setTaskCompleted(success: true) } diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 2292a60c94..cc0731f2ad 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -102,9 +102,15 @@ final class ChatModel: ObservableObject { } } - func replaceChats(with newChats: [Chat]) { - for chat in newChats { - replaceChat(chat.id, chat) + func updateChats(with newChats: [ChatData]) { + for c in newChats { + if let chat = getChat(c.id) { + chat.chatInfo = c.chatInfo + chat.chatItems = c.chatItems + chat.chatStats = c.chatStats + } else { + addChat(Chat(c)) + } } } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index e2f9ecd016..af3ac5d5aa 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -179,9 +179,9 @@ func apiDeleteStorage() async throws { try await sendCommandOkResp(.apiDeleteStorage) } -func apiGetChats() throws -> [Chat] { +func apiGetChats() throws -> [ChatData] { let r = chatSendCmdSync(.apiGetChats) - if case let .apiChats(chats) = r { return chats.map { Chat.init($0) } } + if case let .apiChats(chats) = r { return chats } throw r } @@ -191,6 +191,18 @@ func apiGetChat(type: ChatType, id: Int64) throws -> Chat { throw r } +func loadChat(chat: Chat) { + do { + let cInfo = chat.chatInfo + let chat = try apiGetChat(type: cInfo.chatType, id: cInfo.apiId) + let m = ChatModel.shared + m.updateChatInfo(chat.chatInfo) + m.chatItems = chat.chatItems + } catch let error { + logger.error("loadChat error: \(responseError(error))") + } +} + func apiSendMessage(type: ChatType, id: Int64, file: String?, quotedItemId: Int64?, msg: MsgContent) async throws -> ChatItem { let chatModel = ChatModel.shared let cmd: ChatCommand = .apiSendMessage(type: type, id: id, file: file, quotedItemId: quotedItemId, msg: msg) @@ -524,7 +536,8 @@ func startChat() throws { if justStarted { m.userAddress = try apiGetUserAddress() m.userSMPServers = try getUserSMPServers() - m.chats = try apiGetChats() + let chats = try apiGetChats() + m.chats = chats.map { Chat.init($0) } (m.savedToken, m.tokenStatus, m.notificationMode) = try apiGetNtfToken() if let token = m.deviceToken { registerToken(token: token) diff --git a/apps/ios/Shared/Model/SuspendChat.swift b/apps/ios/Shared/Model/SuspendChat.swift index e2bd313e6b..e19eb64f45 100644 --- a/apps/ios/Shared/Model/SuspendChat.swift +++ b/apps/ios/Shared/Model/SuspendChat.swift @@ -38,9 +38,9 @@ func suspendBgRefresh() { } func chatSuspended() { - logger.debug("chatSuspended") suspendLockQueue.sync { if case .suspending = appStateGroupDefault.get() { + logger.debug("chatSuspended") appStateGroupDefault.set(.suspended) if ChatModel.shared.chatRunning == true { ChatReceiver.shared.stop() @@ -55,7 +55,3 @@ func activateChat(appState: AppState = .active) { apiActivateChat() } } - -func isAppInactive() -> Bool { - UIApplication.shared.applicationState != .active && appStateGroupDefault.get().inactive -} diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index 398bb70d81..587e9762b6 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -63,12 +63,7 @@ struct SimpleXApp: App { let appState = appStateGroupDefault.get() activateChat() if appState.inactive && chatModel.chatRunning == true { - do { - let chats = try apiGetChats() - chatModel.replaceChats(with: chats) - } catch let error { - logger.error("apiGetChats: cannot update chats \(responseError(error))") - } + updateChats() } doAuthenticate = authenticationExpired() default: @@ -107,4 +102,22 @@ struct SimpleXApp: App { return true } } + + private func updateChats() { + do { + let chats = try apiGetChats() + chatModel.updateChats(with: chats) + if let id = chatModel.chatId, + let chat = chatModel.getChat(id) { + loadChat(chat: chat) + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + if chatModel.chatId == chat.id { + Task { await markChatRead(chat) } + } + } + } + } catch let error { + logger.error("apiGetChats: cannot update chats \(responseError(error))") + } + } } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 79b30ebf27..6c5bd9109a 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -225,7 +225,7 @@ struct ChatView: View { } func markAllRead() { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { if chatModel.chatId == chat.id { Task { await markChatRead(chat) } } diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index bce1f0a662..eedf579a10 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -30,16 +30,7 @@ struct ChatListNavLink: View { private func chatView() -> some View { ChatView(chat: chat, showChatInfo: $showChatInfo) - .onAppear { - do { - let cInfo = chat.chatInfo - let chat = try apiGetChat(type: cInfo.chatType, id: cInfo.apiId) - chatModel.updateChatInfo(chat.chatInfo) - chatModel.chatItems = chat.chatItems - } catch { - logger.error("ChatListNavLink.chatView apiGetChatItems error: \(error.localizedDescription)") - } - } + .onAppear { loadChat(chat: chat) } } @ViewBuilder private func contactNavLink(_ contact: Contact) -> some View {