diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index 6eb46d9137..5ca30fd0e0 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -68,6 +68,12 @@ proc changeLanguage(locale: string) = type AppController* = ref object of RootObj appService: AppService + # Global + localAppSettingsVariant: QVariant + localAccountSettingsVariant: QVariant + localAccountSensitiveSettingsVariant: QVariant + userProfileVariant: QVariant + # Services osNotificationService: os_notification_service.Service keychainService: keychain_service.Service @@ -92,12 +98,6 @@ type mnemonicService: mnemonic_service.Service privacyService: privacy_service.Service - # Core - localAppSettingsVariant: QVariant - localAccountSettingsVariant: QVariant - localAccountSensitiveSettingsVariant: QVariant - userProfileVariant: QVariant - # Modules startupModule: startup_module.AccessInterface mainModule: main_module.AccessInterface @@ -134,6 +134,13 @@ proc connect(self: AppController) = proc newAppController*(appService: AppService): AppController = result = AppController() result.appService = appService + + # Global + result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings) + result.localAccountSettingsVariant = newQVariant(singletonInstance.localAccountSettings) + result.localAccountSensitiveSettingsVariant = newQVariant(singletonInstance.localAccountSensitiveSettings) + result.userProfileVariant = newQVariant(singletonInstance.userProfile) + # Services result.osNotificationService = os_notification_service.newService(appService.status.events) result.keychainService = keychain_service.newService(appService.status.events) @@ -161,12 +168,6 @@ proc newAppController*(appService: AppService): AppController = result.ensService = ens_service.newService() result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService, result.ensService) - # Core - result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings) - result.localAccountSettingsVariant = newQVariant(singletonInstance.localAccountSettings) - result.localAccountSensitiveSettingsVariant = newQVariant(singletonInstance.localAccountSensitiveSettings) - result.userProfileVariant = newQVariant(singletonInstance.userProfile) - # Modules result.startupModule = startup_module.newModule[AppController]( result, diff --git a/src/app/chat/signal_handling.nim b/src/app/chat/signal_handling.nim index 485ebb14a8..c3638d11fe 100644 --- a/src/app/chat/signal_handling.nim +++ b/src/app/chat/signal_handling.nim @@ -1,6 +1,5 @@ import - ../core/tasks/marathon/mailserver/worker, - status/signals + ../core/tasks/marathon/mailserver/worker proc handleSignals(self: ChatController) = self.status.events.on(SignalType.Message.event) do(e:Args): diff --git a/src/app/core/main.nim b/src/app/core/main.nim index 21ee5e5820..a3af0e17f7 100644 --- a/src/app/core/main.nim +++ b/src/app/core/main.nim @@ -1,35 +1,37 @@ -import chronicles, task_runner +import NimQml, chronicles, task_runner import status/status as status_lib_status import ./tasks/marathon, - ./tasks/marathon/worker, + ./tasks/marathon/mailserver/controller, + ./tasks/marathon/mailserver/worker, ./tasks/threadpool, - ./signals/signal_controller + ./signals/signals_manager export status_lib_status -export marathon, task_runner, signal_controller - -logScope: - topics = "app-services" +export marathon, task_runner, signals_manager type AppService* = ref object # AppService should be renamed to "Foundation" status*: Status # in one point of time this should be completely removed # foundation threadpool*: ThreadPool marathon*: Marathon - signalController*: SignalsController + signalsManager*: SignalsManager + mailserverController*: MailserverController + mailserverWorker*: MailserverWorker -proc newAppService*(status: Status, worker: MarathonWorker): AppService = +proc newAppService*(status: Status): AppService = result = AppService() result.status = status + result.mailserverController = newMailserverController(status) + result.mailserverWorker = newMailserverWorker(cast[ByteAddress](result.mailserverController.vptr)) result.threadpool = newThreadPool() - result.marathon = newMarathon(worker) - result.signalController = newSignalsController(status) + result.marathon = newMarathon(result.mailserverWorker) + result.signalsManager = newSignalsManager(status.events) proc delete*(self: AppService) = self.threadpool.teardown() self.marathon.teardown() - self.signalController.delete() + self.signalsManager.delete() proc onLoggedIn*(self: AppService) = self.marathon.onLoggedIn() diff --git a/src/app/core/signals/remote_signals/base.nim b/src/app/core/signals/remote_signals/base.nim new file mode 100644 index 0000000000..795509eec8 --- /dev/null +++ b/src/app/core/signals/remote_signals/base.nim @@ -0,0 +1,17 @@ +import json +import json_serialization +import signal_type + +import eventemitter + +export signal_type + +type Signal* = ref object of Args + signalType* {.serializedFieldName("type").}: SignalType + signalTypeStr*: string + +type SignalError* = object + error*: string + +type NodeSignal* = ref object of Signal + event*: SignalError diff --git a/src/app/core/signals/remote_signals/chronicles_logs.nim b/src/app/core/signals/remote_signals/chronicles_logs.nim new file mode 100644 index 0000000000..22d718e155 --- /dev/null +++ b/src/app/core/signals/remote_signals/chronicles_logs.nim @@ -0,0 +1,12 @@ +import json +import base +import signal_type + +type ChroniclesLogsSignal* = ref object of Signal + content*: string + +proc fromEvent*(T: type ChroniclesLogsSignal, jsonSignal: JsonNode): ChroniclesLogsSignal = + result = ChroniclesLogsSignal() + result.signalType = SignalType.ChroniclesLogs + if jsonSignal["event"].kind != JNull: + result.content = jsonSignal["event"].getStr() diff --git a/src/app/core/signals/remote_signals/community.nim b/src/app/core/signals/remote_signals/community.nim new file mode 100644 index 0000000000..ac7f4991de --- /dev/null +++ b/src/app/core/signals/remote_signals/community.nim @@ -0,0 +1,14 @@ +import json + +import base + +import status/types/community +import signal_type + +type CommunitySignal* = ref object of Signal + community*: Community + +proc fromEvent*(T: type CommunitySignal, event: JsonNode): CommunitySignal = + result = CommunitySignal() + result.signalType = SignalType.CommunityFound + result.community = event["event"].toCommunity() diff --git a/src/app/core/signals/remote_signals/discovery_summary.nim b/src/app/core/signals/remote_signals/discovery_summary.nim new file mode 100644 index 0000000000..d8ae686df9 --- /dev/null +++ b/src/app/core/signals/remote_signals/discovery_summary.nim @@ -0,0 +1,14 @@ +import json + +import base +import signal_type + +type DiscoverySummarySignal* = ref object of Signal + enodes*: seq[string] + +proc fromEvent*(T: type DiscoverySummarySignal, jsonSignal: JsonNode): DiscoverySummarySignal = + result = DiscoverySummarySignal() + result.signalType = SignalType.DiscoverySummary + if jsonSignal["event"].kind != JNull: + for discoveryItem in jsonSignal["event"]: + result.enodes.add(discoveryItem["enode"].getStr) diff --git a/src/app/core/signals/remote_signals/envelope.nim b/src/app/core/signals/remote_signals/envelope.nim new file mode 100644 index 0000000000..01f6e8f630 --- /dev/null +++ b/src/app/core/signals/remote_signals/envelope.nim @@ -0,0 +1,15 @@ +import json + +import base +import signal_type + +type EnvelopeSentSignal* = ref object of Signal + messageIds*: seq[string] + +proc fromEvent*(T: type EnvelopeSentSignal, jsonSignal: JsonNode): EnvelopeSentSignal = + result = EnvelopeSentSignal() + result.signalType = SignalType.EnvelopeSent + if jsonSignal["event"].kind != JNull and jsonSignal["event"].hasKey("ids") and jsonSignal["event"]["ids"].kind != JNull: + for messageId in jsonSignal["event"]["ids"]: + result.messageIds.add(messageId.getStr) + \ No newline at end of file diff --git a/src/app/core/signals/remote_signals/expired.nim b/src/app/core/signals/remote_signals/expired.nim new file mode 100644 index 0000000000..a5d6f4ec45 --- /dev/null +++ b/src/app/core/signals/remote_signals/expired.nim @@ -0,0 +1,15 @@ +import json + +import base +import signal_type + +type EnvelopeExpiredSignal* = ref object of Signal + messageIds*: seq[string] + +proc fromEvent*(T: type EnvelopeExpiredSignal, jsonSignal: JsonNode): EnvelopeExpiredSignal = + result = EnvelopeExpiredSignal() + result.signalType = SignalType.EnvelopeExpired + if jsonSignal["event"].kind != JNull and jsonSignal["event"].hasKey("ids") and jsonSignal["event"]["ids"].kind != JNull: + for messageId in jsonSignal["event"]["ids"]: + result.messageIds.add(messageId.getStr) + \ No newline at end of file diff --git a/src/app/core/signals/remote_signals/keycard.nim b/src/app/core/signals/remote_signals/keycard.nim new file mode 100644 index 0000000000..512caf6301 --- /dev/null +++ b/src/app/core/signals/remote_signals/keycard.nim @@ -0,0 +1,11 @@ +import json + +import base +import signal_type + +type KeycardConnectedSignal* = ref object of Signal + started*: string + +proc fromEvent*(T: type KeycardConnectedSignal, event: JsonNode): KeycardConnectedSignal = + result = KeycardConnectedSignal() + result.started = event["event"].getStr() diff --git a/src/app/core/signals/remote_signals/mailserver.nim b/src/app/core/signals/remote_signals/mailserver.nim new file mode 100644 index 0000000000..d51bc9e405 --- /dev/null +++ b/src/app/core/signals/remote_signals/mailserver.nim @@ -0,0 +1,51 @@ +import json + +import base +import signal_type + +type MailserverRequestCompletedSignal* = ref object of Signal + requestID*: string + lastEnvelopeHash*: string + cursor*: string + errorMessage*: string + error*: bool + +type MailserverRequestExpiredSignal* = ref object of Signal + # TODO + +type HistoryRequestStartedSignal* = ref object of Signal +type HistoryRequestCompletedSignal* = ref object of Signal +type HistoryRequestFailedSignal* = ref object of Signal + errorMessage*: string + error*: bool + + +proc fromEvent*(T: type MailserverRequestCompletedSignal, jsonSignal: JsonNode): MailserverRequestCompletedSignal = + result = MailserverRequestCompletedSignal() + result.signalType = SignalType.MailserverRequestCompleted + if jsonSignal["event"].kind != JNull: + result.requestID = jsonSignal["event"]{"requestID"}.getStr() + result.lastEnvelopeHash = jsonSignal["event"]{"lastEnvelopeHash"}.getStr() + result.cursor = jsonSignal["event"]{"cursor"}.getStr() + result.errorMessage = jsonSignal["event"]{"errorMessage"}.getStr() + result.error = result.errorMessage != "" + +proc fromEvent*(T: type MailserverRequestExpiredSignal, jsonSignal: JsonNode): MailserverRequestExpiredSignal = + # TODO: parse signal + result = MailserverRequestExpiredSignal() + result.signalType = SignalType.MailserverRequestExpired + +proc fromEvent*(T: type HistoryRequestStartedSignal, jsonSignal: JsonNode): HistoryRequestStartedSignal = + result = HistoryRequestStartedSignal() + result.signalType = SignalType.HistoryRequestStarted + +proc fromEvent*(T: type HistoryRequestCompletedSignal, jsonSignal: JsonNode): HistoryRequestCompletedSignal = + result = HistoryRequestCompletedSignal() + result.signalType = SignalType.HistoryRequestCompleted + +proc fromEvent*(T: type HistoryRequestFailedSignal, jsonSignal: JsonNode): HistoryRequestFailedSignal = + result = HistoryRequestFailedSignal() + result.signalType = SignalType.HistoryRequestStarted + if jsonSignal["event"].kind != JNull: + result.errorMessage = jsonSignal["event"]{"errorMessage"}.getStr() + result.error = result.errorMessage != "" diff --git a/src/app/core/signals/remote_signals/messages.nim b/src/app/core/signals/remote_signals/messages.nim new file mode 100644 index 0000000000..63631215d1 --- /dev/null +++ b/src/app/core/signals/remote_signals/messages.nim @@ -0,0 +1,95 @@ +import json + +import base + +import status/types/[message, chat, community, profile, installation, + activity_center_notification, status_update, removed_message] + +type MessageSignal* = ref object of Signal + messages*: seq[Message] + pinnedMessages*: seq[Message] + chats*: seq[Chat] + contacts*: seq[Profile] + installations*: seq[Installation] + emojiReactions*: seq[Reaction] + communities*: seq[Community] + membershipRequests*: seq[CommunityMembershipRequest] + activityCenterNotification*: seq[ActivityCenterNotification] + statusUpdates*: seq[StatusUpdate] + deletedMessages*: seq[RemovedMessage] + +proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal = + var signal:MessageSignal = MessageSignal() + signal.messages = @[] + signal.contacts = @[] + + if event["event"]{"contacts"} != nil: + for jsonContact in event["event"]["contacts"]: + signal.contacts.add(jsonContact.toProfile()) + + var chatsWithMentions: seq[string] = @[] + + if event["event"]{"messages"} != nil: + for jsonMsg in event["event"]["messages"]: + var message = jsonMsg.toMessage() + if message.hasMention: + chatsWithMentions.add(message.chatId) + signal.messages.add(message) + + if event["event"]{"chats"} != nil: + for jsonChat in event["event"]["chats"]: + var chat = jsonChat.toChat + if chatsWithMentions.contains(chat.id): + chat.mentionsCount.inc + signal.chats.add(chat) + + if event["event"]{"statusUpdates"} != nil: + for jsonStatusUpdate in event["event"]["statusUpdates"]: + var statusUpdate = jsonStatusUpdate.toStatusUpdate + signal.statusUpdates.add(statusUpdate) + + if event["event"]{"installations"} != nil: + for jsonInstallation in event["event"]["installations"]: + signal.installations.add(jsonInstallation.toInstallation) + + if event["event"]{"emojiReactions"} != nil: + for jsonReaction in event["event"]["emojiReactions"]: + signal.emojiReactions.add(jsonReaction.toReaction) + + if event["event"]{"communities"} != nil: + for jsonCommunity in event["event"]["communities"]: + signal.communities.add(jsonCommunity.toCommunity) + + if event["event"]{"requestsToJoinCommunity"} != nil: + for jsonCommunity in event["event"]["requestsToJoinCommunity"]: + signal.membershipRequests.add(jsonCommunity.toCommunityMembershipRequest) + + if event["event"]{"removedMessages"} != nil: + for jsonRemovedMessage in event["event"]["removedMessages"]: + signal.deletedMessages.add(jsonRemovedMessage.toRemovedMessage) + + if event["event"]{"activityCenterNotifications"} != nil: + for jsonNotification in event["event"]["activityCenterNotifications"]: + signal.activityCenterNotification.add(jsonNotification.toActivityCenterNotification()) + + if event["event"]{"pinMessages"} != nil: + for jsonPinnedMessage in event["event"]["pinMessages"]: + var contentType: ContentType + try: + contentType = ContentType(jsonPinnedMessage{"contentType"}.getInt) + except: + contentType = ContentType.Message + signal.pinnedMessages.add(Message( + id: jsonPinnedMessage{"message_id"}.getStr, + chatId: jsonPinnedMessage{"chat_id"}.getStr, + localChatId: jsonPinnedMessage{"localChatId"}.getStr, + pinnedBy: jsonPinnedMessage{"from"}.getStr, + identicon: jsonPinnedMessage{"identicon"}.getStr, + alias: jsonPinnedMessage{"alias"}.getStr, + clock: jsonPinnedMessage{"clock"}.getInt, + isPinned: jsonPinnedMessage{"pinned"}.getBool, + contentType: contentType + )) + + result = signal + diff --git a/src/app/core/signals/remote_signals/peerstats.nim b/src/app/core/signals/remote_signals/peerstats.nim new file mode 100644 index 0000000000..fc5974351a --- /dev/null +++ b/src/app/core/signals/remote_signals/peerstats.nim @@ -0,0 +1,14 @@ +import json +import base +import signal_type + +type PeerStatsSignal* = ref object of Signal + peers*: seq[string] + +proc fromEvent*(T: type PeerStatsSignal, jsonSignal: JsonNode): PeerStatsSignal = + result = PeerStatsSignal() + result.signalType = SignalType.PeerStats + if jsonSignal["event"].kind != JNull: + for (node, protocols) in jsonSignal["event"]["peers"].pairs(): + if protocols.getElems.len != 0: + result.peers.add(node) diff --git a/src/app/core/signals/remote_signals/signal_type.nim b/src/app/core/signals/remote_signals/signal_type.nim new file mode 100644 index 0000000000..c20bea5af7 --- /dev/null +++ b/src/app/core/signals/remote_signals/signal_type.nim @@ -0,0 +1,32 @@ +{.used.} + +type SignalType* {.pure.} = enum + Message = "messages.new" + Wallet = "wallet" + NodeReady = "node.ready" + NodeCrashed = "node.crashed" + NodeStarted = "node.started" + NodeStopped = "node.stopped" + NodeLogin = "node.login" + EnvelopeSent = "envelope.sent" + EnvelopeExpired = "envelope.expired" + MailserverRequestCompleted = "mailserver.request.completed" + MailserverRequestExpired = "mailserver.request.expired" + DiscoveryStarted = "discovery.started" + DiscoveryStopped = "discovery.stopped" + DiscoverySummary = "discovery.summary" + SubscriptionsData = "subscriptions.data" + SubscriptionsError = "subscriptions.error" + WhisperFilterAdded = "whisper.filter.added" + CommunityFound = "community.found" + PeerStats = "wakuv2.peerstats" + Stats = "stats" + ChroniclesLogs = "chronicles-log" + HistoryRequestStarted = "history.request.started" + HistoryRequestCompleted = "history.request.completed" + HistoryRequestFailed = "history.request.failed" + KeycardConnected = "keycard.connected" + Unknown + +proc event*(self:SignalType):string = + result = "signal:" & $self diff --git a/src/app/core/signals/remote_signals/stats.nim b/src/app/core/signals/remote_signals/stats.nim new file mode 100644 index 0000000000..f28a983ad3 --- /dev/null +++ b/src/app/core/signals/remote_signals/stats.nim @@ -0,0 +1,22 @@ +import json + +import base +import signal_type + +type Stats* = object + uploadRate*: uint64 + downloadRate*: uint64 + +type StatsSignal* = ref object of Signal + stats*: Stats + +proc toStats(jsonMsg: JsonNode): Stats = + result = Stats( + uploadRate: uint64(jsonMsg{"uploadRate"}.getBiggestInt()), + downloadRate: uint64(jsonMsg{"downloadRate"}.getBiggestInt()) + ) + +proc fromEvent*(T: type StatsSignal, event: JsonNode): StatsSignal = + result = StatsSignal() + result.signalType = SignalType.Stats + result.stats = event["event"].toStats diff --git a/src/app/core/signals/remote_signals/wallet.nim b/src/app/core/signals/remote_signals/wallet.nim new file mode 100644 index 0000000000..3a8c25f003 --- /dev/null +++ b/src/app/core/signals/remote_signals/wallet.nim @@ -0,0 +1,28 @@ +import json + +import base +import signal_type + +type WalletSignal* = ref object of Signal + content*: string + eventType*: string + blockNumber*: int + accounts*: seq[string] + baseFeePerGas*: string + # newTransactions*: ??? + erc20*: bool + +proc fromEvent*(T: type WalletSignal, jsonSignal: JsonNode): WalletSignal = + result = WalletSignal() + result.signalType = SignalType.Wallet + result.content = $jsonSignal + if jsonSignal["event"].kind != JNull: + result.eventType = jsonSignal["event"]["type"].getStr + result.blockNumber = jsonSignal["event"]{"blockNumber"}.getInt + result.baseFeePerGas = jsonSignal["event"]{"baseFeePerGas"}.getStr + result.erc20 = jsonSignal["event"]{"erc20"}.getBool + result.accounts = @[] + if jsonSignal["event"]["accounts"].kind != JNull: + for account in jsonSignal["event"]["accounts"]: + result.accounts.add(account.getStr) + \ No newline at end of file diff --git a/src/app/core/signals/remote_signals/whisper_filter.nim b/src/app/core/signals/remote_signals/whisper_filter.nim new file mode 100644 index 0000000000..2581663b89 --- /dev/null +++ b/src/app/core/signals/remote_signals/whisper_filter.nim @@ -0,0 +1,29 @@ +import json + +import base + +type Filter* = object + chatId*: string + symKeyId*: string + listen*: bool + filterId*: string + identity*: string + topic*: string + +type WhisperFilterSignal* = ref object of Signal + filters*: seq[Filter] + +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*(T: type WhisperFilterSignal, event: JsonNode): WhisperFilterSignal = + if event["event"]{"filters"} != nil: + for jsonMsg in event["event"]["filters"]: + result.filters.add(jsonMsg.toFilter) diff --git a/src/app/core/signals/signal_controller.nim b/src/app/core/signals/signal_controller.nim deleted file mode 100644 index 425120bf0c..0000000000 --- a/src/app/core/signals/signal_controller.nim +++ /dev/null @@ -1,57 +0,0 @@ -import NimQml, json, chronicles, json_serialization -import status/signals -import status/status -import eventemitter - -logScope: - topics = "signals" - -QtObject: - type SignalsController* = ref object of QObject - variant*: QVariant - status*: Status - - proc newSignalsController*(status: Status): SignalsController = - new(result) - result.status = status - result.setup() - result.variant = newQVariant(result) - - proc setup(self: SignalsController) = - self.QObject.setup - - proc delete*(self: SignalsController) = - self.variant.delete - self.QObject.delete - - proc processSignal(self: SignalsController, statusSignal: string) = - var jsonSignal: JsonNode - try: - jsonSignal = statusSignal.parseJson - except: - error "Invalid signal received", data = statusSignal - return - - trace "Raw signal data", data = $jsonSignal - - var signal:Signal - try: - signal = decode(jsonSignal) - except: - warn "Error decoding signal", err=getCurrentExceptionMsg() - return - - if(signal.signalType == SignalType.NodeLogin): - if(NodeSignal(signal).event.error != ""): - error "node.login", error=NodeSignal(signal).event.error - - if(signal.signalType == SignalType.NodeCrashed): - error "node.crashed", error=statusSignal - - self.status.events.emit(signal.signalType.event, signal) - - proc signalReceived*(self: SignalsController, signal: string) {.signal.} - - proc receiveSignal(self: SignalsController, signal: string) {.slot.} = - self.processSignal(signal) - self.signalReceived(signal) diff --git a/src/app/core/signals/signals_manager.nim b/src/app/core/signals/signals_manager.nim new file mode 100644 index 0000000000..5ad6e067dc --- /dev/null +++ b/src/app/core/signals/signals_manager.nim @@ -0,0 +1,86 @@ +import NimQml, json, strutils, chronicles, json_serialization +import eventemitter + +include types + +logScope: + topics = "signals-manager" + +QtObject: + type SignalsManager* = ref object of QObject + events: EventEmitter + + ################################################# + # Forward declaration section + proc decode(self: SignalsManager, jsonSignal: JsonNode): Signal + ################################################# + + proc setup(self: SignalsManager) = + self.QObject.setup + + proc delete*(self: SignalsManager) = + self.QObject.delete + + proc newSignalsManager*(events: EventEmitter): SignalsManager = + new(result) + result.setup() + result.events = events + + proc processSignal(self: SignalsManager, statusSignal: string) = + var jsonSignal: JsonNode + try: + jsonSignal = statusSignal.parseJson + except: + error "Invalid signal received", data = statusSignal + return + + trace "Raw signal data", data = $jsonSignal + + var signal:Signal + try: + signal = self.decode(jsonSignal) + except: + warn "Error decoding signal", err=getCurrentExceptionMsg() + return + + if(signal.signalType == SignalType.NodeLogin): + if(NodeSignal(signal).event.error != ""): + error "node.login", error=NodeSignal(signal).event.error + + if(signal.signalType == SignalType.NodeCrashed): + error "node.crashed", error=statusSignal + + self.events.emit(signal.signalType.event, signal) + + proc receiveSignal(self: SignalsManager, signal: string) {.slot.} = + self.processSignal(signal) + + proc decode(self: SignalsManager, jsonSignal: JsonNode): Signal = + let signalString = jsonSignal{"type"}.getStr + var signalType: SignalType + try: + signalType = parseEnum[SignalType](signalString) + except: + raise newException(ValueError, "Unknown signal received: " & signalString) + + result = case signalType: + of SignalType.Message: MessageSignal.fromEvent(jsonSignal) + of SignalType.EnvelopeSent: EnvelopeSentSignal.fromEvent(jsonSignal) + of SignalType.EnvelopeExpired: EnvelopeExpiredSignal.fromEvent(jsonSignal) + of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal) + of SignalType.Wallet: WalletSignal.fromEvent(jsonSignal) + of SignalType.NodeLogin: Json.decode($jsonSignal, NodeSignal) + of SignalType.PeerStats: PeerStatsSignal.fromEvent(jsonSignal) + of SignalType.DiscoverySummary: DiscoverySummarySignal.fromEvent(jsonSignal) + of SignalType.MailserverRequestCompleted: MailserverRequestCompletedSignal.fromEvent(jsonSignal) + of SignalType.MailserverRequestExpired: MailserverRequestExpiredSignal.fromEvent(jsonSignal) + of SignalType.CommunityFound: CommunitySignal.fromEvent(jsonSignal) + of SignalType.Stats: StatsSignal.fromEvent(jsonSignal) + of SignalType.ChroniclesLogs: ChroniclesLogsSignal.fromEvent(jsonSignal) + of SignalType.HistoryRequestCompleted: HistoryRequestCompletedSignal.fromEvent(jsonSignal) + of SignalType.HistoryRequestStarted: HistoryRequestStartedSignal.fromEvent(jsonSignal) + of SignalType.HistoryRequestFailed: HistoryRequestFailedSignal.fromEvent(jsonSignal) + of SignalType.KeycardConnected: KeycardConnectedSignal.fromEvent(jsonSignal) + else: Signal() + + result.signalType = signalType \ No newline at end of file diff --git a/src/app/core/signals/types.nim b/src/app/core/signals/types.nim new file mode 100644 index 0000000000..df924c7694 --- /dev/null +++ b/src/app/core/signals/types.nim @@ -0,0 +1,7 @@ +{.used.} + +import ./remote_signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, +peerstats, signal_type, stats, wallet, whisper_filter, keycard] + +export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats, + signal_type, stats, wallet, whisper_filter, keycard \ No newline at end of file diff --git a/src/app/core/tasks/marathon/mailserver/controller.nim b/src/app/core/tasks/marathon/mailserver/controller.nim index 4c47913018..da2f1b2406 100644 --- a/src/app/core/tasks/marathon/mailserver/controller.nim +++ b/src/app/core/tasks/marathon/mailserver/controller.nim @@ -14,18 +14,15 @@ logScope: ################################################################################ QtObject: type MailserverController* = ref object of QObject - variant*: QVariant status*: Status - proc newController*(status: Status): MailserverController = + proc newMailserverController*(status: Status): MailserverController = new(result) result.status = status result.setup() - result.variant = newQVariant(result) proc setup(self: MailserverController) = self.QObject.setup proc delete*(self: MailserverController) = - self.variant.delete self.QObject.delete diff --git a/src/app/keycard/core.nim b/src/app/keycard/core.nim index 96e6cc42af..0a11ce0da9 100644 --- a/src/app/keycard/core.nim +++ b/src/app/keycard/core.nim @@ -1,7 +1,8 @@ import NimQml, chronicles, std/wrapnils -import status/[signals, status, keycard] +import status/[status, keycard] import types/keycard as keycardtypes import view, pairing +import ../core/signals/types logScope: topics = "keycard-model" diff --git a/src/app/modules/main/app_search/controller.nim b/src/app/modules/main/app_search/controller.nim index d566ff2755..6840722ff1 100644 --- a/src/app/modules/main/app_search/controller.nim +++ b/src/app/modules/main/app_search/controller.nim @@ -7,8 +7,8 @@ import ../../../../app_service/service/chat/service as chat_service import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/message/service as message_service +import ../../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/main/chat_section/chat_content/controller.nim b/src/app/modules/main/chat_section/chat_content/controller.nim index 98c1562846..ef36e9a600 100644 --- a/src/app/modules/main/chat_section/chat_content/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/controller.nim @@ -7,8 +7,8 @@ import ../../../../../app_service/service/chat/service as chat_service import ../../../../../app_service/service/community/service as community_service import ../../../../../app_service/service/message/service as message_service +import ../../../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/main/chat_section/chat_content/messages/controller.nim b/src/app/modules/main/chat_section/chat_content/messages/controller.nim index c02a9f30ef..7d81497035 100644 --- a/src/app/modules/main/chat_section/chat_content/messages/controller.nim +++ b/src/app/modules/main/chat_section/chat_content/messages/controller.nim @@ -5,8 +5,8 @@ import io_interface import ../../../../../../app_service/service/community/service as community_service import ../../../../../../app_service/service/message/service as message_service +import ../../../../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim index 8fa222d59d..f988f9d6c1 100644 --- a/src/app/modules/main/controller.nim +++ b/src/app/modules/main/controller.nim @@ -7,8 +7,8 @@ import ../../../app_service/service/accounts/service_interface as accounts_servi import ../../../app_service/service/chat/service as chat_service import ../../../app_service/service/community/service as community_service +import ../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/main/wallet_section/transactions/controller.nim b/src/app/modules/main/wallet_section/transactions/controller.nim index c8edbcaaf7..05851c60a3 100644 --- a/src/app/modules/main/wallet_section/transactions/controller.nim +++ b/src/app/modules/main/wallet_section/transactions/controller.nim @@ -6,7 +6,6 @@ import ../../../../../app_service/service/wallet_account/service as wallet_accou import status/[status, wallet] -import status/signals export controller_interface diff --git a/src/app/modules/startup/controller.nim b/src/app/modules/startup/controller.nim index 9ab948fde1..5bc5ea0b12 100644 --- a/src/app/modules/startup/controller.nim +++ b/src/app/modules/startup/controller.nim @@ -6,8 +6,8 @@ import io_interface import ../../../app_service/service/keychain/service as keychain_service import ../../../app_service/service/accounts/service_interface as accounts_service +import ../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/startup/login/controller.nim b/src/app/modules/startup/login/controller.nim index a831061742..de18aee8c8 100644 --- a/src/app/modules/startup/login/controller.nim +++ b/src/app/modules/startup/login/controller.nim @@ -7,8 +7,8 @@ import ../../../global/global_singleton import ../../../../app_service/service/keychain/service as keychain_service import ../../../../app_service/service/accounts/service_interface as accounts_service +import ../../../core/signals/types import eventemitter -import status/[signals] export controller_interface diff --git a/src/app/modules/startup/onboarding/controller.nim b/src/app/modules/startup/onboarding/controller.nim index 145c54db97..9fc1f420bd 100644 --- a/src/app/modules/startup/onboarding/controller.nim +++ b/src/app/modules/startup/onboarding/controller.nim @@ -5,8 +5,8 @@ import io_interface import ../../../../app_service/service/accounts/service_interface as accounts_service +import ../../../core/signals/types import eventemitter -import status/[signals, fleet] export controller_interface diff --git a/src/app/node/core.nim b/src/app/node/core.nim index 7f910bbf56..da5e4bf9c7 100644 --- a/src/app/node/core.nim +++ b/src/app/node/core.nim @@ -1,5 +1,5 @@ import NimQml, chronicles -import status/[signals, status, node, network, settings] +import status/[status, node, network, settings] import ../core/[main] import eventemitter import view diff --git a/src/app/node/view.nim b/src/app/node/view.nim index 5c4ce29fb7..de4bb8023a 100644 --- a/src/app/node/view.nim +++ b/src/app/node/view.nim @@ -2,7 +2,6 @@ import NimQml, chronicles, strutils, json import status/[node, settings, accounts] import status/types/[setting] import ../core/[main] -import status/signals/[stats] import ../core/tasks/[qt, threadpool] logScope: diff --git a/src/app/profile/core.nim b/src/app/profile/core.nim index a4dcd87b27..b957eee246 100644 --- a/src/app/profile/core.nim +++ b/src/app/profile/core.nim @@ -1,6 +1,6 @@ import NimQml, json, strutils, sugar, sequtils, tables import json_serialization -import status/[status, signals, settings] +import status/[status, settings] import status/contacts as status_contacts import status/chat as status_chat import status/devices as status_devices diff --git a/src/app/wallet/v1/core.nim b/src/app/wallet/v1/core.nim index 3b848fbec0..3a5c4fe9b9 100644 --- a/src/app/wallet/v1/core.nim +++ b/src/app/wallet/v1/core.nim @@ -6,7 +6,6 @@ import views/[asset_list, account_list, account_item] import status/[status, wallet, settings] import status/wallet/account as WalletTypes import status/types/[transaction, setting] -import status/signals import ../../core/[main] import eventemitter diff --git a/src/app/wallet/v2/core.nim b/src/app/wallet/v2/core.nim index 3d9fe1b61b..13f82b580c 100644 --- a/src/app/wallet/v2/core.nim +++ b/src/app/wallet/v2/core.nim @@ -7,7 +7,6 @@ import status/[status, wallet2, settings] import status/wallet2/account as WalletTypes import status/types/[transaction, setting] import ../../core/[main] -import status/signals import eventemitter logScope: diff --git a/src/app_service/service/accounts/service.nim b/src/app_service/service/accounts/service.nim index 8fd8d1db75..0a9e815681 100644 --- a/src/app_service/service/accounts/service.nim +++ b/src/app_service/service/accounts/service.nim @@ -301,8 +301,8 @@ method login*(self: Service, account: AccountDto, password: string): string = elif(img.imgType == "large"): largeImage = img.uri - let response = status_go.login(account.name, account.keyUid, hashedPassword, - account.identicon, thumbnailImage, largeImage) + let response = status_go.login(account.name, account.keyUid, hashedPassword, account.identicon, thumbnailImage, + largeImage) var error = "response doesn't contain \"error\"" if(response.result.contains("error")): diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index a8fbede9c6..21df335801 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -10,8 +10,6 @@ import status/types/[account] import status_go import status/status as statuslib import eventemitter -import app/core/tasks/marathon/mailserver/controller as mailserver_controller -import app/core/tasks/marathon/mailserver/worker as mailserver_worker import app/core/main import constants @@ -19,7 +17,7 @@ import app/global/global_singleton import app/boot/app_controller -var signalsQObjPointer: pointer +var signalsManagerQObjPointer: pointer logScope: topics = "main" @@ -39,10 +37,8 @@ proc mainProc() = let fleetConfig = readFile(joinPath(getAppDir(), fleets)) status = statuslib.newStatusInstance(fleetConfig) - mailserverController = mailserver_controller.newController(status) - mailserverWorker = mailserver_worker.newMailserverWorker(cast[ByteAddress](mailserverController.vptr)) - let appService = newAppService(status, mailserverWorker) + let appService = newAppService(status) defer: appService.delete() status.initNode(STATUSGODIR, KEYSTOREDIR) @@ -121,16 +117,16 @@ proc mainProc() = # We need this global variable in order to be able to access the application # from the non-closure callback passed to `statusgo_backend.setSignalEventCallback` - signalsQObjPointer = cast[pointer](appService.signalController.vptr) + signalsManagerQObjPointer = cast[pointer](appService.signalsManager.vptr) defer: - signalsQObjPointer = nil + signalsManagerQObjPointer = nil when compiles(defaultChroniclesStream.output.writer): defaultChroniclesStream.output.writer = proc (logLevel: LogLevel, msg: LogOutputStr) {.gcsafe, raises: [Defect].} = try: - if signalsQObjPointer != nil: - signal_handler(signalsQObjPointer, ($(%* {"type": "chronicles-log", "event": msg})).cstring, "receiveSignal") + if signalsManagerQObjPointer != nil: + signal_handler(signalsManagerQObjPointer, ($(%* {"type": "chronicles-log", "event": msg})).cstring, "receiveSignal") except: logLoggingFailure(cstring(msg), getCurrentException()) @@ -208,8 +204,13 @@ proc mainProc() = # 2. Re-init controllers that don't require a running node initControllers() - singletonInstance.engine.setRootContextProperty("signals", appService.signalController.variant) - singletonInstance.engine.setRootContextProperty("mailserver", mailserverController.variant) + var signalsManagerQVariant = newQVariant(appService.signalsManager) + defer: signalsManagerQVariant.delete() + var mailserverControllerQVariant = newQVariant(appService.mailserverController) + defer: mailserverControllerQVariant.delete() + + singletonInstance.engine.setRootContextProperty("signals", signalsManagerQVariant) + singletonInstance.engine.setRootContextProperty("mailserver", mailserverControllerQVariant) var prValue = newQVariant(if defined(production): true else: false) singletonInstance.engine.setRootContextProperty("production", prValue) @@ -225,8 +226,8 @@ proc mainProc() = # it will be passed as a regular C function to statusgo_backend. This means that # we cannot capture any local variables here (we must rely on globals) var callback: SignalCallback = proc(p0: cstring) {.cdecl.} = - if signalsQObjPointer != nil: - signal_handler(signalsQObjPointer, p0, "receiveSignal") + if signalsManagerQObjPointer != nil: + signal_handler(signalsManagerQObjPointer, p0, "receiveSignal") status_go.setSignalEventCallback(callback)