refactor(@desktop/general): move Qt logic out of src/status library

Since `src/status` was Qt dependant part because of the following foundation files:
- /src/status/tasks/marathon/mailserver/controller.nim
- /src/status/signals/core.nim
- /src/status/tasks/marathon/mailserver/events.nim
- /src/status/tasks/qt.nim

and because logic related classes like:
- /src/status/chat.nim

this commit made that part Qt independant.

New layer `src/app_service` is introduced and above mentioned foundation files
are moved there. As well as corresponding logic for requested services.

Communication between logical parts on the high level is as follows:
- `src/app` => `src/app_service` => `src/status` => `src/app`
- `src/app` => `src/status` => `src/app`

Fixes: #3376
This commit is contained in:
Sale Djenic 2021-09-07 21:14:56 +02:00 committed by Iuri Matias
parent 3536b57e08
commit 7c812c0961
170 changed files with 2786 additions and 2477 deletions

View File

@ -1,6 +1,6 @@
import NimQml, json, chronicles
import ../../status/[status, browser]
import ../../status/types
import ../../status/types/[bookmark]
import views/bookmark_list
QtObject:

View File

@ -1,6 +1,6 @@
import NimQml, Tables, chronicles
import sequtils as sequtils
import ../../../status/types
import ../../../status/types/[bookmark]
type
BookmarkRoles {.pure.} = enum

View File

@ -1,9 +1,10 @@
import NimQml, chronicles, tables
import ../../status/chat as chat_model
import ../../status/messages as messages_model
import ../../status/signals/types
import ../../status/types as status_types
import ../../status/[chat, contacts, status, wallet, stickers, settings]
import ../../status/types/[message, transaction, os_notification, setting]
import ../../app_service/[main]
import ../../app_service/signals/[base]
import view, views/channels_list, views/message_list, views/reactions, views/stickers as stickers_view
import ../../eventemitter
@ -14,17 +15,21 @@ type ChatController* = ref object
view*: ChatsView
status*: Status
variant*: QVariant
appService: AppService
proc newController*(status: Status): ChatController =
proc newController*(status: Status, appService: AppService): ChatController =
result = ChatController()
result.status = status
result.view = newChatsView(status)
result.appService = appService
result.view = newChatsView(status, appService)
result.variant = newQVariant(result.view)
proc delete*(self: ChatController) =
delete self.variant
delete self.view
proc loadInitialMessagesForChannel*(self: ChatController, channelId: string)
include event_handling
include signal_handling
@ -61,3 +66,19 @@ proc init*(self: ChatController) =
self.status.events.on("network:connected") do(e: Args):
self.view.stickers.clearStickerPacks()
self.view.stickers.obtainAvailableStickerPacks()
proc loadInitialMessagesForChannel*(self: ChatController, channelId: string) =
if (channelId.len == 0):
info "empty channel id set for loading initial messages"
return
if(self.status.chat.isMessageCursorSet(channelId)):
return
if(self.status.chat.isEmojiCursorSet(channelId)):
return
if(self.status.chat.isPinnedMessageCursorSet(channelId)):
return
self.appService.chatService.loadMoreMessagesForChannel(channelId)

View File

@ -3,11 +3,10 @@ import # std libs
import # status-desktop libs
../../status/chat/chat as status_chat,
../../status/notifications/os_notifications,
../../status/tasks/marathon,
../../status/tasks/marathon/mailserver/worker,
./views/communities,
./views/messages
import ../../app_service/tasks/[qt, threadpool]
import ../../app_service/tasks/marathon/mailserver/worker
proc handleChatEvents(self: ChatController) =
# Display already saved messages
@ -116,7 +115,7 @@ proc handleChatEvents(self: ChatController) =
if channel.chat.chatType == status_chat.ChatType.CommunityChat:
self.view.communities.updateCommunityChat(channel.chat)
self.status.chat.loadInitialMessagesForChannel(channel.chat.id)
self.loadInitialMessagesForChannel(channel.chat.id)
self.status.events.on("chatsLoaded") do(e:Args):
self.view.calculateUnreadMessages()
@ -141,7 +140,7 @@ proc handleChatEvents(self: ChatController) =
discard self.view.channelView.chats.addChatItemToList(channel.chat)
self.view.setActiveChannel(channel.chat.id)
self.status.chat.loadInitialMessagesForChannel(channel.chat.id)
self.loadInitialMessagesForChannel(channel.chat.id)
self.status.chat.statusUpdates()
self.status.events.on("channelLeft") do(e: Args):
@ -190,7 +189,7 @@ proc handleChatEvents(self: ChatController) =
self.view.communities.markNotificationsAsRead(markAsReadProps)
proc handleMailserverEvents(self: ChatController) =
let mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
let mailserverWorker = self.appService.marathon[MailserverWorker().name]
# TODO: test mailserver topics when joining chat
self.status.events.on("channelJoined") do(e:Args):

View File

@ -1,5 +1,7 @@
import
../../status/tasks/marathon/mailserver/worker
../../app_service/tasks/marathon/mailserver/worker,
../../app_service/signals/messages as signals_messages,
../../app_service/signals/[community, discovery_summary, envelope, expired]
proc handleSignals(self: ChatController) =
self.status.events.on(SignalType.Message.event) do(e:Args):
@ -10,7 +12,7 @@ proc handleSignals(self: ChatController) =
## Handle mailserver peers being added and removed
var data = DiscoverySummarySignal(e)
let
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
mailserverWorker = self.appService.marathon[MailserverWorker().name]
task = PeerSummaryChangeTaskArg(
`method`: "peerSummaryChange",
peers: data.enodes

View File

@ -7,13 +7,14 @@ import ../../status/messages as status_messages
import ../../status/mailservers
import ../../status/contacts as status_contacts
import ../../status/ens as status_ens
import ../../status/chat/[chat, message]
import ../../status/chat/[chat]
import ../../status/profile/profile
import ../../status/tasks/[qt, task_runner_impl]
import ../../status/tasks/marathon/mailserver/worker
import ../../status/signals/types as signal_types
import ../../status/types
import ../../status/notifications/[os_notifications, os_notification_details]
import ../../status/types/[activity_center_notification, os_notification, rpc_response]
import ../../app_service/[main]
import ../../app_service/tasks/[qt, threadpool]
import ../../app_service/tasks/marathon/mailserver/worker
import ../../app_service/signals/[base]
import ../../status/notifications/[os_notifications]
import ../utils/image_utils
import web3/[conversions, ethtypes]
import views/message_search/[view_controller]
@ -48,7 +49,7 @@ proc getLinkPreviewData[T](self: T, slot: string, link: string, uuid: string) =
link: link,
uuid: uuid
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
const asyncActivityNotificationLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncActivityNotificationLoadTaskArg](argEncoded)
@ -69,12 +70,13 @@ proc asyncActivityNotificationLoad[T](self: T, slot: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type
ChatsView* = ref object of QAbstractListModel
status: Status
appService: AppService
formatInputView: FormatInputView
ensView: EnsView
channelView*: ChannelView
@ -108,16 +110,17 @@ QtObject:
self.messageSearchViewController.delete
self.QAbstractListModel.delete
proc newChatsView*(status: Status): ChatsView =
proc newChatsView*(status: Status, appService: AppService): ChatsView =
new(result, delete)
result.status = status
result.appService = appService
result.formatInputView = newFormatInputView()
result.ensView = newEnsView(status)
result.ensView = newEnsView(status, appService)
result.communities = newCommunitiesView(status)
result.channelView = newChannelView(status, result.communities)
result.messageView = newMessageView(status, result.channelView, result.communities)
result.channelView = newChannelView(status, appService, result.communities)
result.messageView = newMessageView(status, appService, result.channelView, result.communities)
result.messageSearchViewController = newMessageSearchViewController(status,
result.channelView, result.communities)
appService, result.channelView, result.communities)
result.connected = false
result.activityNotificationList = newActivityNotificationList(status)
result.reactions = newReactionView(
@ -126,7 +129,7 @@ QtObject:
result.messageView.pinnedMessagesList.addr,
result.channelView.activeChannel
)
result.stickers = newStickersView(status, result.channelView.activeChannel)
result.stickers = newStickersView(status, appService, result.channelView.activeChannel)
result.gif = newGifView()
result.groups = newGroupsView(status,result.channelView.activeChannel)
result.transactions = newTransactionsView(status)
@ -393,7 +396,7 @@ QtObject:
if isActiveMailserverAvailable:
self.messageView.setLoadingMessages(true)
let
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
mailserverWorker = self.appService.marathon[MailserverWorker().name]
task = RequestMessagesTaskArg(`method`: "requestMessages")
mailserverWorker.start(task)
@ -443,7 +446,7 @@ QtObject:
proc requestMoreMessages*(self: ChatsView, fetchRange: int) {.slot.} =
self.messageView.loadingMessages = true
self.messageView.loadingMessagesChanged(true)
let mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
let mailserverWorker = self.appService.marathon[MailserverWorker().name]
let task = RequestMessagesTaskArg( `method`: "requestMoreMessages", chatId: self.channelView.activeChannel.id)
mailserverWorker.start(task)
@ -559,5 +562,5 @@ QtObject:
messageId: messageId
)
self.status.osnotifications.showNotification(title, message, details,
useOSNotifications)
self.appService.osNotificationService.showNotification(title, message,
details, useOSNotifications)

View File

@ -1,7 +1,7 @@
import NimQml, Tables, chronicles, json, sequtils, strformat
import ../../../status/chat/chat
import ../../../status/status
import ../../../status/accounts
import ../../../status/types/[activity_center_notification]
import strutils
import message_item

View File

