From 4c6c897b10dd51c343ed0508b89f95f1f85d82c5 Mon Sep 17 00:00:00 2001 From: michal Date: Tue, 29 Sep 2026 00:07:30 +0100 Subject: [PATCH] app v1.1.0: delete-after-upload, duplicate status, clear history, open-with MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Delete the source file once an upload is confirmed (best-effort: SAF picks get a persisted read+write grant and are removed; read-only shared streams are left in place). Cache copy always removed. A removed source shows as 'removed from phone'. - Distinguish duplicates: a HEAD (or the server's 200 existed) marks the item 'Duplicate · already on server' — content is never re-sent or overwritten, since the name IS the sha256. Different content = different hash = a new file, not a duplicate. - 'Clear history' app-bar button clears finished/duplicate/failed rows. - Register as an 'Open with' target (ACTION_VIEW, content/file) in addition to the existing share-sheet target. - Room schema v2 (destructive fallback; queue is ephemeral). Co-Authored-By: Claude Opus 4.8 --- README.md | 22 +++++ android/app/build.gradle.kts | 4 +- android/app/src/main/AndroidManifest.xml | 9 ++ .../eu/itaz/internaluploader/MainActivity.kt | 82 +++++++++++++++++-- .../java/eu/itaz/internaluploader/data/Db.kt | 29 ++++++- .../itaz/internaluploader/ui/QueueAdapter.kt | 9 +- .../itaz/internaluploader/upload/Enqueuer.kt | 1 + .../internaluploader/upload/UploadWorker.kt | 49 ++++++++++- .../main/res/drawable/ic_clear_history.xml | 10 +++ android/app/src/main/res/menu/main_menu.xml | 7 +- android/app/src/main/res/values/strings.xml | 5 +- 11 files changed, 203 insertions(+), 24 deletions(-) create mode 100644 android/app/src/main/res/drawable/ic_clear_history.xml diff --git a/README.md b/README.md index 9d17171..be3ffaa 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,28 @@ Every file is stored as `.`, so names carry nothing, re-uploads are idempotent, and a retried upload can be verified server-side before it is accepted. +## Behaviour + +- **Integrity is structural.** The remote name *is* the SHA-256 of the content. + The server recomputes the hash of the bytes it receives and stores the file + only if it matches (mismatch → 409, nothing written). So a success response + is proof the server holds byte-for-byte-intact content — which is what makes + deleting the local copy safe. +- **Delete after confirmed upload.** Once an upload is confirmed, the app + removes its working copy and, best-effort, the original file. Files picked + in-app (SAF) are removed via the persisted read+write grant; a file that + arrives as a read-only share/`open with` stream cannot be deleted and is left + in place (not a failure). A removed source shows as "removed from phone". +- **Duplicates are never rewritten.** Identical content (same hash) already on + the server is detected by a `HEAD` before any bytes are sent; the item is + marked *Duplicate · already on server* and nothing is re-uploaded or + overwritten. Different content is a different hash, i.e. a different file — + not a duplicate. +- **Entry points.** Share sheet (`ACTION_SEND`), "Open with" on a downloaded + file (`ACTION_VIEW`), and an in-app file picker. "Clear history" (app-bar + button) drops finished, duplicate and failed rows; in-flight uploads keep + running. + ## Parts - `server/` — Node 22 / TypeScript. Runs as a docker container **on nas001** diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index c013234..fcd4f45 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -22,8 +22,8 @@ android { applicationId = "eu.itaz.internaluploader" minSdk = 26 targetSdk = 35 - versionCode = 1 - versionName = "1.0.0" + versionCode = 2 + versionName = "1.1.0" // The one place the server address exists. Never rendered in the UI; // a pairing QR can carry a different origin and overrides this. diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 512da86..3c144b7 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -43,6 +43,15 @@ + + + + + + + +