From ba111e6764598595523713a72ef0b7d20430f201 Mon Sep 17 00:00:00 2001 From: Bruce Berrios <58147810+Bruception@users.noreply.github.com> Date: Tue, 21 Jun 2022 14:50:33 -0400 Subject: [PATCH] Fix leaderboard avatars (#3181) Bruception, zachstence * Fix leaderboard avatars * Allow HTML * Use function notation * Use utility * Fix * larger image * not that large * requesting png Co-authored-by: Miodec --- frontend/src/ts/elements/account-button.ts | 34 ++++++------- frontend/src/ts/elements/leaderboards.ts | 57 +++++++++++++--------- frontend/src/ts/elements/profile.ts | 21 ++++---- frontend/src/ts/ready.ts | 3 +- frontend/src/ts/utils/misc.ts | 24 +++++++++ 5 files changed, 89 insertions(+), 50 deletions(-) diff --git a/frontend/src/ts/elements/account-button.ts b/frontend/src/ts/elements/account-button.ts index 646e3be6a..c98dd5bdb 100644 --- a/frontend/src/ts/elements/account-button.ts +++ b/frontend/src/ts/elements/account-button.ts @@ -21,26 +21,26 @@ export function loading(truefalse: boolean): void { } } -export function update(discordId?: string, discordAvatar?: string): void { +export async function update( + discordId?: string, + discordAvatar?: string +): Promise { if (Auth.currentUser != null) { if (discordAvatar && discordId) { - // Replace font-awesome account icon with Discord avatar only if it loads successfully - // https://stackoverflow.com/a/5058336/9080819 - const avatarUrl = `https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png`; - $("") - .attr("src", avatarUrl) - .on("load", (event) => { - $(event.currentTarget).remove(); + const discordAvatarUrl = await Misc.getDiscordAvatarUrl( + discordId, + discordAvatar + ); + if (discordAvatarUrl) { + $("#top #menu .account .avatar").css( + "background-image", + `url(${discordAvatarUrl})` + ); + usingAvatar = true; - usingAvatar = true; - $("#top #menu .account .avatar").css( - "background-image", - `url(${avatarUrl})` - ); - - $("#top #menu .account .icon").addClass("hidden"); - $("#top #menu .account .avatar").removeClass("hidden"); - }); + $("#top #menu .account .icon").addClass("hidden"); + $("#top #menu .account .avatar").removeClass("hidden"); + } } else { $("#top #menu .account .avatar").addClass("hidden"); } diff --git a/frontend/src/ts/elements/leaderboards.ts b/frontend/src/ts/elements/leaderboards.ts index 57a453604..3d01e931b 100644 --- a/frontend/src/ts/elements/leaderboards.ts +++ b/frontend/src/ts/elements/leaderboards.ts @@ -233,7 +233,7 @@ function checkLbMemory(lb: LbKey): void { } } -function fillTable(lb: LbKey, prepend?: number): void { +async function fillTable(lb: LbKey, prepend?: number): Promise { if (!currentData[lb]) { return; } @@ -253,6 +253,37 @@ function fillTable(lb: LbKey, prepend?: number): void { const loggedInUserName = DB.getSnapshot()?.name; + const snap = DB.getSnapshot(); + + const avatarUrlPromises = currentData[lb].map((entry) => { + const isCurrentUser = + Auth.currentUser && + entry.uid === Auth.currentUser.uid && + snap.discordAvatar && + snap.discordId; + + const entryHasAvatar = entry.discordAvatar && entry.discordId; + + const avatarSource: Partial< + MonkeyTypes.Snapshot | MonkeyTypes.LeaderboardEntry + > = (isCurrentUser && snap) || (entryHasAvatar && entry) || {}; + + return Misc.getDiscordAvatarUrl( + avatarSource.discordId, + avatarSource.discordAvatar + ); + }); + + const avatarUrls = (await Promise.allSettled(avatarUrlPromises)).map( + (promise) => { + if (promise.status === "fulfilled") { + return promise.value; + } + + return null; + } + ); + let a = currentData[lb].length - leaderboardSingleLimit; let b = currentData[lb].length; if (a < 0) a = 0; @@ -279,27 +310,9 @@ function fillTable(lb: LbKey, prepend?: number): void { let avatar = `
`; - const snap = DB.getSnapshot(); - - const isCurrentUser = - Auth.currentUser && - entry.uid === Auth.currentUser.uid && - snap.discordAvatar && - snap.discordId; - - const entryHasAvatar = entry.discordAvatar && entry.discordId; - - const avatarSource = (isCurrentUser && snap) || (entryHasAvatar && entry); - - if (avatarSource) { - const avatarUrl = `https://cdn.discordapp.com/avatars/${avatarSource.discordId}/${avatarSource.discordAvatar}.png?size=32`; - $("") - .attr("src", avatarUrl) - .on("load", (event) => { - $(event.currentTarget).remove(); - - avatar = `
`; - }); + const currentEntryAvatarUrl = avatarUrls[i]; + if (currentEntryAvatarUrl !== null) { + avatar = `
`; } html += ` diff --git a/frontend/src/ts/elements/profile.ts b/frontend/src/ts/elements/profile.ts index ddc28e399..25d85eb6b 100644 --- a/frontend/src/ts/elements/profile.ts +++ b/frontend/src/ts/elements/profile.ts @@ -8,10 +8,10 @@ import * as EditProfilePopup from "../popups/edit-profile-popup"; type ProfileViewPaths = "profile" | "account"; -export function update( +export async function update( where: ProfileViewPaths, profile: Partial -): void { +): Promise { const elementClass = where.charAt(0).toUpperCase() + where.slice(1); const details = $(`.page${elementClass} .profile .details`); @@ -25,15 +25,16 @@ export function update( details.find(".placeholderAvatar").removeClass("hidden"); if (profile.discordAvatar && profile.discordId && !banned) { - const avatarUrl = `https://cdn.discordapp.com/avatars/${profile.discordId}/${profile.discordAvatar}.png`; - $("") - .attr("src", avatarUrl) - .on("load", (event) => { - $(event.currentTarget).remove(); - details.find(".placeholderAvatar").addClass("hidden"); + const avatarUrl = await Misc.getDiscordAvatarUrl( + profile.discordId, + profile.discordAvatar, + 256 + ); - details.find(".avatar").css("background-image", `url(${avatarUrl})`); - }); + if (avatarUrl) { + details.find(".placeholderAvatar").addClass("hidden"); + details.find(".avatar").css("background-image", `url(${avatarUrl})`); + } } if (profile.badgeIds && !banned) { diff --git a/frontend/src/ts/ready.ts b/frontend/src/ts/ready.ts index da0afbeff..b081f69d5 100644 --- a/frontend/src/ts/ready.ts +++ b/frontend/src/ts/ready.ts @@ -59,7 +59,8 @@ $(document).ready(() => { false, () => { window.localStorage.setItem("merchbannerclosed", "true"); - } + }, + true ); } // if (!window.localStorage.getItem("dasbannerclosed")) { diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index ca33a53b3..606fa0e92 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -1153,3 +1153,27 @@ export function isAnyPopupVisible(): boolean { } return popupVisible; } + +export async function getDiscordAvatarUrl( + discordId?: string, + discordAvatar?: string, + discordAvatarSize = 32 +): Promise { + if (!discordId || !discordAvatar) { + return null; + } + + // An invalid request to this URL will return a 404. + try { + const avatarUrl = `https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png?size=${discordAvatarSize}`; + + const response = await fetch(avatarUrl); + if (!response.ok) { + return null; + } + + return avatarUrl; + } catch (error) {} + + return null; +}