Add whisper.added.filter signal handler

This commit is contained in:
Richard Ramos 2020-05-25 13:33:22 -04:00 committed by RichΛrd
parent e5bed448ed
commit 20766d2dae
10 changed files with 108 additions and 25 deletions

View File

@ -2,7 +2,12 @@ import NimQml
import json, eventemitter import json, eventemitter
import ../../models/chat as chat_model import ../../models/chat as chat_model
import ../../signals/types import ../../signals/types
import ../../status/types as status_types
import view import view
import chronicles
logScope:
topics = "chat-controller"
type ChatController* = ref object of SignalSubscriber type ChatController* = ref object of SignalSubscriber
view*: ChatsView view*: ChatsView
@ -36,7 +41,7 @@ proc load*(self: ChatController, chatId: string) =
discard self.view.joinChat(chatId) discard self.view.joinChat(chatId)
self.view.setActiveChannelByIndex(0) self.view.setActiveChannelByIndex(0)
method onSignal(self: ChatController, data: Signal) = proc handleMessage(self: ChatController, data: Signal) =
var messageSignal = cast[MessageSignal](data) var messageSignal = cast[MessageSignal](data)
for c in messageSignal.chats: for c in messageSignal.chats:
@ -45,4 +50,14 @@ method onSignal(self: ChatController, data: Signal) =
for message in messageSignal.messages: for message in messageSignal.messages:
let chatMessage = message.toChatMessage() let chatMessage = message.toChatMessage()
self.view.pushMessage(message.chatId, chatMessage) self.view.pushMessage(message.localChatId, chatMessage)
proc handleWhisperFilter(self: ChatController, data: Signal) =
echo "Do something"
method onSignal(self: ChatController, data: Signal) =
case data.signalType:
of SignalType.Message: handleMessage(self, data)
of SignalType.WhisperFilterAdded: handleWhisperFilter(self, data)
else:
warn "Unhandled signal received", signalType = data.signalType

View File

@ -40,8 +40,8 @@ QtObject:
proc setActiveChannelByIndex*(self: ChatsView, index: int) {.slot.} = proc setActiveChannelByIndex*(self: ChatsView, index: int) {.slot.} =
let selectedChannel = self.chats.getChannel(index) let selectedChannel = self.chats.getChannel(index)
if self.activeChannel == selectedChannel.name: return if self.activeChannel == selectedChannel.id: return
self.activeChannel = selectedChannel.name self.activeChannel = selectedChannel.id
self.activeChannelChanged() self.activeChannelChanged()
proc setActiveChannel*(self: ChatsView, channel: string) = proc setActiveChannel*(self: ChatsView, channel: string) =
@ -72,10 +72,10 @@ QtObject:
proc joinChat*(self: ChatsView, channel: string): int {.slot.} = proc joinChat*(self: ChatsView, channel: string): int {.slot.} =
self.setActiveChannel(channel) self.setActiveChannel(channel)
if self.model.hasChannel(channel): if self.model.hasChannel(channel):
result = self.chats.chats.findByName(channel) result = self.chats.chats.findById(channel)
else: else:
self.model.join(channel) self.model.join(channel)
result = self.chats.addChatItemToList(ChatItem(name: channel)) result = self.chats.addChatItemToList(ChatItem(id: channel, name: channel))
proc updateChat*(self: ChatsView, chat: ChatItem) = proc updateChat*(self: ChatsView, chat: ChatItem) =
self.chats.updateChat(chat) self.chats.updateChat(chat)

View File

