feat(shared-addresses): add loading state for checking permissions

Fixes #11893
This commit is contained in:
Jonathan Rainville 2023-08-22 14:04:58 -04:00
parent cdfd10c592
commit 789a01cf09
17 changed files with 116 additions and 27 deletions

View File

@ -198,6 +198,14 @@ proc init*(self: Controller) =
self.delegate.callbackFromAuthentication(authenticated) self.delegate.callbackFromAuthentication(authenticated)
self.tmpAuthenticationWithCallbackInProgress = false self.tmpAuthenticationWithCallbackInProgress = false
self.events.on(SIGNAL_CHECK_PERMISSIONS_TO_JOIN_FAILED) do(e: Args):
let args = CheckPermissionsToJoinFailedArgs(e)
self.delegate.onCommunityCheckPermissionsToJoinFailed(args.communityId, args.error)
self.events.on(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_FAILED) do(e: Args):
let args = CheckChannelsPermissionsErrorArgs(e)
self.delegate.onCommunityCheckAllChannelPermissionsFailed(args.communityId, args.error)
proc getCommunityTags*(self: Controller): string = proc getCommunityTags*(self: Controller): string =
result = self.communityService.getCommunityTags() result = self.communityService.getCommunityTags()

View File

@ -217,3 +217,9 @@ method onCommunityCheckPermissionsToJoinResponse*(self: AccessInterface, communi
method onCommunityCheckAllChannelsPermissionsResponse*(self: AccessInterface, communityId: string, method onCommunityCheckAllChannelsPermissionsResponse*(self: AccessInterface, communityId: string,
checkChannelPermissionsResponse: CheckAllChannelsPermissionsResponseDto) {.base.} = checkChannelPermissionsResponse: CheckAllChannelsPermissionsResponseDto) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onCommunityCheckPermissionsToJoinFailed*(self: AccessInterface, communityId: string, ValueErrorerror: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityCheckAllChannelPermissionsFailed*(self: AccessInterface, communityId: string, ValueErrorerror: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -44,6 +44,8 @@ type
moduleLoaded: bool moduleLoaded: bool
curatedCommunitiesLoaded: bool curatedCommunitiesLoaded: bool
communityTokensModule: community_tokens_module.AccessInterface communityTokensModule: community_tokens_module.AccessInterface
checkingPermissionToJoinInProgress: bool
checkingAllChannelPermissionsInProgress: bool
# Forward declaration # Forward declaration
method setCommunityTags*(self: Module, communityTags: string) method setCommunityTags*(self: Module, communityTags: string)
@ -79,6 +81,8 @@ proc newModule*(
result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService, communityService) result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService, communityService)
result.moduleLoaded = false result.moduleLoaded = false
result.curatedCommunitiesLoaded = false result.curatedCommunitiesLoaded = false
result.checkingPermissionToJoinInProgress = false
result.checkingAllChannelPermissionsInProgress = false
method delete*(self: Module) = method delete*(self: Module) =
self.view.delete self.view.delete
@ -541,6 +545,7 @@ method getCommunityPublicKeyFromPrivateKey*(self: Module, communityPrivateKey: s
method checkPermissions*(self: Module, communityId: string, sharedAddresses: seq[string]) = method checkPermissions*(self: Module, communityId: string, sharedAddresses: seq[string]) =
self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses) self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses)
self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses) self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses)
self.view.setCheckingPermissionsInProgress(inProgress = true)
method prepareTokenModelForCommunity*(self: Module, communityId: string) = method prepareTokenModelForCommunity*(self: Module, communityId: string) =
let community = self.controller.getCommunityById(communityId) let community = self.controller.getCommunityById(communityId)
@ -595,12 +600,32 @@ proc applyPermissionResponse*(self: Module, communityId: string, permissions: Ta
) )
self.view.spectatedCommunityPermissionModel.updateItem(id, updatedTokenPermissionItem) self.view.spectatedCommunityPermissionModel.updateItem(id, updatedTokenPermissionItem)
proc updateCheckingPermissionsInProgressIfNeeded(self: Module, inProgress = false) =
if self.checkingPermissionToJoinInProgress != self.checkingAllChannelPermissionsInProgress:
# Wait until both join and channel permissions have returned to update the loading
return
self.view.setCheckingPermissionsInProgress(inProgress)
method onCommunityCheckPermissionsToJoinFailed*(self: Module, communityId: string, error: string) =
# TODO show error
self.checkingPermissionToJoinInProgress = false
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
method onCommunityCheckAllChannelPermissionsFailed*(self: Module, communityId: string, error: string) =
# TODO show error
self.checkingAllChannelPermissionsInProgress = false
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
method onCommunityCheckPermissionsToJoinResponse*(self: Module, communityId: string, method onCommunityCheckPermissionsToJoinResponse*(self: Module, communityId: string,
checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) = checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) =
self.applyPermissionResponse(communityId, checkPermissionsToJoinResponse.permissions) self.applyPermissionResponse(communityId, checkPermissionsToJoinResponse.permissions)
self.checkingPermissionToJoinInProgress = false
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
method onCommunityCheckAllChannelsPermissionsResponse*(self: Module, communityId: string, method onCommunityCheckAllChannelsPermissionsResponse*(self: Module, communityId: string,
checkChannelPermissionsResponse: CheckAllChannelsPermissionsResponseDto) = checkChannelPermissionsResponse: CheckAllChannelsPermissionsResponseDto) =
self.checkingAllChannelPermissionsInProgress = false
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
for _, channelPermissionResponse in checkChannelPermissionsResponse.channels: for _, channelPermissionResponse in checkChannelPermissionsResponse.channels:
self.applyPermissionResponse( self.applyPermissionResponse(
communityId, communityId,

View File

@ -50,6 +50,7 @@ QtObject:
discordImportCommunityImage: string discordImportCommunityImage: string
discordImportHasCommunityImage: bool discordImportHasCommunityImage: bool
downloadingCommunityHistoryArchives: bool downloadingCommunityHistoryArchives: bool
checkingPermissionsInProgress: bool
proc delete*(self: View) = proc delete*(self: View) =
self.model.delete self.model.delete
@ -142,7 +143,7 @@ QtObject:
proc downloadingCommunityHistoryArchivesChanged*(self: View) {.signal.} proc downloadingCommunityHistoryArchivesChanged*(self: View) {.signal.}
proc setDownloadingCommunityHistoryArchives*(self: View, flag: bool) {.slot.} = proc setDownloadingCommunityHistoryArchives*(self: View, flag: bool) =
if (self.downloadingCommunityHistoryArchives == flag): return if (self.downloadingCommunityHistoryArchives == flag): return
self.downloadingCommunityHistoryArchives = flag self.downloadingCommunityHistoryArchives = flag
self.downloadingCommunityHistoryArchivesChanged() self.downloadingCommunityHistoryArchivesChanged()
@ -156,7 +157,7 @@ QtObject:
proc discordImportHasCommunityImageChanged*(self: View) {.signal.} proc discordImportHasCommunityImageChanged*(self: View) {.signal.}
proc setDiscordImportHasCommunityImage*(self: View, hasImage: bool) {.slot.} = proc setDiscordImportHasCommunityImage*(self: View, hasImage: bool) =
if (self.discordImportHasCommunityImage == hasImage): return if (self.discordImportHasCommunityImage == hasImage): return
self.discordImportHasCommunityImage = hasImage self.discordImportHasCommunityImage = hasImage
self.discordImportHasCommunityImageChanged() self.discordImportHasCommunityImageChanged()
@ -170,7 +171,7 @@ QtObject:
proc discordImportWarningsCountChanged*(self: View) {.signal.} proc discordImportWarningsCountChanged*(self: View) {.signal.}
proc setDiscordImportWarningsCount*(self: View, count: int) {.slot.} = proc setDiscordImportWarningsCount*(self: View, count: int) =
if (self.discordImportWarningsCount == count): return if (self.discordImportWarningsCount == count): return
self.discordImportWarningsCount = count self.discordImportWarningsCount = count
self.discordImportWarningsCountChanged() self.discordImportWarningsCountChanged()
@ -182,7 +183,7 @@ QtObject:
read = getDiscordImportWarningsCount read = getDiscordImportWarningsCount
notify = discordImportWarningsCountChanged notify = discordImportWarningsCountChanged
proc setDiscordImportErrorsCount*(self: View, count: int) {.slot.} = proc setDiscordImportErrorsCount*(self: View, count: int) =
if (self.discordImportErrorsCount == count): return if (self.discordImportErrorsCount == count): return
self.discordImportErrorsCount = count self.discordImportErrorsCount = count
self.discordImportErrorsCountChanged() self.discordImportErrorsCountChanged()
@ -196,7 +197,7 @@ QtObject:
proc discordImportProgressChanged*(self: View) {.signal.} proc discordImportProgressChanged*(self: View) {.signal.}
proc setDiscordImportProgress*(self: View, value: int) {.slot.} = proc setDiscordImportProgress*(self: View, value: int) =
if (self.discordImportProgress == value): return if (self.discordImportProgress == value): return
self.discordImportProgress = value self.discordImportProgress = value
self.discordImportProgressChanged() self.discordImportProgressChanged()
@ -210,7 +211,7 @@ QtObject:
proc discordImportInProgressChanged*(self: View) {.signal.} proc discordImportInProgressChanged*(self: View) {.signal.}
proc setDiscordImportInProgress*(self: View, value: bool) {.slot.} = proc setDiscordImportInProgress*(self: View, value: bool) =
if (self.discordImportInProgress == value): return if (self.discordImportInProgress == value): return
self.discordImportInProgress = value self.discordImportInProgress = value
self.discordImportInProgressChanged() self.discordImportInProgressChanged()
@ -224,7 +225,7 @@ QtObject:
proc discordImportCancelledChanged*(self: View) {.signal.} proc discordImportCancelledChanged*(self: View) {.signal.}
proc setDiscordImportCancelled*(self: View, value: bool) {.slot.} = proc setDiscordImportCancelled*(self: View, value: bool) =
if (self.discordImportCancelled == value): return if (self.discordImportCancelled == value): return
self.discordImportCancelled = value self.discordImportCancelled = value
self.discordImportCancelledChanged() self.discordImportCancelledChanged()
@ -238,7 +239,7 @@ QtObject:
proc discordImportProgressStoppedChanged*(self: View) {.signal.} proc discordImportProgressStoppedChanged*(self: View) {.signal.}
proc setDiscordImportProgressStopped*(self: View, stopped: bool) {.slot.} = proc setDiscordImportProgressStopped*(self: View, stopped: bool) =
if (self.discordImportProgressStopped == stopped): return if (self.discordImportProgressStopped == stopped): return
self.discordImportProgressStopped = stopped self.discordImportProgressStopped = stopped
self.discordImportProgressStoppedChanged() self.discordImportProgressStoppedChanged()
@ -252,7 +253,7 @@ QtObject:
proc discordImportProgressTotalChunksCountChanged*(self: View) {.signal.} proc discordImportProgressTotalChunksCountChanged*(self: View) {.signal.}
proc setDiscordImportProgressTotalChunksCount*(self: View, count: int) {.slot.} = proc setDiscordImportProgressTotalChunksCount*(self: View, count: int) =
if (self.discordImportProgressTotalChunksCount == count): return if (self.discordImportProgressTotalChunksCount == count): return
self.discordImportProgressTotalChunksCount = count self.discordImportProgressTotalChunksCount = count
self.discordImportProgressTotalChunksCountChanged() self.discordImportProgressTotalChunksCountChanged()
@ -266,7 +267,7 @@ QtObject:
proc discordImportProgressCurrentChunkChanged*(self: View) {.signal.} proc discordImportProgressCurrentChunkChanged*(self: View) {.signal.}
proc setDiscordImportProgressCurrentChunk*(self: View, count: int) {.slot.} = proc setDiscordImportProgressCurrentChunk*(self: View, count: int) =
if (self.discordImportProgressCurrentChunk == count): return if (self.discordImportProgressCurrentChunk == count): return
self.discordImportProgressCurrentChunk = count self.discordImportProgressCurrentChunk = count
self.discordImportProgressCurrentChunkChanged() self.discordImportProgressCurrentChunkChanged()
@ -669,3 +670,17 @@ QtObject:
proc getCommunityPublicKeyFromPrivateKey*(self: View, communityPrivateKey: string): string {.slot.} = proc getCommunityPublicKeyFromPrivateKey*(self: View, communityPrivateKey: string): string {.slot.} =
result = self.delegate.getCommunityPublicKeyFromPrivateKey(communityPrivateKey) result = self.delegate.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
proc checkingPermissionsInProgressChanged*(self: View) {.signal.}
proc setCheckingPermissionsInProgress*(self: View, inProgress: bool) =
if (self.checkingPermissionsInProgress == inProgress): return
self.checkingPermissionsInProgress = inProgress
self.checkingPermissionsInProgressChanged()
proc getCheckingPermissionsInProgress*(self: View): bool {.slot.} =
return self.checkingPermissionsInProgress
QtProperty[bool] requirementsCheckPending:
read = getCheckingPermissionsInProgress
notify = checkingPermissionsInProgressChanged

View File

@ -192,6 +192,7 @@ StackLayout {
loginType: root.rootStore.loginType loginType: root.rootStore.loginType
walletAccountsModel: WalletStore.RootStore.nonWatchAccounts walletAccountsModel: WalletStore.RootStore.nonWatchAccounts
requirementsCheckPending: root.rootStore.requirementsCheckPending
permissionsModel: { permissionsModel: {
root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId) root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId)
return root.rootStore.permissionsModel return root.rootStore.permissionsModel

View File

@ -60,6 +60,8 @@ QtObject {
root.communitiesModuleInst.prepareTokenModelForCommunity(publicKey) root.communitiesModuleInst.prepareTokenModelForCommunity(publicKey)
} }
readonly property bool requirementsCheckPending: root.communitiesModuleInst.requirementsCheckPending
readonly property var permissionsModel: !!root.communitiesModuleInst.spectatedCommunityPermissionModel ? readonly property var permissionsModel: !!root.communitiesModuleInst.spectatedCommunityPermissionModel ?
root.communitiesModuleInst.spectatedCommunityPermissionModel : null root.communitiesModuleInst.spectatedCommunityPermissionModel : null

View File

@ -169,24 +169,9 @@ Control {
color: Theme.palette.dangerColor1 color: Theme.palette.dangerColor1
} }
StatusBaseText { RequirementsCheckPendingLoader {
id: requirementsCheckPendingText
Layout.alignment: Qt.AlignHCenter
visible: root.requirementsCheckPending visible: root.requirementsCheckPending
Layout.alignment: Qt.AlignHCenter
text: qsTr("Requirements check pending...")
color: Theme.palette.dangerColor1
SequentialAnimation {
id: blinkingAnimation
loops: Animation.Infinite
running: requirementsCheckPendingText.visible
NumberAnimation { target: requirementsCheckPendingText; property: "opacity"; to: 0; duration: 1500;}
NumberAnimation { target: requirementsCheckPendingText; property: "opacity"; to: 1; duration: 1500;}
}
} }
} }
} }

