feat(ActivityCenter): Transfer ownership messages

- It created all possible AC notification types and notification component for transfer ownership flow.
- It adds `storybook` support for the new component.
- It adds call from activity center to finalise ownership popup.

Part of #12175

a
This commit is contained in:
Noelia 2023-10-23 13:35:20 +02:00 committed by Michał Iskierko
parent 1600b5fc11
commit e8c0275137
8 changed files with 403 additions and 31 deletions

View File

@ -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/KubaDesktop?type=design&node-id=35909-606817&mode=design&t=Ia7Z0AzyYIjkuPtr-0

View File

@ -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

View File

@ -10407,5 +10407,6 @@
<file>assets/twemoji/LICENSE</file>
<file>assets/twemoji/twemoji.js</file>
<file>assets/img/icons/caution.svg</file>
<file>assets/img/icons/crown-off.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,3 @@
<svg width="28" height="26" viewBox="0 0 28 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.9549 0.987813C3.58573 0.618646 2.98719 0.618646 2.61802 0.987813C2.24885 1.35698 2.24885 1.95552 2.61802 2.32469L25.3055 25.0122C25.6747 25.3814 26.2732 25.3814 26.6424 25.0122C27.0116 24.643 27.0116 24.0445 26.6424 23.6753L23.3299 20.3628C23.6235 17.5343 24.0069 14.0407 24.3528 11.4354C24.3908 11.1492 24.6215 10.9338 24.9006 10.8599C26.3238 10.4829 27.3728 9.1861 27.3728 7.64428C27.3728 5.80724 25.8836 4.31802 24.0467 4.31802C22.2097 4.31802 20.7206 5.80724 20.7206 7.64428C20.7206 7.74498 20.7251 7.84463 20.7338 7.94305C20.7628 8.26863 20.5998 8.60137 20.2835 8.68371C19.6748 8.84214 19.0616 8.89278 18.4754 8.79506C17.8947 8.69824 17.2895 8.44756 16.7031 7.93693C16.4397 7.70758 16.4749 7.30577 16.6901 7.03071C17.1319 6.46608 17.3953 5.75505 17.3953 4.98251C17.3953 3.14547 15.9062 1.65625 14.0692 1.65625C12.2322 1.65625 10.7431 3.14547 10.7431 4.98251C10.7431 5.75526 11.0066 6.46646 11.4486 7.03117C11.664 7.30626 11.6992 7.70821 11.4357 7.93756C11.3375 8.02303 11.2388 8.10122 11.1397 8.17262L3.9549 0.987813ZM12.4883 9.52118L20.3089 17.3418H21.1847C21.5063 17.3418 21.7763 17.0997 21.8116 16.7801C22.0325 14.7775 22.2714 12.7357 22.4949 11.0647C22.5306 10.7974 22.3855 10.5392 22.1634 10.3863C21.965 10.2498 21.7109 10.2037 21.4847 10.2863C20.4686 10.6573 19.3262 10.8536 18.1645 10.6599C16.898 10.4488 15.7042 9.79009 14.692 8.56955C14.5488 8.39688 14.3302 8.30615 14.1059 8.30858L14.0692 8.30877L14.0334 8.30859C13.8092 8.30622 13.5906 8.39695 13.4475 8.56956C13.1432 8.93652 12.8225 9.25269 12.4883 9.52118ZM2.1002 4.97993C2.32427 4.81216 2.63306 4.86056 2.83099 5.05849L7.2474 9.4749C7.6646 9.8921 7.33919 10.5249 6.78178 10.3315C6.71416 10.3081 6.64706 10.2838 6.58053 10.2588C6.40001 10.191 6.19807 10.2259 6.04195 10.3391C5.86813 10.4651 5.76697 10.675 5.80528 10.8863C6.12402 12.6437 6.44467 14.7782 6.67804 16.7806C6.71526 17.1 6.98496 17.3418 7.30645 17.3418H14.8533C15.0205 17.3418 15.1807 17.4082 15.2989 17.5264L15.9291 18.1566C16.3262 18.5536 16.045 19.2325 15.4835 19.2325H7.57389C7.21158 19.2325 6.92395 19.5371 6.94058 19.899C6.97251 20.5945 6.99671 21.3508 7.01223 22.0436C7.01993 22.3877 7.3003 22.6639 7.6445 22.6639H20.1753C20.3425 22.6639 20.5028 22.7303 20.621 22.8484L21.7041 23.9316C21.9364 24.1639 21.8567 24.5545 21.5283 24.5545H6.66482C5.82172 24.5545 5.14752 23.8729 5.13838 23.0419C5.12236 21.5866 5.05176 19.4392 4.94834 18.3789C4.73021 16.1425 4.35822 13.5414 3.98584 11.4508C3.93496 11.1652 3.69207 10.9595 3.40803 10.9002C1.89905 10.5849 0.765625 9.24696 0.765625 7.64428C0.765625 6.55419 1.28997 5.58658 2.1002 4.97993Z" fill="#FF2D55"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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)
}
}
}

View File

@ -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 {

View File

@ -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
}
}
}

View File

@ -1 +1,2 @@
ActivityNotificationCommunityMembershipRequest 1.0 ActivityNotificationCommunityMembershipRequest.qml
ActivityNotificationCommunityMembershipRequest 1.0 ActivityNotificationCommunityMembershipRequest.qml
ActivityNotificationTransferOwnership 1.0 ActivityNotificationTransferOwnership.qml