58 lines
1.8 KiB
Vue
58 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import { toSvg} from 'jdenticon'
|
|
import type { MediaMetadata } from '@/stores/media.ts'
|
|
import { Vibrant } from 'node-vibrant/node'
|
|
import { useTemplateRef } from 'vue'
|
|
import { vi } from 'vitest'
|
|
|
|
const props = defineProps<{
|
|
media?: MediaMetadata
|
|
username: string
|
|
size: number
|
|
}>()
|
|
|
|
/* async function calcBackgroundColor() {
|
|
const imgWrapper = useTemplateRef<HTMLImageElement>("profilePicture");
|
|
if (!imgWrapper) return;
|
|
const img = imgWrapper.value;
|
|
if (!img) return null;
|
|
const vibrant = Vibrant.from(img).build();
|
|
const palette = await vibrant.getPalette();
|
|
if (!palette.Vibrant) return;
|
|
const r = (255 - palette.Vibrant.r).toString(16),
|
|
g = (255 - palette.Vibrant.g).toString(16),
|
|
b = (255 - palette.Vibrant.b).toString(16);
|
|
// pad each with zeros and return
|
|
return '#' + padZero(r) + padZero(g) + padZero(b);
|
|
}
|
|
|
|
function padZero(str: string, len?: number): string {
|
|
len = len || 2;
|
|
const zeros = new Array(len).join('0');
|
|
return (zeros + str).slice(-len);
|
|
}
|
|
|
|
async function calcBackgroundStyle() {
|
|
const color = await calcBackgroundColor();
|
|
if (!color) return "";
|
|
return "background-color: "+color;
|
|
}
|
|
*/
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="props.media" aria-label="profile picture">
|
|
<!-- TODO: Inverted primary color of image
|
|
Get primary color of the image, invert it and set as background for higher contrast in case of transparency
|
|
calcBackgroundStyle *should* do it, but async and vue no like
|
|
-->
|
|
<img :src="props.media.url" :alt="props.media.alt" :height="props.size" :width="props.size" ref="profilePicture"/>
|
|
</div>
|
|
<div
|
|
v-else
|
|
aria-label="profile picture"
|
|
aria-description="No profile picture set, this is a generated identicon"
|
|
>
|
|
<div v-html="toSvg(props.username, 128)" aria-hidden="true"/>
|
|
</div>
|
|
</template>
|