Merge pull request #2102 from RoboSats/new-mobile-app-fixes

New mobile app fixes
This commit is contained in:
KoalaSat
2025-07-24 14:16:11 +00:00
committed by GitHub
4 changed files with 52 additions and 5 deletions

View File

@ -19,6 +19,8 @@ import android.webkit.WebSettings
import android.webkit.WebStorage import android.webkit.WebStorage
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import android.content.Intent
import android.net.Uri
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
@ -186,6 +188,38 @@ class MainActivity : AppCompatActivity() {
runOnUiThread { runOnUiThread {
updateStatus("Secure connection established. Loading app...") updateStatus("Secure connection established. Loading app...")
// Set up WebViewClient that allows external links and deep links to be opened
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
val url = request.url.toString()
val uri = request.url
if (url.startsWith("file:///android_asset/")) return false
try {
Log.d("ExternalLink", "Attempting to open: $url")
val intent = Intent(Intent.ACTION_VIEW, uri)
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
Log.d("ExternalLink", "Successfully opened link in external app")
} else {
Log.w("ExternalLink", "No app found to handle: $url")
if (url.startsWith("http://") || url.startsWith("https://")) {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
startActivity(browserIntent)
Log.d("ExternalLink", "Opened http/https link in browser")
}
}
return true
} catch (e: Exception) {
Log.e("ExternalLink", "Failed to open external link: ${e.message}", e)
return true
}
}
}
// Set up WebChromeClient with restricted permissions // Set up WebChromeClient with restricted permissions
webView.webChromeClient = object : WebChromeClient() { webView.webChromeClient = object : WebChromeClient() {
override fun onGeolocationPermissionsShowPrompt( override fun onGeolocationPermissionsShowPrompt(

View File

@ -319,7 +319,14 @@ class WebAppInterface(private val context: Context, private val webView: WebView
} }
private fun onWsMessage(path: String?, message: String?) { private fun onWsMessage(path: String?, message: String?) {
safeEvaluateJavascript("javascript:window.AndroidRobosats.onWSMessage('$path', '$message')") val escapedMessage = message
?.replace("\\", "\\\\")
?.replace("'", "\\'")
?.replace("\"", "\\\"")
?.replace("\n", "\\n")
?.replace("\r", "\\r")
?.replace("\t", "\\t")
safeEvaluateJavascript("javascript:window.AndroidRobosats.onWSMessage('$path', '$escapedMessage')")
} }
private fun onWsError(path: String?) { private fun onWsError(path: String?) {

View File

@ -23,7 +23,7 @@ import arraysAreDifferent from '../../../utils/array';
import getSettings from '../../../utils/settings'; import getSettings from '../../../utils/settings';
const path = const path =
getSettings().client == 'mobile' getSettings().client === 'mobile'
? 'file:///android_asset/static/assets/sounds' ? 'file:///android_asset/static/assets/sounds'
: '/static/assets/sounds'; : '/static/assets/sounds';
@ -98,12 +98,18 @@ const NotificationsDrawer = ({
const soundType = soundByStatus[orderStatus] ?? 'ding'; const soundType = soundByStatus[orderStatus] ?? 'ding';
const sound = audio[soundType]; const sound = audio[soundType];
void sound.play();
void sound.play();
void sound.play(); void sound.play();
}; };
const loadNotifciationsNostr = (): void => { const loadNotifciationsNostr = (): void => {
const tokens = Object.keys(garage.slots); const tokens = Object.keys(garage.slots);
if (!arraysAreDifferent(subscribedTokens, tokens)) return; if (!arraysAreDifferent(subscribedTokens, tokens)) {
setLoading(false);
return;
}
cleanUpNotifications(); cleanUpNotifications();
setSubscribedTokens(tokens); setSubscribedTokens(tokens);

View File

@ -21,7 +21,7 @@ import { Send } from '@mui/icons-material';
const audioPath = const audioPath =
getSettings().client == 'mobile' getSettings().client == 'mobile'
? 'file:///android_asset//static/assets/sounds' ? 'file:///android_asset/static/assets/sounds'
: '/static/assets/sounds'; : '/static/assets/sounds';
interface Props { interface Props {
@ -135,7 +135,7 @@ const EncryptedSocketChat: React.FC<Props> = ({
); );
connection.onMessage((message) => { connection.onMessage((message) => {
setServerMessages((prev) => [...prev, message]); setServerMessages((prev) => [...prev, message as ServerMessage]);
}); });
connection.onClose(() => { connection.onClose(() => {
setConnected(false); setConnected(false);