From 3ccbdf2c941ac27f6669264120a6d195c14e166e Mon Sep 17 00:00:00 2001 From: Kev Date: Sun, 17 Nov 2024 23:34:22 +0100 Subject: [PATCH] Add avatar loading animation This adds a loading animation to avatars to prevent old avatars showing next to new names in the queue. --- web/admin/assets/css/main.css | 34 +++++++++++++++++++++++ web/admin/components/shared/avatar.vue | 27 ++++++++++++++---- web/admin/components/user-card.vue | 38 ++------------------------ 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/web/admin/assets/css/main.css b/web/admin/assets/css/main.css index 38e9c325..cdb664b2 100644 --- a/web/admin/assets/css/main.css +++ b/web/admin/assets/css/main.css @@ -7,3 +7,37 @@ @apply text-gray-600 dark:text-gray-400; } } + +.loading-flash { + background: linear-gradient( + 120deg, + transparent 5%, + rgb(31, 41, 55) 20%, + transparent 30% + ); + background-size: 200% 100%; + background-position-y: bottom; + animation: 1.25s loading linear infinite; +} + +@media (prefers-color-scheme: light) { + .loading-flash { + background: linear-gradient( + 120deg, + transparent 5%, + rgb(243, 244, 246) 20%, + transparent 30% + ); + background-size: 200% 100%; + background-position-y: bottom; + } +} + +@keyframes loading { + from { + background-position-x: 50%; + } + to { + background-position-x: -150%; + } +} diff --git a/web/admin/components/shared/avatar.vue b/web/admin/components/shared/avatar.vue index 2dd88b94..93582510 100644 --- a/web/admin/components/shared/avatar.vue +++ b/web/admin/components/shared/avatar.vue @@ -7,26 +7,43 @@ const props = defineProps<{ notRounded?: boolean; }>(); -const url = computed(() => { - let base = `https://bsky-cdn.codingpa.ws/avatar/${props.did}`; +const loading = ref(true); +const url = ref(""); +function updateUrl() { + loading.value = true; + const img = new Image(); + let base = `https://bsky-cdn.codingpa.ws/avatar/${props.did}`; if (props.resize) { base += `/${props.resize}`; } + img.addEventListener("load", () => { + url.value = base; + loading.value = false; + }); + img.src = base; +} + +updateUrl(); - return base; -}); +watch(() => props.did, updateUrl);