@ -59,10 +59,16 @@ QtObject:
proc getChannel*(self: ChannelsList, index: int): ChatItem = proc getChannel*(self: ChannelsList, index: int): ChatItem =
self.chats[index] self.chats[index]
proc updateChat*(self: ChannelsList, chat: ChatItem) = proc upsertChannel(self: ChannelsList, channel: ChatItem): int =
var idx = self.chats.findByName(chat.name) let idx = self.chats.findById(channel.id)
if idx > -1: if idx == -1:
self.chats[idx] = chat result = self.addChatItemToList(channel)
var x = self.createIndex(idx,0,nil) else:
var y = self.createIndex(idx,0,nil) result = idx
self.dataChanged(x, y, @[ChannelsRoles.Timestamp.int, ChannelsRoles.LastMessage.int, ChannelsRoles.UnreadMessages.int])
proc updateChat*(self: ChannelsList, channel: ChatItem) =
let idx = self.upsertChannel(channel)
self.chats[idx] = channel
let topLeft = self.createIndex(idx, 0, nil)
let bottomRight = self.createIndex(idx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Timestamp.int, ChannelsRoles.LastMessage.int, ChannelsRoles.UnreadMessages.int])

View File

@ -38,7 +38,7 @@ proc join*(self: ChatModel, chatId: string) =
let oneToOne = isOneToOneChat(chatId) let oneToOne = isOneToOneChat(chatId)
status_chat.loadFilters(chatId, oneToOne) status_chat.loadFilters(chatId = chatId, oneToOne = oneToOne)
status_chat.saveChat(chatId, oneToOne) status_chat.saveChat(chatId, oneToOne)
status_chat.chatMessages(chatId) status_chat.chatMessages(chatId)

View File

