diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml index 5e4e4d9e..dfb70a90 100644 --- a/composeApp/src/commonMain/composeResources/values/strings.xml +++ b/composeApp/src/commonMain/composeResources/values/strings.xml @@ -478,6 +478,7 @@ %1$d of %2$d catalogs visible • %3$d hero sources selected Open a catalog only when you need to rename or reorder it. Visible + Hide value Player, subtitles, and auto-play Corner Radius Poster Card Style @@ -502,6 +503,7 @@ Dense Large Standard + Show value Show a popup to continue where you left off when opening the app after leaving from the player. Resume prompt on launch Poster Card Style diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/MdbListSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/MdbListSettingsPage.kt index 9787b732..3a7a2c40 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/MdbListSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/MdbListSettingsPage.kt @@ -6,11 +6,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.Row import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -19,7 +16,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import com.nuvio.app.features.mdblist.MdbListMetadataService import com.nuvio.app.features.mdblist.MdbListSettings @@ -170,22 +166,13 @@ private fun MdbListApiKeyRow( ) } - OutlinedTextField( + SettingsSecretTextField( value = draft, onValueChange = { draft = it }, modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(stringResource(Res.string.settings_mdb_api_key_label)) }, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.75f), - unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.42f), - focusedContainerColor = MaterialTheme.colorScheme.surface, - unfocusedContainerColor = MaterialTheme.colorScheme.surface, - disabledContainerColor = MaterialTheme.colorScheme.surface, - ), + label = stringResource(Res.string.settings_mdb_api_key_label), ) Row(modifier = Modifier.fillMaxWidth()) { diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt index 681383f3..40c2dfb6 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt @@ -1960,27 +1960,16 @@ private fun IntroDbApiKeyDialog( style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, ) - Surface( - shape = RoundedCornerShape(12.dp), - color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f), - border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline.copy(alpha = if (errorMessage != null) 1f else 0.3f)), - ) { - BasicTextField( - value = value, - onValueChange = { - value = it - errorMessage = null - }, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 14.dp, vertical = 12.dp), - textStyle = MaterialTheme.typography.bodyLarge.copy( - color = MaterialTheme.colorScheme.onSurface, - ), - cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), - singleLine = true, - ) - } + SettingsSecretTextField( + value = value, + onValueChange = { + value = it + errorMessage = null + }, + label = stringResource(Res.string.settings_playback_introdb_api_key), + modifier = Modifier.fillMaxWidth(), + isError = errorMessage != null, + ) if (errorMessage != null) { Text( text = errorMessage!!, @@ -2162,4 +2151,3 @@ private fun libassRenderTypeRes(renderType: String): StringResource = when (rend @Composable private fun libassRenderTypeLabel(renderType: String): String = stringResource(libassRenderTypeRes(renderType)) - diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSecretTextField.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSecretTextField.kt new file mode 100644 index 00000000..0620035f --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsSecretTextField.kt @@ -0,0 +1,69 @@ +package com.nuvio.app.features.settings + +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Visibility +import androidx.compose.material.icons.rounded.VisibilityOff +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import nuvio.composeapp.generated.resources.Res +import nuvio.composeapp.generated.resources.settings_hide_secret +import nuvio.composeapp.generated.resources.settings_show_secret +import org.jetbrains.compose.resources.stringResource + +@Composable +internal fun SettingsSecretTextField( + value: String, + onValueChange: (String) -> Unit, + label: String, + modifier: Modifier = Modifier, + isError: Boolean = false, +) { + var visible by rememberSaveable { mutableStateOf(false) } + + OutlinedTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + isError = isError, + singleLine = true, + label = { Text(label) }, + visualTransformation = if (visible) { + VisualTransformation.None + } else { + PasswordVisualTransformation() + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password), + trailingIcon = { + IconButton(onClick = { visible = !visible }) { + Icon( + imageVector = if (visible) Icons.Rounded.VisibilityOff else Icons.Rounded.Visibility, + contentDescription = stringResource( + if (visible) Res.string.settings_hide_secret else Res.string.settings_show_secret, + ), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + }, + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.75f), + unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.42f), + focusedContainerColor = MaterialTheme.colorScheme.surface, + unfocusedContainerColor = MaterialTheme.colorScheme.surface, + disabledContainerColor = MaterialTheme.colorScheme.surface, + ), + ) +} diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TmdbSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TmdbSettingsPage.kt index 8e1c330f..ed2fbe31 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TmdbSettingsPage.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/TmdbSettingsPage.kt @@ -265,21 +265,13 @@ private fun TmdbApiKeyRow( val normalizedDraft = draft.trim() - OutlinedTextField( + SettingsSecretTextField( value = draft, onValueChange = { draft = it }, modifier = Modifier.fillMaxWidth(), - singleLine = true, - label = { Text(stringResource(Res.string.settings_tmdb_api_key_label)) }, - colors = OutlinedTextFieldDefaults.colors( - focusedBorderColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.75f), - unfocusedBorderColor = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.42f), - focusedContainerColor = MaterialTheme.colorScheme.surface, - unfocusedContainerColor = MaterialTheme.colorScheme.surface, - disabledContainerColor = MaterialTheme.colorScheme.surface, - ), + label = stringResource(Res.string.settings_tmdb_api_key_label), ) Row(modifier = Modifier.fillMaxWidth()) {