The Android app updates itself from our Gitea releases; feed cards fade in instead of bouncing
- API: GET /app/android/latest reads the latest Gitea release (ANDROID_RELEASES_URL, optional token for a private repo) with the APK's SHA-256 from SHA256SUMS; GET /app/android/apk/:name streams that APK. - App (modules/updater): downloads in the background, checks the SHA-256, and installs through PackageInstaller: quietly once when leaving the app (Android 12+), otherwise from the feed banner or Settings > App version. F-Droid builds leave it out and drop the install permissions. - CI: the release notes come from the fastlane changelog; the app shows the part above ---. - Settings: Create-account and Link Spotify buttons for Last.fm and ListenBrainz. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/** The newest Android release, as the server reports it (GET /app/android/latest). */
|
||||
export interface AppUpdateDTO {
|
||||
/** e.g. "1.2.0" (the release tag without its "v"). */
|
||||
version: string;
|
||||
/** Where to download the APK (through our server, so the release host can stay private). */
|
||||
apkUrl: string;
|
||||
/** Hex SHA-256 of the APK; the phone checks it before installing. */
|
||||
sha256: string;
|
||||
size: number;
|
||||
/** What's new, from the release notes. */
|
||||
notes: string | null;
|
||||
publishedAt: string;
|
||||
}
|
||||
|
||||
/** "1.10.0" → [1, 10, 0]; null for anything that isn't a plain dotted version (an optional leading "v" is fine). */
|
||||
export function parseVersion(version: string): number[] | null {
|
||||
const m = /^v?(\d+(?:\.\d+)*)$/.exec(version.trim());
|
||||
return m ? m[1]!.split('.').map(Number) : null;
|
||||
}
|
||||
|
||||
/** True when `candidate` is a later version than `current`. Unparseable versions are never newer. */
|
||||
export function isNewerVersion(candidate: string, current: string): boolean {
|
||||
const a = parseVersion(candidate);
|
||||
const b = parseVersion(current);
|
||||
if (!a || !b) return false;
|
||||
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
||||
const diff = (a[i] ?? 0) - (b[i] ?? 0);
|
||||
if (diff !== 0) return diff > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user