Configuration and fixes

This commit is contained in:
koalasat
2025-07-25 18:16:35 +02:00
parent 77df638340
commit 8ae9165efa
7 changed files with 59 additions and 33 deletions

View File

@ -97,12 +97,23 @@ class MainActivity : AppCompatActivity() {
}
}
/**
* Initialize Notifications service
*/
fun initializeNotifications() {
startForegroundService(
Intent(
this,
NotificationsService::class.java,
),
)
}
/**
* Initialize Notifications service
*/
private fun initializeNotifications() {
startForegroundService(
fun stopNotifications() {
stopService(
Intent(
this,
NotificationsService::class.java,
@ -319,7 +330,8 @@ class MainActivity : AppCompatActivity() {
// Now it's safe to load the local HTML file
webView.loadUrl("file:///android_asset/index.html")
initializeNotifications()
val notifications = EncryptedStorage.getEncryptedStorage("settings_notifications")
if (notifications != "false") initializeNotifications()
webView.post {
try {
@ -425,6 +437,8 @@ class MainActivity : AppCompatActivity() {
WebStorage.getInstance().deleteAllData()
stopNotifications()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeSessionCookies(null)
}

View File

@ -2,12 +2,14 @@ package com.robosats
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.widget.Toast
import com.robosats.models.EncryptedStorage
import com.robosats.models.NostrClient
import com.robosats.services.NotificationsService
import com.robosats.tor.TorKmpManager.getTorKmpObject
import okhttp3.Call
import okhttp3.Callback
@ -171,6 +173,7 @@ class WebAppInterface(private val context: Context, private val webView: WebView
val client: OkHttpClient = Builder()
.connectTimeout(60, TimeUnit.SECONDS) // Set connection timeout
.readTimeout(30, TimeUnit.SECONDS) // Set read timeout
.proxy(getTorKmpObject().proxy)
.build()
@ -356,7 +359,15 @@ class WebAppInterface(private val context: Context, private val webView: WebView
EncryptedStorage.setEncryptedStorage(sanitizedKey, sanitizedValue)
if (key == "federation_relays") NostrClient.refresh()
if (key == "garage_slots") NostrClient.refresh()
if (key == "settings_notifications") {
val serviceIntent = Intent(context, NotificationsService::class.java)
if (value == "true") {
context.startForegroundService(serviceIntent)
} else {
context.stopService(serviceIntent)
}
}
// Safely encode and return the result
resolvePromise(uuid, key)

View File

@ -14,6 +14,7 @@ import org.json.JSONObject
object NostrClient {
private var subscriptionNotificationId = "robosatsNotificationId"
private var authors = garagePubKeys()
fun init() {
RelayPool.register(Client)
@ -29,11 +30,9 @@ object NostrClient {
}
fun refresh() {
val federationRelays = EncryptedStorage.getEncryptedStorage("federation_relays")
val relayPool = RelayPool.getAll().map { it.url }
if (federationRelays.toSet() != relayPool.toSet()) {
stop()
start()
val pubKeys = garagePubKeys()
if (authors.toSet() != pubKeys.toSet()) {
subscribeToInbox()
}
}
@ -55,7 +54,7 @@ object NostrClient {
fun garagePubKeys(): List<String> {
val garageString = EncryptedStorage.getEncryptedStorage("garage_slots")
var authors = emptyList<String>()
var pubKeys = emptyList<String>()
if (garageString.isNotEmpty()) {
val garage = JSONObject(garageString)
@ -66,12 +65,12 @@ object NostrClient {
val slot = garage.getJSONObject(key) // Get the value associated with the key
val hexPubKey = slot.getString("nostrPubKey")
if (hexPubKey.isNotEmpty()) {
authors = authors.plus(hexPubKey)
pubKeys = pubKeys.plus(hexPubKey)
}
}
}
return authors
return pubKeys
}
fun getRobotKeyPair(hexPubKey: String): KeyPair {
@ -110,8 +109,10 @@ object NostrClient {
if (federationRelays.isNotEmpty()) {
val relaysUrls = JSONArray(federationRelays)
for (i in 0 until relaysUrls.length()) {
val url = relaysUrls.getString(i)
val relayList = (0 until relaysUrls.length()).map { relaysUrls.getString(it) }
val randomRelays = relayList.shuffled().take(3)
for (url in randomRelays) {
Client.sendFilterOnlyIfDisconnected()
if (RelayPool.getRelays(url).isEmpty()) {
RelayPool.addRelay(
@ -126,15 +127,20 @@ object NostrClient {
}
}
}
}
private fun subscribeToInbox() {
val garageString = EncryptedStorage.getEncryptedStorage("garage_slots")
if (garageString.isNotEmpty()) {
val authors = garagePubKeys()
authors = garagePubKeys()
if (authors.isNotEmpty()) {
Log.d(
"RobosatsNostrClient",
"Relay subscription authors: ${authors.size}",
)
Client.sendFilter(
subscriptionNotificationId,
listOf(

View File

@ -13,7 +13,6 @@ import android.graphics.Path
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.IBinder
import android.util.Base64
import android.util.Log
@ -22,7 +21,9 @@ import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationChannelGroupCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.graphics.createBitmap
import com.robosats.Connectivity
import com.robosats.MainActivity
import com.robosats.R
import com.robosats.RoboIdentities
import com.robosats.models.EncryptedStorage
@ -45,8 +46,6 @@ import org.json.JSONObject
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.ConcurrentHashMap
import androidx.core.graphics.createBitmap
import com.robosats.MainActivity
class NotificationsService : Service() {
private var channelRelaysId = "RelaysConnections"

View File

@ -51,7 +51,7 @@ const NotificationsDrawer = ({
}: NotificationsDrawerProps): React.JSX.Element => {
const theme = useTheme();
const navigate = useNavigate();
const { page, settings, navigateToPage } = useContext<UseAppStoreType>(AppContext);
const { page, settings, navigateToPage, client } = useContext<UseAppStoreType>(AppContext);
const { federation } = useContext<UseFederationStoreType>(FederationContext);
const { garage, slotUpdatedAt } = useContext<UseGarageStoreType>(GarageContext);
@ -118,11 +118,10 @@ const NotificationsDrawer = ({
setLastNotification((last) => {
if (last < event.created_at) {
setSnakevent(event);
setOpenSnak(true);
systemClient.setItem('last_notification', event.created_at.toString());
console.log(event);
const orderStatus = event.tags.find((t) => t[0] === 'status')?.[1];
if (orderStatus) playSound(parseInt(orderStatus, 10));
if (client !== 'mobile') setOpenSnak(true);
return event.created_at;
} else {

View File

@ -247,19 +247,16 @@ const SettingsForm = ({ dense = false }: SettingsFormProps): React.JSX.Element =
<ToggleButtonGroup
exclusive={true}
sx={{ width: '100%' }}
value={settings.stopNotifications}
onChange={(_e, stopNotifications) => {
setSettings({ ...settings, stopNotifications });
systemClient.setItem(
'settings_stop_notifications',
String(settings.stopNotifications),
);
value={settings.androidNotifications}
onChange={(_e, androidNotifications) => {
setSettings({ ...settings, androidNotifications });
systemClient.setItem('settings_notifications', String(androidNotifications));
}}
>
<ToggleButton value={false} color='primary' sx={{ flexGrow: 1 }}>
<ToggleButton value={true} color='primary' sx={{ flexGrow: 1 }}>
{t('On')}
</ToggleButton>
<ToggleButton value={true} color='secondary' sx={{ flexGrow: 1 }}>
<ToggleButton value={false} color='secondary' sx={{ flexGrow: 1 }}>
{t('Off')}
</ToggleButton>
</ToggleButtonGroup>

View File

@ -59,8 +59,8 @@ class BaseSettings {
this.network = result && result !== '' ? (result as 'mainnet' | 'testnet') : this.network;
});
systemClient.getItem('settings_stop_notifications').then((result) => {
this.stopNotifications = client === 'mobile' && result === 'true';
systemClient.getItem('settings_notifications').then((result) => {
this.androidNotifications = result === 'true';
});
systemClient.getItem('settings_use_proxy').then((result) => {
@ -87,7 +87,7 @@ class BaseSettings {
public unsafeClient: boolean = false;
public selfhostedClient: boolean = false;
public useProxy: boolean = false;
public stopNotifications: boolean = false;
public androidNotifications: boolean = false;
}
export default BaseSettings;