feat: image variants settings screens
This commit is contained in:
1 parent
f1d56ef50e
commit
f567866161
42 files changed
+7192
-11
No files matched your search
@@ -0,0 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import { t } from '@/i18n'
|
||||
|
||||
import { computed, ref } from 'vue'
|
||||
import ImageCompare from '@/components/variants/ImageCompare.vue'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
import { SAMPLE_SOURCE, estimateLabel, estimateVariant } from '@/lib/variants/variantEstimate'
|
||||
import { parseDimension, sliderValue, type VariantFormValues } from '@/lib/variants/variantForm'
|
||||
import { formatVariantSize } from '@/lib/variants/variantFormat'
|
||||
|
||||
const URL_PREFIX = '/static/uploadedImages/'
|
||||
const NAME_PLACEHOLDER = '<name>'
|
||||
|
||||
const props = defineProps<{
|
||||
values: VariantFormValues
|
||||
disabled: boolean
|
||||
}>()
|
||||
|
||||
const position = ref(50)
|
||||
const { copied, copy } = useCopyToClipboard()
|
||||
|
||||
const dimensionsAreValid = computed(
|
||||
() =>
|
||||
(props.values.width.trim() === '' || parseDimension(props.values.width) !== null) &&
|
||||
(props.values.height.trim() === '' || parseDimension(props.values.height) !== null),
|
||||
)
|
||||
|
||||
const estimate = computed(() =>
|
||||
dimensionsAreValid.value
|
||||
? estimateVariant({
|
||||
width: parseDimension(props.values.width),
|
||||
height: parseDimension(props.values.height),
|
||||
fit: props.values.fit,
|
||||
format: props.values.format,
|
||||
quality: sliderValue(props.values.quality),
|
||||
})
|
||||
: null,
|
||||
)
|
||||
|
||||
const shownName = computed(() => props.values.name || t('name'))
|
||||
const outputLine = computed(() =>
|
||||
estimate.value ? estimateLabel(estimate.value) : t('No output yet'),
|
||||
)
|
||||
const originalLine = computed(
|
||||
() =>
|
||||
`${SAMPLE_SOURCE.width} × ${SAMPLE_SOURCE.height} · ${formatVariantSize(SAMPLE_SOURCE.bytes)}`,
|
||||
)
|
||||
const hasName = computed(() => props.values.name !== '')
|
||||
const url = computed(
|
||||
() => `${URL_PREFIX}${SAMPLE_SOURCE.filename}?v=${props.values.name || NAME_PLACEHOLDER}`,
|
||||
)
|
||||
|
||||
async function onCopy() {
|
||||
try {
|
||||
await copy(url.value)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex min-w-0 flex-col gap-3">
|
||||
<div class="flex items-baseline gap-2">
|
||||
<h3 class="flex-1 font-semibold text-highlighted">{{ t('Preview') }}</h3>
|
||||
<span class="text-xs/5 text-muted">{{
|
||||
t('Sample: {0}', [SAMPLE_SOURCE.filename])
|
||||
}}</span>
|
||||
</div>
|
||||
<ImageCompare v-model="position" :name="values.name" :comparable="estimate !== null" />
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-medium text-highlighted">{{ t('Original') }}</span>
|
||||
<span class="text-xs/5 text-muted">{{ originalLine }}</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-mono font-medium text-highlighted">{{ shownName }}</span>
|
||||
<span class="text-xs/5 text-muted">{{ outputLine }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs/5 text-muted">
|
||||
{{
|
||||
t(
|
||||
'Drag the divider, or focus it and use the arrow keys. The estimate comes from a sample; output is never larger than the source.',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<span class="font-medium text-highlighted">{{ t('URL') }}</span>
|
||||
<div class="flex gap-2">
|
||||
<div
|
||||
data-testid="variant-url"
|
||||
class="flex min-h-11 min-w-0 flex-1 items-center truncate border border-default bg-elevated px-3 font-mono text-xs sm:min-h-8"
|
||||
:class="hasName ? 'text-highlighted' : 'text-muted'"
|
||||
>
|
||||
{{ url }}
|
||||
</div>
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
:icon="copied ? 'i-lucide-check' : 'i-lucide-copy'"
|
||||
:disabled="!hasName || disabled"
|
||||
class="h-11 shrink-0 gap-1.5 border border-accented bg-default px-3 text-sm text-highlighted ring-0 sm:h-8"
|
||||
@click="onCopy"
|
||||
>
|
||||
{{ copied ? t('Copied') : t('Copy') }}
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user