diff --git a/PATCHES.md b/PATCHES.md
index d44f909..2f048fe 100644
--- a/PATCHES.md
+++ b/PATCHES.md
@@ -500,6 +500,26 @@ Studio e guarda l'errore reale. Tipicamente:
## Cronologia delle patch
+- **2026-08-16** — v2.9.0: Sync upstream `41d3b9c` (249 commit dopo `abbc2a6`).
+ Upstream ha riscritto lo stack di riproduzione ("unified API": query TIDAL
+ native via `HiFiClient` + `music-api.geeked.wtf` con Turnstile + fallback
+ Deezer; account con better-auth, `@capacitor/browser` per l'OAuth nativo).
+ Patch rimosse: **#53** `storage.js` fallback istanze streaming (upstream ha
+ tolto la lista hardcoded, `INSTANCES_URLS` è vuoto e i vecchi proxy HiFi
+ sono tutti 503/irraggiungibili) e **#56** `HiFi.ts` `tracks.albums.coverArt`
+ (merged upstream). Le altre 12/12 patch matchano. Aggiunto al manifest del
+ wrapper l'intent-filter `monochrome://auth-callback` (login nativo).
+ `build-web.sh`: `rm -f dist-web.zip` prima dello zip (`zip -r` aggiornava
+ l'archivio vecchio) e prune di `assets/` sul server dopo il deploy.
+ **Nota importante**: sul dominio `music.fabiodalez.it` la riproduzione NON
+ funziona più — le API upstream (Turnstile sitekey, CORS del fallback Deezer)
+ sono bloccate ai soli domini ufficiali (issue #725, risposta del maintainer:
+ "self-hosted instances won't be able to use the API"). Servono un App API
+ Key personale, oppure dev-mode + estensione con account TIDAL. L'APK usa
+ `hostname: monochrome.tf` come origin del WebView e resta nel perimetro:
+ **verificato su emulatore** (Pixel 6 / API 35, via CDP sul WebView) — ricerca
+ 100 brani, play di "Creep" e brano successivo con MediaSession `PLAYING` e
+ notifica del foreground service.
- **2026-04-10** — Initial release: 50 + 1 ottimizzazioni implementate
(escluso #31 battery opt su richiesta esplicita dell'utente). Aggiunti
`fm-build.sh`, `verify-patches.sh`, `PATCHES.md`. Rimosso il sed obsoleto
diff --git a/android/app/build.gradle b/android/app/build.gradle
index c212f23..1a810d9 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.monochrome.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 12
- versionName "2.6.1"
+ versionCode 13
+ versionName "2.9.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 0f006e0..93835ab 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -25,6 +25,14 @@
+
+
+
+
+
+
+
+
&1 | tail -3
SIZE=$(du -h "$PROJECT_DIR/dist-web.zip" | awk '{print $1}')
echo " ✓ dist-web.zip (${SIZE}) ready."
@@ -370,6 +360,12 @@ if rsync -az --no-perms --omit-dir-times \
-e "ssh -o ConnectTimeout=10 -o BatchMode=yes" \
dist/ "${DEPLOY_HOST}:~/${DEPLOY_PATH}/" 2>&1; then
echo " ✓ Deployed to ${DEPLOY_HOST}:~/${DEPLOY_PATH}/"
+ # assets/ is 100% build output (hashed chunks + public/assets) → safe to prune
+ # stale files from previous builds there. Root is left untouched (.htaccess, cgi-bin, …).
+ rsync -az --delete --no-perms --omit-dir-times \
+ -e "ssh -o ConnectTimeout=10 -o BatchMode=yes" \
+ dist/assets/ "${DEPLOY_HOST}:~/${DEPLOY_PATH}/assets/" 2>&1 \
+ && echo " ✓ Pruned stale files in assets/"
echo ""
echo "══════════════════════════════════════════"
echo " Live at: https://${DEPLOY_PATH}/"