@ -1,7 +1,9 @@
import ../../signals/types import ../../signals/types
type ChatItem* = ref object type ChatItem* = ref object
id*: string
name*: string name*: string
chatType*: ChatType
lastMessage*: string lastMessage*: string
timestamp*: int64 timestamp*: int64
unviewedMessagesCount*: int unviewedMessagesCount*: int
@ -13,15 +15,26 @@ proc newChatItem*(): ChatItem =
result.timestamp = 0 result.timestamp = 0
result.unviewedMessagesCount = 0 result.unviewedMessagesCount = 0
proc findByName*(self: seq[ChatItem], name: string): int = proc findById*(self: seq[ChatItem], id: string): int =
result = -1 result = -1
var idx = -1
for item in self: for item in self:
inc result inc idx
if(item.name == name): break if(item.id == id):
result = idx
break
proc chatName(chat: Chat): string =
case chat.chatType
of ChatType.OneToOne: result = chat.lastMessage.alias
of ChatType.Public: result = chat.name
of ChatType.PrivateGroupChat: result = "TODO: determine private group name"
proc toChatItem*(chat: Chat): ChatItem = proc toChatItem*(chat: Chat): ChatItem =
result = ChatItem( result = ChatItem(
name: chat.name, id: chat.id,
name: chatName(chat),
chatType: chat.chatType,
lastMessage: chat.lastMessage.text, lastMessage: chat.lastMessage.text,
timestamp: chat.timestamp, timestamp: chat.timestamp,
unviewedMessagesCount: chat.unviewedMessagesCount unviewedMessagesCount: chat.unviewedMessagesCount

View File

@ -72,7 +72,8 @@ proc mainProc() =
signalController.addSubscriber(SignalType.Wallet, wallet) signalController.addSubscriber(SignalType.Wallet, wallet)
signalController.addSubscriber(SignalType.Wallet, node) signalController.addSubscriber(SignalType.Wallet, node)
signalController.addSubscriber(SignalType.Message, chat) signalController.addSubscriber(SignalType.Message, chat)
signalController.addSubscriber(SignalType.WhisperFilterAdded, chat)
engine.setRootContextProperty("signals", signalController.variant) engine.setRootContextProperty("signals", signalController.variant)
appState.subscribe(proc () = appState.subscribe(proc () =

View File

@ -5,6 +5,7 @@ import json
import types import types
import messages import messages
import chronicles import chronicles
import whisperFilter
logScope: logScope:
topics = "signals" topics = "signals"
@ -51,12 +52,18 @@ QtObject:
of "messages.new": of "messages.new":
signalType = SignalType.Message signalType = SignalType.Message
signal = messages.fromEvent(jsonSignal) signal = messages.fromEvent(jsonSignal)
of "whisper.filter.added":
signalType = SignalType.WhisperFilterAdded
signal = whisperFilter.fromEvent(jsonSignal)
of "wallet": of "wallet":
signalType = SignalType.Wallet signalType = SignalType.Wallet
signal = WalletSignal(content: $jsonSignal) signal = WalletSignal(content: $jsonSignal)
else: else:
warn "Unhandled signal received", type = signalString warn "Unhandled signal received", type = signalString
signalType = SignalType.Unknown signalType = SignalType.Unknown
return
signal.signalType = signalType
if not self.signalSubscribers.hasKey(signalType): if not self.signalSubscribers.hasKey(signalType):
self.signalSubscribers[signalType] = @[] self.signalSubscribers[signalType] = @[]

View File

@ -1,8 +1,10 @@
import chronicles import chronicles
import ../status/types
type SignalSubscriber* = ref object of RootObj type SignalSubscriber* = ref object of RootObj
type Signal* = ref object of RootObj type Signal* = ref object of RootObj
signalType*: SignalType
type WalletSignal* = ref object of Signal type WalletSignal* = ref object of Signal
content*: string content*: string
@ -37,9 +39,9 @@ method onSignal*(self: SignalSubscriber, data: Signal) {.base.} =
error "onSignal must be overriden in controller. Signal is unhandled" error "onSignal must be overriden in controller. Signal is unhandled"
type ChatType* = enum type ChatType* = enum
ChatTypeOneToOne = 1, OneToOne = 1,
ChatTypePublic = 2, Public = 2,
ChatTypePrivateGroupChat = 3 PrivateGroupChat = 3
type Chat* = object type Chat* = object
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat
@ -59,3 +61,14 @@ type Chat* = object
type MessageSignal* = ref object of Signal type MessageSignal* = ref object of Signal
messages*: seq[Message] messages*: seq[Message]
chats*: seq[Chat] chats*: seq[Chat]
type Filter* = object
chatId*: string
symKeyId*: string
listen*: bool
filterId*: string
identity*: string
topic*: string
type WhisperFilterSignal* = ref object of Signal
filters*: seq[Filter]

View File

@ -0,0 +1,21 @@
import json
import types
proc toFilter(jsonMsg: JsonNode): Filter =
result = Filter(
chatId: jsonMsg{"chatId"}.getStr,
symKeyId: jsonMsg{"symKeyId"}.getStr,
listen: jsonMsg{"listen"}.getBool,
filterId: jsonMsg{"filterId"}.getStr,
identity: jsonMsg{"identity"}.getStr,
topic: jsonMsg{"topic"}.getStr,
)
proc fromEvent*(event: JsonNode): Signal =
var signal:WhisperFilterSignal = WhisperFilterSignal()
if event["event"]{"filters"} != nil:
for jsonMsg in event["event"]["filters"]:
signal.filters.add(jsonMsg.toFilter)
result = signal

View File

@ -2,11 +2,18 @@ import core
import json import json
import utils import utils
proc loadFilters*(chatId: string, oneToOne = false) = 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, %* [ discard callPrivateRPC("loadFilters".prefix, %* [
[{ [{
"ChatID": chatId, "ChatID": chatId, # identifier of the chat
"OneToOne": oneToOne "FilterID": filterId, # whisper filter id generated
"SymKeyID": symKeyId, # symmetric key id used for symmetric filters
"OneToOne": oneToOne, # if asymmetric encryption is used for this chat
"Identity": identity, # public key of the other recipient for non-public filters.
"Topic": topic, # whisper topic
"Discovery": discovery,
"Negotiated": negotiated,
"Listen": listen # whether we are actually listening for messages on this chat, or the filter is only created in order to be able to post on the topic
}] }]
]) ])