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,93 @@
|
||||
import { formatNumber, t } from '@/i18n'
|
||||
import type { ImageVariant, VariantFit, VariantFormat } from '@/composables/useImageVariants'
|
||||
|
||||
const BYTES_PER_KB = 1024
|
||||
const BYTES_PER_MB = BYTES_PER_KB * 1024
|
||||
const KB_PER_MB = 1024
|
||||
const MB_PER_GB = 1024
|
||||
const NO_QUALITY = '—'
|
||||
const SEPARATOR = ' · '
|
||||
|
||||
function oneDecimal(value: number) {
|
||||
return Math.round(value * 10) / 10
|
||||
}
|
||||
|
||||
export function formatVariantSize(bytes: number) {
|
||||
const kilobytes = Math.round(bytes / BYTES_PER_KB)
|
||||
if (bytes === 0) {
|
||||
return t('{0} KB', [0])
|
||||
}
|
||||
if (kilobytes < KB_PER_MB) {
|
||||
return t('{0} KB', [Math.max(1, kilobytes)])
|
||||
}
|
||||
const megabytes = bytes / BYTES_PER_MB
|
||||
if (megabytes < MB_PER_GB) {
|
||||
return t('{0} MB', [oneDecimal(megabytes)])
|
||||
}
|
||||
return t('{0} GB', [oneDecimal(megabytes / MB_PER_GB)])
|
||||
}
|
||||
|
||||
export function formatDimensions(width: number | null, height: number | null) {
|
||||
if (width !== null && height !== null) {
|
||||
return `${width}×${height}`
|
||||
}
|
||||
if (width !== null) {
|
||||
return `${width} × ${t('auto')}`
|
||||
}
|
||||
return `${t('auto')} × ${height ?? ''}`
|
||||
}
|
||||
|
||||
export function formatLabel(format: VariantFormat) {
|
||||
const labels: Record<VariantFormat, string> = {
|
||||
webp: 'WebP',
|
||||
jpeg: 'JPEG',
|
||||
png: 'PNG',
|
||||
original: t('Original'),
|
||||
}
|
||||
return labels[format]
|
||||
}
|
||||
|
||||
export function fitLabel(fit: VariantFit) {
|
||||
const labels: Record<VariantFit, string> = {
|
||||
cover: t('cover'),
|
||||
contain: t('contain'),
|
||||
inside: t('inside'),
|
||||
}
|
||||
return labels[fit]
|
||||
}
|
||||
|
||||
function hasQuality(variant: Pick<ImageVariant, 'format' | 'quality'>) {
|
||||
return variant.format !== 'png' && variant.quality !== null
|
||||
}
|
||||
|
||||
export function qualityCell(variant: Pick<ImageVariant, 'format' | 'quality'>) {
|
||||
return hasQuality(variant) ? String(variant.quality) : NO_QUALITY
|
||||
}
|
||||
|
||||
export function specLine(variant: ImageVariant) {
|
||||
const parts = [
|
||||
formatDimensions(variant.width, variant.height),
|
||||
fitLabel(variant.fit),
|
||||
formatLabel(variant.format),
|
||||
]
|
||||
if (hasQuality(variant)) {
|
||||
parts.push(t('q{0}', [variant.quality ?? 0]))
|
||||
}
|
||||
return parts.join(SEPARATOR)
|
||||
}
|
||||
|
||||
export function generatedLine(variant: ImageVariant) {
|
||||
return t('{0} generated · {1}', [
|
||||
formatNumber(variant.generated_files),
|
||||
formatVariantSize(variant.cache_size),
|
||||
])
|
||||
}
|
||||
|
||||
export function variantsSummary(items: readonly ImageVariant[]) {
|
||||
const files = items.reduce((total, item) => total + item.generated_files, 0)
|
||||
const bytes = items.reduce((total, item) => total + item.cache_size, 0)
|
||||
const variants = items.length === 1 ? t('1 variant') : t('{0} variants', [items.length])
|
||||
const generated =
|
||||
files === 1 ? t('1 generated file') : t('{0} generated files', [formatNumber(files)])
|
||||
return [variants, generated, formatVariantSize(bytes)].join(SEPARATOR)
|
||||
}
|
||||
Reference in new issue
Block a user