status-desktop/ui/app/AppLayouts/Wallet/services/dapps/DAppsListProvider.qml

144 lines
5.4 KiB
QML
Raw Normal View History

import QtQuick 2.15
import StatusQ 0.1
import StatusQ.Core.Utils 0.1
import SortFilterProxyModel 0.2
import AppLayouts.Wallet.services.dapps 1.0
import shared.stores 1.0
import utils 1.0
QObject {
id: root
required property WalletConnectSDKBase sdk
required property DAppsStore store
required property var supportedAccountsModel
property string selectedAddress: ""
readonly property SortFilterProxyModel dappsModel: SortFilterProxyModel {
objectName: "DAppsModelFiltered"
sourceModel: d.dappsModel
filters: FastExpressionFilter {
enabled: !!root.selectedAddress
function isAddressIncluded(accountAddressesSubModel, selectedAddress) {
const addresses = ModelUtils.modelToFlatArray(accountAddressesSubModel, "address")
return addresses.includes(root.selectedAddress)
}
expression: isAddressIncluded(model.accountAddresses, root.selectedAddress)
expectedRoles: "accountAddresses"
}
}
function updateDapps() {
d.updateDappsModel()
}
QObject {
id: d
property ListModel dappsModel: ListModel {
id: dapps
objectName: "DAppsModel"
}
property var dappsListReceivedFn: null
property var getActiveSessionsFn: null
function updateDappsModel()
{
dappsListReceivedFn = (dappsJson) => {
root.store.dappsListReceived.disconnect(dappsListReceivedFn);
dapps.clear();
let dappsList = JSON.parse(dappsJson);
for (let i = 0; i < dappsList.length; i++) {
const cachedEntry = dappsList[i];
let accountAddresses = cachedEntry.accountAddresses
if (!accountAddresses) {
accountAddresses = [{address: ''}];
}
const dappEntryWithRequiredRoles = {
description: cachedEntry.description,
url: cachedEntry.url,
name: cachedEntry.name,
iconUrl: cachedEntry.url,
accountAddresses: cachedEntry.accountAddresses
}
dapps.append(dappsList[i]);
}
}
root.store.dappsListReceived.connect(dappsListReceivedFn);
// triggers a potential fast response from store.dappsListReceived
if (!store.getDapps()) {
console.warn("Failed retrieving dapps from persistence")
root.store.dappsListReceived.disconnect(dappsListReceivedFn);
}
getActiveSessionsFn = () => {
sdk.getActiveSessions((allSessionsAllProfiles) => {
root.store.dappsListReceived.disconnect(dappsListReceivedFn);
const dAppsMap = {}
const topics = []
const sessions = DAppsHelpers.filterActiveSessionsForKnownAccounts(allSessionsAllProfiles, supportedAccountsModel)
for (const sessionID in sessions) {
const session = sessions[sessionID]
const dapp = session.peer.metadata
if (!!dapp.icons && dapp.icons.length > 0) {
dapp.iconUrl = dapp.icons[0]
} else {
dapp.iconUrl = ""
}
const accounts = DAppsHelpers.getAccountsInSession(session)
const existingDApp = dAppsMap[dapp.url]
if (existingDApp) {
// In Qt5.15.2 this is the way to make a "union" of two arrays
// more modern syntax (ES-6) is not available yet
const combinedAddresses = new Set(existingDApp.accountAddresses.concat(dapp.accountAddresses));
existingDApp.accountAddresses = Array.from(combinedAddresses);
} else {
dapp.accountAddresses = accounts
dAppsMap[dapp.url] = dapp
}
topics.push(sessionID)
}
// TODO #15075: on SDK dApps refresh update the model that has data source from persistence instead of using reset
dapps.clear();
// Iterate dAppsMap and fill dapps
for (const topic in dAppsMap) {
const dAppEntry = dAppsMap[topic];
// Due to ListModel converting flat array to empty nested ListModel
// having array of key value pair fixes the problem
dAppEntry.accountAddresses = dAppEntry.accountAddresses.filter(account => (!!account)).map(account => ({address: account}));
dapps.append(dAppEntry);
}
root.store.updateWalletConnectSessions(JSON.stringify(topics))
});
}
if (root.sdk.sdkReady) {
getActiveSessionsFn()
} else {
let conn = root.sdk.sdkReadyChanged.connect(() => {
if (root.sdk.sdkReady) {
getActiveSessionsFn()
}
});
}
}
}
}