mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-28 23:35:13 +00:00
252061d8e8
Fixes #15750 When the pairing fails, the UI now let's the user use the seed phrase instead. When they do, a call is send to the original device and both instances will show an AC notif. When the original device accepts the pairing, the call is made to pair and sync the devices and the AC notifs get deleted
499 lines
18 KiB
QML
499 lines
18 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtGraphicalEffects 1.15
|
|
import QtQml.Models 2.15
|
|
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Core 0.1
|
|
import StatusQ.Core.Backpressure 0.1
|
|
import StatusQ.Core.Theme 0.1
|
|
import StatusQ.Popups.Dialog 0.1
|
|
|
|
import shared 1.0
|
|
import shared.popups 1.0
|
|
import shared.views.chat 1.0
|
|
|
|
import utils 1.0
|
|
|
|
import AppLayouts.Chat.stores 1.0 as ChatStores
|
|
|
|
import "../views"
|
|
import "../panels"
|
|
import "../stores"
|
|
|
|
Popup {
|
|
id: root
|
|
|
|
property ActivityCenterStore activityCenterStore
|
|
property ChatStores.RootStore store
|
|
|
|
onOpened: {
|
|
Global.activityPopupOpened = true
|
|
}
|
|
onClosed: {
|
|
Global.activityPopupOpened = false
|
|
Qt.callLater(activityCenterStore.markAsSeenActivityCenterNotifications)
|
|
}
|
|
|
|
width: 560
|
|
padding: 0
|
|
modal: true
|
|
parent: Overlay.overlay
|
|
|
|
QtObject {
|
|
id: d
|
|
|
|
readonly property var loadMoreNotificationsIfScrollBelowThreshold: Backpressure.oneInTimeQueued(root, 100, function() {
|
|
if (listView.contentY >= listView.contentHeight - listView.height - 1) {
|
|
root.activityCenterStore.fetchActivityCenterNotifications()
|
|
}
|
|
})
|
|
}
|
|
|
|
Overlay.modal: MouseArea { // eat every event behind the popup
|
|
hoverEnabled: true
|
|
onPressed: (event) => {
|
|
event.accept()
|
|
root.close()
|
|
}
|
|
onWheel: (event) => event.accept()
|
|
}
|
|
|
|
background: Rectangle {
|
|
color: Style.current.background
|
|
radius: Style.current.radius
|
|
layer.enabled: true
|
|
layer.effect: DropShadow {
|
|
verticalOffset: 3
|
|
radius: Style.current.radius
|
|
samples: 15
|
|
fast: true
|
|
cached: true
|
|
color: Style.current.dropShadow
|
|
}
|
|
}
|
|
|
|
ActivityCenterPopupTopBarPanel {
|
|
id: activityCenterTopBar
|
|
width: parent.width
|
|
unreadNotificationsCount: activityCenterStore.unreadNotificationsCount
|
|
hasAdmin: activityCenterStore.adminCount > 0
|
|
hasReplies: activityCenterStore.repliesCount > 0
|
|
hasMentions: activityCenterStore.mentionsCount > 0
|
|
hasContactRequests: activityCenterStore.contactRequestsCount > 0
|
|
hasIdentityVerification: activityCenterStore.identityVerificationCount > 0
|
|
hasMembership: activityCenterStore.membershipCount > 0
|
|
hideReadNotifications: activityCenterStore.activityCenterReadType === ActivityCenterStore.ActivityCenterReadType.Unread
|
|
activeGroup: activityCenterStore.activeNotificationGroup
|
|
onGroupTriggered: activityCenterStore.setActiveNotificationGroup(group)
|
|
onMarkAllReadClicked: activityCenterStore.markAllActivityCenterNotificationsRead()
|
|
onShowHideReadNotifications: activityCenterStore.setActivityCenterReadType(hideReadNotifications ?
|
|
ActivityCenterStore.ActivityCenterReadType.Unread :
|
|
ActivityCenterStore.ActivityCenterReadType.All)
|
|
}
|
|
|
|
StatusListView {
|
|
id: listView
|
|
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: activityCenterTopBar.bottom
|
|
anchors.bottom: parent.bottom
|
|
anchors.margins: Style.current.smallPadding
|
|
spacing: 1
|
|
|
|
model: root.activityCenterStore.activityCenterNotifications
|
|
|
|
onContentYChanged: d.loadMoreNotificationsIfScrollBelowThreshold()
|
|
|
|
delegate: Loader {
|
|
width: listView.availableWidth
|
|
|
|
property int filteredIndex: index
|
|
property var notification: model
|
|
|
|
sourceComponent: {
|
|
switch (model.notificationType) {
|
|
case ActivityCenterStore.ActivityCenterNotificationType.Mention:
|
|
return mentionNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.Reply:
|
|
return replyNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactRequest:
|
|
return contactRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactVerification:
|
|
return verificationRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityInvitation:
|
|
return communityInvitationNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityMembershipRequest:
|
|
return membershipRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityRequest:
|
|
return communityRequestNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityKicked:
|
|
return communityKickedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ContactRemoved:
|
|
return contactRemovedComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewKeypairAddedToPairedDevice:
|
|
return newKeypairFromPairedDeviceComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityTokenReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.FirstCommunityTokenReceived:
|
|
return communityTokenReceivedComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnerTokenReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipLost:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipFailed:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
|
|
return ownerTokenReceivedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.ShareAccounts:
|
|
return shareAccountsNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityBanned:
|
|
return communityBannedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.CommunityUnbanned:
|
|
return communityUnbannedNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewPrivateGroupChat:
|
|
return groupChatInvitationNotificationComponent
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewInstallationReceived:
|
|
case ActivityCenterStore.ActivityCenterNotificationType.NewInstallationCreated:
|
|
return newDeviceDetectedComponent
|
|
default:
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: mentionNotificationComponent
|
|
|
|
ActivityNotificationMention {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: replyNotificationComponent
|
|
|
|
ActivityNotificationReply {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: contactRequestNotificationComponent
|
|
|
|
ActivityNotificationContactRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: verificationRequestNotificationComponent
|
|
|
|
ActivityNotificationContactVerification {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityInvitationNotificationComponent
|
|
|
|
ActivityNotificationCommunityInvitation {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: membershipRequestNotificationComponent
|
|
|
|
ActivityNotificationCommunityMembershipRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityRequestNotificationComponent
|
|
|
|
ActivityNotificationCommunityRequest {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
Component {
|
|
id: communityKickedNotificationComponent
|
|
|
|
ActivityNotificationCommunityKicked {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityBannedNotificationComponent
|
|
|
|
ActivityNotificationCommunityBanUnban {
|
|
banned: true
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityUnbannedNotificationComponent
|
|
|
|
ActivityNotificationCommunityBanUnban {
|
|
banned: false
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: contactRemovedComponent
|
|
|
|
ActivityNotificationContactRemoved {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: newKeypairFromPairedDeviceComponent
|
|
|
|
ActivityNotificationNewKeypairFromPairedDevice {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: ownerTokenReceivedNotificationComponent
|
|
|
|
ActivityNotificationTransferOwnership {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
type: setType(notification)
|
|
|
|
communityName: community ? community.name : ""
|
|
communityColor: community ? community.color : Theme.palette.directColor1
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
|
|
onFinaliseOwnershipClicked: Global.openFinaliseOwnershipPopup(notification.communityId)
|
|
onNavigateToCommunityClicked: root.store.setActiveCommunity(notification.communityId)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: newDeviceDetectedComponent
|
|
|
|
ActivityNotificationNewDevice {
|
|
type: setType(notification)
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
accountName: store.name
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
onMoreDetailsClicked: {
|
|
switch (type) {
|
|
case ActivityNotificationNewDevice.InstallationType.Received:
|
|
Global.openPopup(pairDeviceDialog, {
|
|
name: store.name,
|
|
deviceId: notification.installationId
|
|
});
|
|
break;
|
|
case ActivityNotificationNewDevice.InstallationType.Created:
|
|
Global.openPopup(checkOtherDeviceDialog, {
|
|
deviceId: notification.installationId
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityTokenReceivedComponent
|
|
|
|
ActivityNotificationCommunityTokenReceived {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
communityId: notification.communityId
|
|
communityName: community ? community.name : ""
|
|
communityImage: community ? community.image : ""
|
|
|
|
store: root.store
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: shareAccountsNotificationComponent
|
|
|
|
ActivityNotificationCommunityShareAddresses {
|
|
|
|
readonly property var community : notification ? root.store.getCommunityDetailsAsJson(notification.communityId) : null
|
|
|
|
communityName: community ? community.name : ""
|
|
communityColor: community ? community.color : "transparent"
|
|
communityImage: community ? community.image : ""
|
|
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
|
|
onOpenShareAccountsClicked: {
|
|
Global.communityShareAddressesPopupRequested(notification.communityId, communityName, communityImage)
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: groupChatInvitationNotificationComponent
|
|
|
|
ActivityNotificationUnknownGroupChatInvitation {
|
|
filteredIndex: parent.filteredIndex
|
|
notification: parent.notification
|
|
store: root.store
|
|
activityCenterStore: root.activityCenterStore
|
|
onCloseActivityCenter: root.close()
|
|
}
|
|
}
|
|
|
|
function truncateDeviceId(deviceId) {
|
|
return deviceId.substring(0, 7).toUpperCase()
|
|
}
|
|
|
|
Component {
|
|
id: pairDeviceDialog
|
|
|
|
StatusDialog {
|
|
property string name
|
|
property string deviceId
|
|
|
|
width: 480
|
|
closePolicy: Popup.CloseOnPressOutside
|
|
destroyOnClose: true
|
|
|
|
title: qsTr("Pair new device and sync profile")
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 16
|
|
StatusBaseText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("New device with %1 profile has been detected. You can see the device ID below and on your other device. Only confirm the request if the device ID matches.")
|
|
.arg(name)
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
StatusBaseText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
font.pixelSize: 27
|
|
font.weight: Font.Medium
|
|
font.letterSpacing: 5
|
|
text: truncateDeviceId(deviceId)
|
|
}
|
|
}
|
|
|
|
footer: StatusDialogFooter {
|
|
leftButtons: ObjectModel {
|
|
StatusFlatButton {
|
|
text: qsTr("Cancel")
|
|
onClicked: {
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
rightButtons: ObjectModel {
|
|
StatusButton {
|
|
text: qsTr("Pair and Sync")
|
|
onClicked: {
|
|
activityCenterStore.enableInstallationAndSync(deviceId)
|
|
close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: checkOtherDeviceDialog
|
|
|
|
StatusDialog {
|
|
property string deviceId
|
|
|
|
width: 480
|
|
closePolicy: Popup.CloseOnPressOutside
|
|
destroyOnClose: true
|
|
|
|
title: qsTr("Pair this device and sync profile")
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 16
|
|
StatusBaseText {
|
|
Layout.fillWidth: true
|
|
text: qsTr("Check your other device for a pairing request. Ensure that the this device ID displayed on your other device. Only proceed with pairing and syncing if the IDs are identical.")
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
StatusBaseText {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
font.pixelSize: 27
|
|
font.weight: Font.Medium
|
|
font.letterSpacing: 5
|
|
text: truncateDeviceId(deviceId)
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
footer: null
|
|
}
|
|
}
|
|
}
|