amelioration

This commit is contained in:
2026-06-14 22:40:05 +02:00
parent a6fc9f445f
commit aeafb38789
+43 -14
View File
@@ -506,28 +506,57 @@ function fmtRelative(isoStr) {
return d.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric' }); return d.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric' });
} }
function parseBrowser(ua) {
if (/CriOS\//i.test(ua)) return 'Chrome ' + (ua.match(/CriOS\/(\d+)/)?.[1] || ''); // Chrome sur iOS
if (/FxiOS\//i.test(ua)) return 'Firefox ' + (ua.match(/FxiOS\/(\d+)/)?.[1] || ''); // Firefox sur iOS
if (/EdgiOS\//i.test(ua)) return 'Edge ' + (ua.match(/EdgiOS\/(\d+)/)?.[1] || ''); // Edge sur iOS
if (/OPR\//i.test(ua)) return 'Opera ' + (ua.match(/OPR\/(\d+)/)?.[1] || '');
if (/Edg\//i.test(ua)) return 'Edge ' + (ua.match(/Edg\/(\d+)/)?.[1] || '');
if (/Chrome\//i.test(ua)) return 'Chrome ' + (ua.match(/Chrome\/(\d+)/)?.[1] || '');
if (/Firefox\//i.test(ua)) return 'Firefox ' + (ua.match(/Firefox\/(\d+)/)?.[1] || '');
if (/Safari\//i.test(ua)) return 'Safari ' + (ua.match(/Version\/(\d+)/)?.[1] || '');
return '';
}
function parseUA(ua) { function parseUA(ua) {
if (!ua) return { device: 'Inconnu', browser: '', icon: 'desktop' }; if (!ua) return { device: 'Inconnu', icon: 'desktop' };
const isMobile = /mobile|android|iphone|ipad/i.test(ua); const br = parseBrowser(ua);
let browser = 'Navigateur inconnu'; const suffix = br ? ` ${br}` : '';
if (/Edg\//i.test(ua)) browser = 'Edge ' + (ua.match(/Edg\/([\d.]+)/)?.[1]?.split('.')[0] || '');
else if (/Chrome\//i.test(ua)) browser = 'Chrome ' + (ua.match(/Chrome\/([\d.]+)/)?.[1]?.split('.')[0] || ''); // ── iOS ─────────────────────────────────────────────────────────────────
else if (/Firefox\//i.test(ua)) browser = 'Firefox ' + (ua.match(/Firefox\/([\d.]+)/)?.[1]?.split('.')[0] || ''); if (/iPhone/i.test(ua)) return { device: `iPhone${suffix}`, icon: 'mobile' };
else if (/Safari\//i.test(ua)) browser = 'Safari ' + (ua.match(/Version\/([\d.]+)/)?.[1]?.split('.')[0] || ''); if (/iPad/i.test(ua)) return { device: `iPad${suffix}`, icon: 'tablet' };
// ── Android ─────────────────────────────────────────────────────────────
if (/Android/i.test(ua)) {
// Extrait "Pixel 9 Pro" / "SM-S918B" / etc. depuis "; DEVICE Build/" ou "; DEVICE)"
const m = ua.match(/Android[\s/][\d.]+;\s*([^;)]+?)(?:\s+Build\/|\s*\))/i);
const devName = m ? m[1].trim() : 'Android';
const isTablet = /tablet/i.test(ua) || !/mobile/i.test(ua);
return { device: `${devName}${suffix}`, icon: isTablet ? 'tablet' : 'mobile' };
}
// ── Desktop ─────────────────────────────────────────────────────────────
let os = 'Inconnu'; let os = 'Inconnu';
if (/Windows/i.test(ua)) os = 'Windows'; if (/Windows NT 10\.0/i.test(ua)) os = 'Windows 10/11';
else if (/Macintosh/i.test(ua)) os = 'Mac'; else if (/Windows/i.test(ua)) os = 'Windows';
else if (/Linux/i.test(ua)) os = 'Linux'; else if (/Macintosh/i.test(ua)) os = 'Mac';
else if (/Android/i.test(ua)) os = 'Android'; else if (/CrOS/i.test(ua)) os = 'ChromeOS';
else if (/iPhone|iPad/i.test(ua)) os = 'iOS'; else if (/Linux/i.test(ua)) os = 'Linux';
return { device: os + (browser ? ' — ' + browser : ''), icon: isMobile ? 'mobile' : 'desktop' }; return { device: `${os}${suffix}`, icon: 'desktop' };
} }
function DeviceIcon({ type }) { function DeviceIcon({ type }) {
if (type === 'mobile') return ( if (type === 'mobile') return (
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"> <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<rect x="5" y="2" width="14" height="20" rx="2"/> <rect x="5" y="2" width="14" height="20" rx="2"/>
<line x1="12" y1="18" x2="12" y2="18" strokeWidth="2.5"/> <circle cx="12" cy="18.5" r="0.8" fill="currentColor" stroke="none"/>
</svg>
);
if (type === 'tablet') return (
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<rect x="4" y="2" width="16" height="20" rx="2"/>
<circle cx="12" cy="18.5" r="0.8" fill="currentColor" stroke="none"/>
</svg> </svg>
); );
return ( return (