feat(Import Control Node): Adding ImportControlNode flow
1. Create a new popup as per Design: ImportControlNodePopup 2. Add the popup in storybook 3. Integrate ImportControlNodePopup in the app
This commit is contained in:
parent
83303a011e
commit
4aaae242b5
|
@ -289,6 +289,10 @@ ListModel {
|
||||||
title: "ExportControlNodePopup"
|
title: "ExportControlNodePopup"
|
||||||
section: "Popups"
|
section: "Popups"
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
title: "ImportControlNodePopup"
|
||||||
|
section: "Popups"
|
||||||
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
title: "StatusButton"
|
title: "StatusButton"
|
||||||
section: "Controls"
|
section: "Controls"
|
||||||
|
|
|
@ -253,5 +253,8 @@
|
||||||
],
|
],
|
||||||
"ExportControlNodePopup": [
|
"ExportControlNodePopup": [
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31171-627949&mode=design&t=WxK2N6sL8idHBKMZ-0"
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31171-627949&mode=design&t=WxK2N6sL8idHBKMZ-0"
|
||||||
|
],
|
||||||
|
"ImportControlNodePopup": [
|
||||||
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba⎜Desktop?type=design&node-id=31171-628434&mode=design&t=IFFCNUpRS3oQbzAR-0"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ SplitView {
|
||||||
id: communityColumnHeader
|
id: communityColumnHeader
|
||||||
|
|
||||||
width: widthSlider.value
|
width: widthSlider.value
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: d.name
|
name: d.name
|
||||||
membersCount: d.membersCount
|
membersCount: d.membersCount
|
||||||
image: d.image
|
image: d.image
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQml 2.15
|
||||||
|
|
||||||
|
import AppLayouts.Communities.popups 1.0
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
import Storybook 1.0
|
||||||
|
|
||||||
|
SplitView {
|
||||||
|
id: root
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
Logs { id: logs }
|
||||||
|
|
||||||
|
SplitView {
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
SplitView.fillHeight: true
|
||||||
|
Pane {
|
||||||
|
id: mainPane
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
|
PopupBackground {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "Reopen"
|
||||||
|
|
||||||
|
onClicked: popupComponent.createObject(mainPane)
|
||||||
|
}
|
||||||
|
Component.onCompleted: popupComponent.createObject(mainPane)
|
||||||
|
}
|
||||||
|
Pane {
|
||||||
|
SplitView.preferredWidth: 300
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Matching private key"
|
||||||
|
}
|
||||||
|
TextEdit {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.color: "red"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
id: matchingPrivateKey
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
readOnly: true
|
||||||
|
text: "0x0454f2231543ba02583e4c55e513a75092a4f2c86c04d0796b195e964656d6cd"
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Copy"
|
||||||
|
onClicked: {
|
||||||
|
matchingPrivateKey.selectAll()
|
||||||
|
matchingPrivateKey.copy()
|
||||||
|
matchingPrivateKey.deselect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Mismatching private key"
|
||||||
|
}
|
||||||
|
TextEdit {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.color: "red"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
id: mismatchingPrivateKey
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
readOnly: true
|
||||||
|
text: "0x0454f2231543ba02583e4c55e513a75092a4f2c86c04d0796b195e964656d6ce"
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Copy"
|
||||||
|
onClicked: {
|
||||||
|
mismatchingPrivateKey.selectAll()
|
||||||
|
mismatchingPrivateKey.copy()
|
||||||
|
mismatchingPrivateKey.deselect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Load in progress private key"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.color: "red"
|
||||||
|
border.width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
id: loadInProgressPrivateKey
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: TextEdit.Wrap
|
||||||
|
readOnly: true
|
||||||
|
text: "0x0454f2231543ba02583e4c55e513a75092a4f2c86c04d0796b195e964656d6ca"
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Copy"
|
||||||
|
onClicked: {
|
||||||
|
loadInProgressPrivateKey.selectAll()
|
||||||
|
loadInProgressPrivateKey.copy()
|
||||||
|
loadInProgressPrivateKey.deselect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
readonly property var community: QtObject {
|
||||||
|
property string id: "1"
|
||||||
|
property string name: "Socks"
|
||||||
|
property var members: { "count": 5 }
|
||||||
|
property string image: Style.png("tokens/UNI")
|
||||||
|
property string color: "orchid"
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var otherCommunity: QtObject {
|
||||||
|
property string id: "2"
|
||||||
|
property string name: "Socks"
|
||||||
|
property var members: { "count": 5 }
|
||||||
|
property string image: Style.png("tokens/UNI")
|
||||||
|
property string color: "orchid"
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property Timer timer: Timer {
|
||||||
|
//id: _timer
|
||||||
|
interval: 1000
|
||||||
|
repeat: false
|
||||||
|
function callWithDelay(cb) {
|
||||||
|
d.timer.triggered.connect(cb);
|
||||||
|
d.timer.triggered.connect(function release () {
|
||||||
|
d.timer.triggered.disconnect(cb);
|
||||||
|
d.timer.triggered.disconnect(release);
|
||||||
|
});
|
||||||
|
d.timer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: popupComponent
|
||||||
|
ImportControlNodePopup {
|
||||||
|
id: popup
|
||||||
|
anchors.centerIn: parent
|
||||||
|
modal: false
|
||||||
|
visible: true
|
||||||
|
|
||||||
|
onRequestCommunityInfo: {
|
||||||
|
logs.logEvent("ImportControlNodePopup::onRequestCommunityInfo", ["private key"], [privateKey])
|
||||||
|
if(privateKey === matchingPrivateKey.text)
|
||||||
|
d.timer.callWithDelay(() => popup.setCommunityInfo(d.community))
|
||||||
|
else if (privateKey === mismatchingPrivateKey.text)
|
||||||
|
d.timer.callWithDelay(() => popup.setCommunityInfo(d.otherCommunity))
|
||||||
|
}
|
||||||
|
|
||||||
|
community: d.community
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogsAndControlsPanel {
|
||||||
|
id: logsAndControlsPanel
|
||||||
|
|
||||||
|
SplitView.minimumHeight: 100
|
||||||
|
SplitView.preferredHeight: 160
|
||||||
|
|
||||||
|
logsView.logText: logs.logText
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,6 +77,8 @@ QtObject {
|
||||||
|
|
||||||
signal importingCommunityStateChanged(string communityId, int state, string errorMsg)
|
signal importingCommunityStateChanged(string communityId, int state, string errorMsg)
|
||||||
|
|
||||||
|
signal communityAdded(string communityId)
|
||||||
|
|
||||||
signal communityInfoAlreadyRequested()
|
signal communityInfoAlreadyRequested()
|
||||||
|
|
||||||
signal communityAccessRequested(string communityId)
|
signal communityAccessRequested(string communityId)
|
||||||
|
@ -631,6 +633,10 @@ QtObject {
|
||||||
function onCommunityAccessRequested(communityId) {
|
function onCommunityAccessRequested(communityId) {
|
||||||
root.communityAccessRequested(communityId)
|
root.communityAccessRequested(communityId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCommunityAdded(communityId) {
|
||||||
|
root.communityAdded(communityId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property Connections mainModuleInstConnections: Connections {
|
readonly property Connections mainModuleInstConnections: Connections {
|
||||||
|
|
|
@ -222,7 +222,6 @@ Item {
|
||||||
target: root.store
|
target: root.store
|
||||||
|
|
||||||
function onImportingCommunityStateChanged(communityId, state, errorMsg) {
|
function onImportingCommunityStateChanged(communityId, state, errorMsg) {
|
||||||
|
|
||||||
const community = root.store.getCommunityDetailsAsJson(communityId)
|
const community = root.store.getCommunityDetailsAsJson(communityId)
|
||||||
let title = ""
|
let title = ""
|
||||||
let subTitle = ""
|
let subTitle = ""
|
||||||
|
|
|
@ -52,6 +52,7 @@ StackLayout {
|
||||||
signal inviteNewPeopleClicked
|
signal inviteNewPeopleClicked
|
||||||
signal airdropTokensClicked
|
signal airdropTokensClicked
|
||||||
signal exportControlNodeClicked
|
signal exportControlNodeClicked
|
||||||
|
signal importControlNodeClicked
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
@ -137,6 +138,7 @@ StackLayout {
|
||||||
communityName: root.name
|
communityName: root.name
|
||||||
isControlNode: root.isControlNode
|
isControlNode: root.isControlNode
|
||||||
onExportControlNodeClicked: root.exportControlNodeClicked()
|
onExportControlNodeClicked: root.exportControlNodeClicked()
|
||||||
|
onImportControlNodeClicked: root.importControlNodeClicked()
|
||||||
//TODO update once the domain changes
|
//TODO update once the domain changes
|
||||||
onLearnMoreClicked: Global.openLink(Constants.statusHelpLinkPrefix + "status-communities/about-the-control-node-in-status-communities")
|
onLearnMoreClicked: Global.openLink(Constants.statusHelpLinkPrefix + "status-communities/about-the-control-node-in-status-communities")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQml 2.15
|
||||||
|
import QtQml.Models 2.14
|
||||||
|
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
StatusDialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var community
|
||||||
|
|
||||||
|
signal importControlNode(string privateKey)
|
||||||
|
signal requestCommunityInfo(string privateKey)
|
||||||
|
|
||||||
|
function setCommunityInfo(communityInfo) {
|
||||||
|
d.requestedCommunityInfo = communityInfo
|
||||||
|
d.privateKeyCheckInProgress = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequestCommunityInfo: d.privateKeyCheckInProgress = true
|
||||||
|
|
||||||
|
width: 640
|
||||||
|
height: Math.max(552, implicitHeight)
|
||||||
|
title: qsTr("Make this device the control node for %1").arg(root.community.name)
|
||||||
|
|
||||||
|
closePolicy: Popup.NoAutoClose
|
||||||
|
|
||||||
|
component Paragraph: StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
lineHeight: 22
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
component PasteButton: StatusButton {
|
||||||
|
id: pasteButton
|
||||||
|
borderColor: textColor
|
||||||
|
text: qsTr("Paste")
|
||||||
|
size: StatusButton.Size.Tiny
|
||||||
|
}
|
||||||
|
|
||||||
|
component ChatDetails: Control {
|
||||||
|
verticalPadding: 6
|
||||||
|
horizontalPadding: 4
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
StatusChatInfoButton {
|
||||||
|
id: communityInfoButton
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
title: community.name
|
||||||
|
subTitle: qsTr("%n member(s)", "", community.members.count || 0)
|
||||||
|
asset.name: community.image
|
||||||
|
asset.color: community.color
|
||||||
|
asset.isImage: true
|
||||||
|
type: StatusChatInfoButton.Type.OneToOneChat
|
||||||
|
hoverEnabled: false
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
StatusBaseText {
|
||||||
|
id: detectionLabel
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.pixelSize: Style.current.additionalTextSize
|
||||||
|
visible: !!text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "matchingPrivateKey"
|
||||||
|
when: d.isPrivateKeyMatching
|
||||||
|
PropertyChanges { target: detectionLabel; text: qsTr("Private key is valid") }
|
||||||
|
PropertyChanges { target: detectionLabel; color: Theme.palette.successColor1 }
|
||||||
|
PropertyChanges { target: communityInfoButton; visible: true }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "mismatchingPrivateKey"
|
||||||
|
when: !d.isPrivateKeyMatching && d.isPrivateKey && !d.privateKeyCheckInProgress
|
||||||
|
PropertyChanges { target: detectionLabel; text: qsTr("This is not the correct private key for %1").arg(root.community.name) }
|
||||||
|
PropertyChanges { target: detectionLabel; color: Theme.palette.dangerColor1 }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "checking"
|
||||||
|
when: d.privateKeyCheckInProgress
|
||||||
|
PropertyChanges { target: detectionLabel; text: qsTr("Checking private key...") }
|
||||||
|
PropertyChanges { target: detectionLabel; color: Theme.palette.baseColor1 }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "invalidPrivateKey"
|
||||||
|
when: !d.isPrivateKey && d.isPrivateKeyInserted
|
||||||
|
PropertyChanges { target: detectionLabel; text: qsTr("This is not a private key") }
|
||||||
|
PropertyChanges { target: detectionLabel; color: Theme.palette.dangerColor1 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
readonly property bool isPrivateKey: Utils.isPrivateKey(privateKeyTextArea.text)
|
||||||
|
readonly property bool isPrivateKeyMatching: d.requestedCommunityInfo ? d.requestedCommunityInfo.id === community.id : false
|
||||||
|
readonly property bool isPrivateKeyInserted: privateKeyTextArea.text.length > 0
|
||||||
|
|
||||||
|
property bool privateKeyCheckInProgress: false
|
||||||
|
property var requestedCommunityInfo: undefined
|
||||||
|
|
||||||
|
onIsPrivateKeyChanged: {
|
||||||
|
if(!isPrivateKey) {
|
||||||
|
requestedCommunityInfo = undefined
|
||||||
|
privateKeyCheckInProgress = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKeyCheckInProgress = true
|
||||||
|
requestedCommunityInfo = undefined
|
||||||
|
requestCommunityInfo(privateKeyTextArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
Paragraph {
|
||||||
|
Layout.preferredHeight: 22
|
||||||
|
Layout.bottomMargin: Style.current.halfPadding
|
||||||
|
text: qsTr("To move the %1 control node to this device: ").arg(root.community.name)
|
||||||
|
}
|
||||||
|
Paragraph {
|
||||||
|
text: qsTr("1. Stop using any other devices as the control node for this Community")
|
||||||
|
}
|
||||||
|
Paragraph {
|
||||||
|
text: qsTr("2. Paste the Community’s private key below:")
|
||||||
|
}
|
||||||
|
StatusBaseInput {
|
||||||
|
id: privateKeyTextArea
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 86
|
||||||
|
rightPadding: Style.current.padding
|
||||||
|
multiline: true
|
||||||
|
valid: d.isPrivateKey || !d.isPrivateKeyInserted
|
||||||
|
placeholderText: qsTr("e.g. %1").arg("0x0454f2231543ba02583e4c55e513a75092a4f2c86c04d0796b195e964656d6cd94b8237c64ef668eb0fe268387adc3fe699bce97190a631563c82b718c19cf1fb8")
|
||||||
|
rightComponent: PasteButton {
|
||||||
|
onClicked: {
|
||||||
|
privateKeyTextArea.edit.clear()
|
||||||
|
privateKeyTextArea.edit.paste()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ChatDetails {
|
||||||
|
Layout.topMargin: Style.current.halfPadding
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: 46
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.minimumHeight: Style.current.xlPadding
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
id: agreementLayout
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
spacing: mainLayout.spacing
|
||||||
|
|
||||||
|
visible: d.isPrivateKeyMatching
|
||||||
|
|
||||||
|
StatusDialogDivider {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Paragraph {
|
||||||
|
Layout.topMargin: Style.current.padding
|
||||||
|
text: qsTr("I acknowledge that...")
|
||||||
|
}
|
||||||
|
StatusCheckBox {
|
||||||
|
id: agreementCheckBox
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
text: qsTr("I must keep this device online and running Status for the Community to function")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: StatusDialogFooter {
|
||||||
|
rightButtons: ObjectModel {
|
||||||
|
StatusButton {
|
||||||
|
text: qsTr("Make this device the control node for %1").arg(root.community.name)
|
||||||
|
enabled: d.isPrivateKeyMatching && agreementCheckBox.checked
|
||||||
|
onClicked: {
|
||||||
|
root.importControlNode(privateKeyTextArea.text)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ CreateCommunityPopup 1.0 CreateCommunityPopup.qml
|
||||||
DiscordImportProgressDialog 1.0 DiscordImportProgressDialog.qml
|
DiscordImportProgressDialog 1.0 DiscordImportProgressDialog.qml
|
||||||
ExportControlNodePopup 1.0 ExportControlNodePopup.qml
|
ExportControlNodePopup 1.0 ExportControlNodePopup.qml
|
||||||
HoldingsDropdown 1.0 HoldingsDropdown.qml
|
HoldingsDropdown 1.0 HoldingsDropdown.qml
|
||||||
|
ImportControlNodePopup 1.0 ImportControlNodePopup.qml
|
||||||
InDropdown 1.0 InDropdown.qml
|
InDropdown 1.0 InDropdown.qml
|
||||||
InviteFriendsToCommunityPopup 1.0 InviteFriendsToCommunityPopup.qml
|
InviteFriendsToCommunityPopup 1.0 InviteFriendsToCommunityPopup.qml
|
||||||
MembersDropdown 1.0 MembersDropdown.qml
|
MembersDropdown 1.0 MembersDropdown.qml
|
||||||
|
|
|
@ -37,8 +37,7 @@ StatusSectionLayout {
|
||||||
|
|
||||||
readonly property bool isOwner: community.memberRole === Constants.memberRole.owner
|
readonly property bool isOwner: community.memberRole === Constants.memberRole.owner
|
||||||
readonly property bool isAdmin: isOwner || community.memberRole === Constants.memberRole.admin
|
readonly property bool isAdmin: isOwner || community.memberRole === Constants.memberRole.admin
|
||||||
//TODO: get proper value from backend
|
readonly property bool isControlNode: community.isControlNode
|
||||||
readonly property bool isControlNode: isOwner
|
|
||||||
|
|
||||||
readonly property string filteredSelectedTags: {
|
readonly property string filteredSelectedTags: {
|
||||||
let tagsArray = []
|
let tagsArray = []
|
||||||
|
@ -223,6 +222,13 @@ StatusSectionLayout {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onImportControlNodeClicked: {
|
||||||
|
if(root.isControlNode)
|
||||||
|
return
|
||||||
|
|
||||||
|
Global.openImportControlNodePopup(root.community, d.importControlNodePopupOpened)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MembersSettingsPanel {
|
MembersSettingsPanel {
|
||||||
|
@ -535,6 +541,44 @@ StatusSectionLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requestCommunityInfoWithCallback(privateKey, callback) {
|
||||||
|
if(!callback) return
|
||||||
|
|
||||||
|
//success
|
||||||
|
root.rootStore.communityAdded.connect(function communityAddedHandler(communityId) {
|
||||||
|
root.rootStore.communityAdded.disconnect(communityAddedHandler)
|
||||||
|
let community = null
|
||||||
|
try {
|
||||||
|
const communityJson = root.rootStore.getSectionByIdJson(communityId)
|
||||||
|
community = JSON.parse(communityJson)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Error parsing community json: ", communityJson, " error: ", e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(community)
|
||||||
|
})
|
||||||
|
|
||||||
|
//error
|
||||||
|
root.rootStore.importingCommunityStateChanged.connect(function communityImportingStateChangedHandler(communityId, status) {
|
||||||
|
root.rootStore.importingCommunityStateChanged.disconnect(communityImportingStateChangedHandler)
|
||||||
|
if(status === Constants.communityImportingError) {
|
||||||
|
callback(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
root.rootStore.requestCommunityInfo(privateKey, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function importControlNodePopupOpened(popup) {
|
||||||
|
popup.requestCommunityInfo.connect((privateKey) => {
|
||||||
|
requestCommunityInfoWithCallback(privateKey, popup.setCommunityInfo)
|
||||||
|
})
|
||||||
|
|
||||||
|
popup.importControlNode.connect((privateKey) => {
|
||||||
|
root.rootStore.importCommunity(privateKey)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusQUtils.ModelChangeTracker {
|
StatusQUtils.ModelChangeTracker {
|
||||||
|
|
|
@ -57,6 +57,7 @@ QtObject {
|
||||||
Global.leaveCommunityRequested.connect(openLeaveCommunityPopup)
|
Global.leaveCommunityRequested.connect(openLeaveCommunityPopup)
|
||||||
Global.openTestnetPopup.connect(openTestnetPopup)
|
Global.openTestnetPopup.connect(openTestnetPopup)
|
||||||
Global.openExportControlNodePopup.connect(openExportControlNodePopup)
|
Global.openExportControlNodePopup.connect(openExportControlNodePopup)
|
||||||
|
Global.openImportControlNodePopup.connect(openImportControlNodePopup)
|
||||||
}
|
}
|
||||||
|
|
||||||
property var currentPopup
|
property var currentPopup
|
||||||
|
@ -256,6 +257,10 @@ QtObject {
|
||||||
}, cb)
|
}, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openImportControlNodePopup(community, cb) {
|
||||||
|
openPopup(importControlNodePopup, {community: community}, cb)
|
||||||
|
}
|
||||||
|
|
||||||
readonly property list<Component> _components: [
|
readonly property list<Component> _components: [
|
||||||
Component {
|
Component {
|
||||||
id: removeContactConfirmationDialog
|
id: removeContactConfirmationDialog
|
||||||
|
@ -603,6 +608,14 @@ QtObject {
|
||||||
ExportControlNodePopup {
|
ExportControlNodePopup {
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: importControlNodePopup
|
||||||
|
ImportControlNodePopup {
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,8 @@ QtObject {
|
||||||
signal openOutgoingIDRequestPopup(string publicKey, var cb)
|
signal openOutgoingIDRequestPopup(string publicKey, var cb)
|
||||||
signal openDeleteMessagePopup(string messageId, var messageStore)
|
signal openDeleteMessagePopup(string messageId, var messageStore)
|
||||||
signal openDownloadImageDialog(string imageSource)
|
signal openDownloadImageDialog(string imageSource)
|
||||||
signal openExportControlNodePopup(string communityName, string privateKey, var ctaHandler)
|
signal openExportControlNodePopup(string communityName, string privateKey, var cb)
|
||||||
|
signal openImportControlNodePopup(var community, var cb)
|
||||||
signal contactRenamed(string publicKey)
|
signal contactRenamed(string publicKey)
|
||||||
|
|
||||||
signal openLink(string link)
|
signal openLink(string link)
|
||||||
|
|
Loading…
Reference in New Issue