mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 12:49:53 +00:00
mobile: use batched DOWN/UP events, core: include pending contacts (#573)
* mobile: use batched DOWN/UP events, core: include pending contacts * query style
This commit is contained in:
parent
44de6297ee
commit
fc5cdc5eb1
5 changed files with 61 additions and 43 deletions
|
@ -67,8 +67,8 @@ class ChatModel(val controller: ChatController) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateNetworkStatus(contact: Contact, status: Chat.NetworkStatus) {
|
fun updateNetworkStatus(id: ChatId, status: Chat.NetworkStatus) {
|
||||||
val i = getChatIndex(contact.id)
|
val i = getChatIndex(id)
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
val chat = chats[i]
|
val chat = chats[i]
|
||||||
chats[i] = chat.copy(serverInfo = chat.serverInfo.copy(networkStatus = status))
|
chats[i] = chat.copy(serverInfo = chat.serverInfo.copy(networkStatus = status))
|
||||||
|
@ -389,6 +389,14 @@ class Contact(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class ContactRef(
|
||||||
|
val contactId: Long,
|
||||||
|
var localDisplayName: String
|
||||||
|
) {
|
||||||
|
val id: ChatId get() = "@$contactId"
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class ContactSubStatus(
|
class ContactSubStatus(
|
||||||
val contact: Contact,
|
val contact: Contact,
|
||||||
|
|
|
@ -352,7 +352,7 @@ open class ChatController(private val ctrl: ChatCtrl, private val ntfManager: Nt
|
||||||
is CR.ContactConnected -> {
|
is CR.ContactConnected -> {
|
||||||
chatModel.updateContact(r.contact)
|
chatModel.updateContact(r.contact)
|
||||||
chatModel.removeChat(r.contact.activeConn.id)
|
chatModel.removeChat(r.contact.activeConn.id)
|
||||||
chatModel.updateNetworkStatus(r.contact, Chat.NetworkStatus.Connected())
|
chatModel.updateNetworkStatus(r.contact.id, Chat.NetworkStatus.Connected())
|
||||||
// NtfManager.shared.notifyContactConnected(contact)
|
// NtfManager.shared.notifyContactConnected(contact)
|
||||||
}
|
}
|
||||||
is CR.ContactConnecting -> {
|
is CR.ContactConnecting -> {
|
||||||
|
@ -371,17 +371,18 @@ open class ChatController(private val ctrl: ChatCtrl, private val ntfManager: Nt
|
||||||
chatModel.updateChatInfo(cInfo)
|
chatModel.updateChatInfo(cInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CR.ContactSubscribed -> processContactSubscribed(r.contact)
|
is CR.ContactsSubscribed -> updateContactsStatus(r.contactRefs, Chat.NetworkStatus.Connected())
|
||||||
is CR.ContactDisconnected -> {
|
is CR.ContactsDisconnected -> updateContactsStatus(r.contactRefs, Chat.NetworkStatus.Disconnected())
|
||||||
chatModel.updateContact(r.contact)
|
|
||||||
chatModel.updateNetworkStatus(r.contact, Chat.NetworkStatus.Disconnected())
|
|
||||||
}
|
|
||||||
is CR.ContactSubError -> processContactSubError(r.contact, r.chatError)
|
is CR.ContactSubError -> processContactSubError(r.contact, r.chatError)
|
||||||
is CR.ContactSubSummary -> {
|
is CR.ContactSubSummary -> {
|
||||||
for (sub in r.contactSubscriptions) {
|
for (sub in r.contactSubscriptions) {
|
||||||
val err = sub.contactError
|
val err = sub.contactError
|
||||||
if (err == null) processContactSubscribed(sub.contact)
|
if (err == null) {
|
||||||
else processContactSubError(sub.contact, sub.contactError)
|
chatModel.updateContact(sub.contact)
|
||||||
|
chatModel.updateNetworkStatus(sub.contact.id, Chat.NetworkStatus.Connected())
|
||||||
|
} else {
|
||||||
|
processContactSubError(sub.contact, sub.contactError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is CR.NewChatItem -> {
|
is CR.NewChatItem -> {
|
||||||
|
@ -436,9 +437,10 @@ open class ChatController(private val ctrl: ChatCtrl, private val ntfManager: Nt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processContactSubscribed(contact: Contact) {
|
fun updateContactsStatus(contactRefs: List<ContactRef>, status: Chat.NetworkStatus) {
|
||||||
chatModel.updateContact(contact)
|
for (c in contactRefs) {
|
||||||
chatModel.updateNetworkStatus(contact, Chat.NetworkStatus.Connected())
|
chatModel.updateNetworkStatus(c.id, status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processContactSubError(contact: Contact, chatError: ChatError) {
|
fun processContactSubError(contact: Contact, chatError: ChatError) {
|
||||||
|
@ -454,7 +456,7 @@ open class ChatController(private val ctrl: ChatCtrl, private val ntfManager: Nt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else e.string
|
else e.string
|
||||||
chatModel.updateNetworkStatus(contact, Chat.NetworkStatus.Error(err))
|
chatModel.updateNetworkStatus(contact.id, Chat.NetworkStatus.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showBackgroundServiceNotice() {
|
fun showBackgroundServiceNotice() {
|
||||||
|
@ -667,8 +669,8 @@ sealed class CR {
|
||||||
@Serializable @SerialName("acceptingContactRequest") class AcceptingContactRequest(val contact: Contact): CR()
|
@Serializable @SerialName("acceptingContactRequest") class AcceptingContactRequest(val contact: Contact): CR()
|
||||||
@Serializable @SerialName("contactRequestRejected") class ContactRequestRejected: CR()
|
@Serializable @SerialName("contactRequestRejected") class ContactRequestRejected: CR()
|
||||||
@Serializable @SerialName("contactUpdated") class ContactUpdated(val toContact: Contact): CR()
|
@Serializable @SerialName("contactUpdated") class ContactUpdated(val toContact: Contact): CR()
|
||||||
@Serializable @SerialName("contactSubscribed") class ContactSubscribed(val contact: Contact): CR()
|
@Serializable @SerialName("contactsSubscribed") class ContactsSubscribed(val server: String, val contactRefs: List<ContactRef>): CR()
|
||||||
@Serializable @SerialName("contactDisconnected") class ContactDisconnected(val contact: Contact): CR()
|
@Serializable @SerialName("contactsDisconnected") class ContactsDisconnected(val server: String, val contactRefs: List<ContactRef>): CR()
|
||||||
@Serializable @SerialName("contactSubError") class ContactSubError(val contact: Contact, val chatError: ChatError): CR()
|
@Serializable @SerialName("contactSubError") class ContactSubError(val contact: Contact, val chatError: ChatError): CR()
|
||||||
@Serializable @SerialName("contactSubSummary") class ContactSubSummary(val contactSubscriptions: List<ContactSubStatus>): CR()
|
@Serializable @SerialName("contactSubSummary") class ContactSubSummary(val contactSubscriptions: List<ContactSubStatus>): CR()
|
||||||
@Serializable @SerialName("groupSubscribed") class GroupSubscribed(val group: GroupInfo): CR()
|
@Serializable @SerialName("groupSubscribed") class GroupSubscribed(val group: GroupInfo): CR()
|
||||||
|
@ -713,8 +715,8 @@ sealed class CR {
|
||||||
is AcceptingContactRequest -> "acceptingContactRequest"
|
is AcceptingContactRequest -> "acceptingContactRequest"
|
||||||
is ContactRequestRejected -> "contactRequestRejected"
|
is ContactRequestRejected -> "contactRequestRejected"
|
||||||
is ContactUpdated -> "contactUpdated"
|
is ContactUpdated -> "contactUpdated"
|
||||||
is ContactSubscribed -> "contactSubscribed"
|
is ContactsSubscribed -> "contactsSubscribed"
|
||||||
is ContactDisconnected -> "contactDisconnected"
|
is ContactsDisconnected -> "contactsDisconnected"
|
||||||
is ContactSubError -> "contactSubError"
|
is ContactSubError -> "contactSubError"
|
||||||
is ContactSubSummary -> "contactSubSummary"
|
is ContactSubSummary -> "contactSubSummary"
|
||||||
is GroupSubscribed -> "groupSubscribed"
|
is GroupSubscribed -> "groupSubscribed"
|
||||||
|
@ -760,8 +762,8 @@ sealed class CR {
|
||||||
is AcceptingContactRequest -> json.encodeToString(contact)
|
is AcceptingContactRequest -> json.encodeToString(contact)
|
||||||
is ContactRequestRejected -> noDetails()
|
is ContactRequestRejected -> noDetails()
|
||||||
is ContactUpdated -> json.encodeToString(toContact)
|
is ContactUpdated -> json.encodeToString(toContact)
|
||||||
is ContactSubscribed -> json.encodeToString(contact)
|
is ContactsSubscribed -> "server: $server\ncontacts:\n${json.encodeToString(contactRefs)}"
|
||||||
is ContactDisconnected -> json.encodeToString(contact)
|
is ContactsDisconnected -> "server: $server\ncontacts:\n${json.encodeToString(contactRefs)}"
|
||||||
is ContactSubError -> "error:\n${chatError.string}\ncontact:\n${json.encodeToString(contact)}"
|
is ContactSubError -> "error:\n${chatError.string}\ncontact:\n${json.encodeToString(contact)}"
|
||||||
is ContactSubSummary -> json.encodeToString(contactSubscriptions)
|
is ContactSubSummary -> json.encodeToString(contactSubscriptions)
|
||||||
is GroupSubscribed -> json.encodeToString(group)
|
is GroupSubscribed -> json.encodeToString(group)
|
||||||
|
|
|
@ -70,9 +70,9 @@ final class ChatModel: ObservableObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateNetworkStatus(_ contact: Contact, _ status: Chat.NetworkStatus) {
|
func updateNetworkStatus(_ id: ChatId, _ status: Chat.NetworkStatus) {
|
||||||
if let ix = getChatIndex(contact.id) {
|
if let i = getChatIndex(id) {
|
||||||
chats[ix].serverInfo.networkStatus = status
|
chats[i].serverInfo.networkStatus = status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +488,13 @@ struct Contact: Identifiable, Decodable, NamedChat {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ContactRef: Decodable {
|
||||||
|
var contactId: Int64
|
||||||
|
var localDisplayName: ContactName
|
||||||
|
|
||||||
|
var id: ChatId { get { "@\(contactId)" } }
|
||||||
|
}
|
||||||
|
|
||||||
struct ContactSubStatus: Decodable {
|
struct ContactSubStatus: Decodable {
|
||||||
var contact: Contact
|
var contact: Contact
|
||||||
var contactError: ChatError?
|
var contactError: ChatError?
|
||||||
|
|
|
@ -159,8 +159,8 @@ enum ChatResponse: Decodable, Error {
|
||||||
case acceptingContactRequest(contact: Contact)
|
case acceptingContactRequest(contact: Contact)
|
||||||
case contactRequestRejected
|
case contactRequestRejected
|
||||||
case contactUpdated(toContact: Contact)
|
case contactUpdated(toContact: Contact)
|
||||||
case contactSubscribed(contact: Contact)
|
case contactsSubscribed(server: String, contactRefs: [ContactRef])
|
||||||
case contactDisconnected(contact: Contact)
|
case contactsDisconnected(server: String, contactRefs: [ContactRef])
|
||||||
case contactSubError(contact: Contact, chatError: ChatError)
|
case contactSubError(contact: Contact, chatError: ChatError)
|
||||||
case contactSubSummary(contactSubscriptions: [ContactSubStatus])
|
case contactSubSummary(contactSubscriptions: [ContactSubStatus])
|
||||||
case groupSubscribed(groupInfo: GroupInfo)
|
case groupSubscribed(groupInfo: GroupInfo)
|
||||||
|
@ -207,8 +207,8 @@ enum ChatResponse: Decodable, Error {
|
||||||
case .acceptingContactRequest: return "acceptingContactRequest"
|
case .acceptingContactRequest: return "acceptingContactRequest"
|
||||||
case .contactRequestRejected: return "contactRequestRejected"
|
case .contactRequestRejected: return "contactRequestRejected"
|
||||||
case .contactUpdated: return "contactUpdated"
|
case .contactUpdated: return "contactUpdated"
|
||||||
case .contactSubscribed: return "contactSubscribed"
|
case .contactsSubscribed: return "contactsSubscribed"
|
||||||
case .contactDisconnected: return "contactDisconnected"
|
case .contactsDisconnected: return "contactsDisconnected"
|
||||||
case .contactSubError: return "contactSubError"
|
case .contactSubError: return "contactSubError"
|
||||||
case .contactSubSummary: return "contactSubSummary"
|
case .contactSubSummary: return "contactSubSummary"
|
||||||
case .groupSubscribed: return "groupSubscribed"
|
case .groupSubscribed: return "groupSubscribed"
|
||||||
|
@ -258,8 +258,8 @@ enum ChatResponse: Decodable, Error {
|
||||||
case let .acceptingContactRequest(contact): return String(describing: contact)
|
case let .acceptingContactRequest(contact): return String(describing: contact)
|
||||||
case .contactRequestRejected: return noDetails
|
case .contactRequestRejected: return noDetails
|
||||||
case let .contactUpdated(toContact): return String(describing: toContact)
|
case let .contactUpdated(toContact): return String(describing: toContact)
|
||||||
case let .contactSubscribed(contact): return String(describing: contact)
|
case let .contactsSubscribed(server, contactRefs): return "server: \(server)\ncontacts:\n\(String(describing: contactRefs))"
|
||||||
case let .contactDisconnected(contact): return String(describing: contact)
|
case let .contactsDisconnected(server, contactRefs): return "server: \(server)\ncontacts:\n\(String(describing: contactRefs))"
|
||||||
case let .contactSubError(contact, chatError): return "contact:\n\(String(describing: contact))\nerror:\n\(String(describing: chatError))"
|
case let .contactSubError(contact, chatError): return "contact:\n\(String(describing: contact))\nerror:\n\(String(describing: chatError))"
|
||||||
case let .contactSubSummary(contactSubscriptions): return String(describing: contactSubscriptions)
|
case let .contactSubSummary(contactSubscriptions): return String(describing: contactSubscriptions)
|
||||||
case let .groupSubscribed(groupInfo): return String(describing: groupInfo)
|
case let .groupSubscribed(groupInfo): return String(describing: groupInfo)
|
||||||
|
@ -720,7 +720,7 @@ func processReceivedMsg(_ res: ChatResponse) {
|
||||||
case let .contactConnected(contact):
|
case let .contactConnected(contact):
|
||||||
m.updateContact(contact)
|
m.updateContact(contact)
|
||||||
m.removeChat(contact.activeConn.id)
|
m.removeChat(contact.activeConn.id)
|
||||||
m.updateNetworkStatus(contact, .connected)
|
m.updateNetworkStatus(contact.id, .connected)
|
||||||
NtfManager.shared.notifyContactConnected(contact)
|
NtfManager.shared.notifyContactConnected(contact)
|
||||||
case let .contactConnecting(contact):
|
case let .contactConnecting(contact):
|
||||||
m.updateContact(contact)
|
m.updateContact(contact)
|
||||||
|
@ -736,11 +736,10 @@ func processReceivedMsg(_ res: ChatResponse) {
|
||||||
if m.hasChat(toContact.id) {
|
if m.hasChat(toContact.id) {
|
||||||
m.updateChatInfo(cInfo)
|
m.updateChatInfo(cInfo)
|
||||||
}
|
}
|
||||||
case let .contactSubscribed(contact):
|
case let .contactsSubscribed(_, contactRefs):
|
||||||
processContactSubscribed(contact)
|
updateContactsStatus(contactRefs, status: .connected)
|
||||||
case let .contactDisconnected(contact):
|
case let .contactsDisconnected(_, contactRefs):
|
||||||
m.updateContact(contact)
|
updateContactsStatus(contactRefs, status: .disconnected)
|
||||||
m.updateNetworkStatus(contact, .disconnected)
|
|
||||||
case let .contactSubError(contact, chatError):
|
case let .contactSubError(contact, chatError):
|
||||||
processContactSubError(contact, chatError)
|
processContactSubError(contact, chatError)
|
||||||
case let .contactSubSummary(contactSubscriptions):
|
case let .contactSubSummary(contactSubscriptions):
|
||||||
|
@ -748,7 +747,8 @@ func processReceivedMsg(_ res: ChatResponse) {
|
||||||
if let err = sub.contactError {
|
if let err = sub.contactError {
|
||||||
processContactSubError(sub.contact, err)
|
processContactSubError(sub.contact, err)
|
||||||
} else {
|
} else {
|
||||||
processContactSubscribed(sub.contact)
|
m.updateContact(sub.contact)
|
||||||
|
m.updateNetworkStatus(sub.contact.id, .connected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .newChatItem(aChatItem):
|
case let .newChatItem(aChatItem):
|
||||||
|
@ -810,10 +810,11 @@ func processReceivedMsg(_ res: ChatResponse) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processContactSubscribed(_ contact: Contact) {
|
func updateContactsStatus(_ contactRefs: [ContactRef], status: Chat.NetworkStatus) {
|
||||||
let m = ChatModel.shared
|
let m = ChatModel.shared
|
||||||
m.updateContact(contact)
|
for c in contactRefs {
|
||||||
m.updateNetworkStatus(contact, .connected)
|
m.updateNetworkStatus(c.id, status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processContactSubError(_ contact: Contact, _ chatError: ChatError) {
|
func processContactSubError(_ contact: Contact, _ chatError: ChatError) {
|
||||||
|
@ -825,7 +826,7 @@ func processContactSubError(_ contact: Contact, _ chatError: ChatError) {
|
||||||
case .errorAgent(agentError: .SMP(smpErr: .AUTH)): err = "contact deleted"
|
case .errorAgent(agentError: .SMP(smpErr: .AUTH)): err = "contact deleted"
|
||||||
default: err = String(describing: chatError)
|
default: err = String(describing: chatError)
|
||||||
}
|
}
|
||||||
m.updateNetworkStatus(contact, .error(err))
|
m.updateNetworkStatus(contact.id, .error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct UserResponse: Decodable {
|
private struct UserResponse: Decodable {
|
||||||
|
|
|
@ -1209,11 +1209,11 @@ getConnectionsContacts st userId agentConnIds =
|
||||||
SELECT ct.contact_id, ct.local_display_name
|
SELECT ct.contact_id, ct.local_display_name
|
||||||
FROM contacts ct
|
FROM contacts ct
|
||||||
JOIN connections c ON c.contact_id = ct.contact_id
|
JOIN connections c ON c.contact_id = ct.contact_id
|
||||||
WHERE ct.user_id = ? AND c.agent_conn_id IN (SELECT conn_id FROM temp.conn_ids)
|
WHERE ct.user_id = ?
|
||||||
|
AND c.agent_conn_id IN (SELECT conn_id FROM temp.conn_ids)
|
||||||
AND c.conn_type = ?
|
AND c.conn_type = ?
|
||||||
AND (c.conn_status = ? OR c.conn_status = ?)
|
|
||||||
|]
|
|]
|
||||||
(userId, ConnContact, ConnReady, ConnSndReady)
|
(userId, ConnContact)
|
||||||
DB.execute_ db "DROP TABLE temp.conn_ids"
|
DB.execute_ db "DROP TABLE temp.conn_ids"
|
||||||
pure conns
|
pure conns
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue