diff --git a/.gitignore b/.gitignore index 7dfb059..2416bc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,10 @@ .DS_Store *.apk saved-tokens/ +.upstream-sync-sha +android/.gradle/ +android/build/ +android/app/build/ +android/capacitor-cordova-android-plugins/ +android/app/capacitor.build.gradle +android/app/src/main/assets/ diff --git a/android/android-service.js b/android/android-service.js index 43d477b..0966720 100644 --- a/android/android-service.js +++ b/android/android-service.js @@ -6,12 +6,6 @@ // (fm-logger.js is loaded separately in as a synchronous script // so it captures ALL console output from the very start, before any module.) -// ── TIDAL ORIGIN BYPASS ── -// Tell the upstream proxy-utils.js that we handle the Origin header natively -// (via TidalWebViewClient.java), so it should use direct CDN URLs instead of -// routing through audio-proxy.binimum.org (which is often down/403). -// This is the same flag the Chrome extension "Monochrome Tidal Bypass" sets. -window.__tidalOriginExtension = true; // ── UNREGISTER SERVICE WORKER ── // The upstream workbox SW uses CacheFirst for audio/video, but Tidal CDN diff --git a/android/app/build.gradle b/android/app/build.gradle index 27ddb9a..9485fcb 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 1 - versionName "1.0" + versionCode 7 + versionName "2.4.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/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..3f2acc7 --- /dev/null +++ b/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/android/fm-logger.js b/android/fm-logger.js index fb8e63a..6eef785 100644 --- a/android/fm-logger.js +++ b/android/fm-logger.js @@ -2,7 +2,6 @@ // Saves all console output to Downloads/FabiodalezMusic/fm-console-log.txt // Tell upstream we handle Tidal Origin natively — skip audio-proxy.binimum.org. -window.__tidalOriginExtension = true; // Block Service Worker registration IMMEDIATELY (before any other script runs). // The upstream VitePWA plugin registers a SW that uses CacheFirst for audio, diff --git a/build-android.sh b/build-android.sh index 0035f4e..4295ed0 100755 --- a/build-android.sh +++ b/build-android.sh @@ -29,29 +29,30 @@ cd "$PROJECT_DIR" cleanup() { echo "" echo "▶ Cleaning up patched files..." - # Revert every tracked file we may have touched. - # NOTE: do this file-by-file because `git checkout -- a b c` fails entirely - # if any single file is not tracked (e.g. package-lock.json which upstream - # doesn't track — they use bun.lock). + # Revert tracked files that may have been overwritten by git archive. for f in \ - index.html \ - package.json \ - vite.config.ts \ - js/app.js \ - js/api.js \ - js/cache.js \ - js/ui.js \ - js/storage.js \ + .gitignore \ android/app/src/main/java/tf/monochrome/music/BackgroundAudioPlugin.java do if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then git checkout -- "$f" 2>/dev/null || true fi done - # Untracked files we generated during the build - rm -f js/android-service.js js/fm-logger.js package-lock.json + # Remove all upstream web app files we extracted (they are not tracked in this repo). + rm -rf \ + index.html package.json package-lock.json bun.lock bun.lockb \ + vite.config.ts vite-plugin-auth-gate.js vite-plugin-blob.ts \ + vite-plugin-svg-use.ts vite-plugin-upload.js \ + styles.css stream-stub.js tsconfig.json tsconfig-eslint.json \ + eslint.config.js lhci.yml nginx.conf \ + js/ src/ public/ assets/ functions/ images/ dist/ node_modules/ \ + .npmrc .prettierrc .stylelintrc.json .htmlhintrc .gitmodules \ + .dockerignore .vscode/ .wrangler/ \ + android/build.gradle android/capacitor.settings.gradle \ + android/gradle.properties android/settings.gradle android/variables.gradle \ + android/gradlew android/gradlew.bat android/gradle/ android/.gitignore rm -rf node_modules/@capgo/capacitor-media-session 2>/dev/null || true - echo " ✓ Source restored to upstream." + echo " ✓ Upstream web app files removed." } trap cleanup EXIT @@ -59,23 +60,46 @@ echo "════════════════════════ echo " Fabiodalez Music — Android Build" echo "══════════════════════════════════════════" -# ── 1. Pull latest ── +# ── 1. Pull latest upstream web app source ── +# This repo tracks only the Android wrapper. Web app files come from upstream. +# We use git archive (not git pull) because the histories are unrelated. echo "" echo "▶ Pulling latest from upstream/main..." cleanup 2>/dev/null || true git fetch upstream -LOCAL=$(git rev-parse HEAD) -REMOTE=$(git rev-parse upstream/main) -if [ "$LOCAL" = "$REMOTE" ]; then - echo " Already up to date." +UPSTREAM_SHA=$(git rev-parse upstream/main) +SYNC_FILE="$PROJECT_DIR/.upstream-sync-sha" +LAST_SHA=$(cat "$SYNC_FILE" 2>/dev/null || echo "") + +if [ "$UPSTREAM_SHA" = "$LAST_SHA" ] && [ -f index.html ]; then + echo " Already up to date ($(git rev-parse --short upstream/main))." read -p " Build anyway? (y/N) " -n 1 -r echo [[ ! $REPLY =~ ^[Yy]$ ]] && exit 0 else - echo " $(git rev-list --count HEAD..upstream/main) new commits." - git pull upstream main - echo " ✓ Updated." + N=$(git rev-list --count "${LAST_SHA:-upstream/main^}..upstream/main" 2>/dev/null || echo "?") + echo " $N new commits. Extracting web app from upstream/main..." + # Extract upstream web app files, excluding our Android additions and docs. + git archive upstream/main | tar -x \ + --exclude='capacitor.config.ts' \ + --exclude='README.md' \ + --exclude='android/app' \ + --exclude='android/android-service.js' \ + --exclude='android/fm-logger.js' \ + --exclude='android/capacitor-cordova-android-plugins' \ + --exclude='ios' \ + --exclude='extension' \ + --exclude='docker' \ + --exclude='.devcontainer' \ + --exclude='.github' \ + --exclude='CONTRIBUTING.md' \ + --exclude='DOCKER.md' \ + --exclude='INSTANCES.md' \ + --exclude='THEME_GUIDE.md' \ + --exclude='license' + echo "$UPSTREAM_SHA" > "$SYNC_FILE" + echo " ✓ Updated to $(git rev-parse --short upstream/main)." fi # ── 2a. Pre-npm patch: fix upstream broken override ── @@ -181,16 +205,9 @@ patch( "storage.js: add frankfurt-2 to streaming fallback", ) -# ── #54: Always try native HiFiClient for streaming (not just proxies) ── -# The upstream code skips HiFiClient for streaming requests (type='streaming') -# and goes straight to proxy instances. But when ALL proxies are down/403, -# there's no fallback. Force shouldTryNative=true so HiFiClient is tried first. -patch( - "js/api.js", - " const shouldTryNative = type !== 'streaming';", - " const shouldTryNative = true; // patched: always try native, including streaming", - "api.js: force native HiFiClient for streaming", -) +# ── #54: REMOVED — was forcing native HiFiClient for streaming, which gives +# only preview (1:40) because the browser client credentials aren't premium. +# Streaming MUST go through proxy instances (they have premium credentials). # ── #1 + #2: debounce + min-chars REMOVED ── # The upstream 3000ms debounce works fine in practice — it lets users finish