mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Merge pull request #498 from greenart7c3/claude/grouped-events-ui-options-9xgkdx
Group request options by type with per-group scope settings
This commit is contained in:
@@ -373,25 +373,14 @@ fun MainScreen(
|
||||
content = {
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
val modifier = if (intents.isEmpty() || packageName == null || destinationRoute != Route.IncomingRequest.route) {
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.verticalScrollbar(scrollState)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f)
|
||||
} else {
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.verticalScrollbar(scrollState)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = verticalPadding)
|
||||
}
|
||||
IncomingRequestScreen(
|
||||
horizontalPadding = verticalPadding,
|
||||
modifier = modifier,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.verticalScrollbar(scrollState)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = verticalPadding),
|
||||
scaffoldPadding = padding,
|
||||
intents = intents,
|
||||
bunkerRequests = bunkerRequests,
|
||||
|
||||
+52
-44
@@ -78,11 +78,11 @@ fun BunkerMultiEventHomeScreen(
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val hasRelayAuthEvents = bunkerRequests.any { it.request is BunkerRequestSign && it.request.event.kind == 22242 }
|
||||
var localAccount by remember { mutableStateOf("") }
|
||||
val key = bunkerRequests.first().localKey
|
||||
var rememberType by remember { mutableStateOf(RememberType.NEVER) }
|
||||
var relayAuthScope by remember { mutableStateOf(RelayAuthScope.SPECIFIC) }
|
||||
val groupRememberTypes = remember { mutableStateMapOf<RequestGroupKey, RememberType>() }
|
||||
val groupRelayAuthScopes = remember { mutableStateMapOf<RequestGroupKey, RelayAuthScope>() }
|
||||
val groupDecryptScopes = remember { mutableStateMapOf<RequestGroupKey, DecryptTypeScope>() }
|
||||
var appName by remember { mutableStateOf(ApplicationNameCache["$localAccount-$key"] ?: key.toShortenHex()) }
|
||||
var appIcon by remember { mutableStateOf(bunkerRequests.first().clientMetadata?.image ?: "") }
|
||||
|
||||
@@ -190,6 +190,19 @@ fun BunkerMultiEventHomeScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (groupKey.hasGroupOptions()) {
|
||||
item(key = "group-options:${groupKey.type.name}:${groupKey.payload?.name ?: ""}:${groupKey.kind ?: ""}") {
|
||||
RequestGroupOptions(
|
||||
groupKey = groupKey,
|
||||
rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER,
|
||||
onRememberTypeChanged = { groupRememberTypes[groupKey] = it },
|
||||
relayAuthScope = groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC,
|
||||
onRelayAuthScopeChanged = { groupRelayAuthScopes[groupKey] = it },
|
||||
decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(groupKey.type),
|
||||
onDecryptTypeScopeChanged = { groupDecryptScopes[groupKey] = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
if (expanded) {
|
||||
items(groupItems, key = { it.request.id }) { bunkerRequest ->
|
||||
BunkerRequestCard(
|
||||
@@ -206,41 +219,6 @@ fun BunkerMultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRelayAuthEvents) {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.relay_auth_scope),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = relayAuthScope,
|
||||
options = listOf(RelayAuthScope.SPECIFIC, RelayAuthScope.ALL),
|
||||
onSelected = { relayAuthScope = it },
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
RelayAuthScope.SPECIFIC -> R.string.for_this_relay_only
|
||||
RelayAuthScope.ALL -> R.string.for_all_relays
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
RememberMyChoice(
|
||||
alwaysShow = true,
|
||||
shouldRunAcceptOrReject = null,
|
||||
onAccept = {},
|
||||
onReject = {},
|
||||
onChanged = {
|
||||
rememberType = it
|
||||
MultiEventScreenIntents.rememberType = it
|
||||
},
|
||||
packageName = packageName,
|
||||
)
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -297,10 +275,24 @@ fun BunkerMultiEventHomeScreen(
|
||||
)
|
||||
|
||||
val isChecked = MultiEventScreenIntents.checkedStates[request.request.id] ?: true
|
||||
val requestType = BunkerRequestUtils.getTypeFromBunker(request.request)
|
||||
val groupKey = requestGroupKey(
|
||||
type = requestType,
|
||||
eventKind = (request.request as? BunkerRequestSign)?.event?.kind,
|
||||
encryptedData = request.encryptedData,
|
||||
nip44v3Kind = BunkerRequestUtils.getNip44v3Kind(request.request),
|
||||
)
|
||||
val rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val rejectKind = if (request.request is BunkerRequestSign) request.request.event.kind else null
|
||||
val decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(requestType)
|
||||
val rejectKind = when {
|
||||
request.request is BunkerRequestSign -> request.request.event.kind
|
||||
requestType == SignerType.NIP44_V3_ENCRYPT || requestType == SignerType.NIP44_V3_DECRYPT ->
|
||||
if (decryptTypeScope == DecryptTypeScope.SPECIFIC) BunkerRequestUtils.getNip44v3Kind(request.request) else null
|
||||
else -> null
|
||||
}
|
||||
val rejectRelay = if (request.request is BunkerRequestSign && request.request.event.kind == 22242) {
|
||||
if (relayAuthScope == RelayAuthScope.ALL) {
|
||||
if ((groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC) == RelayAuthScope.ALL) {
|
||||
"*"
|
||||
} else {
|
||||
RelayUrlUtils.extractHostAndPort(AmberEvent.relay(request.request.event))
|
||||
@@ -311,13 +303,14 @@ fun BunkerMultiEventHomeScreen(
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
localKey,
|
||||
BunkerRequestUtils.getTypeFromBunker(request.request),
|
||||
requestType,
|
||||
rejectKind,
|
||||
false,
|
||||
rememberType,
|
||||
thisAccount,
|
||||
relay = rejectRelay,
|
||||
encryptedData = request.encryptedData,
|
||||
decryptTypeScope = decryptTypeScope,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -389,13 +382,21 @@ fun BunkerMultiEventHomeScreen(
|
||||
)
|
||||
|
||||
val isChecked = MultiEventScreenIntents.checkedStates[request.request.id] ?: true
|
||||
val requestType = BunkerRequestUtils.getTypeFromBunker(request.request)
|
||||
val groupKey = requestGroupKey(
|
||||
type = requestType,
|
||||
eventKind = (request.request as? BunkerRequestSign)?.event?.kind,
|
||||
encryptedData = request.encryptedData,
|
||||
nip44v3Kind = BunkerRequestUtils.getNip44v3Kind(request.request),
|
||||
)
|
||||
val rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER
|
||||
|
||||
if (request.request is BunkerRequestSign) {
|
||||
val localEvent = request.signedEvent!!
|
||||
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val signRelay = if (localEvent.kind == 22242) {
|
||||
if (relayAuthScope == RelayAuthScope.ALL) {
|
||||
if ((groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC) == RelayAuthScope.ALL) {
|
||||
"*"
|
||||
} else {
|
||||
RelayUrlUtils.extractHostAndPort(AmberEvent.relay(localEvent))
|
||||
@@ -497,17 +498,24 @@ fun BunkerMultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val type = BunkerRequestUtils.getTypeFromBunker(request.request)
|
||||
val type = requestType
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(type)
|
||||
val permissionKind = if (type == SignerType.NIP44_V3_ENCRYPT || type == SignerType.NIP44_V3_DECRYPT) {
|
||||
if (decryptTypeScope == DecryptTypeScope.SPECIFIC) BunkerRequestUtils.getNip44v3Kind(request.request) else null
|
||||
} else {
|
||||
null
|
||||
}
|
||||
AmberUtils.acceptOrRejectPermission(
|
||||
application,
|
||||
localKey,
|
||||
type,
|
||||
null,
|
||||
permissionKind,
|
||||
true,
|
||||
rememberType,
|
||||
thisAccount,
|
||||
encryptedData = request.encryptedData,
|
||||
decryptTypeScope = decryptTypeScope,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+38
-42
@@ -75,9 +75,9 @@ fun IntentMultiEventHomeScreen(
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val hasRelayAuthEvents = intents.any { it.type == SignerType.SIGN_EVENT && it.event?.kind == 22242 }
|
||||
var rememberType by remember { mutableStateOf(RememberType.NEVER) }
|
||||
var relayAuthScope by remember { mutableStateOf(RelayAuthScope.SPECIFIC) }
|
||||
val groupRememberTypes = remember { mutableStateMapOf<RequestGroupKey, RememberType>() }
|
||||
val groupRelayAuthScopes = remember { mutableStateMapOf<RequestGroupKey, RelayAuthScope>() }
|
||||
val groupDecryptScopes = remember { mutableStateMapOf<RequestGroupKey, DecryptTypeScope>() }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
MultiEventScreenIntents.checkedStates.clear()
|
||||
@@ -156,6 +156,19 @@ fun IntentMultiEventHomeScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
if (groupKey.hasGroupOptions()) {
|
||||
item(key = "group-options:${groupKey.type.name}:${groupKey.payload?.name ?: ""}:${groupKey.kind ?: ""}") {
|
||||
RequestGroupOptions(
|
||||
groupKey = groupKey,
|
||||
rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER,
|
||||
onRememberTypeChanged = { groupRememberTypes[groupKey] = it },
|
||||
relayAuthScope = groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC,
|
||||
onRelayAuthScopeChanged = { groupRelayAuthScopes[groupKey] = it },
|
||||
decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(groupKey.type),
|
||||
onDecryptTypeScopeChanged = { groupDecryptScopes[groupKey] = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
if (expanded) {
|
||||
items(groupIntents, key = { it.id }) { intent ->
|
||||
IntentRequestCard(
|
||||
@@ -172,41 +185,6 @@ fun IntentMultiEventHomeScreen(
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRelayAuthEvents) {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.relay_auth_scope),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = relayAuthScope,
|
||||
options = listOf(RelayAuthScope.SPECIFIC, RelayAuthScope.ALL),
|
||||
onSelected = { relayAuthScope = it },
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
RelayAuthScope.SPECIFIC -> R.string.for_this_relay_only
|
||||
RelayAuthScope.ALL -> R.string.for_all_relays
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
RememberMyChoice(
|
||||
alwaysShow = true,
|
||||
shouldRunAcceptOrReject = null,
|
||||
onAccept = {},
|
||||
onReject = {},
|
||||
onChanged = {
|
||||
rememberType = it
|
||||
MultiEventScreenIntents.rememberType = it
|
||||
},
|
||||
packageName = packageName,
|
||||
)
|
||||
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -260,10 +238,18 @@ fun IntentMultiEventHomeScreen(
|
||||
var permissionsChanged = false
|
||||
for (intentData in accountIntents) {
|
||||
val isChecked = MultiEventScreenIntents.checkedStates[intentData.id] ?: true
|
||||
val groupKey = requestGroupKey(intentData.type, intentData.event?.kind, intentData.encryptedData, intentData.nip44v3Kind)
|
||||
val rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val rejectKind = if (intentData.type == SignerType.SIGN_EVENT) intentData.event?.kind else null
|
||||
val decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(intentData.type)
|
||||
val rejectKind = when {
|
||||
intentData.type == SignerType.SIGN_EVENT -> intentData.event?.kind
|
||||
intentData.type == SignerType.NIP44_V3_ENCRYPT || intentData.type == SignerType.NIP44_V3_DECRYPT ->
|
||||
if (decryptTypeScope == DecryptTypeScope.SPECIFIC) intentData.nip44v3Kind else null
|
||||
else -> null
|
||||
}
|
||||
val rejectRelay = if (intentData.type == SignerType.SIGN_EVENT && intentData.event?.kind == 22242) {
|
||||
if (relayAuthScope == RelayAuthScope.ALL) {
|
||||
if ((groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC) == RelayAuthScope.ALL) {
|
||||
"*"
|
||||
} else {
|
||||
RelayUrlUtils.extractHostAndPort(AmberEvent.relay(intentData.event))
|
||||
@@ -280,6 +266,7 @@ fun IntentMultiEventHomeScreen(
|
||||
rememberType,
|
||||
relay = rejectRelay,
|
||||
encryptedData = intentData.encryptedData,
|
||||
decryptTypeScope = decryptTypeScope,
|
||||
)
|
||||
permissionsChanged = true
|
||||
}
|
||||
@@ -359,13 +346,15 @@ fun IntentMultiEventHomeScreen(
|
||||
for (intentData in accountIntents) {
|
||||
val isChecked = MultiEventScreenIntents.checkedStates[intentData.id] ?: true
|
||||
val type = intentData.type
|
||||
val groupKey = requestGroupKey(type, intentData.event?.kind, intentData.encryptedData, intentData.nip44v3Kind)
|
||||
val rememberType = groupRememberTypes[groupKey] ?: RememberType.NEVER
|
||||
|
||||
if (type == SignerType.SIGN_EVENT) {
|
||||
val localEvent = intentData.event!!
|
||||
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val signRelay = if (localEvent.kind == 22242) {
|
||||
if (relayAuthScope == RelayAuthScope.ALL) {
|
||||
if ((groupRelayAuthScopes[groupKey] ?: RelayAuthScope.SPECIFIC) == RelayAuthScope.ALL) {
|
||||
"*"
|
||||
} else {
|
||||
RelayUrlUtils.extractHostAndPort(AmberEvent.relay(localEvent))
|
||||
@@ -420,14 +409,21 @@ fun IntentMultiEventHomeScreen(
|
||||
}
|
||||
} else {
|
||||
if (rememberType != RememberType.NEVER && isChecked) {
|
||||
val decryptTypeScope = groupDecryptScopes[groupKey] ?: defaultDecryptTypeScope(type)
|
||||
val permissionKind = if (type == SignerType.NIP44_V3_ENCRYPT || type == SignerType.NIP44_V3_DECRYPT) {
|
||||
if (decryptTypeScope == DecryptTypeScope.SPECIFIC) intentData.nip44v3Kind else null
|
||||
} else {
|
||||
null
|
||||
}
|
||||
AmberUtils.updatePermission(
|
||||
application,
|
||||
localKey,
|
||||
type,
|
||||
null,
|
||||
permissionKind,
|
||||
true,
|
||||
rememberType,
|
||||
encryptedData = intentData.encryptedData,
|
||||
decryptTypeScope = decryptTypeScope,
|
||||
)
|
||||
permissionsChanged = true
|
||||
}
|
||||
|
||||
@@ -59,6 +59,23 @@ fun LabeledBorderBox(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RememberMyChoiceToggles(
|
||||
selected: RememberType,
|
||||
onSelected: (RememberType) -> Unit,
|
||||
) {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.automatically_sign_this_for),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = selected,
|
||||
options = rememberTypeDisplayOrder,
|
||||
onSelected = onSelected,
|
||||
label = { stringResource(it.shortResourceId) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RememberMyChoice(
|
||||
shouldRunAcceptOrReject: Boolean?,
|
||||
@@ -79,19 +96,13 @@ fun RememberMyChoice(
|
||||
}
|
||||
}
|
||||
if (packageName != null || alwaysShow) {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.automatically_sign_this_for),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = selected,
|
||||
options = rememberTypeDisplayOrder,
|
||||
onSelected = {
|
||||
selected = it
|
||||
onChanged(it)
|
||||
},
|
||||
label = { stringResource(it.shortResourceId) },
|
||||
)
|
||||
}
|
||||
RememberMyChoiceToggles(
|
||||
selected = selected,
|
||||
onSelected = {
|
||||
selected = it
|
||||
onChanged(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
import android.content.Context
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -17,6 +18,7 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.state.ToggleableState
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
@@ -28,6 +30,7 @@ import com.greenart7c3.nostrsigner.models.PrivateZapEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.encryptDecryptSignerTypes
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
|
||||
enum class RequestPayloadShape {
|
||||
EVENT,
|
||||
@@ -109,6 +112,124 @@ fun RequestGroupKey.toLabel(context: Context): String {
|
||||
}
|
||||
}
|
||||
|
||||
enum class RequestGroupScopeKind {
|
||||
NONE,
|
||||
RELAY_AUTH,
|
||||
ENCRYPTION_METHOD,
|
||||
NIP44_V3_KIND,
|
||||
}
|
||||
|
||||
fun RequestGroupKey.scopeKind(): RequestGroupScopeKind = when {
|
||||
type == SignerType.SIGN_EVENT && kind == 22242 -> RequestGroupScopeKind.RELAY_AUTH
|
||||
type == SignerType.NIP44_V3_ENCRYPT || type == SignerType.NIP44_V3_DECRYPT -> RequestGroupScopeKind.NIP44_V3_KIND
|
||||
type in encryptDecryptSignerTypes && type != SignerType.DECRYPT_ZAP_EVENT -> RequestGroupScopeKind.ENCRYPTION_METHOD
|
||||
else -> RequestGroupScopeKind.NONE
|
||||
}
|
||||
|
||||
// Mirrors the single-event defaults: EncryptDecryptData defaults to ALL, Nip44v3ApprovalData to SPECIFIC
|
||||
fun defaultDecryptTypeScope(type: SignerType): DecryptTypeScope = if (type == SignerType.NIP44_V3_ENCRYPT || type == SignerType.NIP44_V3_DECRYPT) {
|
||||
DecryptTypeScope.SPECIFIC
|
||||
} else {
|
||||
DecryptTypeScope.ALL
|
||||
}
|
||||
|
||||
// CONNECT / GET_PUBLIC_KEY approvals never persist a permission from the grouped flow
|
||||
fun RequestGroupKey.hasGroupOptions(): Boolean = type != SignerType.CONNECT && type != SignerType.GET_PUBLIC_KEY
|
||||
|
||||
@Composable
|
||||
fun RequestGroupOptions(
|
||||
groupKey: RequestGroupKey,
|
||||
rememberType: RememberType,
|
||||
onRememberTypeChanged: (RememberType) -> Unit,
|
||||
relayAuthScope: RelayAuthScope,
|
||||
onRelayAuthScopeChanged: (RelayAuthScope) -> Unit,
|
||||
decryptTypeScope: DecryptTypeScope,
|
||||
onDecryptTypeScopeChanged: (DecryptTypeScope) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 4.dp, vertical = 4.dp),
|
||||
) {
|
||||
when (groupKey.scopeKind()) {
|
||||
RequestGroupScopeKind.RELAY_AUTH -> {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.relay_auth_scope),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = relayAuthScope,
|
||||
options = listOf(RelayAuthScope.SPECIFIC, RelayAuthScope.ALL),
|
||||
onSelected = onRelayAuthScopeChanged,
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
RelayAuthScope.SPECIFIC -> R.string.for_this_relay_only
|
||||
RelayAuthScope.ALL -> R.string.for_all_relays
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
RequestGroupScopeKind.ENCRYPTION_METHOD -> {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.encryption_scope),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = decryptTypeScope,
|
||||
options = listOf(DecryptTypeScope.SPECIFIC, DecryptTypeScope.ALL),
|
||||
onSelected = onDecryptTypeScopeChanged,
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
DecryptTypeScope.SPECIFIC -> R.string.for_this_method_only
|
||||
DecryptTypeScope.ALL -> R.string.for_all_methods
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
RequestGroupScopeKind.NIP44_V3_KIND -> {
|
||||
if (groupKey.kind != null) {
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.encryption_scope),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selected = decryptTypeScope,
|
||||
options = listOf(DecryptTypeScope.SPECIFIC, DecryptTypeScope.ALL),
|
||||
onSelected = onDecryptTypeScopeChanged,
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
DecryptTypeScope.SPECIFIC -> R.string.for_this_kind_only
|
||||
DecryptTypeScope.ALL -> R.string.for_all_kinds
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
RequestGroupScopeKind.NONE -> {}
|
||||
}
|
||||
|
||||
RememberMyChoiceToggles(
|
||||
selected = rememberType,
|
||||
onSelected = onRememberTypeChanged,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RequestGroupHeader(
|
||||
label: String,
|
||||
|
||||
@@ -99,6 +99,35 @@ class RequestGroupUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `scopeKind maps relay auth encryption and v3 groups`() {
|
||||
assertEquals(RequestGroupScopeKind.RELAY_AUTH, RequestGroupKey(SignerType.SIGN_EVENT, 22242, null).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.NONE, RequestGroupKey(SignerType.SIGN_EVENT, 1, null).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.ENCRYPTION_METHOD, RequestGroupKey(SignerType.NIP04_ENCRYPT, null, RequestPayloadShape.CLEAR_TEXT).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.ENCRYPTION_METHOD, RequestGroupKey(SignerType.NIP44_DECRYPT, 4, RequestPayloadShape.EVENT).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.NIP44_V3_KIND, RequestGroupKey(SignerType.NIP44_V3_ENCRYPT, 9, null).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.NIP44_V3_KIND, RequestGroupKey(SignerType.NIP44_V3_DECRYPT, null, null).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.NONE, RequestGroupKey(SignerType.DECRYPT_ZAP_EVENT, null, RequestPayloadShape.PRIVATE_ZAP).scopeKind())
|
||||
assertEquals(RequestGroupScopeKind.NONE, RequestGroupKey(SignerType.CONNECT, null, null).scopeKind())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `defaultDecryptTypeScope is SPECIFIC for v3 and ALL otherwise`() {
|
||||
assertEquals(DecryptTypeScope.SPECIFIC, defaultDecryptTypeScope(SignerType.NIP44_V3_ENCRYPT))
|
||||
assertEquals(DecryptTypeScope.SPECIFIC, defaultDecryptTypeScope(SignerType.NIP44_V3_DECRYPT))
|
||||
assertEquals(DecryptTypeScope.ALL, defaultDecryptTypeScope(SignerType.NIP04_DECRYPT))
|
||||
assertEquals(DecryptTypeScope.ALL, defaultDecryptTypeScope(SignerType.NIP44_ENCRYPT))
|
||||
assertEquals(DecryptTypeScope.ALL, defaultDecryptTypeScope(SignerType.DECRYPT_ZAP_EVENT))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `hasGroupOptions excludes connect and get public key`() {
|
||||
assertEquals(false, RequestGroupKey(SignerType.CONNECT, null, null).hasGroupOptions())
|
||||
assertEquals(false, RequestGroupKey(SignerType.GET_PUBLIC_KEY, null, null).hasGroupOptions())
|
||||
assertEquals(true, RequestGroupKey(SignerType.SIGN_EVENT, 1, null).hasGroupOptions())
|
||||
assertEquals(true, RequestGroupKey(SignerType.NIP44_DECRYPT, null, RequestPayloadShape.CLEAR_TEXT).hasGroupOptions())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `groupRequests preserves input order within a group`() {
|
||||
data class Item(val id: String, val kind: Int)
|
||||
|
||||
Reference in New Issue
Block a user