feat: add vue image lazyload
This commit is contained in:
parent
8e1e243111
commit
e386988bdc
@ -35,6 +35,7 @@
|
||||
"cross-fetch": "^3.1.5",
|
||||
"daisyui": "^2.51.6",
|
||||
"dayjs": "^1.11.7",
|
||||
"lazy-load-vue3": "^1.3.0",
|
||||
"long": "^5.2.1",
|
||||
"md-editor-v3": "^2.8.1",
|
||||
"numeral": "^2.0.6",
|
||||
|
@ -11,6 +11,7 @@ import '@/plugins/vuetify/styles/styles.scss';
|
||||
import '@/style.css';
|
||||
import { createApp } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
import LazyLoad from 'lazy-load-vue3';
|
||||
// import router from "@/plugins/vuetify/router";
|
||||
import router from './router';
|
||||
import { useBaseStore } from './stores/useBaseStore';
|
||||
@ -25,7 +26,7 @@ app.use(vuetify);
|
||||
app.use(createPinia());
|
||||
app.use(layoutsPlugin);
|
||||
app.use(router);
|
||||
|
||||
app.use(LazyLoad, { component: true });
|
||||
// Mount vue app
|
||||
app.mount('#app');
|
||||
|
||||
|
@ -22,48 +22,48 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
async function fetchChange() {
|
||||
console.log('fetch changes')
|
||||
let page = 0
|
||||
console.log('fetch changes');
|
||||
let page = 0;
|
||||
|
||||
let height = Number(base.latest?.block?.header?.height || 0)
|
||||
let height = Number(base.latest?.block?.header?.height || 0);
|
||||
if (height > 14400) {
|
||||
height -= 14400
|
||||
height -= 14400;
|
||||
} else {
|
||||
height = 1
|
||||
height = 1;
|
||||
}
|
||||
// voting power in 24h ago
|
||||
while(page < staking.validators.length && height > 0) {
|
||||
await base.fetchValidatorByHeight(height, page).then(x => {
|
||||
x.validators.forEach(v => {
|
||||
yesterday.value[v.pub_key.key] = Number(v.voting_power)
|
||||
})
|
||||
})
|
||||
page += 100
|
||||
while (page < staking.validators.length && height > 0) {
|
||||
await base.fetchValidatorByHeight(height, page).then((x) => {
|
||||
x.validators.forEach((v) => {
|
||||
yesterday.value[v.pub_key.key] = Number(v.voting_power);
|
||||
});
|
||||
});
|
||||
page += 100;
|
||||
}
|
||||
|
||||
page = 0
|
||||
page = 0;
|
||||
// voting power for now
|
||||
while(page < staking.validators.length) {
|
||||
await base.fetchLatestValidators(page).then(x => {
|
||||
x.validators.forEach(v => {
|
||||
latest.value[v.pub_key.key] = Number(v.voting_power)
|
||||
})
|
||||
})
|
||||
page += 100
|
||||
while (page < staking.validators.length) {
|
||||
await base.fetchLatestValidators(page).then((x) => {
|
||||
x.validators.forEach((v) => {
|
||||
latest.value[v.pub_key.key] = Number(v.voting_power);
|
||||
});
|
||||
});
|
||||
page += 100;
|
||||
}
|
||||
}
|
||||
|
||||
fetchChange();
|
||||
|
||||
const changes = computed(() => {
|
||||
const changes = {} as Record<string, number>
|
||||
Object.keys(latest.value).forEach(k => {
|
||||
const l = latest.value[k] || 0
|
||||
const y = yesterday.value[k] || 0
|
||||
changes[k] = l - y
|
||||
})
|
||||
return changes
|
||||
})
|
||||
const changes = {} as Record<string, number>;
|
||||
Object.keys(latest.value).forEach((k) => {
|
||||
const l = latest.value[k] || 0;
|
||||
const y = yesterday.value[k] || 0;
|
||||
changes[k] = l - y;
|
||||
});
|
||||
return changes;
|
||||
});
|
||||
|
||||
const change24 = (key: Key) => {
|
||||
const txt = key.key;
|
||||
@ -71,7 +71,7 @@ const change24 = (key: Key) => {
|
||||
// const o: number = yesterday.value[txt];
|
||||
// // console.log( txt, n, o)
|
||||
// return n > 0 && o > 0 ? n - o : 0;
|
||||
return changes.value[txt]
|
||||
return changes.value[txt];
|
||||
};
|
||||
|
||||
const change24Text = (key?: Key) => {
|
||||
@ -190,137 +190,144 @@ const rank = function (position: number) {
|
||||
<div class="bg-base-100 px-4 pt-3 pb-4 rounded shadow">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" style="width: 3rem;position: relative;">#</th>
|
||||
<th scope="col">VALIDATOR</th>
|
||||
<th scope="col" class="text-right">VOTING POWER</th>
|
||||
<th scope="col" class="text-right">24h CHANGES</th>
|
||||
<th scope="col" class="text-right">COMMISSION</th>
|
||||
<th scope="col">ACTIONS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(v, i) in list" :key="v.operator_address">
|
||||
<!-- 👉 rank -->
|
||||
<td>
|
||||
<div
|
||||
class="text-xs truncate relative py-2 px-4 rounded-full w-fit"
|
||||
:class="`text-${rank(i)}`"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute"
|
||||
:class="`bg-${rank(i)}`"
|
||||
></span>
|
||||
{{ i + 1 }}
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 Validator -->
|
||||
<td>
|
||||
<div
|
||||
class="d-flex align-center overflow-hidden"
|
||||
style="max-width: 400px"
|
||||
>
|
||||
<div class="avatar mr-4 relative w-9 rounded-full overflow-hidden">
|
||||
<div class="w-9 rounded-full bg-gray-400 absolute opacity-10"></div>
|
||||
<div class="w-9 rounded-full">
|
||||
<img
|
||||
v-if="logo(v.description?.identity) !== ''"
|
||||
:src="logo(v.description?.identity)"
|
||||
class="object-contain"
|
||||
/>
|
||||
<Icon v-else class="text-4xl" :icon="`mdi-help-circle-outline`"/>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" style="width: 3rem; position: relative">#</th>
|
||||
<th scope="col">VALIDATOR</th>
|
||||
<th scope="col" class="text-right">VOTING POWER</th>
|
||||
<th scope="col" class="text-right">24h CHANGES</th>
|
||||
<th scope="col" class="text-right">COMMISSION</th>
|
||||
<th scope="col">ACTIONS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(v, i) in list" :key="v.operator_address">
|
||||
<!-- 👉 rank -->
|
||||
<td>
|
||||
<div
|
||||
class="text-xs truncate relative py-2 px-4 rounded-full w-fit"
|
||||
:class="`text-${rank(i)}`"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute"
|
||||
:class="`bg-${rank(i)}`"
|
||||
></span>
|
||||
{{ i + 1 }}
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 Validator -->
|
||||
<td>
|
||||
<div
|
||||
class="d-flex align-center overflow-hidden"
|
||||
style="max-width: 400px"
|
||||
>
|
||||
<div
|
||||
class="avatar mr-4 relative w-9 rounded-full overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="w-9 rounded-full bg-gray-400 absolute opacity-10"
|
||||
></div>
|
||||
<div class="w-9 rounded-full">
|
||||
<img
|
||||
v-if="logo(v.description?.identity) !== ''"
|
||||
v-lazy="logo(v.description?.identity)"
|
||||
class="object-contain"
|
||||
/>
|
||||
<Icon
|
||||
v-else
|
||||
class="text-4xl"
|
||||
:icon="`mdi-help-circle-outline`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-sm text-primary">
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'chain-staking-validator',
|
||||
params: { validator: v.operator_address },
|
||||
}"
|
||||
class="font-weight-medium user-list-name"
|
||||
>
|
||||
{{ v.description?.moniker }}
|
||||
</RouterLink>
|
||||
</h6>
|
||||
<span class="text-xs">{{
|
||||
v.description?.website || v.description?.identity || '-'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
<!-- 👉 Voting Power -->
|
||||
<td class="text-right">
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-sm text-primary">
|
||||
<RouterLink
|
||||
:to="{
|
||||
name: 'chain-staking-validator',
|
||||
params: { validator: v.operator_address },
|
||||
}"
|
||||
class="font-weight-medium user-list-name"
|
||||
>
|
||||
{{ v.description?.moniker }}
|
||||
</RouterLink>
|
||||
<h6 class="text-sm font-weight-medium">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: parseInt(v.tokens).toString(),
|
||||
denom: staking.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0'
|
||||
)
|
||||
}}
|
||||
</h6>
|
||||
<span class="text-xs">{{
|
||||
v.description?.website || v.description?.identity || '-'
|
||||
format.calculatePercent(
|
||||
v.delegator_shares,
|
||||
staking.totalPower
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- 👉 Voting Power -->
|
||||
<td class="text-right">
|
||||
<div class="d-flex flex-column">
|
||||
<h6 class="text-sm font-weight-medium">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: parseInt(v.tokens).toString(),
|
||||
denom: staking.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0'
|
||||
)
|
||||
}}
|
||||
</h6>
|
||||
<span class="text-xs">{{
|
||||
format.calculatePercent(
|
||||
v.delegator_shares,
|
||||
staking.totalPower
|
||||
)
|
||||
}}</span>
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 24h Changes -->
|
||||
<td
|
||||
class="text-right text-xs"
|
||||
:class="change24Color(v.consensus_pubkey)"
|
||||
>
|
||||
{{ change24Text(v.consensus_pubkey) }}
|
||||
<div v-if="v.jailed"
|
||||
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-error"
|
||||
</td>
|
||||
<!-- 👉 24h Changes -->
|
||||
<td
|
||||
class="text-right text-xs"
|
||||
:class="change24Color(v.consensus_pubkey)"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-error"
|
||||
></span>
|
||||
Jailed
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 commission -->
|
||||
<td class="text-right">
|
||||
{{
|
||||
format.formatCommissionRate(
|
||||
v.commission?.commission_rates?.rate
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<!-- 👉 Action -->
|
||||
<td>
|
||||
{{ 2 }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{ change24Text(v.consensus_pubkey) }}
|
||||
<div
|
||||
v-if="v.jailed"
|
||||
class="text-xs truncate relative py-2 px-4 rounded-full w-fit text-error"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-error"
|
||||
></span>
|
||||
Jailed
|
||||
</div>
|
||||
</td>
|
||||
<!-- 👉 commission -->
|
||||
<td class="text-right">
|
||||
{{
|
||||
format.formatCommissionRate(
|
||||
v.commission?.commission_rates?.rate
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<!-- 👉 Action -->
|
||||
<td>
|
||||
{{ 2 }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="divider"></div>
|
||||
<div class="flex flex-row">
|
||||
<div
|
||||
<div
|
||||
class="text-xs truncate relative py-2 px-4 rounded-md w-fit text-error mr-2"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-error"
|
||||
></span>
|
||||
<span class="inset-x-0 inset-y-0 opacity-10 absolute bg-error"></span>
|
||||
Top 33%
|
||||
</div>
|
||||
<div
|
||||
<div
|
||||
class="text-xs truncate relative py-2 px-4 rounded-md w-fit text-warning"
|
||||
>
|
||||
<span
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-warning"
|
||||
></span>
|
||||
Top 67%
|
||||
|
@ -5977,6 +5977,11 @@ knitwork@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/knitwork/-/knitwork-1.0.0.tgz"
|
||||
integrity sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==
|
||||
|
||||
lazy-load-vue3@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lazy-load-vue3/-/lazy-load-vue3-1.3.0.tgz#6aaf573d1d09626ac11fec6b2de9fd07c0130ac0"
|
||||
integrity sha512-IcyeMiDZrxzuIqqwkYkC+6RRQBdm0yTR0onIj6NITrWd6LaUlzzRmbvAmuzGB0g4H1HeVm/Oa0FokxD2lz9UAA==
|
||||
|
||||
ledger-cosmos-js@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ledger-cosmos-js/-/ledger-cosmos-js-2.1.8.tgz#b409ecd1e77f630e6fb212a9f602fe5c6e8f054b"
|
||||
|
Loading…
Reference in New Issue
Block a user