53 lines
1.9 KiB
JavaScript
53 lines
1.9 KiB
JavaScript
const FALLBACK_MANIFEST = {
|
|
variants: {
|
|
mobile: { folder: 'mobile-image', images: [] },
|
|
desktop: { folder: 'desketop-image', images: [] },
|
|
},
|
|
};
|
|
|
|
export async function loadManifest(request) {
|
|
try {
|
|
const response = await fetch(new URL('/manifest.json', request.url));
|
|
if (!response.ok) return FALLBACK_MANIFEST;
|
|
return await response.json();
|
|
} catch {
|
|
return FALLBACK_MANIFEST;
|
|
}
|
|
}
|
|
|
|
export function detectVariant(request) {
|
|
const url = new URL(request.url);
|
|
const params = url.searchParams;
|
|
const mode = (params.get('mode') || 'auto').toLowerCase();
|
|
const orientation = (params.get('orientation') || '').toLowerCase();
|
|
const device = (params.get('device') || '').toLowerCase();
|
|
const ua = (request.headers.get('user-agent') || '').toLowerCase();
|
|
const chMobile = request.headers.get('sec-ch-ua-mobile');
|
|
|
|
if (mode === 'mobile' || mode === 'desktop') return mode;
|
|
if (orientation === 'portrait' || orientation === 'vertical') return 'mobile';
|
|
if (orientation === 'landscape' || orientation === 'horizontal') return 'desktop';
|
|
if (device === 'mobile' || device === 'desktop') return device;
|
|
if (chMobile === '?1') return 'mobile';
|
|
if (chMobile === '?0') return 'desktop';
|
|
if (['mobi', 'android', 'iphone', 'ipad', 'ipod', 'phone'].some((token) => ua.includes(token))) return 'mobile';
|
|
return 'desktop';
|
|
}
|
|
|
|
export function getVariantPayload(manifest, variant) {
|
|
const data = manifest?.variants?.[variant] || {};
|
|
const folder = data.folder || (variant === 'mobile' ? 'mobile-image' : 'desketop-image');
|
|
const images = Array.isArray(data.images)
|
|
? data.images.filter((name) => typeof name === 'string' && name.toLowerCase().endsWith('.webp'))
|
|
: [];
|
|
return { folder, images };
|
|
}
|
|
|
|
export function buildAssetUrl(request, folder, filename) {
|
|
return new URL(`/${folder}/${filename}`, request.url).toString();
|
|
}
|
|
|
|
export function pickRandom(items) {
|
|
return items[Math.floor(Math.random() * items.length)];
|
|
}
|