diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index b0c4aa4..e9f064a 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -307,7 +307,13 @@ fn pack_snapshot(rows: Vec<(i64, Option, Option, Option, i64, i64 buf.extend_from_slice(&(w.min(65535) as u16).to_le_bytes()); buf.extend_from_slice(&(h.min(65535) as u16).to_le_bytes()); buf.push(kind as u8); - let flags = if thumb_state == 1 { 1u8 } else { 0u8 }; + // 비트0 = 썸네일 준비됨(state 1), 비트1 = 생성 시도했으나 실패(state 2). + // 둘 다 0이면 생성 대기(state 0) — 프론트에서 스켈레톤/실패표시 구분용. + let flags = match thumb_state { + 1 => 1u8, + 2 => 2u8, + _ => 0u8, + }; buf.push(flags); } buf diff --git a/src/features/grid/JustifiedGrid.tsx b/src/features/grid/JustifiedGrid.tsx index 059c4e3..18a4b38 100644 --- a/src/features/grid/JustifiedGrid.tsx +++ b/src/features/grid/JustifiedGrid.tsx @@ -387,6 +387,11 @@ export const JustifiedGrid: Component = () => { const s = snapshot(); return !!s && (s.hasThumb(i) || version() > 0); }; + // 썸네일 미준비 상태: 실패(state 2)면 정적 표시, 그 외엔 '생성 중' 스켈레톤. + const failed = () => { + const s = snapshot(); + return !!s && s.thumbFailed(i); + }; const isVideo = () => { const s = snapshot(); return !!s && s.kind(i) === 1; @@ -417,7 +422,22 @@ export const JustifiedGrid: Component = () => { if (s) onCellDragStart(e, s, i); }} > - + + 🖼 + + } + > +
+ + } + >