mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Merge pull request #433 from greenart7c3/claude/remember-choice-bottom-sheet-k3o94
Replace toggle UI with bottom sheet picker for better UX
This commit is contained in:
@@ -94,6 +94,9 @@ object AmberUtils {
|
||||
RememberType.ONE_MINUTE -> TimeUtils.oneMinuteFromNow()
|
||||
RememberType.FIVE_MINUTES -> TimeUtils.now() + TimeUtils.FIVE_MINUTES
|
||||
RememberType.TEN_MINUTES -> TimeUtils.now() + TimeUtils.FIFTEEN_MINUTES
|
||||
RememberType.ONE_HOUR -> TimeUtils.now() + 3600
|
||||
RememberType.ONE_DAY -> TimeUtils.now() + 86400
|
||||
RememberType.ONE_WEEK -> TimeUtils.now() + 604800
|
||||
RememberType.NEVER -> 0L
|
||||
}
|
||||
|
||||
@@ -240,6 +243,9 @@ object AmberUtils {
|
||||
RememberType.ONE_MINUTE -> TimeUtils.oneMinuteFromNow()
|
||||
RememberType.FIVE_MINUTES -> TimeUtils.now() + TimeUtils.FIVE_MINUTES
|
||||
RememberType.TEN_MINUTES -> TimeUtils.now() + TimeUtils.FIFTEEN_MINUTES
|
||||
RememberType.ONE_HOUR -> TimeUtils.now() + 3600
|
||||
RememberType.ONE_DAY -> TimeUtils.now() + 86400
|
||||
RememberType.ONE_WEEK -> TimeUtils.now() + 604800
|
||||
else -> 0L
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
@@ -52,8 +51,8 @@ import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.ui.actions.RemoveAllPermissionsDialog
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberButton
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberToggles
|
||||
import com.greenart7c3.nostrsigner.ui.components.ToggleOption
|
||||
import com.greenart7c3.nostrsigner.ui.components.LabeledBorderBox
|
||||
import com.greenart7c3.nostrsigner.ui.components.OptionBottomSheetPicker
|
||||
import com.greenart7c3.nostrsigner.ui.components.TrustScoreBadge
|
||||
import com.greenart7c3.nostrsigner.ui.theme.orange
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -240,29 +239,15 @@ fun EditPermission(
|
||||
}
|
||||
}
|
||||
|
||||
fun rememberTypeIndexToRememberType(rememberTypeIndex: Int): RememberType = when (rememberTypeIndex) {
|
||||
0 -> RememberType.ALWAYS
|
||||
1 -> RememberType.ONE_MINUTE
|
||||
2 -> RememberType.FIVE_MINUTES
|
||||
3 -> RememberType.TEN_MINUTES
|
||||
else -> RememberType.NEVER
|
||||
}
|
||||
|
||||
fun rememberTypeToIndex(rememberType: RememberType): Int = when (rememberType) {
|
||||
RememberType.ALWAYS -> 0
|
||||
RememberType.ONE_MINUTE -> 1
|
||||
RememberType.FIVE_MINUTES -> 2
|
||||
RememberType.TEN_MINUTES -> 3
|
||||
else -> 0
|
||||
}
|
||||
|
||||
fun onSetPermission(optionIndex: Int, rememberTypeIndex: Int, permission: ApplicationPermissionsEntity, onToggle: (ApplicationPermissionsEntity) -> Unit) {
|
||||
val rememberType = rememberTypeIndexToRememberType(rememberTypeIndex)
|
||||
fun onSetPermission(optionIndex: Int, rememberType: RememberType, permission: ApplicationPermissionsEntity, onToggle: (ApplicationPermissionsEntity) -> Unit) {
|
||||
val time = when (rememberType) {
|
||||
RememberType.ALWAYS -> Long.MAX_VALUE / 1000
|
||||
RememberType.ONE_MINUTE -> TimeUtils.oneMinuteFromNow()
|
||||
RememberType.FIVE_MINUTES -> TimeUtils.now() + TimeUtils.FIVE_MINUTES
|
||||
RememberType.TEN_MINUTES -> TimeUtils.now() + TimeUtils.FIFTEEN_MINUTES
|
||||
RememberType.ONE_HOUR -> TimeUtils.now() + 3600
|
||||
RememberType.ONE_DAY -> TimeUtils.now() + 86400
|
||||
RememberType.ONE_WEEK -> TimeUtils.now() + 604800
|
||||
RememberType.NEVER -> 0L
|
||||
}
|
||||
val isAcceptable = optionIndex == 0 || optionIndex == 2
|
||||
@@ -284,7 +269,7 @@ fun onSetPermission(optionIndex: Int, rememberTypeIndex: Int, permission: Applic
|
||||
} else {
|
||||
0L
|
||||
},
|
||||
rememberType = rememberTypeIndexToRememberType(rememberTypeIndex).screenCode,
|
||||
rememberType = rememberType.screenCode,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -311,8 +296,6 @@ fun PermissionRow(
|
||||
localPermission.toLocalizedString(context)
|
||||
}
|
||||
}
|
||||
val fixedSegmentWidth = 55.dp
|
||||
|
||||
var optionIndex by remember {
|
||||
if (permission.acceptUntil > 0) {
|
||||
mutableIntStateOf(0)
|
||||
@@ -322,8 +305,12 @@ fun PermissionRow(
|
||||
mutableIntStateOf(2)
|
||||
}
|
||||
}
|
||||
var rememberTypeIndex by remember {
|
||||
mutableIntStateOf(rememberTypeToIndex(parseRememberType(permission.rememberType)))
|
||||
var rememberType by remember {
|
||||
mutableStateOf(
|
||||
parseRememberType(permission.rememberType).let {
|
||||
if (it == RememberType.NEVER) RememberType.ALWAYS else it
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
@@ -362,121 +349,62 @@ fun PermissionRow(
|
||||
)
|
||||
}
|
||||
|
||||
AmberToggles(
|
||||
count = 3,
|
||||
selectedIndex = optionIndex,
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.action),
|
||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp),
|
||||
) {
|
||||
ToggleOption(
|
||||
text = "Allow",
|
||||
isSelected = optionIndex == 0,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
optionIndex = 0
|
||||
|
||||
OptionBottomSheetPicker(
|
||||
selected = optionIndex,
|
||||
options = listOf(0, 1, 2),
|
||||
onSelected = { newIndex ->
|
||||
optionIndex = newIndex
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
rememberType,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "Deny",
|
||||
isSelected = optionIndex == 1,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
optionIndex = 1
|
||||
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "Ask",
|
||||
isSelected = optionIndex == 2,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
optionIndex = 2
|
||||
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
0 -> R.string.allow
|
||||
1 -> R.string.deny
|
||||
else -> R.string.ask
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if (optionIndex != 2) {
|
||||
AmberToggles(
|
||||
selectedIndex = rememberTypeIndex,
|
||||
count = 4,
|
||||
content = {
|
||||
ToggleOption(
|
||||
text = "Always",
|
||||
isSelected = rememberTypeIndex == 0,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
rememberTypeIndex = 0
|
||||
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "1m",
|
||||
isSelected = rememberTypeIndex == 1,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
rememberTypeIndex = 1
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "5m",
|
||||
isSelected = rememberTypeIndex == 2,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
rememberTypeIndex = 2
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "10m",
|
||||
isSelected = rememberTypeIndex == 3,
|
||||
modifier = Modifier.width(fixedSegmentWidth),
|
||||
onClick = {
|
||||
rememberTypeIndex = 3
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberTypeIndex,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.automatically_sign_this_for),
|
||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp),
|
||||
) {
|
||||
OptionBottomSheetPicker(
|
||||
selected = rememberType,
|
||||
options = listOf(
|
||||
RememberType.ONE_MINUTE,
|
||||
RememberType.FIVE_MINUTES,
|
||||
RememberType.TEN_MINUTES,
|
||||
RememberType.ONE_HOUR,
|
||||
RememberType.ONE_DAY,
|
||||
RememberType.ONE_WEEK,
|
||||
RememberType.ALWAYS,
|
||||
),
|
||||
onSelected = { newType ->
|
||||
rememberType = newType
|
||||
onSetPermission(
|
||||
optionIndex,
|
||||
rememberType,
|
||||
permission,
|
||||
onToggle,
|
||||
)
|
||||
},
|
||||
label = { stringResource(it.resourceId) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,13 +480,30 @@ enum class RememberType(val screenCode: Int, val resourceId: Int) {
|
||||
FIVE_MINUTES(2, R.string.five_minutes),
|
||||
TEN_MINUTES(3, R.string.ten_minutes),
|
||||
ALWAYS(4, R.string.always),
|
||||
ONE_HOUR(5, R.string.one_hour),
|
||||
ONE_DAY(6, R.string.one_day),
|
||||
ONE_WEEK(7, R.string.one_week),
|
||||
}
|
||||
|
||||
val rememberTypeDisplayOrder: List<RememberType> = listOf(
|
||||
RememberType.NEVER,
|
||||
RememberType.ONE_MINUTE,
|
||||
RememberType.FIVE_MINUTES,
|
||||
RememberType.TEN_MINUTES,
|
||||
RememberType.ONE_HOUR,
|
||||
RememberType.ONE_DAY,
|
||||
RememberType.ONE_WEEK,
|
||||
RememberType.ALWAYS,
|
||||
)
|
||||
|
||||
fun parseRememberType(screenCode: Int): RememberType = when (screenCode) {
|
||||
0 -> RememberType.NEVER
|
||||
1 -> RememberType.ONE_MINUTE
|
||||
2 -> RememberType.FIVE_MINUTES
|
||||
3 -> RememberType.TEN_MINUTES
|
||||
RememberType.NEVER.screenCode -> RememberType.NEVER
|
||||
RememberType.ONE_MINUTE.screenCode -> RememberType.ONE_MINUTE
|
||||
RememberType.FIVE_MINUTES.screenCode -> RememberType.FIVE_MINUTES
|
||||
RememberType.TEN_MINUTES.screenCode -> RememberType.TEN_MINUTES
|
||||
RememberType.ONE_HOUR.screenCode -> RememberType.ONE_HOUR
|
||||
RememberType.ONE_DAY.screenCode -> RememberType.ONE_DAY
|
||||
RememberType.ONE_WEEK.screenCode -> RememberType.ONE_WEEK
|
||||
else -> RememberType.ALWAYS
|
||||
}
|
||||
|
||||
|
||||
+13
-19
@@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
@@ -170,24 +169,19 @@ fun BunkerMultiEventHomeScreen(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = if (relayAuthScope == RelayAuthScope.SPECIFIC) 0 else 1,
|
||||
count = 2,
|
||||
segmentWidth = 120.dp,
|
||||
) {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_this_relay_only),
|
||||
isSelected = relayAuthScope == RelayAuthScope.SPECIFIC,
|
||||
onClick = { relayAuthScope = RelayAuthScope.SPECIFIC },
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_all_relays),
|
||||
isSelected = relayAuthScope == RelayAuthScope.ALL,
|
||||
onClick = { relayAuthScope = RelayAuthScope.ALL },
|
||||
)
|
||||
}
|
||||
OptionBottomSheetPicker(
|
||||
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
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-19
@@ -6,12 +6,10 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
@@ -52,7 +50,6 @@ fun BunkerRelayAuthScreen(
|
||||
) {
|
||||
var rememberType by remember { mutableStateOf(RememberType.NEVER) }
|
||||
var scope by remember { mutableStateOf(defaultScope) }
|
||||
val scopeIndex by remember(scope) { mutableIntStateOf(if (scope == RelayAuthScope.SPECIFIC) 0 else 1) }
|
||||
|
||||
if (shouldAcceptOrReject != null) {
|
||||
LaunchedEffect(Unit) {
|
||||
@@ -109,22 +106,16 @@ fun BunkerRelayAuthScreen(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = scopeIndex,
|
||||
count = 2,
|
||||
segmentWidth = 120.dp,
|
||||
content = {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_this_relay_only),
|
||||
isSelected = scope == RelayAuthScope.SPECIFIC,
|
||||
onClick = { scope = RelayAuthScope.SPECIFIC },
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_all_relays),
|
||||
isSelected = scope == RelayAuthScope.ALL,
|
||||
onClick = { scope = RelayAuthScope.ALL },
|
||||
OptionBottomSheetPicker(
|
||||
selected = scope,
|
||||
options = listOf(RelayAuthScope.SPECIFIC, RelayAuthScope.ALL),
|
||||
onSelected = { scope = it },
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
RelayAuthScope.SPECIFIC -> R.string.for_this_relay_only
|
||||
RelayAuthScope.ALL -> R.string.for_all_relays
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -5,14 +5,12 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
@@ -55,7 +53,6 @@ fun EncryptDecryptData(
|
||||
mutableStateOf(RememberType.NEVER)
|
||||
}
|
||||
var scope by remember { mutableStateOf(defaultScope) }
|
||||
val scopeIndex by remember(scope) { mutableIntStateOf(if (scope == DecryptTypeScope.SPECIFIC) 0 else 1) }
|
||||
val showScopeToggle = type != SignerType.DECRYPT_ZAP_EVENT
|
||||
|
||||
Column(
|
||||
@@ -199,22 +196,16 @@ fun EncryptDecryptData(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = scopeIndex,
|
||||
count = 2,
|
||||
segmentWidth = 120.dp,
|
||||
content = {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_this_method_only),
|
||||
isSelected = scope == DecryptTypeScope.SPECIFIC,
|
||||
onClick = { scope = DecryptTypeScope.SPECIFIC },
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_all_methods),
|
||||
isSelected = scope == DecryptTypeScope.ALL,
|
||||
onClick = { scope = DecryptTypeScope.ALL },
|
||||
OptionBottomSheetPicker(
|
||||
selected = scope,
|
||||
options = listOf(DecryptTypeScope.SPECIFIC, DecryptTypeScope.ALL),
|
||||
onSelected = { scope = it },
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
DecryptTypeScope.SPECIFIC -> R.string.for_this_method_only
|
||||
DecryptTypeScope.ALL -> R.string.for_all_methods
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -274,7 +265,6 @@ fun BunkerEncryptDecryptData(
|
||||
mutableStateOf(RememberType.NEVER)
|
||||
}
|
||||
var scope by remember { mutableStateOf(defaultScope) }
|
||||
val scopeIndex by remember(scope) { mutableIntStateOf(if (scope == DecryptTypeScope.SPECIFIC) 0 else 1) }
|
||||
val showScopeToggle = type != SignerType.DECRYPT_ZAP_EVENT
|
||||
|
||||
Column(
|
||||
@@ -409,22 +399,16 @@ fun BunkerEncryptDecryptData(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = scopeIndex,
|
||||
count = 2,
|
||||
segmentWidth = 120.dp,
|
||||
content = {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_this_method_only),
|
||||
isSelected = scope == DecryptTypeScope.SPECIFIC,
|
||||
onClick = { scope = DecryptTypeScope.SPECIFIC },
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_all_methods),
|
||||
isSelected = scope == DecryptTypeScope.ALL,
|
||||
onClick = { scope = DecryptTypeScope.ALL },
|
||||
OptionBottomSheetPicker(
|
||||
selected = scope,
|
||||
options = listOf(DecryptTypeScope.SPECIFIC, DecryptTypeScope.ALL),
|
||||
onSelected = { scope = it },
|
||||
label = {
|
||||
stringResource(
|
||||
when (it) {
|
||||
DecryptTypeScope.SPECIFIC -> R.string.for_this_method_only
|
||||
DecryptTypeScope.ALL -> R.string.for_all_methods
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
+13
-19
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
@@ -145,24 +144,19 @@ fun IntentMultiEventHomeScreen(
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 4.dp, vertical = 8.dp),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = if (relayAuthScope == RelayAuthScope.SPECIFIC) 0 else 1,
|
||||
count = 2,
|
||||
segmentWidth = 120.dp,
|
||||
) {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_this_relay_only),
|
||||
isSelected = relayAuthScope == RelayAuthScope.SPECIFIC,
|
||||
onClick = { relayAuthScope = RelayAuthScope.SPECIFIC },
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(120.dp),
|
||||
text = stringResource(R.string.for_all_relays),
|
||||
isSelected = relayAuthScope == RelayAuthScope.ALL,
|
||||
onClick = { relayAuthScope = RelayAuthScope.ALL },
|
||||
)
|
||||
}
|
||||
OptionBottomSheetPicker(
|
||||
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
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.ExpandMore
|
||||
import androidx.compose.material3.BottomSheetDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun <T> OptionBottomSheetPicker(
|
||||
selected: T,
|
||||
options: List<T>,
|
||||
onSelected: (T) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
label: @Composable (T) -> String,
|
||||
) {
|
||||
var showSheet by remember { mutableStateOf(false) }
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { showSheet = true }
|
||||
.padding(horizontal = 12.dp, vertical = 14.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = label(selected),
|
||||
modifier = Modifier.weight(1f),
|
||||
fontSize = 16.sp,
|
||||
)
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ExpandMore,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
if (showSheet) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showSheet = false },
|
||||
sheetState = sheetState,
|
||||
dragHandle = { BottomSheetDefaults.DragHandle() },
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
) {
|
||||
options.forEach { option ->
|
||||
val isSelected = option == selected
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
onSelected(option)
|
||||
scope.launch { sheetState.hide() }.invokeOnCompletion {
|
||||
if (!sheetState.isVisible) showSheet = false
|
||||
}
|
||||
}
|
||||
.padding(horizontal = 24.dp, vertical = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(
|
||||
text = label(option),
|
||||
fontSize = 16.sp,
|
||||
fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
if (isSelected) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Check,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
} else {
|
||||
Spacer(Modifier.size(24.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,13 @@ import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -23,6 +22,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.greenart7c3.nostrsigner.ui.rememberTypeDisplayOrder
|
||||
|
||||
@Composable
|
||||
fun LabeledBorderBox(
|
||||
@@ -66,15 +66,13 @@ fun RememberMyChoice(
|
||||
onReject: (RememberType) -> Unit,
|
||||
onChanged: (RememberType) -> Unit,
|
||||
) {
|
||||
var index by remember {
|
||||
mutableIntStateOf(0)
|
||||
}
|
||||
var selected by remember { mutableStateOf(RememberType.NEVER) }
|
||||
if (shouldRunAcceptOrReject != null) {
|
||||
LaunchedEffect(Unit) {
|
||||
if (shouldRunAcceptOrReject) {
|
||||
onAccept(RememberType.entries[index])
|
||||
onAccept(selected)
|
||||
} else {
|
||||
onReject(RememberType.entries[index])
|
||||
onReject(selected)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,56 +80,14 @@ fun RememberMyChoice(
|
||||
LabeledBorderBox(
|
||||
label = stringResource(R.string.automatically_sign_this_for),
|
||||
) {
|
||||
AmberToggles(
|
||||
selectedIndex = index,
|
||||
count = 5,
|
||||
content = {
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(55.dp),
|
||||
text = stringResource(RememberType.NEVER.resourceId),
|
||||
isSelected = RememberType.NEVER == RememberType.entries[index],
|
||||
onClick = {
|
||||
index = RememberType.NEVER.screenCode
|
||||
onChanged(RememberType.NEVER)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(55.dp),
|
||||
text = stringResource(R.string.one_minute_short),
|
||||
isSelected = RememberType.ONE_MINUTE == RememberType.entries[index],
|
||||
onClick = {
|
||||
index = RememberType.ONE_MINUTE.screenCode
|
||||
onChanged(RememberType.ONE_MINUTE)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(55.dp),
|
||||
text = stringResource(R.string.five_minutes_short),
|
||||
isSelected = RememberType.FIVE_MINUTES == RememberType.entries[index],
|
||||
onClick = {
|
||||
index = RememberType.FIVE_MINUTES.screenCode
|
||||
onChanged(RememberType.FIVE_MINUTES)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(55.dp),
|
||||
text = stringResource(R.string.ten_minutes_short),
|
||||
isSelected = RememberType.TEN_MINUTES == RememberType.entries[index],
|
||||
onClick = {
|
||||
index = RememberType.TEN_MINUTES.screenCode
|
||||
onChanged(RememberType.TEN_MINUTES)
|
||||
},
|
||||
)
|
||||
ToggleOption(
|
||||
modifier = Modifier.width(55.dp),
|
||||
text = stringResource(RememberType.ALWAYS.resourceId),
|
||||
isSelected = RememberType.ALWAYS == RememberType.entries[index],
|
||||
onClick = {
|
||||
index = RememberType.ALWAYS.screenCode
|
||||
onChanged(RememberType.entries[RememberType.ALWAYS.screenCode])
|
||||
},
|
||||
)
|
||||
OptionBottomSheetPicker(
|
||||
selected = selected,
|
||||
options = rememberTypeDisplayOrder,
|
||||
onSelected = {
|
||||
selected = it
|
||||
onChanged(it)
|
||||
},
|
||||
label = { stringResource(it.resourceId) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,9 +226,6 @@
|
||||
<string name="one_minute">One minute</string>
|
||||
<string name="five_minutes">Five minutes</string>
|
||||
<string name="ten_minutes">Ten Minutes</string>
|
||||
<string name="one_minute_short">1m</string>
|
||||
<string name="five_minutes_short">5m</string>
|
||||
<string name="ten_minutes_short">10m</string>
|
||||
<string name="event_kind_9000">Add user to group</string>
|
||||
<string name="event_kind_9001">Remove user from group</string>
|
||||
<string name="event_kind_9002">Edit group metadata</string>
|
||||
@@ -430,6 +427,7 @@
|
||||
<string name="notifications_are_needed_to_use_amber_as_a_nsec_bunker">Notifications are needed to use Amber as a nsec bunker.</string>
|
||||
<string name="allow">Allow</string>
|
||||
<string name="deny">Deny</string>
|
||||
<string name="ask">Ask</string>
|
||||
<string name="never">Never</string>
|
||||
<string name="warning">Warning</string>
|
||||
<string name="of_events">%1$s of %2$s events</string>
|
||||
@@ -529,6 +527,7 @@
|
||||
<string name="event_kind_39092">Media starter packs</string>
|
||||
<string name="event_kind_10020">Media follows</string>
|
||||
<string name="automatically_sign_this_for">Automatically sign this for</string>
|
||||
<string name="action">Action</string>
|
||||
<string name="always">Always</string>
|
||||
<string name="proxy_is_connected">Proxy is connected</string>
|
||||
<string name="proxy_is_not_working">Proxy is not working. Check your proxy settings/application.</string>
|
||||
|
||||
Reference in New Issue
Block a user