diff --git a/src/review.rs b/src/review.rs index 097ba11..c0f1fd6 100644 --- a/src/review.rs +++ b/src/review.rs @@ -16,7 +16,6 @@ pub fn launch_review(groups: &[DuplicateGroup], entries: &[ImageEntry]) { eprintln!("review server running at http://{addr}"); let db = ignore_db::open_db().ok(); - let _ = open::that(format!("http://{addr}")); loop { @@ -73,13 +72,8 @@ fn handle_delete(mut req: tiny_http::Request) -> usize { let mut deleted = 0; for path in &paths { match fs::remove_file(path) { - Ok(_) => { - eprintln!("deleted: {path}"); - deleted += 1; - } - Err(e) => { - eprintln!("failed to delete {path}: {e}"); - } + Ok(_) => { eprintln!("deleted: {path}"); deleted += 1; } + Err(e) => { eprintln!("failed to delete {path}: {e}"); } } } @@ -164,7 +158,6 @@ fn handle_ignore( let _ = std::io::Read::read_to_end(req.as_reader(), &mut body); let body_str = String::from_utf8_lossy(&body); - // Body = group index as JSON number let group_idx: usize = serde_json::from_str(&body_str).unwrap_or(usize::MAX); let (ok, msg) = if let Some(conn) = db { @@ -176,21 +169,11 @@ fn handle_ignore( .collect(); let fp = ignore_db::group_fingerprint(&sha_list); match ignore_db::ignore_group(conn, &fp) { - Ok(_) => { - eprintln!("ignored group {group_idx} (fingerprint: {fp})"); - (true, "group ignored") - } - Err(e) => { - eprintln!("failed to ignore group: {e}"); - (false, "db error") - } + Ok(_) => { eprintln!("ignored group {group_idx} (fingerprint: {fp})"); (true, "group ignored") } + Err(e) => { eprintln!("failed to ignore group: {e}"); (false, "db error") } } - } else { - (false, "invalid group index") - } - } else { - (false, "no database") - }; + } else { (false, "invalid group index") } + } else { (false, "no database") }; let json = format!("{{\"ok\":{ok},\"message\":\"{msg}\"}}"); let header = Header::from_bytes("Content-Type", "application/json").unwrap(); @@ -214,14 +197,11 @@ fn make_thumbnail_data_uri(path: &std::path::Path) -> String { let thumb = img.resize(THUMB_MAX, THUMB_MAX, FilterType::Triangle); let mut buf = std::io::Cursor::new(Vec::new()); - thumb - .write_to(&mut buf, image::ImageFormat::Jpeg) - .unwrap_or(()); + thumb.write_to(&mut buf, image::ImageFormat::Jpeg).unwrap_or(()); let b64 = base64::engine::general_purpose::STANDARD.encode(buf.into_inner()); format!("data:image/jpeg;base64,{b64}") } - fn build_review_html(groups: &[DuplicateGroup]) -> String { let mut html = String::from(r#" @@ -262,17 +242,21 @@ h1 { text-align: center; margin-bottom: 20px; color: #e94560; } .lightbox { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.92); z-index: 1000; justify-content: center; align-items: center; cursor: zoom-out; } .lightbox.active { display: flex; } .lightbox img { max-width: 95vw; max-height: 95vh; object-fit: contain; border-radius: 8px; } +.lightbox img.loading { display: none; } .lightbox .lb-path { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); color: #aaa; font-size: 0.85em; background: rgba(0,0,0,0.7); padding: 6px 16px; border-radius: 8px; max-width: 90vw; text-align: center; word-break: break-all; } +.spinner { display: none; width: 48px; height: 48px; border: 5px solid rgba(255,255,255,0.2); border-top: 5px solid #e94560; border-radius: 50%; animation: spin 0.8s linear infinite; } +.lightbox.active .spinner.loading { display: block; } +@keyframes spin { to { transform: rotate(360deg); } }
-{} groups, {} files — select files to delete or dismiss false positives
\n", + "{} groups, {} files select files to delete or dismiss false positives
\n", groups.len(), total_files )); @@ -293,7 +277,7 @@ h1 { text-align: center; margin-bottom: 20px; color: #e94560; } Group {} {kind_str} - +