From 2435ef796175f8cded796107fa311e3c61bb4fc3 Mon Sep 17 00:00:00 2001
From: Bryan Van Deusen
Date: Sun, 10 May 2026 20:23:56 -0400
Subject: [PATCH] feat(web): MobileAppDownload component on login + settings
(#397 follow-up)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes the discoverability gap on the in-app update flow — the
/api/client/apk endpoint exists but had no web UI surface to find
it. User asked to be able to "visit the site on my phone and
download the apk from there."
- web/src/lib/components/MobileAppDownload.svelte — fetches
/api/client/version once on mount; renders a download link with
version + size when 200; renders nothing on 404 (no APK bundled,
graceful degradation in dev environments and pre-CI-wiring images).
- Mounted on the login page (below the Register link) so the link
is discoverable without authentication. The /api/client/* endpoints
are themselves unauthed, so the flow works end-to-end for any
visitor on a phone.
- Also mounted in Settings → Mobile app section for logged-in users
who want to grab the matching APK for sideloading on a different
device.
Browser handles the download via the server's existing
Content-Disposition: attachment; filename="minstrel.apk" header.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
.../lib/components/MobileAppDownload.svelte | 54 +++++++++++++++++++
web/src/routes/login/+page.svelte | 5 ++
web/src/routes/settings/+page.svelte | 9 ++++
3 files changed, 68 insertions(+)
create mode 100644 web/src/lib/components/MobileAppDownload.svelte
diff --git a/web/src/lib/components/MobileAppDownload.svelte b/web/src/lib/components/MobileAppDownload.svelte
new file mode 100644
index 00000000..6c4e49d8
--- /dev/null
+++ b/web/src/lib/components/MobileAppDownload.svelte
@@ -0,0 +1,54 @@
+
+
+{#if info}
+
+
+
+ Get the Android app
+
+ {info.version}{info.sizeBytes > 0 ? ` · ${formatSize(info.sizeBytes)}` : ''}
+
+
+
+{/if}
diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte
index 82a2caf1..3293e968 100644
--- a/web/src/routes/login/+page.svelte
+++ b/web/src/routes/login/+page.svelte
@@ -4,6 +4,7 @@
import { goto } from '$app/navigation';
import { login } from '$lib/auth/store.svelte';
import type { ApiError } from '$lib/api/client';
+ import MobileAppDownload from '$lib/components/MobileAppDownload.svelte';
let username = $state('');
let password = $state('');
@@ -88,5 +89,9 @@
Don't have an account?
Register
+
+
+
+
diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte
index ffacb011..60ec8465 100644
--- a/web/src/routes/settings/+page.svelte
+++ b/web/src/routes/settings/+page.svelte
@@ -17,6 +17,7 @@
} from '$lib/api/me';
import { errCode } from '$lib/api/errors';
import { pushToast } from '$lib/stores/toast.svelte';
+ import MobileAppDownload from '$lib/components/MobileAppDownload.svelte';
const queryClient = useQueryClient();
@@ -323,4 +324,12 @@
+
+
+ Mobile app
+
+ Install the Android app paired to this server. Sign in with the same account.
+
+
+