Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.arflix.tv.ui.components

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.arflix.tv.util.DeviceType
import com.arflix.tv.util.LocalDeviceType

/**
* A persistent, visible back button for phone layouts.
*
* On Android phones and tablets running gesture navigation, the system nav bar
* auto-hides after a short idle, leaving users with no visible way to go back
* until they swipe up to re-reveal it. On TV this is a non-issue (Back key on
* the remote is always available) but on touch devices it makes deep screens
* feel trapped \u2014 the exact complaint in issue #43.
*
* This composable renders an IconButton-shaped circle in the top-start corner
* of the screen, inset from the status bar, but only when the device type is
* [DeviceType.PHONE]. On TV and tablet it returns an empty Box so callers can
* drop it unconditionally into their UI without per-device branching.
*
* Callers should place this inside a `Box` root (or similar) that fills the
* screen, so the absolute `.align(Alignment.TopStart)` positioning lands above
* their main content.
*
* Usage:
* ```
* Box(modifier = Modifier.fillMaxSize()) {
* MyScreenContent(...)
* MobileBackButton(onBack = onBack)
* }
* ```
*/
@Composable
fun MobileBackButton(
onBack: () -> Unit,
modifier: Modifier = Modifier
) {
val deviceType = LocalDeviceType.current
if (deviceType != DeviceType.PHONE) return

Box(
modifier = modifier
.statusBarsPadding()
.padding(start = 12.dp, top = 12.dp)
.size(40.dp)
.clip(CircleShape)
.background(Color.Black.copy(alpha = 0.55f))
.clickable(onClick = onBack),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back",
tint = Color.White,
modifier = Modifier.size(22.dp)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ fun DetailsScreen(
contentHasFocus = !isSidebarFocused,
usePosterCards = usePosterCards,
isMobile = isMobile,
onBack = onBack,
onButtonClick = { idx ->
when (idx) {
0 -> { // Play
Expand Down Expand Up @@ -935,6 +936,9 @@ private fun DetailsContent(
contentHasFocus: Boolean = true,
usePosterCards: Boolean = false,
isMobile: Boolean = false,
// Persistent back callback used by the phone-layout back button overlay
// (issue #43). No-op by default so tablet/TV callers don't need to pass it.
onBack: () -> Unit = {},
onButtonClick: (Int) -> Unit = {},
onSeasonClick: (Int) -> Unit = {},
onEpisodeClick: (Int) -> Unit = {},
Expand Down Expand Up @@ -1272,6 +1276,14 @@ private fun DetailsContent(
// Bottom spacing
Spacer(modifier = Modifier.height(32.dp))
}

// Persistent back button for phone users (hidden on tablet/TV).
// Sits on top of the scrolling Column so it's always reachable even
// when the system nav bar auto-hides. Issue #43.
com.arflix.tv.ui.components.MobileBackButton(
onBack = onBack,
modifier = Modifier.align(Alignment.TopStart)
)
}
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ fun SearchScreen(
}
}
}

// Persistent back button for phone users (hidden on tablet/TV). Issue #43.
com.arflix.tv.ui.components.MobileBackButton(
onBack = onBack,
modifier = Modifier.align(Alignment.TopStart)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,14 @@ fun SettingsScreen(
onDismiss = { viewModel.dismissToast() }
)
}

// Persistent back button for phone users (hidden on tablet/TV).
// Always visible in the top-start corner even when the system nav bar
// auto-hides. Issue #43.
com.arflix.tv.ui.components.MobileBackButton(
onBack = onBack,
modifier = Modifier.align(Alignment.TopStart)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,5 +388,11 @@ fun WatchlistScreen(
onDismiss = { viewModel.dismissToast() }
)
}

// Persistent back button for phone users (hidden on tablet/TV). Issue #43.
com.arflix.tv.ui.components.MobileBackButton(
onBack = onBack,
modifier = Modifier.align(Alignment.TopStart)
)
}
}
Loading