Files
RenewCMS/web/src/components/variants/VariantPreviewDialog.vue
T

110 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { SHEET_CONTENT_CLASS, SHEET_FOOTER_CLASS } from '@/components/sheetClasses'
import { t } from '@/i18n'
import { computed } from 'vue'
import VariantPaneImage from '@/components/variants/VariantPaneImage.vue'
import type { MediaItem } from '@/composables/useMedia'
import type { MediaVariantItem } from '@/composables/useMediaVariants'
import type { VariantFormat } from '@/composables/useImageVariants'
import { formatSize, formatType } from '@/lib/mediaFormat'
import { formatLabel, formatVariantSize } from '@/lib/variants/variantFormat'
import { savesPercent } from '@/lib/variants/variantSaving'
const VARIANT_TONE_HASH = '1'
const PANE =
'flex overflow-auto border border-default bg-muted h-45 items-start justify-start sm:h-75 sm:items-center sm:justify-center'
const props = defineProps<{ variant: MediaVariantItem; original: MediaItem }>()
const open = defineModel<boolean>('open', { default: false })
const variantSize = computed(() => props.variant.size ?? 0)
const variantTitle = computed(
() =>
`${props.variant.name} · ${props.variant.output_width}×${props.variant.output_height} · ${formatLabel(props.variant.output_format as VariantFormat)}`,
)
const variantSub = computed(() =>
t('{0} · saves {1}%', [
formatVariantSize(variantSize.value),
savesPercent(props.original.size, variantSize.value),
]),
)
const originalTitle = computed(
() =>
`${t('Original')} · ${props.original.width ?? 0}×${props.original.height ?? 0} · ${formatType(props.original.content_type)}`,
)
</script>
<template>
<UModal
v-model:open="open"
:title="t('Preview: {0}', [variant.name])"
:description="t('Both images are shown at actual size. Scroll to pan.')"
:ui="{
content: `${SHEET_CONTENT_CLASS} sm:top-20 sm:max-w-220`,
header: 'min-h-0 px-6 pt-5 pb-0 sm:px-6',
close: 'top-5 end-6 max-sm:top-8 max-sm:size-11 max-sm:justify-center',
title: 'text-lg/6 font-semibold',
description: 'sr-only',
body: 'px-6 pt-5 pb-0 sm:px-6 sm:pt-5 sm:pb-0',
footer: SHEET_FOOTER_CLASS,
}"
>
<template #body>
<div class="flex flex-col gap-3">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="flex min-w-0 flex-col gap-2">
<div :class="PANE" data-testid="preview-variant-pane">
<VariantPaneImage
:src="variant.url"
:width="variant.output_width"
:height="variant.output_height"
:content-type="original.content_type"
:sha256="VARIANT_TONE_HASH"
/>
</div>
<div class="flex flex-col">
<span class="font-semibold text-highlighted">{{ variantTitle }}</span>
<span class="text-xs/5 text-toned">{{ variantSub }}</span>
</div>
</div>
<div class="flex min-w-0 flex-col gap-2">
<div :class="PANE" data-testid="preview-original-pane">
<VariantPaneImage
:src="original.url"
:width="original.width ?? 0"
:height="original.height ?? 0"
:content-type="original.content_type"
:sha256="original.sha256"
/>
</div>
<div class="flex flex-col">
<span class="font-semibold text-highlighted">{{ originalTitle }}</span>
<span class="text-xs/5 text-toned">{{
formatSize(original.size)
}}</span>
</div>
</div>
</div>
<p class="text-xs/5 text-muted">
{{ t('Both images are shown at actual size. Scroll to pan.') }}
</p>
</div>
</template>
<template #footer>
<div class="flex w-full flex-col-reverse gap-2 sm:flex-row sm:justify-end">
<UButton
color="neutral"
variant="outline"
block
class="h-11 justify-center border border-accented bg-default text-sm text-highlighted ring-0 sm:h-8 sm:w-auto sm:px-3"
@click="open = false"
>
{{ t('Close') }}
</UButton>
</div>
</template>
</UModal>
</template>