Optimized avatars and added avatar auto-fixer when cache is old.

This commit is contained in:
zenodeapp 2023-12-01 14:26:49 +01:00
parent aa17be0839
commit 727979bf20
2 changed files with 93 additions and 47 deletions

View File

@ -79,6 +79,7 @@ const selfRate = computed(() => {
}
return '-';
});
const logo = (identity?: string) => {
if (!identity) return '';
const url = avatars.value[identity] || '';
@ -86,25 +87,43 @@ const logo = (identity?: string) => {
? url
: `https://s3.amazonaws.com/keybase_processed_uploads/${url}`;
};
const fetchAvatar = (identity: string) => {
// fetch avatar from keybase
return new Promise<void>((resolve) => {
staking
.keybase(identity)
.then((d) => {
if (Array.isArray(d.them) && d.them.length > 0) {
const uri = String(d.them[0]?.pictures?.primary?.url).replace(
'https://s3.amazonaws.com/keybase_processed_uploads/',
''
);
avatars.value[identity] = uri;
resolve();
} else throw new Error(`failed to fetch avatar for ${identity}.`);
})
.catch((error) => {
// console.error(error); // uncomment this if you want the user to see if the avatar failed to load.
resolve();
});
});
};
const loadAvatar = () => {
fetchAvatar(identity.value).then(() => {
localStorage.setItem('avatars', JSON.stringify(avatars.value));
});
};
onMounted(() => {
if (validator) {
staking.fetchValidator(validator).then((res) => {
v.value = res.validator;
identity.value = res.validator?.description?.identity || '';
if (identity.value && !avatars.value[identity.value]) {
staking.keybase(identity.value).then((d) => {
if (Array.isArray(d.them) && d.them.length > 0) {
const uri = String(d.them[0]?.pictures?.primary?.url).replace(
'https://s3.amazonaws.com/keybase_processed_uploads/',
''
);
if (uri) {
avatars.value[identity.value] = uri;
localStorage.setItem('avatars', JSON.stringify(avatars.value));
}
}
});
}
if (identity.value && !avatars.value[identity.value]) loadAvatar();
const prefix = valoperToPrefix(v.value.operator_address) || '<Invalid>';
addresses.value.hex = consensusPubkeyToHexAddress(
v.value.consensus_pubkey
@ -187,6 +206,13 @@ function pageload(p: number) {
v-if="avatars[identity] !== 'undefined'"
v-lazy="logo(identity)"
class="object-contain"
@error="
(e) => {
if (identity) {
loadAvatar();
}
}
"
/>
<Icon
v-else

View File

@ -141,39 +141,54 @@ const list = computed(() => {
return unbondList.value.map((x, i) => ({v: x, rank: 'primary', logo: logo(x.description.identity)}));
});
const loadAvatars = () => {
// fetch avatar from keybase
let promise = Promise.resolve();
staking.validators.forEach((item) => {
promise = promise.then(
() =>
new Promise((resolve) => {
const identity = item.description?.identity;
if (identity && !avatars.value[identity]) {
staking.keybase(identity).then((d) => {
if (Array.isArray(d.them) && d.them.length > 0) {
const uri = String(
d.them[0]?.pictures?.primary?.url
).replace(
'https://s3.amazonaws.com/keybase_processed_uploads/',
''
);
if (uri) {
avatars.value[identity] = uri;
localStorage.setItem(
'avatars',
JSON.stringify(avatars.value)
);
}
}
resolve();
});
} else {
resolve();
}
})
);
const fetchAvatar = (identity: string) => {
// fetch avatar from keybase
return new Promise<void>((resolve) => {
staking
.keybase(identity)
.then((d) => {
if (Array.isArray(d.them) && d.them.length > 0) {
const uri = String(d.them[0]?.pictures?.primary?.url).replace(
'https://s3.amazonaws.com/keybase_processed_uploads/',
''
);
avatars.value[identity] = uri;
resolve();
} else throw new Error(`failed to fetch avatar for ${identity}`);
})
.catch((error) => {
// console.error(error); // uncomment this if you want the user to see which avatars failed to load.
resolve();
});
});
};
const loadAvatar = (validator: Validator) => {
const identity = validator.description?.identity;
if (identity) {
fetchAvatar(identity).then(() => {
localStorage.setItem('avatars', JSON.stringify(avatars.value));
});
}
};
const loadAvatars = () => {
const promises = staking.validators.map((validator) => {
const identity = validator.description?.identity;
// Here we also check whether we haven't already fetched the avatar
if (identity && !avatars.value[identity]) {
return fetchAvatar(identity);
} else {
return Promise.resolve();
}
});
Promise.all(promises).then(() =>
localStorage.setItem('avatars', JSON.stringify(avatars.value))
);
};
const logo = (identity?: string) => {
@ -313,7 +328,7 @@ loadAvatars();
style="max-width: 300px"
>
<div
class="avatar mr-4 relative w-8 h-8 rounded-full overflow-hidden"
class="avatar mr-4 relative w-8 h-8 rounded-full"
>
<div
class="w-8 h-8 rounded-full bg-gray-400 absolute opacity-10"
@ -323,6 +338,11 @@ loadAvatars();
v-if="logo"
:src="logo"
class="object-contain"
@error="
(e) => {
loadAvatar(v);
}
"
/>
<Icon
v-else