A base structure for new architecture added
Initial structure for MainModule containing ChatSectionModule and CommunitySectionModule is added, as well as initial structure for StartupModule containing OnboardingModule and LoginModule. Order of execution is updated and adapted to the current app state. Main module gets loaded once a user is successfully logged in.
This commit is contained in:
parent
69656cfef5
commit
9f4eeffdea
|
@ -0,0 +1,110 @@
|
|||
import NimQml
|
||||
|
||||
import ../../app_service/service/contacts/service as contact_service
|
||||
import ../../app_service/service/chat/service as chat_service
|
||||
import ../../app_service/service/community/service as community_service
|
||||
import ../modules/startup/module as startup_module
|
||||
import ../modules/main/module as main_module
|
||||
|
||||
import global_singleton
|
||||
|
||||
# This will be removed later:
|
||||
import status/status
|
||||
import ../../app_service/[main]
|
||||
# This to will be adapted to appropriate modules later:
|
||||
import ../onboarding/core as onboarding
|
||||
import ../login/core as login
|
||||
import status/types/[account]
|
||||
|
||||
type
|
||||
AppController* = ref object of RootObj
|
||||
# Services
|
||||
contactService: contact_service.Service
|
||||
chatService: chat_service.Service
|
||||
communityService: community_service.Service
|
||||
# Modules
|
||||
startupModule: startup_module.AccessInterface
|
||||
mainModule: main_module.AccessInterface
|
||||
|
||||
# This to will be adapted to appropriate modules later:
|
||||
status: Status
|
||||
appService: AppService
|
||||
login: LoginController
|
||||
onboarding: OnboardingController
|
||||
accountArgs: AccountArgs
|
||||
|
||||
#################################################
|
||||
# Forward declaration section
|
||||
proc load*(self: AppController)
|
||||
|
||||
# Startup Module Delegate Interface
|
||||
proc startupDidLoad*(self: AppController)
|
||||
|
||||
# Main Module Delegate Interface
|
||||
proc mainDidLoad*(self: AppController)
|
||||
#################################################
|
||||
|
||||
proc connect(self: AppController) =
|
||||
self.status.events.once("login") do(a: Args):
|
||||
self.accountArgs = AccountArgs(a)
|
||||
self.load()
|
||||
self.status.events.once("nodeStopped") do(a: Args):
|
||||
self.login.reset()
|
||||
self.onboarding.reset()
|
||||
|
||||
proc newAppController*(status: Status, appService: AppService): AppController =
|
||||
result = AppController()
|
||||
# Services
|
||||
result.contactService = contact_service.newService()
|
||||
result.chatService = chat_service.newService()
|
||||
result.communityService = community_service.newService()
|
||||
# Modules
|
||||
result.startupModule = startup_module.newModule[AppController](result)
|
||||
result.mainModule = main_module.newModule[AppController](result, result.communityService)
|
||||
|
||||
# Adding status and appService here now is just because of having a controll
|
||||
# over order of execution while we integrating this refactoring architecture
|
||||
# into the current app state.
|
||||
# Once we complete refactoring process we will get rid of "status" part/lib.
|
||||
#
|
||||
# This to will be adapted to appropriate modules later:
|
||||
result.status = status
|
||||
result.appService = appService
|
||||
result.login = login.newController(status, appService)
|
||||
result.onboarding = onboarding.newController(status)
|
||||
singletonInstance.engine.setRootContextProperty("loginModel", result.login.variant)
|
||||
singletonInstance.engine.setRootContextProperty("onboardingModel", result.onboarding.variant)
|
||||
result.connect()
|
||||
|
||||
proc delete*(self: AppController) =
|
||||
self.startupModule.delete
|
||||
self.mainModule.delete
|
||||
self.login.delete
|
||||
self.onboarding.delete
|
||||
|
||||
proc startupDidLoad*(self: AppController) =
|
||||
discard
|
||||
|
||||
proc mainDidLoad*(self: AppController) =
|
||||
# This to will be adapted to appropriate modules later:
|
||||
self.appService.onLoggedIn()
|
||||
|
||||
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
|
||||
self.login.reset()
|
||||
self.onboarding.reset()
|
||||
|
||||
self.login.moveToAppState()
|
||||
self.onboarding.moveToAppState()
|
||||
self.status.events.emit("loginCompleted", self.accountArgs)
|
||||
|
||||
proc start*(self: AppController) =
|
||||
self.login.init()
|
||||
self.onboarding.init()
|
||||
|
||||
proc load*(self: AppController) =
|
||||
self.contactService.init()
|
||||
self.chatService.init()
|
||||
self.communityService.init()
|
||||
|
||||
self.startupModule.load()
|
||||
self.mainModule.load()
|
|
@ -0,0 +1,18 @@
|
|||
import NimQml
|
||||
|
||||
type
|
||||
GlobalSingleton = object
|
||||
# Don't export GlobalSingleton type.
|
||||
# Other global things like local/global settings will be added here.
|
||||
|
||||
var singletonInstance* = GlobalSingleton()
|
||||
|
||||
proc engine*(self: GlobalSingleton): QQmlApplicationEngine =
|
||||
var qmlEngine {.global.}: QQmlApplicationEngine
|
||||
if (qmlEngine.isNil):
|
||||
qmlEngine = newQQmlApplicationEngine()
|
||||
|
||||
return qmlEngine
|
||||
|
||||
proc delete*(self: GlobalSingleton) =
|
||||
self.engine.delete()
|
|
@ -0,0 +1,18 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.chatSectionDidLoad()
|
|
@ -0,0 +1,21 @@
|
|||
import NimQml
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Item* = ref object of QObject
|
||||
|
||||
proc setup(self: Item) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: Item) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newItem*(): Item =
|
||||
new(result, delete)
|
||||
result.setup()
|
||||
|
||||
proc id*(self: Item): string {.slot.} =
|
||||
self.id
|
||||
|
||||
QtProperty[string] id:
|
||||
read = id
|
|
@ -0,0 +1,17 @@
|
|||
import NimQml
|
||||
import item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
sections: seq[Item]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete*(self: Model) =
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
|
@ -0,0 +1,25 @@
|
|||
import io_interface, view
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: DelegateInterface] = ref object of AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T): Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = newView()
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.view.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.chatSectionDidLoad()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
return self.moduleLoaded
|
|
@ -0,0 +1,19 @@
|
|||
import NimQml
|
||||
import model
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
model: Model
|
||||
|
||||
proc setup(self: View) =
|
||||
self.QObject.setup
|
||||
self.model = newModel()
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(): View =
|
||||
new(result, delete)
|
||||
result.setup()
|
|
@ -0,0 +1,35 @@
|
|||
import Tables
|
||||
|
||||
import controller_interface
|
||||
|
||||
import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
id: string
|
||||
communityService: community_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T,
|
||||
id: string,
|
||||
communityService: community_service.ServiceInterface):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.id = id
|
||||
result.communityService = communityService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method getId*(self: Controller): string =
|
||||
return self.id
|
||||
|
||||
method getCommunities*(self: Controller): seq[community_service.Dto] =
|
||||
return self.communityService.getCommunities()
|
|
@ -0,0 +1,24 @@
|
|||
import ../../../../app_service/service/community/service_interface as community_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getId*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCommunities*(self: AccessInterface): seq[community_service.Dto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.communitySectionDidLoad()
|
|
@ -0,0 +1,21 @@
|
|||
import NimQml
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Item* = ref object of QObject
|
||||
|
||||
proc setup(self: Item) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: Item) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newItem*(): Item =
|
||||
new(result, delete)
|
||||
result.setup()
|
||||
|
||||
proc id*(self: Item): string {.slot.} =
|
||||
self.id
|
||||
|
||||
QtProperty[string] id:
|
||||
read = id
|
|
@ -0,0 +1,17 @@
|
|||
import NimQml
|
||||
import item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
sections: seq[Item]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete*(self: Model) =
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
|
@ -0,0 +1,39 @@
|
|||
import NimQml
|
||||
import io_interface, view, controller
|
||||
|
||||
import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T, id: string,
|
||||
communityService: community_service.Service):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result, id, communityService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.communitySectionDidLoad()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
discard
|
|
@ -0,0 +1,22 @@
|
|||
import NimQml
|
||||
import model
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
|
@ -0,0 +1,29 @@
|
|||
import Tables
|
||||
|
||||
import controller_interface
|
||||
|
||||
import ../../../app_service/service/community/service as community_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
communityService: community_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T,
|
||||
communityService: community_service.ServiceInterface):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
result.communityService = communityService
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method getCommunities*[T](self: Controller[T]): seq[community_service.Dto] =
|
||||
return self.communityService.getCommunities()
|
|
@ -0,0 +1,21 @@
|
|||
import ../../../app_service/service/community/service_interface as community_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCommunities*(self: AccessInterface): seq[community_service.Dto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.mainDidLoad()
|
|
@ -0,0 +1,53 @@
|
|||
import json, strformat
|
||||
|
||||
type
|
||||
Item* = object
|
||||
id: string
|
||||
name: string
|
||||
image: string
|
||||
icon: string
|
||||
color: string
|
||||
mentionsCount: int
|
||||
unviewedMessagesCount: int
|
||||
|
||||
proc initItem*(id, name, image, icon, color: string,
|
||||
mentionsCount, unviewedMessagesCount: int): Item =
|
||||
result.id = id
|
||||
result.name = name
|
||||
result.image = image
|
||||
result.icon = icon
|
||||
result.color = color
|
||||
result.mentionsCount = mentionsCount
|
||||
result.unviewedMessagesCount = unviewedMessagesCount
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""MainModuleItem(
|
||||
id: {self.id},
|
||||
name: {self.name},
|
||||
image: {self.image},
|
||||
icon: {self.icon},
|
||||
color: {self.color},
|
||||
mentionsCount: {self.mentionsCount},
|
||||
unviewedMessagesCount:{self.unviewedMessagesCount}
|
||||
]"""
|
||||
|
||||
proc getId*(self: Item): string =
|
||||
return self.id
|
||||
|
||||
proc getName*(self: Item): string =
|
||||
return self.name
|
||||
|
||||
proc getImage*(self: Item): string =
|
||||
return self.image
|
||||
|
||||
proc getIcon*(self: Item): string =
|
||||
return self.icon
|
||||
|
||||
proc getColor*(self: Item): string =
|
||||
return self.color
|
||||
|
||||
proc getMentionsCount*(self: Item): int =
|
||||
return self.mentionsCount
|
||||
|
||||
proc getUnviewedMessagesCount*(self: Item): int =
|
||||
return self.unviewedMessagesCount
|
|
@ -0,0 +1,94 @@
|
|||
import NimQml, Tables, strutils, strformat
|
||||
|
||||
import item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Id = UserRole + 1
|
||||
Name
|
||||
Image
|
||||
Icon
|
||||
Color
|
||||
MentionsCount
|
||||
UnviewedMessagesCount
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
items: seq[Item]
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""
|
||||
[{i}]:({$self.items[i]})
|
||||
"""
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
|
||||
proc getCount(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Id.int:"id",
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.Image.int:"image",
|
||||
ModelRole.Icon.int:"icon",
|
||||
ModelRole.Color.int:"color",
|
||||
ModelRole.MentionsCount.int:"mentionsCount",
|
||||
ModelRole.UnviewedMessagesCount.int:"unviewedMessagesCount"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.items.len):
|
||||
return
|
||||
|
||||
let item = self.items[index.row]
|
||||
let enumRole = role.ModelRole
|
||||
|
||||
case enumRole:
|
||||
of ModelRole.Id:
|
||||
result = newQVariant(item.getId())
|
||||
of ModelRole.Name:
|
||||
result = newQVariant(item.getName())
|
||||
of ModelRole.Image:
|
||||
result = newQVariant(item.getImage())
|
||||
of ModelRole.Icon:
|
||||
result = newQVariant(item.getIcon())
|
||||
of ModelRole.Color:
|
||||
result = newQVariant(item.getColor())
|
||||
of ModelRole.MentionsCount:
|
||||
result = newQVariant(item.getMentionsCount())
|
||||
of ModelRole.UnviewedMessagesCount:
|
||||
result = newQVariant(item.getUnviewedMessagesCount())
|
||||
|
||||
proc addItem*(self: Model, item: Item) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
|
||||
self.items.add(item)
|
||||
self.endInsertRows()
|
||||
|
||||
self.countChanged()
|
|
@ -0,0 +1,97 @@
|
|||
import NimQml, Tables
|
||||
|
||||
import io_interface, view, controller, item
|
||||
import ../../../app/boot/global_singleton
|
||||
|
||||
import chat_section/module as chat_section_module
|
||||
import community_section/module as community_section_module
|
||||
|
||||
import ../../../app_service/service/community/service as community_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module*[T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
chatSectionModule: chat_section_module.AccessInterface
|
||||
communitySectionsModule: OrderedTable[string, community_section_module.AccessInterface]
|
||||
|
||||
#################################################
|
||||
# Forward declaration section
|
||||
|
||||
# Controller Delegate Interface
|
||||
|
||||
|
||||
# Chat Section Module Delegate Interface
|
||||
proc chatSectionDidLoad*[T](self: Module[T])
|
||||
|
||||
# Community Section Module Delegate Interface
|
||||
proc communitySectionDidLoad*[T](self: Module[T])
|
||||
|
||||
#################################################
|
||||
|
||||
proc newModule*[T](delegate: T,
|
||||
communityService: community_service.Service):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result, communityService)
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("mainModule", result.viewVariant)
|
||||
|
||||
# Submodules
|
||||
result.chatSectionModule = chat_section_module.newModule[Module[T]](result)
|
||||
result.communitySectionsModule = initOrderedTable[string, community_section_module.AccessInterface]()
|
||||
let communities = result.controller.getCommunities()
|
||||
for c in communities:
|
||||
result.communitySectionsModule[c.id] = community_section_module.newModule[Module[T]](result,
|
||||
c.id, communityService)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.chatSectionModule.delete
|
||||
for cModule in self.communitySectionsModule.values:
|
||||
cModule.delete
|
||||
self.communitySectionsModule.clear
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.view.load()
|
||||
|
||||
let chatSectionItem = initItem("chat", "Chat", "", "chat", "", 0, 0)
|
||||
self.view.addItem(chatSectionItem)
|
||||
|
||||
let communities = self.controller.getCommunities()
|
||||
for c in communities:
|
||||
self.view.addItem(initItem(c.id, c.name,
|
||||
if not c.images.isNil: c.images.thumbnail else: "",
|
||||
"", c.color, 0, 0))
|
||||
|
||||
self.chatSectionModule.load()
|
||||
for cModule in self.communitySectionsModule.values:
|
||||
cModule.load()
|
||||
|
||||
proc checkIfModuleDidLoad [T](self: Module[T]) =
|
||||
if(not self.chatSectionModule.isLoaded()):
|
||||
return
|
||||
|
||||
for cModule in self.communitySectionsModule.values:
|
||||
if(not cModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.delegate.mainDidLoad()
|
||||
|
||||
proc chatSectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
proc communitySectionDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
method viewDidLoad*[T](self: Module[T]) =
|
||||
discard
|
|
@ -0,0 +1,38 @@
|
|||
import NimQml
|
||||
import model, item
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
modelVariant: QVariant
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.modelVariant.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
result.modelVariant = newQVariant(result.model)
|
||||
|
||||
proc load*(self: View) =
|
||||
# In some point, here, we will setup some exposed main module related things.
|
||||
self.delegate.viewDidLoad()
|
||||
|
||||
proc addItem*(self: View, item: Item) =
|
||||
self.model.addItem(item)
|
||||
|
||||
proc modelChanged*(self: View) {.signal.}
|
||||
|
||||
proc getModel(self: View): QVariant {.slot.} =
|
||||
return self.modelVariant
|
||||
|
||||
QtProperty[QVariant] sectionsModel:
|
||||
read = getModel
|
||||
notify = modelChanged
|
|
@ -0,0 +1,22 @@
|
|||
import Tables
|
||||
|
||||
import controller_interface
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
|
||||
proc newController*[T](delegate: T):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
discard
|
|
@ -0,0 +1,16 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.startupDidLoad()
|
|
@ -0,0 +1,53 @@
|
|||
import json, strformat
|
||||
|
||||
type
|
||||
Item* = object
|
||||
id: string
|
||||
name: string
|
||||
image: string
|
||||
icon: string
|
||||
color: string
|
||||
mentionsCount: int
|
||||
unviewedMessagesCount: int
|
||||
|
||||
proc initItem*(id, name, image, icon, color: string,
|
||||
mentionsCount, unviewedMessagesCount: int): Item =
|
||||
result.id = id
|
||||
result.name = name
|
||||
result.image = image
|
||||
result.icon = icon
|
||||
result.color = color
|
||||
result.mentionsCount = mentionsCount
|
||||
result.unviewedMessagesCount = unviewedMessagesCount
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""MainModuleItem(
|
||||
id: {self.id},
|
||||
name: {self.name},
|
||||
image: {self.image},
|
||||
icon: {self.icon},
|
||||
color: {self.color},
|
||||
mentionsCount: {self.mentionsCount},
|
||||
unviewedMessagesCount:{self.unviewedMessagesCount}
|
||||
]"""
|
||||
|
||||
proc getId*(self: Item): string =
|
||||
return self.id
|
||||
|
||||
proc getName*(self: Item): string =
|
||||
return self.name
|
||||
|
||||
proc getImage*(self: Item): string =
|
||||
return self.image
|
||||
|
||||
proc getIcon*(self: Item): string =
|
||||
return self.icon
|
||||
|
||||
proc getColor*(self: Item): string =
|
||||
return self.color
|
||||
|
||||
proc getMentionsCount*(self: Item): int =
|
||||
return self.mentionsCount
|
||||
|
||||
proc getUnviewedMessagesCount*(self: Item): int =
|
||||
return self.unviewedMessagesCount
|
|
@ -0,0 +1,24 @@
|
|||
import Tables
|
||||
|
||||
import controller_interface
|
||||
|
||||
#import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
#communityService: community_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
discard
|
|
@ -0,0 +1,18 @@
|
|||
#import ../../../../app_service/service/community/service_interface as community_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.loginDidLoad()
|
|
@ -0,0 +1,21 @@
|
|||
import NimQml
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Item* = ref object of QObject
|
||||
|
||||
proc setup(self: Item) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: Item) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newItem*(): Item =
|
||||
new(result, delete)
|
||||
result.setup()
|
||||
|
||||
proc id*(self: Item): string {.slot.} =
|
||||
self.id
|
||||
|
||||
QtProperty[string] id:
|
||||
read = id
|
|
@ -0,0 +1,17 @@
|
|||
import NimQml
|
||||
import item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
sections: seq[Item]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete*(self: Model) =
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
|
@ -0,0 +1,38 @@
|
|||
import NimQml
|
||||
import io_interface, view, controller
|
||||
|
||||
#import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.loginDidLoad()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
discard
|
|
@ -0,0 +1,22 @@
|
|||
import NimQml
|
||||
import model
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
|
@ -0,0 +1,94 @@
|
|||
import NimQml, Tables, strutils, strformat
|
||||
|
||||
import item
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Id = UserRole + 1
|
||||
Name
|
||||
Image
|
||||
Icon
|
||||
Color
|
||||
MentionsCount
|
||||
UnviewedMessagesCount
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
items: seq[Item]
|
||||
|
||||
proc delete(self: Model) =
|
||||
self.items = @[]
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""
|
||||
[{i}]:({$self.items[i]})
|
||||
"""
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
|
||||
proc getCount(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
|
||||
QtProperty[int] count:
|
||||
read = getCount
|
||||
notify = countChanged
|
||||
|
||||
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||
return self.items.len
|
||||
|
||||
method roleNames(self: Model): Table[int, string] =
|
||||
{
|
||||
ModelRole.Id.int:"id",
|
||||
ModelRole.Name.int:"name",
|
||||
ModelRole.Image.int:"image",
|
||||
ModelRole.Icon.int:"icon",
|
||||
ModelRole.Color.int:"color",
|
||||
ModelRole.MentionsCount.int:"mentionsCount",
|
||||
ModelRole.UnviewedMessagesCount.int:"unviewedMessagesCount"
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
if (not index.isValid):
|
||||
return
|
||||
|
||||
if (index.row < 0 or index.row >= self.items.len):
|
||||
return
|
||||
|
||||
let item = self.items[index.row]
|
||||
let enumRole = role.ModelRole
|
||||
|
||||
case enumRole:
|
||||
of ModelRole.Id:
|
||||
result = newQVariant(item.getId())
|
||||
of ModelRole.Name:
|
||||
result = newQVariant(item.getName())
|
||||
of ModelRole.Image:
|
||||
result = newQVariant(item.getImage())
|
||||
of ModelRole.Icon:
|
||||
result = newQVariant(item.getIcon())
|
||||
of ModelRole.Color:
|
||||
result = newQVariant(item.getColor())
|
||||
of ModelRole.MentionsCount:
|
||||
result = newQVariant(item.getMentionsCount())
|
||||
of ModelRole.UnviewedMessagesCount:
|
||||
result = newQVariant(item.getUnviewedMessagesCount())
|
||||
|
||||
proc addItem*(self: Model, item: Item) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginInsertRows(parentModelIndex, self.items.len, self.items.len)
|
||||
self.items.add(item)
|
||||
self.endInsertRows()
|
||||
|
||||
self.countChanged()
|
|
@ -0,0 +1,76 @@
|
|||
import NimQml
|
||||
|
||||
import io_interface, view, controller
|
||||
import ../../../app/boot/global_singleton
|
||||
|
||||
import onboarding/module as onboarding_module
|
||||
import login/module as login_module
|
||||
|
||||
#import ../../../app_service/service/community/service as community_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module*[T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
onboardingModule: onboarding_module.AccessInterface
|
||||
loginModule: login_module.AccessInterface
|
||||
|
||||
#################################################
|
||||
# Forward declaration section
|
||||
|
||||
# Controller Delegate Interface
|
||||
|
||||
|
||||
# Onboarding Module Delegate Interface
|
||||
proc onboardingDidLoad*[T](self: Module[T])
|
||||
|
||||
# Login Module Delegate Interface
|
||||
proc loginDidLoad*[T](self: Module[T])
|
||||
|
||||
#################################################
|
||||
|
||||
proc newModule*[T](delegate: T):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result)
|
||||
|
||||
singletonInstance.engine.setRootContextProperty("startupModule", result.viewVariant)
|
||||
|
||||
# Submodules
|
||||
result.onboardingModule = onboarding_module.newModule[Module[T]](result)
|
||||
result.loginModule = login_module.newModule[Module[T]](result)
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.onboardingModule.delete
|
||||
self.loginModule.delete
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.view.load()
|
||||
|
||||
method viewDidLoad*[T](self: Module[T]) =
|
||||
discard
|
||||
|
||||
proc checkIfModuleDidLoad[T](self: Module[T]) =
|
||||
if(not self.onboardingModule.isLoaded()):
|
||||
return
|
||||
|
||||
if(not self.loginModule.isLoaded()):
|
||||
return
|
||||
|
||||
self.delegate.startupDidLoad()
|
||||
|
||||
proc onboardingDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
||||
|
||||
proc loginDidLoad*[T](self: Module[T]) =
|
||||
self.checkIfModuleDidLoad()
|
|
@ -0,0 +1,24 @@
|
|||
import Tables
|
||||
|
||||
import controller_interface
|
||||
|
||||
#import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export controller_interface
|
||||
|
||||
type
|
||||
Controller*[T: controller_interface.DelegateInterface] =
|
||||
ref object of controller_interface.AccessInterface
|
||||
delegate: T
|
||||
#communityService: community_service.ServiceInterface
|
||||
|
||||
proc newController*[T](delegate: T):
|
||||
Controller[T] =
|
||||
result = Controller[T]()
|
||||
result.delegate = delegate
|
||||
|
||||
method delete*[T](self: Controller[T]) =
|
||||
discard
|
||||
|
||||
method init*[T](self: Controller[T]) =
|
||||
discard
|
|
@ -0,0 +1,18 @@
|
|||
#import ../../../../app_service/service/community/service_interface as community_service
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for any input/interaction with this module.
|
||||
|
||||
method delete*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method load*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
# View Delegate Interface
|
||||
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||
# inheritance, which is not well supported in Nim.
|
||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
type
|
||||
## Abstract class (concept) which must be implemented by object/s used in this
|
||||
## module.
|
||||
DelegateInterface* = concept c
|
||||
c.onboardingDidLoad()
|
|
@ -0,0 +1,21 @@
|
|||
import NimQml
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Item* = ref object of QObject
|
||||
|
||||
proc setup(self: Item) =
|
||||
self.QObject.setup
|
||||
|
||||
proc delete*(self: Item) =
|
||||
self.QObject.delete
|
||||
|
||||
proc newItem*(): Item =
|
||||
new(result, delete)
|
||||
result.setup()
|
||||
|
||||
proc id*(self: Item): string {.slot.} =
|
||||
self.id
|
||||
|
||||
QtProperty[string] id:
|
||||
read = id
|
|
@ -0,0 +1,17 @@
|
|||
import NimQml
|
||||
import item
|
||||
|
||||
QtObject:
|
||||
type
|
||||
Model* = ref object of QAbstractListModel
|
||||
sections: seq[Item]
|
||||
|
||||
proc setup(self: Model) =
|
||||
self.QAbstractListModel.setup
|
||||
|
||||
proc delete*(self: Model) =
|
||||
self.QAbstractListModel.delete
|
||||
|
||||
proc newModel*(): Model =
|
||||
new(result, delete)
|
||||
result.setup
|
|
@ -0,0 +1,38 @@
|
|||
import NimQml
|
||||
import io_interface, view, controller
|
||||
|
||||
#import ../../../../app_service/service/community/service as community_service
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
|
||||
delegate: T
|
||||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: controller.AccessInterface
|
||||
moduleLoaded: bool
|
||||
|
||||
proc newModule*[T](delegate: T):
|
||||
Module[T] =
|
||||
result = Module[T]()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController[Module[T]](result)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*[T](self: Module[T]) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
self.controller.delete
|
||||
|
||||
method load*[T](self: Module[T]) =
|
||||
self.moduleLoaded = true
|
||||
self.delegate.onboardingDidLoad()
|
||||
|
||||
method isLoaded*[T](self: Module[T]): bool =
|
||||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
discard
|
|
@ -0,0 +1,22 @@
|
|||
import NimQml
|
||||
import model
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
|
||||
proc load*(self: View) =
|
||||
self.delegate.viewDidLoad()
|
|
@ -0,0 +1,26 @@
|
|||
import NimQml
|
||||
import model, item
|
||||
import io_interface
|
||||
|
||||
QtObject:
|
||||
type
|
||||
View* = ref object of QObject
|
||||
delegate: io_interface.AccessInterface
|
||||
model: Model
|
||||
modelVariant: QVariant
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
self.modelVariant.delete
|
||||
self.QObject.delete
|
||||
|
||||
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||
new(result, delete)
|
||||
result.QObject.setup
|
||||
result.delegate = delegate
|
||||
result.model = newModel()
|
||||
result.modelVariant = newQVariant(result.model)
|
||||
|
||||
proc load*(self: View) =
|
||||
# In some point, here, we will setup some exposed main module related things.
|
||||
self.delegate.viewDidLoad()
|
|
@ -0,0 +1,49 @@
|
|||
import json
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[int]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop].getInt
|
||||
success = true
|
||||
|
||||
success
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[int64]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop].getBiggestInt
|
||||
success = true
|
||||
|
||||
success
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[string]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop].getStr
|
||||
success = true
|
||||
|
||||
success
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[float]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop].getFloat
|
||||
success = true
|
||||
|
||||
success
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[bool]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop].getBool
|
||||
success = true
|
||||
|
||||
success
|
||||
|
||||
template getProp(obj: JsonNode, prop: string, value: var typedesc[JsonNode]): bool =
|
||||
var success = false
|
||||
if (obj.kind == JObject and obj.contains(prop)):
|
||||
value = obj[prop]
|
||||
success = true
|
||||
|
||||
success
|
|
@ -0,0 +1,95 @@
|
|||
{.used.}
|
||||
|
||||
import json, strformat
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
type ChatType* {.pure.}= enum
|
||||
Unknown = 0,
|
||||
OneToOne = 1,
|
||||
Public = 2,
|
||||
PrivateGroupChat = 3,
|
||||
Profile = 4,
|
||||
Timeline = 5
|
||||
CommunityChat = 6
|
||||
|
||||
type Dto* = 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
|
||||
name*: string
|
||||
description*: string
|
||||
color*: string
|
||||
emoji*: string # not sure why do we receive this at all?
|
||||
active*: bool # indicates whether the chat has been soft deleted
|
||||
chatType*: ChatType
|
||||
timestamp*: int64 # indicates the last time this chat has received/sent a message
|
||||
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 ???? It's a question why do we need it here within this context ????
|
||||
#members*: seq[ChatMember] ???? It's always null and a question why do we need it here within this context ????
|
||||
#membershipUpdateEvents*: seq[ChatMembershipEvent] ???? It's always null and a question why do we need it here within this context ????
|
||||
alias*: string
|
||||
identicon*: string
|
||||
muted*: bool
|
||||
communityId*: string #set if chat belongs to a community
|
||||
profile*: string
|
||||
joined*: int64 # indicates when the user joined the chat last time
|
||||
syncedTo*: int64
|
||||
syncedFrom*: int64
|
||||
|
||||
proc `$`*(self: Dto): string =
|
||||
result = fmt"""ChatDto(
|
||||
id: {self.id},
|
||||
name: {self.name},
|
||||
description: {self.description},
|
||||
color: {self.color},
|
||||
emoji: {self.emoji},
|
||||
active: {self.active},
|
||||
chatType: {self.chatType},
|
||||
timestamp: {self.timestamp},
|
||||
lastClockValue: {self.lastClockValue},
|
||||
deletedAtClockValue: {self.deletedAtClockValue},
|
||||
unviewedMessagesCount: {self.unviewedMessagesCount},
|
||||
unviewedMentionsCount: {self.unviewedMentionsCount},
|
||||
alias: {self.alias},
|
||||
identicon: {self.identicon},
|
||||
muted: {self.muted},
|
||||
communityId: {self.communityId},
|
||||
profile: {self.profile},
|
||||
joined: {self.joined},
|
||||
syncedTo: {self.syncedTo},
|
||||
syncedFrom: {self.syncedFrom}
|
||||
)"""
|
||||
|
||||
proc toDto*(jsonObj: JsonNode): Dto =
|
||||
result = Dto()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("color", result.color)
|
||||
discard jsonObj.getProp("emoji", result.emoji)
|
||||
discard jsonObj.getProp("active", result.active)
|
||||
|
||||
result.chatType = ChatType.Unknown
|
||||
var chatTypeInt: int
|
||||
if (jsonObj.getProp("chatType", chatTypeInt) and
|
||||
(chatTypeInt >= ord(low(ChatType)) or chatTypeInt <= ord(high(ChatType)))):
|
||||
result.chatType = ChatType(chatTypeInt)
|
||||
|
||||
discard jsonObj.getProp("timestamp", result.timestamp)
|
||||
discard jsonObj.getProp("lastClockValue", result.lastClockValue)
|
||||
discard jsonObj.getProp("deletedAtClockValue", result.deletedAtClockValue)
|
||||
discard jsonObj.getProp("unviewedMessagesCount", result.unviewedMessagesCount)
|
||||
discard jsonObj.getProp("unviewedMentionsCount", result.unviewedMentionsCount)
|
||||
discard jsonObj.getProp("alias", result.alias)
|
||||
discard jsonObj.getProp("identicon", result.identicon)
|
||||
discard jsonObj.getProp("muted", result.muted)
|
||||
discard jsonObj.getProp("communityId", result.communityId)
|
||||
discard jsonObj.getProp("profile", result.profile)
|
||||
discard jsonObj.getProp("joined", result.joined)
|
||||
discard jsonObj.getProp("syncedTo", result.syncedTo)
|
||||
discard jsonObj.getProp("syncedFrom", result.syncedFrom)
|
|
@ -0,0 +1,36 @@
|
|||
import Tables, json, sequtils, strformat, chronicles
|
||||
|
||||
import service_interface, dto
|
||||
import status/statusgo_backend_new/chat as status_go
|
||||
|
||||
export service_interface
|
||||
|
||||
logScope:
|
||||
topics = "chat-service"
|
||||
|
||||
type
|
||||
Service* = ref object of ServiceInterface
|
||||
chats: Table[string, Dto] # [chat_id, Dto]
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): Service =
|
||||
result = Service()
|
||||
result.chats = initTable[string, Dto]()
|
||||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
let response = status_go.getChats()
|
||||
|
||||
let chats = map(response.result.getElems(),
|
||||
proc(x: JsonNode): Dto = x.toDto())
|
||||
|
||||
for chat in chats:
|
||||
if chat.active and chat.chatType != ChatType.Unknown:
|
||||
self.chats[chat.id] = chat
|
||||
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
|
@ -0,0 +1,13 @@
|
|||
import dto
|
||||
|
||||
export dto
|
||||
|
||||
type
|
||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for this service access.
|
||||
|
||||
method delete*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,142 @@
|
|||
{.used.}
|
||||
|
||||
import json, strformat
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
type
|
||||
Permission* = ref object
|
||||
access*: int
|
||||
|
||||
type
|
||||
Images* = ref object
|
||||
thumbnail*: string
|
||||
large*: string
|
||||
|
||||
type Chat* = ref object
|
||||
id*: string
|
||||
name*: string
|
||||
color*: string
|
||||
emoji*: string
|
||||
description*: string
|
||||
#members*: seq[ChatMember] ???? It's always null and a question why do we need it here within this context ????
|
||||
permissions*: Permission
|
||||
canPost*: bool
|
||||
position*: int
|
||||
categoryId*: string
|
||||
|
||||
type Category* = ref object
|
||||
id*: string
|
||||
name*: string
|
||||
position*: int
|
||||
|
||||
type Member* = ref object
|
||||
id*: string
|
||||
roles*: seq[int]
|
||||
|
||||
type Dto* = ref object
|
||||
id*: string
|
||||
admin*: bool
|
||||
verified*: bool
|
||||
joined*: bool
|
||||
requestedAccessAt: int64
|
||||
name*: string
|
||||
description*: string
|
||||
chats*: seq[Chat]
|
||||
categories*: seq[Category]
|
||||
images*: Images
|
||||
permissions*: Permission
|
||||
members*: seq[Member]
|
||||
canRequestAccess*: bool
|
||||
canManageUsers*: bool
|
||||
canJoin*: bool
|
||||
color*: string
|
||||
requestedToJoinAt*: int64
|
||||
isMember*: bool
|
||||
muted*: bool
|
||||
|
||||
proc toPermission(jsonObj: JsonNode): Permission =
|
||||
result = Permission()
|
||||
discard jsonObj.getProp("access", result.access)
|
||||
|
||||
proc toImages(jsonObj: JsonNode): Images =
|
||||
result = Images()
|
||||
|
||||
var largeObj: JsonNode
|
||||
if(jsonObj.getProp("large", largeObj)):
|
||||
discard largeObj.getProp("uri", result.large)
|
||||
|
||||
var thumbnailObj: JsonNode
|
||||
if(jsonObj.getProp("thumbnail", thumbnailObj)):
|
||||
discard thumbnailObj.getProp("uri", result.thumbnail)
|
||||
|
||||
proc toChat(jsonObj: JsonNode): Chat =
|
||||
result = Chat()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("color", result.color)
|
||||
discard jsonObj.getProp("emoji", result.emoji)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
var permissionObj: JsonNode
|
||||
if(jsonObj.getProp("permissions", permissionObj)):
|
||||
result.permissions = toPermission(permissionObj)
|
||||
discard jsonObj.getProp("canPost", result.canPost)
|
||||
discard jsonObj.getProp("position", result.position)
|
||||
discard jsonObj.getProp("categoryId", result.categoryId)
|
||||
|
||||
proc toCategory(jsonObj: JsonNode): Category =
|
||||
result = Category()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("position", result.position)
|
||||
|
||||
proc toMember(jsonObj: JsonNode, memberId: string): Member =
|
||||
# Mapping this DTO is not strightforward since only keys are used for id. We
|
||||
# handle it a bit different.
|
||||
result = Member()
|
||||
result.id = memberId
|
||||
var rolesObj: JsonNode
|
||||
if(jsonObj.getProp("roles", rolesObj)):
|
||||
for roleObj in rolesObj:
|
||||
result.roles.add(roleObj.getInt)
|
||||
|
||||
proc toDto*(jsonObj: JsonNode): Dto =
|
||||
result = Dto()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("admin", result.admin)
|
||||
discard jsonObj.getProp("verified", result.verified)
|
||||
discard jsonObj.getProp("joined", result.joined)
|
||||
discard jsonObj.getProp("requestedAccessAt", result.requestedAccessAt)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
|
||||
var chatsObj: JsonNode
|
||||
if(jsonObj.getProp("chats", chatsObj)):
|
||||
for _, chatObj in chatsObj:
|
||||
result.chats.add(toChat(chatObj))
|
||||
|
||||
var categoriesObj: JsonNode
|
||||
if(jsonObj.getProp("categories", categoriesObj)):
|
||||
for _, categoryObj in categoriesObj:
|
||||
result.categories.add(toCategory(categoryObj))
|
||||
|
||||
var imagesObj: JsonNode
|
||||
if(jsonObj.getProp("images", imagesObj)):
|
||||
result.images = toImages(imagesObj)
|
||||
|
||||
var permissionObj: JsonNode
|
||||
if(jsonObj.getProp("permissions", permissionObj)):
|
||||
result.permissions = toPermission(permissionObj)
|
||||
|
||||
var membersObj: JsonNode
|
||||
if(jsonObj.getProp("members", membersObj)):
|
||||
for memberId, memberObj in membersObj:
|
||||
result.members.add(toMember(memberObj, memberId))
|
||||
|
||||
discard jsonObj.getProp("canRequestAccess", result.canRequestAccess)
|
||||
discard jsonObj.getProp("canManageUsers", result.canManageUsers)
|
||||
discard jsonObj.getProp("canJoin", result.canJoin)
|
||||
discard jsonObj.getProp("color", result.color)
|
||||
discard jsonObj.getProp("requestedToJoinAt", result.requestedToJoinAt)
|
||||
discard jsonObj.getProp("isMember", result.isMember)
|
||||
discard jsonObj.getProp("muted", result.muted)
|
|
@ -0,0 +1,38 @@
|
|||
import Tables, json, sequtils, strformat, chronicles
|
||||
|
||||
import service_interface, dto
|
||||
import status/statusgo_backend_new/communities as status_go
|
||||
|
||||
export service_interface
|
||||
|
||||
logScope:
|
||||
topics = "community-service"
|
||||
|
||||
type
|
||||
Service* = ref object of ServiceInterface
|
||||
communities: Table[string, Dto] # [community_id, Dto]
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): Service =
|
||||
result = Service()
|
||||
result.communities = initTable[string, Dto]()
|
||||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
let response = status_go.getJoinedComunities()
|
||||
|
||||
let communities = map(response.result.getElems(),
|
||||
proc(x: JsonNode): Dto = x.toDto())
|
||||
|
||||
for community in communities:
|
||||
self.communities[community.id] = community
|
||||
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
||||
|
||||
method getCommunities*(self: Service): seq[Dto] =
|
||||
return toSeq(self.communities.values)
|
|
@ -0,0 +1,16 @@
|
|||
import dto
|
||||
|
||||
export dto
|
||||
|
||||
type
|
||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for this service access.
|
||||
|
||||
method delete*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getCommunities*(self: ServiceInterface): seq[Dto] {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,78 @@
|
|||
{.used.}
|
||||
|
||||
import json, strformat
|
||||
|
||||
include ../../common/json_utils
|
||||
|
||||
type
|
||||
Images* = ref object
|
||||
thumbnail*: string
|
||||
large*: string
|
||||
|
||||
type Dto* = ref object
|
||||
id*: string
|
||||
name*: string
|
||||
ensVerified*: bool
|
||||
alias: string
|
||||
identicon*: string
|
||||
lastUpdated*: int64
|
||||
image*: Images
|
||||
added*: bool
|
||||
blocked*: bool
|
||||
hasAddedUs*: bool
|
||||
isSyncing*: bool
|
||||
removed: bool
|
||||
|
||||
proc `$`(self: Images): string =
|
||||
result = fmt"""Images(
|
||||
thumbnail: {self.thumbnail},
|
||||
large: {self.large},
|
||||
]"""
|
||||
|
||||
proc `$`*(self: Dto): string =
|
||||
result = fmt"""ContactDto(
|
||||
id: {self.id},
|
||||
name: {self.name},
|
||||
ensVerified: {self.ensVerified},
|
||||
alias: {self.alias},
|
||||
identicon: {self.identicon},
|
||||
lastUpdated: {self.lastUpdated},
|
||||
image:[
|
||||
{$self.image}
|
||||
],
|
||||
added:{self.added}
|
||||
blocked:{self.blocked}
|
||||
hasAddedUs:{self.hasAddedUs}
|
||||
isSyncing:{self.isSyncing}
|
||||
removed:{self.removed}
|
||||
)"""
|
||||
|
||||
proc toImages(jsonObj: JsonNode): Images =
|
||||
result = Images()
|
||||
|
||||
var largeObj: JsonNode
|
||||
if(jsonObj.getProp("large", largeObj)):
|
||||
discard jsonObj.getProp("uri", result.large)
|
||||
|
||||
var thumbnailObj: JsonNode
|
||||
if(jsonObj.getProp("thumbnail", thumbnailObj)):
|
||||
discard jsonObj.getProp("uri", result.thumbnail)
|
||||
|
||||
proc toDto*(jsonObj: JsonNode): Dto =
|
||||
result = Dto()
|
||||
discard jsonObj.getProp("id", result.id)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("ensVerified", result.ensVerified)
|
||||
discard jsonObj.getProp("alias", result.alias)
|
||||
discard jsonObj.getProp("identicon", result.identicon)
|
||||
discard jsonObj.getProp("lastUpdated", result.lastUpdated)
|
||||
|
||||
var imageObj: JsonNode
|
||||
if(jsonObj.getProp("images", imageObj)):
|
||||
result.image = toImages(imageObj)
|
||||
|
||||
discard jsonObj.getProp("added", result.added)
|
||||
discard jsonObj.getProp("blocked", result.blocked)
|
||||
discard jsonObj.getProp("hasAddedUs", result.hasAddedUs)
|
||||
discard jsonObj.getProp("IsSyncing", result.isSyncing)
|
||||
discard jsonObj.getProp("Removed", result.removed)
|
|
@ -0,0 +1,35 @@
|
|||
import Tables, json, sequtils, strformat, chronicles
|
||||
|
||||
import service_interface, dto
|
||||
import status/statusgo_backend_new/contacts as status_go
|
||||
|
||||
export service_interface
|
||||
|
||||
logScope:
|
||||
topics = "contacts-service"
|
||||
|
||||
type
|
||||
Service* = ref object of ServiceInterface
|
||||
contacts: Table[string, Dto] # [contact_id, Dto]
|
||||
|
||||
method delete*(self: Service) =
|
||||
discard
|
||||
|
||||
proc newService*(): Service =
|
||||
result = Service()
|
||||
result.contacts = initTable[string, Dto]()
|
||||
|
||||
method init*(self: Service) =
|
||||
try:
|
||||
let response = status_go.getContacts()
|
||||
|
||||
let contacts = map(response.result.getElems(),
|
||||
proc(x: JsonNode): Dto = x.toDto())
|
||||
|
||||
for contact in contacts:
|
||||
self.contacts[contact.id] = contact
|
||||
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error: ", errDesription
|
||||
return
|
|
@ -0,0 +1,13 @@
|
|||
import dto
|
||||
|
||||
export dto
|
||||
|
||||
type
|
||||
ServiceInterface* {.pure inheritable.} = ref object of RootObj
|
||||
## Abstract class for this service access.
|
||||
|
||||
method delete*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method init*(self: ServiceInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
|
@ -8,8 +8,6 @@ import app/utilsView/core as utilsView
|
|||
import app/browser/core as browserView
|
||||
import app/profile/core as profile
|
||||
import app/profile/view
|
||||
import app/onboarding/core as onboarding
|
||||
import app/login/core as login
|
||||
import app/provider/core as provider
|
||||
import app/keycard/core as keycard
|
||||
import status/types/[account]
|
||||
|
@ -21,6 +19,10 @@ import app_service/tasks/marathon/mailserver/worker as mailserver_worker
|
|||
import app_service/main
|
||||
import constants
|
||||
|
||||
import app/boot/global_singleton
|
||||
import app/boot/app_controller
|
||||
|
||||
|
||||
var signalsQObjPointer: pointer
|
||||
|
||||
logScope:
|
||||
|
@ -58,6 +60,9 @@ proc mainProc() =
|
|||
let app = newQGuiApplication()
|
||||
defer: app.delete()
|
||||
|
||||
let appController = newAppController(status, appService)
|
||||
defer: appController.delete()
|
||||
|
||||
let resources =
|
||||
if defined(windows) and defined(production):
|
||||
"/../resources/resources.rcc"
|
||||
|
@ -103,22 +108,23 @@ proc mainProc() =
|
|||
|
||||
let networkAccessFactory = newQNetworkAccessManagerFactory(TMPDIR & "netcache")
|
||||
|
||||
let engine = newQQmlApplicationEngine()
|
||||
defer: engine.delete()
|
||||
engine.addImportPath("qrc:/./StatusQ/src")
|
||||
engine.addImportPath("qrc:/./imports")
|
||||
engine.setNetworkAccessManagerFactory(networkAccessFactory)
|
||||
engine.setRootContextProperty("uiScaleFilePath", newQVariant(uiScaleFilePath))
|
||||
|
||||
#let engine = newQQmlApplicationEngine()
|
||||
#defer: engine.delete()
|
||||
singletonInstance.engine.addImportPath("qrc:/./StatusQ/src")
|
||||
singletonInstance.engine.addImportPath("qrc:/./imports")
|
||||
singletonInstance.engine.setNetworkAccessManagerFactory(networkAccessFactory)
|
||||
singletonInstance.engine.setRootContextProperty("uiScaleFilePath", newQVariant(uiScaleFilePath))
|
||||
|
||||
# Register events objects
|
||||
let dockShowAppEvent = newStatusDockShowAppEventObject(engine)
|
||||
let dockShowAppEvent = newStatusDockShowAppEventObject(singletonInstance.engine)
|
||||
defer: dockShowAppEvent.delete()
|
||||
let osThemeEvent = newStatusOSThemeEventObject(engine)
|
||||
let osThemeEvent = newStatusOSThemeEventObject(singletonInstance.engine)
|
||||
defer: osThemeEvent.delete()
|
||||
app.installEventFilter(dockShowAppEvent)
|
||||
app.installEventFilter(osThemeEvent)
|
||||
|
||||
let netAccMgr = newQNetworkAccessManager(engine.getNetworkAccessManager())
|
||||
let netAccMgr = newQNetworkAccessManager(singletonInstance.engine.getNetworkAccessManager())
|
||||
|
||||
status.events.on("network:connected") do(e: Args):
|
||||
# This is a workaround for Qt bug https://bugreports.qt.io/browse/QTBUG-55180
|
||||
|
@ -152,47 +158,43 @@ proc mainProc() =
|
|||
|
||||
var wallet = wallet.newController(status, appService)
|
||||
defer: wallet.delete()
|
||||
engine.setRootContextProperty("walletModel", wallet.variant)
|
||||
singletonInstance.engine.setRootContextProperty("walletModel", wallet.variant)
|
||||
|
||||
var wallet2 = walletV2.newController(status, appService)
|
||||
defer: wallet2.delete()
|
||||
engine.setRootContextProperty("walletV2Model", wallet2.variant)
|
||||
singletonInstance.engine.setRootContextProperty("walletV2Model", wallet2.variant)
|
||||
|
||||
var chat = chat.newController(status, appService, OPENURI)
|
||||
defer: chat.delete()
|
||||
engine.setRootContextProperty("chatsModel", chat.variant)
|
||||
singletonInstance.engine.setRootContextProperty("chatsModel", chat.variant)
|
||||
|
||||
var node = node.newController(status, appService, netAccMgr)
|
||||
defer: node.delete()
|
||||
engine.setRootContextProperty("nodeModel", node.variant)
|
||||
singletonInstance.engine.setRootContextProperty("nodeModel", node.variant)
|
||||
|
||||
var utilsController = utilsView.newController(status, appService)
|
||||
defer: utilsController.delete()
|
||||
engine.setRootContextProperty("utilsModel", utilsController.variant)
|
||||
singletonInstance.engine.setRootContextProperty("utilsModel", utilsController.variant)
|
||||
|
||||
var browserController = browserView.newController(status)
|
||||
defer: browserController.delete()
|
||||
engine.setRootContextProperty("browserModel", browserController.variant)
|
||||
singletonInstance.engine.setRootContextProperty("browserModel", browserController.variant)
|
||||
|
||||
proc changeLanguage(locale: string) =
|
||||
if (locale == currentLanguageCode):
|
||||
return
|
||||
currentLanguageCode = locale
|
||||
let shouldRetranslate = not defined(linux)
|
||||
engine.setTranslationPackage(joinPath(i18nPath, fmt"qml_{locale}.qm"), shouldRetranslate)
|
||||
singletonInstance.engine.setTranslationPackage(joinPath(i18nPath, fmt"qml_{locale}.qm"), shouldRetranslate)
|
||||
|
||||
var profile = profile.newController(status, appService, changeLanguage)
|
||||
defer: profile.delete()
|
||||
engine.setRootContextProperty("profileModel", profile.variant)
|
||||
singletonInstance.engine.setRootContextProperty("profileModel", profile.variant)
|
||||
|
||||
var provider = provider.newController(status)
|
||||
defer: provider.delete()
|
||||
engine.setRootContextProperty("web3Provider", provider.variant)
|
||||
singletonInstance.engine.setRootContextProperty("web3Provider", provider.variant)
|
||||
|
||||
var login = login.newController(status, appService)
|
||||
defer: login.delete()
|
||||
var onboarding = onboarding.newController(status)
|
||||
defer: onboarding.delete()
|
||||
var keycard = keycard.newController(status)
|
||||
defer: keycard.delete()
|
||||
|
||||
|
@ -203,18 +205,6 @@ proc mainProc() =
|
|||
var args = AccountArgs(a)
|
||||
onAccountChanged(args.account)
|
||||
|
||||
status.events.once("login") do(a: Args):
|
||||
var args = AccountArgs(a)
|
||||
appService.onLoggedIn()
|
||||
|
||||
# Reset login and onboarding to remove any mnemonic that would have been saved in the accounts list
|
||||
login.reset()
|
||||
onboarding.reset()
|
||||
|
||||
login.moveToAppState()
|
||||
onboarding.moveToAppState()
|
||||
status.events.emit("loginCompleted", args)
|
||||
|
||||
status.events.once("loginCompleted") do(a: Args):
|
||||
var args = AccountArgs(a)
|
||||
|
||||
|
@ -234,33 +224,30 @@ proc mainProc() =
|
|||
# this should be the last defer in the scope
|
||||
defer:
|
||||
info "Status app is shutting down..."
|
||||
singletonInstance.delete()
|
||||
|
||||
engine.setRootContextProperty("loginModel", login.variant)
|
||||
engine.setRootContextProperty("onboardingModel", onboarding.variant)
|
||||
engine.setRootContextProperty("keycardModel", keycard.variant)
|
||||
engine.setRootContextProperty("singleInstance", newQVariant(singleInstance))
|
||||
singletonInstance.engine.setRootContextProperty("keycardModel", keycard.variant)
|
||||
singletonInstance.engine.setRootContextProperty("singleInstance", newQVariant(singleInstance))
|
||||
|
||||
let isExperimental = if getEnv("EXPERIMENTAL") == "1": "1" else: "0" # value explicity passed to avoid trusting input
|
||||
let experimentalFlag = newQVariant(isExperimental)
|
||||
engine.setRootContextProperty("isExperimental", experimentalFlag)
|
||||
singletonInstance.engine.setRootContextProperty("isExperimental", experimentalFlag)
|
||||
|
||||
# Initialize only controllers whose init functions
|
||||
# do not need a running node
|
||||
proc initControllers() =
|
||||
login.init()
|
||||
onboarding.init()
|
||||
keycard.init()
|
||||
|
||||
initControllers()
|
||||
|
||||
appController.start()
|
||||
|
||||
# Handle node.stopped signal when user has logged out
|
||||
status.events.once("nodeStopped") do(a: Args):
|
||||
# TODO: remove this once accounts are not tracked in the AccountsModel
|
||||
status.reset()
|
||||
|
||||
# 1. Reset controller data
|
||||
login.reset()
|
||||
onboarding.reset()
|
||||
# TODO: implement all controller resets
|
||||
# chat.reset()
|
||||
# node.reset()
|
||||
|
@ -271,18 +258,18 @@ proc mainProc() =
|
|||
# 2. Re-init controllers that don't require a running node
|
||||
initControllers()
|
||||
|
||||
engine.setRootContextProperty("signals", appService.signalController.variant)
|
||||
engine.setRootContextProperty("mailserver", mailserverController.variant)
|
||||
singletonInstance.engine.setRootContextProperty("signals", appService.signalController.variant)
|
||||
singletonInstance.engine.setRootContextProperty("mailserver", mailserverController.variant)
|
||||
|
||||
var prValue = newQVariant(if defined(production): true else: false)
|
||||
engine.setRootContextProperty("production", prValue)
|
||||
singletonInstance.engine.setRootContextProperty("production", prValue)
|
||||
|
||||
# We're applying default language before we load qml. Also we're aware that
|
||||
# switch language at runtime will have some impact to cpu usage.
|
||||
# https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-linguist-programmers.html
|
||||
changeLanguage("en")
|
||||
|
||||
engine.load(newQUrl("qrc:///main.qml"))
|
||||
singletonInstance.engine.load(newQUrl("qrc:///main.qml"))
|
||||
|
||||
# Please note that this must use the `cdecl` calling convention because
|
||||
# it will be passed as a regular C function to statusgo_backend. This means that
|
||||
|
|
|
@ -164,15 +164,24 @@ StatusAppThreePanelLayout {
|
|||
sourceComponent: appSettings.communitiesEnabled && root.rootStore.chatsModelInst.communities.activeCommunity.active ? communtiyColumnComponent : contactsColumnComponent
|
||||
}
|
||||
|
||||
centerPanel: ChatColumnView {
|
||||
// centerPanel: ChatColumn {
|
||||
// id: chatColumn
|
||||
// chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount
|
||||
// }
|
||||
|
||||
centerPanel: Rectangle {
|
||||
id: chatColumn
|
||||
rootStore: root.rootStore
|
||||
chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount
|
||||
anchors.fill: parent
|
||||
color: "green"
|
||||
}
|
||||
|
||||
showRightPanel: (appSettings.expandUsersList && (appSettings.showOnlineUsers || root.rootStore.chatsModelInst.communities.activeCommunity.active)
|
||||
&& (root.rootStore.chatsModelInst.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne))
|
||||
rightPanel: appSettings.communitiesEnabled && root.rootStore.chatsModelInst.communities.activeCommunity.active ? communityUserListComponent : userListComponent
|
||||
showRightPanel: (appSettings.expandUsersList && (appSettings.showOnlineUsers || chatsModel.communities.activeCommunity.active)
|
||||
&& (chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne))
|
||||
//rightPanel: appSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communityUserListComponent : userListComponent
|
||||
rightPanel: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "blue"
|
||||
}
|
||||
|
||||
Component {
|
||||
id: communityUserListComponent
|
||||
|
|
|
@ -213,7 +213,7 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
navBarCommunityTabButtons.model: appSettings.communitiesEnabled && chatsModel.communities.joinedCommunities
|
||||
navBarCommunityTabButtons.model: appSettings.communitiesEnabled && mainModule.sectionsModel
|
||||
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
|
||||
onClicked: {
|
||||
appMain.changeAppSection(Constants.chat)
|
||||
|
@ -226,8 +226,9 @@ Item {
|
|||
checked: chatsModel.communities.activeCommunity.active && chatsModel.communities.activeCommunity.id === model.id
|
||||
name: model.name
|
||||
tooltip.text: model.name
|
||||
icon.color: model.communityColor
|
||||
icon.source: model.thumbnailImage
|
||||
icon.color: model.color
|
||||
icon.source: model.image.length > 0? model.image : model.icon
|
||||
icon.name: model.icon
|
||||
|
||||
badge.value: model.unviewedMentionsCount + model.requestsCount
|
||||
badge.visible: badge.value > 0 || (!checked && model.unviewedMessagesCount > 0)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 72a32ee72549e44d14d28a430a75a09078efc7e3
|
||||
Subproject commit c8b721994b91dccdc7ab6d4b03c90e48730aa682
|
Loading…
Reference in New Issue