feature(@desktop/communities): add loading state when import community
Toast message is added when user access an existing community using community's private key. Toast message with message that importing community is in progress is displayed while community is being imported and once it is imported toast is closed and new one, which will be closed in 4 seconds, with message that community is imported is displayed. Fixes: #2467
This commit is contained in:
parent
9a348e1836
commit
e9585e6209
|
@ -12,6 +12,12 @@ import ../../../status/types
|
||||||
logScope:
|
logScope:
|
||||||
topics = "communities-view"
|
topics = "communities-view"
|
||||||
|
|
||||||
|
type
|
||||||
|
CommunityImportState {.pure.} = enum
|
||||||
|
Imported,
|
||||||
|
InProgress,
|
||||||
|
Error
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type CommunitiesView* = ref object of QObject
|
type CommunitiesView* = ref object of QObject
|
||||||
status: Status
|
status: Status
|
||||||
|
@ -20,6 +26,8 @@ QtObject:
|
||||||
communityList*: CommunityList
|
communityList*: CommunityList
|
||||||
joinedCommunityList*: CommunityList
|
joinedCommunityList*: CommunityList
|
||||||
myCommunityRequests*: seq[CommunityMembershipRequest]
|
myCommunityRequests*: seq[CommunityMembershipRequest]
|
||||||
|
importingCommunityState: CommunityImportState
|
||||||
|
communityImportingProcessId: string
|
||||||
|
|
||||||
proc setup(self: CommunitiesView) =
|
proc setup(self: CommunitiesView) =
|
||||||
self.QObject.setup
|
self.QObject.setup
|
||||||
|
@ -33,6 +41,7 @@ QtObject:
|
||||||
|
|
||||||
proc newCommunitiesView*(status: Status): CommunitiesView =
|
proc newCommunitiesView*(status: Status): CommunitiesView =
|
||||||
new(result, delete)
|
new(result, delete)
|
||||||
|
result.importingCommunityState = CommunityImportState.Imported
|
||||||
result.status = status
|
result.status = status
|
||||||
result.activeCommunity = newCommunityItemView(status)
|
result.activeCommunity = newCommunityItemView(status)
|
||||||
result.observedCommunity = newCommunityItemView(status)
|
result.observedCommunity = newCommunityItemView(status)
|
||||||
|
@ -40,6 +49,16 @@ QtObject:
|
||||||
result.joinedCommunityList = newCommunityList(status)
|
result.joinedCommunityList = newCommunityList(status)
|
||||||
result.setup
|
result.setup
|
||||||
|
|
||||||
|
proc importingCommunityStateChanged*(self: CommunitiesView, state: int, communityImportingProcessId: string) {.signal.}
|
||||||
|
|
||||||
|
proc setImportCommunityState(self: CommunitiesView, state: CommunityImportState, communityImportingProcessId: string) =
|
||||||
|
if (self.importingCommunityState == state):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.communityImportingProcessId = communityImportingProcessId
|
||||||
|
self.importingCommunityState = state
|
||||||
|
self.importingCommunityStateChanged(state.int, communityImportingProcessId)
|
||||||
|
|
||||||
proc calculateUnreadMessages*(self: CommunitiesView, community: var Community) =
|
proc calculateUnreadMessages*(self: CommunitiesView, community: var Community) =
|
||||||
var unreadTotal = 0
|
var unreadTotal = 0
|
||||||
for chatItem in community.chats:
|
for chatItem in community.chats:
|
||||||
|
@ -230,6 +249,8 @@ QtObject:
|
||||||
# @cammellos mentioned this would likely changed in Communities Phase 3, so
|
# @cammellos mentioned this would likely changed in Communities Phase 3, so
|
||||||
# no need to polish now.
|
# no need to polish now.
|
||||||
|
|
||||||
|
self.setImportCommunityState(CommunityImportState.Imported, self.communityImportingProcessId)
|
||||||
|
|
||||||
proc isCommunityRequestPending*(self: CommunitiesView, communityId: string): bool {.slot.} =
|
proc isCommunityRequestPending*(self: CommunitiesView, communityId: string): bool {.slot.} =
|
||||||
for communityRequest in self.myCommunityRequests:
|
for communityRequest in self.myCommunityRequests:
|
||||||
if (communityRequest.communityId == communityId):
|
if (communityRequest.communityId == communityId):
|
||||||
|
@ -369,10 +390,22 @@ QtObject:
|
||||||
error "Error exporting the community", msg = e.msg
|
error "Error exporting the community", msg = e.msg
|
||||||
result = fmt"Error exporting the community: {e.msg}"
|
result = fmt"Error exporting the community: {e.msg}"
|
||||||
|
|
||||||
proc importCommunity*(self: CommunitiesView, communityKey: string): string {.slot.} =
|
proc importCommunity*(self: CommunitiesView, communityKey: string, communityImportingProcessId: string): string {.slot.} =
|
||||||
try:
|
try:
|
||||||
discard self.status.chat.importCommunity(communityKey)
|
self.setImportCommunityState(CommunityImportState.InProgress, communityImportingProcessId)
|
||||||
|
let response = self.status.chat.importCommunity(communityKey)
|
||||||
|
|
||||||
|
let jsonNode = response.parseJSON()
|
||||||
|
if (jsonNode.contains("error")):
|
||||||
|
if (jsonNode["error"].contains("message")):
|
||||||
|
let msg = jsonNode["error"]["message"].getStr()
|
||||||
|
result = fmt"Error importing the community: {msg}"
|
||||||
|
else:
|
||||||
|
result = fmt"Error importing the community: unknown error"
|
||||||
|
self.setImportCommunityState(CommunityImportState.Error, communityImportingProcessId)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
self.setImportCommunityState(CommunityImportState.Error, communityImportingProcessId)
|
||||||
error "Error importing the community", msg = e.msg
|
error "Error importing the community", msg = e.msg
|
||||||
result = fmt"Error importing the community: {e.msg}"
|
result = fmt"Error importing the community: {e.msg}"
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ ModalPopup {
|
||||||
communityKey = "0x" + communityKey
|
communityKey = "0x" + communityKey
|
||||||
}
|
}
|
||||||
|
|
||||||
const error = chatsModel.communities.importCommunity(communityKey)
|
const error = chatsModel.communities.importCommunity(communityKey, Utils.uuid())
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
creatingError.text = error
|
creatingError.text = error
|
||||||
|
|
|
@ -239,10 +239,50 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*##^##
|
Connections {
|
||||||
Designer {
|
target: chatsModel.communities
|
||||||
D{i:0;autoSize:true;formeditorColor:"#ffffff";height:480;width:640}
|
onImportingCommunityStateChanged: {
|
||||||
|
if (state !== Constants.communityImported &&
|
||||||
|
state !== Constants.communityImportingInProgress &&
|
||||||
|
state !== Constants.communityImportingError)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === Constants.communityImported)
|
||||||
|
{
|
||||||
|
if (toastMessage.uuid !== communityImportingProcessId)
|
||||||
|
return
|
||||||
|
|
||||||
|
toastMessage.close()
|
||||||
|
|
||||||
|
toastMessage.title = qsTr("Community imported")
|
||||||
|
toastMessage.source = ""
|
||||||
|
toastMessage.iconRotates = false
|
||||||
|
toastMessage.dissapearInMs = 4000
|
||||||
|
}
|
||||||
|
else if (state === Constants.communityImportingInProgress)
|
||||||
|
{
|
||||||
|
toastMessage.uuid = communityImportingProcessId
|
||||||
|
toastMessage.title = qsTr("Importing community is in progress")
|
||||||
|
toastMessage.source = "../../img/loading.svg"
|
||||||
|
toastMessage.iconRotates = true
|
||||||
|
toastMessage.dissapearInMs = -1
|
||||||
|
}
|
||||||
|
else if (state === Constants.communityImportingError)
|
||||||
|
{
|
||||||
|
if (toastMessage.uuid !== communityImportingProcessId)
|
||||||
|
return
|
||||||
|
|
||||||
|
toastMessage.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
toastMessage.displayCloseButton = false
|
||||||
|
toastMessage.displayLink = false
|
||||||
|
toastMessage.iconColor = Style.current.primary
|
||||||
|
toastMessage.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
##^##*/
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ pragma Singleton
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
readonly property int communityImported: 0
|
||||||
|
readonly property int communityImportingInProgress: 1
|
||||||
|
readonly property int communityImportingError: 2
|
||||||
|
|
||||||
readonly property int chatTypeOneToOne: 1
|
readonly property int chatTypeOneToOne: 1
|
||||||
readonly property int chatTypePublic: 2
|
readonly property int chatTypePublic: 2
|
||||||
readonly property int chatTypePrivateGroupChat: 3
|
readonly property int chatTypePrivateGroupChat: 3
|
||||||
|
|
|
@ -5,34 +5,52 @@ import "../imports"
|
||||||
import "."
|
import "."
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
property url source: "../app/img/check-circle.svg"
|
|
||||||
property color iconColor: Style.current.primary
|
|
||||||
property bool iconRotates: false
|
|
||||||
property string title: "Transaction pending..."
|
|
||||||
//% "View on Etherscan"
|
|
||||||
readonly property string defaultLinkText: qsTrId("view-on-etherscan")
|
|
||||||
property string link: "https://etherscan.io/"
|
|
||||||
property string linkText: defaultLinkText
|
|
||||||
|
|
||||||
id: root
|
id: root
|
||||||
closePolicy: Popup.NoAutoClose
|
closePolicy: Popup.NoAutoClose
|
||||||
height: 68
|
height: 68
|
||||||
padding: 0
|
padding: 0
|
||||||
margins: 0
|
margins: 0
|
||||||
width: Math.max(Math.max(titleText.width, linkText.width) + toastImage.width + 12 * 4, 343)
|
width: Math.max(Math.max(titleText.width, linkStyledText.width)
|
||||||
|
+ (toastImage.visible? toastImage.width + rowId.spacing : 0)
|
||||||
|
+ rowId.leftPadding + rowId.rightPadding,
|
||||||
|
343)
|
||||||
x: parent.width - width - Style.current.bigPadding
|
x: parent.width - width - Style.current.bigPadding
|
||||||
y: parent.height - height - Style.current.bigPadding
|
y: parent.height - height - Style.current.bigPadding
|
||||||
|
|
||||||
|
|
||||||
|
//% "View on Etherscan"
|
||||||
|
readonly property string defaultLinkText: qsTrId("view-on-etherscan")
|
||||||
|
|
||||||
|
property string uuid: "" // set this if you want to distinct among multiple toasts
|
||||||
|
property url source: "../app/img/check-circle.svg"
|
||||||
|
property color iconColor: Style.current.primary
|
||||||
|
property bool iconRotates: false
|
||||||
|
property string title: "Transaction pending..."
|
||||||
|
property string link: "https://etherscan.io/"
|
||||||
|
property string linkText: defaultLinkText
|
||||||
|
property int dissapearInMs: 4000 /* setting this to -1 makes caller responsible to close it */
|
||||||
|
property bool displayCloseButton: true
|
||||||
|
property bool displayLink: true
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
|
if(dissapearInMs == -1)
|
||||||
|
return
|
||||||
|
|
||||||
timer.setTimeout(function() {
|
timer.setTimeout(function() {
|
||||||
root.close()
|
root.close()
|
||||||
}, 4000);
|
}, dissapearInMs);
|
||||||
}
|
}
|
||||||
onClosed: {
|
onClosed: {
|
||||||
// Reset props
|
// Reset props
|
||||||
|
source = "../app/img/check-circle.svg"
|
||||||
iconColor = Style.current.primary
|
iconColor = Style.current.primary
|
||||||
iconRotates = false
|
iconRotates = false
|
||||||
root.linkText = defaultLinkText
|
title = "Transaction pending..."
|
||||||
|
link = "https://etherscan.io/"
|
||||||
|
linkText = defaultLinkText
|
||||||
|
dissapearInMs = 4000
|
||||||
|
displayCloseButton = true
|
||||||
|
displayLink = true
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
@ -60,54 +78,58 @@ Popup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundedIcon {
|
Row {
|
||||||
id: toastImage
|
id: rowId
|
||||||
width: 32
|
anchors.fill: parent
|
||||||
height: 32
|
leftPadding: 12
|
||||||
iconHeight: 20
|
rightPadding: 12
|
||||||
iconWidth: 20
|
topPadding: Style.current.padding
|
||||||
color: Utils.setColorAlpha(root.iconColor, 0.1)
|
bottomPadding: Style.current.padding
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
spacing: 12
|
||||||
anchors.left: parent.left
|
|
||||||
source: root.source
|
|
||||||
anchors.leftMargin: 12
|
|
||||||
iconColor: root.iconColor
|
|
||||||
rotates: root.iconRotates
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
RoundedIcon {
|
||||||
id: titleText
|
id: toastImage
|
||||||
text: root.title
|
visible: root.source != ""
|
||||||
anchors.left: toastImage.right
|
width: 32
|
||||||
anchors.top: parent.top
|
height: 32
|
||||||
font.pixelSize: 13
|
iconHeight: 20
|
||||||
font.weight: Font.Medium
|
iconWidth: 20
|
||||||
anchors.topMargin: Style.current.padding
|
color: Utils.setColorAlpha(root.iconColor, 0.1)
|
||||||
anchors.leftMargin: 12
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
source: root.source
|
||||||
|
iconColor: root.iconColor
|
||||||
|
rotates: root.iconRotates
|
||||||
|
}
|
||||||
|
|
||||||
StyledText {
|
Column {
|
||||||
id: linkText
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
//% "<a href='%1' style='color:%2;text-decoration:none;'>%3</a>"
|
|
||||||
text: qsTrId("-a-href---1--style--color--2-text-decoration-none----3--a-")
|
StyledText {
|
||||||
.arg(Style.current.textColorTertiary)
|
id: titleText
|
||||||
.arg(root.link)
|
text: root.title
|
||||||
.arg(root.linkText)
|
font.pixelSize: 13
|
||||||
color: Style.current.textColorTertiary
|
font.weight: Font.Medium
|
||||||
textFormat: Text.RichText
|
}
|
||||||
anchors.left: toastImage.right
|
|
||||||
anchors.top: titleText.bottom
|
StyledText {
|
||||||
font.pixelSize: 13
|
id: linkStyledText
|
||||||
font.weight: Font.Medium
|
visible: displayLink
|
||||||
anchors.leftMargin: 12
|
text: `<a href='${root.link}' style='color:${Style.current.textColorTertiary};text-decoration:none;'>${root.linkText}</a>`
|
||||||
onLinkActivated: {
|
color: Style.current.textColorTertiary
|
||||||
appMain.openLink(root.link)
|
textFormat: Text.RichText
|
||||||
root.close()
|
font.pixelSize: 13
|
||||||
|
font.weight: Font.Medium
|
||||||
|
onLinkActivated: {
|
||||||
|
appMain.openLink(root.link)
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SVGImage {
|
SVGImage {
|
||||||
id: closeImage
|
id: closeImage
|
||||||
|
visible: displayCloseButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
source: "../app/img/plusSign.svg"
|
source: "../app/img/plusSign.svg"
|
||||||
|
@ -126,15 +148,10 @@ Popup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColorOverlay {
|
ColorOverlay {
|
||||||
|
visible: displayCloseButton
|
||||||
anchors.fill: closeImage
|
anchors.fill: closeImage
|
||||||
source: closeImage
|
source: closeImage
|
||||||
rotation: 45
|
rotation: 45
|
||||||
color: Style.current.textColor
|
color: Style.current.textColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*##^##
|
|
||||||
Designer {
|
|
||||||
D{i:0;formeditorColor:"#4c4e50";formeditorZoom:1.5;height:68;width:343}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
||||||
|
|
Loading…
Reference in New Issue