Files
moshing-mammut/src/lib/components/AvatarComponent.svelte

57 lines
1.8 KiB
Svelte

<script lang="ts">
import type { Account } from '$lib/mastodon/response';
interface Props {
account: Account;
}
let { account }: Props = $props();
let avatarDescription: string = $derived(`Avatar for ${account.acct}`);
let sourceSetHtml: string = $derived.by(() => {
// Sort thumbnails by file type. This is important, because the order of the srcset entries matter.
// We need the best format to be first
const formatPriority = new Map<string, number>([
['avif', 0],
['webp', 1],
['jpg', 99],
['jpeg', 99]
]);
const resizedAvatars = (account.resizedAvatars ?? []).toSorted((a, b) => {
const extensionA = a.file.split('.').pop() ?? '';
const extensionB = b.file.split('.').pop() ?? '';
const prioA = formatPriority.get(extensionA) ?? 3;
const prioB = formatPriority.get(extensionB) ?? 3;
return prioA - prioB;
});
const m = new Map<string, string[]>();
for (const resizedAvatar of resizedAvatars) {
const extension = resizedAvatar.file.split('.').pop();
const mime = extension ? `image/${extension}` : 'application/octet-stream';
const sourceSetEntry = `${resizedAvatar.file} ${resizedAvatar.sizeDescriptor}`;
m.set(mime, [...(m.get(mime) || []), sourceSetEntry]);
}
let html = '';
for (const entry of m.entries()) {
const srcset = entry[1].join(', ');
html += `<source srcset="${srcset}" type="${entry[0]}" />`;
}
return html;
});
</script>
<picture>
{@html sourceSetHtml}
<img src={account.avatar} alt={avatarDescription} loading="lazy" width="50" height="50" />
</picture>
<style>
img {
max-width: 100%;
max-height: 100%;
width: 50px;
height: 50px;
object-fit: contain;
border-radius: 3px;
}
</style>