diff --git a/storybook/pages/ActivityNotificationCommunityMembershipRequestPage.qml b/storybook/pages/ActivityNotificationCommunityMembershipRequestPage.qml
index a9d40be7fb..45062bed24 100644
--- a/storybook/pages/ActivityNotificationCommunityMembershipRequestPage.qml
+++ b/storybook/pages/ActivityNotificationCommunityMembershipRequestPage.qml
@@ -58,11 +58,12 @@ SplitView {
valueRole: "value"
model: ListModel {
id: model
- ListElement { text: "Pending"; value: ActivityCenterStore.ActivityCenterMembershipStatus.Pending }
- ListElement { text: "Accepted"; value: ActivityCenterStore.ActivityCenterMembershipStatus.Accepted }
- ListElement { text: "Declined"; value: ActivityCenterStore.ActivityCenterMembershipStatus.Declined }
- ListElement { text: "AcceptedPending"; value: ActivityCenterStore.ActivityCenterMembershipStatus.AcceptedPending }
- ListElement { text: "DeclinedPending"; value: ActivityCenterStore.ActivityCenterMembershipStatus.DeclinedPending }
+
+ ListElement { text: "Pending"; value: 1 } // ActivityCenterStore.ActivityCenterMembershipStatus.Pending }
+ ListElement { text: "Accepted"; value: 2 } //ActivityCenterStore.ActivityCenterMembershipStatus.Accepted }
+ ListElement { text: "Declined"; value: 3 } //ActivityCenterStore.ActivityCenterMembershipStatus.Declined }
+ ListElement { text: "AcceptedPending"; value: 4 } //ActivityCenterStore.ActivityCenterMembershipStatus.AcceptedPending }
+ ListElement { text: "DeclinedPending"; value: 5 } //ActivityCenterStore.ActivityCenterMembershipStatus.DeclinedPending }
}
}
}
@@ -178,4 +179,5 @@ SplitView {
}
}
+// category: Activity Center
// https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=35909-606817&mode=design&t=Ia7Z0AzyYIjkuPtr-0
diff --git a/storybook/pages/ActivityNotificationTransferOwnershipPage.qml b/storybook/pages/ActivityNotificationTransferOwnershipPage.qml
new file mode 100644
index 0000000000..24a67044fa
--- /dev/null
+++ b/storybook/pages/ActivityNotificationTransferOwnershipPage.qml
@@ -0,0 +1,114 @@
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+import QtQuick.Layouts 1.15
+
+import Qt.labs.settings 1.0
+
+import mainui.activitycenter.views 1.0
+import mainui.activitycenter.stores 1.0
+
+import Storybook 1.0
+
+SplitView {
+ id: root
+
+ orientation: Qt.Vertical
+
+ Logs { id: logs }
+
+ QtObject {
+ id: notificationMock
+
+ property string id: "1"
+ property string communityId: "1"
+ property string sectionId: "1"
+ property int notificationType: 1
+ property int timestamp: Date.now()
+ property int previousTimestamp: 0
+ property bool read: false
+ property bool dismissed: false
+ property bool accepted: false
+ }
+
+ Item {
+ SplitView.fillHeight: true
+ SplitView.fillWidth: true
+
+ ActivityNotificationTransferOwnership {
+ id: notification
+
+ anchors.centerIn: parent
+ width: parent.width - 50
+ height: implicitHeight
+
+ type: ActivityNotificationTransferOwnership.OwnershipState.Pending
+ store: undefined
+ notification: notificationMock
+ communityName: communityNameText.text
+ communityColor: colorSwitch.checked ? "green" : "orange"
+
+ onFinaliseOwnershipClicked: logs.logEvent("ActivityNotificationOwnerTokenReceived::onFinaliseOwnershipClicked")
+ onNavigateToCommunityClicked: logs.logEvent("ActivityNotificationOwnerTokenReceived::onNavigateToCommunityClicked")
+ }
+
+ }
+
+ LogsAndControlsPanel {
+ SplitView.minimumHeight: 100
+ SplitView.preferredHeight: 160
+
+ logsView.logText: logs.logText
+
+ Column {
+ Row {
+ Label {
+ text: "Community Name: "
+ }
+
+ TextInput {
+ id: communityNameText
+
+ text: "Doodles"
+ }
+ }
+
+ Switch {
+ id: colorSwitch
+
+ text: "Orange OR Green"
+ checked: true
+ }
+
+ Row {
+ RadioButton {
+ text: "Pending"
+ checked: true
+ onCheckedChanged: if(checked) notification.type = ActivityNotificationTransferOwnership.OwnershipState.Pending
+ }
+
+ RadioButton {
+ text: "Declined"
+ onCheckedChanged: if(checked) notification.type = ActivityNotificationTransferOwnership.OwnershipState.Declined
+ }
+
+ RadioButton {
+ text: "Succeded"
+ onCheckedChanged: if(checked) notification.type = ActivityNotificationTransferOwnership.OwnershipState.Succeeded
+ }
+
+ RadioButton {
+ text: "Failed"
+ onCheckedChanged: if(checked) notification.type = ActivityNotificationTransferOwnership.OwnershipState.Failed
+ }
+
+ RadioButton {
+ text: "No longer control node"
+ onCheckedChanged: if(checked) notification.type = ActivityNotificationTransferOwnership.OwnershipState.NoLongerControlNode
+ }
+ }
+ }
+ }
+}
+
+// category: Activity Center
+// https://www.figma.com/file/qHfFm7C9LwtXpfdbxssCK3/Kuba%E2%8E%9CDesktop---Communities?type=design&node-id=37206%3A86911&mode=design&t=LuuR3YcDBwDkWIBw-1
diff --git a/ui/StatusQ/src/assets.qrc b/ui/StatusQ/src/assets.qrc
index be2f22ebd8..86c15111b7 100644
--- a/ui/StatusQ/src/assets.qrc
+++ b/ui/StatusQ/src/assets.qrc
@@ -10407,5 +10407,6 @@
assets/twemoji/LICENSE
assets/twemoji/twemoji.js
assets/img/icons/caution.svg
+ assets/img/icons/crown-off.svg
diff --git a/ui/StatusQ/src/assets/img/icons/crown-off.svg b/ui/StatusQ/src/assets/img/icons/crown-off.svg
new file mode 100644
index 0000000000..2e3cfe7ef7
--- /dev/null
+++ b/ui/StatusQ/src/assets/img/icons/crown-off.svg
@@ -0,0 +1,3 @@
+
diff --git a/ui/app/mainui/activitycenter/popups/ActivityCenterPopup.qml b/ui/app/mainui/activitycenter/popups/ActivityCenterPopup.qml
index 35a07ad510..e649556c57 100644
--- a/ui/app/mainui/activitycenter/popups/ActivityCenterPopup.qml
+++ b/ui/app/mainui/activitycenter/popups/ActivityCenterPopup.qml
@@ -4,6 +4,7 @@ import QtGraphicalEffects 1.15
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
+import StatusQ.Core.Theme 0.1
import shared 1.0
import shared.popups 1.0
@@ -72,8 +73,8 @@ Popup {
onGroupTriggered: activityCenterStore.setActiveNotificationGroup(group)
onMarkAllReadClicked: activityCenterStore.markAllActivityCenterNotificationsRead()
onShowHideReadNotifications: activityCenterStore.setActivityCenterReadType(hideReadNotifications ?
- ActivityCenterStore.ActivityCenterReadType.Unread :
- ActivityCenterStore.ActivityCenterReadType.All)
+ ActivityCenterStore.ActivityCenterReadType.Unread :
+ ActivityCenterStore.ActivityCenterReadType.All)
}
StatusListView {
@@ -95,28 +96,34 @@ Popup {
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
- default:
- return null
+ 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.OwnerTokenReceived:
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipSucceeded:
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipFailed:
+ case ActivityCenterStore.ActivityCenterNotificationType.NoLongerControlNode:
+ return ownerTokenReceivedNotificationComponent
+ default:
+ return null
}
}
}
@@ -232,4 +239,27 @@ Popup {
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)
+ }
+ }
}
diff --git a/ui/app/mainui/activitycenter/stores/ActivityCenterStore.qml b/ui/app/mainui/activitycenter/stores/ActivityCenterStore.qml
index 76a81f2ae4..44b3710465 100644
--- a/ui/app/mainui/activitycenter/stores/ActivityCenterStore.qml
+++ b/ui/app/mainui/activitycenter/stores/ActivityCenterStore.qml
@@ -30,7 +30,12 @@ QtObject {
CommunityKicked = 9,
ContactVerification = 10,
ContactRemoved = 11,
- NewKeypairAddedToPairedDevice = 12
+ NewKeypairAddedToPairedDevice = 12,
+ OwnerTokenReceived = 13,
+ OwnershipDeclined = 14,
+ OwnershipSucceeded = 15,
+ OwnershipFailed = 16,
+ NoLongerControlNode = 17
}
enum ActivityCenterReadType {
diff --git a/ui/app/mainui/activitycenter/views/ActivityNotificationTransferOwnership.qml b/ui/app/mainui/activitycenter/views/ActivityNotificationTransferOwnership.qml
new file mode 100644
index 0000000000..298b76617e
--- /dev/null
+++ b/ui/app/mainui/activitycenter/views/ActivityNotificationTransferOwnership.qml
@@ -0,0 +1,216 @@
+import QtQuick 2.14
+import QtQuick.Layouts 1.14
+
+import StatusQ.Controls 0.1
+import StatusQ.Core 0.1
+import StatusQ.Core.Theme 0.1
+import StatusQ.Components 0.1
+
+import shared 1.0
+import shared.panels 1.0
+import utils 1.0
+
+import "../panels"
+import "../popups"
+import "../stores"
+
+ActivityNotificationBase {
+ id: root
+
+ required property string communityName
+ required property string communityColor
+ required property int type // Possible values [OwnershipState]
+
+ signal finaliseOwnershipClicked
+ signal navigateToCommunityClicked
+
+ function setType(notification) {
+ if(notification)
+ switch(notification.notificationType){
+
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnerTokenReceived:
+ return ActivityNotificationTransferOwnership.OwnershipState.Pending
+
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipDeclined:
+ return ActivityNotificationTransferOwnership.OwnershipState.Declined
+
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipReceived:
+ return ActivityNotificationTransferOwnership.OwnershipState.Succeeded
+
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipFailed:
+ return ActivityNotificationTransferOwnership.OwnershipState.Failed
+
+ case ActivityCenterStore.ActivityCenterNotificationType.OwnershipLost:
+ return ActivityNotificationTransferOwnership.OwnershipState.NoLongerControlNode
+
+ }
+ return ActivityNotificationTransferOwnership.OwnershipState.Failed
+ }
+
+ enum OwnershipState {
+ Pending,
+ Declined,
+ Succeeded,
+ Failed,
+ NoLongerControlNode
+ }
+
+ QtObject {
+ id: d
+
+ property string title: ""
+ property string info: ""
+ property string assetColor: ""
+ property string assetName: ""
+ property string assetBgColor: ""
+ property string ctaText: ""
+ property var actionSourceComponent: undefined
+
+ readonly property string crownAssetName: "crown"
+ }
+
+ bodyComponent: RowLayout {
+ spacing: 8
+
+ StatusSmartIdenticon {
+ Layout.preferredWidth: 40
+ Layout.preferredHeight: 40
+ Layout.alignment: Qt.AlignTop
+ Layout.leftMargin: Style.current.padding
+ Layout.topMargin: 2
+
+ asset {
+ width: 24
+ height: width
+ name: d.assetName
+ color: d.assetColor
+ bgWidth: 40
+ bgHeight: 40
+ bgColor: d.assetBgColor
+ }
+ }
+
+ ColumnLayout {
+ spacing: 2
+ Layout.alignment: Qt.AlignTop
+ Layout.fillWidth: true
+
+ StatusMessageHeader {
+ displayNameLabel.text: d.title
+ timestamp: root.notification.timestamp
+ }
+
+ RowLayout {
+ spacing: Style.current.padding
+
+ StatusBaseText {
+ Layout.fillWidth: true
+ text: d.info
+ font.italic: true
+ wrapMode: Text.WordWrap
+ color: Theme.palette.baseColor1
+ }
+
+ Loader { sourceComponent: d.actionSourceComponent }
+
+ }
+ }
+ }
+
+ ctaComponent: undefined
+
+ states: [
+ State {
+ when: root.type === ActivityNotificationTransferOwnership.OwnershipState.Pending
+ PropertyChanges {
+ target: d
+ title: qsTr("You received the owner token from %1").arg(root.communityName)
+ info: qsTr("To finalise your ownership of the %1 Community, make your device the control node").arg(root.communityName)
+ ctaText: qsTr("Finalise ownership")
+ assetColor: root.communityColor
+ assetBgColor: Theme.palette.getColor(d.assetColor, 0.1)
+ assetName: d.crownAssetName
+ actionSourceComponent: ctaFlatBtnComponent
+ }
+ },
+ State {
+ when: root.type === ActivityNotificationTransferOwnership.OwnershipState.Declined
+ PropertyChanges {
+ target: d
+ title: qsTr("You received the owner token from %1").arg(root.communityName)
+ info: qsTr("To finalise your ownership of the %1 Community, make your device the control node").arg(root.communityName)
+ ctaText: qsTr("Ownership Declined")
+ assetColor: root.communityColor
+ assetBgColor: Theme.palette.getColor(d.assetColor, 0.1)
+ assetName: d.crownAssetName
+ actionSourceComponent: ctaTextComponent
+ }
+ },
+ State {
+ when: root.type === ActivityNotificationTransferOwnership.OwnershipState.Succeeded
+ PropertyChanges {
+ target: d
+ title: qsTr("Your device is now the control node for %1").arg(root.communityName)
+ info: qsTr("Congratulations, you are now the official owner of the %1 Community with full admin rights").arg(root.communityName)
+ ctaText: qsTr("Community admin")
+ assetColor: root.communityColor
+ assetBgColor: Theme.palette.getColor(d.assetColor, 0.1)
+ assetName: d.crownAssetName
+ actionSourceComponent: ctaFlatBtnComponent
+ }
+ },
+ State {
+ when: root.type === ActivityNotificationTransferOwnership.OwnershipState.Failed
+ PropertyChanges {
+ target: d
+ title: qsTr("%1 smart contract update failed").arg(root.communityName)
+ info: qsTr("You will need to retry the transaction in order to finalise your ownership of the %1 community").arg(root.communityName)
+ ctaText: qsTr("Finalise ownership")
+ assetColor: Theme.palette.dangerColor1
+ assetBgColor: Theme.palette.dangerColor3
+ assetName: "warning"
+ actionSourceComponent: ctaFlatBtnComponent
+ }
+ },
+ State {
+ when: root.type === ActivityNotificationTransferOwnership.OwnershipState.NoLongerControlNode
+ PropertyChanges {
+ target: d
+ title: qsTr("Your device is no longer the control node for %1").arg(root.communityName)
+ info: qsTr("Your ownership and admin rights for %1 have been removed and transferred to the new owner").arg(root.communityName)
+ ctaText: ""
+ assetColor: Theme.palette.dangerColor1
+ assetBgColor: Theme.palette.dangerColor3
+ assetName: "crown-off"
+ actionSourceComponent: undefined
+ }
+ }
+ ]
+
+ Component {
+ id: ctaFlatBtnComponent
+
+ StatusFlatButton {
+ size: StatusBaseButton.Size.Small
+ text: d.ctaText
+ onClicked: {
+ if((root.type === ActivityNotificationTransferOwnership.OwnershipState.Pending) ||
+ (root.type === ActivityNotificationTransferOwnership.OwnershipState.Failed))
+ root.finaliseOwnershipClicked()
+ else if(root.type === ActivityNotificationTransferOwnership.OwnershipState.Succeeded)
+ root.navigateToCommunityClicked()
+ }
+ }
+ }
+
+ Component {
+ id: ctaTextComponent
+
+ StatusBaseText {
+ text: d.ctaText
+ font.pixelSize: Style.current.additionalTextSize
+ color: Theme.palette.dangerColor1
+ padding: 10
+ }
+ }
+}
diff --git a/ui/app/mainui/activitycenter/views/qmldir b/ui/app/mainui/activitycenter/views/qmldir
index 675ac97c5e..64e97907d0 100644
--- a/ui/app/mainui/activitycenter/views/qmldir
+++ b/ui/app/mainui/activitycenter/views/qmldir
@@ -1 +1,2 @@
-ActivityNotificationCommunityMembershipRequest 1.0 ActivityNotificationCommunityMembershipRequest.qml
\ No newline at end of file
+ActivityNotificationCommunityMembershipRequest 1.0 ActivityNotificationCommunityMembershipRequest.qml
+ActivityNotificationTransferOwnership 1.0 ActivityNotificationTransferOwnership.qml