refactor(@desktop/settings-devices): device settings added

This commit is contained in:
Sale Djenic 2021-12-27 12:04:10 +01:00
parent a6b8fbe4b3
commit 44ceb6730d
28 changed files with 668 additions and 49 deletions

View File

@ -28,6 +28,7 @@ import ../../app_service/service/node_configuration/service as node_configuratio
import ../../app_service/service/network/service as network_service
import ../../app_service/service/activity_center/service as activity_center_service
import ../../app_service/service/saved_address/service as saved_address_service
import ../../app_service/service/devices/service as devices_service
import ../modules/startup/module as startup_module
import ../modules/main/module as main_module
@ -96,6 +97,7 @@ type
privacyService: privacy_service.Service
nodeConfigurationService: node_configuration_service.Service
savedAddressService: saved_address_service.Service
devicesService: devices_service.Service
# Modules
startupModule: startup_module.AccessInterface
@ -171,6 +173,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.privacyService = privacy_service.newService()
result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService)
result.savedAddressService = saved_address_service.newService(statusFoundation.status.events)
result.devicesService = devices_service.newService(statusFoundation.status.events, result.settingsService)
# Modules
result.startupModule = startup_module.newModule[AppController](
@ -204,7 +207,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.stickersService,
result.activityCenterService,
result.savedAddressService,
result.nodeConfigurationService
result.nodeConfigurationService,
result.devicesService
)
# Do connections
@ -242,6 +246,7 @@ proc delete*(self: AppController) =
self.settingsService.delete
self.stickersService.delete
self.savedAddressService.delete
self.devicesService.delete
proc startupDidLoad*(self: AppController) =
singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant)
@ -282,6 +287,7 @@ proc load(self: AppController) =
self.activityCenterService.init()
self.savedAddressService.init()
self.aboutService.init()
self.devicesService.init()
let pubKey = self.settingsService.getPublicKey()
singletonInstance.localAccountSensitiveSettings.setFileName(pubKey)

View File

@ -3,7 +3,7 @@ import json
import base
# Step by step we should remove all these types from `status-lib`
import status/types/[installation, activity_center_notification, removed_message]
import status/types/[activity_center_notification, removed_message]
import status/types/community as old_community
import ../../../../app_service/service/message/dto/[message, pinned_message, reaction]
@ -11,13 +11,14 @@ import ../../../../app_service/service/chat/dto/[chat]
import ../../../../app_service/service/community/dto/[community]
import ../../../../app_service/service/activity_center/dto/[notification]
import ../../../../app_service/service/contacts/dto/[contacts, status_update]
import ../../../../app_service/service/devices/dto/[device]
type MessageSignal* = ref object of Signal
messages*: seq[MessageDto]
pinnedMessages*: seq[PinnedMessageDto]
chats*: seq[ChatDto]
contacts*: seq[ContactsDto]
installations*: seq[Installation]
devices*: seq[DeviceDto]
emojiReactions*: seq[ReactionDto]
communities*: seq[CommunityDto]
membershipRequests*: seq[old_community.CommunityMembershipRequest]
@ -50,8 +51,8 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
signal.statusUpdates.add(statusUpdate)
if event["event"]{"installations"} != nil:
for jsonInstallation in event["event"]["installations"]:
signal.installations.add(jsonInstallation.toInstallation)
for jsonDevice in event["event"]["installations"]:
signal.devices.add(jsonDevice.toDeviceDto())
if event["event"]{"emojiReactions"} != nil:
for jsonReaction in event["event"]["emojiReactions"]:

View File

@ -37,6 +37,7 @@ import ../../../app_service/service/stickers/service as stickers_service
import ../../../app_service/service/activity_center/service as activity_center_service
import ../../../app_service/service/saved_address/service as saved_address_service
import ../../../app_service/service/node_configuration/service_interface as node_configuration_service
import ../../../app_service/service/devices/service as devices_service
import eventemitter
@ -84,7 +85,8 @@ proc newModule*[T](
stickersService: stickers_service.Service,
activityCenterService: activity_center_service.Service,
savedAddressService: saved_address_service.ServiceInterface,
nodeConfigurationService: node_configuration_service.ServiceInterface
nodeConfigurationService: node_configuration_service.ServiceInterface,
devicesService: devices_service.Service
): Module[T] =
result = Module[T]()
result.delegate = delegate
@ -116,7 +118,7 @@ proc newModule*[T](
dappPermissionsService, providerService)
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService,
profileService, contactsService, aboutService, languageService, mnemonicService, privacyService,
nodeConfigurationService)
nodeConfigurationService, devicesService)
result.stickersModule = stickers_module.newModule(result, events, stickersService)
result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService)
result.communitiesModule = communities_module.newModule(result, events, communityService)