@ -4,7 +4,7 @@ import ../../../status/[status, contacts]
import ../../../status/ens as status_ens
import ../../../status/chat as status_chat
import ../../../status/chat/[chat]
import ../../../status/tasks/[task_runner_impl]
import ../../../app_service/[main]
import communities, chat_item, channels_list, communities, community_list
@ -14,6 +14,7 @@ logScope:
QtObject:
type ChannelView* = ref object of QObject
status: Status
appService: AppService
communities*: CommunitiesView
chats*: ChannelsList
activeChannel*: ChatItemView
@ -27,9 +28,10 @@ QtObject:
self.contextChannel.delete
self.QObject.delete
proc newChannelView*(status: Status, communities: CommunitiesView): ChannelView =
proc newChannelView*(status: Status, appService: AppService, communities: CommunitiesView): ChannelView =
new(result, delete)
result.status = status
result.appService = appService
result.chats = newChannelsList(status)
result.activeChannel = newChatItemView(status)
result.contextChannel = newChatItemView(status)
@ -92,13 +94,13 @@ QtObject:
if (self.chats.chats.len == 0): return
let selectedChannel = self.getChannel(channelIndex)
if (selectedChannel == nil): return
self.status.chat.asyncMarkAllChannelMessagesRead(selectedChannel.id)
self.appService.chatService.asyncMarkAllChannelMessagesRead(selectedChannel.id)
proc markChatItemAsRead*(self: ChannelView, id: string) {.slot.} =
if (self.chats.chats.len == 0): return
let selectedChannel = self.getChannelById(id)
if (selectedChannel == nil): return
self.status.chat.asyncMarkAllChannelMessagesRead(selectedChannel.id)
self.appService.chatService.asyncMarkAllChannelMessagesRead(selectedChannel.id)
proc clearUnreadIfNeeded*(self: ChannelView, channel: var Chat) =
if (not channel.isNil and (channel.unviewedMessagesCount > 0 or channel.mentionsCount > 0)):
@ -165,7 +167,7 @@ QtObject:
if not self.communities.activeCommunity.active:
self.previousActiveChannelIndex = self.chats.chats.findIndexById(self.activeChannel.id)
self.status.chat.asyncMarkAllChannelMessagesRead(self.activeChannel.id)
self.appService.chatService.asyncMarkAllChannelMessagesRead(self.activeChannel.id)
self.activeChannelChanged()

View File

@ -1,8 +1,9 @@
import NimQml, Tables
import algorithm
import ../../../status/chat/[chat, message]
import ../../../status/chat/[chat]
import ../../../status/status
import ../../../status/accounts
import ../../../status/types/[message]
import strutils
type

View File

@ -1,7 +1,7 @@
import NimQml, Tables, std/wrapnils
import ../../../status/[chat/chat, status, ens, accounts, settings]
from ../../../status/types import Setting
import ../../../status/utils as status_utils
import ../../../status/types/[setting]
import chat_members

View File

@ -5,8 +5,8 @@ import ./community_list
import ./community_item
import ./community_membership_request_list
import ../../utils/image_utils
import ../../../status/signals/types as signal_types
import ../../../status/types
import ../../../status/types/[activity_center_notification, status_update, rpc_response]
import ../../../app_service/signals/[base]
logScope:
topics = "communities-view"

View File

@ -6,6 +6,7 @@ import # vendor libs
import # status-desktop libs
../../../status/chat/chat, ../../../status/status, ../../../status/accounts
import ../../../status/types/[status_update]
type
CommunityRoles {.pure.} = enum

View File

@ -1,6 +1,6 @@
import NimQml, Tables
import ../../../status/types as status_types
import ../../../status/[chat/chat, ens, status, settings]
import ../../../status/types/[setting, status_update]
type
CommunityMembersRoles {.pure.} = enum

View File

