No description
Find a file
2026-01-28 20:15:46 +01:00
app first commit 2026-01-28 20:06:31 +01:00
gradle first commit 2026-01-28 20:06:31 +01:00
build.gradle.kts first commit 2026-01-28 20:06:31 +01:00
gradle.properties first commit 2026-01-28 20:06:31 +01:00
gradlew first commit 2026-01-28 20:06:31 +01:00
gradlew.bat first commit 2026-01-28 20:06:31 +01:00
README.md init 2026-01-28 20:15:46 +01:00
settings.gradle.kts first commit 2026-01-28 20:06:31 +01:00

PixHeap (Android)

PixHeap is an Android client for browsing and auto-uploading photos/videos to a PixHeap server. It combines a media gallery, a manual uploader, and a resilient background sync pipeline that hashes local media, de-duplicates by SHA-256, and uploads only what the server does not already have.

This README documents how the app behaves, how it talks to the server, and how to run it locally.

What the app does

  • Browse a server-backed folder tree and media grid (photos + videos) with pagination.
  • Toggle recursive mode to see subfolders alongside the current folder contents.
  • Pinch to change thumbnail size on the grid.
  • Tap any item to open a full-screen lightbox with swipe navigation.
  • For videos, show poster frames and auto-play short previews when ready.
  • Upload media manually via a 2-step prepare/commit flow.
  • Auto-upload new local media in the background, with retries and detailed logging.
  • Export a sync log file for diagnostics.

Core screens & flows

Library

  • Navigation drawer with a server folder tree.
  • Grid of media cards; each card shows a thumbnail or video poster.
  • Pagination loads more items as you scroll.
  • Preview readiness polling for thumbnails/posters/preview clips.
  • Lightbox supports both images and full video playback.

Upload (manual)

  • Select multiple images/videos from the device.
  • App uploads each file to a temporary server location (/api/upload/prepare).
  • You can edit the destination path before committing.
  • Commit moves files from temp into the final folder (/api/upload/commit).
  • Cancel optionally rolls back temp files (/api/upload/cancel).

Sync status

  • Shows current queue, per-item status, and progress.
  • Displays scan counts and how many known hashes are cached.
  • Clear log, clear known-hash cache, rescan, and export log.

Background sync behavior

The app continuously watches device media and uploads new items when possible:

  • Scans MediaStore for images/videos and computes SHA-256 hashes.
  • Checks /api/hash/exists?hash=... to skip duplicates already on server.
  • Queues missing items for upload; persists queue in SharedPreferences.
  • Uploads using the prepare/commit API while tracking progress.
  • Retries failed uploads with exponential backoff.
  • Pauses uploads for a short time on network errors.
  • Runs DNS diagnostics if a hostname cannot be resolved.
  • Logs per-file details and a high-level sync log.

There are two sync entry points:

  • Foreground (app open): uses PixHeapViewModel to scan and process the queue.
  • Background (WorkManager): SyncWorker runs periodic and one-time sync.

Server API contract (expected)

PixHeap expects a server that implements the following endpoints:

Auth

  • POST /auth/login with JSON { "username": "...", "password": "..." }
    • Session cookie name: pixheap_session

Browse

  • GET /api/tree?dir=... -> folder tree
  • GET /api/list?dir=...&offset=...&limit=...&recursive=... -> paged files

Sync & Upload

  • GET /api/hash/exists?hash=... -> { "hash": "...", "exists": true|false }
  • POST /api/upload/prepare (multipart file) -> { "temp_name": "...", "suggested_path": "..." }
  • POST /api/upload/commit with JSON { "temp_name": "...", "dest_path": "..." }
  • POST /api/upload/cancel with JSON { "temp_name": "..." }
  • POST /api/upload/log with JSON { "hash": "...", "filename": "...", "status": "...", "log": ["..."] }

Media file fields returned by /api/list:

  • thumb_url, file_url, preview_url, poster_url, lightbox_url
  • Video readiness fields: preview_ready, preview_busy, preview_failed, preview_error

The UI will repeatedly issue HEAD requests to these URLs until they become available.

Configuration

Base URL & credentials

  • The base URL and credentials are stored in SharedPreferences.
  • Default base URL: http://10.0.2.2:8000 (Android emulator → host loopback).
  • You can change the base URL, username, and password in the Settings dialog.

Cleartext traffic

android:usesCleartextTraffic="true" is enabled so the default http:// URL works. For production, prefer HTTPS and disable cleartext if possible.

Permissions

Required:

  • INTERNET
  • ACCESS_NETWORK_STATE
  • Media access:
    • Android 13+ (SDK 33+): READ_MEDIA_IMAGES, READ_MEDIA_VIDEO
    • Android 12 and below: READ_EXTERNAL_STORAGE

The app will show an in-app banner if media permission is missing, since auto-upload relies on it.

Caching & storage

  • Auth + base URL stored in SharedPreferences (pixheap_prefs).
  • Known hashes and logs stored in SharedPreferences (pixheap_sync_state).
  • Media previews are cached via ExoPlayer + SimpleCache (200 MB LRU).

Project structure (high level)

  • app/src/main/java/eu/hoeyer/pixheap
    • MainActivity.kt: App entry point, schedules one-time sync.
    • PixHeapApp.kt: Application class, schedules periodic sync.
    • ui/: Compose UI and ViewModel.
    • data/: Retrofit service, repository, data models, storage, sync worker.

Build & run

Requirements:

  • Android Studio Hedgehog or newer (or a recent Gradle + Android toolchain).
  • JDK 11 (project uses Java 11 compatibility).
  • Android SDK 24+ (minSdk 24, targetSdk 36).

Steps:

  1. Open the project in Android Studio.
  2. Sync Gradle.
  3. Run on an emulator or device.
  4. Open Settings in the app to set your server URL and credentials.

Troubleshooting

Common issues and where to look:

  • Login failures: Check Base URL and credentials (Settings dialog).
  • Nothing uploads: Ensure media permissions are granted.
  • Uploads stuck: Open Sync status → check queue + log; try rescan.
  • Server unreachable: Verify networking; sync log includes DNS diagnostics.
  • Previews never appear: Server may not provide preview URLs or be generating media.

Exported logs include:

  • Base URL, known hash count, queue snapshot, sync log, and per-file logs.

Notes for developers

  • Background sync uses WorkManager with network constraints.
  • Foreground sync has a ticker (10 minutes) and a MediaStore observer.
  • The app optimizes polling for previews via HEAD requests with backoff.
  • Manual uploads share the same server endpoints but allow editing destination paths.