← Commit history
Cargo.lock+1−1
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-shotlog"-version = "0.26.1"+version = "0.26.2" dependencies = [  "axum",  "base64",
Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "adom-shotlog"-version = "0.26.1"+version = "0.26.2" edition = "2021" description = "Screenshot log viewer and CLI for Adom" license = "MIT"
VERSION+1−1
@@ -1 +1 @@-0.26.1+0.26.2
bin/adom-shotlog
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-shotlog",-  "version": "0.26.1",+  "version": "0.26.2",   "type": "app",   "title": "Shotlog - Screenshot Log",   "description": "See the shots your AI never showed you, and know it actually SAW them. adom-shotlog streams every screenshot the AI gathers into a live gallery (webview/pup/browser/phone), reports whether a human is really watching and on which surface, and ingests Adom Bridge child-window arrays via --meta.",
page.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-shotlog",-  "version": "0.26.1",+  "version": "0.26.2",   "type": "app",   "title": "Shotlog - Screenshot Log",   "description": "See the shots your AI never showed you, and know it actually SAW them. adom-shotlog streams every screenshot the AI gathers into a live gallery (webview/pup/browser/phone), reports whether a human is really watching and on which surface, and ingests Adom Bridge child-window arrays via --meta.",
src/html/index.html+10−2
@@ -1694,8 +1694,16 @@ body.compact .card-popups .ph { padding-top: 4px; }         t=setTimeout(reset,3000); return; }       reset();       entries=[]; renderAll();-      await fetch('api/clear-all?channel='+encodeURIComponent(channel),{method:'DELETE'}).catch(()=>{});-      showToast('cleared');+      try{+        const r=await fetch('api/clear-all?channel='+encodeURIComponent(channel),{method:'DELETE'}).then(x=>x.json());+        const b=r.bytes_freed||0;+        // Human-readable: GB once it's a gigabyte-scale cleanup, else MB/KB.+        const size = b>=1024*1024*1024 ? (b/(1024*1024*1024)).toFixed(2)+' GB'+                   : b>=1024*1024      ? (b/(1024*1024)).toFixed(1)+' MB'+                   : b>0               ? Math.max(1,Math.round(b/1024))+' KB'+                   : '0 KB';+        showToast('cleared '+(r.cleared??0)+' shot'+((r.cleared??0)===1?'':'s')+' - freed '+size+' of disk', 7000);+      }catch{ showToast('cleared'); }     });   })(); 
src/server.rs+3−2
@@ -1445,8 +1445,9 @@ async fn clear_all(     Query(q): Query<ChannelQuery>, ) -> Json<serde_json::Value> {     let channel = q.channel.unwrap_or_else(|| "default".into());-    let count = state.store.clear_all(&channel).await;-    Json(serde_json::json!({ "ok": true, "cleared": count, "files_deleted": true }))+    let (count, bytes_freed) = state.store.clear_all(&channel).await;+    println!("{} CLEAR '{channel}': {count} shot(s), {bytes_freed} bytes freed.", ts());+    Json(serde_json::json!({ "ok": true, "cleared": count, "files_deleted": true, "bytes_freed": bytes_freed })) }  #[derive(Deserialize)]
src/store.rs+10−3
@@ -580,8 +580,12 @@ impl Store {     }      /// Clear entries AND delete all files for a channel.-    pub async fn clear_all(&self, channel_name: &str) -> usize {+    /// Returns (shots cleared, BYTES actually freed from disk) - the byte count+    /// sums every deleted file (safe PNGs, __full pairs, __popup child windows,+    /// .json sidecars), so the human can be told how much space came back.+    pub async fn clear_all(&self, channel_name: &str) -> (usize, u64) {         let count = self.clear_log(channel_name).await;+        let mut bytes_freed: u64 = 0;         let channel_dir = self.base_dir.join(channel_name);         if channel_dir.is_dir() {             if let Ok(entries) = fs::read_dir(&channel_dir) {@@ -591,13 +595,16 @@ impl Store {                     // sidecars and __popup child-window PNGs must go too, or the                     // folder fills with orphaned metadata.                     match p.extension().and_then(|e| e.to_str()) {-                        Some("png") | Some("json") => { fs::remove_file(&p).ok(); }+                        Some("png") | Some("json") => {+                            let sz = fs::metadata(&p).map(|m| m.len()).unwrap_or(0);+                            if fs::remove_file(&p).is_ok() { bytes_freed += sz; }+                        }                         _ => {}                     }                 }             }         }-        count+        (count, bytes_freed)     }      /// List all channel names.