mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-24 12:38:57 +00:00
closes #16883 #16882 1. connect the dapps service online state to the enabled state for the dapps button 2. Fix the connect modal primary action button 3. Align DappsComboBox disabled color with the refresh button disabled color (cherry picked from commit 2c4f6b5da3d484b8e36f2ec572ba738e490cda40)
2481 lines
107 KiB
QML
2481 lines
107 KiB
QML
import QtQuick 2.15
|
||
import QtQuick.Controls 2.15
|
||
import QtQuick.Window 2.15
|
||
import QtQuick.Layouts 1.15
|
||
import QtMultimedia 5.15
|
||
import Qt.labs.platform 1.1
|
||
import Qt.labs.settings 1.1
|
||
import QtQml.Models 2.15
|
||
import QtQml 2.15
|
||
|
||
import AppLayouts.Wallet 1.0
|
||
import AppLayouts.Node 1.0
|
||
import AppLayouts.Chat 1.0
|
||
import AppLayouts.Chat.views 1.0
|
||
import AppLayouts.Profile 1.0
|
||
import AppLayouts.Communities 1.0
|
||
import AppLayouts.Wallet.services.dapps 1.0
|
||
|
||
import utils 1.0
|
||
import shared 1.0
|
||
import shared.controls 1.0
|
||
import shared.controls.chat.menuItems 1.0
|
||
import shared.panels 1.0
|
||
import shared.popups 1.0
|
||
import shared.popups.keycard 1.0
|
||
import shared.status 1.0
|
||
import shared.stores 1.0 as SharedStores
|
||
import shared.popups.send 1.0 as SendPopups
|
||
import shared.popups.send.views 1.0
|
||
import shared.stores.send 1.0
|
||
|
||
import StatusQ 0.1
|
||
import StatusQ.Core 0.1
|
||
import StatusQ.Core.Theme 0.1
|
||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||
import StatusQ.Components 0.1
|
||
import StatusQ.Controls 0.1
|
||
import StatusQ.Layout 0.1
|
||
import StatusQ.Popups 0.1
|
||
import StatusQ.Popups.Dialog 0.1
|
||
|
||
import AppLayouts.Chat.stores 1.0 as ChatStores
|
||
import AppLayouts.Communities.stores 1.0
|
||
import AppLayouts.Profile.stores 1.0 as ProfileStores
|
||
import AppLayouts.Wallet.popups 1.0 as WalletPopups
|
||
import AppLayouts.Wallet.popups.dapps 1.0 as DAppsPopups
|
||
import AppLayouts.Wallet.stores 1.0 as WalletStores
|
||
import AppLayouts.stores 1.0 as AppStores
|
||
|
||
import mainui.adaptors 1.0
|
||
import mainui.activitycenter.stores 1.0
|
||
import mainui.activitycenter.popups 1.0
|
||
|
||
import SortFilterProxyModel 0.2
|
||
|
||
Item {
|
||
id: appMain
|
||
|
||
property alias appLayout: appLayout
|
||
|
||
readonly property SharedStores.RootStore sharedRootStore: SharedStores.RootStore {
|
||
currencyStore: appMain.currencyStore
|
||
}
|
||
|
||
property SharedStores.UtilsStore utilsStore
|
||
|
||
readonly property AppStores.RootStore rootStore: AppStores.RootStore {}
|
||
readonly property ProfileStores.ProfileSectionStore profileSectionStore: rootStore.profileSectionStore
|
||
readonly property ProfileStores.ProfileStore profileStore: profileSectionStore.profileStore
|
||
|
||
property ChatStores.RootStore rootChatStore: ChatStores.RootStore {
|
||
contactsStore: appMain.rootStore.contactStore
|
||
currencyStore: appMain.currencyStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
emojiReactionsModel: appMain.rootStore.emojiReactionsModel
|
||
openCreateChat: createChatView.opened
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
}
|
||
property ChatStores.CreateChatPropertiesStore createChatPropertiesStore: ChatStores.CreateChatPropertiesStore {}
|
||
property ActivityCenterStore activityCenterStore: ActivityCenterStore {}
|
||
property SharedStores.NetworkConnectionStore networkConnectionStore: SharedStores.NetworkConnectionStore {}
|
||
property SharedStores.CommunityTokensStore communityTokensStore: SharedStores.CommunityTokensStore {}
|
||
property CommunitiesStore communitiesStore: CommunitiesStore {}
|
||
readonly property WalletStores.TokensStore tokensStore: WalletStores.RootStore.tokensStore
|
||
readonly property WalletStores.WalletAssetsStore walletAssetsStore: WalletStores.RootStore.walletAssetsStore
|
||
readonly property WalletStores.CollectiblesStore walletCollectiblesStore: WalletStores.RootStore.collectiblesStore
|
||
readonly property SharedStores.CurrenciesStore currencyStore: SharedStores.CurrenciesStore {}
|
||
readonly property TransactionStore transactionStore: TransactionStore {
|
||
walletAssetStore: appMain.walletAssetsStore
|
||
tokensStore: appMain.tokensStore
|
||
currencyStore: appMain.currencyStore
|
||
}
|
||
readonly property WalletStores.BuyCryptoStore buyCryptoStore: WalletStores.BuyCryptoStore {}
|
||
|
||
readonly property AppStores.FeatureFlagsStore featureFlagsStore: AppStores.FeatureFlagsStore {
|
||
readonly property var featureFlags: typeof featureFlagsRootContextProperty !== undefined ? featureFlagsRootContextProperty : null
|
||
|
||
connectorEnabled: featureFlags ? featureFlags.connectorEnabled : false
|
||
dappsEnabled: featureFlags ? featureFlags.dappsEnabled : false
|
||
swapEnabled: featureFlags ? featureFlags.swapEnabled : false
|
||
sendViaPersonalChatEnabled: featureFlags ? featureFlags.sendViaPersonalChatEnabled : false
|
||
paymentRequestEnabled: featureFlags ? featureFlags.paymentRequestEnabled : false
|
||
simpleSendEnabled: featureFlags ? featureFlags.simpleSendEnabled : false
|
||
}
|
||
|
||
required property bool isCentralizedMetricsEnabled
|
||
|
||
// set from main.qml
|
||
property var sysPalette
|
||
|
||
AllContactsAdaptor {
|
||
id: allContacsAdaptor
|
||
|
||
contactsModel: appMain.rootStore.contactStore.contactsModel
|
||
|
||
selfPubKey: appMain.profileStore.pubkey
|
||
selfDisplayName : appMain.profileStore.displayName
|
||
selfName: appMain.profileStore.name
|
||
selfPreferredDisplayName: appMain.profileStore.preferredName
|
||
selfAlias: appMain.profileStore.username
|
||
selfIcon: appMain.profileStore.icon
|
||
selfColorId: appMain.profileStore.colorId
|
||
selfColorHash: appMain.profileStore.colorHash
|
||
selfOnlineStatus: appMain.profileStore.currentUserStatus
|
||
selfThumbnailImage: appMain.profileStore.thumbnailImage
|
||
selfLargeImage: appMain.profileStore.largeImage
|
||
selfBio: appMain.profileStore.bio
|
||
}
|
||
|
||
ContactsModelAdaptor {
|
||
id: contactsModelAdaptor
|
||
|
||
allContacts: appMain.profileSectionStore.contactsStore.contactsModel
|
||
}
|
||
|
||
// Central UI point for managing app toasts:
|
||
ToastsManager {
|
||
id: toastsManager
|
||
|
||
rootStore: appMain.rootStore
|
||
rootChatStore: appMain.rootChatStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
profileStore: appMain.profileStore
|
||
|
||
onSendRequested: sendModalHandler.openSend()
|
||
}
|
||
|
||
Connections {
|
||
target: rootStore.mainModuleInst
|
||
|
||
function onDisplayUserProfile(publicKey: string) {
|
||
popups.openProfilePopup(publicKey)
|
||
}
|
||
|
||
function onDisplayKeycardSharedModuleForAuthenticationOrSigning() {
|
||
keycardPopupForAuthenticationOrSigning.active = true
|
||
}
|
||
|
||
function onDestroyKeycardSharedModuleForAuthenticationOrSigning() {
|
||
keycardPopupForAuthenticationOrSigning.active = false
|
||
}
|
||
|
||
function onDisplayKeycardSharedModuleFlow() {
|
||
keycardPopup.active = true
|
||
}
|
||
|
||
function onDestroyKeycardSharedModuleFlow() {
|
||
keycardPopup.active = false
|
||
}
|
||
|
||
function onMailserverWorking() {
|
||
mailserverConnectionBanner.hide()
|
||
}
|
||
|
||
function onMailserverNotWorking() {
|
||
mailserverConnectionBanner.show()
|
||
}
|
||
|
||
function onActiveSectionChanged() {
|
||
createChatView.opened = false
|
||
profileLoader.settingsSubSubsection = -1
|
||
}
|
||
|
||
function onOpenActivityCenter() {
|
||
d.openActivityCenterPopup()
|
||
}
|
||
|
||
function onShowToastAccountAdded(name: string) {
|
||
Global.displayToastMessage(
|
||
qsTr("\"%1\" successfully added").arg(name),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowToastAccountRemoved(name: string) {
|
||
Global.displayToastMessage(
|
||
qsTr("\"%1\" successfully removed").arg(name),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowToastKeypairRenamed(oldName: string, newName: string) {
|
||
Global.displayToastMessage(
|
||
qsTr("You successfully renamed your key pair\nfrom \"%1\" to \"%2\"").arg(oldName).arg(newName),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowNetworkEndpointUpdated(name: string, isTest: bool, revertToDefault: bool) {
|
||
let mainText = revertToDefault ?
|
||
(isTest ? qsTr("Test network settings for %1 reverted to default").arg(name): qsTr("Live network settings for %1 reverted to default").arg(name)):
|
||
(isTest ? qsTr("Test network settings for %1 updated").arg(name): qsTr("Live network settings for %1 updated").arg(name))
|
||
Global.displayToastMessage(
|
||
mainText,
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowToastKeypairRemoved(keypairName: string) {
|
||
Global.displayToastMessage(
|
||
qsTr("“%1” key pair and its derived accounts were successfully removed from all devices").arg(keypairName),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowToastKeypairsImported(keypairName: string, keypairsCount: int, error: string) {
|
||
let notification = qsTr("Please re-generate QR code and try importing again")
|
||
if (error !== "") {
|
||
if (error.startsWith("one or more expected keystore files are not found among the sent files")) {
|
||
notification = qsTr("Make sure you're importing the exported key pair on paired device")
|
||
}
|
||
}
|
||
else {
|
||
notification = qsTr("%1 key pair successfully imported").arg(keypairName)
|
||
if (keypairsCount > 1) {
|
||
notification = qsTr("%n key pair(s) successfully imported", "", keypairsCount)
|
||
}
|
||
}
|
||
Global.displayToastMessage(
|
||
notification,
|
||
"",
|
||
error!==""? "info" : "checkmark-circle",
|
||
false,
|
||
error!==""? Constants.ephemeralNotificationType.normal : Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowTransactionToast(uuid: string,
|
||
txType: int,
|
||
fromChainId: int,
|
||
toChainId: int,
|
||
fromAddr: string,
|
||
fromName: string,
|
||
toAddr: string,
|
||
toName: string,
|
||
txToAddr: string,
|
||
txToName: string,
|
||
txHash: string,
|
||
approvalTx: bool,
|
||
fromAmount: string,
|
||
toAmount: string,
|
||
fromAsset: string,
|
||
toAsset: string,
|
||
username: string,
|
||
publicKey: string,
|
||
packId: string,
|
||
status: string,
|
||
error: string) {
|
||
|
||
let toastTitle = ""
|
||
let toastSubtitle = ""
|
||
let toastIcon = ""
|
||
let toastLoading = false
|
||
let toastType = Constants.ephemeralNotificationType.normal
|
||
let toastLink = ""
|
||
|
||
const sender = !!fromName? fromName : SQUtils.Utils.elideAndFormatWalletAddress(fromAddr)
|
||
let senderChainName = qsTr("unknown")
|
||
let sentAmount = ""
|
||
|
||
const recipient = !!toName? toName : SQUtils.Utils.elideAndFormatWalletAddress(toAddr)
|
||
const txRecipient = !!txToName? txToName : SQUtils.Utils.elideAndFormatWalletAddress(txToAddr)
|
||
let recipientChainName = qsTr("unknown")
|
||
let receivedAmount = ""
|
||
|
||
let assetName = qsTr("unknown")
|
||
let ensName = d.ensName(username)
|
||
let stickersPackName = qsTr("unknown")
|
||
|
||
if (!!txHash) {
|
||
toastLink = "%1/%2".arg(appMain.rootStore.getEtherscanTxLink(fromChainId)).arg(txHash)
|
||
}
|
||
|
||
const fromChainName = SQUtils.ModelUtils.getByKey(WalletStores.RootStore.filteredFlatModel, "chainId", fromChainId, "chainName")
|
||
if (!!fromChainName) {
|
||
senderChainName = fromChainName
|
||
toastSubtitle = qsTr("View on %1").arg(senderChainName)
|
||
}
|
||
const toChainName = SQUtils.ModelUtils.getByKey(WalletStores.RootStore.filteredFlatModel, "chainId", toChainId, "chainName")
|
||
if (!!toChainName) {
|
||
recipientChainName = toChainName
|
||
}
|
||
|
||
const fromToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", fromAsset)
|
||
if (!!fromToken) {
|
||
sentAmount = currencyStore.formatCurrencyAmountFromBigInt(fromAmount, fromToken.symbol, fromToken.decimals)
|
||
}
|
||
|
||
const toToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", toAsset)
|
||
if (!!toToken) {
|
||
receivedAmount = currencyStore.formatCurrencyAmountFromBigInt(toAmount, toToken.symbol, toToken.decimals)
|
||
}
|
||
|
||
if (txType === Constants.SendType.ERC721Transfer || txType === Constants.SendType.ERC1155Transfer) {
|
||
const key = "%1+%2+%3".arg(fromChainId).arg(txToAddr).arg(fromAsset)
|
||
const entry = SQUtils.ModelUtils.getByKey(appMain.walletCollectiblesStore.allCollectiblesModel, "symbol", key)
|
||
if (!!entry) {
|
||
assetName = entry.name
|
||
}
|
||
}
|
||
|
||
if (txType === Constants.SendType.StickersBuy) {
|
||
const idx = appMain.rootChatStore.stickersModuleInst.stickerPacks.findIndexById(packId, false)
|
||
if(idx >= 0) {
|
||
const entry = SQUtils.ModelUtils.get(appMain.rootChatStore.stickersModuleInst.stickerPacks, idx)
|
||
if (!!entry) {
|
||
stickersPackName = entry.name
|
||
}
|
||
}
|
||
}
|
||
|
||
switch(status) {
|
||
case Constants.txStatus.sending: {
|
||
toastTitle = qsTr("Sending %1 from %2 to %3")
|
||
toastLoading = true
|
||
|
||
switch(txType) {
|
||
case Constants.SendType.Transfer: {
|
||
toastTitle = toastTitle.arg(sentAmount).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRegister: {
|
||
toastTitle = qsTr("Registering %1 ENS name using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRelease: {
|
||
toastTitle = qsTr("Releasing %1 ENS username using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSSetPubKey: {
|
||
toastTitle = qsTr("Setting public key %1 using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.StickersBuy: {
|
||
toastTitle = qsTr("Purchasing %1 sticker pack using %2").arg(stickersPackName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.Bridge: {
|
||
toastTitle = qsTr("Bridging %1 from %2 to %3 in %4").arg(sentAmount).arg(senderChainName).arg(recipientChainName).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Setting spending cap: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.ERC721Transfer: {
|
||
toastTitle = toastTitle.arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ERC1155Transfer: {
|
||
toastTitle = qsTr("Sending %1 %2 from %3 to %4").arg(fromAmount).arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.Swap: {
|
||
toastTitle = qsTr("Swapping %1 to %2 in %3").arg(sentAmount).arg(receivedAmount).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Setting spending cap: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.Approve: {
|
||
console.warn("tx type approve not yet identified as a stand alone path")
|
||
break
|
||
}
|
||
default:
|
||
console.warn("status: sending - tx type not supproted")
|
||
return
|
||
}
|
||
break
|
||
}
|
||
case Constants.txStatus.pending: {
|
||
// So far we don't display notification when it's accepted by the network and its status is pending
|
||
// discussed in wallet group chat, we considered that pending status will be displayed almost at the
|
||
// same time as sending and decided to skip it.
|
||
return
|
||
}
|
||
case Constants.txStatus.success: {
|
||
toastTitle = qsTr("Sent %1 from %2 to %3")
|
||
toastIcon = "checkmark-circle"
|
||
toastType = Constants.ephemeralNotificationType.success
|
||
|
||
switch(txType) {
|
||
case Constants.SendType.Transfer: {
|
||
toastTitle = toastTitle.arg(sentAmount).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRegister: {
|
||
toastTitle = qsTr("Registered %1 ENS name using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRelease: {
|
||
toastTitle = qsTr("Released %1 ENS username using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSSetPubKey: {
|
||
toastTitle = qsTr("Set public key %1 using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.StickersBuy: {
|
||
toastTitle = qsTr("Purchased %1 sticker pack using %2").arg(stickersPackName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.Bridge: {
|
||
toastTitle = qsTr("Bridged %1 from %2 to %3 in %4").arg(sentAmount).arg(senderChainName).arg(recipientChainName).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Spending spending cap: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.ERC721Transfer: {
|
||
toastTitle = toastTitle.arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ERC1155Transfer: {
|
||
toastTitle = qsTr("Sent %1 %2 from %3 to %4").arg(fromAmount).arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.Swap: {
|
||
toastTitle = qsTr("Swapped %1 to %2 in %3").arg(sentAmount).arg(receivedAmount).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Spending cap set: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.Approve: {
|
||
console.warn("tx type approve not yet identified as a stand alone path")
|
||
break
|
||
}
|
||
default:
|
||
console.warn("status: success - tx type not supproted")
|
||
return
|
||
}
|
||
break
|
||
}
|
||
case Constants.txStatus.failed: {
|
||
toastTitle = qsTr("Send failed: %1 from %2 to %3")
|
||
toastIcon = "warning"
|
||
toastType = Constants.ephemeralNotificationType.danger
|
||
|
||
switch(txType) {
|
||
case Constants.SendType.Transfer: {
|
||
toastTitle = toastTitle.arg(sentAmount).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRegister: {
|
||
toastTitle = qsTr("ENS username registeration failed: %1 using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSRelease: {
|
||
toastTitle = qsTr("ENS username release failed: %1 using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.ENSSetPubKey: {
|
||
toastTitle = qsTr("Set public key failed: %1 using %2").arg(ensName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.StickersBuy: {
|
||
toastTitle = qsTr("Sticker pack purchase failed: %1 using %2").arg(stickersPackName).arg(sender)
|
||
break
|
||
}
|
||
case Constants.SendType.Bridge: {
|
||
toastTitle = qsTr("Bridge failed: %1 from %2 to %3 in %4").arg(sentAmount).arg(senderChainName).arg(recipientChainName).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Spending spending failed: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.ERC721Transfer: {
|
||
toastTitle = toastTitle.arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.ERC1155Transfer: {
|
||
toastTitle = qsTr("Send failed: %1 %2 from %3 to %4").arg(fromAmount).arg(assetName).arg(sender).arg(recipient)
|
||
break
|
||
}
|
||
case Constants.SendType.Swap: {
|
||
toastTitle = qsTr("Swap failed: %1 to %2 in %3").arg(sentAmount).arg(receivedAmount).arg(sender)
|
||
if (approvalTx) {
|
||
toastTitle = qsTr("Spending cap failed: %1 in %2 for %3").arg(sentAmount).arg(sender).arg(txRecipient)
|
||
}
|
||
break
|
||
}
|
||
case Constants.SendType.Approve: {
|
||
console.warn("tx type approve not yet identified as a stand alone path")
|
||
break
|
||
}
|
||
default:
|
||
console.warn("status: failed - tx type not supproted")
|
||
return
|
||
}
|
||
break
|
||
}
|
||
default:
|
||
console.warn("not supported status")
|
||
return
|
||
}
|
||
|
||
Global.displayToastMessage(toastTitle, toastSubtitle, toastIcon, toastLoading, toastType, toastLink)
|
||
}
|
||
|
||
function onCommunityMemberStatusEphemeralNotification(communityName: string, memberName: string, state: CommunityMembershipRequestState) {
|
||
var text = ""
|
||
switch (state) {
|
||
case Constants.CommunityMembershipRequestState.Banned:
|
||
case Constants.CommunityMembershipRequestState.BannedWithAllMessagesDelete:
|
||
text = qsTr("%1 was banned from %2").arg(memberName).arg(communityName)
|
||
break
|
||
case Constants.CommunityMembershipRequestState.Unbanned:
|
||
text = qsTr("%1 unbanned from %2").arg(memberName).arg(communityName)
|
||
break
|
||
case Constants.CommunityMembershipRequestState.Kicked:
|
||
text = qsTr("%1 was kicked from %2").arg(memberName).arg(communityName)
|
||
break
|
||
default: return
|
||
}
|
||
|
||
Global.displayToastMessage(
|
||
text,
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
|
||
function onShowToastPairingFallbackCompleted() {
|
||
Global.displayToastMessage(
|
||
qsTr("Device paired"),
|
||
qsTr("Sync in process. Keep device powered and app open."),
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
}
|
||
|
||
QtObject {
|
||
id: d
|
||
|
||
property var activityCenterPopupObj: null
|
||
|
||
function openActivityCenterPopup() {
|
||
if (!activityCenterPopupObj) {
|
||
activityCenterPopupObj = activityCenterPopupComponent.createObject(appMain)
|
||
}
|
||
|
||
if (activityCenterPopupObj.opened) {
|
||
activityCenterPopupObj.close()
|
||
} else {
|
||
activityCenterPopupObj.open()
|
||
}
|
||
}
|
||
|
||
function ensName(username) {
|
||
if (!username.endsWith(".stateofus.eth") && !username.endsWith(".eth")) {
|
||
return "%1.%2".arg(username).arg("stateofus.eth")
|
||
}
|
||
return username
|
||
}
|
||
}
|
||
|
||
Settings {
|
||
id: appMainLocalSettings
|
||
property var whitelistedUnfurledDomains: []
|
||
}
|
||
|
||
Popups {
|
||
id: popups
|
||
|
||
sharedRootStore: appMain.sharedRootStore
|
||
popupParent: appMain
|
||
rootStore: appMain.rootStore
|
||
utilsStore: appMain.utilsStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
communitiesStore: appMain.communitiesStore
|
||
profileStore: appMain.profileStore
|
||
devicesStore: appMain.rootStore.profileSectionStore.devicesStore
|
||
currencyStore: appMain.currencyStore
|
||
walletAssetsStore: appMain.walletAssetsStore
|
||
walletCollectiblesStore: appMain.walletCollectiblesStore
|
||
buyCryptoStore: appMain.buyCryptoStore
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
|
||
allContactsModel: allContacsAdaptor.allContactsModel
|
||
mutualContactsModel: contactsModelAdaptor.mutualContacts
|
||
|
||
isDevBuild: !production
|
||
|
||
onOpenExternalLink: globalConns.onOpenLink(link)
|
||
onSaveDomainToUnfurledWhitelist: {
|
||
const whitelistedHostnames = appMainLocalSettings.whitelistedUnfurledDomains || []
|
||
if (!whitelistedHostnames.includes(domain)) {
|
||
whitelistedHostnames.push(domain)
|
||
appMainLocalSettings.whitelistedUnfurledDomains = whitelistedHostnames
|
||
}
|
||
}
|
||
onTransferOwnershipRequested: sendModalHandler.transferOwnership(tokenId, senderAddress)
|
||
}
|
||
|
||
SendModalHandler {
|
||
id: sendModalHandler
|
||
|
||
popupParent: appMain
|
||
loginType: appMain.rootStore.loginType
|
||
transactionStore: appMain.transactionStore
|
||
walletCollectiblesStore: appMain.walletCollectiblesStore
|
||
|
||
// for ens flows
|
||
ensRegisteredAddress: appMain.rootStore.profileSectionStore.ensUsernamesStore.getEnsRegisteredAddress()
|
||
myPublicKey: appMain.rootStore.contactStore.myPublicKey
|
||
getStatusTokenKey: function() {
|
||
return appMain.rootStore.profileSectionStore.ensUsernamesStore.getStatusTokenKey()
|
||
}
|
||
|
||
// for sticker flows
|
||
stickersMarketAddress: appMain.rootChatStore.stickersStore.getStickersMarketAddress()
|
||
stickersNetworkId: appMain.rootChatStore.appNetworkId
|
||
|
||
simpleSendEnabled: appMain.featureFlagsStore.simpleSendEnabled
|
||
|
||
Component.onCompleted: {
|
||
// It's requested from many nested places, so as a workaround we use
|
||
// Global to shorten the path via global signal.
|
||
Global.sendToRecipientRequested.connect(sendToRecipient)
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
id: globalConns
|
||
target: Global
|
||
|
||
function onOpenCreateChatView() {
|
||
createChatView.opened = true
|
||
}
|
||
|
||
function onCloseCreateChatView() {
|
||
createChatView.opened = false
|
||
}
|
||
|
||
function onOpenActivityCenterPopupRequested() {
|
||
d.openActivityCenterPopup()
|
||
}
|
||
|
||
function onOpenLink(link: string) {
|
||
// Qt sometimes inserts random HTML tags; and this will break on invalid URL inside QDesktopServices::openUrl(link)
|
||
link = SQUtils.StringUtils.plainText(link)
|
||
Qt.openUrlExternally(link)
|
||
}
|
||
|
||
function onOpenLinkWithConfirmation(link: string, domain: string) {
|
||
if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain) || link.startsWith("mailto:"))
|
||
globalConns.onOpenLink(link)
|
||
else
|
||
popups.openConfirmExternalLinkPopup(link, domain)
|
||
}
|
||
|
||
function onActivateDeepLink(link: string) {
|
||
appMain.rootStore.mainModuleInst.activateStatusDeepLink(link)
|
||
}
|
||
|
||
function onPlaySendMessageSound() {
|
||
sendMessageSound.stop()
|
||
sendMessageSound.play()
|
||
}
|
||
|
||
function onPlayNotificationSound() {
|
||
notificationSound.stop()
|
||
notificationSound.play()
|
||
}
|
||
|
||
function onPlayErrorSound() {
|
||
errorSound.stop()
|
||
errorSound.play()
|
||
}
|
||
|
||
function onSetNthEnabledSectionActive(nthSection: int) {
|
||
if(!appMain.rootStore.mainModuleInst)
|
||
return
|
||
appMain.rootStore.mainModuleInst.setNthEnabledSectionActive(nthSection)
|
||
}
|
||
|
||
function onAppSectionBySectionTypeChanged(sectionType, subsection, subSubsection = -1, data = {}) {
|
||
if(!appMain.rootStore.mainModuleInst)
|
||
return
|
||
|
||
appMain.rootStore.mainModuleInst.setActiveSectionBySectionType(sectionType)
|
||
|
||
if (sectionType === Constants.appSection.profile) {
|
||
profileLoader.settingsSubsection = subsection
|
||
profileLoader.settingsSubSubsection = subSubsection;
|
||
} else if (sectionType === Constants.appSection.wallet) {
|
||
appView.children[Constants.appViewStackIndex.wallet].item.openDesiredView(subsection, subSubsection, data)
|
||
}
|
||
}
|
||
|
||
function onPaymentRequestClicked(receiverAddress: string, symbol: string, amount: string, chainId: int) {
|
||
if (!!symbol) {
|
||
sendModal.preSelectedHoldingID = symbol
|
||
sendModal.preSelectedHoldingType = Constants.TokenType.ERC20
|
||
}
|
||
if (!!amount) {
|
||
sendModal.preDefinedRawAmountToSend = amount
|
||
}
|
||
if (!!chainId) {
|
||
sendModal.preSelectedChainId = chainId
|
||
}
|
||
|
||
sendModal.open(receiverAddress)
|
||
}
|
||
|
||
function onSwitchToCommunity(communityId: string) {
|
||
appMain.communitiesStore.setActiveCommunity(communityId)
|
||
}
|
||
|
||
function onOpenAddEditSavedAddressesPopup(params) {
|
||
addEditSavedAddress.open(params)
|
||
}
|
||
|
||
function onOpenDeleteSavedAddressesPopup(params) {
|
||
deleteSavedAddress.open(params)
|
||
}
|
||
|
||
function onOpenShowQRPopup(params) {
|
||
showQR.open(params)
|
||
}
|
||
|
||
function onOpenSavedAddressActivityPopup(params) {
|
||
savedAddressActivity.open(params)
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: appMain.communitiesStore
|
||
|
||
function onImportingCommunityStateChanged(communityId, state, errorMsg) {
|
||
let title = ""
|
||
let subTitle = ""
|
||
let loading = false
|
||
let notificationType = Constants.ephemeralNotificationType.normal
|
||
let icon = ""
|
||
|
||
switch (state)
|
||
{
|
||
case Constants.communityImported:
|
||
const community = appMain.communitiesStore.getCommunityDetailsAsJson(communityId)
|
||
if(community.isControlNode) {
|
||
title = qsTr("This device is now the control node for the %1 Community").arg(community.name)
|
||
notificationType = Constants.ephemeralNotificationType.success
|
||
icon = "checkmark-circle"
|
||
} else {
|
||
title = qsTr("'%1' community imported").arg(community.name)
|
||
}
|
||
break
|
||
case Constants.communityImportingInProgress:
|
||
title = qsTr("Importing community is in progress")
|
||
loading = true
|
||
break
|
||
case Constants.communityImportingError:
|
||
title = qsTr("Failed to import community '%1'").arg(communityId)
|
||
subTitle = errorMsg
|
||
break
|
||
case Constants.communityImportingCanceled:
|
||
title = qsTr("Import community '%1' was canceled").arg(community.name)
|
||
break;
|
||
default:
|
||
console.error("unknown state while importing community: %1").arg(state)
|
||
return
|
||
}
|
||
|
||
Global.displayToastMessage(title,
|
||
subTitle,
|
||
icon,
|
||
loading,
|
||
notificationType,
|
||
"")
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: Window.window
|
||
|
||
function onActiveChanged() {
|
||
if (Window.window.active)
|
||
appMain.rootStore.windowActivated()
|
||
else
|
||
appMain.rootStore.windowDeactivated()
|
||
}
|
||
}
|
||
|
||
function changeAppSectionBySectionId(sectionId) {
|
||
appMain.rootStore.mainModuleInst.setActiveSectionById(sectionId)
|
||
}
|
||
|
||
Audio {
|
||
id: sendMessageSound
|
||
store: rootStore
|
||
source: "qrc:/imports/assets/audio/send_message.wav"
|
||
}
|
||
|
||
Audio {
|
||
id: notificationSound
|
||
store: rootStore
|
||
source: "qrc:/imports/assets/audio/notification.wav"
|
||
}
|
||
|
||
Audio {
|
||
id: errorSound
|
||
source: "qrc:/imports/assets/audio/error.mp3"
|
||
store: rootStore
|
||
}
|
||
|
||
Loader {
|
||
id: appSearch
|
||
active: false
|
||
asynchronous: true
|
||
|
||
function openSearchPopup() {
|
||
if (!active)
|
||
active = true
|
||
item.openSearchPopup()
|
||
}
|
||
|
||
function closeSearchPopup() {
|
||
if (item)
|
||
item.closeSearchPopup()
|
||
|
||
active = false
|
||
}
|
||
|
||
sourceComponent: AppSearch {
|
||
store: appMain.rootStore.appSearchStore
|
||
utilsStore: appMain.utilsStore
|
||
onClosed: appSearch.active = false
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: statusEmojiPopup
|
||
active: appMain.rootStore.mainModuleInst.sectionsLoaded
|
||
sourceComponent: StatusEmojiPopup {
|
||
height: 440
|
||
settings: localAccountSensitiveSettings
|
||
emojiModel: SQUtils.Emoji.emojiModel
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: statusStickersPopupLoader
|
||
active: appMain.rootStore.mainModuleInst.sectionsLoaded
|
||
sourceComponent: StatusStickersPopup {
|
||
store: appMain.rootChatStore
|
||
isWalletEnabled: appMain.profileStore.isWalletEnabled
|
||
onBuyClicked: sendModalHandler.buyStickerPack(packId, price)
|
||
}
|
||
}
|
||
|
||
StatusMainLayout {
|
||
id: appLayout
|
||
|
||
anchors.fill: parent
|
||
|
||
leftPanel: StatusAppNavBar {
|
||
topSectionModel: SortFilterProxyModel {
|
||
sourceModel: appMain.rootStore.mainModuleInst.sectionsModel
|
||
filters: [
|
||
AnyOf {
|
||
ValueFilter {
|
||
roleName: "sectionType"
|
||
value: Constants.appSection.wallet
|
||
}
|
||
ValueFilter {
|
||
roleName: "sectionType"
|
||
value: Constants.appSection.chat
|
||
}
|
||
},
|
||
ValueFilter {
|
||
roleName: "enabled"
|
||
value: true
|
||
}
|
||
]
|
||
}
|
||
topSectionDelegate: navbarButton
|
||
|
||
communityItemsModel: SortFilterProxyModel {
|
||
sourceModel: appMain.rootStore.mainModuleInst.sectionsModel
|
||
filters: [
|
||
ValueFilter {
|
||
roleName: "sectionType"
|
||
value: Constants.appSection.community
|
||
},
|
||
ValueFilter {
|
||
roleName: "enabled"
|
||
value: true
|
||
}
|
||
]
|
||
}
|
||
communityItemDelegate: StatusNavBarTabButton {
|
||
objectName: "CommunityNavBarButton"
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
name: model.icon.length > 0? "" : model.name
|
||
icon.name: model.icon
|
||
icon.source: model.image
|
||
identicon.asset.color: (hovered || identicon.highlighted || checked) ? model.color : icon.color
|
||
tooltip.text: model.name
|
||
checked: model.active
|
||
badge.value: model.notificationsCount
|
||
badge.visible: model.hasNotification
|
||
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
|
||
badge.border.width: 2
|
||
|
||
stateIcon.color: Theme.palette.dangerColor1
|
||
stateIcon.border.color: Theme.palette.baseColor2
|
||
stateIcon.border.width: 2
|
||
stateIcon.visible: model.amIBanned
|
||
stateIcon.asset.name: "cancel"
|
||
stateIcon.asset.color: Theme.palette.baseColor2
|
||
stateIcon.asset.width: 14
|
||
|
||
onClicked: {
|
||
changeAppSectionBySectionId(model.id)
|
||
}
|
||
|
||
popupMenu: Component {
|
||
StatusMenu {
|
||
id: communityContextMenu
|
||
property var chatCommunitySectionModule
|
||
|
||
readonly property bool isSpectator: model.spectated && !model.joined
|
||
|
||
openHandler: function () {
|
||
// we cannot return QVariant if we pass another parameter in a function call
|
||
// that's why we're using it this way
|
||
appMain.rootStore.mainModuleInst.prepareCommunitySectionModuleForCommunityId(model.id)
|
||
communityContextMenu.chatCommunitySectionModule = appMain.rootStore.mainModuleInst.getCommunitySectionModule()
|
||
}
|
||
|
||
StatusAction {
|
||
text: qsTr("Invite People")
|
||
icon.name: "share-ios"
|
||
objectName: "invitePeople"
|
||
onTriggered: {
|
||
popups.openInviteFriendsToCommunityPopup(model,
|
||
communityContextMenu.chatCommunitySectionModule,
|
||
null)
|
||
}
|
||
}
|
||
|
||
StatusAction {
|
||
text: qsTr("View Community")
|
||
icon.name: "group-chat"
|
||
onTriggered: popups.openCommunityProfilePopup(appMain.rootStore, model, communityContextMenu.chatCommunitySectionModule)
|
||
}
|
||
|
||
StatusMenuSeparator {}
|
||
|
||
MuteChatMenuItem {
|
||
enabled: !model.muted
|
||
title: qsTr("Mute Community")
|
||
onMuteTriggered: {
|
||
communityContextMenu.chatCommunitySectionModule.setCommunityMuted(interval)
|
||
communityContextMenu.close()
|
||
}
|
||
}
|
||
|
||
StatusAction {
|
||
enabled: model.muted
|
||
text: qsTr("Unmute Community")
|
||
icon.name: "notification"
|
||
onTriggered: {
|
||
communityContextMenu.chatCommunitySectionModule.setCommunityMuted(Constants.MutingVariations.Unmuted)
|
||
}
|
||
}
|
||
|
||
StatusAction {
|
||
text: qsTr("Edit Shared Addresses")
|
||
icon.name: "wallet"
|
||
enabled: {
|
||
if (model.memberRole === Constants.memberRole.owner || communityContextMenu.isSpectator)
|
||
return false
|
||
return true
|
||
}
|
||
onTriggered: {
|
||
communityContextMenu.close()
|
||
Global.openEditSharedAddressesFlow(model.id)
|
||
}
|
||
}
|
||
|
||
StatusMenuSeparator { visible: leaveCommunityMenuItem.enabled }
|
||
|
||
StatusAction {
|
||
id: leaveCommunityMenuItem
|
||
objectName: "leaveCommunityMenuItem"
|
||
// allow to leave community for the owner in non-production builds
|
||
enabled: model.memberRole !== Constants.memberRole.owner || !production
|
||
text: {
|
||
if (communityContextMenu.isSpectator)
|
||
return qsTr("Close Community")
|
||
return qsTr("Leave Community")
|
||
}
|
||
icon.name: communityContextMenu.isSpectator ? "close-circle" : "arrow-left"
|
||
type: StatusAction.Type.Danger
|
||
onTriggered: communityContextMenu.isSpectator ? communityContextMenu.chatCommunitySectionModule.leaveCommunity()
|
||
: popups.openLeaveCommunityPopup(model.name, model.id, model.outroMessage)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
regularItemsModel: SortFilterProxyModel {
|
||
sourceModel: appMain.rootStore.mainModuleInst.sectionsModel
|
||
filters: [
|
||
RangeFilter {
|
||
roleName: "sectionType"
|
||
minimumValue: Constants.appSection.profile
|
||
maximumValue: Constants.appSection.loadingSection
|
||
},
|
||
ValueFilter {
|
||
roleName: "enabled"
|
||
value: true
|
||
}
|
||
]
|
||
}
|
||
regularItemDelegate: navbarButton
|
||
|
||
delegateHeight: 40
|
||
|
||
profileComponent: StatusNavBarTabButton {
|
||
id: profileButton
|
||
objectName: "statusProfileNavBarTabButton"
|
||
property bool opened: false
|
||
|
||
name: appMain.profileStore.name
|
||
icon.source: appMain.profileStore.icon
|
||
implicitWidth: 32
|
||
implicitHeight: 32
|
||
identicon.asset.width: width
|
||
identicon.asset.height: height
|
||
identicon.asset.useAcronymForLetterIdenticon: true
|
||
identicon.asset.color: Utils.colorForPubkey(appMain.profileStore.pubkey)
|
||
identicon.ringSettings.ringSpecModel: Utils.getColorHashAsJson(appMain.profileStore.pubkey,
|
||
appMain.profileStore.preferredName)
|
||
|
||
badge.visible: true
|
||
badge.anchors {
|
||
left: undefined
|
||
top: undefined
|
||
right: profileButton.right
|
||
bottom: profileButton.bottom
|
||
margins: 0
|
||
rightMargin: -badge.border.width
|
||
bottomMargin: -badge.border.width
|
||
}
|
||
badge.implicitHeight: 12
|
||
badge.implicitWidth: 12
|
||
badge.border.width: 2
|
||
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusAppNavBar.backgroundColor
|
||
badge.color: {
|
||
switch(appMain.profileStore.currentUserStatus){
|
||
case Constants.currentUserStatus.automatic:
|
||
case Constants.currentUserStatus.alwaysOnline:
|
||
return Theme.palette.successColor1
|
||
default:
|
||
return Theme.palette.baseColor1
|
||
}
|
||
}
|
||
|
||
onClicked: userStatusContextMenu.opened ? userStatusContextMenu.close() : userStatusContextMenu.open()
|
||
|
||
UserStatusContextMenu {
|
||
id: userStatusContextMenu
|
||
|
||
readonly property string pubKey: appMain.profileStore.pubkey
|
||
|
||
y: profileButton.y - userStatusContextMenu.height + profileButton.height
|
||
x: profileButton.x + profileButton.width + 5
|
||
|
||
compressedPubKey: appMain.profileStore.compressedPubKey
|
||
emojiHash: appMain.utilsStore.getEmojiHash(pubKey)
|
||
colorHash: appMain.profileStore.colorHash
|
||
colorId: appMain.profileStore.colorId
|
||
name: appMain.profileStore.name
|
||
icon: appMain.profileStore.icon
|
||
isEnsVerified: !!appMain.profileStore.preferredName
|
||
|
||
currentUserStatus: appMain.profileStore.currentUserStatus
|
||
|
||
onViewProfileRequested: Global.openProfilePopup(pubKey)
|
||
onCopyLinkRequested: ClipboardUtils.setText(appMain.rootStore.contactStore.getLinkToProfile(pubKey))
|
||
onSetCurrentUserStatusRequested: appMain.rootStore.setCurrentUserStatus(status)
|
||
}
|
||
}
|
||
|
||
Component {
|
||
id: navbarButton
|
||
StatusNavBarTabButton {
|
||
id: navbar
|
||
objectName: model.name + "-navbar"
|
||
anchors.horizontalCenter: parent.horizontalCenter
|
||
name: model.icon.length > 0? "" : model.name
|
||
icon.name: model.icon
|
||
icon.source: model.image
|
||
tooltip.text: Utils.translatedSectionName(model.sectionType, model.name)
|
||
checked: model.active
|
||
badge.value: model.notificationsCount
|
||
badge.visible: (model.sectionType === Constants.appSection.profile &&
|
||
contactsModelAdaptor.pendingReceivedRequestContacts.ModelCount.count > 0) ? // pending contact request
|
||
true :
|
||
model.hasNotification // Otherwise, use the value coming from the model
|
||
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
|
||
badge.border.width: 2
|
||
onClicked: {
|
||
changeAppSectionBySectionId(model.id)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
rightPanel: ColumnLayout {
|
||
spacing: 0
|
||
objectName: "mainRightView"
|
||
|
||
ColumnLayout {
|
||
id: bannersLayout
|
||
|
||
enabled: !localAppSettings.testEnvironment
|
||
visible: enabled
|
||
|
||
property var updateBanner: null
|
||
property var connectedBanner: null
|
||
readonly property bool isConnected: appMain.rootStore.mainModuleInst.isOnline
|
||
|
||
function processUpdateAvailable() {
|
||
if (!updateBanner)
|
||
updateBanner = updateBannerComponent.createObject(this)
|
||
}
|
||
|
||
function processConnected() {
|
||
if (!connectedBanner)
|
||
connectedBanner = connectedBannerComponent.createObject(this)
|
||
}
|
||
|
||
Layout.fillWidth: true
|
||
Layout.maximumHeight: implicitHeight
|
||
spacing: 1
|
||
|
||
onIsConnectedChanged: {
|
||
processConnected()
|
||
}
|
||
|
||
Component.onCompleted: {
|
||
if (!isConnected)
|
||
processConnected()
|
||
}
|
||
|
||
Connections {
|
||
target: rootStore.aboutModuleInst
|
||
function onAppVersionFetched(available: bool, version: string, url: string) {
|
||
rootStore.setLatestVersionInfo(available, version, url);
|
||
// TODO when we re-implement check for updates, uncomment this
|
||
// bannersLayout.processUpdateAvailable()
|
||
}
|
||
}
|
||
|
||
ModuleWarning {
|
||
id: testnetBanner
|
||
objectName: "testnetBanner"
|
||
Layout.fillWidth: true
|
||
text: qsTr("Testnet mode enabled. All balances, transactions and dApp interactions will be on testnets.")
|
||
buttonText: qsTr("Turn off")
|
||
type: ModuleWarning.Warning
|
||
iconName: "warning"
|
||
active: appMain.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
|
||
delay: false
|
||
onClicked: Global.openTestnetPopup()
|
||
closeBtnVisible: false
|
||
}
|
||
|
||
ModuleWarning {
|
||
id: secureYourSeedPhrase
|
||
objectName: "secureYourSeedPhraseBanner"
|
||
Layout.fillWidth: true
|
||
active: !appMain.rootStore.profileSectionStore.profileStore.userDeclinedBackupBanner
|
||
&& !appMain.rootStore.profileSectionStore.profileStore.privacyStore.mnemonicBackedUp
|
||
type: ModuleWarning.Danger
|
||
text: qsTr("Secure your seed phrase")
|
||
buttonText: qsTr("Back up now")
|
||
delay: false
|
||
onClicked: popups.openBackUpSeedPopup()
|
||
|
||
onCloseClicked: {
|
||
appMain.rootStore.profileSectionStore.profileStore.userDeclinedBackupBanner = true
|
||
}
|
||
}
|
||
|
||
|
||
ModuleWarning {
|
||
Layout.fillWidth: true
|
||
readonly property int progress: appMain.communitiesStore.discordImportProgress
|
||
readonly property bool inProgress: (progress > 0 && progress < 100) || appMain.communitiesStore.discordImportInProgress
|
||
readonly property bool finished: progress >= 100
|
||
readonly property bool cancelled: appMain.communitiesStore.discordImportCancelled
|
||
readonly property bool stopped: appMain.communitiesStore.discordImportProgressStopped
|
||
readonly property int errors: appMain.communitiesStore.discordImportErrorsCount
|
||
readonly property int warnings: appMain.communitiesStore.discordImportWarningsCount
|
||
readonly property string communityId: appMain.communitiesStore.discordImportCommunityId
|
||
readonly property string communityName: appMain.communitiesStore.discordImportCommunityName
|
||
readonly property string channelId: appMain.communitiesStore.discordImportChannelId
|
||
readonly property string channelName: appMain.communitiesStore.discordImportChannelName
|
||
readonly property string channelOrCommunityName: channelName || communityName
|
||
delay: false
|
||
active: !cancelled && (inProgress || finished || stopped)
|
||
type: errors ? ModuleWarning.Type.Danger : ModuleWarning.Type.Success
|
||
text: {
|
||
if (finished || stopped) {
|
||
if (errors)
|
||
return qsTr("The import of ‘%1’ from Discord to Status was stopped: <a href='#'>Critical issues found</a>").arg(channelOrCommunityName)
|
||
|
||
let result = qsTr("‘%1’ was successfully imported from Discord to Status").arg(channelOrCommunityName) + " <a href='#'>"
|
||
if (warnings)
|
||
result += qsTr("Details (%1)").arg(qsTr("%n issue(s)", "", warnings))
|
||
else
|
||
result += qsTr("Details")
|
||
result += "</a>"
|
||
return result
|
||
}
|
||
if (inProgress) {
|
||
let result = qsTr("Importing ‘%1’ from Discord to Status").arg(channelOrCommunityName) + " <a href='#'>"
|
||
if (warnings)
|
||
result += qsTr("Check progress (%1)").arg(qsTr("%n issue(s)", "", warnings))
|
||
else
|
||
result += qsTr("Check progress")
|
||
result += "</a>"
|
||
return result
|
||
}
|
||
|
||
return ""
|
||
}
|
||
onLinkActivated: popups.openDiscordImportProgressPopup(!!channelId)
|
||
progressValue: progress
|
||
closeBtnVisible: finished || stopped
|
||
buttonText: finished && !errors ? !!channelId ? qsTr("Visit your new channel") : qsTr("Visit your Community") : ""
|
||
onClicked: function() {
|
||
if (!!channelId)
|
||
rootStore.setActiveSectionChat(communityId, channelId)
|
||
else
|
||
appMain.communitiesStore.setActiveCommunity(communityId)
|
||
}
|
||
onCloseClicked: hide()
|
||
}
|
||
|
||
ModuleWarning {
|
||
id: downloadingArchivesBanner
|
||
Layout.fillWidth: true
|
||
active: appMain.communitiesStore.downloadingCommunityHistoryArchives
|
||
type: ModuleWarning.Danger
|
||
text: qsTr("Downloading message history archives, DO NOT CLOSE THE APP until this banner disappears.")
|
||
closeBtnVisible: false
|
||
delay: false
|
||
}
|
||
|
||
ModuleWarning {
|
||
id: mailserverConnectionBanner
|
||
type: ModuleWarning.Warning
|
||
text: qsTr("Can not connect to store node. Retrying automatically")
|
||
onCloseClicked: hide()
|
||
Layout.fillWidth: true
|
||
}
|
||
|
||
Component {
|
||
id: connectedBannerComponent
|
||
|
||
ModuleWarning {
|
||
id: connectedBanner
|
||
property bool isConnected: true
|
||
|
||
objectName: "connectionInfoBanner"
|
||
Layout.fillWidth: true
|
||
text: isConnected ? qsTr("You are back online") : qsTr("Internet connection lost. Reconnect to ensure everything is up to date.")
|
||
type: isConnected ? ModuleWarning.Success : ModuleWarning.Danger
|
||
|
||
function updateState() {
|
||
if (isConnected)
|
||
showFor()
|
||
else
|
||
show();
|
||
}
|
||
|
||
Component.onCompleted: {
|
||
connectedBanner.isConnected = Qt.binding(() => bannersLayout.isConnected);
|
||
}
|
||
onIsConnectedChanged: {
|
||
updateState();
|
||
}
|
||
onCloseClicked: {
|
||
hide();
|
||
}
|
||
onHideFinished: {
|
||
destroy()
|
||
bannersLayout.connectedBanner = null
|
||
}
|
||
}
|
||
}
|
||
|
||
Component {
|
||
id: updateBannerComponent
|
||
|
||
ModuleWarning {
|
||
readonly property string version: appMain.rootStore.latestVersion
|
||
readonly property bool updateAvailable: appMain.rootStore.newVersionAvailable
|
||
|
||
objectName: "appVersionUpdateBanner"
|
||
Layout.fillWidth: true
|
||
type: ModuleWarning.Success
|
||
delay: false
|
||
text: updateAvailable ? qsTr("A new version of Status (%1) is available").arg(version)
|
||
: qsTr("Your version is up to date")
|
||
|
||
buttonText: updateAvailable ? qsTr("Update")
|
||
: qsTr("Close")
|
||
|
||
function updateState() {
|
||
if (updateAvailable)
|
||
show()
|
||
else
|
||
showFor(5000)
|
||
}
|
||
|
||
Component.onCompleted: {
|
||
updateState()
|
||
}
|
||
onUpdateAvailableChanged: {
|
||
updateState();
|
||
}
|
||
onClicked: {
|
||
if (updateAvailable)
|
||
Global.openDownloadModal(appMain.rootStore.newVersionAvailable,
|
||
appMain.rootStore.latestVersion,
|
||
appMain.rootStore.downloadURL)
|
||
else
|
||
close()
|
||
}
|
||
onCloseClicked: {
|
||
if (updateAvailable)
|
||
appMain.rootStore.resetLastVersion();
|
||
hide()
|
||
}
|
||
onHideFinished: {
|
||
destroy()
|
||
bannersLayout.updateBanner = null
|
||
}
|
||
}
|
||
}
|
||
|
||
ConnectionWarnings {
|
||
id: walletBlockchainConnectionBanner
|
||
objectName: "walletBlockchainConnectionBanner"
|
||
Layout.fillWidth: true
|
||
websiteDown: Constants.walletConnections.blockchains
|
||
withCache: networkConnectionStore.balanceCache
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
tooltipMessage: qsTr("Pocket Network (POKT) & Infura are currently both unavailable for %1. Balances for those chains are as of %2.").arg(jointChainIdString).arg(lastCheckedAt)
|
||
toastText: {
|
||
switch(connectionState) {
|
||
case Constants.ConnectionStatus.Success:
|
||
return qsTr("Pocket Network (POKT) connection successful")
|
||
case Constants.ConnectionStatus.Failure:
|
||
if(completelyDown) {
|
||
if(withCache)
|
||
return qsTr("POKT & Infura down. Token balances are as of %1.").arg(lastCheckedAt)
|
||
else
|
||
return qsTr("POKT & Infura down. Token balances cannot be retrieved.")
|
||
}
|
||
else if(chainIdsDown.length > 0) {
|
||
if(chainIdsDown.length > 2) {
|
||
return qsTr("POKT & Infura down for <a href='#'>multiple chains </a>. Token balances for those chains cannot be retrieved.")
|
||
}
|
||
else if(chainIdsDown.length === 1) {
|
||
return qsTr("POKT & Infura down for %1. %1 token balances are as of %2.").arg(jointChainIdString).arg(lastCheckedAt)
|
||
}
|
||
else {
|
||
return qsTr("POKT & Infura down for %1. %1 token balances cannot be retrieved.").arg(jointChainIdString)
|
||
}
|
||
}
|
||
else
|
||
return ""
|
||
case Constants.ConnectionStatus.Retrying:
|
||
return qsTr("Retrying connection to POKT Network (grove.city).")
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
}
|
||
|
||
ConnectionWarnings {
|
||
id: walletCollectiblesConnectionBanner
|
||
objectName: "walletCollectiblesConnectionBanner"
|
||
Layout.fillWidth: true
|
||
websiteDown: Constants.walletConnections.collectibles
|
||
withCache: lastCheckedAtUnix > 0
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
tooltipMessage: {
|
||
if(withCache)
|
||
return qsTr("Collectibles providers are currently unavailable for %1. Collectibles for those chains are as of %2.").arg(jointChainIdString).arg(lastCheckedAt)
|
||
else
|
||
return qsTr("Collectibles providers are currently unavailable for %1.").arg(jointChainIdString)
|
||
}
|
||
toastText: {
|
||
switch(connectionState) {
|
||
case Constants.ConnectionStatus.Success:
|
||
return qsTr("Collectibles providers connection successful")
|
||
case Constants.ConnectionStatus.Failure:
|
||
if(completelyDown) {
|
||
if(withCache)
|
||
return qsTr("Collectibles providers down. Collectibles are as of %1.").arg(lastCheckedAt)
|
||
else
|
||
return qsTr("Collectibles providers down. Collectibles cannot be retrieved.")
|
||
}
|
||
else if(chainIdsDown.length > 0) {
|
||
if(chainIdsDown.length > 2) {
|
||
if(withCache)
|
||
return qsTr("Collectibles providers down for <a href='#'>multiple chains</a>. Collectibles for these chains are as of %1.".arg(lastCheckedAt))
|
||
else
|
||
return qsTr("Collectibles providers down for <a href='#'>multiple chains</a>. Collectibles for these chains cannot be retrieved.")
|
||
}
|
||
else if(chainIdsDown.length === 1) {
|
||
if(withCache)
|
||
return qsTr("Collectibles providers down for %1. Collectibles for this chain are as of %2.").arg(jointChainIdString).arg(lastCheckedAt)
|
||
else
|
||
return qsTr("Collectibles providers down for %1. Collectibles for this chain cannot be retrieved.").arg(jointChainIdString)
|
||
}
|
||
else {
|
||
if(withCache)
|
||
return qsTr("Collectibles providers down for %1. Collectibles for these chains are as of %2.").arg(jointChainIdString).arg(lastCheckedAt)
|
||
else
|
||
return qsTr("Collectibles providers down for %1. Collectibles for these chains cannot be retrieved.").arg(jointChainIdString)
|
||
}
|
||
}
|
||
else
|
||
return ""
|
||
case Constants.ConnectionStatus.Retrying:
|
||
return qsTr("Retrying connection to collectibles providers...")
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
}
|
||
|
||
ConnectionWarnings {
|
||
id: walletMarketConnectionBanner
|
||
objectName: "walletMarketConnectionBanner"
|
||
Layout.fillWidth: true
|
||
websiteDown: Constants.walletConnections.market
|
||
withCache: networkConnectionStore.marketValuesCache
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
toastText: {
|
||
switch(connectionState) {
|
||
case Constants.ConnectionStatus.Success:
|
||
return qsTr("CryptoCompare and CoinGecko connection successful")
|
||
case Constants.ConnectionStatus.Failure: {
|
||
if(withCache) {
|
||
return qsTr("CryptoCompare and CoinGecko down. Market values are as of %1.").arg(lastCheckedAt)
|
||
}
|
||
else {
|
||
return qsTr("CryptoCompare and CoinGecko down. Market values cannot be retrieved.")
|
||
}
|
||
}
|
||
case Constants.ConnectionStatus.Retrying:
|
||
return qsTr("Retrying connection to CryptoCompare and CoinGecko...")
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Item {
|
||
Layout.fillWidth: true
|
||
Layout.fillHeight: true
|
||
|
||
StackLayout {
|
||
id: appView
|
||
anchors.fill: parent
|
||
|
||
currentIndex: {
|
||
const activeSectionType = appMain.rootStore.mainModuleInst.activeSection.sectionType
|
||
|
||
if (activeSectionType === Constants.appSection.chat)
|
||
return Constants.appViewStackIndex.chat
|
||
if (activeSectionType === Constants.appSection.community) {
|
||
for (let i = this.children.length - 1; i >=0; i--) {
|
||
var obj = this.children[i]
|
||
if (obj && obj.sectionId && obj.sectionId === appMain.rootStore.mainModuleInst.activeSection.id) {
|
||
return i
|
||
}
|
||
}
|
||
|
||
// Should never be here, correct index must be returned from the for loop above
|
||
console.error("Wrong section type:", appMain.rootStore.mainModuleInst.activeSection.sectionType,
|
||
"or section id: ", appMain.rootStore.mainModuleInst.activeSection.id)
|
||
return Constants.appViewStackIndex.community
|
||
}
|
||
if (activeSectionType === Constants.appSection.communitiesPortal)
|
||
return Constants.appViewStackIndex.communitiesPortal
|
||
if (activeSectionType === Constants.appSection.wallet)
|
||
return Constants.appViewStackIndex.wallet
|
||
if (activeSectionType === Constants.appSection.profile)
|
||
return Constants.appViewStackIndex.profile
|
||
if (activeSectionType === Constants.appSection.node)
|
||
return Constants.appViewStackIndex.node
|
||
|
||
// We should never end up here
|
||
console.error("AppMain: Unknown section type")
|
||
}
|
||
|
||
// NOTE:
|
||
// If we ever change stack layout component order we need to updade
|
||
// Constants.appViewStackIndex accordingly
|
||
|
||
Loader {
|
||
id: personalChatLayoutLoader
|
||
asynchronous: true
|
||
active: false
|
||
sourceComponent: {
|
||
if (appMain.rootStore.mainModuleInst.chatsLoadingFailed) {
|
||
return errorStateComponent
|
||
}
|
||
if (appMain.rootStore.mainModuleInst.sectionsLoaded) {
|
||
return personalChatLayoutComponent
|
||
}
|
||
return loadingStateComponent
|
||
}
|
||
|
||
// Do not unload section data from the memory in order not
|
||
// to reset scroll, not send text input and etc during the
|
||
// sections switching
|
||
Binding on active {
|
||
when: appView.currentIndex === Constants.appViewStackIndex.chat
|
||
value: true
|
||
restoreMode: Binding.RestoreNone
|
||
}
|
||
|
||
Component {
|
||
id: loadingStateComponent
|
||
Item {
|
||
anchors.fill: parent
|
||
|
||
Row {
|
||
anchors.centerIn: parent
|
||
spacing: 6
|
||
StatusBaseText {
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: qsTr("Loading sections...")
|
||
}
|
||
LoadingAnimation { anchors.verticalCenter: parent.verticalCenter }
|
||
}
|
||
}
|
||
}
|
||
|
||
Component {
|
||
id: errorStateComponent
|
||
Item {
|
||
anchors.fill: parent
|
||
StatusBaseText {
|
||
text: qsTr("Error loading chats, try closing the app and restarting")
|
||
anchors.centerIn: parent
|
||
}
|
||
}
|
||
}
|
||
|
||
Component {
|
||
id: personalChatLayoutComponent
|
||
|
||
ChatLayout {
|
||
id: chatLayoutContainer
|
||
|
||
sharedRootStore: appMain.sharedRootStore
|
||
utilsStore: appMain.utilsStore
|
||
rootStore: ChatStores.RootStore {
|
||
contactsStore: appMain.rootStore.contactStore
|
||
currencyStore: appMain.currencyStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
emojiReactionsModel: appMain.rootStore.emojiReactionsModel
|
||
openCreateChat: createChatView.opened
|
||
chatCommunitySectionModule: appMain.rootStore.mainModuleInst.getChatSectionModule()
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
}
|
||
createChatPropertiesStore: appMain.createChatPropertiesStore
|
||
tokensStore: appMain.tokensStore
|
||
transactionStore: appMain.transactionStore
|
||
walletAssetsStore: appMain.walletAssetsStore
|
||
currencyStore: appMain.currencyStore
|
||
emojiPopup: statusEmojiPopup.item
|
||
stickersPopup: statusStickersPopupLoader.item
|
||
sendViaPersonalChatEnabled: featureFlagsStore.sendViaPersonalChatEnabled && appMain.networkConnectionStore.sendBuyBridgeEnabled
|
||
areTestNetworksEnabled: appMain.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
|
||
paymentRequestFeatureEnabled: featureFlagsStore.paymentRequestEnabled
|
||
|
||
mutualContactsModel: contactsModelAdaptor.mutualContacts
|
||
|
||
onProfileButtonClicked: {
|
||
Global.changeAppSectionBySectionType(Constants.appSection.profile);
|
||
}
|
||
|
||
onOpenAppSearch: {
|
||
appSearch.openSearchPopup()
|
||
}
|
||
|
||
onBuyStickerPackRequested: sendModalHandler.buyStickerPack(packId, price)
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
active: appView.currentIndex === Constants.appViewStackIndex.communitiesPortal
|
||
asynchronous: true
|
||
CommunitiesPortalLayout {
|
||
anchors.fill: parent
|
||
communitiesStore: appMain.communitiesStore
|
||
assetsModel: appMain.rootStore.globalAssetsModel
|
||
collectiblesModel: appMain.rootStore.globalCollectiblesModel
|
||
notificationCount: appMain.activityCenterStore.unreadNotificationsCount
|
||
hasUnseenNotifications: activityCenterStore.hasUnseenNotifications
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: walletLoader
|
||
active: appView.currentIndex === Constants.appViewStackIndex.wallet
|
||
asynchronous: true
|
||
sourceComponent: WalletLayout {
|
||
objectName: "walletLayoutReal"
|
||
sharedRootStore: appMain.sharedRootStore
|
||
store: appMain.rootStore
|
||
contactsStore: appMain.rootStore.profileSectionStore.contactsStore
|
||
communitiesStore: appMain.communitiesStore
|
||
transactionStore: appMain.transactionStore
|
||
emojiPopup: statusEmojiPopup.item
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
appMainVisible: appMain.visible
|
||
swapEnabled: featureFlagsStore.swapEnabled
|
||
hideSignPhraseModal: userAgreementLoader.active
|
||
dAppsVisible: dAppsServiceLoader.item ? dAppsServiceLoader.item.serviceAvailableToCurrentAddress : false
|
||
dAppsEnabled: dAppsServiceLoader.item ? dAppsServiceLoader.item.isServiceOnline : false
|
||
walletConnectEnabled: featureFlagsStore.dappsEnabled
|
||
browserConnectEnabled: featureFlagsStore.connectorEnabled
|
||
dAppsModel: dAppsServiceLoader.item ? dAppsServiceLoader.item.dappsModel : null
|
||
|
||
onDappPairRequested: dAppsServiceLoader.dappPairRequested()
|
||
onDappDisconnectRequested: (dappUrl) => dAppsServiceLoader.dappDisconnectRequested(dappUrl)
|
||
onSendTokenRequested: sendModalHandler.sendToken(
|
||
senderAddress, tokenId, tokenType)
|
||
onBridgeTokenRequested: sendModalHandler.bridgeToken(tokenId, tokenType)
|
||
}
|
||
onLoaded: {
|
||
item.resetView()
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: profileLoader
|
||
|
||
property int settingsSubsection: Constants.settingsSubsection.profile
|
||
property int settingsSubSubsection: -1
|
||
|
||
active: appView.currentIndex === Constants.appViewStackIndex.profile
|
||
asynchronous: true
|
||
sourceComponent: ProfileLayout {
|
||
sharedRootStore: appMain.sharedRootStore
|
||
utilsStore: appMain.utilsStore
|
||
store: appMain.rootStore.profileSectionStore
|
||
globalStore: appMain.rootStore
|
||
communitiesStore: appMain.communitiesStore
|
||
systemPalette: appMain.sysPalette
|
||
emojiPopup: statusEmojiPopup.item
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
tokensStore: appMain.tokensStore
|
||
walletAssetsStore: appMain.walletAssetsStore
|
||
collectiblesStore: appMain.walletCollectiblesStore
|
||
currencyStore: appMain.currencyStore
|
||
isCentralizedMetricsEnabled: appMain.isCentralizedMetricsEnabled
|
||
settingsSubSubsection: profileLoader.settingsSubSubsection
|
||
|
||
mutualContactsModel: contactsModelAdaptor.mutualContacts
|
||
blockedContactsModel: contactsModelAdaptor.blockedContacts
|
||
pendingReceivedRequestContactsModel: contactsModelAdaptor.pendingReceivedRequestContacts
|
||
pendingSentRequestContactsModel: contactsModelAdaptor.pendingSentRequestContacts
|
||
|
||
Binding on settingsSubsection {
|
||
value: profileLoader.settingsSubsection
|
||
}
|
||
|
||
onSettingsSubsectionChanged: profileLoader.settingsSubsection = settingsSubsection
|
||
|
||
onConnectUsernameRequested: sendModalHandler.connectUsername(ensName)
|
||
onRegisterUsernameRequested: sendModalHandler.registerUsername(ensName)
|
||
onReleaseUsernameRequested: sendModalHandler.releaseUsername(ensName, senderAddress, chainId)
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
active: appView.currentIndex === Constants.appViewStackIndex.node
|
||
asynchronous: true
|
||
sourceComponent: NodeLayout {}
|
||
}
|
||
|
||
Repeater {
|
||
model: SortFilterProxyModel {
|
||
sourceModel: appMain.rootStore.mainModuleInst.sectionsModel
|
||
filters: ValueFilter {
|
||
roleName: "sectionType"
|
||
value: Constants.appSection.community
|
||
}
|
||
}
|
||
|
||
delegate: Loader {
|
||
id: communityLoader
|
||
|
||
readonly property string sectionId: model.id
|
||
|
||
Layout.fillWidth: true
|
||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||
Layout.fillHeight: true
|
||
|
||
asynchronous: true
|
||
active: false
|
||
|
||
// Do not unload section data from the memory in order not
|
||
// to reset scroll, not send text input and etc during the
|
||
// sections switching
|
||
Binding on active {
|
||
when: sectionId === appMain.rootStore.mainModuleInst.activeSection.id
|
||
value: true
|
||
restoreMode: Binding.RestoreNone
|
||
}
|
||
|
||
sourceComponent: ChatLayout {
|
||
id: chatLayoutComponent
|
||
|
||
readonly property bool isManageCommunityEnabledInAdvanced: appMain.rootStore.profileSectionStore.advancedStore.isManageCommunityOnTestModeEnabled
|
||
|
||
Connections {
|
||
target: Global
|
||
function onSwitchToCommunitySettings(communityId: string) {
|
||
if (communityId !== model.id)
|
||
return
|
||
chatLayoutComponent.currentIndex = 1 // Settings
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: Global
|
||
function onSwitchToCommunityChannelsView(communityId: string) {
|
||
if (communityId !== model.id)
|
||
return
|
||
chatLayoutComponent.currentIndex = 0
|
||
}
|
||
}
|
||
|
||
emojiPopup: statusEmojiPopup.item
|
||
stickersPopup: statusStickersPopupLoader.item
|
||
sectionItemModel: model
|
||
createChatPropertiesStore: appMain.createChatPropertiesStore
|
||
areTestNetworksEnabled: appMain.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
|
||
communitiesStore: appMain.communitiesStore
|
||
communitySettingsDisabled: !chatLayoutComponent.isManageCommunityEnabledInAdvanced &&
|
||
(production && appMain.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled)
|
||
sharedRootStore: appMain.sharedRootStore
|
||
utilsStore: appMain.utilsStore
|
||
rootStore: ChatStores.RootStore {
|
||
contactsStore: appMain.rootStore.contactStore
|
||
currencyStore: appMain.currencyStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
emojiReactionsModel: appMain.rootStore.emojiReactionsModel
|
||
openCreateChat: createChatView.opened
|
||
chatCommunitySectionModule: {
|
||
appMain.rootStore.mainModuleInst.prepareCommunitySectionModuleForCommunityId(model.id)
|
||
return appMain.rootStore.mainModuleInst.getCommunitySectionModule()
|
||
}
|
||
}
|
||
tokensStore: appMain.tokensStore
|
||
transactionStore: appMain.transactionStore
|
||
walletAssetsStore: appMain.walletAssetsStore
|
||
currencyStore: appMain.currencyStore
|
||
paymentRequestFeatureEnabled: featureFlagsStore.paymentRequestEnabled
|
||
|
||
mutualContactsModel: contactsModelAdaptor.mutualContacts
|
||
|
||
onProfileButtonClicked: {
|
||
Global.changeAppSectionBySectionType(Constants.appSection.profile);
|
||
}
|
||
|
||
onOpenAppSearch: {
|
||
appSearch.openSearchPopup()
|
||
}
|
||
|
||
onBuyStickerPackRequested: sendModalHandler.buyStickerPack(packId, price)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: createChatView
|
||
|
||
property bool opened: false
|
||
active: appMain.rootStore.mainModuleInst.sectionsLoaded && opened
|
||
|
||
asynchronous: true
|
||
anchors.top: parent.top
|
||
anchors.topMargin: 8
|
||
anchors.rightMargin: 8
|
||
anchors.bottom: parent.bottom
|
||
anchors.right: parent.right
|
||
width: active ?
|
||
parent.width - Constants.chatSectionLeftColumnWidth -
|
||
anchors.rightMargin - anchors.leftMargin : 0
|
||
|
||
sourceComponent: CreateChatView {
|
||
sharedRootStore: appMain.sharedRootStore
|
||
utilsStore: appMain.utilsStore
|
||
rootStore: ChatStores.RootStore {
|
||
contactsStore: appMain.rootStore.contactStore
|
||
currencyStore: appMain.currencyStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
emojiReactionsModel: appMain.rootStore.emojiReactionsModel
|
||
openCreateChat: createChatView.opened
|
||
chatCommunitySectionModule: appMain.rootStore.mainModuleInst.getChatSectionModule()
|
||
}
|
||
createChatPropertiesStore: appMain.createChatPropertiesStore
|
||
|
||
mutualContactsModel: contactsModelAdaptor.mutualContacts
|
||
|
||
emojiPopup: statusEmojiPopup.item
|
||
stickersPopup: statusStickersPopupLoader.item
|
||
}
|
||
}
|
||
}
|
||
} // ColumnLayout
|
||
|
||
Component {
|
||
id: activityCenterPopupComponent
|
||
ActivityCenterPopup {
|
||
// TODO get screen size // Taken from old code top bar height was fixed there to 56
|
||
readonly property int _buttonSize: 56
|
||
|
||
x: parent.width - width - Theme.smallPadding
|
||
y: parent.y + _buttonSize
|
||
height: appView.height - _buttonSize * 2
|
||
store: ChatStores.RootStore {
|
||
contactsStore: appMain.rootStore.contactStore
|
||
currencyStore: appMain.currencyStore
|
||
communityTokensStore: appMain.communityTokensStore
|
||
emojiReactionsModel: appMain.rootStore.emojiReactionsModel
|
||
openCreateChat: createChatView.opened
|
||
walletStore: WalletStores.RootStore
|
||
chatCommunitySectionModule: appMain.rootStore.mainModuleInst.getChatSectionModule()
|
||
}
|
||
activityCenterStore: appMain.activityCenterStore
|
||
}
|
||
}
|
||
|
||
Action {
|
||
shortcut: "Ctrl+1"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(0)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+2"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(1)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+3"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(2)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+4"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(3)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+5"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(4)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+6"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(5)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+7"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(6)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+8"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(7)
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+9"
|
||
onTriggered: {
|
||
Global.setNthEnabledSectionActive(8)
|
||
}
|
||
}
|
||
|
||
Action {
|
||
shortcut: "Ctrl+K"
|
||
onTriggered: {
|
||
// FIXME the focus is no longer on the AppMain when the popup is opened, so this does not work to close
|
||
if (!channelPickerLoader.active)
|
||
channelPickerLoader.active = true
|
||
|
||
if (channelPickerLoader.item.opened) {
|
||
channelPickerLoader.item.close()
|
||
channelPickerLoader.active = false
|
||
} else {
|
||
channelPickerLoader.item.open()
|
||
}
|
||
}
|
||
}
|
||
Action {
|
||
shortcut: "Ctrl+F"
|
||
onTriggered: {
|
||
// FIXME the focus is no longer on the AppMain when the popup is opened, so this does not work to close
|
||
if (appSearch.active) {
|
||
appSearch.closeSearchPopup()
|
||
} else {
|
||
appSearch.openSearchPopup()
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: channelPickerLoader
|
||
active: false
|
||
asynchronous: true
|
||
sourceComponent: StatusSearchListPopup {
|
||
searchBoxPlaceholder: qsTr("Where do you want to go?")
|
||
model: rootStore.chatSearchModel
|
||
|
||
onAboutToShow: rootStore.rebuildChatSearchModel()
|
||
onSelected: {
|
||
rootStore.setActiveSectionChat(sectionId, chatId)
|
||
close()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
StatusListView {
|
||
id: toastArea
|
||
objectName: "ephemeralNotificationList"
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 8
|
||
anchors.bottom: parent.bottom
|
||
anchors.bottomMargin: 60
|
||
width: 374
|
||
height: Math.min(parent.height - 120, toastArea.contentHeight)
|
||
spacing: 8
|
||
verticalLayoutDirection: ListView.BottomToTop
|
||
model: appMain.rootStore.mainModuleInst.ephemeralNotificationModel
|
||
clip: false
|
||
|
||
delegate: StatusToastMessage {
|
||
readonly property bool isSquare : isSquareShape(model.actionData)
|
||
|
||
// Specific method to calculate image radius depending on if the toast represents some info about a collectible or an asset
|
||
function isSquareShape(data) {
|
||
// It expects the data is a JSON file containing `tokenType`
|
||
if(data) {
|
||
var parsedData = JSON.parse(data)
|
||
var tokenType = parsedData.tokenType
|
||
return tokenType === Constants.TokenType.ERC721
|
||
}
|
||
return false
|
||
}
|
||
|
||
objectName: "statusToastMessage"
|
||
width: ListView.view.width
|
||
primaryText: model.title
|
||
secondaryText: model.subTitle
|
||
image: model.image
|
||
imageRadius: model.image && isSquare ? 8 : imageSize / 2
|
||
icon.name: model.icon
|
||
iconColor: model.iconColor
|
||
loading: model.loading
|
||
type: model.ephNotifType
|
||
linkUrl: model.url
|
||
actionRequired: model.actionType !== ToastsManager.ActionType.None
|
||
duration: model.durationInMs
|
||
onClicked: {
|
||
appMain.rootStore.mainModuleInst.ephemeralNotificationClicked(model.timestamp)
|
||
this.open = false
|
||
}
|
||
onLinkActivated: {
|
||
this.open = false
|
||
if(actionRequired) {
|
||
toastsManager.doAction(model.actionType, model.actionData)
|
||
return
|
||
}
|
||
|
||
if (link.startsWith("#") && link !== "#") { // internal link to section
|
||
const sectionArgs = link.substring(1).split("/")
|
||
const section = sectionArgs[0]
|
||
let subsection = sectionArgs.length > 1 ? sectionArgs[1] : 0
|
||
let subsubsection = sectionArgs.length > 2 ? sectionArgs[2] : -1
|
||
Global.changeAppSectionBySectionType(section, subsection, subsubsection)
|
||
}
|
||
else
|
||
Global.openLink(link)
|
||
}
|
||
onClose: {
|
||
appMain.rootStore.mainModuleInst.removeEphemeralNotification(model.timestamp)
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: keycardPopupForAuthenticationOrSigning
|
||
active: false
|
||
sourceComponent: KeycardPopup {
|
||
myKeyUid: appMain.profileStore.keyUid
|
||
sharedKeycardModule: appMain.rootStore.mainModuleInst.keycardSharedModuleForAuthenticationOrSigning
|
||
}
|
||
|
||
onLoaded: {
|
||
keycardPopupForAuthenticationOrSigning.item.open()
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: keycardPopup
|
||
active: false
|
||
sourceComponent: KeycardPopup {
|
||
myKeyUid: appMain.profileStore.keyUid
|
||
sharedKeycardModule: appMain.rootStore.mainModuleInst.keycardSharedModule
|
||
}
|
||
|
||
onLoaded: {
|
||
keycardPopup.item.open()
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: addEditSavedAddress
|
||
|
||
active: false
|
||
|
||
property var params
|
||
|
||
function open(params = {}) {
|
||
addEditSavedAddress.params = params
|
||
addEditSavedAddress.active = true
|
||
}
|
||
|
||
function close() {
|
||
addEditSavedAddress.active = false
|
||
}
|
||
|
||
onLoaded: {
|
||
addEditSavedAddress.item.initWithParams(addEditSavedAddress.params)
|
||
addEditSavedAddress.item.open()
|
||
}
|
||
|
||
sourceComponent: WalletPopups.AddEditSavedAddressPopup {
|
||
store: WalletStores.RootStore
|
||
sharedRootStore: appMain.sharedRootStore
|
||
|
||
onClosed: {
|
||
addEditSavedAddress.close()
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: WalletStores.RootStore
|
||
|
||
function onSavedAddressAddedOrUpdated(added: bool, name: string, address: string, errorMsg: string) {
|
||
WalletStores.RootStore.addingSavedAddress = false
|
||
WalletStores.RootStore.lastCreatedSavedAddress = { address: address, error: errorMsg }
|
||
|
||
if (!!errorMsg) {
|
||
let mode = qsTr("adding")
|
||
if (!added) {
|
||
mode = qsTr("editing")
|
||
}
|
||
|
||
Global.displayToastMessage(qsTr("An error occurred while %1 %2 address").arg(mode).arg(name),
|
||
"",
|
||
"warning",
|
||
false,
|
||
Constants.ephemeralNotificationType.danger,
|
||
""
|
||
)
|
||
return
|
||
}
|
||
|
||
let msg = qsTr("%1 successfully added to your saved addresses")
|
||
if (!added) {
|
||
msg = qsTr("%1 saved address successfully edited")
|
||
}
|
||
Global.displayToastMessage(msg.arg(name),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: deleteSavedAddress
|
||
|
||
active: false
|
||
|
||
property var params
|
||
|
||
function open(params = {}) {
|
||
deleteSavedAddress.params = params
|
||
deleteSavedAddress.active = true
|
||
}
|
||
|
||
function close() {
|
||
deleteSavedAddress.active = false
|
||
}
|
||
|
||
onLoaded: {
|
||
deleteSavedAddress.item.address = deleteSavedAddress.params.address?? ""
|
||
deleteSavedAddress.item.ens = deleteSavedAddress.params.ens?? ""
|
||
deleteSavedAddress.item.name = deleteSavedAddress.params.name?? ""
|
||
deleteSavedAddress.item.colorId = deleteSavedAddress.params.colorId?? "blue"
|
||
|
||
deleteSavedAddress.item.open()
|
||
}
|
||
|
||
sourceComponent: WalletPopups.RemoveSavedAddressPopup {
|
||
onClosed: {
|
||
deleteSavedAddress.close()
|
||
}
|
||
|
||
onRemoveSavedAddress: {
|
||
WalletStores.RootStore.deleteSavedAddress(address)
|
||
close()
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: WalletStores.RootStore
|
||
|
||
function onSavedAddressDeleted(name: string, address: string, errorMsg: string) {
|
||
WalletStores.RootStore.deletingSavedAddress = false
|
||
|
||
if (!!errorMsg) {
|
||
|
||
Global.displayToastMessage(qsTr("An error occurred while removing %1 address").arg(name),
|
||
"",
|
||
"warning",
|
||
false,
|
||
Constants.ephemeralNotificationType.danger,
|
||
""
|
||
)
|
||
return
|
||
}
|
||
|
||
Global.displayToastMessage(qsTr("%1 was successfully removed from your saved addresses").arg(name),
|
||
"",
|
||
"checkmark-circle",
|
||
false,
|
||
Constants.ephemeralNotificationType.success,
|
||
""
|
||
)
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: showQR
|
||
|
||
active: false
|
||
|
||
property bool showSingleAccount: false
|
||
property bool showForSavedAddress: false
|
||
property var params
|
||
property var selectedAccount: ({
|
||
name: "",
|
||
address: "",
|
||
colorId: "",
|
||
emoji: ""
|
||
})
|
||
|
||
function open(params = {}) {
|
||
showQR.showSingleAccount = params.showSingleAccount?? false
|
||
showQR.showForSavedAddress = params.showForSavedAddress?? false
|
||
showQR.params = params
|
||
|
||
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
|
||
showQR.selectedAccount.name = params.name?? ""
|
||
showQR.selectedAccount.address = params.address?? ""
|
||
showQR.selectedAccount.colorId = params.colorId?? ""
|
||
showQR.selectedAccount.emoji = params.emoji?? ""
|
||
}
|
||
|
||
showQR.active = true
|
||
}
|
||
|
||
function close() {
|
||
showQR.active = false
|
||
}
|
||
|
||
onLoaded: {
|
||
showQR.item.switchingAccounsEnabled = showQR.params.switchingAccounsEnabled?? true
|
||
showQR.item.hasFloatingButtons = showQR.params.hasFloatingButtons?? true
|
||
|
||
showQR.item.open()
|
||
}
|
||
|
||
sourceComponent: WalletPopups.ReceiveModal {
|
||
|
||
ModelEntry {
|
||
id: selectedReceiverAccount
|
||
key: "address"
|
||
sourceModel: appMain.transactionStore.accounts
|
||
value: appMain.transactionStore.selectedReceiverAccountAddress
|
||
}
|
||
|
||
accounts: {
|
||
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
|
||
return null
|
||
}
|
||
return WalletStores.RootStore.accounts
|
||
}
|
||
|
||
selectedAccount: {
|
||
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
|
||
return showQR.selectedAccount
|
||
}
|
||
return selectedReceiverAccount.item ?? SQUtils.ModelUtils.get(appMain.transactionStore.accounts, 0)
|
||
}
|
||
|
||
onUpdateSelectedAddress: (address) => {
|
||
if (showQR.showSingleAccount || showQR.showForSavedAddress) {
|
||
return
|
||
}
|
||
appMain.transactionStore.setReceiverAccount(address)
|
||
}
|
||
|
||
onClosed: {
|
||
showQR.close()
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
Loader {
|
||
id: savedAddressActivity
|
||
|
||
active: false
|
||
|
||
property var params
|
||
|
||
function open(params = {}) {
|
||
savedAddressActivity.params = params
|
||
savedAddressActivity.active = true
|
||
}
|
||
|
||
function close() {
|
||
savedAddressActivity.active = false
|
||
}
|
||
|
||
onLoaded: {
|
||
savedAddressActivity.item.initWithParams(savedAddressActivity.params)
|
||
savedAddressActivity.item.open()
|
||
}
|
||
|
||
sourceComponent: WalletPopups.SavedAddressActivityPopup {
|
||
networkConnectionStore: appMain.networkConnectionStore
|
||
contactsStore: appMain.rootStore.contactStore
|
||
|
||
onSendToAddressRequested: {
|
||
Global.sendToRecipientRequested(address)
|
||
}
|
||
onClosed: {
|
||
savedAddressActivity.close()
|
||
}
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: userAgreementLoader
|
||
active: production && !localAppSettings.testEnvironment
|
||
sourceComponent: UserAgreementPopup {
|
||
visible: appMain.visible
|
||
onClosed: userAgreementLoader.active = false
|
||
}
|
||
}
|
||
|
||
Loader {
|
||
id: dAppsServiceLoader
|
||
|
||
signal dappPairRequested()
|
||
signal dappDisconnectRequested(string dappUrl)
|
||
|
||
// It seems some of the functionality of the dapp connector depends on the DAppsService
|
||
active: {
|
||
return (featureFlagsStore.dappsEnabled || featureFlagsStore.connectorEnabled) && appMain.visible
|
||
}
|
||
|
||
sourceComponent: DAppsService {
|
||
id: dAppsService
|
||
|
||
DAppsPopups.DAppsWorkflow {
|
||
id: dappsWorkflow
|
||
|
||
enabled: dAppsService.isServiceOnline
|
||
visualParent: appMain
|
||
loginType: appMain.rootStore.loginType
|
||
selectedAccountAddress: WalletStores.RootStore.selectedAddress
|
||
dAppsModel: dAppsService.dappsModel
|
||
accountsModel: WalletStores.RootStore.nonWatchAccounts
|
||
networksModel: WalletStores.RootStore.filteredFlatModel
|
||
sessionRequestsModel: dAppsService.sessionRequestsModel
|
||
|
||
formatBigNumber: (number, symbol, noSymbolOption) => WalletStores.RootStore.currencyStore.formatBigNumber(number, symbol, noSymbolOption)
|
||
|
||
onDisconnectRequested: (connectionId) => dAppsService.disconnectDapp(connectionId)
|
||
onPairingRequested: (uri) => dAppsService.pair(uri)
|
||
onPairingValidationRequested: (uri) => dAppsService.validatePairingUri(uri)
|
||
onConnectionAccepted: (pairingId, chainIds, selectedAccount) => dAppsService.approvePairSession(pairingId, chainIds, selectedAccount)
|
||
onConnectionDeclined: (pairingId) => dAppsService.rejectPairSession(pairingId)
|
||
onSignRequestAccepted: (connectionId, requestId) => dAppsService.sign(connectionId, requestId)
|
||
onSignRequestRejected: (connectionId, requestId) => dAppsService.rejectSign(connectionId, requestId, false /*hasError*/)
|
||
onSignRequestIsLive: (connectionId, requestId) => dAppsService.signRequestIsLive(connectionId, requestId)
|
||
|
||
Connections {
|
||
target: dAppsServiceLoader
|
||
|
||
function onDappPairRequested() {
|
||
dappsWorkflow.openPairing()
|
||
}
|
||
|
||
function onDappDisconnectRequested(dappUrl) {
|
||
dappsWorkflow.disconnectDapp(dappUrl)
|
||
}
|
||
}
|
||
}
|
||
|
||
// DAppsModule provides the middleware for the dapps
|
||
dappsModule: DAppsModule {
|
||
currenciesStore: WalletStores.RootStore.currencyStore
|
||
groupedAccountAssetsModel: WalletStores.RootStore.walletAssetsStore.groupedAccountAssetsModel
|
||
accountsModel: WalletStores.RootStore.nonWatchAccounts
|
||
networksModel: SortFilterProxyModel {
|
||
sourceModel: WalletStores.RootStore.filteredFlatModel
|
||
proxyRoles: [
|
||
FastExpressionRole {
|
||
name: "isOnline"
|
||
expression: !appMain.networkConnectionStore.blockchainNetworksDown.map(Number).includes(model.chainId)
|
||
expectedRoles: "chainId"
|
||
}
|
||
]
|
||
}
|
||
wcSdk: WalletConnectSDK {
|
||
enabled: featureFlagsStore.dappsEnabled && WalletStores.RootStore.walletSectionInst.walletReady
|
||
userUID: appMain.rootStore.profileSectionStore.profileStore.pubkey
|
||
projectId: WalletStores.RootStore.appSettings.walletConnectProjectID
|
||
}
|
||
bcSdk: DappsConnectorSDK {
|
||
enabled: featureFlagsStore.connectorEnabled && WalletStores.RootStore.walletSectionInst.walletReady
|
||
store: SharedStores.BrowserConnectStore {
|
||
controller: WalletStores.RootStore.dappsConnectorController
|
||
}
|
||
networksModel: WalletStores.RootStore.filteredFlatModel
|
||
accountsModel: WalletStores.RootStore.nonWatchAccounts
|
||
}
|
||
store: SharedStores.DAppsStore {
|
||
controller: WalletStores.RootStore.walletConnectController
|
||
}
|
||
}
|
||
selectedAddress: WalletStores.RootStore.selectedAddress
|
||
accountsModel: WalletStores.RootStore.nonWatchAccounts
|
||
connectorFeatureEnabled: featureFlagsStore.connectorEnabled
|
||
walletConnectFeatureEnabled: featureFlagsStore.dappsEnabled
|
||
|
||
onDisplayToastMessage: (message, type) => {
|
||
const icon = type === Constants.ephemeralNotificationType.danger ? "warning" :
|
||
type === Constants.ephemeralNotificationType.success ? "checkmark-circle" : "info"
|
||
Global.displayToastMessage(message, "", icon, false, type, "")
|
||
}
|
||
onPairingValidated: (validationState) => {
|
||
dappsWorkflow.pairingValidated(validationState)
|
||
}
|
||
onApproveSessionResult: (pairingId, err, newConnectionId) => {
|
||
if (err) {
|
||
dappsWorkflow.connectionFailed(pairingId)
|
||
return
|
||
}
|
||
|
||
dappsWorkflow.connectionSuccessful(pairingId, newConnectionId)
|
||
}
|
||
onConnectDApp: (dappChains, dappUrl, dappName, dappIcon, connectorIcon, pairingId) => {
|
||
dappsWorkflow.connectDApp(dappChains, dappUrl, dappName, dappIcon, connectorIcon, pairingId)
|
||
}
|
||
}
|
||
}
|
||
|
||
Connections {
|
||
target: ClipboardUtils
|
||
|
||
function onContentChanged() {
|
||
if (!ClipboardUtils.hasText)
|
||
return
|
||
|
||
const text = ClipboardUtils.text
|
||
|
||
if (text.length === 0 || text.length > 100)
|
||
return
|
||
|
||
const isAddress = SQUtils.ModelUtils.contains(
|
||
WalletStores.RootStore.accounts, "address",
|
||
text, Qt.CaseInsensitive)
|
||
if (isAddress)
|
||
WalletStores.RootStore.addressWasShown(text)
|
||
}
|
||
}
|
||
}
|