From 1c3ab8d68e4bea7dcf9f55aad7ca512d79c40532 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 11 Apr 2026 02:22:32 +0200 Subject: [PATCH] Fix mobile app bugs: package name, deprecated API, server check - Fix AudioRecordingService ACTION_STOP to use com.pedshub.scribe - Fix deprecated stopForeground(true) to STOP_FOREGROUND_REMOVE - Fix launcher.js testServer: prevent double callback, fix onerror always reporting success (now correctly fails on unreachable servers) - Update service comment from TWA to Capacitor --- .../app/src/main/assets/public/launcher.js | 25 ++++++++++--------- .../pedshub/scribe/AudioRecordingService.java | 6 ++--- mobile/ios/App/App/public/launcher.js | 25 ++++++++++--------- mobile/src/launcher.js | 25 ++++++++++--------- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/mobile/android/app/src/main/assets/public/launcher.js b/mobile/android/app/src/main/assets/public/launcher.js index acb56e8..2b00a1b 100644 --- a/mobile/android/app/src/main/assets/public/launcher.js +++ b/mobile/android/app/src/main/assets/public/launcher.js @@ -80,22 +80,23 @@ } function testServer(url, callback) { - // Try to reach the health endpoint - var controller = new AbortController(); - var timeout = setTimeout(function() { controller.abort(); }, 8000); + var done = false; + function respond(ok) { + if (done) return; + done = true; + callback(ok); + } - fetch(url + '/api/health', { signal: controller.signal, mode: 'no-cors' }) - .then(function() { clearTimeout(timeout); callback(true); }) + // Try to reach the health endpoint (no-cors: opaque response = server exists) + fetch(url + '/api/health', { mode: 'no-cors', signal: AbortSignal.timeout(8000) }) + .then(function() { respond(true); }) .catch(function() { - clearTimeout(timeout); - // no-cors mode always succeeds for reachable servers (opaque response) - // If it fails, the server is truly unreachable - // Try again with a simple image load as fallback + // Fetch failed — try image load as a fallback connectivity check + var fallbackTimer = setTimeout(function() { respond(false); }, 5000); var img = new Image(); - img.onload = function() { callback(true); }; - img.onerror = function() { callback(true); }; // Even errors mean server responded + img.onload = function() { clearTimeout(fallbackTimer); respond(true); }; + img.onerror = function() { clearTimeout(fallbackTimer); respond(false); }; img.src = url + '/favicon.ico?t=' + Date.now(); - setTimeout(function() { callback(false); }, 5000); }); } diff --git a/mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java b/mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java index 5697dbb..220f878 100644 --- a/mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java +++ b/mobile/android/app/src/main/java/com/pedshub/scribe/AudioRecordingService.java @@ -15,7 +15,7 @@ import androidx.core.app.NotificationCompat; /** * Foreground service that keeps the app alive during audio recording. * Acquires a partial wake lock to prevent CPU sleep during recording. - * The TWA web app sends a message to start/stop this service when recording. + * The Capacitor web app sends a message to start/stop this service when recording. */ public class AudioRecordingService extends Service { @@ -23,7 +23,7 @@ public class AudioRecordingService extends Service { private static final int NOTIFICATION_ID = 1; private static final String WAKE_LOCK_TAG = "PedScribe:AudioRecording"; - public static final String ACTION_STOP = "com.pediatricscribe.twa.STOP_RECORDING"; + public static final String ACTION_STOP = "com.pedshub.scribe.STOP_RECORDING"; private PowerManager.WakeLock wakeLock; @@ -80,7 +80,7 @@ public class AudioRecordingService extends Service { wakeLock.release(); wakeLock = null; } - stopForeground(true); + stopForeground(STOP_FOREGROUND_REMOVE); super.onDestroy(); } diff --git a/mobile/ios/App/App/public/launcher.js b/mobile/ios/App/App/public/launcher.js index acb56e8..2b00a1b 100644 --- a/mobile/ios/App/App/public/launcher.js +++ b/mobile/ios/App/App/public/launcher.js @@ -80,22 +80,23 @@ } function testServer(url, callback) { - // Try to reach the health endpoint - var controller = new AbortController(); - var timeout = setTimeout(function() { controller.abort(); }, 8000); + var done = false; + function respond(ok) { + if (done) return; + done = true; + callback(ok); + } - fetch(url + '/api/health', { signal: controller.signal, mode: 'no-cors' }) - .then(function() { clearTimeout(timeout); callback(true); }) + // Try to reach the health endpoint (no-cors: opaque response = server exists) + fetch(url + '/api/health', { mode: 'no-cors', signal: AbortSignal.timeout(8000) }) + .then(function() { respond(true); }) .catch(function() { - clearTimeout(timeout); - // no-cors mode always succeeds for reachable servers (opaque response) - // If it fails, the server is truly unreachable - // Try again with a simple image load as fallback + // Fetch failed — try image load as a fallback connectivity check + var fallbackTimer = setTimeout(function() { respond(false); }, 5000); var img = new Image(); - img.onload = function() { callback(true); }; - img.onerror = function() { callback(true); }; // Even errors mean server responded + img.onload = function() { clearTimeout(fallbackTimer); respond(true); }; + img.onerror = function() { clearTimeout(fallbackTimer); respond(false); }; img.src = url + '/favicon.ico?t=' + Date.now(); - setTimeout(function() { callback(false); }, 5000); }); } diff --git a/mobile/src/launcher.js b/mobile/src/launcher.js index acb56e8..2b00a1b 100644 --- a/mobile/src/launcher.js +++ b/mobile/src/launcher.js @@ -80,22 +80,23 @@ } function testServer(url, callback) { - // Try to reach the health endpoint - var controller = new AbortController(); - var timeout = setTimeout(function() { controller.abort(); }, 8000); + var done = false; + function respond(ok) { + if (done) return; + done = true; + callback(ok); + } - fetch(url + '/api/health', { signal: controller.signal, mode: 'no-cors' }) - .then(function() { clearTimeout(timeout); callback(true); }) + // Try to reach the health endpoint (no-cors: opaque response = server exists) + fetch(url + '/api/health', { mode: 'no-cors', signal: AbortSignal.timeout(8000) }) + .then(function() { respond(true); }) .catch(function() { - clearTimeout(timeout); - // no-cors mode always succeeds for reachable servers (opaque response) - // If it fails, the server is truly unreachable - // Try again with a simple image load as fallback + // Fetch failed — try image load as a fallback connectivity check + var fallbackTimer = setTimeout(function() { respond(false); }, 5000); var img = new Image(); - img.onload = function() { callback(true); }; - img.onerror = function() { callback(true); }; // Even errors mean server responded + img.onload = function() { clearTimeout(fallbackTimer); respond(true); }; + img.onerror = function() { clearTimeout(fallbackTimer); respond(false); }; img.src = url + '/favicon.ico?t=' + Date.now(); - setTimeout(function() { callback(false); }, 5000); }); }