diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt b/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt index 498a6387..dd674db0 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt @@ -91,7 +91,7 @@ class Amber : val client: NostrClient = NostrClient(factory, applicationIOScope) - val stats = AmberRelayStats(client, applicationIOScope, this) + val stats = AmberRelayStats(client, this) // logs and stat counts. val listener = NostrClientLoggerListener(this, stats, applicationIOScope).also { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/relays/AmberRelayStat.kt b/app/src/main/java/com/greenart7c3/nostrsigner/relays/AmberRelayStat.kt index eb7c40eb..0f9cab5e 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/relays/AmberRelayStat.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/relays/AmberRelayStat.kt @@ -1,6 +1,7 @@ package com.greenart7c3.nostrsigner.relays import android.Manifest +import android.annotation.SuppressLint import android.app.Notification import android.app.NotificationManager import android.app.PendingIntent @@ -20,20 +21,38 @@ import com.greenart7c3.nostrsigner.service.KillSwitchReceiver import com.greenart7c3.nostrsigner.service.ReconnectReceiver import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.stateIn class AmberRelayStats( client: NostrClient, - scope: CoroutineScope, val appContext: Context, ) { var oldMessage = "" - val relayStatus = client.relayStatusFlow() + var available = emptySet() + var connected = emptySet() + + @OptIn(FlowPreview::class) + @SuppressLint("MissingPermission") + val relayStatus = combine(client.availableRelaysFlow(), client.connectedRelaysFlow()) { available, connected -> + available to connected + }.debounce(300).onEach { + this.available = it.first + this.connected = it.second + val notificationManager = NotificationManagerCompat.from(appContext) + if (ActivityCompat.checkSelfPermission(appContext, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { + createNotification( + it.second, + it.first, + false, + )?.let { notification -> + Log.d(Amber.TAG, "updateNotification") + notificationManager.notify(2, notification) + } + } + } lateinit var group: NotificationChannelGroupCompat lateinit var channel: NotificationChannelCompat @@ -72,26 +91,8 @@ class AmberRelayStats( notificationManager.createNotificationChannel(statusChannel) } - @OptIn(FlowPreview::class) - val relayStatusUpdater = client.relayStatusFlow().debounce(300).onEach { - try { - updateNotification() - } catch (_: NullPointerException) { - } - }.stateIn( - scope, - SharingStarted.Eagerly, - relayStatus.value, - ) - private val innerCache = mutableMapOf() - fun createNotification(forceCreate: Boolean = false) = createNotification( - relayStatus.value.connected, - relayStatus.value.available, - forceCreate, - ) - fun createForegroundNotification(): Notification { val contentIntent = Intent(appContext, MainActivity::class.java) contentIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) @@ -189,7 +190,10 @@ class AmberRelayStats( fun updateNotification() { val notificationManager = NotificationManagerCompat.from(appContext) if (ActivityCompat.checkSelfPermission(appContext, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { - createNotification()?.let { + createNotification( + connected, + available, + )?.let { Log.d(Amber.TAG, "updateNotification") notificationManager.notify(2, it) } @@ -203,11 +207,6 @@ class AmberRelayStats( updateNotification() } - fun addReceived(url: NormalizedRelayUrl) { - get(url).addReceived() - updateNotification() - } - fun addFailed(url: NormalizedRelayUrl) { get(url).addFailed() updateNotification() diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt index 3ab0bd29..598c59fc 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt @@ -110,7 +110,7 @@ private fun askNotificationPermission( @SuppressLint("BatteryLife") fun requestIgnoreBatteryOptimizations(context: Context) { if (BuildFlavorChecker.isOfflineFlavor()) return - if (Amber.instance.client.relayStatusFlow().value.connected.isEmpty()) return + if (Amber.instance.client.connectedRelaysFlow().value.isEmpty()) return val packageName = context.packageName val pm = context.getSystemService(PowerManager::class.java) if (!pm.isIgnoringBatteryOptimizations(packageName) && !LocalPreferences.getBatteryOptimization(context)) { diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/EditRelaysDialog.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/EditRelaysDialog.kt index 7a730aa0..02309231 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/EditRelaysDialog.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/actions/EditRelaysDialog.kt @@ -547,9 +547,9 @@ fun ActiveRelaysScreen( Column( verticalArrangement = Arrangement.Center, ) { - val isConnected by Amber.instance.client.relayStatusFlow().map { status -> - relay in status.connected - }.collectAsStateWithLifecycle(relay in Amber.instance.client.relayStatusFlow().value.connected) + val isConnected by Amber.instance.client.connectedRelaysFlow().map { status -> + relay in status + }.collectAsStateWithLifecycle(relay in Amber.instance.client.connectedRelaysFlow().value) Text( modifier = Modifier.padding(top = 16.dp), diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AmberTopAppBar.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AmberTopAppBar.kt index 98b14f4f..f8cf5cbc 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AmberTopAppBar.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/AmberTopAppBar.kt @@ -5,7 +5,6 @@ import android.graphics.drawable.Drawable import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Shield import androidx.compose.material3.CenterAlignedTopAppBar @@ -91,8 +90,8 @@ fun AmberTopAppBar( horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.CenterVertically, ) { - val relayStats = Amber.instance.client.relayStatusFlow().collectAsStateWithLifecycle() - Text("${relayStats.value.connected.size}/${relayStats.value.available.size}") + val relayStats = Amber.instance.stats.relayStatus.collectAsStateWithLifecycle(Pair(emptySet(), emptySet())) + Text("${relayStats.value.second.size}/${relayStats.value.first.size}") Icon( imageVector = ImageVector.vectorResource(R.drawable.relays), contentDescription = context.getString(R.string.reconnect), diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bd4cd6ed..106d4e00 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ junitVersion = "1.3.0" lifecycle_version = "2.10.0" material3 = "1.4.0" nav_version = "2.9.6" -quartz = "1.04.2" +quartz = "1.05.1" compose_ui = "1.10.0" richtextUi = "e1151c8" roomKtx = "2.8.4"