View File

@ -33,6 +33,8 @@ proc newModule*(
method delete*(self: Module) =
self.view.delete
self.viewVariant.delete
self.controller.delete
method load*(self: Module) =
self.view.load()

View File

@ -0,0 +1,62 @@
import Tables, chronicles
import controller_interface
import io_interface
import ../../../../../app_service/service/settings/service_interface as settings_service
import ../../../../../app_service/service/devices/service as devices_service
import eventemitter
export controller_interface
logScope:
topics = "profile-section-devices-module-controller"
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
events: EventEmitter
settingsService: settings_service.ServiceInterface
devicesService: devices_service.Service
proc newController*(delegate: io_interface.AccessInterface,
events: EventEmitter,
settingsService: settings_service.ServiceInterface,
devicesService: devices_service.Service): Controller =
result = Controller()
result.delegate = delegate
result.events = events
result.settingsService = settingsService
result.devicesService = devicesService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
self.events.on(SIGNAL_UPDATE_DEVICE) do(e: Args):
var args = UpdateDeviceArgs(e)
self.delegate.updateOrAddDevice(args.deviceId, args.name, args.enabled)
method getMyInstallationId*(self: Controller): string =
return self.settingsService.getInstallationId()
method getAllDevices*(self: Controller): seq[DeviceDto] =
return self.devicesService.getAllDevices()
method isDeviceSetup*(self: Controller): bool =
return self.devicesService.isDeviceSetup()
method setDeviceName*(self: Controller, name: string) =
self.devicesService.setDeviceName(name)
method syncAllDevices*(self: Controller) =
self.devicesService.syncAllDevices()
method advertise*(self: Controller) =
self.devicesService.advertise()
method enableDevice*(self: Controller, deviceId: string, enable: bool) =
if enable:
self.devicesService.enable(deviceId)
else:
self.devicesService.disable(deviceId)

View File

@ -0,0 +1,32 @@
import ../../../../../app_service/service/devices/dto/device
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 getMyInstallationId*(self: AccessInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method getAllDevices*(self: AccessInterface): seq[DeviceDto] {.base.} =
raise newException(ValueError, "No implementation available")
method isDeviceSetup*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method setDeviceName*(self: AccessInterface, name: string) {.base.} =
raise newException(ValueError, "No implementation available")
method syncAllDevices*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method advertise*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method enableDevice*(self: AccessInterface, deviceId: string, enable: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,11 @@
# Defines how parent module accesses this module
include ./private_interfaces/module_base_interface
include ./private_interfaces/module_access_interface
# Defines how this module view communicates with this module
include ./private_interfaces/module_view_delegate_interface
# Defines how this controller communicates with this module
include ./private_interfaces/module_controller_delegate_interface
# Defines how submodules of this module communicate with this module

View File

@ -0,0 +1,31 @@
type
Item* = ref object
installationId: string
name: string
enabled: bool
isCurrentDevice: bool
proc initItem*(installationId, name: string, enabled, isCurrentDevice: bool): Item =
result = Item()
result.installationId = installationId
result.name = name
result.enabled = enabled
result.isCurrentDevice = isCurrentDevice
proc installationId*(self: Item): string =
self.installationId
proc name*(self: Item): string =
self.name
proc `name=`*(self: Item, value: string) =
self.name = value
proc enabled*(self: Item): bool =
self.enabled
proc `enabled=`*(self: Item, value: bool) =
self.enabled = value
proc isCurrentDevice*(self: Item): bool =
self.isCurrentDevice

View File

@ -0,0 +1,94 @@
import NimQml, Tables
import item
type
ModelRole {.pure.} = enum
Name = UserRole + 1,
InstallationId
IsCurrentDevice
Enabled
QtObject:
type Model* = ref object of QAbstractListModel
items*: seq[Item]
proc setup(self: Model) =
self.QAbstractListModel.setup
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc newModel*(): Model =
new(result, delete)
result.setup
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.Name.int:"name",
ModelRole.InstallationId.int:"installationId",
ModelRole.IsCurrentDevice.int:"isCurrentDevice",
ModelRole.Enabled.int:"enabled"
}.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.Name:
result = newQVariant(item.name)
of ModelRole.InstallationId:
result = newQVariant(item.installationId)
of ModelRole.IsCurrentDevice:
result = newQVariant(item.isCurrentDevice)
of ModelRole.Enabled:
result = newQVariant(item.enabled)
proc addItems*(self: Model, items: seq[Item]) =
if(items.len == 0):
return
let parentModelIndex = newQModelIndex()
defer: parentModelIndex.delete
let first = self.items.len
let last = first + items.len - 1
self.beginInsertRows(parentModelIndex, first, last)
self.items.add(items)
self.endInsertRows()
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()
proc findIndexByInstallationId(self: Model, installationId: string): int =
for i in 0..<self.items.len:
if installationId == self.items[i].installationId():
return i
return -1
proc isItemWithInstallationIdAdded*(self: Model, installationId: string): bool =
return self.findIndexByInstallationId(installationId) != -1
proc updateItem*(self: Model, installationId: string, name: string, enabled: bool) =
var i = self.findIndexByInstallationId(installationId)
if(i == -1):
return
let first = self.createIndex(i, 0, nil)
let last = self.createIndex(i, 0, nil)
self.items[i].name = name
self.items[i].enabled = enabled
self.dataChanged(first, last, @[ModelRole.Name.int, ModelRole.Enabled.int])

View File

@ -0,0 +1,91 @@
import NimQml, chronicles
import io_interface
import ../io_interface as delegate_interface
import view, controller, model, item
import ../../../../../app_service/service/settings/service_interface as settings_service
import ../../../../../app_service/service/devices/service as devices_service
import eventemitter
export io_interface
logScope:
topics = "profile-section-devices-module"
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
controller: controller.AccessInterface
view: View
viewVariant: QVariant
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface,
events: EventEmitter,
settingsService: settings_service.ServiceInterface,
devicesService: devices_service.Service): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, settingsService, devicesService)
result.moduleLoaded = false
method delete*(self: Module) =
self.view.delete
self.viewVariant.delete
self.controller.delete
method load*(self: Module) =
self.controller.init()
self.view.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
proc isMyDevice(self: Module, installationId: string): bool =
let myInstallationId = self.controller.getMyInstallationId()
return installationId == myInstallationId
proc initModel(self: Module) =
var items: seq[Item]
let allDevices = self.controller.getAllDevices()
for d in allDevices:
let item = initItem(d.id, d.metadata.name, d.enabled, self.isMyDevice(d.id))
items.add(item)
self.view.model().addItems(items)
method viewDidLoad*(self: Module) =
self.initModel()
self.moduleLoaded = true
self.delegate.devicesModuleDidLoad()
method getModuleAsVariant*(self: Module): QVariant =
return self.viewVariant
method isDeviceSetup*(self: Module): bool =
return self.controller.isDeviceSetup()
method setDeviceName*(self: Module, name: string) =
self.controller.setDeviceName(name)
# in future if we start getting more meaningful response form the `status-go` part, we may
# move this call to the `onDeviceNameSet` slot and confirm change on the qml side that way.
self.view.emitDeviceSetupChangedSignal()
method syncAllDevices*(self: Module) =
self.controller.syncAllDevices()
method advertise*(self: Module) =
self.controller.advertise()
method enableDevice*(self: Module, deviceId: string, enable: bool) =
self.controller.enableDevice(deviceId, enable)
method updateOrAddDevice*(self: Module, deviceId: string, name: string, enabled: bool) =
if(self.view.model().isItemWithInstallationIdAdded(deviceId)):
self.view.model().updateItem(deviceId, name, enabled)
else:
let item = initItem(deviceId, name, enabled, self.isMyDevice(deviceId))
self.view.model().addItem(item)

