status-lib/status/statusgo_backend/contacts.nim

102 lines
3.2 KiB
Nim

import tables, json, strmisc, atomics, sequtils, json_serialization, chronicles
import ./core, ./settings, ./accounts, ../utils, ../types/[profile, setting]
var
contacts {.threadvar.}: seq[Profile]
contactsIndex {.threadvar.}: Table[string, Profile]
contactsInited {.threadvar.}: bool
dirty: Atomic[bool]
proc getContactByID*(id: string): Profile =
let response = callPrivateRPC("getContactByID".prefix, %* [id])
dirty.store(true)
let responseResult = parseJSON($response)["result"]
if responseResult == nil or responseResult.kind == JNull:
return nil
return toProfile(parseJSON($response)["result"])
proc getContacts*(useCache: bool = true): (seq[Profile], bool) =
let cacheIsDirty = (not useCache) or (not contactsInited) or dirty.load
if not cacheIsDirty:
return (contacts, true)
let payload = %* []
let response = callPrivateRPC("contacts".prefix, payload).parseJson
dirty.store(false)
contactsIndex = initTable[string, Profile]()
contactsInited = true
if response["result"].kind == JNull:
contacts = @[]
return (contacts, false)
contacts = map(response["result"].getElems(), proc(x: JsonNode): Profile = x.toProfile())
for contact in contacts:
contactsIndex[contact.id] = contact
return (contacts, false)
proc getContactsIndex*(): (Table[string, Profile], bool)=
let cacheIsDirty = (not contactsInited) or dirty.load
if not cacheIsDirty:
return (contactsIndex, true)
discard getContacts()
return (contactsIndex, false)
proc blockContact*(id: string) =
discard callPrivateRPC("blockContact".prefix, %* [id])
dirty.store(true)
proc unblockContact*(id: string) =
discard callPrivateRPC("unblockContact".prefix, %* [id])
dirty.store(true)
proc removeContact*(id: string) =
discard callPrivateRPC("removeContact".prefix, %* [id])
dirty.store(true)
proc rejectContactRequest*(id: string) =
let payload = %*[{
"id": id
}]
discard callPrivateRPC("rejectContactRequest".prefix, payload)
dirty.store(true)
proc setContactLocalNickname*(id: string, name: string) =
let payload = %* [{
"id": id,
"nickname": name
}]
discard callPrivateRPC("setContactLocalNickname".prefix, payload)
dirty.store(true)
proc saveContact*(id: string, ensVerified: bool, ensName: string, alias: string,
identicon: string, thumbnail: string, largeImage: string, added: bool, blocked: bool,
hasAddedUs: bool, localNickname: string) =
# TODO: Most of these method arguments aren't used anymore
# as status-go's RPC API became smarter. Should remove those.
let payload = %* [{
"id": id,
"ensName": ensName
}]
discard callPrivateRPC("addContact".prefix, payload)
dirty.store(true)
proc sendContactUpdate*(publicKey: string, accountKeyUID: string) =
let preferredUsername = getSetting[string](Setting.PreferredUsername, "")
let usernames = getSetting[seq[string]](Setting.Usernames, @[])
var ensName = ""
if len(preferredUsername) > 0:
ensName = preferredUsername
elif len(usernames) >= 1:
ensName = usernames[0]
let identityImage = getIdentityImage(accountKeyUID)
discard callPrivateRPC("sendContactUpdate".prefix, %* [publicKey, ensName, identityImage.thumbnail])
dirty.store(true)