From f7d99c4bb441889d5704f10bdcd88af5df95fc6a Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Mon, 25 May 2020 15:20:11 -0400 Subject: [PATCH] feat: get last 20 messages of a channel when joining the chat --- src/models/accounts.nim | 7 +++++++ src/models/chat.nim | 25 +++++++++++++++++++++---- src/status/chat.nim | 29 +++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/models/accounts.nim b/src/models/accounts.nim index b88762f24d..21bda57cdc 100644 --- a/src/models/accounts.nim +++ b/src/models/accounts.nim @@ -2,6 +2,7 @@ import eventemitter import json_serialization import ../status/accounts as status_accounts import ../status/types +import ../status/libstatus type Address* = ref object @@ -36,9 +37,15 @@ proc generateAddresses*(self: AccountModel): seq[GeneratedAccount] = proc generateRandomAccountAndLogin*(self: AccountModel) = let generatedAccounts = status_accounts.generateAddresses() let account = status_accounts.setupAccount(generatedAccounts[0], "qwerty") + # TODO this is needed for now for the retrieving of past messages. We'll either move or remove it later + let peer = "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443" + discard libstatus.addPeer(peer) self.events.emit("accountsReady", AccountArgs(account: account)) proc storeAccountAndLogin*(self: AccountModel, selectedAccountIndex: int, password: string): Account = let generatedAccount: GeneratedAccount = self.generatedAddresses[selectedAccountIndex] result = status_accounts.setupAccount(generatedAccount, password) + # TODO this is needed for now for the retrieving of past messages. We'll either move or remove it later + let peer = "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443" + discard libstatus.addPeer(peer) self.events.emit("accountsReady", AccountArgs(account: result)) diff --git a/src/models/chat.nim b/src/models/chat.nim index 8788b55e91..11e577bea9 100644 --- a/src/models/chat.nim +++ b/src/models/chat.nim @@ -1,7 +1,8 @@ -import eventemitter, sets -import json, sets, eventemitter +import eventemitter, sets, json, strutils import ../status/utils import ../status/chat as status_chat +import chronicles +import ../status/libstatus import chat/chat_item import chat/chat_message @@ -34,14 +35,30 @@ proc join*(self: ChatModel, chatId: string) = self.channels.incl chatId - # TODO: save chat list in the db + let generatedSymKey = status_chat.generateSymKeyFromPassword() + # TODO get this from the connection or something + let peer = "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443" + + # TODO: save chat list in the db let oneToOne = isOneToOneChat(chatId) - status_chat.loadFilters(chatId = chatId, oneToOne = oneToOne) + let filterResult = status_chat.loadFilters(chatId = chatId, oneToOne = oneToOne) status_chat.saveChat(chatId, oneToOne) status_chat.chatMessages(chatId) + let parsedResult = parseJson(filterResult)["result"] + var topics = newSeq[string](0) + for topicObj in parsedResult: + if (($topicObj["chatId"]).strip(chars = {'"'}) == chatId): + topics.add(($topicObj["topic"]).strip(chars = {'"'})) + + if (topics.len == 0): + warn "No topic found for the chat. Cannot load past messages" + else: + status_chat.requestMessages(topics, generatedSymKey, peer, 20) + + proc sendMessage*(self: ChatModel, chatId: string, msg: string): string = var sentMessage = status_chat.sendChatMessage(chatId, msg) var parsedMessage = parseJson(sentMessage)["result"]["chats"][0]["lastMessage"] diff --git a/src/status/chat.nim b/src/status/chat.nim index cbe2f749db..9c01daf85d 100644 --- a/src/status/chat.nim +++ b/src/status/chat.nim @@ -1,9 +1,12 @@ import core import json import utils +import times +import strutils +import chronicles -proc loadFilters*(chatId: string, filterId: string = "", symKeyId: string = "", oneToOne: bool = false, identity: string = "", topic: string = "", discovery: bool = false, negotiated: bool = false, listen: bool = true) = - discard callPrivateRPC("loadFilters".prefix, %* [ +proc loadFilters*(chatId: string, filterId: string = "", symKeyId: string = "", oneToOne: bool = false, identity: string = "", topic: string = "", discovery: bool = false, negotiated: bool = false, listen: bool = true): string = + result = callPrivateRPC("loadFilters".prefix, %* [ [{ "ChatID": chatId, # identifier of the chat "FilterID": filterId, # whisper filter id generated @@ -27,6 +30,7 @@ proc saveChat*(chatId: string, oneToOne = false) = "active": true, "id": chatId, "unviewedMessagesCount": 0, + # TODO use constants for those too or use the Date "chatType": if oneToOne: 1 else: 2, "timestamp": 1588940692659 } @@ -35,6 +39,27 @@ proc saveChat*(chatId: string, oneToOne = false) = proc chatMessages*(chatId: string) = discard callPrivateRPC("chatMessages".prefix, %* [chatId, nil, 20]) +# TODO this probably belongs in another file +proc generateSymKeyFromPassword*(): string = + result = ($parseJson(callPrivateRPC("waku_generateSymKeyFromPassword", %* [ + # TODO unhardcode this for non-status mailservers + "status-offline-inbox" + ]))["result"]).strip(chars = {'"'}) + +proc requestMessages*(topics: seq[string], symKeyID: string, peer: string, numberOfMessages: int) = + discard callPrivateRPC("requestMessages".prefix, %* [ + { + "topics": topics, + "mailServerPeer": peer, + "symKeyID": symKeyID, + "timeout": 30, + "limit": numberOfMessages, + "cursor": nil, + "from": times.toUnix(times.getTime()) - 30000 # Unhardcode this. Need to keep the last fetch in a DB + } + ]) + + proc sendChatMessage*(chatId: string, msg: string): string = callPrivateRPC("sendChatMessage".prefix, %* [ {