diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberBunkerRequest.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberBunkerRequest.kt index 3e198b64..8d640df9 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberBunkerRequest.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberBunkerRequest.kt @@ -1,8 +1,5 @@ package com.greenart7c3.nostrsigner.models -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import com.greenart7c3.nostrsigner.ui.RememberType import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequest @@ -22,8 +19,6 @@ data class AmberBunkerRequest( val name: String, val signedEvent: Event?, val encryptedData: EncryptedDataKind?, - val checked: MutableState = mutableStateOf(true), - val rememberType: MutableState = mutableStateOf(RememberType.NEVER), val encryptionType: EncryptionType, val isNostrConnectUri: Boolean, ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/IntentData.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/IntentData.kt index f953bf62..fbc463e8 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/IntentData.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/IntentData.kt @@ -1,7 +1,5 @@ package com.greenart7c3.nostrsigner.models -import androidx.compose.runtime.MutableState -import com.greenart7c3.nostrsigner.ui.RememberType import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey @@ -16,8 +14,6 @@ data class IntentData( val returnType: ReturnType, val permissions: List?, val currentAccount: String, - val checked: MutableState, - val rememberType: MutableState, val route: String?, val event: Event?, val encryptedData: EncryptedDataKind?, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt index b4010e7e..1043b07f 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/IntentUtils.kt @@ -8,7 +8,6 @@ import android.net.Uri import android.provider.Browser import android.util.Log import android.widget.Toast -import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.platform.Clipboard import androidx.compose.ui.text.intl.Locale @@ -173,8 +172,6 @@ object IntentUtils { returnType = returnType, permissions = listOf(), currentAccount = Hex.decode(signedEvent.pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = signedEvent, encryptedData = null, @@ -219,8 +216,6 @@ object IntentUtils { returnType = returnType, permissions = listOf(), currentAccount = Hex.decode(pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = encryptedDataKind, @@ -238,8 +233,6 @@ object IntentUtils { returnType = returnType, permissions = listOf(), currentAccount = "", - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = null, @@ -257,8 +250,6 @@ object IntentUtils { returnType = returnType, permissions = listOf(), currentAccount = "", - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = null, @@ -359,8 +350,6 @@ object IntentUtils { returnType = returnType, permissions = permissions?.map { Permission(it.type.trim(), it.kind, it.checked) }, currentAccount = npub ?: Hex.decode(signed.pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = signed, encryptedData = null, @@ -411,8 +400,6 @@ object IntentUtils { returnType = returnType, permissions = permissions?.map { Permission(it.type.trim(), it.kind, it.checked) }, currentAccount = npub ?: Hex.decode(pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = encryptedDataKind, @@ -435,8 +422,6 @@ object IntentUtils { returnType = returnType, permissions = permissions?.map { Permission(it.type.trim(), it.kind, it.checked) }, currentAccount = npub ?: Hex.decode(pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = null, @@ -459,8 +444,6 @@ object IntentUtils { returnType = returnType, permissions = permissions?.map { Permission(it.type.trim(), it.kind, it.checked) }, currentAccount = npub ?: Hex.decode(pubKey).toNpub(), - checked = mutableStateOf(true), - rememberType = mutableStateOf(RememberType.NEVER), route = route, event = null, encryptedData = null, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/service/MultiEventScreenIntents.kt b/app/src/main/java/com/greenart7c3/nostrsigner/service/MultiEventScreenIntents.kt index 7d394c0b..865340d0 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/service/MultiEventScreenIntents.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/service/MultiEventScreenIntents.kt @@ -1,10 +1,17 @@ package com.greenart7c3.nostrsigner.service +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import com.greenart7c3.nostrsigner.models.AmberBunkerRequest import com.greenart7c3.nostrsigner.models.IntentData +import com.greenart7c3.nostrsigner.ui.RememberType object MultiEventScreenIntents { var intents = listOf() var bunkerRequests = listOf() var appName = "" + val checkedStates = mutableStateMapOf() + var rememberType by mutableStateOf(RememberType.NEVER) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SeeDetailsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SeeDetailsScreen.kt index 7ad7f4b8..f71b044c 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SeeDetailsScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SeeDetailsScreen.kt @@ -56,7 +56,7 @@ fun SeeDetailsScreen( .weight(1f) .verticalScroll(rememberScrollState()), ) { - var rememberType by remember { mutableStateOf(MultiEventScreenIntents.intents.firstOrNull()?.rememberType?.value ?: MultiEventScreenIntents.bunkerRequests.first().rememberType.value) } + var rememberType by remember { mutableStateOf(MultiEventScreenIntents.rememberType) } val type = if (MultiEventScreenIntents.intents.isNotEmpty()) { MultiEventScreenIntents.intents.first().type } else { @@ -96,15 +96,14 @@ fun SeeDetailsScreen( onReject = {}, onChanged = { rememberType = it - MultiEventScreenIntents.intents.forEach { intent -> - intent.rememberType.value = rememberType - } + MultiEventScreenIntents.rememberType = it }, packageName = null, ) } MultiEventScreenIntents.intents.forEach { intent -> + val intentChecked = MultiEventScreenIntents.checkedStates[intent.id] ?: true Card( Modifier .padding(4.dp), @@ -118,13 +117,13 @@ fun SeeDetailsScreen( modifier = Modifier .fillMaxWidth() .clickable { - intent.checked.value = !intent.checked.value + MultiEventScreenIntents.checkedStates[intent.id] = !intentChecked }, ) { Checkbox( - checked = intent.checked.value, + checked = intentChecked, onCheckedChange = { _ -> - intent.checked.value = !intent.checked.value + MultiEventScreenIntents.checkedStates[intent.id] = !intentChecked }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, @@ -163,13 +162,14 @@ fun SeeDetailsScreen( .weight(1f) .padding(vertical = 8.dp), text = data.ifBlank { message }, - color = if (intent.checked.value) Color.Unspecified else Color.Gray, + color = if (intentChecked) Color.Unspecified else Color.Gray, ) } } } MultiEventScreenIntents.bunkerRequests.forEach { bunkerRequest -> + val bunkerChecked = MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] ?: true Card( Modifier .padding(4.dp), @@ -183,13 +183,13 @@ fun SeeDetailsScreen( modifier = Modifier .fillMaxWidth() .clickable { - bunkerRequest.checked.value = !bunkerRequest.checked.value + MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] = !bunkerChecked }, ) { Checkbox( - checked = bunkerRequest.checked.value, + checked = bunkerChecked, onCheckedChange = { _ -> - bunkerRequest.checked.value = !bunkerRequest.checked.value + MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] = !bunkerChecked }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, @@ -228,7 +228,7 @@ fun SeeDetailsScreen( .weight(1f) .padding(vertical = 8.dp), text = data.ifBlank { message }, - color = if (bunkerRequest.checked.value) Color.Unspecified else Color.Gray, + color = if (bunkerChecked) Color.Unspecified else Color.Gray, ) } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt index f7cf3594..716dd559 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerMultiEventHomeScreen.kt @@ -53,6 +53,7 @@ import com.greenart7c3.nostrsigner.service.AmberUtils import com.greenart7c3.nostrsigner.service.ApplicationNameCache import com.greenart7c3.nostrsigner.service.BunkerRequestUtils import com.greenart7c3.nostrsigner.service.EventNotificationConsumer +import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents import com.greenart7c3.nostrsigner.service.model.AmberEvent import com.greenart7c3.nostrsigner.service.toShortenHex import com.greenart7c3.nostrsigner.ui.RememberType @@ -82,6 +83,12 @@ fun BunkerMultiEventHomeScreen( var relayAuthScope by remember { mutableStateOf(RelayAuthScope.SPECIFIC) } var appName by remember { mutableStateOf(ApplicationNameCache.names["$localAccount-$key"] ?: key.toShortenHex()) } + LaunchedEffect(Unit) { + MultiEventScreenIntents.checkedStates.clear() + MultiEventScreenIntents.rememberType = RememberType.NEVER + bunkerRequests.forEach { MultiEventScreenIntents.checkedStates[it.request.id] = true } + } + LaunchedEffect(Unit) { launch(Dispatchers.IO) { localAccount = LocalPreferences.loadFromEncryptedStorage( @@ -116,8 +123,8 @@ fun BunkerMultiEventHomeScreen( SigningAs(accountParam) val allCheckedState = when { - bunkerRequests.all { it.checked.value } -> ToggleableState.On - bunkerRequests.none { it.checked.value } -> ToggleableState.Off + bunkerRequests.all { MultiEventScreenIntents.checkedStates[it.request.id] ?: true } -> ToggleableState.On + bunkerRequests.none { MultiEventScreenIntents.checkedStates[it.request.id] ?: true } -> ToggleableState.Off else -> ToggleableState.Indeterminate } Row( @@ -126,14 +133,14 @@ fun BunkerMultiEventHomeScreen( .fillMaxWidth() .clickable { val newValue = allCheckedState != ToggleableState.On - bunkerRequests.forEach { it.checked.value = newValue } + bunkerRequests.forEach { MultiEventScreenIntents.checkedStates[it.request.id] = newValue } }, ) { TriStateCheckbox( state = allCheckedState, onClick = { val newValue = allCheckedState != ToggleableState.On - bunkerRequests.forEach { it.checked.value = newValue } + bunkerRequests.forEach { MultiEventScreenIntents.checkedStates[it.request.id] = newValue } }, ) Text(stringResource(R.string.select_deselect_all)) @@ -145,7 +152,15 @@ fun BunkerMultiEventHomeScreen( .verticalScroll(rememberScrollState()), ) { bunkerRequests.forEach { bunkerRequest -> - BunkerRequestCard(context = context, bunkerRequest = bunkerRequest) + BunkerRequestCard( + context = context, + bunkerRequest = bunkerRequest, + checked = MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] ?: true, + onToggleChecked = { + val current = MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] ?: true + MultiEventScreenIntents.checkedStates[bunkerRequest.request.id] = !current + }, + ) } } @@ -184,9 +199,7 @@ fun BunkerMultiEventHomeScreen( onReject = {}, onChanged = { rememberType = it - bunkerRequests.forEach { bunkerRequest -> - bunkerRequest.rememberType.value = rememberType - } + MultiEventScreenIntents.rememberType = it }, packageName = packageName, ) @@ -247,7 +260,8 @@ fun BunkerMultiEventHomeScreen( permissions = mutableListOf(), ) - if (request.rememberType.value != RememberType.NEVER && request.checked.value) { + val isChecked = MultiEventScreenIntents.checkedStates[request.request.id] ?: true + if (rememberType != RememberType.NEVER && isChecked) { val rejectKind = if (request.request is BunkerRequestSign) request.request.event.kind else null val rejectRelay = if (request.request is BunkerRequestSign && request.request.event.kind == 22242) { if (relayAuthScope == RelayAuthScope.ALL) { @@ -272,7 +286,7 @@ fun BunkerMultiEventHomeScreen( BunkerRequestUtils.getTypeFromBunker(request.request), rejectKind, false, - request.rememberType.value, + rememberType, thisAccount, relay = rejectRelay, ) @@ -345,10 +359,12 @@ fun BunkerMultiEventHomeScreen( permissions = mutableListOf(), ) + val isChecked = MultiEventScreenIntents.checkedStates[request.request.id] ?: true + if (request.request is BunkerRequestSign) { val localEvent = request.signedEvent!! - if (request.rememberType.value != RememberType.NEVER && request.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { val signRelay = if (localEvent.kind == 22242) { if (relayAuthScope == RelayAuthScope.ALL) { "*" @@ -372,7 +388,7 @@ fun BunkerMultiEventHomeScreen( signerType = SignerType.SIGN_EVENT, kind = localEvent.kind, value = true, - rememberType = request.rememberType.value, + rememberType = rememberType, account = thisAccount, relay = signRelay, ) @@ -387,7 +403,7 @@ fun BunkerMultiEventHomeScreen( type = SignerType.SIGN_EVENT.toString(), kind = localEvent.kind, time = TimeUtils.now(), - accepted = request.checked.value, + accepted = isChecked, content = localEvent.toJson(), ), thisAccount.npub, @@ -395,7 +411,7 @@ fun BunkerMultiEventHomeScreen( BunkerRequestUtils.remove(request.request.id) - if (request.checked.value) { + if (isChecked) { BunkerRequestUtils.sendBunkerResponse( context, thisAccount, @@ -416,14 +432,14 @@ fun BunkerMultiEventHomeScreen( ) } } else if (request.request.method == "sign_message") { - if (request.rememberType.value != RememberType.NEVER && request.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { AmberUtils.acceptOrRejectPermission( application, localKey, SignerType.SIGN_MESSAGE, null, true, - request.rememberType.value, + rememberType, thisAccount, ) } @@ -436,7 +452,7 @@ fun BunkerMultiEventHomeScreen( SignerType.SIGN_MESSAGE.toString(), null, TimeUtils.now(), - request.checked.value, + isChecked, content = request.request.params.first(), ), thisAccount.npub, @@ -445,7 +461,7 @@ fun BunkerMultiEventHomeScreen( val signedMessage = thisAccount.signString(request.request.params.first()) BunkerRequestUtils.remove(request.request.id) - if (request.checked.value) { + if (isChecked) { BunkerRequestUtils.sendBunkerResponse( context, thisAccount, @@ -476,14 +492,14 @@ fun BunkerMultiEventHomeScreen( SignerType.CONNECT.toString(), null, TimeUtils.now(), - request.checked.value, + isChecked, content = "", ), thisAccount.npub, ) BunkerRequestUtils.remove(request.request.id) - if (request.checked.value) { + if (isChecked) { BunkerRequestUtils.sendBunkerResponse( context, thisAccount, @@ -506,14 +522,14 @@ fun BunkerMultiEventHomeScreen( } } else { val type = BunkerRequestUtils.getTypeFromBunker(request.request) - if (request.rememberType.value != RememberType.NEVER && request.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { AmberUtils.acceptOrRejectPermission( application, localKey, type, null, true, - request.rememberType.value, + rememberType, thisAccount, ) } @@ -527,7 +543,7 @@ fun BunkerMultiEventHomeScreen( type.toString(), null, TimeUtils.now(), - request.checked.value, + isChecked, content = if (type == SignerType.NIP04_DECRYPT || type == SignerType.NIP44_DECRYPT || type == SignerType.DECRYPT_ZAP_EVENT) { request.encryptedData?.result ?: "" } else { @@ -539,7 +555,7 @@ fun BunkerMultiEventHomeScreen( val signature = request.encryptedData?.result ?: continue BunkerRequestUtils.remove(request.request.id) - if (request.checked.value) { + if (isChecked) { BunkerRequestUtils.sendBunkerResponse( context, thisAccount, @@ -572,7 +588,12 @@ fun BunkerMultiEventHomeScreen( } @Composable -private fun BunkerRequestCard(context: Context, bunkerRequest: AmberBunkerRequest) { +private fun BunkerRequestCard( + context: Context, + bunkerRequest: AmberBunkerRequest, + checked: Boolean, + onToggleChecked: () -> Unit, +) { val type = BunkerRequestUtils.getTypeFromBunker(bunkerRequest.request) var showDetails by remember { mutableStateOf(false) } val hasDetails = (type == SignerType.SIGN_EVENT && bunkerRequest.signedEvent != null) || @@ -655,11 +676,11 @@ private fun BunkerRequestCard(context: Context, bunkerRequest: AmberBunkerReques verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable { bunkerRequest.checked.value = !bunkerRequest.checked.value }, + .clickable { onToggleChecked() }, ) { Checkbox( - checked = bunkerRequest.checked.value, - onCheckedChange = { bunkerRequest.checked.value = !bunkerRequest.checked.value }, + checked = checked, + onCheckedChange = { onToggleChecked() }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, ), @@ -671,7 +692,7 @@ private fun BunkerRequestCard(context: Context, bunkerRequest: AmberBunkerReques ) { Text( text = label, - color = if (bunkerRequest.checked.value) Color.Unspecified else Color.Gray, + color = if (checked) Color.Unspecified else Color.Gray, ) if (preview.isNotBlank()) { Text( diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerPermissionCard.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerPermissionCard.kt index 7b957aa7..680a0ec0 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerPermissionCard.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/BunkerPermissionCard.kt @@ -16,6 +16,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState +import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -66,14 +67,14 @@ fun BunkerPermissionCard( .fillMaxWidth() .clickable { acceptEventsGroup[index].value = !acceptEventsGroup[index].value - item.second.forEach { it.checked.value = acceptEventsGroup[index].value } + item.second.forEach { MultiEventScreenIntents.checkedStates[it.request.id] = acceptEventsGroup[index].value } }, ) { Checkbox( checked = acceptEventsGroup[index].value, onCheckedChange = { _ -> acceptEventsGroup[index].value = !acceptEventsGroup[index].value - item.second.forEach { it.checked.value = acceptEventsGroup[index].value } + item.second.forEach { MultiEventScreenIntents.checkedStates[it.request.id] = acceptEventsGroup[index].value } }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, @@ -134,7 +135,7 @@ fun BunkerPermissionCard( ) } if (acceptEventsGroup[index].value) { - val selected = item.second.filter { it.checked.value }.size + val selected = item.second.filter { MultiEventScreenIntents.checkedStates[it.request.id] ?: true }.size val total = item.second.size Row( Modifier diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt index a707e1be..1b133f7e 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/IntentMultiEventHomeScreen.kt @@ -55,6 +55,7 @@ import com.greenart7c3.nostrsigner.models.SignerType import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind import com.greenart7c3.nostrsigner.service.AmberUtils import com.greenart7c3.nostrsigner.service.ApplicationNameCache +import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents import com.greenart7c3.nostrsigner.service.model.AmberEvent import com.greenart7c3.nostrsigner.service.toShortenHex import com.greenart7c3.nostrsigner.ui.RememberType @@ -82,6 +83,12 @@ fun IntentMultiEventHomeScreen( var rememberType by remember { mutableStateOf(RememberType.NEVER) } var relayAuthScope by remember { mutableStateOf(RelayAuthScope.SPECIFIC) } + LaunchedEffect(Unit) { + MultiEventScreenIntents.checkedStates.clear() + MultiEventScreenIntents.rememberType = RememberType.NEVER + intents.forEach { MultiEventScreenIntents.checkedStates[it.id] = true } + } + LaunchedEffect(Unit) { launch(Dispatchers.IO) { localAccount = LocalPreferences.loadFromEncryptedStorage( @@ -124,8 +131,8 @@ fun IntentMultiEventHomeScreen( SigningAs(accountParam) val allCheckedState = when { - intents.all { it.checked.value } -> ToggleableState.On - intents.none { it.checked.value } -> ToggleableState.Off + intents.all { MultiEventScreenIntents.checkedStates[it.id] ?: true } -> ToggleableState.On + intents.none { MultiEventScreenIntents.checkedStates[it.id] ?: true } -> ToggleableState.Off else -> ToggleableState.Indeterminate } Row( @@ -134,14 +141,14 @@ fun IntentMultiEventHomeScreen( .fillMaxWidth() .clickable { val newValue = allCheckedState != ToggleableState.On - intents.forEach { it.checked.value = newValue } + intents.forEach { MultiEventScreenIntents.checkedStates[it.id] = newValue } }, ) { TriStateCheckbox( state = allCheckedState, onClick = { val newValue = allCheckedState != ToggleableState.On - intents.forEach { it.checked.value = newValue } + intents.forEach { MultiEventScreenIntents.checkedStates[it.id] = newValue } }, ) Text(stringResource(R.string.select_deselect_all)) @@ -153,7 +160,15 @@ fun IntentMultiEventHomeScreen( .verticalScroll(rememberScrollState()), ) { intents.forEach { intent -> - IntentRequestCard(context = context, intent = intent) + IntentRequestCard( + context = context, + intent = intent, + checked = MultiEventScreenIntents.checkedStates[intent.id] ?: true, + onToggleChecked = { + val current = MultiEventScreenIntents.checkedStates[intent.id] ?: true + MultiEventScreenIntents.checkedStates[intent.id] = !current + }, + ) } } @@ -192,9 +207,7 @@ fun IntentMultiEventHomeScreen( onReject = {}, onChanged = { rememberType = it - intents.forEach { intent -> - intent.rememberType.value = rememberType - } + MultiEventScreenIntents.rememberType = it }, packageName = packageName, ) @@ -250,7 +263,8 @@ fun IntentMultiEventHomeScreen( permissions = mutableListOf(), ) - if (intentData.rememberType.value != RememberType.NEVER && intentData.checked.value) { + val isChecked = MultiEventScreenIntents.checkedStates[intentData.id] ?: true + if (rememberType != RememberType.NEVER && isChecked) { val rejectKind = if (intentData.type == SignerType.SIGN_EVENT) intentData.event?.kind else null val rejectRelay = if (intentData.type == SignerType.SIGN_EVENT && intentData.event?.kind == 22242) { if (relayAuthScope == RelayAuthScope.ALL) { @@ -275,7 +289,7 @@ fun IntentMultiEventHomeScreen( intentData.type, rejectKind, false, - intentData.rememberType.value, + rememberType, thisAccount, relay = rejectRelay, ) @@ -356,10 +370,12 @@ fun IntentMultiEventHomeScreen( closeApp = false } + val isChecked = MultiEventScreenIntents.checkedStates[intentData.id] ?: true + if (intentData.type == SignerType.SIGN_EVENT) { val localEvent = intentData.event!! - if (intentData.rememberType.value != RememberType.NEVER && intentData.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { val signRelay = if (localEvent.kind == 22242) { if (relayAuthScope == RelayAuthScope.ALL) { "*" @@ -383,7 +399,7 @@ fun IntentMultiEventHomeScreen( intentData.type, localEvent.kind, true, - intentData.rememberType.value, + rememberType, thisAccount, relay = signRelay, ) @@ -398,13 +414,13 @@ fun IntentMultiEventHomeScreen( intentData.type.toString(), localEvent.kind, TimeUtils.now(), - intentData.checked.value, + isChecked, content = localEvent.toJson(), ), thisAccount.npub, ) - if (intentData.checked.value) { + if (isChecked) { results.add( Result( null, @@ -432,14 +448,14 @@ fun IntentMultiEventHomeScreen( ) } } else if (intentData.type == SignerType.SIGN_MESSAGE) { - if (intentData.rememberType.value != RememberType.NEVER && intentData.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { AmberUtils.acceptOrRejectPermission( application, localKey, intentData.type, null, true, - intentData.rememberType.value, + rememberType, thisAccount, ) } @@ -452,14 +468,14 @@ fun IntentMultiEventHomeScreen( intentData.type.toString(), null, TimeUtils.now(), - intentData.checked.value, + isChecked, content = intentData.data, ), thisAccount.npub, ) val signedMessage = thisAccount.signString(intentData.data) - if (intentData.checked.value) { + if (isChecked) { results.add( Result( null, @@ -471,14 +487,14 @@ fun IntentMultiEventHomeScreen( ) } } else { - if (intentData.rememberType.value != RememberType.NEVER && intentData.checked.value) { + if (rememberType != RememberType.NEVER && isChecked) { AmberUtils.acceptOrRejectPermission( application, localKey, intentData.type, null, true, - intentData.rememberType.value, + rememberType, thisAccount, ) } @@ -492,7 +508,7 @@ fun IntentMultiEventHomeScreen( intentData.type.toString(), null, TimeUtils.now(), - intentData.checked.value, + isChecked, content = if (intentData.type == SignerType.NIP04_DECRYPT || intentData.type == SignerType.NIP44_DECRYPT || intentData.type == SignerType.DECRYPT_ZAP_EVENT) { intentData.encryptedData?.result ?: "" } else { @@ -503,7 +519,7 @@ fun IntentMultiEventHomeScreen( ) val signature = intentData.encryptedData?.result ?: continue - if (intentData.checked.value) { + if (isChecked) { results.add( Result( null, @@ -533,7 +549,12 @@ fun IntentMultiEventHomeScreen( } @Composable -private fun IntentRequestCard(context: Context, intent: IntentData) { +private fun IntentRequestCard( + context: Context, + intent: IntentData, + checked: Boolean, + onToggleChecked: () -> Unit, +) { val type = intent.type var showDetails by remember { mutableStateOf(false) } val hasDetails = (type == SignerType.SIGN_EVENT && intent.event != null) || @@ -615,11 +636,11 @@ private fun IntentRequestCard(context: Context, intent: IntentData) { verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable { intent.checked.value = !intent.checked.value }, + .clickable { onToggleChecked() }, ) { Checkbox( - checked = intent.checked.value, - onCheckedChange = { intent.checked.value = !intent.checked.value }, + checked = checked, + onCheckedChange = { onToggleChecked() }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, ), @@ -631,7 +652,7 @@ private fun IntentRequestCard(context: Context, intent: IntentData) { ) { Text( text = label, - color = if (intent.checked.value) Color.Unspecified else Color.Gray, + color = if (checked) Color.Unspecified else Color.Gray, ) if (preview.isNotBlank()) { Text( diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/PermissionCard.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/PermissionCard.kt index 78c411a6..a12c7fa8 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/PermissionCard.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/PermissionCard.kt @@ -16,6 +16,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState +import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -66,14 +67,14 @@ fun PermissionCard( .fillMaxWidth() .clickable { acceptEventsGroup[index].value = !acceptEventsGroup[index].value - item.second.forEach { it.checked.value = acceptEventsGroup[index].value } + item.second.forEach { MultiEventScreenIntents.checkedStates[it.id] = acceptEventsGroup[index].value } }, ) { Checkbox( checked = acceptEventsGroup[index].value, onCheckedChange = { _ -> acceptEventsGroup[index].value = !acceptEventsGroup[index].value - item.second.forEach { it.checked.value = acceptEventsGroup[index].value } + item.second.forEach { MultiEventScreenIntents.checkedStates[it.id] = acceptEventsGroup[index].value } }, colors = CheckboxDefaults.colors().copy( uncheckedBorderColor = Color.Gray, @@ -134,7 +135,7 @@ fun PermissionCard( ) } if (acceptEventsGroup[index].value) { - val selected = item.second.filter { it.checked.value }.size + val selected = item.second.filter { MultiEventScreenIntents.checkedStates[it.id] ?: true }.size val total = item.second.size Row( Modifier