@ -2,7 +2,9 @@ import NimQml, Tables, json, sequtils, chronicles, times, re, sugar, strutils, o
import ../../../status/[status, contacts]
import ../../../status/ens as status_ens
import ../../../status/tasks/[qt, task_runner_impl]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import ../../../app_service/tasks/marathon/mailserver/worker
logScope:
topics = "ens-view"
@ -23,18 +25,20 @@ proc resolveEns[T](self: T, slot: string, ens: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot, ens: ens
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type EnsView* = ref object of QObject
status: Status
appService: AppService
proc setup(self: EnsView) = self.QObject.setup
proc delete*(self: EnsView) = self.QObject.delete
proc newEnsView*(status: Status): EnsView =
proc newEnsView*(status: Status, appService: AppService): EnsView =
new(result, delete)
result.status = status
result.appService = appService
result.setup
proc isEnsVerified*(self: EnsView, id: string): bool {.slot.} =

View File

@ -2,9 +2,9 @@ import NimQml, Tables, json, re
import ../../../status/status
import ../../../status/accounts
import ../../../status/chat
import ../../../status/chat/[message]
import ../../../status/profile/profile
import ../../../status/ens
import ../../../status/types/[message]
import strformat, strutils, sequtils
let NEW_LINE = re"\n|\r"

View File

@ -1,7 +1,7 @@
import NimQml, std/wrapnils, chronicles
import ../../../status/status
import ../../../status/chat/message
import ../../../status/chat/stickers
import ../../../status/types/[message]
import message_format
QtObject:

View File

@ -2,9 +2,10 @@ import NimQml, Tables, sets, json, sugar, chronicles, sequtils
import ../../../status/status
import ../../../status/accounts
import ../../../status/chat as status_chat
import ../../../status/chat/[message,stickers,chat]
import ../../../status/chat/[stickers,chat]
import ../../../status/profile/profile
import ../../../status/ens
import ../../../status/types/[message]
import strutils
import message_format
import user_list

View File

@ -1,11 +1,13 @@
import NimQml, Tables, json, strutils, chronicles
import NimQml, Tables, json, strutils, chronicles, json_serialization
import result_model, result_item, location_menu_model, location_menu_item, location_menu_sub_item
import constants as sr_constants
import ../../../../status/[status, types]
import ../../../../status/chat/[message, chat]
import ../../../../status/[status]
import ../../../../status/chat/[chat]
import ../../../../status/types/[message, setting]
import ../../../../status/libstatus/[settings]
import ../../../../app_service/[main]
import ../communities
import ../channel
import ../chat_item
@ -28,6 +30,7 @@ method isEmpty*(self: ResultItemInfo): bool {.base.} =
QtObject:
type MessageSearchViewController* = ref object of QObject
status: Status
appService: AppService
channelView: ChannelView
communitiesView: CommunitiesView
resultItems: Table[string, ResultItemInfo] # [resuiltItemId, ResultItemInfo]
@ -47,10 +50,12 @@ QtObject:
self.resultItems.clear
self.QObject.delete
proc newMessageSearchViewController*(status: Status, channelView: ChannelView,
communitiesView: CommunitiesView): MessageSearchViewController =
proc newMessageSearchViewController*(status: Status, appService: AppService,
channelView: ChannelView, communitiesView: CommunitiesView):
MessageSearchViewController =
new(result, delete)
result.status = status
result.appService = appService
result.channelView = channelView
result.communitiesView = communitiesView
result.resultItems = initTable[string, ResultItemInfo]()
@ -147,7 +152,7 @@ QtObject:
for co in self.communitiesView.joinedCommunityList.communities:
communities.add(co.id)
self.status.chat.asyncSearchMessages(communities, chats,
self.appService.chatService.asyncSearchMessages(communities, chats,
self.meassgeSearchTerm, false)
proc onSearchMessagesLoaded*(self: MessageSearchViewController,

View File

@ -1,14 +1,15 @@
import NimQml, Tables, json, sequtils, chronicles, times, re, sugar, strutils, os, strformat, algorithm
import ../../../status/[status, contacts, types, mailservers]
import ../../../status/signals/types as signal_types
import ../../../status/[status, contacts, mailservers]
import ../../../status/ens as status_ens
import ../../../status/messages as status_messages
import ../../../status/utils as status_utils
import ../../../status/chat/[chat, message]
import ../../../status/chat/[chat]
import ../../../status/profile/profile
import ../../../status/tasks/[qt, task_runner_impl]
import ../../../status/tasks/marathon/mailserver/worker
import ../../../status/types/[message]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import ../../../app_service/tasks/marathon/mailserver/worker
import communities, chat_item, channels_list, communities, community_list, message_list, channel, message_item
@ -23,6 +24,7 @@ type
QtObject:
type MessageView* = ref object of QAbstractListModel
status: Status
appService: AppService
messageList*: OrderedTable[string, ChatMessageList]
pinnedMessagesList*: OrderedTable[string, ChatMessageList]
channelView*: ChannelView
@ -45,9 +47,10 @@ QtObject:
self.channelOpenTime = initTable[string, int64]()
self.QAbstractListModel.delete
proc newMessageView*(status: Status, channelView: ChannelView, communitiesView: CommunitiesView): MessageView =
proc newMessageView*(status: Status, appService: AppService, channelView: ChannelView, communitiesView: CommunitiesView): MessageView =
new(result, delete)
result.status = status
result.appService = appService
result.channelView = channelView
result.communities = communitiesView
result.messageList = initOrderedTable[string, ChatMessageList]()
@ -260,7 +263,7 @@ QtObject:
proc loadMoreMessages*(self: MessageView, channelId: string) {.slot.} =
self.setLoadingHistoryMessages(channelId, true)
self.status.chat.loadMoreMessagesForChannel(channelId)
self.appService.chatService.loadMoreMessagesForChannel(channelId)
proc onMessagesLoaded*(self: MessageView, chatId: string, messages: var seq[Message]) =
self.pushMessages(messages)
@ -290,7 +293,7 @@ QtObject:
proc fillGaps*(self: MessageView, messageId: string) {.slot.} =
self.setLoadingMessages(true)
let mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
let mailserverWorker = self.appService.marathon[MailserverWorker().name]
let task = FillGapsTaskArg( `method`: "fillGaps", chatId: self.channelView.activeChannel.id, messageIds: @[messageId])
mailserverWorker.start(task)

View File

@ -1,8 +1,8 @@
import NimQml, tables, json, chronicles
import ../../../status/[status, chat/message, chat/chat, settings]
import ../../../status/[status, chat/chat, settings]
import message_list, chat_item
import ../../../status/utils as status_utils
import ../../../status/types
import ../../../status/types/[message, setting]
logScope:
topics = "reactions-view"

View File

@ -1,6 +1,6 @@
import NimQml, Tables, sequtils
import ../../../status/chat/stickers
import ../../../status/types
import ../../../status/types/[sticker]
type
StickerRoles {.pure.} = enum

View File

@ -1,6 +1,7 @@
import NimQml, Tables, sequtils, sugar
import ../../../status/chat/stickers, ./sticker_list
import ../../../status/types, ../../../status/utils
import ../../../status/utils
import ../../../status/types/[sticker]
type
StickerPackRoles {.pure.} = enum

View File

@ -5,8 +5,12 @@ import # vendor libs
chronicles, NimQml
import # status-desktop libs
../../../status/[status, stickers, wallet, types, utils],
sticker_pack_list, sticker_list, chat_item, ../../../status/tasks/[qt, task_runner_impl]
../../../status/[status, stickers, wallet, utils],
sticker_pack_list, sticker_list, chat_item
import ../../../status/types/[sticker, pending_transaction_type]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import ../../../app_service/tasks/marathon/mailserver/worker
logScope:
topics = "stickers-view"
@ -48,7 +52,7 @@ proc estimate[T](self: T, slot: string, packId: int, address: string, price: str
price: price,
uuid: uuid
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
const obtainAvailableStickerPacksTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[ObtainAvailableStickerPacksTaskArg](argEncoded)
@ -64,13 +68,14 @@ proc obtainAvailableStickerPacks[T](self: T, slot: string) =
tptr: cast[ByteAddress](obtainAvailableStickerPacksTask),
vptr: cast[ByteAddress](self.vptr),
slot: slot,
running: cast[ByteAddress](addr self.status.tasks.threadpool.running)
running: cast[ByteAddress](addr self.appService.threadpool.running)
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type StickersView* = ref object of QObject
status: Status
appService: AppService
activeChannel: ChatItemView
stickerPacks*: StickerPackList
recentStickers*: StickerList
@ -81,10 +86,11 @@ QtObject:
proc delete*(self: StickersView) =
self.QObject.delete
proc newStickersView*(status: Status, activeChannel: ChatItemView): StickersView =
proc newStickersView*(status: Status, appService: AppService, activeChannel: ChatItemView): StickersView =
new(result, delete)
result = StickersView()
result.status = status
result.appService = appService
result.stickerPacks = newStickerPackList()
result.recentStickers = newStickerList()
result.activeChannel = activeChannel

View File

@ -2,8 +2,9 @@ import NimQml, Tables, json, chronicles, sequtils
import ../../../status/status
import ../../../status/accounts
import ../../../status/chat as status_chat
import ../../../status/chat/[message, chat]
import ../../../status/chat/[chat]
import ../../../status/ens
import ../../../status/types/[message]
import strutils

View File

@ -1,7 +1,7 @@
import NimQml, chronicles, options, std/wrapnils
import ../../status/types as status_types
import ../../status/signals/types
import ../../status/status
import ../../status/types/[account, rpc_response]
import ../../app_service/signals/[base]
import view
import ../../eventemitter

View File

@ -1,10 +1,9 @@
import NimQml, Tables, json, nimcrypto, strformat, json_serialization, chronicles
import ../../status/signals/types
import ../../status/types as status_types
import ../../status/accounts as AccountModel
import ../../status/types/[account, rpc_response]
import ../../app_service/signals/[base]
import ../onboarding/views/account_info
import ../../status/status
import core
type
AccountRoles {.pure.} = enum

View File

@ -1,7 +1,7 @@
import NimQml, chronicles
import ../../status/signals/types
import ../../status/[status, node, network]
import ../../status/types as status_types
import ../../app_service/[main]
import ../../app_service/signals/[base, wallet, discovery_summary, stats]
import ../../eventemitter
import view
@ -10,14 +10,16 @@ logScope:
type NodeController* = ref object
status*: Status
appService: AppService
view*: NodeView
variant*: QVariant
networkAccessMananger*: QNetworkAccessManager
proc newController*(status: Status, nam: QNetworkAccessManager): NodeController =
proc newController*(status: Status, appService: AppService, nam: QNetworkAccessManager): NodeController =
result = NodeController()
result.status = status
result.view = newNodeView(status)
result.appService = appService
result.view = newNodeView(status, appService)
result.variant = newQVariant(result.view)
result.networkAccessMananger = nam

View File

@ -1,7 +1,9 @@
import NimQml, chronicles, strutils, json
import ../../status/[status, node, types, settings, accounts]
import ../../status/signals/types as signal_types
import ../../status/tasks/[qt, task_runner_impl]
import ../../status/[status, node, settings, accounts]
import ../../status/types/[setting]
import ../../app_service/[main]
import ../../app_service/signals/[stats]
import ../../app_service/tasks/[qt, threadpool]
logScope:
topics = "node-view"
@ -22,12 +24,13 @@ proc bloomFiltersBitsSet[T](self: T, slot: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type NodeView* = ref object of QObject
status*: Status
appService: AppService
callResult: string
lastMessage*: string
wakuBloomFilterMode*: bool
@ -39,9 +42,10 @@ QtObject:
proc setup(self: NodeView) =
self.QObject.setup
proc newNodeView*(status: Status): NodeView =
proc newNodeView*(status: Status, appService: AppService): NodeView =
new(result)
result.status = status
result.appService = appService
result.callResult = "Use this tool to call JSONRPC methods"
result.lastMessage = ""
result.wakuBloomFilterMode = false

View File

@ -1,8 +1,8 @@
import NimQml, chronicles, std/wrapnils
import ../../status/types as status_types
import ../../status/accounts as AccountModel
import ../../status/status
import ../../status/signals/types
import ../../status/types/[account]
import ../../app_service/signals/[base]
import ../../eventemitter
import view

View File

@ -1,8 +1,8 @@
import NimQml, Tables, json, nimcrypto, strformat, json_serialization, strutils
import ../../status/types as status_types
import ../../status/signals/types
import ../../status/accounts as AccountModel
import ../../status/[status, wallet]
import ../../status/types/[account, rpc_response]
import ../../app_service/signals/[base]
import views/account_info
type

View File

@ -1,5 +1,5 @@
import NimQml
import ../../../status/types
import ../../../status/types/[account]
import std/wrapnils
QtObject:

View File

@ -1,7 +1,5 @@
import NimQml, json, strutils, sugar, sequtils, tables
import json_serialization
import ../../status/signals/types
import ../../status/types as status_types
import ../../status/profile/[profile, mailserver]
import ../../status/[status, settings]
import ../../status/contacts as status_contacts
@ -9,24 +7,29 @@ import ../../status/chat as status_chat
import ../../status/devices as status_devices
import ../../status/chat/chat
import ../../status/wallet
import ../../status/types/[account, transaction, setting]
import ../../app_service/[main]
import ../../app_service/signals/[base, messages]
import ../../app_service/tasks/marathon/mailserver/events
import ../../eventemitter
import view
import views/[ens_manager, devices, network, mailservers, contacts, muted_chats]
import ../chat/views/channels_list
import chronicles
import ../../status/tasks/marathon/mailserver/events
const DEFAULT_NETWORK_NAME* = "mainnet_rpc"
type ProfileController* = ref object
view*: ProfileView
variant*: QVariant
status*: Status
status: Status
appService: AppService
proc newController*(status: Status, changeLanguage: proc(locale: string)): ProfileController =
proc newController*(status: Status, appService: AppService, changeLanguage: proc(locale: string)): ProfileController =
result = ProfileController()
result.status = status
result.view = newProfileView(status, changeLanguage)
result.appService = appService
result.view = newProfileView(status, appService, changeLanguage)
result.variant = newQVariant(result.view)
proc delete*(self: ProfileController) =

View File

@ -9,9 +9,10 @@ import ../../status/contacts as status_contacts
import ../../status/status
import ../../status/ens as status_ens
import ../../status/chat/chat
import ../../status/types
import ../../status/types/[setting, os_notification]
import ../../status/constants as accountConstants
import ../../status/notifications/[os_notifications, os_notification_details]
import ../../status/notifications/[os_notifications]
import ../../app_service/[main]
import qrcode/qrcode
import ../utils/image_utils
@ -32,6 +33,7 @@ QtObject:
fleets*: Fleets
network*: NetworkView
status*: Status
appService: AppService
changeLanguage*: proc(locale: string)
ens*: EnsManager
@ -53,23 +55,24 @@ QtObject:
if not self.mailservers.isNil: self.mailservers.delete
self.QObject.delete
proc newProfileView*(status: Status, changeLanguage: proc(locale: string)): ProfileView =
proc newProfileView*(status: Status, appService: AppService, changeLanguage: proc(locale: string)): ProfileView =
new(result, delete)
result = ProfileView()
result.profile = newProfileInfoView()
result.profilePicture = newProfilePictureView(status, result.profile)
result.profileSettings = newProfileSettingsView(status, result.profile)
result.mutedChats = newMutedChatsView(status)
result.contacts = newContactsView(status)
result.contacts = newContactsView(status, appService)
result.devices = newDevicesView(status)
result.network = newNetworkView(status)
result.mnemonic = newMnemonicView(status)
result.mailservers = newMailserversView(status)
result.mailservers = newMailserversView(status, appService)
result.dappList = newDappList(status)
result.ens = newEnsManager(status)
result.ens = newEnsManager(status, appService)
result.fleets = newFleets(status)
result.changeLanguage = changeLanguage
result.status = status
result.appService = appService
result.setup
proc initialized*(self: ProfileView) {.signal.}
@ -201,5 +204,5 @@ QtObject:
notificationType: notificationType.OsNotificationType
)
self.status.osnotifications.showNotification(title, message, details,
useOSNotifications)
self.appService.osNotificationService.showNotification(title, message,
details, useOSNotifications)

View File

@ -5,7 +5,8 @@ import ../../../status/chat/chat
import contact_list
import ../../../status/profile/profile
import ../../../status/ens as status_ens
import ../../../status/tasks/[qt, task_runner_impl]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
logScope:
topics = "contacts-view"
@ -28,11 +29,12 @@ proc lookupContact[T](self: T, slot: string, value: string) =
slot: slot,
value: value
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type ContactsView* = ref object of QObject
status: Status
appService: AppService
contactList*: ContactList
contactRequests*: ContactList
addedContacts*: ContactList
@ -49,9 +51,10 @@ QtObject:
self.blockedContacts.delete
self.QObject.delete
proc newContactsView*(status: Status): ContactsView =
proc newContactsView*(status: Status, appService: AppService): ContactsView =
new(result, delete)
result.status = status
result.appService = appService
result.contactList = newContactList()
result.contactRequests = newContactList()
result.addedContacts = newContactList()

View File

@ -2,7 +2,7 @@ import NimQml
import Tables
import json, sequtils
import ../../../status/settings
import ../../../status/types
import ../../../status/types/[setting]
import ../../../status/status
type

View File

@ -1,6 +1,6 @@
import NimQml
import Tables
import ../../../status/profile/devices
import ../../../status/types/[installation]
type
DeviceRoles {.pure.} = enum

View File

@ -1,7 +1,7 @@
import NimQml, chronicles
import ../../../status/status
import ../../../status/devices as status_devices
import ../../../status/profile/devices
import ../../../status/types/[installation]
import device_list
logScope:

View File

@ -3,14 +3,15 @@ import Tables
import json
import sequtils
import strutils
from ../../../status/types import Setting, PendingTransactionType, RpcException
import ../../../status/ens as status_ens
import ../../../status/utils as status_utils
import ../../../status/[status, settings, wallet]
import ../../../status/wallet
import ../../../status/types/[setting, transaction, rpc_response]
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import sets
import web3/ethtypes
import ../../../status/tasks/[qt, task_runner_impl]
import chronicles
type
EnsRoles {.pure.} = enum
@ -38,7 +39,7 @@ proc validate[T](self: T, slot: string, ens: string, isStatus: bool, usernames:
isStatus: isStatus,
usernames: usernames
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
const detailsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let
@ -69,13 +70,14 @@ proc details[T](self: T, slot: string, username: string) =
slot: slot,
username: username
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type EnsManager* = ref object of QAbstractListModel
usernames*: seq[string]
pendingUsernames*: HashSet[string]
status: Status
appService: AppService
proc setup(self: EnsManager) = self.QAbstractListModel.setup
@ -83,10 +85,11 @@ QtObject:
self.usernames = @[]
self.QAbstractListModel.delete
proc newEnsManager*(status: Status): EnsManager =
proc newEnsManager*(status: Status, appService: AppService): EnsManager =
new(result, delete)
result.usernames = @[]
result.status = status
result.appService = appService
result.pendingUsernames = initHashSet[string]()
result.setup

View File

@ -1,6 +1,5 @@
import NimQml, json
import chronicles, strutils
import ../../../status/types as status_types
import ../../../status/[status, settings, accounts]
QtObject:

View File

@ -2,7 +2,9 @@ import NimQml, chronicles
import ../../../status/[status, settings]
import ../../../status/profile/mailserver
import mailservers_list
import ../../../status/tasks/marathon/mailserver/worker
import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool]
import ../../../app_service/tasks/marathon/mailserver/worker
logScope:
topics = "mailservers-view"
@ -10,6 +12,7 @@ logScope:
QtObject:
type MailserversView* = ref object of QObject
status: Status
appService: AppService
mailserversList*: MailServersList
proc setup(self: MailserversView) =
@ -19,9 +22,10 @@ QtObject:
self.mailserversList.delete
self.QObject.delete
proc newMailserversView*(status: Status): MailserversView =
proc newMailserversView*(status: Status, appService: AppService): MailserversView =
new(result, delete)
result.status = status
result.appService = appService
result.mailserversList = newMailServersList()
result.setup
@ -38,7 +42,7 @@ QtObject:
proc getActiveMailserver(self: MailserversView): string {.slot.} =
let
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
mailserverWorker = self.appService.marathon[MailserverWorker().name]
task = GetActiveMailserverTaskArg(
`method`: "getActiveMailserver",
vptr: cast[ByteAddress](self.vptr),
@ -64,7 +68,7 @@ QtObject:
self.status.settings.pinMailserver()
else:
let
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
mailserverWorker = self.appService.marathon[MailserverWorker().name]
task = GetActiveMailserverTaskArg(
`method`: "getActiveMailserver",
vptr: cast[ByteAddress](self.vptr),

View File

@ -1,6 +1,6 @@
import NimQml, chronicles, strutils
import ../../../status/[status, settings]
import ../../../status/types
import ../../../status/types/[setting]
import options
logScope:

View File

@ -1,7 +1,6 @@
import NimQml
import chronicles
import ../../../status/profile/profile
import ../../../status/types
import std/wrapnils
QtObject:

View File

@ -1,5 +1,4 @@
import NimQml, chronicles
import ../../status/signals/types
import ../../status/status
import view

View File

@ -1,6 +1,6 @@
import NimQml
import ../../status/[status, ens, chat/stickers, wallet, settings, provider]
import ../../status/types
import ../../status/types/[setting]
import json, json_serialization, sets, strutils
import chronicles
import nbaser

View File

@ -1,7 +1,6 @@
import NimQml, chronicles
import ../../status/signals/types
import ../../status/[status, node, network]
import ../../status/types as status_types
import ../../app_service/[main]
import view
import ../../eventemitter
@ -10,13 +9,15 @@ logScope:
type UtilsController* = ref object
status*: Status
appService: AppService
view*: UtilsView
variant*: QVariant
proc newController*(status: Status): UtilsController =
proc newController*(status: Status, appService: AppService): UtilsController =
result = UtilsController()
result.status = status
result.view = newUtilsView(status)
result.appService = appService
result.view = newUtilsView(status, appService)
result.variant = newQVariant(result.view)
proc delete*(self: UtilsController) =

View File

@ -1,12 +1,13 @@
import NimQml, os, strformat, strutils, parseUtils, chronicles
import stint
import ../../status/[status, wallet, settings, updates]
import ../../status/tasks/[qt, task_runner_impl]
import ../../status/stickers
import ../../status/tokens as status_tokens
import ../../status/types
import ../../status/utils as status_utils
import ../../status/ens as status_ens
import ../../status/types/[network]
import ../../app_service/[main]
import ../../app_service/tasks/[qt, threadpool]
import ../utils/image_utils
import web3/[ethtypes, conversions]
import stew/byteutils
@ -20,6 +21,7 @@ type CheckForNewVersionTaskArg = ref object of QObjectTaskArg
QtObject:
type UtilsView* = ref object of QObject
status*: Status
appService: AppService
newVersion*: string
proc setup(self: UtilsView) =
@ -33,10 +35,11 @@ QtObject:
proc delete*(self: UtilsView) =
self.QObject.delete
proc newUtilsView*(status: Status): UtilsView =
proc newUtilsView*(status: Status, appService: AppService): UtilsView =
new(result, delete)
result = UtilsView()
result.status = status
result.appService = appService
result.setup
proc getOs*(self: UtilsView): string {.slot.} =
@ -159,7 +162,7 @@ QtObject:
vptr: cast[ByteAddress](self.vptr),
slot: slot
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
proc latestVersionSuccess*(self: UtilsView, latestVersionJSON: string) {.slot.} =
let latestVersionObj = parseJSON(latestVersionJSON)

View File

@ -2,10 +2,13 @@ import NimQml, strformat, strutils, chronicles, sugar, sequtils
import view
import views/[asset_list, account_list, account_item]
import ../../../status/types as status_types
import ../../../status/signals/types
import ../../../status/[status, wallet, settings]
import ../../../status/wallet/account as WalletTypes
import ../../../status/types/[transaction, setting]
import ../../../app_service/[main]
import ../../../app_service/signals/[base]
import ../../../app_service/signals/wallet as wallet_signal
import ../../../eventemitter
logScope:
@ -13,13 +16,15 @@ logScope:
type WalletController* = ref object
status: Status
appService: AppService
view*: WalletView
variant*: QVariant
proc newController*(status: Status): WalletController =
proc newController*(status: Status, appService: AppService): WalletController =
result = WalletController()
result.status = status
result.view = newWalletView(status)
result.appService = appService
result.view = newWalletView(status, appService)
result.variant = newQVariant(result.view)
proc delete*(self: WalletController) =

View File

@ -4,11 +4,13 @@ import NimQml, chronicles, stint
import
../../../status/[status, wallet],
views/[accounts, collectibles, transactions, tokens, gas, ens, dapp_browser, history, balance, utils, asset_list, account_list]
import ../../../app_service/[main]
QtObject:
type
WalletView* = ref object of QAbstractListModel
status: Status
appService: AppService
accountsView: AccountsView
collectiblesView: CollectiblesView
transactionsView*: TransactionsView
@ -37,19 +39,20 @@ QtObject:
proc setup(self: WalletView) =
self.QAbstractListModel.setup
proc newWalletView*(status: Status): WalletView =
proc newWalletView*(status: Status, appService: AppService): WalletView =
new(result, delete)
result.status = status
result.appService = appService
result.accountsView = newAccountsView(status)
result.collectiblesView = newCollectiblesView(status, result.accountsView)
result.transactionsView = newTransactionsView(status, result.accountsView)
result.tokensView = newTokensView(status, result.accountsView)
result.gasView = newGasView(status)
result.ensView = newEnsView(status)
result.collectiblesView = newCollectiblesView(status, appService, result.accountsView)
result.transactionsView = newTransactionsView(status, appService, result.accountsView)
result.tokensView = newTokensView(status, appService, result.accountsView)
result.gasView = newGasView(status, appService)
result.ensView = newEnsView(status, appService)
result.dappBrowserView = newDappBrowserView(status, result.accountsView)
result.historyView = newHistoryView(status, result.accountsView, result.transactionsView)
result.balanceView = newBalanceView(status, result.accountsView, result.transactionsView, result.historyView)
result.historyView = newHistoryView(status, appService, result.accountsView, result.transactionsView)
result.balanceView = newBalanceView(status, appService, result.accountsView, result.transactionsView, result.historyView)
result.utilsView = newUtilsView()
result.isNonArchivalNode = false

View File

@ -1,9 +1,10 @@
import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, settings, types],
../../../../status/signals/types as signal_types,
../../../../status/wallet as status_wallet
../../../../status/[status, settings],
../../../../status/wallet as status_wallet,
../../../../status/types/[rpc_response],
../../../../app_service/signals/[base]
import account_list, account_item

View File

@ -3,8 +3,9 @@ import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, wallet, tokens],
../../../../status/tokens as status_tokens,
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/tokens as status_tokens
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import account_item, accounts, transactions, history
@ -34,11 +35,12 @@ proc initBalances[T](self: T, slot: string, address: string, tokenList: seq[stri
vptr: cast[ByteAddress](self.vptr),
slot: slot, address: address, tokenList: tokenList
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type BalanceView* = ref object of QObject
status: Status
appService: AppService
totalFiatBalance: string
accountsView: AccountsView
transactionsView*: TransactionsView
@ -47,9 +49,10 @@ QtObject:
proc setup(self: BalanceView) = self.QObject.setup
proc delete(self: BalanceView) = self.QObject.delete
proc newBalanceView*(status: Status, accountsView: AccountsView, transactionsView: TransactionsView, historyView: HistoryView): BalanceView =
proc newBalanceView*(status: Status, appService: AppService, accountsView: AccountsView, transactionsView: TransactionsView, historyView: HistoryView): BalanceView =
new(result, delete)
result.status = status
result.appService = appService
result.totalFiatBalance = ""
result.accountsView = accountsView
result.transactionsView = transactionsView

View File

@ -2,9 +2,10 @@ import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, t
import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, settings, wallet, tokens, utils, types],
../../../../status/wallet/collectibles as status_collectibles,
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/[status, settings, wallet, tokens, utils],
../../../../status/wallet/collectibles as status_collectibles
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import collectibles_list, accounts, account_list, account_item
@ -43,13 +44,14 @@ proc loadCollectibles[T](self: T, slot: string, address: string, collectiblesTyp
tptr: cast[ByteAddress](loadCollectiblesTask),
vptr: cast[ByteAddress](self.vptr),
slot: slot, address: address, collectiblesType: collectiblesType,
running: cast[ByteAddress](addr self.status.tasks.threadpool.running)
running: cast[ByteAddress](addr self.appService.threadpool.running)
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type CollectiblesView* = ref object of QObject
status: Status
appService: AppService
accountsView*: AccountsView
currentCollectiblesLists*: CollectiblesList
@ -58,9 +60,10 @@ QtObject:
self.currentCollectiblesLists.delete
self.QObject.delete
proc newCollectiblesView*(status: Status, accountsView: AccountsView): CollectiblesView =
proc newCollectiblesView*(status: Status, appService: AppService, accountsView: AccountsView): CollectiblesView =
new(result, delete)
result.status = status
result.appService = appService
result.currentCollectiblesLists = newCollectiblesList()
result.accountsView = accountsView # TODO: not ideal but a solution for now
result.setup

View File

@ -1,7 +1,8 @@
import sequtils, json, chronicles, web3/[ethtypes, conversions], stint
import NimQml, json, sequtils, chronicles, strutils, json
import ../../../../status/[status, settings, wallet, types]
import ../../../../status/[status, settings, wallet]
import ../../../../status/types/[setting]
import account_list, account_item, accounts

View File

@ -3,8 +3,9 @@ import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, settings, wallet, tokens],
../../../../status/ens as status_ens,
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/ens as status_ens
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import account_list, account_item, transaction_list, accounts, asset_list, token_list
@ -28,18 +29,20 @@ proc resolveEns[T](self: T, slot: string, ens: string, uuid: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot, ens: ens, uuid: uuid
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type EnsView* = ref object of QObject
status: Status
appService: AppService
proc setup(self: EnsView) = self.QObject.setup
proc delete(self: EnsView) = self.QObject.delete
proc newEnsView*(status: Status): EnsView =
proc newEnsView*(status: Status, appService: AppService): EnsView =
new(result, delete)
result.status = status
result.appService = appService
result.setup
proc resolveENS*(self: EnsView, ens: string, uuid: string) {.slot.} =

View File

@ -2,8 +2,10 @@ import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, c
import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, wallet, utils, types],
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/[status, wallet, utils],
../../../../status/types/[gas_prediction]
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import account_item
@ -24,7 +26,7 @@ proc getGasPredictions[T](self: T, slot: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
logScope:
topics = "gas-view"
@ -32,6 +34,7 @@ logScope:
QtObject:
type GasView* = ref object of QObject
status: Status
appService: AppService
safeLowGasPrice: string
standardGasPrice: string
fastGasPrice: string
@ -41,9 +44,10 @@ QtObject:
proc setup(self: GasView) = self.QObject.setup
proc delete(self: GasView) = self.QObject.delete
proc newGasView*(status: Status): GasView =
proc newGasView*(status: Status, appService: AppService): GasView =
new(result, delete)
result.status = status
result.appService = appService
result.safeLowGasPrice = "0"
result.standardGasPrice = "0"
result.fastGasPrice = "0"

View File

@ -3,10 +3,11 @@ from sugar import `=>`, `->`
import NimQml, json, sequtils, chronicles, strutils, json
import
../../../../status/[status, wallet, types, utils],
../../../../status/[status, wallet, utils],
../../../../status/wallet as status_wallet,
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/types/[transaction]
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import account_list, account_item, transaction_list, accounts, transactions
logScope:
@ -39,11 +40,12 @@ proc loadTransactions*[T](self: T, slot: string, address: string, toBlock: Uint2
limit: limit,
loadMore: loadMore
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type HistoryView* = ref object of QObject
status: Status
appService: AppService
accountsView: AccountsView
transactionsView*: TransactionsView
fetchingHistoryState: Table[string, bool]
@ -51,9 +53,11 @@ QtObject:
proc setup(self: HistoryView) = self.QObject.setup
proc delete(self: HistoryView) = self.QObject.delete
proc newHistoryView*(status: Status, accountsView: AccountsView, transactionsView: TransactionsView): HistoryView =
proc newHistoryView*(status: Status, appService: AppService,
accountsView: AccountsView, transactionsView: TransactionsView): HistoryView =
new(result, delete)
result.status = status
result.appService = appService
result.fetchingHistoryState = initTable[string, bool]()
result.accountsView = accountsView
result.transactionsView = transactionsView

View File

@ -6,7 +6,10 @@ import # vendor libs
import # status-desktop libs
../../../../status/[utils, tokens, settings],
../../../../status/tasks/[qt, task_runner_impl], ../../../../status/status
../../../../status/status
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import ../../../../app_service/tasks/marathon/mailserver/worker
from web3/conversions import `$`
type
@ -46,11 +49,12 @@ proc getTokenDetails[T](self: T, slot: string, address: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot,
address: address)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type TokenList* = ref object of QAbstractListModel
status*: Status
status: Status
appService: AppService
tokens*: seq[Erc20Contract]
isCustom*: bool
@ -76,10 +80,11 @@ QtObject:
self.isCustom = true
self.endResetModel()
proc newTokenList*(status: Status): TokenList =
proc newTokenList*(status: Status, appService: AppService): TokenList =
new(result, delete)
result.tokens = @[]
result.status = status
result.appService = appService
result.setup
proc rowData(self: TokenList, index: int, column: string): string {.slot.} =

View File

@ -1,8 +1,8 @@
import atomics, strformat, strutils, sequtils, json, std/wrapnils, parseUtils, tables, chronicles, web3/[ethtypes, conversions], stint
import NimQml, json, sequtils, chronicles, strutils, strformat, json
import ../../../../status/[status, settings, wallet, tokens, utils, types]
import ../../../../status/[status, settings, wallet, tokens, utils]
import ../../../../app_service/[main]
import account_list, account_item, transaction_list, accounts, asset_list, token_list
logScope:
@ -11,6 +11,7 @@ logScope:
QtObject:
type TokensView* = ref object of QObject
status: Status
appService: AppService
accountsView: AccountsView
currentAssetList*: AssetList
defaultTokenList: TokenList
@ -23,13 +24,14 @@ QtObject:
self.customTokenList.delete
self.QObject.delete
proc newTokensView*(status: Status, accountsView: AccountsView): TokensView =
proc newTokensView*(status: Status, appService: AppService, accountsView: AccountsView): TokensView =
new(result, delete)
result.status = status
result.appService = appService
result.accountsView = accountsView
result.currentAssetList = newAssetList()
result.defaultTokenList = newTokenList(status)
result.customTokenList = newTokenList(status)
result.defaultTokenList = newTokenList(status, appService)
result.customTokenList = newTokenList(status, appService)
result.setup
proc hasAsset*(self: TokensView, symbol: string): bool {.slot.} =

View File

@ -3,8 +3,11 @@ import NimQml, json, sequtils, chronicles, strutils, strformat, json, stint
import
../../../../status/[status, settings, wallet, tokens, utils],
../../../../status/wallet as status_wallet,
../../../../status/tasks/[qt, task_runner_impl]
../../../../status/wallet as status_wallet
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import ../../../../app_service/tasks/marathon/mailserver/worker
import account_list, account_item, transaction_list, accounts
@ -46,7 +49,7 @@ proc sendTransaction[T](self: T, slot: string, from_addr: string, to: string, as
assetAddress: assetAddress, value: value, gas: gas,
gasPrice: gasPrice, password: password, uuid: uuid
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
const watchTransactionTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let
@ -61,11 +64,12 @@ proc watchTransaction[T](self: T, slot: string, transactionHash: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot, transactionHash: transactionHash
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type TransactionsView* = ref object of QObject
status: Status
appService: AppService
accountsView*: AccountsView
transactionsView*: TransactionsView
currentTransactions*: TransactionList
@ -75,9 +79,10 @@ QtObject:
self.currentTransactions.delete
self.QObject.delete
proc newTransactionsView*(status: Status, accountsView: AccountsView): TransactionsView =
proc newTransactionsView*(status: Status, appService: AppService, accountsView: AccountsView): TransactionsView =
new(result, delete)
result.status = status
result.appService = appService
result.accountsView = accountsView # TODO: not ideal but a solution for now
result.currentTransactions = newTransactionList()
result.setup

View File

@ -2,10 +2,13 @@ import NimQml, strformat, strutils, chronicles, sugar, sequtils
import view
import views/[account_list, account_item]
import ../../../status/types as status_types
import ../../../status/signals/types
import ../../../status/[status, wallet2, settings]
import ../../../status/wallet2/account as WalletTypes
import ../../../status/types/[transaction, setting]
import ../../../app_service/[main]
import ../../../app_service/signals/[base]
import ../../../app_service/signals/wallet as wallet_signal
import ../../../eventemitter
logScope:
@ -13,13 +16,15 @@ logScope:
type WalletController* = ref object
status: Status
appService: AppService
view*: WalletView
variant*: QVariant
proc newController*(status: Status): WalletController =
proc newController*(status: Status, appService: AppService): WalletController =
result = WalletController()
result.status = status
result.view = newWalletView(status)
result.appService = appService
result.view = newWalletView(status, appService)
result.variant = newQVariant(result.view)
proc delete*(self: WalletController) =

View File

@ -4,11 +4,13 @@ import NimQml, chronicles, stint
import ../../../status/[status, wallet2]
import views/[accounts, account_list, collectibles]
import views/buy_sell_crypto/[service_controller]
import ../../../app_service/[main]
QtObject:
type
WalletView* = ref object of QAbstractListModel
status: Status
appService: AppService
accountsView: AccountsView
collectiblesView: CollectiblesView
cryptoServiceController: CryptoServiceController
@ -22,12 +24,13 @@ QtObject:
proc setup(self: WalletView) =
self.QAbstractListModel.setup
proc newWalletView*(status: Status): WalletView =
proc newWalletView*(status: Status, appService: AppService): WalletView =
new(result, delete)
result.status = status
result.appService = appService
result.accountsView = newAccountsView(status)
result.collectiblesView = newCollectiblesView(status)
result.cryptoServiceController = newCryptoServiceController(status)
result.collectiblesView = newCollectiblesView(status, appService)
result.cryptoServiceController = newCryptoServiceController(status, appService)
result.setup
proc getAccounts(self: WalletView): QVariant {.slot.} =

View File

@ -1,9 +1,10 @@
import NimQml, json, sequtils, chronicles, strutils, strformat, json
import
../../../../status/[status, settings, types],
../../../../status/signals/types as signal_types,
../../../../status/wallet2 as status_wallet
../../../../status/[status, settings],
../../../../status/wallet2 as status_wallet,
../../../../status/types/[rpc_response],
../../../../app_service/signals/[base]
import account_list, account_item

View File

@ -2,6 +2,7 @@ import NimQml, json, strutils, chronicles
import service_model, service_item
import ../../../../../app_service/[main]
import ../../../../../status/[status, wallet2]
logScope:
@ -10,6 +11,7 @@ logScope:
QtObject:
type CryptoServiceController* = ref object of QObject
status: Status
appService: AppService
cryptoServiceModel: CryptoServiceModel
servicesFetched: bool
@ -20,9 +22,11 @@ QtObject:
self.cryptoServiceModel.delete
self.QObject.delete
proc newCryptoServiceController*(status: Status): CryptoServiceController =
proc newCryptoServiceController*(status: Status, appService: AppService):
CryptoServiceController =
new(result, delete)
result.status = status
result.appService = appService
result.cryptoServiceModel = newCryptoServiceModel()
result.servicesFetched = false
result.setup
@ -37,7 +41,7 @@ QtObject:
proc fetchCryptoServices*(self: CryptoServiceController) {.slot.} =
if(not self.servicesFetched):
self.status.wallet2.asyncFetchCryptoServices()
self.appService.walletService.asyncFetchCryptoServices()
else:
self.fetchCryptoServicesFetched()

View File

@ -1,8 +1,8 @@
import NimQml, Tables, json, chronicles
import
../../../../status/[status, wallet2],
../../../../status/tasks/[qt, task_runner_impl]
import ../../../../status/[status, wallet2]
import ../../../../app_service/[main]
import ../../../../app_service/tasks/[qt, threadpool]
import collection_list, asset_list
@ -24,7 +24,7 @@ proc loadCollections[T](self: T, slot: string, address: string) =
vptr: cast[ByteAddress](self.vptr),
slot: slot, address: address,
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
type
LoadAssetsTaskArg = ref object of QObjectTaskArg
@ -46,11 +46,12 @@ proc loadAssets[T](self: T, slot: string, address: string, collectionSlug: strin
vptr: cast[ByteAddress](self.vptr),
slot: slot, address: address, collectionSlug: collectionSlug, limit: 200
)
self.status.tasks.threadpool.start(arg)
self.appService.threadpool.start(arg)
QtObject:
type CollectiblesView* = ref object of QObject
status: Status
appService: AppService
collections: CollectionList
isLoading: bool
assets: Table[string, AssetList]
@ -63,9 +64,10 @@ QtObject:
list.delete
self.QObject.delete
proc newCollectiblesView*(status: Status): CollectiblesView =
proc newCollectiblesView*(status: Status, appService: AppService): CollectiblesView =
new(result, delete)
result.status = status
result.appService = appService
result.collections = newCollectionList()
result.assets = initTable[string, AssetList]()
result.isLoading = false

View File

@ -1,4 +1,4 @@
include ../utils/json_utils
include ../../../status/utils/json_utils
type
AsyncSearchMessagesTaskArg = ref object of QObjectTaskArg

View File

@ -0,0 +1,111 @@
import NimQml
import json, chronicles
import ../../tasks/[qt, threadpool]
import ../../../status/status
import ../../../status/libstatus/chat as status_chat
include ../../../status/chat/utils
include async_tasks
logScope:
topics = "chat-async-service"
QtObject:
type ChatService* = ref object of QObject
status: Status
threadpool: ThreadPool
proc setup(self: ChatService) =
self.QObject.setup
proc delete*(self: ChatService) =
self.QObject.delete
proc newChatService*(status: Status, threadpool: ThreadPool): ChatService =
new(result, delete)
result.status = status
result.threadpool = threadpool
result.setup()
proc onAsyncMarkMessagesRead(self: ChatService, response: string) {.slot.} =
self.status.chat.onAsyncMarkMessagesRead(response)
proc asyncMarkAllChannelMessagesRead*(self: ChatService, chatId: string) =
let arg = AsyncMarkAllReadTaskArg(
tptr: cast[ByteAddress](asyncMarkAllReadTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncMarkMessagesRead",
chatId: chatId,
)
self.threadpool.start(arg)
proc onAsyncSearchMessages*(self: ChatService, response: string) {.slot.} =
self.status.chat.onAsyncSearchMessages(response)
proc asyncSearchMessages*(self: ChatService, chatId: string, searchTerm: string,
caseSensitive: bool) =
## Asynchronous search for messages which contain the searchTerm and belong
## to the chat with chatId.
if (chatId.len == 0):
info "empty channel id set for fetching more messages"
return
if (searchTerm.len == 0):
return
let arg = AsyncSearchMessagesInChatTaskArg(
tptr: cast[ByteAddress](asyncSearchMessagesInChatTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncSearchMessages",
chatId: chatId,
searchTerm: searchTerm,
caseSensitive: caseSensitive
)
self.threadpool.start(arg)
proc asyncSearchMessages*(self: ChatService, communityIds: seq[string],
chatIds: seq[string], searchTerm: string, caseSensitive: bool) =
## Asynchronous search for messages which contain the searchTerm and belong
## to either any chat/channel from chatIds array or any channel of community
## from communityIds array.
if (communityIds.len == 0 and chatIds.len == 0):
info "either community ids or chat ids or both must be set"
return
if (searchTerm.len == 0):
return
let arg = AsyncSearchMessagesInChatsAndCommunitiesTaskArg(
tptr: cast[ByteAddress](asyncSearchMessagesInChatsAndCommunitiesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncSearchMessages",
communityIds: communityIds,
chatIds: chatIds,
searchTerm: searchTerm,
caseSensitive: caseSensitive
)
self.threadpool.start(arg)
proc onLoadMoreMessagesForChannel*(self: ChatService, response: string) {.slot.} =
self.status.chat.onLoadMoreMessagesForChannel(response)
proc loadMoreMessagesForChannel*(self: ChatService, channelId: string) =
if (channelId.len == 0):
info "empty channel id set for fetching more messages"
return
let arg = AsyncFetchChatMessagesTaskArg(
tptr: cast[ByteAddress](asyncFetchChatMessagesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onLoadMoreMessagesForChannel",
chatId: channelId,
chatCursor: self.status.chat.getCurrentMessageCursor(channelId),
emojiCursor: self.status.chat.getCurrentEmojiCursor(channelId),
pinnedMsgCursor: self.status.chat.getCurrentPinnedMessageCursor(channelId),
limit: 20
)
self.threadpool.start(arg)

View File

@ -1,4 +1,4 @@
include ../utils/json_utils
include ../../../status/utils/json_utils
#################################################
# Async request for the list of services to buy/sell crypto

View File

@ -0,0 +1,42 @@
import NimQml
import json, chronicles
import ../../tasks/[qt, threadpool]
import ../../../status/[status, wallet2]
import ../../../status/libstatus/wallet as status_wallet
include async_tasks
logScope:
topics = "wallet-async-service"
QtObject:
type WalletService* = ref object of QObject
status: Status
threadpool: ThreadPool
proc setup(self: WalletService) =
self.QObject.setup
proc delete*(self: WalletService) =
self.QObject.delete
proc newWalletService*(status: Status, threadpool: ThreadPool): WalletService =
new(result, delete)
result.status = status
result.threadpool = threadpool
result.setup()
proc onAsyncFetchCryptoServices*(self: WalletService, response: string) {.slot.} =
self.status.wallet2.onAsyncFetchCryptoServices(response)
proc asyncFetchCryptoServices*(self: WalletService) =
## Asynchronous request for the list of services to buy/sell crypto.
let arg = QObjectTaskArg(
tptr: cast[ByteAddress](asyncGetCryptoServicesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncFetchCryptoServices"
)
self.threadpool.start(arg)

49
src/app_service/main.nim Normal file
View File

@ -0,0 +1,49 @@
import chronicles, task_runner
import ../status/status
import
./tasks/marathon,
./tasks/marathon/worker,
./tasks/threadpool,
./signals/signal_controller
import service/os_notification/service as os_notification_service
import async_service/chat/service as chat_async_service
import async_service/wallet/service as wallet_async_service
export marathon, task_runner, signal_controller
export os_notification_service
export chat_async_service, wallet_async_service
logScope:
topics = "app-services"
type AppService* = ref object
# foundation
threadpool*: ThreadPool
marathon*: Marathon
signalController*: SignalsController
# services
osNotificationService*: OsNotificationService
# async services
chatService*: ChatService
walletService*: WalletService
proc newAppService*(status: Status, worker: MarathonWorker): AppService =
result = AppService()
result.threadpool = newThreadPool()
result.marathon = newMarathon(worker)
result.signalController = newSignalsController(status)
result.osNotificationService = newOsNotificationService(status)
result.chatService = newChatService(status, result.threadpool)
result.walletService = newWalletService(status, result.threadpool)
proc delete*(self: AppService) =
self.threadpool.teardown()
self.marathon.teardown()
self.signalController.delete()
self.osNotificationService.delete()
self.chatService.delete()
self.walletService.delete()
proc onLoggedIn*(self: AppService) =
self.marathon.onLoggedIn()

View File

@ -0,0 +1,48 @@
import NimQml, json, chronicles
import ../../../status/[status]
import ../../../status/notifications/[os_notifications]
import ../../../status/types/[os_notification]
logScope:
topics = "os-notification-service"
QtObject:
type OsNotificationService* = ref object of QObject
status: Status
notification: StatusOSNotificationObject
proc setup(self: OsNotificationService, status: Status) =
self.QObject.setup
self.status = status
self.notification = newStatusOSNotificationObject()
signalConnect(self.notification, "notificationClicked(QString)", self,
"onNotificationClicked(QString)", 2)
proc delete*(self: OsNotificationService) =
self.notification.delete
self.QObject.delete
proc newOsNotificationService*(status: Status): OsNotificationService =
new(result, delete)
result.setup(status)
proc showNotification*(self: OsNotificationService, title: string,
message: string, details: OsNotificationDetails, useOSNotifications: bool) =
## This method will add new notification to the Notification center. Param
## "details" is used to uniquely define a notification bubble.
# Whether we need to use OS notifications or not should be checked only here,
# but because we don't have settings class on the nim side yet, we're using
# useOSNotifications param sent from the qml side. Once we are able to check
# that here, we will remove useOSNotifications param from this method.
if(not useOSNotifications):
return
let identifier = $(details.toJsonNode())
self.notification.showNotification(title, message, identifier)
proc onNotificationClicked*(self: OsNotificationService, identifier: string) {.slot.} =
## This slot is called once user clicks a notificaiton bubble, "identifier"
## contains data which uniquely define that notification.
self.status.osnotifications.onNotificationClicked(identifier)

View File

@ -0,0 +1,15 @@
import json_serialization
import signal_type
import ../../eventemitter
export signal_type
type Signal* = ref object of Args
signalType* {.serializedFieldName("type").}: SignalType
type StatusGoError* = object
error*: string
type NodeSignal* = ref object of Signal
event*: StatusGoError

View File

@ -0,0 +1,13 @@
import json
import base
import ../../status/types/community
type CommunitySignal* = ref object of Signal
community*: Community
proc fromEvent*(event: JsonNode): Signal =
var signal: CommunitySignal = CommunitySignal()
signal.community = event["event"].toCommunity()
result = signal

View File

@ -1,10 +1,13 @@
import json
import types
import base
type DiscoverySummarySignal* = ref object of Signal
enodes*: seq[string]
proc fromEvent*(jsonSignal: JsonNode): Signal =
var signal:DiscoverySummarySignal = DiscoverySummarySignal()
if jsonSignal["event"].kind != JNull:
for discoveryItem in jsonSignal["event"]:
signal.enodes.add(discoveryItem["enode"].getStr)
result = signal
result = signal

View File

@ -1,5 +1,9 @@
import json
import types
import base
type EnvelopeSentSignal* = ref object of Signal
messageIds*: seq[string]
proc fromEvent*(jsonSignal: JsonNode): Signal =
var signal:EnvelopeSentSignal = EnvelopeSentSignal()

View File

@ -1,5 +1,9 @@
import json
import types
import base
type EnvelopeExpiredSignal* = ref object of Signal
messageIds*: seq[string]
proc fromEvent*(jsonSignal: JsonNode): Signal =
var signal:EnvelopeExpiredSignal = EnvelopeExpiredSignal()

View File

@ -1,5 +1,16 @@
import json
import types
import base
type MailserverRequestCompletedSignal* = ref object of Signal
requestID*: string
lastEnvelopeHash*: string
cursor*: string
errorMessage*: string
error*: bool
type MailserverRequestExpiredSignal* = ref object of Signal
# TODO
proc fromCompletedEvent*(jsonSignal: JsonNode): Signal =
var signal:MailserverRequestCompletedSignal = MailserverRequestCompletedSignal()

View File

@ -0,0 +1,95 @@
import json, chronicles
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*(event: JsonNode): Signal =
var signal:MessageSignal = MessageSignal()
signal.messages = @[]
signal.contacts = @[]
if event["event"]{"contacts"} != nil:
for jsonContact in event["event"]["contacts"]:
signal.contacts.add(jsonContact.toProfileModel())
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:
warn "Unknown content type received", type = jsonPinnedMessage{"contentType"}.getInt
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

View File

@ -1,7 +1,7 @@
import NimQml, tables, json, chronicles, strutils, json_serialization
import ../types as status_types
import types, messages, discovery, whisperFilter, envelopes, expired, wallet, mailserver, communities, stats
import ../status
import NimQml, json, chronicles, strutils, json_serialization
import base, signal_type, messages, discovery_summary, whisper_filter, envelope, expired,
wallet, mailserver, community, stats
import ../../status/status
import ../../eventemitter
logScope:
@ -12,7 +12,7 @@ QtObject:
variant*: QVariant
status*: Status
proc newController*(status: Status): SignalsController =
proc newSignalsController*(status: Status): SignalsController =
new(result)
result.status = status
result.setup()
@ -48,15 +48,15 @@ QtObject:
var signal: Signal = case signalType:
of SignalType.Message: messages.fromEvent(jsonSignal)
of SignalType.EnvelopeSent: envelopes.fromEvent(jsonSignal)
of SignalType.EnvelopeSent: envelope.fromEvent(jsonSignal)
of SignalType.EnvelopeExpired: expired.fromEvent(jsonSignal)
of SignalType.WhisperFilterAdded: whisperFilter.fromEvent(jsonSignal)
of SignalType.Wallet: wallet.fromEvent(jsonSignal)
of SignalType.NodeLogin: Json.decode($jsonSignal, NodeSignal)
of SignalType.DiscoverySummary: discovery.fromEvent(jsonSignal)
of SignalType.DiscoverySummary: discovery_summary.fromEvent(jsonSignal)
of SignalType.MailserverRequestCompleted: mailserver.fromCompletedEvent(jsonSignal)
of SignalType.MailserverRequestExpired: mailserver.fromExpiredEvent(jsonSignal)
of SignalType.CommunityFound: communities.fromEvent(jsonSignal)
of SignalType.CommunityFound: community.fromEvent(jsonSignal)
of SignalType.Stats: stats.fromEvent(jsonSignal)
else: Signal()

View File

@ -0,0 +1,26 @@
{.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"
Stats = "stats"
Unknown
proc event*(self:SignalType):string =
result = "signal:" & $self

View File

@ -1,5 +1,13 @@
import json
import types
import base
type Stats* = object
uploadRate*: uint64
downloadRate*: uint64
type StatsSignal* = ref object of Signal
stats*: Stats
proc toStats(jsonMsg: JsonNode): Stats =
result = Stats(

View File

@ -1,5 +1,14 @@
import json
import types
import base
type WalletSignal* = ref object of Signal
content*: string
eventType*: string
blockNumber*: int
accounts*: seq[string]
# newTransactions*: ???
erc20*: bool
proc fromEvent*(jsonSignal: JsonNode): Signal =
var signal:WalletSignal = WalletSignal()

View File

@ -1,5 +1,17 @@
import json
import types
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(

View File

@ -18,22 +18,21 @@ type
proc start*[T: MarathonTaskArg](self: MarathonWorker, arg: T) =
self.chanSendToWorker.sendSync(arg.encode.safe)
proc newMarathon*(): Marathon =
proc init(self: Marathon) =
for worker in self.workers.values:
worker.init()
proc newMarathon*(worker: MarathonWorker): Marathon =
new(result)
result.workers = initTable[string, MarathonWorker]()
proc registerWorker*(self: Marathon, worker: MarathonWorker) =
self.workers[worker.name] = worker # overwrite if exists
result.workers[worker.name] = worker
result.init()
proc `[]`*(self: Marathon, name: string): MarathonWorker =
if not self.workers.contains(name):
raise newException(ValueError, &"""Worker '{name}' is not registered. Use 'registerWorker("{name}", {name}Worker)' to register the worker first.""")
self.workers[name]
proc init*(self: Marathon) =
for worker in self.workers.values:
worker.init()
proc teardown*(self: Marathon) =
for worker in self.workers.values:
worker.teardown()

View File

@ -5,7 +5,7 @@ import # vendor libs
chronicles, NimQml, json_serialization
import # status-desktop libs
../../../status, ../../common as task_runner_common, ./events
../../../../status/status, ../../common as task_runner_common, ./events
logScope:
topics = "mailserver controller"

View File

@ -4,11 +4,11 @@ import
from times import cpuTime
import
../../../libstatus/settings as status_settings,
../../../libstatus/chat as status_chat,
../../../libstatus/mailservers as status_mailservers,
../../../libstatus/core as status_core,
../../../types, ../../../fleet,
../../../../status/libstatus/settings as status_settings,
../../../../status/libstatus/chat as status_chat,
../../../../status/libstatus/mailservers as status_mailservers,
../../../../status/libstatus/core as status_core,
../../../../status/fleet,
./events as mailserver_events
logScope:

View File

@ -7,7 +7,7 @@ import # vendor libs
import # status-desktop libs
../worker, ./model, ../../qt, ../../common as task_runner_common,
../common as methuselash_common,
../../../libstatus/mailservers # TODO: needed for MailserverTopic type, remove?
../../../../status/libstatus/mailservers # TODO: needed for MailserverTopic type, remove?
export
chronos, task_runner_common, json_serialization

View File

@ -37,15 +37,7 @@ proc poolThread(arg: PoolThreadArg) {.thread.}
const MaxThreadPoolSize = 16
proc newThreadPool*(size: int = MaxThreadPoolSize): ThreadPool =
new(result)
result.chanRecvFromPool = newAsyncChannel[ThreadSafeString](-1)
result.chanSendToPool = newAsyncChannel[ThreadSafeString](-1)
result.thread = Thread[PoolThreadArg]()
result.size = size
result.running.store(false)
proc init*(self: ThreadPool) =
proc init(self: ThreadPool) =
self.chanRecvFromPool.open()
self.chanSendToPool.open()
let arg = PoolThreadArg(
@ -57,6 +49,15 @@ proc init*(self: ThreadPool) =
# block until we receive "ready"
discard $(self.chanRecvFromPool.recvSync())
proc newThreadPool*(size: int = MaxThreadPoolSize): ThreadPool =
new(result)
result.chanRecvFromPool = newAsyncChannel[ThreadSafeString](-1)
result.chanSendToPool = newAsyncChannel[ThreadSafeString](-1)
result.thread = Thread[PoolThreadArg]()
result.size = size
result.running.store(false)
result.init()
proc teardown*(self: ThreadPool) =
self.running.store(false)
self.chanSendToPool.sendSync("shutdown".safe)

View File

@ -10,14 +10,14 @@ import app/profile/core as profile
import app/onboarding/core as onboarding
import app/login/core as login
import app/provider/core as provider
import status/signals/core as signals
import status/types
import status/types/[account]
import status/constants
import status_go
import status/status as statuslib
import ./eventemitter
import ./status/tasks/marathon/mailserver/controller as mailserver_controller
import ./status/tasks/marathon/mailserver/worker as mailserver_worker
import eventemitter
import app_service/tasks/marathon/mailserver/controller as mailserver_controller
import app_service/tasks/marathon/mailserver/worker as mailserver_worker
import app_service/main
var signalsQObjPointer: pointer
@ -45,8 +45,9 @@ proc mainProc() =
mailserverController = mailserver_controller.newController(status)
mailserverWorker = mailserver_worker.newMailserverWorker(cast[ByteAddress](mailserverController.vptr))
# TODO: create and register an ipcWorker
status.tasks.marathon.registerWorker(mailserverWorker)
let appService = newAppService(status, mailserverWorker)
defer: appService.delete()
status.initNode()
let uiScaleFilePath = joinPath(DATADIR, "ui-scale")
@ -119,32 +120,30 @@ proc mainProc() =
netAccMgr.clearConnectionCache()
netAccMgr.setNetworkAccessible(NetworkAccessibility.Accessible)
let signalController = signals.newController(status)
defer:
signalsQObjPointer = nil
signalController.delete()
# We need this global variable in order to be able to access the application
# from the non-closure callback passed to `libstatus.setSignalEventCallback`
signalsQObjPointer = cast[pointer](signalController.vptr)
signalsQObjPointer = cast[pointer](appService.signalController.vptr)
defer:
signalsQObjPointer = nil
var wallet = wallet.newController(status)
var wallet = wallet.newController(status, appService)
defer: wallet.delete()
engine.setRootContextProperty("walletModel", wallet.variant)
var wallet2 = walletV2.newController(status)
var wallet2 = walletV2.newController(status, appService)
defer: wallet2.delete()
engine.setRootContextProperty("walletV2Model", wallet2.variant)
var chat = chat.newController(status)
var chat = chat.newController(status, appService)
defer: chat.delete()
engine.setRootContextProperty("chatsModel", chat.variant)
var node = node.newController(status, netAccMgr)
var node = node.newController(status, appService, netAccMgr)
defer: node.delete()
engine.setRootContextProperty("nodeModel", node.variant)
var utilsController = utilsView.newController(status)
var utilsController = utilsView.newController(status, appService)
defer: utilsController.delete()
engine.setRootContextProperty("utilsModel", utilsController.variant)
@ -159,7 +158,7 @@ proc mainProc() =
let shouldRetranslate = not defined(linux)
engine.setTranslationPackage(joinPath(i18nPath, fmt"qml_{locale}.qm"), shouldRetranslate)
var profile = profile.newController(status, changeLanguage)
var profile = profile.newController(status, appService, changeLanguage)
defer: profile.delete()
engine.setRootContextProperty("profileModel", profile.variant)
@ -175,7 +174,7 @@ proc mainProc() =
status.events.once("login") do(a: Args):
var args = AccountArgs(a)
status.tasks.marathon.onLoggedIn()
appService.onLoggedIn()
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
login.reset()
@ -202,7 +201,6 @@ proc mainProc() =
# this should be the last defer in the scope
defer:
info "Status app is shutting down..."
status.tasks.teardown()
engine.setRootContextProperty("loginModel", login.variant)
engine.setRootContextProperty("onboardingModel", onboarding.variant)
@ -237,7 +235,7 @@ proc mainProc() =
# 2. Re-init controllers that don't require a running node
initControllers()
engine.setRootContextProperty("signals", signalController.variant)
engine.setRootContextProperty("signals", appService.signalController.variant)
engine.setRootContextProperty("mailserver", mailserverController.variant)
var prValue = newQVariant(if defined(production): true else: false)

View File

@ -1,7 +1,7 @@
import options, chronicles, json, json_serialization, sequtils, sugar
import libstatus/accounts as status_accounts
import libstatus/settings as status_settings
import types
import ./types/[account, fleet, sticker, setting]
import utils
import ../eventemitter

View File

@ -1,10 +1,7 @@
import json
import libstatus/browser as status_browser
import ../eventemitter
#TODO: temporary?
import types as LibStatusTypes
import ./types/[bookmark]
type
BrowserModel* = ref object

File diff suppressed because it is too large Load Diff

View File

@ -1,189 +1,6 @@
import strformat, json, sequtils, tables
from message import Message
import ../types
import ../types/[chat, community]
type ChatType* {.pure.}= enum
Unknown = 0,
OneToOne = 1,
Public = 2,
PrivateGroupChat = 3,
Profile = 4,
Timeline = 5
CommunityChat = 6
type ActivityCenterNotificationType* {.pure.}= enum
Unknown = 0,
NewOneToOne = 1,
NewPrivateGroupChat = 2,
Mention = 3
Reply = 4
proc isOneToOne*(self: ChatType): bool = self == ChatType.OneToOne
proc isTimeline*(self: ChatType): bool = self == ChatType.Timeline
type ChatMember* = object
admin*: bool
id*: string
joined*: bool
identicon*: string
userName*: string
localNickname*: string
proc toJsonNode*(self: ChatMember): JsonNode =
result = %* {
"id": self.id,
"admin": self.admin,
"joined": self.joined
}
proc toJsonNode*(self: seq[ChatMember]): seq[JsonNode] =
result = map(self, proc(x: ChatMember): JsonNode = x.toJsonNode)
type ChatMembershipEvent* = object
chatId*: string
clockValue*: int64
fromKey*: string
name*: string
members*: seq[string]
rawPayload*: string
signature*: string
eventType*: int
proc toJsonNode*(self: ChatMembershipEvent): JsonNode =
result = %* {
"chatId": self.chatId,
"name": self.name,
"clockValue": self.clockValue,
"from": self.fromKey,
"members": self.members,
"rawPayload": self.rawPayload,
"signature": self.signature,
"type": self.eventType
}
proc toJsonNode*(self: seq[ChatMembershipEvent]): seq[JsonNode] =
result = map(self, proc(x: ChatMembershipEvent): JsonNode = x.toJsonNode)
type Chat* = ref 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
communityId*: string
private*: bool
categoryId*: string
name*: string
description*: string
color*: string
identicon*: string
isActive*: bool # indicates whether the chat has been soft deleted
chatType*: ChatType
timestamp*: int64 # indicates the last time this chat has received/sent a message
joined*: int64 # indicates when the user joined the chat last time
lastClockValue*: int64 # indicates the last clock value to be used when sending messages
deletedAtClockValue*: int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded
unviewedMessagesCount*: int
unviewedMentionsCount*: int
lastMessage*: Message
members*: seq[ChatMember]
membershipUpdateEvents*: seq[ChatMembershipEvent]
mentionsCount*: int # Using this is not a good approach, we should instead use unviewedMentionsCount and refer to it always.
muted*: bool
canPost*: bool
ensName*: string
position*: int
type RemovedMessage* = object
chatId*: string
messageId*: string
type CommunityAccessLevel* = enum
unknown = 0
public = 1
invitationOnly = 2
onRequest = 3
type CommunityMembershipRequest* = object
id*: string
publicKey*: string
chatId*: string
communityId*: string
state*: int
our*: string
type CommunityCategory* = object
id*: string
name*: string
position*: int
type StatusUpdateType* {.pure.}= enum
Unknown = 0,
Online = 1,
DoNotDisturb = 2
type StatusUpdate* = object
publicKey*: string
statusType*: StatusUpdateType
clock*: uint64
text*: string
type Community* = object
id*: string
name*: string
lastChannelSeen*: string
description*: string
chats*: seq[Chat]
categories*: seq[CommunityCategory]
members*: seq[string]
access*: int
unviewedMessagesCount*: int
unviewedMentionsCount*: int
admin*: bool
joined*: bool
verified*: bool
ensOnly*: bool
canRequestAccess*: bool
canManageUsers*: bool
canJoin*: bool
isMember*: bool
muted*: bool
communityImage*: IdentityImage
membershipRequests*: seq[CommunityMembershipRequest]
communityColor*: string
memberStatus*: OrderedTable[string, StatusUpdate]
type ActivityCenterNotification* = ref object of RootObj
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
chatId*: string
name*: string
author*: string
notificationType*: ActivityCenterNotificationType
message*: Message
timestamp*: int64
read*: bool
dismissed*: bool
accepted*: bool
proc `$`*(self: Chat): string =
result = fmt"Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType})"
proc `$`*(self: Community): string =
result = fmt"Community(id:{self.id}, name:{self.name}, description:{self.description}"
proc toJsonNode*(self: Chat): JsonNode =
result = %* {
"active": self.isActive,
"chatType": self.chatType.int,
"color": self.color,
"deletedAtClockValue": self.deletedAtClockValue,
"id": self.id,
"lastClockValue": self.lastClockValue,
"lastMessage": nil,
"members": self.members.toJsonNode,
"membershipUpdateEvents": self.membershipUpdateEvents.toJsonNode,
"name": (if self.ensName != "": self.ensName else: self.name),
"timestamp": self.timestamp,
"unviewedMessagesCount": self.unviewedMessagesCount,
"joined": self.joined,
"position": self.position
}
export chat, community
proc findIndexById*(self: seq[Chat], id: string): int =
result = -1

View File

@ -1,90 +0,0 @@
import strformat
type ContentType* {.pure.} = enum
FetchMoreMessagesButton = -2
ChatIdentifier = -1,
Unknown = 0,
Message = 1,
Sticker = 2,
Status = 3,
Emoji = 4,
Transaction = 5,
Group = 6,
Image = 7,
Audio = 8
Community = 9
Gap = 10
Edit = 11
type TextItem* = object
textType*: string
children*: seq[TextItem]
literal*: string
destination*: string
type CommandParameters* = object
id*: string
fromAddress*: string
address*: string
contract*: string
value*: string
transactionHash*: string
commandState*: int
signature*: string
proc `$`*(self: CommandParameters): string =
result = fmt"CommandParameters(id:{self.id}, fromAddr:{self.fromAddress}, addr:{self.address}, contract:{self.contract}, value:{self.value}, transactionHash:{self.transactionHash}, commandState:{self.commandState}, signature:{self.signature})"
type Message* = object
alias*: string
userName*: string
localName*: string
chatId*: string
clock*: int
gapFrom*: int
gapTo*: int
commandParameters*: CommandParameters
contentType*: ContentType
ensName*: string
fromAuthor*: string
id*: string
identicon*: string
lineCount*: int
localChatId*: string
messageType*: string # ???
parsedText*: seq[TextItem]
# quotedMessage: # ???
replace*: string
responseTo*: string
rtl*: bool # ???
seen*: bool # ???
sticker*: string
stickerPackId*: int
text*: string
timestamp*: string
editedAt*: string
whisperTimestamp*: string
isCurrentUser*: bool
stickerHash*: string
outgoingStatus*: string
linkUrls*: string
image*: string
audio*: string
communityId*: string
audioDurationMs*: int
hasMention*: bool
isPinned*: bool
pinnedBy*: string
deleted*: bool
type Reaction* = object
id*: string
chatId*: string
fromAccount*: string
messageId*: string
emojiId*: int
retracted*: bool
proc `$`*(self: Message): string =
result = fmt"Message(id:{self.id}, chatId:{self.chatId}, clock:{self.clock}, from:{self.fromAuthor}, contentType:{self.contentType})"

View File

@ -1,4 +1,7 @@
proc formatChatUpdate(response: JsonNode): (seq[Chat], seq[Message]) =
import json
import ../types/[message, chat]
proc formatChatUpdate*(response: JsonNode): (seq[Chat], seq[Message]) =
var chats: seq[Chat] = @[]
var messages: seq[Message] = @[]
if response["result"]{"messages"} != nil:

View File

@ -1,8 +1,7 @@
import system
import libstatus/settings
import types
import types/[setting, installation]
import libstatus/installations
import profile/devices
import json
proc setDeviceName*(name: string) =

View File

@ -7,7 +7,7 @@ import json_serialization
import tables
import strformat
import libstatus/core
import types
import ./types/[transaction, setting, rpc_response]
import utils
import libstatus/wallet
import stew/byteutils

Some files were not shown because too many files have changed in this diff Show More