Live watching is now event-driven, no tree polling: - Android: MainActivity registers a MediaStore ContentObserver (Images, notifyForDescendants) and wakes the Rust watcher thread via a JNI call (Java_wow_gmp_gallery_MainActivity_nativeFsChange) — a single channel send, no main-thread work. Covers camera saves, media-scanner indexing, other apps' indexed writes. - Desktop: inotify/FSEvents via notify on the scan roots. - On wake: coalesce + debounce, diff dir mtimes, rescan only the changed subtrees. The 1 s recv timeout doubles as a cheap backstop (raw out-of-band copies the scanner hasn't indexed yet); a 5-minute full pass is the safety net. minSdk 30 (3-arg ContentObserver API). Stale-listing truncation bug found and fixed (reproduced on the emulator's 9p /sdcard; the phone's FUSE does the same): a readdir over a large directory can return a SILENT early EOF — a stale cached listing with NO error. The phone's 9961-file Camera dir truncated at ~8400 once and db::apply deleted ~1700 good rows. Three layers now: 1. scan::read_dir_full — retry whole-dir reads on mid-stream errors; 2. per-directory cross-check in walk_dir: if the enumeration is far below the DB's count for that dir, re-read up to 3x keeping the best listing; whole-walk re-check in rescan keeps the larger of two walks; 3. db::apply mass-delete guard: never delete >20% of the DB in one apply unless a previous walk already saw the low count (two-strike; a meta.walked row tracks it). Genuine gradual deletions still flow through (verified: a 4000-file mass move streams the grid down progressively), and a second consecutive low walk still deletes. Emulator reliability suite (all pass): 3x launch count stability, add +1 / remove -1 in ~2 s, 20-file burst, DB recovery from damage, stale-listing refusal (0 rows lost), two-strike delete, live restore, idle 0.0% dropped frames, deep fling loads thumbnails. A/B vs ttimg (no-backend CSS-scroll control): adb-swipe drop deltas are at the input-injection artifact level, idle identical (0.0%).
42 lines
825 B
JSON
42 lines
825 B
JSON
{
|
|
"$schema": "https://schema.tauri.app/config/2",
|
|
"productName": "gtauri",
|
|
"version": "0.1.0",
|
|
"identifier": "wow.gmp.gallery",
|
|
"build": {
|
|
"beforeDevCommand": "",
|
|
"devUrl": "http://localhost",
|
|
"beforeBuildCommand": "",
|
|
"frontendDist": "frontend/dist"
|
|
},
|
|
"app": {
|
|
"withGlobalTauri": true,
|
|
"windows": [
|
|
{
|
|
"label": "main",
|
|
"title": "Gallery",
|
|
"width": 800,
|
|
"height": 600,
|
|
"fullscreen": true,
|
|
"decorations": false
|
|
}
|
|
],
|
|
"security": {
|
|
"csp": null
|
|
}
|
|
},
|
|
"bundle": {
|
|
"active": true,
|
|
"targets": "all",
|
|
"android": {
|
|
"minSdkVersion": 30
|
|
},
|
|
"icon": [
|
|
"icons/32x32.png",
|
|
"icons/128x128.png",
|
|
"icons/128x128@2x.png",
|
|
"icons/icon.icns",
|
|
"icons/icon.ico"
|
|
]
|
|
}
|
|
} |