Skip to content

Commit

Permalink
Merge pull request #869 from telosnetwork/dev
Browse files Browse the repository at this point in the history
Improve Address Page Display and Contract Manager Optimization
  • Loading branch information
pmjanus authored Nov 7, 2024
2 parents 6de7707 + 3300def commit 374973b
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 87 deletions.
2 changes: 1 addition & 1 deletion src/components/AppSearch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ const handleResultClick = (item: SearchResult): void => {
<div class="c-search__results">
<template
v-for="(entry, index) in searchResults"
:key="entry.address ?? entry.hash"
:key="(entry.address) ?? entry.hash"
>
<div
v-if="shouldShowDivider(index)"
Expand Down
12 changes: 2 additions & 10 deletions src/components/AppSearchResultEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
SearchResultUnknown,
} from 'src/types';
import { createIcon } from '@download/blockies';
import { computed } from 'vue';
import { createIconFromData } from 'src/lib/blockies/blockies';
const props = defineProps<{
entry: SearchResult,
Expand Down Expand Up @@ -40,15 +40,7 @@ const item = {
unknown: asUnknown(props.entry),
};
const createIconFromData = (data: string) => {
// https://github.com/download13/blockies
var imgData = createIcon({
seed: data,
size: 8,
scale: 3,
}).toDataURL();
return imgData;
};
const emit = defineEmits(['click']);
Expand Down
2 changes: 1 addition & 1 deletion src/components/MethodField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const setValues = async () => {

<style lang="scss">
.c-method {
width: 80px;
width: 150px;
height: 24px;
text-overflow: ellipsis;
overflow: hidden;
Expand Down
11 changes: 11 additions & 0 deletions src/lib/blockies/blockies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createIcon } from '@download/blockies';

export const createIconFromData = (data: string) => {
// https://github.com/download13/blockies
const imgData = createIcon({
seed: data,
size: 8,
scale: 3,
}).toDataURL();
return imgData;
};
104 changes: 29 additions & 75 deletions src/lib/contract/ContractManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ const tokenList = 'https://raw.githubusercontent.com/telosnetwork/token-list/mai
const systemContractList =
'https://raw.githubusercontent.com/telosnetwork/token-list/main/telosevm.systemcontractlist.json';


class AddressCacheManager {
constructor() {
this.addressesByNetwork = {};
this.contractInfoByNetwork = {};
this.maxAddresses = 1000;
this.loadFromLocalStorage();
}

Expand All @@ -22,37 +21,16 @@ class AddressCacheManager {
}

loadFromLocalStorage() {
const storedAddresses = localStorage.getItem('noContractAddressesByNetwork');
const storedContractInfo = localStorage.getItem('contractInfoByNetwork');
if (storedAddresses) {
this.addressesByNetwork = JSON.parse(storedAddresses);
}
if (storedContractInfo) {
this.contractInfoByNetwork = JSON.parse(storedContractInfo);
}
}

saveToLocalStorage() {
localStorage.setItem('noContractAddressesByNetwork', JSON.stringify(this.addressesByNetwork));
localStorage.setItem('contractInfoByNetwork', JSON.stringify(this.contractInfoByNetwork));
}

addNullAddress(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
if (!this.addressesByNetwork[network]) {
this.addressesByNetwork[network] = [];
}

if (!this.exists(addressLower)) {
this.addressesByNetwork[network].push(addressLower);
if (this.addressesByNetwork[network].length > this.maxAddresses) {
this.addressesByNetwork[network] = this.addressesByNetwork[network].slice(-this.maxAddresses);
}
this.saveToLocalStorage();
}
}

addContractInfo(address, name, symbol = null) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
Expand All @@ -66,14 +44,6 @@ class AddressCacheManager {
this.contractInfoByNetwork[network][addressLower] = info;
this.saveToLocalStorage();
}

this.removeNullAddress(address);
}

exists(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
return this.addressesByNetwork[network] && this.addressesByNetwork[network].includes(addressLower);
}

existsContract(address) {
Expand All @@ -82,37 +52,12 @@ class AddressCacheManager {
return this.contractInfoByNetwork[network] && this.contractInfoByNetwork[network][addressLower];
}

removeNullAddress(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
if (this.addressesByNetwork[network]) {
const index = this.addressesByNetwork[network].indexOf(addressLower);
if (index !== -1) {
this.addressesByNetwork[network].splice(index, 1);
this.saveToLocalStorage();
}
}
}

getAddresses() {
const network = this.getCurrentNetwork();
return this.addressesByNetwork[network] ? [...this.addressesByNetwork[network]] : [];
}

getContractInfo(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
return this.contractInfoByNetwork[network] ? this.contractInfoByNetwork[network][addressLower] : null;
}

clearAddresses() {
const network = this.getCurrentNetwork();
if (this.addressesByNetwork[network]) {
this.addressesByNetwork[network] = [];
this.saveToLocalStorage();
}
}

clearContractInfo() {
const network = this.getCurrentNetwork();
if (this.contractInfoByNetwork[network]) {
Expand Down Expand Up @@ -141,10 +86,7 @@ export default class ContractManager {
if (!this.contracts[network]) {
this.contracts[network] = {};
}
if (this.nullContractsManager.exists(address)) {
return null;
}
return this.contracts[network][address.toLowerCase()];
return this.contracts[network][address.toLowerCase()] || null;
}

setNetworkContract(address, contract) {
Expand All @@ -153,9 +95,7 @@ export default class ContractManager {
this.contracts[network] = {};
}
this.contracts[network][address.toLowerCase()] = contract;
if (contract === null) {
this.nullContractsManager.addNullAddress(address);
} else {
if (contract) {
this.nullContractsManager.addContractInfo(address, contract.name, contract.properties?.symbol || null);
}
}
Expand Down Expand Up @@ -381,27 +321,21 @@ export default class ContractManager {
}
async getContractDisplayInfo(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
let result;
if (this.nullContractsManager.exists(addressLower)) {
result = null;
} else if (this.nullContractsManager.existsContract(addressLower)) {
result = this.nullContractsManager.getContractInfo(addressLower);
if (this.nullContractsManager.existsContract(addressLower)) {
return this.nullContractsManager.getContractInfo(addressLower);
} else {
// We are going to always assume that if the address is a contract, it is already in the cache
// Because the indexer API should always return all involved contracts in a query response
return null;
}
return result;
}
async getContract(address, force) {
async getContractForced(address) {
if (address === null || typeof address !== 'string') {
return;
}
const addressLower = address.toLowerCase();

if (!force && typeof this.getNetworkContract(addressLower) !== 'undefined') {
return this.getNetworkContract(addressLower);
}

// if this function is repeatedly called for the same address, wait for the first call to finish
if (this.processing.includes(addressLower)) {
await new Promise(resolve => setTimeout(resolve, 300));
return await this.getNetworkContract(addressLower);
Expand Down Expand Up @@ -430,8 +364,28 @@ export default class ContractManager {
if(index > -1){
this.processing.splice(index, 1);
}
return this.factory.buildContract(contract);
return this.getContract(address);
}

async getContract(address, force) {
if (address === null || typeof address !== 'string') {
return null;
}

if (force) {
return await this.getContractForced(address);
}

const addressLower = address.toLowerCase();

const cashedContract = this.getNetworkContract(addressLower);
if (!force && cashedContract) {
return cashedContract;
}

return null;
}

async getContractFromAbi(address, abi){
return new ethers.Contract(address, abi, this.getEthersProvider());
}
Expand Down
17 changes: 17 additions & 0 deletions src/pages/AccountPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { contractManager } from 'src/boot/telosApi';
import { evm } from 'src/boot/evm';
import { toChecksumAddress } from 'src/lib/utils';
import { SystemBalance, getSystemBalance } from 'src/lib/balance-utils';
import { createIconFromData } from 'src/lib/blockies/blockies';
import { getIcon } from 'src/lib/token-utils';
import { Token } from 'src/types/Token';
Expand Down Expand Up @@ -155,6 +156,14 @@ async function loadAccount() {
:alt="contract.getName() + ' ERC20 token'"
:src="getIcon(contract.logoURI)"
/>
<!-- Blockies icon for address + {{accountAddress}} -->
<img
v-else
:src="createIconFromData(accountAddress)"
:alt="`Blockies icon for address ${accountAddress}`"
class="c-address__icon"
>
<!--
<q-icon
v-else-if="!contract"
name="account_circle"
Expand All @@ -165,6 +174,7 @@ async function loadAccount() {
:name="(contract.supportedInterfaces?.includes('erc721')) ? 'perm_media' : 'source'"
size="sm"
/>
-->
<span class="c-address__title">{{ title }}</span>
<span class="c-address__hex">{{ accountAddress }}</span>
<q-tooltip v-if="fullTitle" anchor="top middle" self="bottom middle">{{ fullTitle }} </q-tooltip>
Expand Down Expand Up @@ -420,6 +430,13 @@ async function loadAccount() {
.c-address {
@include page-container;
&__icon {
width: 22px;
height: 22px;
margin-right: 2px;
border-radius: 50%;
}
&__info-container{
margin-bottom: 2.5rem;
}
Expand Down

0 comments on commit 374973b

Please sign in to comment.