From 5eaceba518052424fcce8752cb4b80ff250f706f Mon Sep 17 00:00:00 2001 From: Himanth Reddy Date: Sun, 29 Mar 2026 11:28:48 +0530 Subject: [PATCH 1/3] Fix settings modal touch focus handling --- .../tv/ui/screens/settings/SettingsScreen.kt | 903 ++++++++++-------- 1 file changed, 481 insertions(+), 422 deletions(-) diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt index 12edd16f7..055bc2ea1 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.focusable import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState @@ -19,6 +20,7 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -293,6 +295,21 @@ fun SettingsScreen( } } + val hasBlockingModal = + showCustomAddonInput || + showIptvInput || + showStalkerInput || + showCatalogInput || + showCatalogRename || + showSubtitlePicker || + showAudioLanguagePicker || + showDnsProviderPicker || + showContentLanguagePicker || + uiState.showCloudPairDialog || + uiState.showCloudEmailPasswordDialog || + uiState.showAppUpdateDialog || + uiState.showUnknownSourcesDialog + Box( modifier = Modifier .fillMaxSize() @@ -301,8 +318,7 @@ fun SettingsScreen( .focusable() .onPreviewKeyEvent { event -> if (isTouchDevice) return@onPreviewKeyEvent false - // BLOCKER FIX: Ignore main screen navigation if modals are open - if (showCustomAddonInput || showSubtitlePicker || showAudioLanguagePicker || showDnsProviderPicker || showContentLanguagePicker || showIptvInput || showCatalogInput || uiState.showCloudPairDialog || uiState.showCloudEmailPasswordDialog) return@onPreviewKeyEvent false + if (hasBlockingModal) return@onPreviewKeyEvent false if (event.type == KeyEventType.KeyDown) { val currentSection = sections.getOrNull(sectionIndex).orEmpty() @@ -1117,6 +1133,36 @@ fun SettingsScreen( } } +@Composable +private fun ModalScrim( + onDismiss: () -> Unit, + content: @Composable BoxScope.() -> Unit +) { + val scrimInteraction = remember { MutableInteractionSource() } + val contentInteraction = remember { MutableInteractionSource() } + + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.Black.copy(alpha = 0.72f)) + .clickable( + interactionSource = scrimInteraction, + indication = null, + onClick = onDismiss + ), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier.clickable( + interactionSource = contentInteraction, + indication = null, + onClick = {} + ), + content = content + ) + } +} + @OptIn(ExperimentalTvMaterial3Api::class) @Composable private fun CloudEmailPasswordModal( @@ -1145,228 +1191,230 @@ private fun CloudEmailPasswordModal( onDismissRequest = onDismiss, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { - Column( - modifier = Modifier - .fillMaxWidth(if (LocalDeviceType.current.isTouchDevice()) 0.92f else 1f) - .widthIn(max = 600.dp) - .background(BackgroundElevated, RoundedCornerShape(16.dp)) - .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 32.dp) - .onPreviewKeyEvent { event -> - if (event.type == KeyEventType.KeyDown) { - when (event.key) { - Key.Back, Key.Escape -> { - onDismiss() - true - } - Key.DirectionUp -> { - focusedIndex = when (focusedIndex) { - 1 -> 0 - 2, 3, 4 -> 1 - else -> focusedIndex + ModalScrim(onDismiss = onDismiss) { + Column( + modifier = Modifier + .fillMaxWidth(if (LocalDeviceType.current.isTouchDevice()) 0.92f else 1f) + .widthIn(max = 600.dp) + .background(BackgroundElevated, RoundedCornerShape(16.dp)) + .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 32.dp) + .onPreviewKeyEvent { event -> + if (event.type == KeyEventType.KeyDown) { + when (event.key) { + Key.Back, Key.Escape -> { + onDismiss() + true } - true - } - Key.DirectionDown -> { - focusedIndex = when (focusedIndex) { - 0 -> 1 - 1 -> 3 // Move to primary action; avoid "Down moves right" feeling. - else -> focusedIndex + Key.DirectionUp -> { + focusedIndex = when (focusedIndex) { + 1 -> 0 + 2, 3, 4 -> 1 + else -> focusedIndex + } + true } - true - } - Key.DirectionLeft -> { - focusedIndex = when (focusedIndex) { - 4 -> 3 - 3 -> 2 - else -> focusedIndex + Key.DirectionDown -> { + focusedIndex = when (focusedIndex) { + 0 -> 1 + 1 -> 3 + else -> focusedIndex + } + true } - true - } - Key.DirectionRight -> { - focusedIndex = when (focusedIndex) { - 2 -> 3 - 3 -> 4 - else -> focusedIndex + Key.DirectionLeft -> { + focusedIndex = when (focusedIndex) { + 4 -> 3 + 3 -> 2 + else -> focusedIndex + } + true } - true - } - Key.Enter, Key.DirectionCenter -> { - when (focusedIndex) { - 2 -> { onDismiss(); true } - 3 -> { onSignIn(); true } - 4 -> { onCreateAccount(); true } - else -> false + Key.DirectionRight -> { + focusedIndex = when (focusedIndex) { + 2 -> 3 + 3 -> 4 + else -> focusedIndex + } + true } + Key.Enter, Key.DirectionCenter -> { + when (focusedIndex) { + 2 -> { onDismiss(); true } + 3 -> { onSignIn(); true } + 4 -> { onCreateAccount(); true } + else -> false + } + } + else -> false } - else -> false - } - } else false - }, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text( - text = "ARVIO Cloud Sign-in", - style = ArflixTypography.sectionTitle, - color = TextPrimary, - modifier = Modifier.padding(bottom = 24.dp) - ) - - Column(modifier = Modifier.fillMaxWidth()) { - Text( - text = "Email", - style = ArflixTypography.caption, - color = if (focusedIndex == 0) Pink else TextSecondary, - modifier = Modifier.padding(bottom = 8.dp) - ) - androidx.compose.material3.TextField( - value = email, - onValueChange = onEmailChange, - singleLine = true, - textStyle = ArflixTypography.body.copy(color = TextPrimary), - colors = androidx.compose.material3.TextFieldDefaults.colors( - focusedTextColor = TextPrimary, - unfocusedTextColor = TextPrimary, - focusedContainerColor = Color.White.copy(alpha = 0.1f), - unfocusedContainerColor = Color.White.copy(alpha = 0.05f), - focusedIndicatorColor = Pink, - unfocusedIndicatorColor = Color.Transparent, - cursorColor = Pink - ), - modifier = Modifier - .fillMaxWidth() - .focusRequester(emailRequester) - .border( - width = if (focusedIndex == 0) 2.dp else 1.dp, - color = if (focusedIndex == 0) Pink else Color.White.copy(alpha = 0.2f), - shape = RoundedCornerShape(8.dp) - ) - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Column(modifier = Modifier.fillMaxWidth()) { + } else false + }, + horizontalAlignment = Alignment.CenterHorizontally + ) { Text( - text = "Password", - style = ArflixTypography.caption, - color = if (focusedIndex == 1) Pink else TextSecondary, - modifier = Modifier.padding(bottom = 8.dp) - ) - androidx.compose.material3.TextField( - value = password, - onValueChange = onPasswordChange, - singleLine = true, - visualTransformation = androidx.compose.ui.text.input.PasswordVisualTransformation(), - textStyle = ArflixTypography.body.copy(color = TextPrimary), - colors = androidx.compose.material3.TextFieldDefaults.colors( - focusedTextColor = TextPrimary, - unfocusedTextColor = TextPrimary, - focusedContainerColor = Color.White.copy(alpha = 0.1f), - unfocusedContainerColor = Color.White.copy(alpha = 0.05f), - focusedIndicatorColor = Pink, - unfocusedIndicatorColor = Color.Transparent, - cursorColor = Pink - ), - modifier = Modifier - .fillMaxWidth() - .focusRequester(passwordRequester) - .border( - width = if (focusedIndex == 1) 2.dp else 1.dp, - color = if (focusedIndex == 1) Pink else Color.White.copy(alpha = 0.2f), - shape = RoundedCornerShape(8.dp) - ) + text = "ARVIO Cloud Sign-in", + style = ArflixTypography.sectionTitle, + color = TextPrimary, + modifier = Modifier.padding(bottom = 24.dp) ) - } - - Spacer(modifier = Modifier.height(24.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(16.dp) - ) { - val isCancelFocused = focusedIndex == 2 - Box( - modifier = Modifier - .weight(1f) - .clip(RoundedCornerShape(8.dp)) - .background( - color = if (isCancelFocused) Color.White.copy(alpha = 0.2f) else Color.White.copy(alpha = 0.1f) - ) - .clickable { onDismiss() } - .border( - width = if (isCancelFocused) 2.dp else 0.dp, - color = if (isCancelFocused) Pink else Color.Transparent, - shape = RoundedCornerShape(8.dp) - ) - .padding(vertical = 14.dp), - contentAlignment = Alignment.Center - ) { + Column(modifier = Modifier.fillMaxWidth()) { Text( - text = "Cancel", - style = ArflixTypography.button, - color = if (isCancelFocused) TextPrimary else TextSecondary + text = "Email", + style = ArflixTypography.caption, + color = if (focusedIndex == 0) Pink else TextSecondary, + modifier = Modifier.padding(bottom = 8.dp) + ) + androidx.compose.material3.TextField( + value = email, + onValueChange = onEmailChange, + singleLine = true, + textStyle = ArflixTypography.body.copy(color = TextPrimary), + colors = androidx.compose.material3.TextFieldDefaults.colors( + focusedTextColor = TextPrimary, + unfocusedTextColor = TextPrimary, + focusedContainerColor = Color.White.copy(alpha = 0.1f), + unfocusedContainerColor = Color.White.copy(alpha = 0.05f), + focusedIndicatorColor = Pink, + unfocusedIndicatorColor = Color.Transparent, + cursorColor = Pink + ), + modifier = Modifier + .fillMaxWidth() + .focusRequester(emailRequester) + .border( + width = if (focusedIndex == 0) 2.dp else 1.dp, + color = if (focusedIndex == 0) Pink else Color.White.copy(alpha = 0.2f), + shape = RoundedCornerShape(8.dp) + ) ) } - val isSignInFocused = focusedIndex == 3 - Box( - modifier = Modifier - .weight(1f) - .clip(RoundedCornerShape(8.dp)) - .background( - color = if (isSignInFocused) SuccessGreen else Pink.copy(alpha = 0.6f) - ) - .clickable { onSignIn() } - .border( - width = if (isSignInFocused) 2.dp else 0.dp, - color = if (isSignInFocused) SuccessGreen.copy(alpha = 0.5f) else Color.Transparent, - shape = RoundedCornerShape(8.dp) - ) - .padding(vertical = 14.dp), - contentAlignment = Alignment.Center - ) { + Spacer(modifier = Modifier.height(16.dp)) + + Column(modifier = Modifier.fillMaxWidth()) { Text( - text = "Sign In", - style = ArflixTypography.button, - color = Color.White + text = "Password", + style = ArflixTypography.caption, + color = if (focusedIndex == 1) Pink else TextSecondary, + modifier = Modifier.padding(bottom = 8.dp) + ) + androidx.compose.material3.TextField( + value = password, + onValueChange = onPasswordChange, + singleLine = true, + visualTransformation = androidx.compose.ui.text.input.PasswordVisualTransformation(), + textStyle = ArflixTypography.body.copy(color = TextPrimary), + colors = androidx.compose.material3.TextFieldDefaults.colors( + focusedTextColor = TextPrimary, + unfocusedTextColor = TextPrimary, + focusedContainerColor = Color.White.copy(alpha = 0.1f), + unfocusedContainerColor = Color.White.copy(alpha = 0.05f), + focusedIndicatorColor = Pink, + unfocusedIndicatorColor = Color.Transparent, + cursorColor = Pink + ), + modifier = Modifier + .fillMaxWidth() + .focusRequester(passwordRequester) + .border( + width = if (focusedIndex == 1) 2.dp else 1.dp, + color = if (focusedIndex == 1) Pink else Color.White.copy(alpha = 0.2f), + shape = RoundedCornerShape(8.dp) + ) ) } - val isCreateFocused = focusedIndex == 4 - Box( - modifier = Modifier - .weight(1f) - .clip(RoundedCornerShape(8.dp)) - .background( - color = if (isCreateFocused) SuccessGreen else Color.White.copy(alpha = 0.08f) + Spacer(modifier = Modifier.height(24.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { + val isCancelFocused = focusedIndex == 2 + Box( + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .background( + color = if (isCancelFocused) Color.White.copy(alpha = 0.2f) else Color.White.copy(alpha = 0.1f) + ) + .clickable { onDismiss() } + .border( + width = if (isCancelFocused) 2.dp else 0.dp, + color = if (isCancelFocused) Pink else Color.Transparent, + shape = RoundedCornerShape(8.dp) + ) + .padding(vertical = 14.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "Cancel", + style = ArflixTypography.button, + color = if (isCancelFocused) TextPrimary else TextSecondary ) - .clickable { onCreateAccount() } - .border( - width = if (isCreateFocused) 2.dp else 0.dp, - color = if (isCreateFocused) SuccessGreen.copy(alpha = 0.5f) else Color.Transparent, - shape = RoundedCornerShape(8.dp) + } + + val isSignInFocused = focusedIndex == 3 + Box( + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .background( + color = if (isSignInFocused) SuccessGreen else Pink.copy(alpha = 0.6f) + ) + .clickable { onSignIn() } + .border( + width = if (isSignInFocused) 2.dp else 0.dp, + color = if (isSignInFocused) SuccessGreen.copy(alpha = 0.5f) else Color.Transparent, + shape = RoundedCornerShape(8.dp) + ) + .padding(vertical = 14.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "Sign In", + style = ArflixTypography.button, + color = Color.White ) - .padding(vertical = 14.dp), - contentAlignment = Alignment.Center - ) { - Text( - text = "Create", - style = ArflixTypography.button, - color = Color.White - ) + } + + val isCreateFocused = focusedIndex == 4 + Box( + modifier = Modifier + .weight(1f) + .clip(RoundedCornerShape(8.dp)) + .background( + color = if (isCreateFocused) SuccessGreen else Color.White.copy(alpha = 0.08f) + ) + .clickable { onCreateAccount() } + .border( + width = if (isCreateFocused) 2.dp else 0.dp, + color = if (isCreateFocused) SuccessGreen.copy(alpha = 0.5f) else Color.Transparent, + shape = RoundedCornerShape(8.dp) + ) + .padding(vertical = 14.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "Create", + style = ArflixTypography.button, + color = Color.White + ) + } } - } - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = if (LocalDeviceType.current.isTouchDevice()) "Enter your email and password to sign in." else "Tip: Use TV keyboard. D-pad to navigate.", - style = ArflixTypography.caption, - color = TextSecondary.copy(alpha = 0.5f) - ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = if (LocalDeviceType.current.isTouchDevice()) "Enter your email and password to sign in." else "Tip: Use TV keyboard. D-pad to navigate.", + style = ArflixTypography.caption, + color = TextSecondary.copy(alpha = 0.5f) + ) + } } } } @@ -1394,12 +1442,13 @@ private fun CloudPairModal( onDismissRequest = onDismiss, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { val isMobile = LocalDeviceType.current.isTouchDevice() - BoxWithConstraints(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + ModalScrim(onDismiss = onDismiss) { + BoxWithConstraints(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { val modalWidth = if (isMobile) maxWidth else (maxWidth * 0.62f).coerceIn(520.dp, 760.dp) val qrContainerSize = (modalWidth * 0.42f).coerceIn(190.dp, 260.dp) val qrBitmapSizePx = ((qrContainerSize.value * 3.2f).toInt()).coerceIn(512, 900) @@ -1647,6 +1696,7 @@ private fun CloudPairModal( } } } + } } } @@ -1756,46 +1806,47 @@ private fun AppUpdateModal( onDismissRequest = onDismiss, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { - Column( - modifier = Modifier - .then( - if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 600.dp) - else Modifier.width(760.dp) - ) - .background(BackgroundElevated, RoundedCornerShape(18.dp)) - .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) - .focusRequester(focusRequester) - .focusable() - .onPreviewKeyEvent { event -> - if (event.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false - when (event.key) { - Key.Back, Key.Escape -> { onDismiss(); true } - Key.DirectionLeft -> { - focusedIndex = (focusedIndex - 1).coerceAtLeast(0) - true - } - Key.DirectionRight -> { - focusedIndex = (focusedIndex + 1).coerceAtMost(2) - true - } - Key.Enter, Key.DirectionCenter -> { - when (focusedIndex) { - 0 -> onDismiss() - 1 -> onIgnore() - 2 -> if (primaryEnabled) { - if (downloadedApkPath != null) onInstall() else onDownload() + ModalScrim(onDismiss = onDismiss) { + Column( + modifier = Modifier + .then( + if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 600.dp) + else Modifier.width(760.dp) + ) + .background(BackgroundElevated, RoundedCornerShape(18.dp)) + .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) + .focusRequester(focusRequester) + .focusable() + .onPreviewKeyEvent { event -> + if (event.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false + when (event.key) { + Key.Back, Key.Escape -> { onDismiss(); true } + Key.DirectionLeft -> { + focusedIndex = (focusedIndex - 1).coerceAtLeast(0) + true + } + Key.DirectionRight -> { + focusedIndex = (focusedIndex + 1).coerceAtMost(2) + true + } + Key.Enter, Key.DirectionCenter -> { + when (focusedIndex) { + 0 -> onDismiss() + 1 -> onIgnore() + 2 -> if (primaryEnabled) { + if (downloadedApkPath != null) onInstall() else onDownload() + } } + true } - true + else -> false } - else -> false } - } - ) { + ) { Text("App Update", style = ArflixTypography.sectionTitle, color = TextPrimary) Spacer(modifier = Modifier.height(10.dp)) @@ -1877,6 +1928,7 @@ private fun AppUpdateModal( ) } } + } } } @@ -1897,45 +1949,47 @@ private fun UnknownSourcesModal( onDismissRequest = onDismiss, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { - Column( - modifier = Modifier - .then( - if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 600.dp) - else Modifier.width(620.dp) - ) - .background(BackgroundElevated, RoundedCornerShape(18.dp)) - .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) - .focusRequester(focusRequester) - .focusable() - .onPreviewKeyEvent { event -> - if (event.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false - when (event.key) { - Key.Back, Key.Escape -> { onDismiss(); true } - Key.DirectionLeft -> { focusedIndex = 0; true } - Key.DirectionRight -> { focusedIndex = 1; true } - Key.Enter, Key.DirectionCenter -> { - if (focusedIndex == 0) onDismiss() else onOpenSettings() - true + ModalScrim(onDismiss = onDismiss) { + Column( + modifier = Modifier + .then( + if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 600.dp) + else Modifier.width(620.dp) + ) + .background(BackgroundElevated, RoundedCornerShape(18.dp)) + .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) + .focusRequester(focusRequester) + .focusable() + .onPreviewKeyEvent { event -> + if (event.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false + when (event.key) { + Key.Back, Key.Escape -> { onDismiss(); true } + Key.DirectionLeft -> { focusedIndex = 0; true } + Key.DirectionRight -> { focusedIndex = 1; true } + Key.Enter, Key.DirectionCenter -> { + if (focusedIndex == 0) onDismiss() else onOpenSettings() + true + } + else -> false } - else -> false } + ) { + Text("Allow Unknown Sources", style = ArflixTypography.sectionTitle, color = TextPrimary) + Spacer(modifier = Modifier.height(12.dp)) + Text( + "Allow installs from unknown sources for ARVIO so the downloaded update APK can be installed.", + style = ArflixTypography.body, + color = TextSecondary + ) + Spacer(modifier = Modifier.height(24.dp)) + Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { + UpdateActionButton("Close", focusedIndex == 0, onDismiss) + UpdateActionButton("Open Settings", focusedIndex == 1, onOpenSettings, highlighted = true) } - ) { - Text("Allow Unknown Sources", style = ArflixTypography.sectionTitle, color = TextPrimary) - Spacer(modifier = Modifier.height(12.dp)) - Text( - "Allow installs from unknown sources for ARVIO so the downloaded update APK can be installed.", - style = ArflixTypography.body, - color = TextSecondary - ) - Spacer(modifier = Modifier.height(24.dp)) - Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { - UpdateActionButton("Close", focusedIndex == 0, onDismiss) - UpdateActionButton("Open Settings", focusedIndex == 1, onOpenSettings, highlighted = true) } } } @@ -3308,73 +3362,73 @@ private fun InputModalLegacy( onDismissRequest = onDismiss, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { - Column( - modifier = Modifier - .width(550.dp) - .background(BackgroundElevated, RoundedCornerShape(16.dp)) - .padding(32.dp) - .onPreviewKeyEvent { event -> - if (event.type == KeyEventType.KeyDown) { - when (event.key) { - Key.Back, Key.Escape -> { - onDismiss() - true - } - Key.DirectionUp -> { - if (focusedIndex > 0) { - focusedIndex-- - } - true - } - Key.DirectionDown -> { - if (focusedIndex < totalItems - 1) { - focusedIndex++ + ModalScrim(onDismiss = onDismiss) { + Column( + modifier = Modifier + .width(550.dp) + .background(BackgroundElevated, RoundedCornerShape(16.dp)) + .padding(32.dp) + .onPreviewKeyEvent { event -> + if (event.type == KeyEventType.KeyDown) { + when (event.key) { + Key.Back, Key.Escape -> { + onDismiss() + true } - true - } - Key.DirectionLeft -> { - if (focusedIndex == fields.size + 2) { - focusedIndex = fields.size + 1 + Key.DirectionUp -> { + if (focusedIndex > 0) { + focusedIndex-- + } + true } - true - } - Key.DirectionRight -> { - if (focusedIndex == fields.size + 1) { - focusedIndex = fields.size + 2 + Key.DirectionDown -> { + if (focusedIndex < totalItems - 1) { + focusedIndex++ + } + true } - true - } - Key.Enter, Key.DirectionCenter -> { - when { - focusedIndex == fields.size -> { - // Paste button - paste clipboard to first field (URL) - val clipboardText = clipboardManager.getText()?.text - if (clipboardText != null && fields.isNotEmpty()) { - fields[0].onValueChange(clipboardText) - } - true + Key.DirectionLeft -> { + if (focusedIndex == fields.size + 2) { + focusedIndex = fields.size + 1 } - focusedIndex == fields.size + 1 -> { - onDismiss() - true + true + } + Key.DirectionRight -> { + if (focusedIndex == fields.size + 1) { + focusedIndex = fields.size + 2 } - focusedIndex == fields.size + 2 -> { - onConfirm() - true + true + } + Key.Enter, Key.DirectionCenter -> { + when { + focusedIndex == fields.size -> { + val clipboardText = clipboardManager.getText()?.text + if (clipboardText != null && fields.isNotEmpty()) { + fields[0].onValueChange(clipboardText) + } + true + } + focusedIndex == fields.size + 1 -> { + onDismiss() + true + } + focusedIndex == fields.size + 2 -> { + onConfirm() + true + } + else -> false } - else -> false // Let text field handle Enter } + else -> false } - else -> false - } - } else false - }, - horizontalAlignment = Alignment.CenterHorizontally - ) { + } else false + }, + horizontalAlignment = Alignment.CenterHorizontally + ) { Text( text = title, style = ArflixTypography.sectionTitle, @@ -3527,6 +3581,7 @@ private fun InputModalLegacy( style = ArflixTypography.caption, color = TextSecondary.copy(alpha = 0.5f) ) + } } } } @@ -3593,15 +3648,15 @@ private fun InputModal( }, properties = androidx.compose.ui.window.DialogProperties( dismissOnBackPress = true, - dismissOnClickOutside = false, + dismissOnClickOutside = true, usePlatformDefaultWidth = false ) ) { - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.72f)), - contentAlignment = Alignment.Center + ModalScrim( + onDismiss = { + hideKeyboardAll() + onDismiss() + } ) { Column( modifier = Modifier @@ -3918,7 +3973,7 @@ private fun InputModal( text = if (LocalDeviceType.current.isTouchDevice()) "Tap a field to edit, tap Confirm when done" else "OK: edit/select \u2022 Back: close keyboard first", style = ArflixTypography.caption, color = TextSecondary.copy(alpha = 0.56f) - ) + ) } } } @@ -3948,107 +4003,111 @@ private fun SubtitlePickerModal( focusRequester.requestFocus() } - Box( - modifier = Modifier - .fillMaxSize() - .background(Color.Black.copy(alpha = 0.6f)) - .focusRequester(focusRequester) - .focusable() - .onPreviewKeyEvent { event -> - if (event.type == KeyEventType.KeyDown) { - when (event.key) { - Key.Back, Key.Escape -> { - onDismiss() - true - } - Key.DirectionUp -> { - if (safeIndex > 0) onFocusChange(safeIndex - 1) - true - } - Key.DirectionDown -> { - if (safeIndex < options.size - 1) onFocusChange(safeIndex + 1) - true - } - Key.Enter, Key.DirectionCenter -> { - if (options.isNotEmpty()) { - onSelect(options[safeIndex]) + androidx.compose.ui.window.Dialog( + onDismissRequest = onDismiss, + properties = androidx.compose.ui.window.DialogProperties( + dismissOnBackPress = true, + dismissOnClickOutside = true, + usePlatformDefaultWidth = false + ) + ) { + ModalScrim(onDismiss = onDismiss) { + Column( + modifier = Modifier + .then( + if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 520.dp) + else Modifier.width(520.dp) + ) + .background(BackgroundElevated, RoundedCornerShape(16.dp)) + .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) + .focusRequester(focusRequester) + .focusable() + .onPreviewKeyEvent { event -> + if (event.type == KeyEventType.KeyDown) { + when (event.key) { + Key.Back, Key.Escape -> { + onDismiss() + true + } + Key.DirectionUp -> { + if (safeIndex > 0) onFocusChange(safeIndex - 1) + true + } + Key.DirectionDown -> { + if (safeIndex < options.size - 1) onFocusChange(safeIndex + 1) + true + } + Key.Enter, Key.DirectionCenter -> { + if (options.isNotEmpty()) { + onSelect(options[safeIndex]) + } + true + } + else -> false } - true - } - else -> false + } else false } - } else false - }, - contentAlignment = Alignment.Center - ) { - Column( - modifier = Modifier - .then( - if (LocalDeviceType.current.isTouchDevice()) Modifier.fillMaxWidth(0.92f).widthIn(max = 520.dp) - else Modifier.width(520.dp) + ) { + Text( + text = title, + style = ArflixTypography.sectionTitle, + color = TextPrimary ) - .background(BackgroundElevated, RoundedCornerShape(16.dp)) - .padding(if (LocalDeviceType.current.isTouchDevice()) 20.dp else 28.dp) - ) { - Text( - text = title, - style = ArflixTypography.sectionTitle, - color = TextPrimary - ) - Spacer(modifier = Modifier.height(16.dp)) + Spacer(modifier = Modifier.height(16.dp)) - LazyColumn( - state = listState, - modifier = Modifier.heightIn(max = 360.dp) - ) { - itemsIndexed(options) { index, option -> - val isFocused = index == safeIndex - val isSelected = option.equals(selected, ignoreCase = true) - Row( - modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(10.dp)) - .background( - if (isFocused) Color.White.copy(alpha = 0.12f) else Color.Transparent, - RoundedCornerShape(10.dp) - ) - .border( - width = if (isFocused) 2.dp else 1.dp, - color = if (isFocused) Pink else Color.White.copy(alpha = 0.1f), - shape = RoundedCornerShape(10.dp) - ) - .clickable { onSelect(option) } - .padding(horizontal = 16.dp, vertical = 12.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - text = option, - style = ArflixTypography.body, - color = if (isFocused) TextPrimary else TextSecondary, - modifier = Modifier.weight(1f) - ) - if (isSelected) { - Icon( - imageVector = Icons.Default.Check, - contentDescription = null, - tint = SuccessGreen, - modifier = Modifier.size(18.dp) + LazyColumn( + state = listState, + modifier = Modifier.heightIn(max = 360.dp) + ) { + itemsIndexed(options) { index, option -> + val isFocused = index == safeIndex + val isSelected = option.equals(selected, ignoreCase = true) + Row( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(10.dp)) + .background( + if (isFocused) Color.White.copy(alpha = 0.12f) else Color.Transparent, + RoundedCornerShape(10.dp) + ) + .border( + width = if (isFocused) 2.dp else 1.dp, + color = if (isFocused) Pink else Color.White.copy(alpha = 0.1f), + shape = RoundedCornerShape(10.dp) + ) + .clickable { onSelect(option) } + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = option, + style = ArflixTypography.body, + color = if (isFocused) TextPrimary else TextSecondary, + modifier = Modifier.weight(1f) ) + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = null, + tint = SuccessGreen, + modifier = Modifier.size(18.dp) + ) + } } + Spacer(modifier = Modifier.height(10.dp)) } - Spacer(modifier = Modifier.height(10.dp)) } - } - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = "Press Enter to select", - style = ArflixTypography.caption, - color = TextSecondary.copy(alpha = 0.6f), - textAlign = TextAlign.Center, - modifier = Modifier.fillMaxWidth() - ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = "Press Enter to select", + style = ArflixTypography.caption, + color = TextSecondary.copy(alpha = 0.6f), + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + } } } } From abb2ffa7a4d4e8a4cde484ca8fdb8f51ee5fbf4c Mon Sep 17 00:00:00 2001 From: Himanth Reddy Date: Sun, 29 Mar 2026 11:36:57 +0530 Subject: [PATCH 2/3] Theme settings popups to match app colors --- .../tv/ui/screens/settings/SettingsScreen.kt | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt index 055bc2ea1..a0af581e9 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt @@ -1520,17 +1520,27 @@ private fun CloudPairModal( Box( modifier = Modifier .size(qrContainerSize) - .background(Color.White, RoundedCornerShape(12.dp)) - .padding(10.dp), + .background(BackgroundDark.copy(alpha = 0.92f), RoundedCornerShape(16.dp)) + .border(1.dp, Color.White.copy(alpha = 0.12f), RoundedCornerShape(16.dp)) + .padding(12.dp), contentAlignment = Alignment.Center ) { - QrCodeImage( - data = effectiveVerificationUrl, - sizePx = qrBitmapSizePx, - modifier = Modifier.fillMaxSize(), - foreground = android.graphics.Color.BLACK, - background = android.graphics.Color.WHITE, - ) + Box( + modifier = Modifier + .fillMaxSize() + .clip(RoundedCornerShape(10.dp)) + .background(Color.White) + .padding(10.dp), + contentAlignment = Alignment.Center + ) { + QrCodeImage( + data = effectiveVerificationUrl, + sizePx = qrBitmapSizePx, + modifier = Modifier.fillMaxSize(), + foreground = android.graphics.Color.BLACK, + background = android.graphics.Color.WHITE, + ) + } } } @@ -2005,13 +2015,23 @@ private fun UpdateActionButton( ) { val background = when { !enabled -> Color.White.copy(alpha = 0.06f) - isFocused -> Color.White - else -> Color.Black.copy(alpha = 0.72f) + highlighted && isFocused -> Pink + isFocused -> Color.White.copy(alpha = 0.16f) + highlighted -> Pink.copy(alpha = 0.18f) + else -> Color.White.copy(alpha = 0.08f) } val textColor = when { !enabled -> TextSecondary.copy(alpha = 0.6f) - isFocused -> Color.Black - else -> Color.White + highlighted -> Color.White + isFocused -> TextPrimary + else -> TextSecondary + } + val borderColor = when { + !enabled -> Color.White.copy(alpha = 0.1f) + highlighted && isFocused -> Pink.copy(alpha = 0.95f) + highlighted -> Pink.copy(alpha = 0.4f) + isFocused -> Color.White.copy(alpha = 0.75f) + else -> Color.White.copy(alpha = 0.12f) } Box( @@ -2019,8 +2039,8 @@ private fun UpdateActionButton( .clip(RoundedCornerShape(10.dp)) .background(background, RoundedCornerShape(10.dp)) .border( - width = if (isFocused) 2.dp else 0.dp, - color = if (isFocused) Color.White.copy(alpha = 0.92f) else Color.White.copy(alpha = 0.12f), + width = if (isFocused || highlighted) 1.5.dp else 1.dp, + color = borderColor, shape = RoundedCornerShape(10.dp) ) .clickable(enabled = enabled) { onClick() } From 86ee953be36406bcff1d12266ea8eadad8e9abd8 Mon Sep 17 00:00:00 2001 From: Himanth Reddy Date: Sun, 29 Mar 2026 12:07:46 +0530 Subject: [PATCH 3/3] Polish startup loading screen --- .../main/kotlin/com/arflix/tv/MainActivity.kt | 125 +++++++++--------- .../res/drawable-nodpi/arvio_loading_logo.png | Bin 0 -> 48974 bytes 2 files changed, 65 insertions(+), 60 deletions(-) create mode 100644 app/src/main/res/drawable-nodpi/arvio_loading_logo.png diff --git a/app/src/main/kotlin/com/arflix/tv/MainActivity.kt b/app/src/main/kotlin/com/arflix/tv/MainActivity.kt index 2b93eddec..f69cdc68c 100644 --- a/app/src/main/kotlin/com/arflix/tv/MainActivity.kt +++ b/app/src/main/kotlin/com/arflix/tv/MainActivity.kt @@ -27,6 +27,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.Image import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -43,8 +46,9 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -186,7 +190,12 @@ class MainActivity : ComponentActivity() { setContent { // Observe device mode override changes live from DataStore val deviceModeOverride by remember { this@MainActivity.settingsDataStore.data.map { it[DEVICE_MODE_OVERRIDE_KEY] } }.collectAsState(initial = null) - val skipProfileSelection by remember { this@MainActivity.settingsDataStore.data.map { it[SKIP_PROFILE_SELECTION_KEY] ?: false } }.collectAsState(initial = false) + val skipProfileSelection by remember { + this@MainActivity.settingsDataStore.data.map { it[SKIP_PROFILE_SELECTION_KEY] ?: false } + }.collectAsState(initial = null as Boolean?) + val activeProfileLoaded by remember { + profileRepository.get().activeProfileId.map { true } + }.collectAsState(initial = false) val deviceType = when (deviceModeOverride) { "tv" -> DeviceType.TV "tablet" -> DeviceType.TABLET @@ -210,6 +219,7 @@ class MainActivity : ComponentActivity() { traktRepository = traktRepository.get(), launcherContinueWatchingRepository = launcherContinueWatchingRepository.get(), skipProfileSelection = skipProfileSelection, + activeProfileLoaded = activeProfileLoaded, pendingLauncherRequest = pendingLauncherRequest, onConsumeLauncherRequest = { pendingLauncherRequest = null }, preloadedCategories = startupState.categories, @@ -283,7 +293,7 @@ private fun ComponentActivity.runAfterFirstDraw(block: () -> Unit) { } /** - * Simple ARVIO loading screen - white glowing text + spinner + * Simple ARVIO loading screen - app logo + spinner */ @OptIn(ExperimentalTvMaterial3Api::class) @Composable @@ -301,15 +311,14 @@ fun ArvioLoadingScreen() { label = "rotation" ) - // Pulsing glow for text - val glowAlpha by infiniteTransition.animateFloat( - initialValue = 0.5f, + val logoAlpha by infiniteTransition.animateFloat( + initialValue = 0.72f, targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(1500, easing = FastOutSlowInEasing), repeatMode = RepeatMode.Reverse ), - label = "glow" + label = "logoAlpha" ) Box( @@ -318,58 +327,45 @@ fun ArvioLoadingScreen() { .background(Color(0xFF0a0a0a)), contentAlignment = Alignment.Center ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + Image( + painter = painterResource(id = R.drawable.arvio_loading_logo), + contentDescription = "ARVIO", + modifier = Modifier.padding(horizontal = 24.dp), + contentScale = ContentScale.Fit, + alpha = logoAlpha + ) + + Canvas( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(bottom = 132.dp) + .size(28.dp) ) { - // ARVIO text with white glow - Text( - text = "ARVIO", - fontSize = 48.sp, - fontWeight = FontWeight.Bold, - color = Color.White, - letterSpacing = 8.sp, - style = androidx.compose.ui.text.TextStyle( - shadow = Shadow( - color = Color.White.copy(alpha = glowAlpha), - offset = Offset.Zero, - blurRadius = 30f - ) - ) + val strokeWidth = 2.dp.toPx() + val arcSize = androidx.compose.ui.geometry.Size( + size.width - strokeWidth, + size.height - strokeWidth ) - Spacer(modifier = Modifier.height(48.dp)) - - // Simple rotating spinner - Canvas(modifier = Modifier.size(48.dp)) { - val strokeWidth = 3.dp.toPx() - val arcSize = androidx.compose.ui.geometry.Size( - size.width - strokeWidth, - size.height - strokeWidth - ) - - // Background ring - drawArc( - color = Color.White.copy(alpha = 0.15f), - startAngle = 0f, - sweepAngle = 360f, - useCenter = false, - topLeft = Offset(strokeWidth / 2, strokeWidth / 2), - size = arcSize, - style = Stroke(width = strokeWidth, cap = StrokeCap.Round) - ) + drawArc( + color = Color.White.copy(alpha = 0.12f), + startAngle = 0f, + sweepAngle = 360f, + useCenter = false, + topLeft = Offset(strokeWidth / 2, strokeWidth / 2), + size = arcSize, + style = Stroke(width = strokeWidth, cap = StrokeCap.Round) + ) - // Rotating arc - drawArc( - color = Color.White, - startAngle = rotation, - sweepAngle = 90f, - useCenter = false, - topLeft = Offset(strokeWidth / 2, strokeWidth / 2), - size = arcSize, - style = Stroke(width = strokeWidth, cap = StrokeCap.Round) - ) - } + drawArc( + color = Color.White.copy(alpha = 0.9f), + startAngle = rotation, + sweepAngle = 82f, + useCenter = false, + topLeft = Offset(strokeWidth / 2, strokeWidth / 2), + size = arcSize, + style = Stroke(width = strokeWidth, cap = StrokeCap.Round) + ) } } } @@ -384,7 +380,8 @@ fun ArflixApp( profileRepository: ProfileRepository, traktRepository: TraktRepository, launcherContinueWatchingRepository: LauncherContinueWatchingRepository, - skipProfileSelection: Boolean = false, + skipProfileSelection: Boolean? = null, + activeProfileLoaded: Boolean = false, pendingLauncherRequest: LauncherContinueWatchingRequest? = null, onConsumeLauncherRequest: () -> Unit = {}, preloadedCategories: List = emptyList(), @@ -394,10 +391,19 @@ fun ArflixApp( onExitApp: () -> Unit = {} ) { val context = LocalContext.current - val navController = rememberNavController() - val appCoroutineScope = androidx.compose.runtime.rememberCoroutineScope() val authState by authRepository.authState.collectAsState() val activeProfile by profileRepository.activeProfile.collectAsState(initial = null) + val startupReady = skipProfileSelection != null && + activeProfileLoaded && + authState !is AuthState.Loading + + if (!startupReady) { + ArvioLoadingScreen() + return + } + + val navController = rememberNavController() + val appCoroutineScope = androidx.compose.runtime.rememberCoroutineScope() var lastAddonsSyncKey by remember { mutableStateOf(null) } LaunchedEffect(authState, activeProfile?.id) { @@ -412,7 +418,7 @@ fun ArflixApp( } // Always show profile selection on startup - user must manually choose a profile - val startDestination = if (skipProfileSelection && activeProfile != null) { + val startDestination = if (skipProfileSelection == true && activeProfile != null) { Screen.Home.route } else { Screen.ProfileSelection.route @@ -515,4 +521,3 @@ private fun enqueueFullTraktSync(context: android.content.Context) { request ) } - diff --git a/app/src/main/res/drawable-nodpi/arvio_loading_logo.png b/app/src/main/res/drawable-nodpi/arvio_loading_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd26e9448fca15cc801919531d578c222f1c4d0 GIT binary patch literal 48974 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%0AWdj;dGBh58)ptqrY-2Xwf-3^xzuTgIKtzfXOri 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 KXaD@!>U;nuW>H)K literal 0 HcmV?d00001