View File

@ -0,0 +1,22 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
StatusBaseText {
id: root
text: qsTr("Requirements check pending...")
color: Theme.palette.dangerColor1
SequentialAnimation {
id: blinkingAnimation
loops: Animation.Infinite
running: root.visible
NumberAnimation { target: root; property: "opacity"; to: 0; duration: 1500;}
NumberAnimation { target: root; property: "opacity"; to: 1; duration: 1500;}
}
}

View File

@ -26,6 +26,8 @@ Control {
property bool isEditMode property bool isEditMode
property bool requirementsCheckPending: false
required property string communityName required property string communityName
required property string communityIcon required property string communityIcon
property int loginType: Constants.LoginType.Password property int loginType: Constants.LoginType.Password
@ -174,6 +176,16 @@ Control {
} }
} }
RequirementsCheckPendingLoader {
visible: root.requirementsCheckPending
Layout.alignment: Qt.AlignHCenter
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: Style.current.padding
}
// divider with top rounded corners + drop shadow // divider with top rounded corners + drop shadow
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -27,6 +27,7 @@ PrivilegedTokenArtworkPanel 1.0 PrivilegedTokenArtworkPanel.qml
ProfilePopupInviteFriendsPanel 1.0 ProfilePopupInviteFriendsPanel.qml ProfilePopupInviteFriendsPanel 1.0 ProfilePopupInviteFriendsPanel.qml
ProfilePopupInviteMessagePanel 1.0 ProfilePopupInviteMessagePanel.qml ProfilePopupInviteMessagePanel 1.0 ProfilePopupInviteMessagePanel.qml
ProfilePopupOverviewPanel 1.0 ProfilePopupOverviewPanel.qml ProfilePopupOverviewPanel 1.0 ProfilePopupOverviewPanel.qml
RequirementsCheckPendingLoader 1.0 RequirementsCheckPendingLoader.qml
SharedAddressesPanel 1.0 SharedAddressesPanel.qml SharedAddressesPanel 1.0 SharedAddressesPanel.qml
SortableTokenHoldersList 1.0 SortableTokenHoldersList.qml SortableTokenHoldersList 1.0 SortableTokenHoldersList.qml
SortableTokenHoldersPanel 1.0 SortableTokenHoldersPanel.qml SortableTokenHoldersPanel 1.0 SortableTokenHoldersPanel.qml