View File

@ -0,0 +1,13 @@
import NimQml
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")
method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,5 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
# Since nim doesn't support using concepts in second level nested types we
# define delegate interfaces within access interface.

View File

@ -0,0 +1,2 @@
method updateOrAddDevice*(self: AccessInterface, installationId: string, name: string, enabled: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,17 @@
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method isDeviceSetup*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method setDeviceName*(self: AccessInterface, name: string) {.base.} =
raise newException(ValueError, "No implementation available")
method syncAllDevices*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method advertise*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method enableDevice*(self: AccessInterface, installationId: string, enable: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,56 @@
import NimQml
import io_interface, model
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) =
self.delegate.viewDidLoad()
proc model*(self: View): Model =
return self.model
proc modelChanged*(self: View) {.signal.}
proc getModel(self: View): QVariant {.slot.} =
return self.modelVariant
QtProperty[QVariant] model:
read = getModel
notify = modelChanged
proc deviceSetupChanged*(self: View) {.signal.}
proc getIsDeviceSetup*(self: View): bool {.slot} =
return self.delegate.isDeviceSetup()
QtProperty[bool] isDeviceSetup:
read = getIsDeviceSetup
notify = deviceSetupChanged
proc emitDeviceSetupChangedSignal*(self: View) =
self.deviceSetupChanged()
proc setName*(self: View, deviceName: string) {.slot.} =
self.delegate.setDeviceName(deviceName)
proc syncAll*(self: View) {.slot.} =
self.delegate.syncAllDevices()
proc advertise*(self: View) {.slot.} =
self.delegate.advertise()
proc enableDevice*(self: View, installationId: string, enable: bool) {.slot.} =
self.delegate.enableDevice(installationId, enable)

View File

@ -44,6 +44,12 @@ method advancedModuleDidLoad*(self: AccessInterface) {.base.} =
method getAdvancedModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method devicesModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getDevicesModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.

View File

@ -11,6 +11,7 @@ import ../../../../app_service/service/language/service as language_service
import ../../../../app_service/service/mnemonic/service as mnemonic_service
import ../../../../app_service/service/privacy/service as privacy_service
import ../../../../app_service/service/node_configuration/service_interface as node_configuration_service
import ../../../../app_service/service/devices/service as devices_service
import ./profile/module as profile_module
import ./contacts/module as contacts_module
@ -19,6 +20,7 @@ import ./mnemonic/module as mnemonic_module
import ./privacy/module as privacy_module
import ./about/module as about_module
import ./advanced/module as advanced_module
import ./devices/module as devices_module
import eventemitter
@ -39,6 +41,7 @@ type
privacyModule: privacy_module.AccessInterface
aboutModule: about_module.AccessInterface
advancedModule: advanced_module.AccessInterface
devicesModule: devices_module.AccessInterface
proc newModule*[T](delegate: T,
events: EventEmitter,
@ -50,7 +53,8 @@ proc newModule*[T](delegate: T,
languageService: language_service.ServiceInterface,
mnemonicService: mnemonic_service.ServiceInterface,
privacyService: privacy_service.ServiceInterface,
nodeConfigurationService: node_configuration_service.ServiceInterface
nodeConfigurationService: node_configuration_service.ServiceInterface,
devicesService: devices_service.Service
):
Module[T] =
result = Module[T]()
@ -67,6 +71,7 @@ proc newModule*[T](delegate: T,
result.privacyModule = privacy_module.newModule(result, privacyService, accountsService)
result.aboutModule = about_module.newModule(result, events, aboutService)
result.advancedModule = advanced_module.newModule(result, events, settingsService, nodeConfigurationService)
result.devicesModule = devices_module.newModule(result, events, settingsService, devicesService)
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
@ -78,6 +83,7 @@ method delete*[T](self: Module[T]) =
self.privacyModule.delete
self.aboutModule.delete
self.advancedModule.delete
self.devicesModule.delete
self.view.delete
self.viewVariant.delete
@ -92,6 +98,7 @@ method load*[T](self: Module[T]) =
self.privacyModule.load()
self.aboutModule.load()
self.advancedModule.load()
self.devicesModule.load()
method isLoaded*[T](self: Module[T]): bool =
return self.moduleLoaded
@ -118,6 +125,9 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
if(not self.advancedModule.isLoaded()):
return
if(not self.devicesModule.isLoaded()):
return
self.moduleLoaded = true
self.delegate.profileSectionDidLoad()
@ -146,4 +156,10 @@ method advancedModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method getAdvancedModule*[T](self: Module[T]): QVariant =
self.advancedModule.getModuleAsVariant()
self.advancedModule.getModuleAsVariant()
method devicesModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method getDevicesModule*[T](self: Module[T]): QVariant =
self.devicesModule.getModuleAsVariant()

View File

@ -23,6 +23,10 @@ QtObject:
proc getAdvancedModule(self: View): QVariant {.slot.} =
return self.delegate.getAdvancedModule()
QtProperty[QVariant] advancedModule:
read = getAdvancedModule
read = getAdvancedModule
proc getDevicesModule(self: View): QVariant {.slot.} =
return self.delegate.getDevicesModule()
QtProperty[QVariant] devicesModule:
read = getDevicesModule

View File

@ -11,7 +11,7 @@ import ./update
include async_tasks
logScope:
topics = "settings-service"
topics = "about-service"
# This is changed during compilation by reading the VERSION file
const DESKTOP_VERSION {.strdefine.} = "0.0.0"
@ -33,7 +33,7 @@ QtObject:
proc asyncRequestLatestVersion(self: Service)
proc delete*(self: Service) =
discard
self.QObject.delete
proc newService*(
events: EventEmitter,

View File

@ -0,0 +1,39 @@
{.used.}
import json
include ../../../common/[json_utils]
type Metadata* = object
name*: string
deviceType*: string
fcmToken*: string
type DeviceDto* = object
id*: string
identity*: string
version*: int
enabled*: bool
timestamp*: int64
metadata*: Metadata
proc isEmpty*(self: Metadata): bool =
return self.name.len == 0
proc toMetadata(jsonObj: JsonNode): Metadata =
result = Metadata()
discard jsonObj.getProp("name", result.name)
discard jsonObj.getProp("deviceType", result.deviceType)
discard jsonObj.getProp("fcmToken", result.fcmToken)
proc toDeviceDto*(jsonObj: JsonNode): DeviceDto =
result = DeviceDto()
discard jsonObj.getProp("id", result.id)
discard jsonObj.getProp("identity", result.identity)
discard jsonObj.getProp("version", result.version)
discard jsonObj.getProp("enabled", result.enabled)
discard jsonObj.getProp("timestamp", result.timestamp)
var metadataObj: JsonNode
if(jsonObj.getProp("metadata", metadataObj)):
result.metadata = toMetadata(metadataObj)

View File

@ -0,0 +1,99 @@
import NimQml, json, sequtils, system, chronicles
import ../../../app/core/signals/types
import ./dto/device as device_dto
import ../settings/service as settings_service
import status/statusgo_backend_new/installations as status_installations
import eventemitter
export device_dto
logScope:
topics = "devices-service"
type
UpdateDeviceArgs* = ref object of Args
deviceId*: string
name*: string
enabled*: bool
# Signals which may be emitted by this service:
const SIGNAL_UPDATE_DEVICE* = "updateDevice"
QtObject:
type Service* = ref object of QObject
events: EventEmitter
settingsService: settings_service.ServiceInterface
## Forward declaration
proc isNewDevice(self: Service, device: DeviceDto): bool
proc delete*(self: Service) =
self.QObject.delete
proc newService*(events: EventEmitter, settingsService: settings_service.ServiceInterface): Service =
new(result, delete)
result.QObject.setup
result.events = events
result.settingsService = settingsService
proc doConnect(self: Service) =
self.events.on(SignalType.Message.event) do(e:Args):
var receivedData = MessageSignal(e)
if(receivedData.devices.len > 0):
for d in receivedData.devices:
let data = UpdateDeviceArgs(
deviceId: d.id,
name: d.metadata.name,
enabled: d.enabled)
self.events.emit(SIGNAL_UPDATE_DEVICE, data)
proc init*(self: Service) =
self.doConnect()
proc getAllDevices*(self: Service): seq[DeviceDto] =
try:
let response = status_installations.getOurInstallations()
return map(response.result.getElems(), proc(x: JsonNode): DeviceDto = x.toDeviceDto())
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
proc isNewDevice(self: Service, device: DeviceDto): bool =
let allDevices = self.getAllDevices()
for d in allDevices:
if(d.id == device.id):
return false
return true
proc setDeviceName*(self: Service, name: string) =
let installationId = self.settingsService.getInstallationId()
# Once we get more info from `status-go` we may emit success/failed signal from here.
discard status_installations.setInstallationMetadata(installationId, name, hostOs)
proc isDeviceSetup*(self: Service): bool =
let allDevices = self.getAllDevices()
let installationId = self.settingsService.getInstallationId()
for d in allDevices:
if d.id == installationId:
return not d.metadata.isEmpty()
return false
proc syncAllDevices*(self: Service) =
let preferredName = self.settingsService.getPreferredName()
let photoPath = "" # From the old code: TODO change this to identicon when status-go is updated
# Once we get more info from `status-go` we may emit success/failed signal from here.
discard status_installations.syncDevices(preferredName, "")
proc advertise*(self: Service) =
# Once we get more info from `status-go` we may emit success/failed signal from here.
discard status_installations.sendPairInstallation()
proc enable*(self: Service, deviceId: string) =
# Once we get more info from `status-go` we may emit success/failed signal from here.
discard status_installations.enableInstallation(deviceId)
proc disable*(self: Service, deviceId: string) =
# Once we get more info from `status-go` we may emit success/failed signal from here.
discard status_installations.disableInstallation(deviceId)

View File

@ -11,6 +11,7 @@ const KEY_NETWORKS_ALL_NETWORKS* = "networks/networks"
const KEY_DAPPS_ADDRESS* = "dapps-address"
const KEY_EIP1581_ADDRESS* = "eip1581-address"
const KEY_INSTALLATION_ID* = "installation-id"
const KEY_PREFERRED_NAME* = "preferred-name"
const KEY_KEY_UID* = "key-uid"
const KEY_LATEST_DERIVED_PATH* = "latest-derived-path"
const KEY_LINK_PREVIEW_REQUEST_ENABLED* = "link-preview-request-enabled"
@ -75,6 +76,7 @@ type
dappsAddress*: string
eip1581Address*: string
installationId*: string
preferredName*: string
keyUid*: string
latestDerivedPath*: int
linkPreviewRequestEnabled*: bool
@ -171,6 +173,7 @@ proc toSettingsDto*(jsonObj: JsonNode): SettingsDto =
discard jsonObj.getProp(KEY_DAPPS_ADDRESS, result.dappsAddress)
discard jsonObj.getProp(KEY_EIP1581_ADDRESS, result.eip1581Address)
discard jsonObj.getProp(KEY_INSTALLATION_ID, result.installationId)
discard jsonObj.getProp(KEY_PREFERRED_NAME, result.preferredName)
discard jsonObj.getProp(KEY_KEY_UID, result.keyUid)
discard jsonObj.getProp(KEY_LATEST_DERIVED_PATH, result.latestDerivedPath)
discard jsonObj.getProp(KEY_LINK_PREVIEW_REQUEST_ENABLED, result.linkPreviewRequestEnabled)

View File

@ -98,6 +98,15 @@ method saveInstallationId*(self: Service, value: string): bool =
method getInstallationId*(self: Service): string =
return self.settings.installationId
method savePreferredName*(self: Service, value: string): bool =
if(self.saveSetting(KEY_PREFERRED_NAME, value)):
self.settings.preferredName = value
return true
return false
method getPreferredName*(self: Service): string =
return self.settings.preferredName
method saveKeyUid*(self: Service, value: string): bool =
if(self.saveSetting(KEY_KEY_UID, value)):
self.settings.keyUid = value

View File

@ -59,6 +59,12 @@ method saveInstallationId*(self: ServiceInterface, value: string): bool {.base.}
method getInstallationId*(self: ServiceInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method savePreferredName*(self: ServiceInterface, value: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
method getPreferredName*(self: ServiceInterface): string {.base.} =
raise newException(ValueError, "No implementation available")
method saveKeyUid*(self: ServiceInterface, value: string): bool {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -93,7 +93,7 @@ StatusAppTwoPanelLayout {
}
DevicesView {
store: profileView.store
devicesStore: profileView.store.devicesStore
}
BrowserView {

View File

@ -0,0 +1,29 @@
import QtQuick 2.13
import utils 1.0
QtObject {
id: root
property var devicesModule
property var devicesModel: devicesModule.model
// Module Properties
property bool isDeviceSetup: devicesModule.isDeviceSetup
function setName(name) {
return root.devicesModule.setName(name)
}
function syncAll() {
root.devicesModule.syncAll()
}
function advertise() {
root.devicesModule.advertise()
}
function enableDevice(installationId, enable) {
root.devicesModule.enableDevice(installationId, enable)
}
}

View File

@ -11,10 +11,15 @@ QtObject {
property var mnemonicModuleInst: mnemonicModule
property var profileModuleInst: profileSectionModule
property AdvancedStore advancedStore: AdvancedStore {
advancedModule: profileModuleInst.advancedModule
}
property DevicesStore devicesStore: DevicesStore {
devicesModule: profileModuleInst.devicesModule
}
// Not Refactored Yet
// property var chatsModelInst: chatsModel
// Not Refactored Yet
@ -37,7 +42,6 @@ QtObject {
// Not Refactored Yet
// property var mutedChatsContacts: profileModelInst.mutedChats.contacts
// property var mutedChats: profileModelInst.mutedChats.chats
// property var devicesList: profileModelInst.devices.list
// Not Refactored Yet
property string ensRegisterAddress: "" //utilsModelInst.ensRegisterAddress
@ -55,8 +59,6 @@ QtObject {
property bool profileHasIdentityImage: profile.hasIdentityImage
// Not Refactored Yet
// property bool automaticMailserverSelection: profileModelInst.mailservers.automaticSelection
// Not Refactored Yet
property bool devicesSetup: false //profileModelInst.devices.isSetup
property bool mnemonicBackedUp: mnemonicModuleInst.isBackedUp
property bool messagesFromContactsOnly: profile.messagesFromContactsOnly
@ -364,26 +366,6 @@ QtObject {
// return profileModelInst.ens.setPubKey(username, address, gasLimit, gasPrice, password)
}
function setDeviceName(name) {
// Not Refactored Yet
// profileModelInst.devices.setName(name)
}
function advertiseDevice() {
// Not Refactored Yet
// profileModelInst.devices.advertise()
}
function enableDeviceInstallation(id, pairedSwitch) {
// Not Refactored Yet
// profileModelInst.devices.enableInstallation(id, pairedSwitch)
}
function syncAllDevices() {
// Not Refactored Yet
// profileModelInst.devices.syncAll()
}
function readTextFile(path) {
return globalUtils.readTextFile(path)
}

View File

@ -15,7 +15,8 @@ import shared.controls 1.0
Item {
id: root
property var store
property var devicesStore
property bool isSyncing: false
width: 200
@ -32,7 +33,7 @@ Item {
anchors.topMargin: 24
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
visible: !root.store.devicesSetup
visible: !root.devicesStore.isDeviceSetup
height: visible ? childrenRect.height : 0
StatusBaseText {
@ -59,7 +60,7 @@ Item {
//% "Continue"
text: qsTrId("continue")
enabled: deviceNameTxt.text !== ""
onClicked : root.store.setDeviceName(deviceNameTxt.text.trim())
onClicked : root.devicesStore.setName(deviceNameTxt.text.trim())
}
}
@ -71,7 +72,7 @@ Item {
anchors.topMargin: Style.current.padding
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
visible: root.store.devicesSetup
visible: root.devicesStore.isDeviceSetup
height: visible ? childrenRect.height : 0
Rectangle {
@ -122,7 +123,7 @@ Item {
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: root.store.advertiseDevice()
onClicked: root.devicesStore.advertise()
}
}
@ -153,7 +154,7 @@ Item {
anchors.bottomMargin: Style.current.padding
anchors.right: root.right
anchors.rightMargin: Style.current.padding
visible: root.store.devicesSetup
visible: root.devicesStore.isDeviceSetup
StatusBaseText {
id: deviceListLbl
@ -193,7 +194,7 @@ Item {
//% "No info"
let labelText = `${model.name || qsTrId("pairing-no-info")} ` +
//% "you"
`(${model.isUserDevice ? qsTrId("you") + ", ": ""}${deviceId})`;
`(${model.isCurrentDevice ? qsTrId("you") + ", ": ""}${deviceId})`;
return labelText;
}
elide: Text.ElideRight
@ -204,15 +205,15 @@ Item {
}
StatusSwitch {
id: devicePairedSwitch
visible: !model.isUserDevice
checked: model.isEnabled
visible: !model.isCurrentDevice
checked: model.enabled
anchors.left: deviceItemLbl.right
anchors.leftMargin: Style.current.padding
anchors.top: deviceItemLbl.top
onClicked: root.store.enableDeviceInstallation(model.installationId, devicePairedSwitch)
onClicked: root.devicesStore.enableDevice(model.installationId, devicePairedSwitch)
}
}
model: root.store.devicesList
model: root.devicesStore.devicesModel
}
}
@ -229,7 +230,7 @@ Item {
enabled: !isSyncing
onClicked : {
isSyncing = true;
root.store.syncAllDevices()
root.devicesStore.syncAll()
// Currently we don't know how long it takes, so we just disable for 10s, to avoid spamming
timer.setTimeout(function(){
isSyncing = false