fix(EditCommunity): Added transfer ownership&backup popups

Closes #7411
This commit is contained in:
Alexandra Betouni 2022-09-21 12:57:55 +03:00
parent 36a56a8af3
commit 9978be18cb
17 changed files with 307 additions and 151 deletions

View File

@ -0,0 +1,17 @@
import QtQuick 2.14
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
color: Theme.palette.primaryColor1
implicitWidth: 2
implicitHeight: 22
radius: 1
SequentialAnimation on visible {
loops: Animation.Infinite
running: parent.visible
PropertyAnimation { to: false; duration: 600; }
PropertyAnimation { to: true; duration: 600; }
}
}

View File

@ -25,6 +25,7 @@ Rectangle {
property real rightPadding: 16
property bool highlighted: false
property bool propagateTitleClicks: true
property bool elideText: true
property int type: StatusListItem.Type.Primary
property list<Item> components
property var bottomModel: []
@ -207,7 +208,8 @@ Rectangle {
text: statusListItem.title
font.pixelSize: 15
height: visible ? contentHeight : 0
elide: Text.ElideRight
elide: statusListItem.elideText ? Text.ElideRight : Text.ElideNone
wrapMode: statusListItem.elideText ? Text.NoWrap : Text.WordWrap
anchors.left: parent.left
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20

View File

@ -45,3 +45,4 @@ StatusCard 0.1 StatusCard.qml
StatusDatePicker 0.1 StatusDatePicker.qml
StatusChart 0.1 StatusChart.qml
StatusChartPanel 0.1 StatusChartPanel.qml
StatusCursorDelegate 0.1 StatusCursorDelegate.qml

View File

@ -384,19 +384,8 @@ Item {
}
}
cursorDelegate: Rectangle {
color: Theme.palette.primaryColor1
implicitWidth: 2
implicitHeight: 22
radius: 1
cursorDelegate: StatusCursorDelegate {
visible: edit.cursorVisible
SequentialAnimation on visible {
loops: Animation.Infinite
running: edit.cursorVisible
PropertyAnimation { to: false; duration: 600; }
PropertyAnimation { to: true; duration: 600; }
}
}
StatusBaseText {

View File

@ -2,6 +2,7 @@ import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
/*!
\qmltype StatusTextArea
@ -94,18 +95,7 @@ TextArea {
}
}
cursorDelegate: Rectangle {
color: Theme.palette.primaryColor1
implicitWidth: 2
implicitHeight: 22
radius: 1
cursorDelegate: StatusCursorDelegate {
visible: root.cursorVisible
SequentialAnimation on visible {
loops: Animation.Infinite
running: root.cursorVisible
PropertyAnimation { to: false; duration: 600 }
PropertyAnimation { to: true; duration: 600 }
}
}
}

View File

@ -44,6 +44,8 @@ StatusModal {
}
}
signal backButtonPressed()
Component.onCompleted: updateRightButtons()
onCurrentIndexChanged: updateRightButtons()
onReplaceItemChanged: updateRightButtons()
@ -56,6 +58,7 @@ StatusModal {
id: backButton
visible: replaceItem || stackLayout.currentIndex > 0
onClicked: {
root.backButtonPressed();
if (replaceItem) {
replaceItem = null;
} else {

View File

@ -49,6 +49,12 @@ StackLayout {
onCreateCommunityClicked: {
root.createCommunityClicked();
}
onBackupButtonClicked: {
Global.openPopup(backupCommunityPopup, {
store: root.rootStore,
privateKey: root.rootStore.chatCommunitySectionModule.exportCommunity(root.communityId),
})
}
}
Loader {
@ -62,14 +68,27 @@ StackLayout {
community: root.rootStore.mainModuleInst ? root.rootStore.mainModuleInst.activeSection
|| {} : {}
onBackToCommunityClicked: root.currentIndex = 0
onBackToCommunityClicked: root.currentIndex = 0
// TODO: remove me when migration to new settings is done
onOpenLegacyPopupClicked: Global.openPopup(Global.communityProfilePopup, {
// TODO: remove me when migration to new settings is done
onOpenLegacyPopupClicked: Global.openPopup(Global.communityProfilePopup, {
"store": root.rootStore,
"community": community,
"communitySectionModule": chatCommunitySectionModule
})
onBackupButtonClicked: {
Global.openPopup(backupCommunityPopup, {
store: root.rootStore,
privateKey: root.rootStore.chatCommunitySectionModule.exportCommunity(root.communityId),
})
}
}
}
Component {
id: backupCommunityPopup
BackUpCommunityPopup {
anchors.centerIn: parent
}
}
}

View File

@ -17,6 +17,7 @@ Item {
property Component content
// optional
property list<Item> headerComponents
property string previousPage
property bool dirty: false
property bool editable: false
@ -39,6 +40,14 @@ Item {
settingsDirtyToastMessage.notifyDirty()
}
Component.onCompleted: {
if (headerComponents.length) {
for (let i in headerComponents) {
headerComponents[i].parent = titleRow;
}
}
}
implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight
@ -60,13 +69,20 @@ Item {
onClicked: root.previousPageClicked()
}
StatusBaseText {
RowLayout {
id: titleRow
Layout.fillWidth: true
height: 56
Layout.leftMargin: 36
text: root.title
color: Theme.palette.directColor1
font.pixelSize: 26
font.bold: true
Layout.rightMargin: 24
visible: root.title !== ""
StatusBaseText {
Layout.fillWidth: true
text: root.title
color: Theme.palette.directColor1
font.pixelSize: 26
font.bold: true
}
}
Loader {

View File

@ -5,6 +5,7 @@ import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Popups.Dialog 0.1
@ -89,17 +90,8 @@ Item {
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
color: Theme.palette.directColor1
cursorDelegate: Rectangle {
color: Theme.palette.primaryColor1
implicitWidth: 2
radius: 1
cursorDelegate: StatusCursorDelegate {
visible: edit.cursorVisible
SequentialAnimation on visible {
loops: Animation.Infinite
running: edit.cursorVisible
PropertyAnimation { to: false; duration: 600; }
PropertyAnimation { to: true; duration: 600; }
}
}
Keys.onPressed: {

View File

@ -39,6 +39,7 @@ StackLayout {
signal inviteNewPeopleClicked
signal airdropTokensClicked
signal backUpClicked
signal transferOwnershipClicked
clip: true
@ -159,11 +160,23 @@ StackLayout {
SettingsPageLayout {
id: editCommunityPage
previousPage: qsTr("Overview")
title: qsTr("Edit Community")
editable: true
headerComponents: [
StatusListItem {
implicitWidth: 229
implicitHeight: 38
leftPadding: 0
rightPadding: 0
title: qsTr("Transfer Owner Node")
asset.name: "exchange"
type: StatusListItem.Type.Secondary
onClicked: {
root.transferOwnershipClicked();
}
}
]
content: CommunityEditSettingsPanel {
name: root.name
description: root.description

View File

@ -0,0 +1,142 @@
import QtQuick 2.12
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import utils 1.0
import shared.controls 1.0
import shared 1.0
StatusStackModal {
id: root
property var store
property string privateKey
property int maximumLength: 4
width: 480
height: 504
header.title: (currentIndex === 0) ? qsTr("Back up community key")
: qsTr("Confirm your community key")
padding: Style.current.padding
stackItems: [
ColumnLayout {
spacing: Style.current.halfPadding
StatusInput {
id: pKeyInput
Layout.fillWidth: true
leftPadding: 14
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
label: qsTr("Your community key")
minimumHeight: 56
maximumHeight: 56
input.text: Utils.getElidedPk(root.privateKey)
input.edit.readOnly: true
input.rightComponent: StatusButton {
anchors.verticalCenter: parent.verticalCenter
borderColor: Theme.palette.primaryColor1
size: StatusBaseButton.Size.Tiny
text: qsTr("Copy")
onClicked: {
text = qsTr("Copied");
root.store.copyToClipboard(root.privateKey);
}
}
}
StatusBaseText {
Layout.fillWidth: true
Layout.preferredHeight: 36
Layout.topMargin: Style.current.halfPadding
text: qsTr("You should keep it safe and only share it with people you trust to take ownership of your community")
wrapMode: Text.WordWrap
font.pixelSize: 13
color: Theme.palette.baseColor1
}
StatusBaseText {
Layout.fillWidth: true
Layout.preferredHeight: 34
text: qsTr("You can also use this key to import your community on another device")
wrapMode: Text.WordWrap
font.pixelSize: 13
color: Theme.palette.baseColor1
}
},
Item {
TextEdit {
id: validationInput
property string previousText: text
width: parent.width
height: 24
anchors.centerIn: parent
anchors.verticalCenterOffset: -indicationText.height
horizontalAlignment: Text.AlignHCenter
color: Theme.palette.baseColor1
cursorDelegate: StatusCursorDelegate {
implicitHeight: 24
visible: indicationText.cursorVisible
}
onTextChanged: {
if (previousText === text) {
// Not sure why, but the textChanged event was triggered even if it didn't really
return
}
if (root.maximumLength > 0) {
if (text.length > root.maximumLength) {
var cursor = cursorPosition;
text = previousText;
if (cursor > text.length) {
cursorPosition = text.length;
} else {
cursorPosition = cursor - 1;
}
}
previousText = text;
}
}
}
StatusBaseText {
id: indicationText
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.halfPadding
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("Write down <font color=\"%1\">last %n character(s)</font> of your private key", "", root.maximumLength).arg(Theme.palette.directColor1)
}
}
]
onBackButtonPressed: {
validationInput.text = "";
}
nextButton: StatusButton {
text: qsTr("Next")
onClicked: {
root.currentIndex++;
validationInput.forceActiveFocus();
}
}
finishButton: StatusButton {
enabled: (validationInput.text === root.privateKey.slice(root.privateKey.length - 4, root.privateKey.length))
text: qsTr("Finish")
onClicked: {
root.close();
}
}
}

View File

@ -6,6 +6,7 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import utils 1.0
@ -15,36 +16,40 @@ import shared 1.0
StatusModal {
id: root
property string privateKey
property var store
property string privateKey
property string communityName
header.title: qsTr("Transfer ownership")
padding: 16
width: 640
height: 472 - 46 //TODO remove when below functionality is implemented
header.title: qsTr("Transfer ownership of %1 community").arg(root.communityName)
padding: Style.current.padding
ColumnLayout {
anchors.fill: parent
spacing: Style.current.padding
spacing: 16
StatusBaseText {
Layout.fillWidth: true
text: qsTr("I acknowledge that I lose ownership of this community by leaving and not saving the community key. I acknowledge that I lose ownership of this community by leaving and not saving the community key.")
wrapMode: Text.WordWrap
font.pixelSize: 15
}
StatusInput {
id: pKeyInput
Layout.fillWidth: true
readonly property string elidedPkey: Utils.elideText(root.privateKey, 16)
leftPadding: 0
rightPadding: 0
label: qsTr("Community private key")
input.text: elidedPkey
Layout.preferredHeight: 81
leftPadding: 14
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
label: qsTr("Your Community's private key")
minimumHeight: 56
maximumHeight: 56
input.text: Utils.getElidedPk(root.privateKey)
input.edit.readOnly: true
input.edit.onActiveFocusChanged: {
pKeyInput.input.text = pKeyInput.input.edit.focus ? root.privateKey : elidedPkey
}
input.rightComponent: StatusButton {
anchors.right: parent.right
anchors.rightMargin: Style.current.halfPadding
anchors.verticalCenter: parent.verticalCenter
borderColor: Theme.palette.primaryColor1
size: StatusBaseButton.Size.Tiny
@ -56,30 +61,43 @@ StatusModal {
}
}
StatusBaseText {
RowLayout {
Layout.fillWidth: true
text: qsTr("You should keep it safe and only share it with people you trust to take ownership of your community")
wrapMode: Text.WordWrap
font.pixelSize: 13
color: Theme.palette.baseColor1
Layout.preferredHeight: 76
StatusBaseText {
Layout.preferredWidth: 466
Layout.alignment: Qt.AlignVCenter
font.pixelSize: 15
wrapMode: Text.WordWrap
text: qsTr("I acknowledge that I lose ownership of this community by leaving and not saving the community key.")
}
Item { Layout.fillWidth: true }
StatusSwitch {
id: acknowledgeSwitch
Layout.alignment: Qt.AlignVCenter
}
}
StatusBaseText {
Layout.fillWidth: true
text: qsTr("You can also use this key to import your community on another device")
wrapMode: Text.WordWrap
font.pixelSize: 13
color: Theme.palette.baseColor1
}
//TODO remove when below functionality is implemented?
Item { Layout.fillHeight: true }
//TODO uncomment when functionality is implemented
// StatusBaseText {
// Layout.fillWidth: true
// Layout.topMargin: Style.current.halfPadding
// text: qsTr("This is the only Owner Node running this community at the moment")
// wrapMode: Text.WordWrap
// horizontalAlignment: Text.AlignHCenter
// font.pixelSize: 15
// color: Theme.palette.dangerColor1
// }
}
leftButtons: [
StatusBackButton {
onClicked: {
root.close()
}
rightButtons: [
StatusButton {
text: qsTr("Stop Being Community Owner Node")
enabled: acknowledgeSwitch.checked
type: enabled ? StatusBaseButton.Type.Danger : StatusBaseButton.Type.Normal
onClicked: { root.close(); }
}
]
}

View File

@ -37,6 +37,7 @@ StatusSectionLayout {
signal communityManageButtonClicked()
signal profileButtonClicked()
signal openAppSearch()
signal backupButtonClicked()
signal importCommunityClicked()
signal createCommunityClicked()
@ -160,6 +161,7 @@ StatusSectionLayout {
membershipRequestPopup: root.membershipRequestPopup
onInfoButtonClicked: root.communityInfoButtonClicked()
onManageButtonClicked: root.communityManageButtonClicked()
onBackupButtonClicked: root.backupButtonClicked()
}
}

View File

@ -36,6 +36,7 @@ Item {
signal infoButtonClicked
signal manageButtonClicked
signal backupButtonClicked
MouseArea {
enabled: communityData.amISectionAdmin
@ -437,12 +438,7 @@ Item {
BackUpCommuntyBannerPanel {
id: backupBanner
communityId: communityData.id
onBackupButtonClicked: {
Global.openPopup(transferOwnershipPopup, {
privateKey: communitySectionModule.exportCommunity(communityData.id),
store: root.store
})
}
onBackupButtonClicked: { root.backupButtonClicked(); }
}
}
} // Loader
@ -538,21 +534,6 @@ Item {
standardButtons: StandardButton.Ok
}
Component {
id: transferOwnershipPopup
TransferOwnershipPopup {
anchors.centerIn: parent
onClosed: {
let hiddenBannerIds = localAccountSensitiveSettings.hiddenCommunityBackUpBanners || []
if (hiddenBannerIds.includes(root.store.activeCommunity.id)) {
return
}
hiddenBannerIds.push(root.store.activeCommunity.id)
localAccountSensitiveSettings.hiddenCommunityBackUpBanners = hiddenBannerIds
}
}
}
Connections {
target: root.store.mainModuleInst

View File

@ -25,6 +25,7 @@ StatusSectionLayout {
notificationCount: root.rootStore.unreadNotificationsCount
onNotificationButtonClicked: Global.openActivityCenterPopup()
property var communityData: root.rootStore.mainModuleInst ? root.rootStore.mainModuleInst.activeSection || {} : {}
// TODO: get this model from backend?
property var settingsMenuModel: root.rootStore.communityPermissionsEnabled ? [{name: qsTr("Overview"), icon: "help"},
{name: qsTr("Members"), icon: "group-chat"},
@ -56,6 +57,7 @@ StatusSectionLayout {
signal backToCommunityClicked
signal openLegacyPopupClicked // TODO: remove me when migration to new settings is done
signal backupButtonClicked
leftPanel: ColumnLayout {
anchors {
@ -182,8 +184,11 @@ StatusSectionLayout {
}
onAirdropTokensClicked: { /* TODO in future */ }
onBackUpClicked: {
onBackUpClicked: { root.backupButtonClicked(); }
onTransferOwnershipClicked: {
Global.openPopup(transferOwnershipPopup, {
store: root.rootStore,
communityName: root.community.name,
privateKey: root.chatCommunitySectionModule.exportCommunity(root.communityId),
})
}
@ -227,7 +232,14 @@ StatusSectionLayout {
id: transferOwnershipPopup
TransferOwnershipPopup {
anchors.centerIn: parent
store: root.rootStore
onClosed: {
let hiddenBannerIds = localAccountSensitiveSettings.hiddenCommunityBackUpBanners || []
if (hiddenBannerIds.includes(root.communityData.id)) {
return
}
hiddenBannerIds.push(root.communityData.id)
localAccountSensitiveSettings.hiddenCommunityBackUpBanners = hiddenBannerIds
}
}
}

View File

@ -2,6 +2,7 @@ import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@ -26,39 +27,8 @@ StatusInput {
input.background.color: "transparent"
input.background.border.width: 0
// To-do this needs to be removed once https://github.com/status-im/StatusQ/issues/578 is implemented and cursor is moved to StatusInput
input.edit.cursorDelegate: Rectangle {
id: cursor
visible: input.edit.cursorVisible
input.edit.cursorDelegate: StatusCursorDelegate {
color: cursorColor
width: 2
SequentialAnimation {
loops: Animation.Infinite
running: input.edit.cursorVisible
PropertyAction {
target: cursor
property: 'visible'
value: true
}
PauseAnimation {
duration: 600
}
PropertyAction {
target: cursor
property: 'visible'
value: false
}
PauseAnimation {
duration: 600
}
onStopped: {
cursor.visible = false
}
}
visible: input.edit.cursorVisible
}
}

View File

@ -1212,19 +1212,8 @@ Rectangle {
lastClick = now
}
cursorDelegate: Rectangle {
color: Theme.palette.primaryColor1
implicitWidth: 2
implicitHeight: 22
radius: 1
cursorDelegate: StatusCursorDelegate {
visible: messageInputField.cursorVisible
SequentialAnimation on visible {
loops: Animation.Infinite
running: messageInputField.cursorVisible
PropertyAnimation { to: false; duration: 600; }
PropertyAnimation { to: true; duration: 600; }
}
}
StatusSyntaxHighlighter {