Merge pull request #334 from greenart7c3/claude/improve-relay-ui-V8KKM

Replace button with inline icons in relay input fields
This commit is contained in:
greenart7c3
2026-03-16 16:35:21 -03:00
committed by GitHub
3 changed files with 141 additions and 63 deletions
@@ -8,6 +8,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ContentPaste
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
@@ -20,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
@@ -33,7 +40,6 @@ import com.greenart7c3.nostrsigner.R
import com.greenart7c3.nostrsigner.models.Account
import com.greenart7c3.nostrsigner.service.TrustScoreService
import com.greenart7c3.nostrsigner.ui.actions.onAddRelay
import com.greenart7c3.nostrsigner.ui.components.AmberButton
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -44,6 +50,7 @@ fun DefaultProfileRelaysScreen(
) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
val clipboardManager = LocalClipboard.current
val textFieldRelay = remember {
mutableStateOf(TextFieldValue(""))
}
@@ -137,42 +144,64 @@ fun DefaultProfileRelaysScreen(
},
),
label = {
Text("Relay")
Text(stringResource(R.string.wss))
},
)
AmberButton(
modifier = Modifier
.fillMaxWidth(),
onClick = {
scope.launch(Dispatchers.IO) {
onAddRelay(
textFieldRelay,
isLoading,
relays2,
scope,
account,
context,
shouldCheckForBunker = false,
onDone = {
isLoading.value = true
Amber.instance.settings = Amber.instance.settings.copy(
defaultProfileRelays = relays2,
)
LocalPreferences.saveSettingsToEncryptedStorage(Amber.instance.settings)
scope.launch(Dispatchers.IO) {
if (!BuildFlavorChecker.isOfflineFlavor()) {
Amber.instance.checkForNewRelaysAndUpdateAllFilters()
isLoading.value = false
} else {
isLoading.value = false
}
leadingIcon = {
IconButton(
onClick = {
scope.launch {
val text = clipboardManager.getClipEntry()?.clipData?.getItemAt(0)?.text?.toString()
if (!text.isNullOrBlank()) {
textFieldRelay.value = TextFieldValue(text)
}
},
}
},
) {
Icon(
Icons.Default.ContentPaste,
contentDescription = stringResource(R.string.paste_from_clipboard),
)
}
},
trailingIcon = {
IconButton(
colors = IconButtonDefaults.iconButtonColors().copy(
containerColor = MaterialTheme.colorScheme.primary,
),
onClick = {
scope.launch(Dispatchers.IO) {
onAddRelay(
textFieldRelay,
isLoading,
relays2,
scope,
account,
context,
shouldCheckForBunker = false,
onDone = {
Amber.instance.settings = Amber.instance.settings.copy(
defaultProfileRelays = relays2,
)
LocalPreferences.saveSettingsToEncryptedStorage(Amber.instance.settings)
scope.launch(Dispatchers.IO) {
if (!BuildFlavorChecker.isOfflineFlavor()) {
Amber.instance.checkForNewRelaysAndUpdateAllFilters()
isLoading.value = false
} else {
isLoading.value = false
}
}
},
)
}
},
) {
Icon(
Icons.Default.Add,
contentDescription = stringResource(R.string.add),
)
}
},
text = stringResource(R.string.add),
)
LazyColumn(
@@ -14,6 +14,7 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ContentPaste
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
@@ -68,6 +69,7 @@ fun NewNsecBunkerScreen(
val secret = remember { mutableStateOf(UUID.randomUUID().toString()) }
var name by remember { mutableStateOf(TextFieldValue(AnnotatedString(""))) }
val context = LocalContext.current
val clipboardManager = LocalClipboard.current
val relays =
remember {
@@ -99,7 +101,7 @@ fun NewNsecBunkerScreen(
if (isLoading.value) {
CenterCircularProgressIndicator(
modifier = Modifier,
text = "Testing the relay...",
text = stringResource(R.string.testing_relay),
)
} else {
Column(
@@ -173,6 +175,23 @@ fun NewNsecBunkerScreen(
label = {
Text(stringResource(R.string.wss))
},
leadingIcon = {
IconButton(
onClick = {
scope.launch {
val text = clipboardManager.getClipEntry()?.clipData?.getItemAt(0)?.text?.toString()
if (!text.isNullOrBlank()) {
textFieldRelay.value = TextFieldValue(text)
}
}
},
) {
Icon(
Icons.Default.ContentPaste,
contentDescription = stringResource(R.string.paste_from_clipboard),
)
}
},
trailingIcon = {
IconButton(
colors = IconButtonDefaults.iconButtonColors().copy(
@@ -16,7 +16,13 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ContentPaste
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
@@ -34,6 +40,7 @@ import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
@@ -96,6 +103,7 @@ fun DefaultRelaysScreen(
) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
val clipboardManager = LocalClipboard.current
val textFieldRelay = remember { mutableStateOf(TextFieldValue("")) }
val isLoading = remember { mutableStateOf(false) }
val relays2 = remember { mutableStateListOf(*Amber.instance.settings.defaultRelays.toTypedArray()) }
@@ -207,41 +215,63 @@ fun DefaultRelaysScreen(
},
),
label = {
Text("Relay")
Text(stringResource(R.string.wss))
},
)
AmberButton(
modifier = Modifier
.fillMaxWidth(),
onClick = {
scope.launch(Dispatchers.IO) {
onAddRelay(
textFieldRelay,
isLoading,
relays2,
scope,
account,
context,
onDone = {
isLoading.value = true
Amber.instance.settings = Amber.instance.settings.copy(
defaultRelays = relays2,
)
LocalPreferences.saveSettingsToEncryptedStorage(Amber.instance.settings)
scope.launch(Dispatchers.IO) {
if (!BuildFlavorChecker.isOfflineFlavor()) {
Amber.instance.checkForNewRelaysAndUpdateAllFilters()
isLoading.value = false
} else {
isLoading.value = false
}
leadingIcon = {
IconButton(
onClick = {
scope.launch {
val text = clipboardManager.getClipEntry()?.clipData?.getItemAt(0)?.text?.toString()
if (!text.isNullOrBlank()) {
textFieldRelay.value = TextFieldValue(text)
}
},
}
},
) {
Icon(
Icons.Default.ContentPaste,
contentDescription = stringResource(R.string.paste_from_clipboard),
)
}
},
trailingIcon = {
IconButton(
colors = IconButtonDefaults.iconButtonColors().copy(
containerColor = MaterialTheme.colorScheme.primary,
),
onClick = {
scope.launch(Dispatchers.IO) {
onAddRelay(
textFieldRelay,
isLoading,
relays2,
scope,
account,
context,
onDone = {
Amber.instance.settings = Amber.instance.settings.copy(
defaultRelays = relays2,
)
LocalPreferences.saveSettingsToEncryptedStorage(Amber.instance.settings)
scope.launch(Dispatchers.IO) {
if (!BuildFlavorChecker.isOfflineFlavor()) {
Amber.instance.checkForNewRelaysAndUpdateAllFilters()
isLoading.value = false
} else {
isLoading.value = false
}
}
},
)
}
},
) {
Icon(
Icons.Default.Add,
contentDescription = stringResource(R.string.add),
)
}
},
text = stringResource(R.string.add),
)
LazyColumn(