mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-25 22:54:29 +00:00
core, ui: replace map of network statuses with subscription status of current chat (#6353)
* core: subscription status wip
* update
* update
* update
* remove statuses core
* cleanup ios
* comment
* plans
* remove NetworkStatus
* ios wip
* contact sub status
* Revert "contact sub status"
This reverts commit 50cf94beed.
* sub status
* set on connected
* kotlin
* rename
* layout
* member status
* kotlin
* fix chat subscription status
* string
* core: update simplexmq
* client notices
* update simplexmq
* update alert
* update simplexmq
* android/desktop
* formatting
* fix tests
* update plans and API docs
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
@@ -15,8 +15,6 @@ import SwiftUI
|
||||
|
||||
private var chatController: chat_ctrl?
|
||||
|
||||
private let networkStatusesLock = DispatchQueue(label: "chat.simplex.app.network-statuses.lock")
|
||||
|
||||
enum TerminalItem: Identifiable {
|
||||
case cmd(Date, ChatCommand)
|
||||
case res(Date, ChatAPIResult)
|
||||
@@ -1319,6 +1317,10 @@ func apiCreateUserAddress() async throws -> CreatedConnLink? {
|
||||
let userId = try currentUserId("apiCreateUserAddress")
|
||||
let r: APIResult<ChatResponse1>? = await chatApiSendCmdWithRetry(.apiCreateMyAddress(userId: userId))
|
||||
if case let .result(.userContactLinkCreated(_, connLink)) = r { return connLink }
|
||||
if case let .error(.errorAgent(.NOTICE(server, preset, expires))) = r {
|
||||
showClientNotice(server, preset, expires)
|
||||
return nil
|
||||
}
|
||||
if let r { throw r.unexpected } else { return nil }
|
||||
}
|
||||
|
||||
@@ -1640,7 +1642,6 @@ func acceptContactRequest(incognito: Bool, contactRequestId: Int64, inProgress:
|
||||
} else {
|
||||
ChatModel.shared.replaceChat(contactRequestChatId(contactRequestId), chat)
|
||||
}
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
inProgress?.wrappedValue = false
|
||||
}
|
||||
if contact.sndReady {
|
||||
@@ -1728,12 +1729,6 @@ func apiCallStatus(_ contact: Contact, _ status: String) async throws {
|
||||
}
|
||||
}
|
||||
|
||||
func apiGetNetworkStatuses() throws -> [ConnNetworkStatus] {
|
||||
let r: ChatResponse1 = try chatSendCmdSync(.apiGetNetworkStatuses)
|
||||
if case let .networkStatuses(_, statuses) = r { return statuses }
|
||||
throw r.unexpected
|
||||
}
|
||||
|
||||
func markChatRead(_ im: ItemsModel, _ chat: Chat) async {
|
||||
do {
|
||||
if chat.chatStats.unreadCount > 0 {
|
||||
@@ -1899,6 +1894,10 @@ func apiUpdateGroup(_ groupId: Int64, _ groupProfile: GroupProfile) async throws
|
||||
func apiCreateGroupLink(_ groupId: Int64, memberRole: GroupMemberRole = .member) async throws -> GroupLink? {
|
||||
let r: APIResult<ChatResponse2>? = await chatApiSendCmdWithRetry(.apiCreateGroupLink(groupId: groupId, memberRole: memberRole))
|
||||
if case let .result(.groupLinkCreated(_, _, groupLink)) = r { return groupLink }
|
||||
if case let .error(.errorAgent(.NOTICE(server, preset, expires))) = r {
|
||||
showClientNotice(server, preset, expires)
|
||||
return nil
|
||||
}
|
||||
if let r { throw r.unexpected } else { return nil }
|
||||
}
|
||||
|
||||
@@ -1955,7 +1954,6 @@ func acceptMemberContact(contactId: Int64, inProgress: Binding<Bool>? = nil) asy
|
||||
if let contact = await apiAcceptMemberContact(contactId: contactId) {
|
||||
await MainActor.run {
|
||||
ChatModel.shared.updateContact(contact)
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
inProgress?.wrappedValue = false
|
||||
}
|
||||
if contact.sndReady {
|
||||
@@ -2241,7 +2239,6 @@ class ChatReceiver {
|
||||
|
||||
func processReceivedMsg(_ res: ChatEvent) async {
|
||||
let m = ChatModel.shared
|
||||
let n = NetworkModel.shared
|
||||
logger.debug("processReceivedMsg: \(res.responseType)")
|
||||
switch res {
|
||||
case let .contactDeletedByContact(user, contact):
|
||||
@@ -2258,14 +2255,15 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
m.dismissConnReqView(conn.id)
|
||||
m.removeChat(conn.id)
|
||||
}
|
||||
if contact.id == m.chatId, let conn = contact.activeConn {
|
||||
m.chatAgentConnId = conn.agentConnId
|
||||
m.chatSubStatus = .active
|
||||
}
|
||||
}
|
||||
}
|
||||
if contact.directOrUsed {
|
||||
NtfManager.shared.notifyContactConnected(user, contact)
|
||||
}
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
case let .contactConnecting(user, contact):
|
||||
if active(user) && contact.directOrUsed {
|
||||
await MainActor.run {
|
||||
@@ -2286,9 +2284,6 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
}
|
||||
}
|
||||
}
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
case let .receivedContactRequest(user, contactRequest, chat_):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
@@ -2327,30 +2322,10 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
_ = m.upsertGroupMember(groupInfo, toMember)
|
||||
}
|
||||
}
|
||||
case let .networkStatus(status, connections):
|
||||
// dispatch queue to synchronize access
|
||||
networkStatusesLock.sync {
|
||||
var ns = n.networkStatuses
|
||||
// slow loop is on the background thread
|
||||
for cId in connections {
|
||||
ns[cId] = status
|
||||
}
|
||||
// fast model update is on the main thread
|
||||
DispatchQueue.main.sync {
|
||||
n.networkStatuses = ns
|
||||
}
|
||||
}
|
||||
case let .networkStatuses(_, statuses): ()
|
||||
// dispatch queue to synchronize access
|
||||
networkStatusesLock.sync {
|
||||
var ns = n.networkStatuses
|
||||
// slow loop is on the background thread
|
||||
for s in statuses {
|
||||
ns[s.agentConnId] = s.networkStatus
|
||||
}
|
||||
// fast model update is on the main thread
|
||||
DispatchQueue.main.sync {
|
||||
n.networkStatuses = ns
|
||||
case let .subscriptionStatus(status, connections):
|
||||
if let chatAgentConnId = m.chatAgentConnId, connections.contains(chatAgentConnId) {
|
||||
await MainActor.run {
|
||||
m.chatSubStatus = status
|
||||
}
|
||||
}
|
||||
case let .chatInfoUpdated(user, chatInfo):
|
||||
@@ -2554,11 +2529,6 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
_ = m.upsertGroupMember(groupInfo, member)
|
||||
}
|
||||
}
|
||||
if let contact = memberContact {
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
}
|
||||
case let .groupUpdated(user, toGroup):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
@@ -2784,13 +2754,10 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
|
||||
func switchToLocalSession() {
|
||||
let m = ChatModel.shared
|
||||
let n = NetworkModel.shared
|
||||
m.remoteCtrlSession = nil
|
||||
do {
|
||||
m.users = try listUsers()
|
||||
try getUserChatData()
|
||||
let statuses = (try apiGetNetworkStatuses()).map { s in (s.agentConnId, s.networkStatus) }
|
||||
n.networkStatuses = Dictionary(uniqueKeysWithValues: statuses)
|
||||
} catch let error {
|
||||
logger.debug("error updating chat data: \(responseError(error))")
|
||||
}
|
||||
@@ -2898,3 +2865,26 @@ private struct UserResponse: Decodable {
|
||||
var user: User?
|
||||
var error: String?
|
||||
}
|
||||
|
||||
private func showClientNotice(_ server: String, _ preset: Bool, _ expiresAt: Date?) {
|
||||
DispatchQueue.main.async {
|
||||
var message = "Server: \(server).\nConditions of use violation notice received from \(preset ? "preset" : "this") server.\nNo IDs shared, see How it works."
|
||||
if let expiresAt {
|
||||
message += "\n\nNew addresses can be created after \(expiresAt.formatted(date: .abbreviated, time: .shortened))."
|
||||
}
|
||||
showAlert("Not allowed", message: message) {
|
||||
let howItWorks = UIAlertAction(title: NSLocalizedString("How it works", comment: "alert button"), style: .default, handler: { _ in
|
||||
UIApplication.shared.open(contentModerationPostLink)
|
||||
})
|
||||
return preset
|
||||
? [
|
||||
okAlertAction,
|
||||
UIAlertAction(title: NSLocalizedString("Conditions of use", comment: "alert button"), style: .default, handler: { _ in
|
||||
UIApplication.shared.open(conditionsURL)
|
||||
}),
|
||||
howItWorks
|
||||
]
|
||||
: [okAlertAction, howItWorks]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user