Fix picker access and finish Wolfskin on root Back
This commit is contained in:
parent
febcded034
commit
9cfe9362ee
11 changed files with 481 additions and 31 deletions
|
|
@ -15,6 +15,7 @@ sealed interface ShellAction {
|
|||
data class Person(val person: ShellPerson) : ShellAction
|
||||
data class HandOff(val group: String) : ShellAction
|
||||
data object Pop : ShellAction
|
||||
data object Exit : ShellAction
|
||||
data object RetryPeople : ShellAction
|
||||
data object RetryRequests : ShellAction
|
||||
data class RequestTitle(val request: ComingInRequest) : ShellAction
|
||||
|
|
@ -196,7 +197,7 @@ class ShellState(
|
|||
when (key) {
|
||||
ShellKey.Left -> pickerIndex = (pickerIndex - 1).coerceAtLeast(0)
|
||||
ShellKey.Right -> pickerIndex = (pickerIndex + 1).coerceAtMost(people.lastIndex)
|
||||
ShellKey.Down -> if (pickerIndex == people.lastIndex) gearFocused = true
|
||||
ShellKey.Down -> gearFocused = true
|
||||
ShellKey.Ok -> choosePerson(people[pickerIndex])
|
||||
ShellKey.Back -> closePicker()
|
||||
else -> Unit
|
||||
|
|
@ -220,7 +221,8 @@ class ShellState(
|
|||
}
|
||||
|
||||
private fun closePicker() {
|
||||
if (!pickerLaunch) { pickerVisible = false; navFocused = true; navIndex = tabs.size }
|
||||
if (pickerLaunch) onAction(ShellAction.Exit)
|
||||
else { pickerVisible = false; navFocused = true; navIndex = tabs.size }
|
||||
}
|
||||
|
||||
private fun navKey(key: ShellKey) {
|
||||
|
|
@ -288,7 +290,7 @@ class ShellState(
|
|||
onAction(ShellAction.RequestTitle(request))
|
||||
}
|
||||
|
||||
/** Back never discards a root view, including the card below a focused nav. */
|
||||
/** Back retains root view memory; a second root Back exits instead of detouring through Home. */
|
||||
fun back() {
|
||||
if (requestsVisible) { closeRequests(); return }
|
||||
val returnRoute = requestReturnRoute
|
||||
|
|
@ -306,17 +308,13 @@ class ShellState(
|
|||
pickerVisible = true
|
||||
pickerLaunch = false
|
||||
gearFocused = true
|
||||
pickerIndex = people.lastIndex
|
||||
} else if (route !in tabs) {
|
||||
onAction(ShellAction.Pop)
|
||||
} else if (!navFocused) {
|
||||
navFocused = true
|
||||
navIndex = currentTab
|
||||
} else if (route != "home") {
|
||||
route = "home"
|
||||
rootRoute = "home"
|
||||
navIndex = 0
|
||||
onAction(ShellAction.Destination(route))
|
||||
} else {
|
||||
onAction(ShellAction.Exit)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.tv.material3.Text
|
||||
import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C
|
||||
import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L
|
||||
import org.justinvisser.wolfskin.design.WolfskinTokens.Shell as S
|
||||
|
||||
/** The picker covers the nav and exposes Settings only below the final person. */
|
||||
/** The picker covers the nav; Down from any person reaches Settings below the final avatar. */
|
||||
@Composable
|
||||
fun WhosWatching(state: ShellState, modifier: Modifier = Modifier) {
|
||||
Box(modifier.fillMaxSize().background(C.bg)) {
|
||||
|
|
@ -42,7 +43,7 @@ private fun PeoplePicker(state: ShellState) {
|
|||
Row(Modifier.fillMaxWidth().offset(y = S.pickerPeopleTop), horizontalArrangement = Arrangement.spacedBy(L.pickerGap, Alignment.CenterHorizontally)) {
|
||||
state.people.forEachIndexed { index, person ->
|
||||
val focused = !state.gearFocused && state.pickerIndex == index
|
||||
Column(Modifier.width(L.pickerAvatar).focusScale(focused, WolfskinTokens.Focus.scaleCard).clickable {
|
||||
Column(Modifier.width(L.pickerAvatar).testTag("picker-person:${person.key}").focusScale(focused, WolfskinTokens.Focus.scaleCard).clickable {
|
||||
state.focusPerson(index); state.key(ShellKey.Ok)
|
||||
}, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Avatar(person, L.pickerAvatar, WolfskinTokens.Type.avatarLetterPicker,
|
||||
|
|
@ -52,8 +53,8 @@ private fun PeoplePicker(state: ShellState) {
|
|||
}
|
||||
}
|
||||
}
|
||||
val left = (S.stageWidth - L.gear) / 2
|
||||
Box(Modifier.offset(left, S.pickerGearTop).size(L.gear).focusScale(state.gearFocused, WolfskinTokens.Focus.scaleCard)
|
||||
val left = (S.stageWidth - L.gear + (L.pickerAvatar + L.pickerGap) * (state.people.size - 1)) / 2
|
||||
Box(Modifier.offset(left, S.pickerGearTop).size(L.gear).testTag("picker-settings").focusScale(state.gearFocused, WolfskinTokens.Focus.scaleCard)
|
||||
.focusRing(state.gearFocused, L.gear / 2, WolfskinTokens.Focus.ringPickerRing)
|
||||
.clickable { state.gearFocused = true; state.key(ShellKey.Ok) }, contentAlignment = Alignment.Center) {
|
||||
Glyph("gear", if (state.gearFocused) C.fg else C.dim.copy(alpha = C.dim.alpha * S.gearOpacity), Modifier.size(L.buttonIcon))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue