mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-25 04:15:31 +00:00
cleanup ios
This commit is contained in:
@@ -158,7 +158,6 @@ enum ChatCommand: ChatCmdProtocol {
|
||||
case apiGetCallInvitations
|
||||
case apiCallStatus(contact: Contact, callStatus: WebRTCCallStatus)
|
||||
// WebRTC calls /
|
||||
case apiGetNetworkStatuses
|
||||
case apiChatRead(type: ChatType, id: Int64, scope: GroupChatScope?)
|
||||
case apiChatItemsRead(type: ChatType, id: Int64, scope: GroupChatScope?, itemIds: [Int64])
|
||||
case apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool)
|
||||
@@ -359,7 +358,6 @@ enum ChatCommand: ChatCmdProtocol {
|
||||
case let .apiEndCall(contact): return "/_call end @\(contact.apiId)"
|
||||
case .apiGetCallInvitations: return "/_call get"
|
||||
case let .apiCallStatus(contact, callStatus): return "/_call status @\(contact.apiId) \(callStatus.rawValue)"
|
||||
case .apiGetNetworkStatuses: return "/_network_statuses"
|
||||
case let .apiChatRead(type, id, scope): return "/_read chat \(ref(type, id, scope: scope))"
|
||||
case let .apiChatItemsRead(type, id, scope, itemIds): return "/_read chat items \(ref(type, id, scope: scope)) \(joinedIds(itemIds))"
|
||||
case let .apiChatUnread(type, id, unreadChat): return "/_unread chat \(ref(type, id, scope: nil)) \(onOff(unreadChat))"
|
||||
@@ -534,7 +532,6 @@ enum ChatCommand: ChatCmdProtocol {
|
||||
case .apiEndCall: return "apiEndCall"
|
||||
case .apiGetCallInvitations: return "apiGetCallInvitations"
|
||||
case .apiCallStatus: return "apiCallStatus"
|
||||
case .apiGetNetworkStatuses: return "apiGetNetworkStatuses"
|
||||
case .apiChatRead: return "apiChatRead"
|
||||
case .apiChatItemsRead: return "apiChatItemsRead"
|
||||
case .apiChatUnread: return "apiChatUnread"
|
||||
@@ -793,7 +790,6 @@ enum ChatResponse1: Decodable, ChatAPIResult {
|
||||
case userContactLinkDeleted(user: User)
|
||||
case acceptingContactRequest(user: UserRef, contact: Contact)
|
||||
case contactRequestRejected(user: UserRef, contactRequest: UserContactRequest, contact_: Contact?)
|
||||
case networkStatuses(user_: UserRef?, networkStatuses: [ConnNetworkStatus])
|
||||
case newChatItems(user: UserRef, chatItems: [AChatItem])
|
||||
case groupChatItemsDeleted(user: UserRef, groupInfo: GroupInfo, chatItemIDs: Set<Int64>, byUser: Bool, member_: GroupMember?)
|
||||
case forwardPlan(user: UserRef, chatItemIds: [Int64], forwardConfirmation: ForwardConfirmation?)
|
||||
@@ -837,7 +833,6 @@ enum ChatResponse1: Decodable, ChatAPIResult {
|
||||
case .userContactLinkDeleted: "userContactLinkDeleted"
|
||||
case .acceptingContactRequest: "acceptingContactRequest"
|
||||
case .contactRequestRejected: "contactRequestRejected"
|
||||
case .networkStatuses: "networkStatuses"
|
||||
case .newChatItems: "newChatItems"
|
||||
case .groupChatItemsDeleted: "groupChatItemsDeleted"
|
||||
case .forwardPlan: "forwardPlan"
|
||||
@@ -870,7 +865,6 @@ enum ChatResponse1: Decodable, ChatAPIResult {
|
||||
case .userContactLinkDeleted: return noDetails
|
||||
case let .acceptingContactRequest(u, contact): return withUser(u, String(describing: contact))
|
||||
case let .contactRequestRejected(u, contactRequest, contact_): return withUser(u, "contactRequest: \(String(describing: contactRequest))\ncontact_: \(String(describing: contact_))")
|
||||
case let .networkStatuses(u, statuses): return withUser(u, String(describing: statuses))
|
||||
case let .newChatItems(u, chatItems):
|
||||
let itemsString = chatItems.map { chatItem in String(describing: chatItem) }.joined(separator: "\n")
|
||||
return withUser(u, itemsString)
|
||||
@@ -1060,7 +1054,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case contactUpdated(user: UserRef, toContact: Contact)
|
||||
case groupMemberUpdated(user: UserRef, groupInfo: GroupInfo, fromMember: GroupMember, toMember: GroupMember)
|
||||
case networkStatus(networkStatus: NetworkStatus, connections: [String])
|
||||
case networkStatuses(user_: UserRef?, networkStatuses: [ConnNetworkStatus])
|
||||
case chatInfoUpdated(user: UserRef, chatInfo: ChatInfo)
|
||||
case newChatItems(user: UserRef, chatItems: [AChatItem])
|
||||
case chatItemsStatusesUpdated(user: UserRef, chatItems: [AChatItem])
|
||||
@@ -1138,7 +1131,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case .contactUpdated: "contactUpdated"
|
||||
case .groupMemberUpdated: "groupMemberUpdated"
|
||||
case .networkStatus: "networkStatus"
|
||||
case .networkStatuses: "networkStatuses"
|
||||
case .chatInfoUpdated: "chatInfoUpdated"
|
||||
case .newChatItems: "newChatItems"
|
||||
case .chatItemsStatusesUpdated: "chatItemsStatusesUpdated"
|
||||
@@ -1211,7 +1203,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case let .contactUpdated(u, toContact): return withUser(u, String(describing: toContact))
|
||||
case let .groupMemberUpdated(u, groupInfo, fromMember, toMember): return withUser(u, "groupInfo: \(groupInfo)\nfromMember: \(fromMember)\ntoMember: \(toMember)")
|
||||
case let .networkStatus(status, conns): return "networkStatus: \(String(describing: status))\nconnections: \(String(describing: conns))"
|
||||
case let .networkStatuses(u, statuses): return withUser(u, String(describing: statuses))
|
||||
case let .chatInfoUpdated(u, chatInfo): return withUser(u, String(describing: chatInfo))
|
||||
case let .newChatItems(u, chatItems):
|
||||
let itemsString = chatItems.map { chatItem in String(describing: chatItem) }.joined(separator: "\n")
|
||||
@@ -1410,11 +1401,6 @@ enum ForwardConfirmation: Decodable, Hashable {
|
||||
case filesFailed(filesCount: Int)
|
||||
}
|
||||
|
||||
struct ConnNetworkStatus: Decodable {
|
||||
var agentConnId: String
|
||||
var networkStatus: NetworkStatus
|
||||
}
|
||||
|
||||
struct UserMsgReceiptSettings: Codable {
|
||||
var enable: Bool
|
||||
var clearOverrides: Bool
|
||||
|
||||
@@ -283,29 +283,6 @@ class ChatTagsModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
class NetworkModel: ObservableObject {
|
||||
// map of connections network statuses, key is agent connection id
|
||||
@Published var networkStatuses: Dictionary<String, NetworkStatus> = [:]
|
||||
|
||||
static let shared = NetworkModel()
|
||||
|
||||
private init() { }
|
||||
|
||||
func setContactNetworkStatus(_ contact: Contact, _ status: NetworkStatus) {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] = status
|
||||
}
|
||||
}
|
||||
|
||||
func contactNetworkStatus(_ contact: Contact) -> NetworkStatus {
|
||||
if let conn = contact.activeConn {
|
||||
networkStatuses[conn.agentConnId] ?? .unknown
|
||||
} else {
|
||||
.unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ChatItemWithMenu can depend on previous or next item for it's appearance
|
||||
/// This dummy model is used to force an update of all chat items,
|
||||
/// when they might have changed appearance.
|
||||
|
||||
@@ -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)
|
||||
@@ -1640,7 +1638,8 @@ func acceptContactRequest(incognito: Bool, contactRequestId: Int64, inProgress:
|
||||
} else {
|
||||
ChatModel.shared.replaceChat(contactRequestChatId(contactRequestId), chat)
|
||||
}
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
// TODO [sub status] review
|
||||
// NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
inProgress?.wrappedValue = false
|
||||
}
|
||||
if contact.sndReady {
|
||||
@@ -1728,12 +1727,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 {
|
||||
@@ -1955,7 +1948,8 @@ 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)
|
||||
// TODO [sub status] review
|
||||
// NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
inProgress?.wrappedValue = false
|
||||
}
|
||||
if contact.sndReady {
|
||||
@@ -2241,7 +2235,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):
|
||||
@@ -2263,9 +2256,10 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
if contact.directOrUsed {
|
||||
NtfManager.shared.notifyContactConnected(user, contact)
|
||||
}
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
// TODO [sub status] review
|
||||
// await MainActor.run {
|
||||
// n.setContactNetworkStatus(contact, .connected)
|
||||
// }
|
||||
case let .contactConnecting(user, contact):
|
||||
if active(user) && contact.directOrUsed {
|
||||
await MainActor.run {
|
||||
@@ -2286,9 +2280,10 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
}
|
||||
}
|
||||
}
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
// TODO [sub status] review
|
||||
// await MainActor.run {
|
||||
// n.setContactNetworkStatus(contact, .connected)
|
||||
// }
|
||||
case let .receivedContactRequest(user, contactRequest, chat_):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
@@ -2328,31 +2323,8 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
// TODO [sub status] update status for current chat in model if id matches
|
||||
return
|
||||
case let .chatInfoUpdated(user, chatInfo):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
@@ -2554,11 +2526,12 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
_ = m.upsertGroupMember(groupInfo, member)
|
||||
}
|
||||
}
|
||||
if let contact = memberContact {
|
||||
await MainActor.run {
|
||||
n.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
}
|
||||
// TODO [sub status] review
|
||||
// if let contact = memberContact {
|
||||
// await MainActor.run {
|
||||
// n.setContactNetworkStatus(contact, .connected)
|
||||
// }
|
||||
// }
|
||||
case let .groupUpdated(user, toGroup):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
@@ -2784,13 +2757,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))")
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@ struct ChatInfoView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.dismiss) var dismiss: DismissAction
|
||||
@ObservedObject var networkModel = NetworkModel.shared
|
||||
@ObservedObject var chat: Chat
|
||||
@State var contact: Contact
|
||||
@State var localAlias: String
|
||||
@@ -553,14 +552,17 @@ struct ChatInfoView: View {
|
||||
.foregroundColor(theme.colors.primary)
|
||||
.font(.system(size: 14))
|
||||
Spacer()
|
||||
Text(networkModel.contactNetworkStatus(contact).statusString)
|
||||
// TODO [sub status] use status from model
|
||||
// Text(networkModel.contactNetworkStatus(contact).statusString)
|
||||
Text(NetworkStatus.connected.statusString)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
serverImage()
|
||||
}
|
||||
}
|
||||
|
||||
private func serverImage() -> some View {
|
||||
let status = networkModel.contactNetworkStatus(contact)
|
||||
// TODO [sub status] use status from model
|
||||
let status = NetworkStatus.connected // networkModel.contactNetworkStatus(contact)
|
||||
return Image(systemName: status.imageName)
|
||||
.foregroundColor(status == .connected ? .green : theme.colors.secondary)
|
||||
.font(.system(size: 12))
|
||||
@@ -608,7 +610,8 @@ struct ChatInfoView: View {
|
||||
private func networkStatusAlert() -> Alert {
|
||||
Alert(
|
||||
title: Text("Network status"),
|
||||
message: Text(networkModel.contactNetworkStatus(contact).statusExplanation)
|
||||
// TODO [sub status] use status from model
|
||||
message: Text("") // Text(networkModel.contactNetworkStatus(contact).statusExplanation)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -788,7 +788,8 @@ struct ComposeView: View {
|
||||
await MainActor.run {
|
||||
self.chatModel.updateContact(contact)
|
||||
clearState()
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
// TODO [sub status] review
|
||||
// NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(title: "Empty message!")
|
||||
@@ -827,7 +828,8 @@ struct ComposeView: View {
|
||||
if let contact = await apiConnectPreparedContact(contactId: chat.chatInfo.apiId, incognito: incognito, msg: mc) {
|
||||
await MainActor.run {
|
||||
self.chatModel.updateContact(contact)
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
// TODO [sub status] review
|
||||
// NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
clearState()
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -396,7 +396,8 @@ struct GroupMemberInfoView: View {
|
||||
ItemsModel.shared.loadOpenChat(memberContact.id) {
|
||||
dismissAllSheets(animated: true)
|
||||
}
|
||||
NetworkModel.shared.setContactNetworkStatus(memberContact, .connected)
|
||||
// TODO [sub status] review
|
||||
// NetworkModel.shared.setContactNetworkStatus(memberContact, .connected)
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("createMemberContactButton apiCreateMemberContact error: \(responseError(error))")
|
||||
|
||||
@@ -460,12 +460,6 @@ struct ChatPreviewView: View {
|
||||
@ViewBuilder private func chatStatusImage() -> some View {
|
||||
let size = dynamicSize(userFont).incognitoSize
|
||||
switch chat.chatInfo {
|
||||
case let .direct(contact):
|
||||
if contact.active, let status = contact.activeConn?.connStatus, status == .ready || status == .sndReady {
|
||||
NetworkStatusView(contact: contact, size: size)
|
||||
} else {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
}
|
||||
case .group:
|
||||
if progressByTimeout {
|
||||
ProgressView()
|
||||
@@ -482,30 +476,6 @@ struct ChatPreviewView: View {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
}
|
||||
}
|
||||
|
||||
struct NetworkStatusView: View {
|
||||
@Environment(\.dynamicTypeSize) private var userFont: DynamicTypeSize
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@ObservedObject var networkModel = NetworkModel.shared
|
||||
|
||||
let contact: Contact
|
||||
let size: CGFloat
|
||||
|
||||
var body: some View {
|
||||
let dynamicChatInfoSize = dynamicSize(userFont).chatInfoSize
|
||||
switch (networkModel.contactNetworkStatus(contact)) {
|
||||
case .connected: incognitoIcon(contact.contactConnIncognito, theme.colors.secondary, size: size)
|
||||
case .error:
|
||||
Image(systemName: "exclamationmark.circle")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: dynamicChatInfoSize, height: dynamicChatInfoSize)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
default:
|
||||
ProgressView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func incognitoIcon(_ incognito: Bool, _ secondaryColor: Color, size: CGFloat) -> some View {
|
||||
|
||||
@@ -28,12 +28,6 @@ chatStartedSwift = "{\"result\":{\"_owsf\":true,\"chatStarted\":{}}}"
|
||||
chatStartedTagged :: LB.ByteString
|
||||
chatStartedTagged = "{\"result\":{\"type\":\"chatStarted\"}}"
|
||||
|
||||
networkStatusesSwift :: LB.ByteString
|
||||
networkStatusesSwift = "{\"result\":{\"_owsf\":true,\"networkStatuses\":{\"user_\":" <> userJSON <> ",\"networkStatuses\":[]}}}"
|
||||
|
||||
networkStatusesTagged :: LB.ByteString
|
||||
networkStatusesTagged = "{\"result\":{\"type\":\"networkStatuses\",\"user_\":" <> userJSON <> ",\"networkStatuses\":[]}}"
|
||||
|
||||
userJSON :: LB.ByteString
|
||||
userJSON = "{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"\",\"shortDescr\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"},\"files\":{\"allow\":\"always\"},\"calls\":{\"allow\":\"yes\"},\"sessions\":{\"allow\":\"no\"},\"commands\":[]},\"activeUser\":true,\"activeOrder\":1,\"showNtfs\":true,\"sendRcptsContacts\":true,\"sendRcptsSmallGroups\":true,\"autoAcceptMemberContacts\":false}"
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ owsf2TaggedJSONTest = do
|
||||
activeUserExistsSwift `to` activeUserExistsTagged
|
||||
activeUserSwift `to` activeUserTagged
|
||||
chatStartedSwift `to` chatStartedTagged
|
||||
networkStatusesSwift `to` networkStatusesTagged
|
||||
parsedMarkdownSwift `to` parsedMarkdownTagged
|
||||
where
|
||||
to :: LB.ByteString -> LB.ByteString -> IO ()
|
||||
|
||||
Reference in New Issue
Block a user