summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt54
1 files changed, 51 insertions, 3 deletions
diff --git a/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt b/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt
index b7897f4..3bd6e3e 100644
--- a/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt
+++ b/app/src/main/java/org/terst/feedreader/ui/SettingsScreen.kt
@@ -13,7 +13,10 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Delete
+import androidx.compose.material.icons.filled.Visibility
+import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.Button
+import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -36,12 +39,17 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import org.terst.feedreader.data.AppDatabase
import org.terst.feedreader.data.FilterAction
import org.terst.feedreader.data.FilterRuleEntity
+import org.terst.feedreader.data.Net
import org.terst.feedreader.data.Settings
+import org.terst.feedreader.stash.StashClient
+import org.terst.feedreader.stash.StashVerifyResult
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -53,6 +61,9 @@ fun SettingsScreen(onBack: () -> Unit) {
var stashUrl by remember { mutableStateOf("") }
var stashKey by remember { mutableStateOf("") }
+ var stashKeyVisible by remember { mutableStateOf(false) }
+ var isVerifyingStash by remember { mutableStateOf(false) }
+ var stashStatus by remember { mutableStateOf<String?>(null) }
LaunchedEffect(Unit) {
stashUrl = settings.stashBaseUrlNow()
stashKey = settings.stashApiKeyNow()
@@ -105,15 +116,52 @@ fun SettingsScreen(onBack: () -> Unit) {
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = stashKey,
- onValueChange = { stashKey = it },
+ onValueChange = { stashKey = it; stashStatus = null },
label = { Text("API key") },
+ singleLine = true,
+ visualTransformation = if (stashKeyVisible) VisualTransformation.None else PasswordVisualTransformation(),
+ trailingIcon = {
+ IconButton(onClick = { stashKeyVisible = !stashKeyVisible }) {
+ Icon(
+ if (stashKeyVisible) Icons.Default.VisibilityOff else Icons.Default.Visibility,
+ contentDescription = if (stashKeyVisible) "Hide API key" else "Show API key"
+ )
+ }
+ },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
Button(
- onClick = { scope.launch { settings.setStash(stashUrl, stashKey) } },
+ enabled = !isVerifyingStash,
+ onClick = {
+ scope.launch {
+ isVerifyingStash = true
+ stashStatus = null
+ val client = StashClient(Net.client, stashUrl.trim(), stashKey.trim())
+ when (val result = client.verifyCredentials()) {
+ is StashVerifyResult.Valid -> {
+ settings.setStash(stashUrl.trim(), stashKey.trim())
+ stashStatus = "Verified and saved"
+ }
+ is StashVerifyResult.Invalid -> {
+ stashStatus = result.message
+ }
+ }
+ isVerifyingStash = false
+ }
+ },
modifier = Modifier.fillMaxWidth()
- ) { Text("Save") }
+ ) {
+ if (isVerifyingStash) {
+ CircularProgressIndicator(modifier = Modifier.height(20.dp).width(20.dp))
+ } else {
+ Text("Verify and save")
+ }
+ }
+ stashStatus?.let {
+ Spacer(modifier = Modifier.height(8.dp))
+ Text(it, style = MaterialTheme.typography.bodySmall)
+ }
}
HorizontalDivider()
}