From abf58b008faec63398b6b60fd0cfc491da5f1c3c Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Sat, 29 Apr 2023 13:33:08 +0300 Subject: [PATCH] fix(Pairing): Added installation info to pairing results (#10418) --- .../core/signals/remote_signals/pairing.nim | 25 ++++++--- .../main/profile_section/devices/view.nim | 18 ++++++ src/app/modules/startup/controller.nim | 2 +- src/app/modules/startup/view.nim | 20 ++++++- .../devices/dto/local_pairing_event.nim | 12 +++- .../devices/dto/local_pairing_status.nim | 56 ++++++++++++------- src/app_service/service/devices/service.nim | 11 ++-- .../src/StatusQ/Components/StatusListItem.qml | 3 +- .../Onboarding/stores/StartupStore.qml | 3 + .../Onboarding/views/SyncDeviceResult.qml | 3 + .../Profile/popups/SetupSyncingPopup.qml | 6 +- .../popups/SyncDeviceCustomizationPopup.qml | 1 + .../Profile/stores/DevicesStore.qml | 3 + ui/imports/shared/views/DeviceSyncingView.qml | 32 ++++++++--- ui/imports/utils/Constants.qml | 7 +-- vendor/status-go | 2 +- 16 files changed, 150 insertions(+), 54 deletions(-) diff --git a/src/app/core/signals/remote_signals/pairing.nim b/src/app/core/signals/remote_signals/pairing.nim index 63cae0dee5..450953419b 100644 --- a/src/app/core/signals/remote_signals/pairing.nim +++ b/src/app/core/signals/remote_signals/pairing.nim @@ -1,23 +1,32 @@ import json, tables import base import ../../../../app_service/service/accounts/dto/accounts - +import ../../../../app_service/service/devices/dto/installation +import ../../../../app_service/service/devices/dto/local_pairing_event type LocalPairingSignal* = ref object of Signal - eventType*: string - action*: int + eventType*: EventType + action*: Action error*: string account*: AccountDto + installation*: InstallationDto proc fromEvent*(T: type LocalPairingSignal, event: JsonNode): LocalPairingSignal = result = LocalPairingSignal() let e = event["event"] if e.contains("type"): - result.eventType = e["type"].getStr + result.eventType = e["type"].getStr().parse() if e.contains("action"): - result.action = e["action"].getInt + result.action = e["action"].getInt().parse() if e.contains("error"): - result.error = e["error"].getStr - if e.contains("data"): - result.account = e["data"].toAccountDto() + result.error = e["error"].getStr() + if not e.contains("data"): + return + case result.eventType: + of EventReceivedAccount: + result.account = e["data"].toAccountDto() + of EventReceivedInstallation: + result.installation = e["data"].toInstallationDto() + else: + discard diff --git a/src/app/modules/main/profile_section/devices/view.nim b/src/app/modules/main/profile_section/devices/view.nim index 2efedd746e..8b85521418 100644 --- a/src/app/modules/main/profile_section/devices/view.nim +++ b/src/app/modules/main/profile_section/devices/view.nim @@ -109,6 +109,24 @@ QtObject: proc onLocalPairingEvent*(self: View, eventType: EventType, action: Action, error: string) = self.localPairingEvent(ord(eventType), ord(action), error) + proc getLocalPairingInstallationId*(self: View): string {.slot.} = + return self.localPairingStatus.installation.id + QtProperty[string] localPairingInstallationId: + read = getLocalPairingInstallationId + notify = localPairingStatusChanged + + proc getLocalPairingInstallationName*(self: View): string {.slot.} = + return self.localPairingStatus.installation.metadata.name + QtProperty[string] localPairingInstallationName: + read = getLocalPairingInstallationName + notify = localPairingStatusChanged + + proc getLocalPairingInstallationDeviceType*(self: View): string {.slot.} = + return self.localPairingStatus.installation.metadata.deviceType + QtProperty[string] localPairingInstallationDeviceType: + read = getLocalPairingInstallationDeviceType + notify = localPairingStatusChanged + proc onLocalPairingStatusUpdate*(self: View, status: LocalPairingStatus) = self.localPairingStatus = status self.localPairingStatusChanged() diff --git a/src/app/modules/startup/controller.nim b/src/app/modules/startup/controller.nim index 919ab3e9d1..b3a95e1b82 100644 --- a/src/app/modules/startup/controller.nim +++ b/src/app/modules/startup/controller.nim @@ -571,4 +571,4 @@ proc validateLocalPairingConnectionString*(self: Controller, connectionString: s return self.devicesService.validateConnectionString(connectionString) proc inputConnectionStringForBootstrapping*(self: Controller, connectionString: string): string = - return self.devicesService.inputConnectionStringForBootstrapping(connectionString) \ No newline at end of file + return self.devicesService.inputConnectionStringForBootstrapping(connectionString) diff --git a/src/app/modules/startup/view.nim b/src/app/modules/startup/view.nim index ca15c024fe..03ee25141d 100644 --- a/src/app/modules/startup/view.nim +++ b/src/app/modules/startup/view.nim @@ -349,6 +349,24 @@ QtObject: read = getLocalPairingImage notify = localPairingStatusChanged + proc getLocalPairingInstallationId*(self: View): string {.slot.} = + return self.localPairingStatus.installation.id + QtProperty[string] localPairingInstallationId: + read = getLocalPairingInstallationId + notify = localPairingStatusChanged + + proc getLocalPairingInstallationName*(self: View): string {.slot.} = + return self.localPairingStatus.installation.metadata.name + QtProperty[string] localPairingInstallationName: + read = getLocalPairingInstallationName + notify = localPairingStatusChanged + + proc getLocalPairingInstallationDeviceType*(self: View): string {.slot.} = + return self.localPairingStatus.installation.metadata.deviceType + QtProperty[string] localPairingInstallationDeviceType: + read = getLocalPairingInstallationDeviceType + notify = localPairingStatusChanged + proc onLocalPairingStatusUpdate*(self: View, status: LocalPairingStatus) = self.localPairingStatus = status self.localPairingStatusChanged() @@ -357,4 +375,4 @@ QtObject: return self.delegate.validateLocalPairingConnectionString(connectionString) proc onReencryptionProcessStarted*(self: View) = - self.setAppState(AppState.AppEncryptionProcessState) \ No newline at end of file + self.setAppState(AppState.AppEncryptionProcessState) diff --git a/src/app_service/service/devices/dto/local_pairing_event.nim b/src/app_service/service/devices/dto/local_pairing_event.nim index ad900d46b3..ef3e1f1edf 100644 --- a/src/app_service/service/devices/dto/local_pairing_event.nim +++ b/src/app_service/service/devices/dto/local_pairing_event.nim @@ -1,5 +1,6 @@ import ../../../../app/core/eventemitter import ../../accounts/dto/accounts +import installation type EventType* {.pure.} = enum @@ -9,8 +10,9 @@ type EventTransferError = 2, EventTransferSuccess = 3, EventReceivedAccount = 4, - EventProcessSuccess = 5, - EventProcessError = 6 + EventReceivedInstallation = 5 + EventProcessSuccess = 6, + EventProcessError = 7 type Action* {.pure.} = enum @@ -18,6 +20,7 @@ type ActionConnect = 1, ActionPairingAccount = 2, ActionSyncDevice = 3, + ActionPairingInstallation = 4, type LocalPairingEventArgs* = ref object of Args @@ -25,6 +28,7 @@ type action*: Action error*: string account*: AccountDTO + installation*: InstallationDto proc parse*(self: string): EventType = case self: @@ -42,6 +46,8 @@ proc parse*(self: string): EventType = return EventProcessError of "received-account": return EventReceivedAccount + of "received-installation": + return EventReceivedInstallation else: return EventUnknown @@ -53,5 +59,7 @@ proc parse*(self: int): Action = return ActionPairingAccount of 3: return ActionSyncDevice + of 4: + return ActionPairingInstallation else: return ActionUnknown diff --git a/src/app_service/service/devices/dto/local_pairing_status.nim b/src/app_service/service/devices/dto/local_pairing_status.nim index a9d41865cd..a572cfe499 100644 --- a/src/app_service/service/devices/dto/local_pairing_status.nim +++ b/src/app_service/service/devices/dto/local_pairing_status.nim @@ -1,11 +1,11 @@ import ../../../../app/core/eventemitter import ../../accounts/dto/accounts +import installation import local_pairing_event type LocalPairingState* {.pure.} = enum Idle = 0 - WaitingForConnection Transferring Error Finished @@ -13,20 +13,22 @@ type type LocalPairingMode* {.pure.} = enum Idle = 0 - BootstrapingOtherDevice - BootstrapingThisDevice + Sender + Receiver type LocalPairingStatus* = ref object of Args mode*: LocalPairingMode state*: LocalPairingState account*: AccountDTO + installation*: InstallationDto error*: string proc reset*(self: LocalPairingStatus) = self.mode = LocalPairingMode.Idle self.state = LocalPairingState.Idle self.error = "" + self.installation = InstallationDto() proc setup(self: LocalPairingStatus) = self.reset() @@ -38,29 +40,41 @@ proc newLocalPairingStatus*(): LocalPairingStatus = new(result, delete) result.setup() -proc update*(self: LocalPairingStatus, eventType: EventType, action: Action, account: AccountDTO, error: string) = - case eventType: - of EventConnectionSuccess: - self.state = LocalPairingState.WaitingForConnection - of EventTransferSuccess: - self.state = case self.mode: - of LocalPairingMode.BootstrapingOtherDevice: - LocalPairingState.Finished # For servers, `transfer` is last event - of LocalPairingMode.BootstrapingThisDevice: - LocalPairingState.Transferring # For clients, `process` is last event - else: - LocalPairingState.Idle - of EventProcessSuccess: - self.state = LocalPairingState.Finished +proc update*(self: LocalPairingStatus, data: LocalPairingEventArgs) = + + self.error = data.error + + # process any incoming data + case data.eventType: + of EventReceivedAccount: + self.account = data.account + of EventReceivedInstallation: + self.installation = data.installation of EventConnectionError: self.state = LocalPairingState.Error of EventTransferError: self.state = LocalPairingState.Error of EventProcessError: self.state = LocalPairingState.Error - of EventReceivedAccount: - self.account = account else: discard - - self.error = error \ No newline at end of file + + if self.state == LocalPairingState.Error: + return + + # Detect finished state + if (self.mode == LocalPairingMode.Sender and + data.eventType == EventProcessSuccess and + data.action == ActionPairingInstallation): + self.state = LocalPairingState.Finished + + if (self.mode == LocalPairingMode.Receiver and + data.eventType == EventTransferSuccess and + data.action == ActionPairingInstallation): + self.state = LocalPairingState.Finished + + if self.state == LocalPairingState.Finished: + return + + self.state = LocalPairingState.Transferring + diff --git a/src/app_service/service/devices/service.nim b/src/app_service/service/devices/service.nim index 4cea063545..c7c0395768 100644 --- a/src/app_service/service/devices/service.nim +++ b/src/app_service/service/devices/service.nim @@ -76,7 +76,7 @@ QtObject: proc updateLocalPairingStatus(self: Service, data: LocalPairingEventArgs) = self.events.emit(SIGNAL_LOCAL_PAIRING_EVENT, data) - self.localPairingStatus.update(data.eventType, data.action, data.account, data.error) + self.localPairingStatus.update(data) self.events.emit(SIGNAL_LOCAL_PAIRING_STATUS_UPDATE, self.localPairingStatus) proc doConnect(self: Service) = @@ -90,9 +90,10 @@ QtObject: self.events.on(SignalType.LocalPairing.event) do(e:Args): let signalData = LocalPairingSignal(e) let data = LocalPairingEventArgs( - eventType: signalData.eventType.parse(), - action: signalData.action.parse(), + eventType: signalData.eventType, + action: signalData.action, account: signalData.account, + installation: signalData.installation, error: signalData.error) self.updateLocalPairingStatus(data) @@ -187,7 +188,7 @@ QtObject: "timeout": 5 * 60 * 1000, } } - self.localPairingStatus.mode = LocalPairingMode.BootstrapingOtherDevice + self.localPairingStatus.mode = LocalPairingMode.Sender return status_go.getConnectionStringForBootstrappingAnotherDevice($configJSON) proc inputConnectionStringForBootstrapping*(self: Service, connectionString: string): string = @@ -203,7 +204,7 @@ QtObject: }, "clientConfig": %* {} } - self.localPairingStatus.mode = LocalPairingMode.BootstrapingThisDevice + self.localPairingStatus.mode = LocalPairingMode.Receiver let arg = AsyncInputConnectionStringArg( tptr: cast[ByteAddress](asyncInputConnectionStringTask), diff --git a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml index 4f3cb61d8e..ca8d0cecf3 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusListItem.qml @@ -33,6 +33,7 @@ Rectangle { property var inlineTagModel: [] property Component inlineTagDelegate property bool loading: false + property bool loadingSubTitle: loading property bool errorMode: false property StatusAssetSettings asset: StatusAssetSettings { @@ -291,7 +292,7 @@ Rectangle { Theme.palette.baseColor1 : Theme.palette.directColor1 visible: !!root.subTitle wrapMode: Text.WrapAtWordBoundaryOrAnywhere - loading: root.loading + loading: root.loadingSubTitle maximumLineCount: 3 elide: Text.ElideRight } diff --git a/ui/app/AppLayouts/Onboarding/stores/StartupStore.qml b/ui/app/AppLayouts/Onboarding/stores/StartupStore.qml index bdeb33fbbb..97f6d3a3bc 100644 --- a/ui/app/AppLayouts/Onboarding/stores/StartupStore.qml +++ b/ui/app/AppLayouts/Onboarding/stores/StartupStore.qml @@ -17,6 +17,9 @@ QtObject { readonly property string localPairingImage: startupModuleInst ? startupModuleInst.localPairingImage : "" readonly property int localPairingColorId: startupModuleInst ? startupModuleInst.localPairingColorId : 0 readonly property string localPairingColorHash: startupModuleInst ? startupModuleInst.localPairingColorHash : "" + readonly property string localPairingInstallationId: startupModuleInst ? startupModuleInst.localPairingInstallationId : "" + readonly property string localPairingInstallationName: startupModuleInst ? startupModuleInst.localPairingInstallationName : "" + readonly property string localPairingInstallationDeviceType: startupModuleInst ? startupModuleInst.localPairingInstallationDeviceType : "" function backAction() { root.currentStartupState.backAction() diff --git a/ui/app/AppLayouts/Onboarding/views/SyncDeviceResult.qml b/ui/app/AppLayouts/Onboarding/views/SyncDeviceResult.qml index 36d6adf903..0df853a96a 100644 --- a/ui/app/AppLayouts/Onboarding/views/SyncDeviceResult.qml +++ b/ui/app/AppLayouts/Onboarding/views/SyncDeviceResult.qml @@ -50,6 +50,9 @@ Item { userColorId: startupStore.localPairingColorId userColorHash: startupStore.localPairingColorHash + installationId: startupStore.localPairingInstallationId + installationName: startupStore.localPairingInstallationName + installationDeviceType: startupStore.localPairingInstallationDeviceType } StatusButton { diff --git a/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml b/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml index e8d24eb10b..eff86d8faf 100644 --- a/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml +++ b/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml @@ -76,8 +76,6 @@ StatusDialog { target: root.devicesStore function onLocalPairingStateChanged() { switch (root.devicesStore.localPairingState) { - case Constants.LocalPairingState.WaitingForConnection: - break; case Constants.LocalPairingState.Transferring: d.localPairingStarted() break @@ -220,6 +218,10 @@ StatusDialog { localPairingState: root.devicesStore.localPairingState localPairingError: root.devicesStore.localPairingError + + installationId: root.devicesStore.localPairingInstallationId + installationName: root.devicesStore.localPairingInstallationName + installationDeviceType: root.devicesStore.localPairingInstallationDeviceType } Views.ErrorMessage { diff --git a/ui/app/AppLayouts/Profile/popups/SyncDeviceCustomizationPopup.qml b/ui/app/AppLayouts/Profile/popups/SyncDeviceCustomizationPopup.qml index 9c1f4e611e..20147dda71 100644 --- a/ui/app/AppLayouts/Profile/popups/SyncDeviceCustomizationPopup.qml +++ b/ui/app/AppLayouts/Profile/popups/SyncDeviceCustomizationPopup.qml @@ -42,6 +42,7 @@ StatusDialog { onOpened: { nameInput.text = deviceModel.name + nameInput.forceActiveFocus() } contentItem: ColumnLayout { diff --git a/ui/app/AppLayouts/Profile/stores/DevicesStore.qml b/ui/app/AppLayouts/Profile/stores/DevicesStore.qml index 637b61cc80..e7530fe253 100644 --- a/ui/app/AppLayouts/Profile/stores/DevicesStore.qml +++ b/ui/app/AppLayouts/Profile/stores/DevicesStore.qml @@ -13,6 +13,9 @@ QtObject { readonly property int localPairingState: devicesModule ? devicesModule.localPairingState : -1 readonly property string localPairingError: devicesModule ? devicesModule.localPairingError : "" + readonly property string localPairingInstallationId: devicesModule ? devicesModule.localPairingInstallationId : "" + readonly property string localPairingInstallationName: devicesModule ? devicesModule.localPairingInstallationName : "" + readonly property string localPairingInstallationDeviceType: devicesModule ? devicesModule.localPairingInstallationDeviceType : "" function loadDevices() { return root.devicesModule.loadDevices() diff --git a/ui/imports/shared/views/DeviceSyncingView.qml b/ui/imports/shared/views/DeviceSyncingView.qml index b07e99f825..beff849576 100644 --- a/ui/imports/shared/views/DeviceSyncingView.qml +++ b/ui/imports/shared/views/DeviceSyncingView.qml @@ -10,15 +10,20 @@ import shared.controls 1.0 import shared.controls.chat 1.0 import utils 1.0 +import SortFilterProxyModel 0.2 + Item { id: root - property alias devicesModel: listView.model + property alias devicesModel: sfpModel.sourceModel property string userDisplayName property string userColorId property string userColorHash property string userPublicKey property string userImage + property string installationId + property string installationName + property string installationDeviceType property int localPairingState: Constants.LocalPairingState.Idle property string localPairingError @@ -66,7 +71,6 @@ Item { active: root.userPublicKey == "" Layout.alignment: Qt.AlignHCenter sourceComponent: UserImage { - opacity: name ? 1 : 0 name: root.userDisplayName colorId: root.userColorId colorHash: root.userColorHash @@ -74,10 +78,7 @@ Item { interactive: false imageWidth: 80 imageHeight: 80 - - Behavior on opacity { - NumberAnimation { duration: 250 } - } + loading: name === "" } } @@ -130,10 +131,13 @@ Item { Layout.alignment: Qt.AlignHCenter implicitWidth: d.deviceDelegateWidth visible: !d.pairingFailed - subTitle: qsTr("Synced device") + subTitle: d.pairingInProgress ? qsTr("Syncing with device") + : qsTr("Synced device") enabled: false loading: d.pairingInProgress - deviceName: qsTr("No device name") + loadingSubTitle: false + deviceName: root.installationName + deviceType: root.installationDeviceType isCurrentDevice: false showOnlineBadge: false } @@ -180,6 +184,18 @@ Item { spacing: 4 clip: true + model: SortFilterProxyModel { + id: sfpModel + filters: [ + ValueFilter { + enabled: true + roleName: "installationId" + value: root.installationId + inverted: true + } + ] + } + delegate: StatusSyncDeviceDelegate { width: ListView.view.width enabled: false diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index a5e530a9c2..ea8c39b7ef 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -676,10 +676,9 @@ QtObject { enum LocalPairingState { Idle = 0, - WaitingForConnection = 1, - Transferring = 2, - Error = 3, - Finished = 4 + Transferring = 1, + Error = 2, + Finished = 3 } readonly property var socialLinkPrefixesByType: [ // NB order must match the "socialLinkType" enum above diff --git a/vendor/status-go b/vendor/status-go index 4212dde288..c8161a5fa4 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 4212dde28870479b23e84249937456917532db5a +Subproject commit c8161a5fa4ba87f7ae9b1e1e50c2d2bc93123103