⭐
Log in to mark this repository.
Animated grid previews for videos and GIFs
376a05c · Gabriel Morell · 2026-09-26 04:40
Message
{commit_body(@commit)}
Files changed
modified
Dockerfile
+4
−0
@@ -52,11 +52,13 @@ RUN cargo build --release \
| 52 | 52 | --bin queue-worker \ |
| 53 | 53 | --bin registration-token \ |
| 54 | 54 | --bin user-admin \ |
| 55 | + --bin backfill-previews \ | |
| 55 | 56 | && mkdir -p /out \ |
| 56 | 57 | && cp target/release/webservice /out/ \ |
| 57 | 58 | && cp target/release/queue-worker /out/ \ |
| 58 | 59 | && cp target/release/registration-token /out/ \ |
| 59 | 60 | && cp target/release/user-admin /out/ \ |
| 61 | + && cp target/release/backfill-previews /out/ \ | |
| 60 | 62 | && rm -rf target |
| 61 | 63 | |
| 62 | 64 | # --------------------------------------------------------------------------- |
@@ -93,6 +95,7 @@ COPY --from=rust-builder /out/webservice /usr/local/bin/dms-webservice
| 93 | 95 | COPY --from=rust-builder /out/queue-worker /usr/local/bin/dms-queue-worker |
| 94 | 96 | COPY --from=rust-builder /out/registration-token /usr/local/bin/dms-registration-token |
| 95 | 97 | COPY --from=rust-builder /out/user-admin /usr/local/bin/dms-user-admin |
| 98 | +COPY --from=rust-builder /out/backfill-previews /usr/local/bin/dms-backfill-previews | |
| 96 | 99 | COPY --from=assets /app/assets/f /app/assets/f |
| 97 | 100 | COPY --chown=dms:dms templates /app/templates |
| 98 | 101 | # OCR models bundled at a fixed image path — read-only and tied to the app |
@@ -117,4 +120,5 @@ VOLUME ["/data"]
| 117 | 120 | # `docker run … dms-queue-worker --kind ocr` → categorizer |
| 118 | 121 | # `docker run … dms-registration-token …` → CLI |
| 119 | 122 | # `docker run … dms-user-admin …` → user management CLI |
| 123 | +# `docker run … dms-backfill-previews` → queue grid previews for older videos/GIFs | |
| 120 | 124 | CMD ["dms-webservice"] |
modified
android/README.md
+1
−1
@@ -27,7 +27,7 @@ intent filter forwards it to the pair screen with the fields pre-filled.
| 27 | 27 | |
| 28 | 28 | - QR scan → pair → token + base URL persisted (encrypted) |
| 29 | 29 | - `GET /api/profile` round-trip for verification |
| 30 | −- **Home grid**: paginated upload thumbnails from `/files/<path>.thumb.<ext>` with original-file fallback; videos use `.thumb.jpg` with the `.poster.jpg` frame as fallback, and carry a play badge | |
| 30 | +- **Home grid**: paginated upload thumbnails from `/files/<path>.thumb.<ext>` with original-file fallback; videos and GIFs animate, showing the server's short `.preview.webp` loop (Android 9+) before falling back to `.thumb` / `.poster.jpg` / the original, and videos carry a play badge | |
| 31 | 31 | - **Search**: free-text + tag filter (server parses `ns:value` and `ns:*` wildcards) |
| 32 | 32 | - **Search**: free-text query, per-source toggles (file name / item name / description / user tags / ocr / desc / other namespaces) with full parity to the web `/search` page; matched tags surface as chips on each result card |
| 33 | 33 | - **Detail**: full image — or, for a video, an ExoPlayer that streams it from `/files/` looping and muted (with an unmute toggle) like the web page — metadata, tag chips that pivot to a tag-filtered search, plus an "Add tags" input that writes via the new `POST /api/uploads/{id}/tags` |
modified
android/app/build.gradle.kts
+1
−0
@@ -106,6 +106,7 @@ dependencies {
| 106 | 106 | debugImplementation(libs.compose.ui.tooling) |
| 107 | 107 | |
| 108 | 108 | implementation(libs.coil.compose) |
| 109 | + implementation(libs.coil.gif) | |
| 109 | 110 | implementation(libs.kotlinx.coroutines) |
| 110 | 111 | |
| 111 | 112 | implementation(libs.media3.exoplayer) |
modified
android/app/src/main/AndroidManifest.xml
+1
−0
@@ -9,6 +9,7 @@
| 9 | 9 | <uses-feature android:name="android.hardware.camera" android:required="false"/> |
| 10 | 10 | |
| 11 | 11 | <application |
| 12 | + android:name=".DmsApplication" | |
| 12 | 13 | android:icon="@mipmap/ic_icon" |
| 13 | 14 | android:roundIcon="@mipmap/ic_icon" |
| 14 | 15 | android:label="DMS" |
added
android/app/src/main/java/org/neiam/dms/app/DmsApplication.kt
+24
−0
@@ -0,0 +1,24 @@
| 1 | +package org.neiam.dms.app | |
| 2 | + | |
| 3 | +import android.app.Application | |
| 4 | +import android.os.Build | |
| 5 | +import coil.ImageLoader | |
| 6 | +import coil.ImageLoaderFactory | |
| 7 | +import coil.decode.GifDecoder | |
| 8 | +import coil.decode.ImageDecoderDecoder | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * Hands Coil an image loader that can animate. The grid shows each video's | |
| 12 | + * and GIF's animated WebP preview; the stock loader would decode just its | |
| 13 | + * first frame. The platform ImageDecoder (API 28+) plays animated WebP and | |
| 14 | + * GIF; below that only GIF animates and a preview shows as a still. | |
| 15 | + */ | |
| 16 | +class DmsApplication : Application(), ImageLoaderFactory { | |
| 17 | + override fun newImageLoader(): ImageLoader = | |
| 18 | + ImageLoader.Builder(this) | |
| 19 | + .components { | |
| 20 | + if (Build.VERSION.SDK_INT >= 28) add(ImageDecoderDecoder.Factory()) | |
| 21 | + else add(GifDecoder.Factory()) | |
| 22 | + } | |
| 23 | + .build() | |
| 24 | +} |
modified
android/app/src/main/java/org/neiam/dms/app/data/PathHelpers.kt
+16
−6
Click to load diff…
modified
android/app/src/main/java/org/neiam/dms/app/ui/UploadCard.kt
+39
−22
Click to load diff…
modified
android/gradle/libs.versions.toml
+1
−0
Click to load diff…
modified
assets/f/js/src.js
+19
−13
Click to load diff…
modified
compose.yml
+7
−0
Click to load diff…
added
src/bin/backfill-previews.rs
+120
−0
Click to load diff…
modified
src/bin/queue-worker.rs
+3
−2
Click to load diff…
modified
src/config.rs
+6
−0
Click to load diff…
modified
src/handlers/uploads.rs
+7
−2
Click to load diff…
modified
src/queue/messages.rs
+13
−6
Click to load diff…
modified
src/queue/mod.rs
+1
−0
Click to load diff…
modified
src/workers/mod.rs
+1
−0
Click to load diff…
added
src/workers/preview.rs
+170
−0
Click to load diff…
modified
templates/search.html
+9
−7
Click to load diff…
modified
templates/uploads/list.html
+9
−7
Click to load diff…
modified
templates/uploads/show.html
+1
−0
Click to load diff…
Parents: 6f01817