75 lines
2.3 KiB
Vue
75 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import { TagItem } from '@modrinth/ui'
|
|
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
|
|
|
import { useImageThumbnail } from '@/composables/use-image-thumbnail'
|
|
import type { InstanceScreenshot } from '@/helpers/instance'
|
|
|
|
import { gatherDuration } from './use-screenshot-drag-gather'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
screenshot: InstanceScreenshot
|
|
count?: number
|
|
}>(),
|
|
{
|
|
count: 1,
|
|
},
|
|
)
|
|
|
|
const thumbnail = useImageThumbnail(
|
|
() => ({
|
|
instanceId: props.screenshot.instance_id,
|
|
filePath: `screenshots/${props.screenshot.file_name}`,
|
|
path: props.screenshot.path,
|
|
}),
|
|
512,
|
|
() => props.screenshot.modified_at,
|
|
)
|
|
const showGatheredCount = ref(false)
|
|
let countTimer: number | undefined
|
|
|
|
onMounted(() => {
|
|
if (props.count <= 1 || window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
showGatheredCount.value = true
|
|
return
|
|
}
|
|
|
|
countTimer = window.setTimeout(() => {
|
|
showGatheredCount.value = true
|
|
countTimer = undefined
|
|
}, gatherDuration - 150)
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
if (countTimer !== undefined) {
|
|
clearTimeout(countTimer)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div aria-hidden="true" class="relative w-full select-none">
|
|
<div
|
|
v-if="count > 1"
|
|
class="absolute inset-x-3 -bottom-2 top-2 rounded-xl border border-solid border-surface-5 bg-surface-2 shadow-md motion-safe:transition-opacity motion-safe:duration-200 motion-safe:delay-100 motion-safe:ease-out"
|
|
:class="showGatheredCount ? 'opacity-60' : 'opacity-0'"
|
|
/>
|
|
<div
|
|
v-if="count > 1"
|
|
class="absolute inset-x-1.5 -bottom-1 top-1 rounded-xl border border-solid border-surface-4 bg-surface-3 shadow-md motion-safe:transition-opacity motion-safe:duration-150 motion-safe:ease-out"
|
|
:class="showGatheredCount ? 'opacity-80' : 'opacity-0'"
|
|
/>
|
|
<div
|
|
class="relative aspect-video w-full overflow-hidden rounded-xl border border-solid border-surface-5 bg-surface-2 opacity-90 shadow-lg"
|
|
>
|
|
<img v-if="thumbnail" :src="thumbnail" alt="" class="h-full w-full object-cover" />
|
|
<TagItem
|
|
v-if="count > 1"
|
|
class="!absolute right-3 top-3 z-[2] border-surface-5 bg-surface-4 tabular-nums text-[var(--color-text-tertiary)] motion-safe:transition-opacity motion-safe:duration-150 motion-safe:ease-out"
|
|
>
|
|
{{ count }}
|
|
</TagItem>
|
|
</div>
|
|
</div>
|
|
</template> |