Restore household colours on the cold-start profile picker
This commit is contained in:
parent
4af1898fd2
commit
27b7554fc1
3 changed files with 34 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
|||
package org.justinvisser.wolfskin.tv
|
||||
|
||||
import android.app.Application
|
||||
import android.graphics.BitmapFactory
|
||||
import android.content.Intent
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
|
|
@ -11,6 +12,7 @@ import androidx.compose.runtime.mutableStateListOf
|
|||
import androidx.compose.runtime.snapshots.Snapshot
|
||||
import org.robolectric.Shadows
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.test.*
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.datastore.core.DataStore
|
||||
|
|
@ -46,6 +48,7 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.justinvisser.wolfskin.conductarr.MemoryCacheStore
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.justinvisser.wolfskin.design.WolfskinTokens
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
|
|
@ -137,6 +140,34 @@ class WolfskinSetupNavigationTest {
|
|||
coVerify(exactly = 0) { repository.switchServerOrUser() }
|
||||
}
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
@Test fun coldStartSavedPeopleKeepTheirOwnColorsWithoutConductarr() {
|
||||
val saved = listOf(user, user.copy(id = UUID.randomUUID(), name = "Mindel"),
|
||||
user.copy(id = UUID.randomUUID(), name = "Shared"))
|
||||
every { repository.serverDao.getServer(server.id) } returns JellyfinServerUsers(server, saved)
|
||||
runBlocking { appModel().handleAppStart() }
|
||||
mount()
|
||||
assertOwnPicker()
|
||||
saved.forEach { rule.onNodeWithText(it.name!!).assertIsDisplayed() }
|
||||
rule.mainClock.advanceTimeBy(1_000)
|
||||
rule.waitForIdle()
|
||||
val people = model.picker!!.people
|
||||
val bounds = people.map { rule.onNodeWithTag("picker-person:${it.key}").fetchSemanticsNode().boundsInRoot }
|
||||
val directory = File(requireNotNull(System.getProperty("wolfskin.captureDirectory")), "setup").apply { mkdirs() }
|
||||
val frame = File(directory, "cold-start-people.png")
|
||||
rule.onRoot().captureRoboImage(frame)
|
||||
val bitmap = BitmapFactory.decodeFile(frame.absolutePath)
|
||||
try {
|
||||
val fills = bounds.map { bitmap.getPixel(it.center.x.toInt(), (it.top + it.width / 5).toInt()) }
|
||||
assertEquals(listOf(WolfskinTokens.PersonColor.justin.toArgb(),
|
||||
WolfskinTokens.PersonColor.mindel.toArgb(), WolfskinTokens.PersonColor.shared.toArgb()), fills)
|
||||
} finally {
|
||||
bitmap.recycle()
|
||||
}
|
||||
assertNull(conductarr.identity.value)
|
||||
assertEquals(saved.map { it.id.toString() }, people.map { it.jellyfinUserId })
|
||||
}
|
||||
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
@Test fun unreachableSelectionRendersWolfskinRecoveryFrame() {
|
||||
stack[0] = SetupDestination.UserList(server)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class WolfskinSetupViewModel @Inject constructor(
|
|||
if (users.isEmpty()) {
|
||||
showLogin(null)
|
||||
} else {
|
||||
val people = users.map { ShellPerson(it.id.toString(), it.name.orEmpty(), it.name.orEmpty().take(1).uppercase(), false, it.id.toString()) }
|
||||
val people = users.map { ShellPerson(it.name.orEmpty().lowercase(), it.name.orEmpty(), it.name.orEmpty().take(1).uppercase(), false, it.id.toString()) }
|
||||
picker = ShellState(people, people.first().key) { onAction(it) }
|
||||
stage = Stage.Picker
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ Down from any avatar reaches the gear; Up returns to its origin, including after
|
|||
|
||||
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”.
|
||||
|
||||
Saved profiles retain their approved household colours before Conductarr answers: Justin **#62c4ff**, Mindel **#ff9d72**, Shared **#9be38f**. Setup uses the same lowercase-name presentation key as the signed-in picker; the separate Jellyfin user ID remains the authentication identity. `WolfskinSetupNavigationTest.coldStartSavedPeopleKeepTheirOwnColorsWithoutConductarr` exercises the real cold-start setup boundary and checks the native avatar-fill pixels without a Conductarr session.
|
||||
|
||||
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.
|
||||
|
||||
Native Android Back (`KEYCODE_BACK`) belongs exclusively to the activity’s system dispatcher, including Navigation 3 predictive completion; Compose key previews must not also navigate on its raw key-down. Escape remains the existing local keyboard Back shortcut. Each completed system Back has one consumer. A retained title/person callback checks the live navigation entry at invocation and hands Back to the incoming entry if its own entry has already popped; it does not depend on an enabled flag catching up with the exit animation. Root handling synchronizes the shell route to the current entry before applying content → nav → task exit. Back ownership is exercised on both SDK 34 (Android 14) and SDK 36.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue