fix(vwb): capture plein écran + auto-détection MIME PNG/JPEG des ancres
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 12s
tests / Tests unitaires (sans GPU) (push) Failing after 13s
tests / Tests sécurité (critique) (push) Has been skipped

- CSS fullscreen-content : height:0 + min-height:0 pour forcer flex fill
- Image fullscreen : max-height calc(100vh - 60px) + object-fit contain
- Fonction b64ImgSrc() détecte automatiquement PNG vs JPEG depuis le base64
- Corrige l'affichage des thumbnails compressés JPEG dans la bibliothèque
- Appliqué dans CapturePanel + CaptureLibrary (toutes les occurrences)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-04-18 10:55:51 +02:00
parent 1acea85fa6
commit f5a672d7b9
3 changed files with 27 additions and 10 deletions

View File

@@ -6,6 +6,12 @@ import {
compressThumbnail,
} from '../services/captureLibraryStorage';
function b64ImgSrc(base64: string): string {
if (base64.startsWith('data:')) return base64;
const mime = base64.startsWith('/9j/') ? 'image/jpeg' : 'image/png';
return `data:${mime};base64,${base64}`;
}
interface LibraryItem {
id: string;
capture: Capture;
@@ -149,7 +155,7 @@ export default function CaptureLibrary({ currentCapture, onSelectCapture, onCapt
{!isExpanded && currentCapture && (
<div className="library-preview">
<img
src={`data:image/png;base64,${currentCapture.screenshot_base64}`}
src={{b64ImgSrc(currentCapture.screenshot_base64)}}
alt="Dernière capture"
onClick={() => setIsExpanded(true)}
/>
@@ -209,7 +215,7 @@ export default function CaptureLibrary({ currentCapture, onSelectCapture, onCapt
className={`library-item ${selectedItems.has(item.id) ? 'selected' : ''}`}
>
<img
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
src={{b64ImgSrc(item.capture.screenshot_base64)}}
alt="Capture"
onClick={() => onSelectCapture(item.capture)}
/>

View File

@@ -7,6 +7,12 @@ import {
compressThumbnail,
} from '../services/captureLibraryStorage';
function b64ImgSrc(base64: string): string {
if (base64.startsWith('data:')) return base64;
const mime = base64.startsWith('/9j/') ? 'image/jpeg' : 'image/png';
return `data:${mime};base64,${base64}`;
}
interface DetectionZone {
x: number;
y: number;
@@ -106,7 +112,7 @@ export default function CapturePanel({
try {
const { detectUIElements } = await import('../services/uiDetection');
const result = await detectUIElements(
`data:image/png;base64,${currentCapture.screenshot_base64}`,
{b64ImgSrc(currentCapture.screenshot_base64)},
{ threshold: 0.35 }
);
setPreviewElements(result.elements);
@@ -211,7 +217,7 @@ export default function CapturePanel({
<div className="capture-preview-container">
<img
ref={previewImgRef}
src={`data:image/png;base64,${currentCapture.screenshot_base64}`}
src={{b64ImgSrc(currentCapture.screenshot_base64)}}
alt="Capture"
onClick={() => setIsFullscreen(true)}
onLoad={handlePreviewImageLoad}
@@ -274,7 +280,7 @@ export default function CapturePanel({
{library.slice(0, 4).map(item => (
<div key={item.id} className="library-item">
<img
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
src={{b64ImgSrc(item.capture.screenshot_base64)}}
alt="Capture"
onClick={() => handleLibrarySelect(item)}
/>
@@ -315,7 +321,7 @@ export default function CapturePanel({
}}
>
<img
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
src={{b64ImgSrc(item.capture.screenshot_base64)}}
alt="Capture"
/>
<div className="library-gallery-label">
@@ -382,7 +388,7 @@ function FullscreenSelector({
try {
const { detectUIElements } = await import('../services/uiDetection');
const result = await detectUIElements(
`data:image/png;base64,${capture.screenshot_base64}`,
b64ImgSrc(capture.screenshot_base64),
{ threshold: 0.35 }
);
setDetectedElements(result.elements);
@@ -538,14 +544,14 @@ function FullscreenSelector({
onMouseUp={handleMouseUp}
>
{/* Conteneur relatif pour positionner les bboxes et la sélection par rapport à l'image */}
<div style={{ position: 'relative', display: 'inline-block' }}>
<div style={{ position: 'relative', display: 'inline-block', maxWidth: '100%', maxHeight: '100%' }}>
<img
ref={imgRef}
src={`data:image/png;base64,${capture.screenshot_base64}`}
src={{b64ImgSrc(capture.screenshot_base64)}}
alt="Capture plein écran"
draggable={false}
onLoad={handleImageLoad}
style={{ display: 'block' }}
style={{ display: 'block', maxWidth: '100%', maxHeight: 'calc(100vh - 60px)', objectFit: 'contain' }}
/>
{/* Overlay des éléments détectés — visible dans tous les modes */}

View File

@@ -1079,11 +1079,16 @@ body {
justify-content: center;
overflow: auto;
position: relative;
height: 0;
min-height: 0;
}
.fullscreen-content img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
cursor: crosshair;
}