View File

@ -11,6 +11,8 @@ StatusDialog {
property bool isEditMode property bool isEditMode
property bool requirementsCheckPending
required property string communityName required property string communityName
required property string communityIcon required property string communityIcon
property int loginType: Constants.LoginType.Password property int loginType: Constants.LoginType.Password
@ -34,6 +36,7 @@ StatusDialog {
contentItem: SharedAddressesPanel { contentItem: SharedAddressesPanel {
id: panel id: panel
isEditMode: root.isEditMode isEditMode: root.isEditMode
requirementsCheckPending: root.requirementsCheckPending
communityName: root.communityName communityName: root.communityName
communityIcon: root.communityIcon communityIcon: root.communityIcon
loginType: root.loginType loginType: root.loginType

View File

@ -110,6 +110,7 @@ QtObject {
} }
property var communitiesList: communitiesModuleInst.model property var communitiesList: communitiesModuleInst.model
readonly property bool requirementsCheckPending: communitiesModuleInst.requirementsCheckPending
function spectateCommunity(publicKey) { function spectateCommunity(publicKey) {
root.communitiesModuleInst.spectateCommunity(publicKey, ""); root.communitiesModuleInst.spectateCommunity(publicKey, "");

View File

@ -120,6 +120,7 @@ Item {
CommunityIntroDialog { CommunityIntroDialog {
isInvitationPending: joinCommunityButton.invitationPending isInvitationPending: joinCommunityButton.invitationPending
requirementsCheckPending: root.store.requirementsCheckPending
name: communityData.name name: communityData.name
introMessage: communityData.introMessage introMessage: communityData.introMessage
imageSrc: communityData.image imageSrc: communityData.image

View File

@ -234,6 +234,7 @@ SettingsContentBase {
loginType: chatStore.loginType loginType: chatStore.loginType
walletAccountsModel: WalletStore.RootStore.nonWatchAccounts walletAccountsModel: WalletStore.RootStore.nonWatchAccounts
requirementsCheckPending: root.rootStore.requirementsCheckPending
permissionsModel: { permissionsModel: {
root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId) root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId)
return root.rootStore.permissionsModel return root.rootStore.permissionsModel

View File

@ -15,6 +15,7 @@ QtObject {
property var aboutModuleInst: aboutModule property var aboutModuleInst: aboutModule
property var communitiesModuleInst: communitiesModule property var communitiesModuleInst: communitiesModule
property bool newVersionAvailable: false property bool newVersionAvailable: false
readonly property bool requirementsCheckPending: communitiesModuleInst.requirementsCheckPending
property string latestVersion property string latestVersion
property string downloadURL property string downloadURL

View File

@ -523,6 +523,7 @@ QtObject {
id: communityIntroDialog id: communityIntroDialog
property string communityId property string communityId
loginType: root.rootStore.loginType loginType: root.rootStore.loginType
requirementsCheckPending: root.rootStore.requirementsCheckPending
walletAccountsModel: root.rootStore.walletAccountsModel walletAccountsModel: root.rootStore.walletAccountsModel
permissionsModel: { permissionsModel: {
root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId) root.rootStore.prepareTokenModelForCommunity(communityIntroDialog.communityId)
@ -708,6 +709,7 @@ QtObject {
communityName: chatStore.sectionDetails.name communityName: chatStore.sectionDetails.name
communityIcon: chatStore.sectionDetails.image communityIcon: chatStore.sectionDetails.image
requirementsCheckPending: root.rootStore.requirementsCheckPending
// FIXME get these from the community settings (from the initial "join" call) // FIXME get these from the community settings (from the initial "join" call)
//selectedSharedAddresses: [???] //selectedSharedAddresses: [???]
//selectedAirdropAddress: "???" //selectedAirdropAddress: "???"

View File

@ -30,6 +30,8 @@ StatusStackModal {
required property var assetsModel required property var assetsModel
required property var collectiblesModel required property var collectiblesModel
required property bool requirementsCheckPending
signal joined(string airdropAddress, var sharedAddresses) signal joined(string airdropAddress, var sharedAddresses)
signal cancelMembershipRequest() signal cancelMembershipRequest()
signal sharedAddressesUpdated(var sharedAddresses) signal sharedAddressesUpdated(var sharedAddresses)
@ -102,6 +104,7 @@ StatusStackModal {
communityName: root.name communityName: root.name
communityIcon: root.imageSrc communityIcon: root.imageSrc
loginType: root.loginType loginType: root.loginType
requirementsCheckPending: root.requirementsCheckPending
walletAccountsModel: SortFilterProxyModel { walletAccountsModel: SortFilterProxyModel {
sourceModel: root.walletAccountsModel sourceModel: root.walletAccountsModel
sorters: [ sorters: [