Restore approved picker Settings centring
This commit is contained in:
parent
a27e922675
commit
7c67596cb6
4 changed files with 24 additions and 11 deletions
|
|
@ -4,10 +4,16 @@
|
|||
|
||||
## Who’s watching
|
||||
|
||||
Round-2 correction: the Settings gear is centred beneath the **last avatar**, independent of selection. Down from **any avatar** reaches it; Up returns to the avatar that supplied focus, including after visiting Settings and returning. Left/Right still traverse only avatars. This supersedes the revision-5 whole-row centring and final-avatar-only Down rule. The 4 px accent straddle ring, 1.08 scale and focus-only Settings caption are unchanged.
|
||||
The Settings gear is horizontally centred beneath the complete people row, independent of person count or selection. Justin confirmed this placement. It uses the same 4 px accent straddle ring as the people, with the existing 1.08 scale and focus-only Settings caption.
|
||||
|
||||
Down from any avatar reaches the gear; Up returns to its origin, including after visiting Settings. Left/Right avatar traversal is unchanged.
|
||||
|
||||
Source — Justin (2026-11-07): “the settings icon moved, but pressing down only works from the last profile icon. I want it to always move there when pressing down in that screen”.
|
||||
|
||||
Root content Back moves to the nav; the next Back **finishes and removes Wolfskin’s Android task**, returning to the launcher without visiting an old Home/setup interface. This applies to Home, Discover, Movies, Shows and Anime. Cold-launch picker Back exits; a reopened picker first dismisses to its opener’s nav. Pushed title/person/settings/Updates pages pop their parent stack, and menus/sheets/unsaved-settings prompts get first refusal. A singleton full-screen page exits rather than becoming a dead end.
|
||||
|
||||
Source — Justin (2026-11-07): “pressing back enough times should close wolfskin, currently there is no way to go back to projectivity apart from weird methods via the old ui”.
|
||||
|
||||
## Focus visibility
|
||||
|
||||
“Centered” means consistent visibility, not geometric centering. Keep the approved shelf rule: one-card lookahead, shifting after the second-last visible slot, with first/last positions clamped to the actual contents. Short rows do not manufacture empty scroll space. Poster, tile, wide, service, episode, cast and related shelves follow the same rule.
|
||||
|
|
@ -18,7 +24,7 @@ Library and Person grids retain six columns and the existing Level 2 row spacing
|
|||
|
||||
## Home continuation and navigation — round 2 amendment
|
||||
|
||||
Home has one **Continue watching** lane for in-progress films/episodes and next-up episodes. Use the existing landscape-tile geometry, order by most recent actual watch activity, and show a series once: its resumable episode takes precedence over its next-up episode. Unknown activity dates retain source order after known dates. The non-rotating hero keeps its resume → next-up → newest → pick precedence and is not duplicated in the lane.
|
||||
Justin asked for one **Continue watching** lane merging in-progress films/episodes and next-up episodes. **Implementation choice:** reuse the existing Next up landscape-tile geometry for the merged lane, rather than the old Resume/wide geometry. Order by most recent actual watch activity and show a series once: its resumable episode takes precedence over its next-up episode. Unknown activity dates retain source order after known dates. The non-rotating hero keeps its resume → next-up → newest → pick precedence and is not duplicated in the lane.
|
||||
|
||||
The lane retains the `cw` identity. Legacy local, server, web and plugin Home settings merge saved Resume/Next up rows at the first watch row's position and preserve that row's view options. Existing serialized types remain readable; new settings offer only Continue watching.
|
||||
|
||||
|
|
@ -26,7 +32,7 @@ Every navigation entry owns its own viewport even while an outgoing page and inc
|
|||
|
||||
An unvisited Home row starts at its leftmost card rather than inheriting horizontal alignment from the previous row. Visited rows retain their remembered column and first-visible position across row changes, title Back and root-tab leave/return. Home does not adopt Discover’s tab-leave memory reset; Library keeps standard grid navigation. Outgoing title/person entries cannot intercept Android Back during their exit animation.
|
||||
|
||||
Landscape-card bottom gradients extend through the reserved state-line area, ending at the solid bottom backing with no exposed artwork band. The title-gradient top padding is **36 px / 18 dp**, down from 54 px / 27 dp; the approved 92% bottom opacity is unchanged. Captions and state lines retain their existing geometry.
|
||||
Landscape-card bottom gradients extend through the reserved state-line area, ending at the solid bottom backing with no exposed artwork band, as Justin requested. **Implementation choice for the amount:** title-gradient top padding is **36 px / 18 dp**, down from 54 px / 27 dp. The existing approved 92% bottom opacity is unchanged. Captions and state lines retain their existing geometry.
|
||||
|
||||
|
||||
## Episode artwork and dimensions
|
||||
|
|
|
|||
|
|
@ -233,9 +233,13 @@ The stroke is inset within the fixed 20 dp / 40 px height; horizontal border-box
|
|||
padding includes it. The 6 px dash / 4 px gap follows the browser's 3:2 stroke-width
|
||||
ratios. Resting borders are white at 22% opacity; focused borders use ink at 40%.
|
||||
|
||||
The small gear beneath the last avatar opens Settings with Requests focused.
|
||||
The small gear centred beneath the complete people row opens Settings with Requests focused.
|
||||
Down from any avatar reaches it; Up returns to the originating avatar, including
|
||||
after a Settings visit. Left/Right avatar traversal is unchanged.
|
||||
The navigation requirement comes from Justin's words: “the settings icon moved,
|
||||
but pressing down only works from the last profile icon. I want it to always
|
||||
move there when pressing down in that screen”. The approved gear placement stays
|
||||
centred beneath the complete people row.
|
||||
Settings groups hand off to existing upstream pages; Requests opens the household
|
||||
Coming-in sheet described below. **Advanced settings → Wolfskin screens** is the persistent
|
||||
rollout switch: turning it off renders upstream Home and library destinations with
|
||||
|
|
@ -251,6 +255,9 @@ pages pop normally. Child dialogs, title menus, request sheets and unsaved-setti
|
|||
prompts keep Back priority. Singleton full-screen pages also exit; they cannot
|
||||
fall through to the older setup/user UI.
|
||||
|
||||
Source — Justin: “pressing back enough times should close wolfskin, currently
|
||||
there is no way to go back to projectivity apart from weird methods via the old ui”.
|
||||
|
||||
`rememberWolfskinBackHandler` owns Android Back at the app root, including a
|
||||
single-entry `NavDisplay`; full-screen hand-offs use the same `NavigationManager`
|
||||
exit event rather than exposing the parent setup stack. `WolfskinRootExitTest`
|
||||
|
|
@ -680,9 +687,8 @@ The [revision-5 amendment](../data/tv-spec/spec.md) and
|
|||
[native frame prototype delta](../data/tv-v2/feedback-2026-11-06/index.html)
|
||||
retain the approved frames except for the requested feedback changes:
|
||||
|
||||
- Round 2 supersedes revision 5: the picker gear sits under the last avatar,
|
||||
is reachable with Down from every avatar, and returns Up to its origin.
|
||||
It retains the picker-person ring.
|
||||
- The picker gear retains its approved whole-row centring and picker-person ring.
|
||||
Down from every avatar reaches it; Up returns to the originating avatar.
|
||||
- Shelf tracks share second-last-slot lookahead, count clamping and settled
|
||||
offsets. Home records completed frame positioning rather than an animation
|
||||
that may still be cancelled; first mount restores the intended shelf item.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ 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; Down from any person reaches Settings below the final avatar. */
|
||||
/** The picker covers the nav; Down from any person reaches the centred Settings gear. */
|
||||
@Composable
|
||||
fun WhosWatching(state: ShellState, modifier: Modifier = Modifier) {
|
||||
Box(modifier.fillMaxSize().background(C.bg)) {
|
||||
|
|
@ -53,7 +53,7 @@ private fun PeoplePicker(state: ShellState) {
|
|||
}
|
||||
}
|
||||
}
|
||||
val left = (S.stageWidth - L.gear + (L.pickerAvatar + L.pickerGap) * (state.people.size - 1)) / 2
|
||||
val left = (S.stageWidth - L.gear) / 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) {
|
||||
|
|
|
|||
|
|
@ -49,16 +49,17 @@ class PickerNavigationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test fun settingsGearIsCenteredUnderTheFinalAvatarForAnyProfileCount() {
|
||||
@Test fun settingsGearIsCenteredUnderTheWholePeopleRowForAnyProfileCount() {
|
||||
val state = ShellState(fixturePeople(), "justin")
|
||||
rule.setContent { WolfskinTheme { ShellSurface(state) } }
|
||||
for (count in 1..5) {
|
||||
val people = (0 until count).map { ShellPerson("person-$it", "Person $it", "$it", false) }
|
||||
rule.runOnIdle { state.updatePeople(people); state.gearFocused = true }
|
||||
rule.mainClock.advanceTimeBy(400)
|
||||
val first = rule.onNodeWithTag("picker-person:${people.first().key}").fetchSemanticsNode().boundsInRoot
|
||||
val last = rule.onNodeWithTag("picker-person:${people.last().key}").fetchSemanticsNode().boundsInRoot
|
||||
val gear = rule.onNodeWithTag("picker-settings").fetchSemanticsNode().boundsInRoot
|
||||
assertEquals("Settings must stay under the last profile for $count people", last.center.x, gear.center.x, .1f)
|
||||
assertEquals("Settings must stay centred under the whole row for $count people", (first.center.x + last.center.x) / 2, gear.center.x, .1f)
|
||||
assertTrue("Settings must be below the avatars", gear.top > last.bottom)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue