From 727979bf20fa96fd76040f8934519c62ddd0cb14 Mon Sep 17 00:00:00 2001 From: zenodeapp Date: Fri, 1 Dec 2023 14:26:49 +0100 Subject: [PATCH 1/3] Optimized avatars and added avatar auto-fixer when cache is old. --- src/modules/[chain]/staking/[validator].vue | 54 +++++++++---- src/modules/[chain]/staking/index.vue | 86 +++++++++++++-------- 2 files changed, 93 insertions(+), 47 deletions(-) diff --git a/src/modules/[chain]/staking/[validator].vue b/src/modules/[chain]/staking/[validator].vue index d0f45ea3..bb2a4bc4 100644 --- a/src/modules/[chain]/staking/[validator].vue +++ b/src/modules/[chain]/staking/[validator].vue @@ -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((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) || ''; 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(); + } + } + " /> { 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((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" >
Date: Fri, 1 Dec 2023 15:03:53 +0100 Subject: [PATCH 2/3] Fixed no avatar bug and styling of question mark fixed. --- src/modules/[chain]/staking/[validator].vue | 8 +++----- src/modules/[chain]/staking/index.vue | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/modules/[chain]/staking/[validator].vue b/src/modules/[chain]/staking/[validator].vue index bb2a4bc4..ba44b7db 100644 --- a/src/modules/[chain]/staking/[validator].vue +++ b/src/modules/[chain]/staking/[validator].vue @@ -203,20 +203,18 @@ function pageload(p: number) {
diff --git a/src/modules/[chain]/staking/index.vue b/src/modules/[chain]/staking/index.vue index 609340ee..490d5b7c 100644 --- a/src/modules/[chain]/staking/index.vue +++ b/src/modules/[chain]/staking/index.vue @@ -346,7 +346,7 @@ loadAvatars(); /> From ccf63cd4131c810c2a044b6a9fd7a1723368774d Mon Sep 17 00:00:00 2001 From: zenodeapp Date: Fri, 1 Dec 2023 16:43:06 +0100 Subject: [PATCH 3/3] Made everything a bit more consistent. --- src/modules/[chain]/staking/[validator].vue | 9 +++++---- src/modules/[chain]/staking/index.vue | 17 ++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/modules/[chain]/staking/[validator].vue b/src/modules/[chain]/staking/[validator].vue index ba44b7db..071d7ddd 100644 --- a/src/modules/[chain]/staking/[validator].vue +++ b/src/modules/[chain]/staking/[validator].vue @@ -111,8 +111,9 @@ const fetchAvatar = (identity: string) => { }); }; -const loadAvatar = () => { - fetchAvatar(identity.value).then(() => { +const loadAvatar = (identity: string) => { + // fetches avatar from keybase and stores it in localStorage + fetchAvatar(identity).then(() => { localStorage.setItem('avatars', JSON.stringify(avatars.value)); }); }; @@ -122,7 +123,7 @@ onMounted(() => { staking.fetchValidator(validator).then((res) => { v.value = res.validator; identity.value = res.validator?.description?.identity || ''; - if (identity.value && !avatars.value[identity.value]) loadAvatar(); + if (identity.value && !avatars.value[identity.value]) loadAvatar(identity.value); const prefix = valoperToPrefix(v.value.operator_address) || ''; addresses.value.hex = consensusPubkeyToHexAddress( @@ -208,7 +209,7 @@ function pageload(p: number) { class="object-contain" @error=" (e) => { - loadAvatar(); + loadAvatar(identity); } " /> diff --git a/src/modules/[chain]/staking/index.vue b/src/modules/[chain]/staking/index.vue index 490d5b7c..e93aa69d 100644 --- a/src/modules/[chain]/staking/index.vue +++ b/src/modules/[chain]/staking/index.vue @@ -164,17 +164,15 @@ const fetchAvatar = (identity: string) => { }); }; -const loadAvatar = (validator: Validator) => { - const identity = validator.description?.identity; - - if (identity) { - fetchAvatar(identity).then(() => { - localStorage.setItem('avatars', JSON.stringify(avatars.value)); - }); - } +const loadAvatar = (identity: string) => { + // fetches avatar from keybase and stores it in localStorage + fetchAvatar(identity).then(() => { + localStorage.setItem('avatars', JSON.stringify(avatars.value)); + }); }; const loadAvatars = () => { + // fetches all avatars from keybase and stores it in localStorage const promises = staking.validators.map((validator) => { const identity = validator.description?.identity; @@ -340,7 +338,8 @@ loadAvatars(); class="object-contain" @error=" (e) => { - loadAvatar(v); + const identity = v.description?.identity; + if (identity) loadAvatar(identity); } " />