Fix highlighting the wrong 'more' nav drawer item (#1515)

## Description
Fixes an issue where the wrong nav drawer item would be highlighted in
the "More" section

Previously, displaying the discover nav item was partially handled in
the view model state and partially within the UI code which caused this
bug. This PR moves it all into the view model state.

### Related issues
N/A

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-06-03 20:46:57 -04:00 • committed by GitHub
parent 471dbd62db
commit a1b372667b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 107 additions and 128 deletions

View file

@ -67,7 +67,6 @@ import androidx.tv.material3.NavigationDrawerItemDefaults
import androidx.tv.material3.NavigationDrawerScope
import androidx.tv.material3.ProvideTextStyle
import androidx.tv.material3.Text
import androidx.tv.material3.surfaceColorAtElevation
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.model.JellyfinServer
import com.github.damontecres.wholphin.data.model.JellyfinUser
@ -120,7 +119,6 @@ class NavDrawerViewModel
index: Int,
item: NavDrawerItem,
) {
if (item !is NavDrawerItem.More) setShowMore(false)
when (item) {
NavDrawerItem.Favorites -> {
setIndex(index)
@ -163,48 +161,40 @@ class NavDrawerViewModel
fun updateSelectedIndex() {
viewModelScope.launchDefault {
val asDestinations =
(
serviceState.value.items +
listOf(
NavDrawerItem.More,
NavDrawerItem.Discover,
) + serviceState.value.moreItems
).map {
if (it is ServerNavDrawerItem) {
it.destination
} else if (it is NavDrawerItem.Favorites) {
Destination.Favorites
} else if (it is NavDrawerItem.Discover) {
Destination.Discover
} else {
null
buildList {
addAll(serviceState.value.items)
addAll(serviceState.value.moreItems)
}.map {
when (it) {
is ServerNavDrawerItem -> it.destination
is NavDrawerItem.Favorites -> Destination.Favorites
is NavDrawerItem.Discover -> Destination.Discover
else -> null
}
}
val backstack = navigationManager.backStack.toList().reversed()
for (i in 0..<backstack.size) {
val key = backstack[i]
if (key is Destination) {
val index =
if (key is Destination.Home) {
HOME_INDEX
} else if (key is Destination.Search) {
SEARCH_INDEX
} else if (key is Destination.NowPlaying) {
NOW_PLAYING_INDEX
val index =
if (key is Destination.Home) {
HOME_INDEX
} else if (key is Destination.Search) {
SEARCH_INDEX
} else if (key is Destination.NowPlaying) {
NOW_PLAYING_INDEX
} else {
val idx = asDestinations.indexOf(key)
if (idx >= 0) {
idx
} else {
val idx = asDestinations.indexOf(key)
if (idx >= 0) {
idx
} else {
null
}
null
}
Timber.v("Found $index => $key")
if (index != null) {
_state.update { it.copy(selectedIndex = index) }
break
}
Timber.v("Found $index => $key")
if (index != null) {
_state.update { it.copy(selectedIndex = index) }
break
}
}
}
@ -455,25 +445,23 @@ fun NavDrawer(
)
}
itemsIndexed(serviceState.items) { index, it ->
if (it !is NavDrawerItem.Discover || serviceState.discoverEnabled) {
val interactionSource = remember { MutableInteractionSource() }
NavItem(
library = it,
selected = selectedIndex == index,
moreExpanded = moreExpanded,
drawerOpen = isOpen,
interactionSource = interactionSource,
onClick = {
viewModel.onClickDrawerItem(index, it)
},
modifier =
Modifier
.ifElse(
selectedIndex == index,
Modifier.focusRequester(focusRequester),
),
)
}
val interactionSource = remember { MutableInteractionSource() }
NavItem(
library = it,
selected = selectedIndex == index,
moreExpanded = moreExpanded,
drawerOpen = isOpen,
interactionSource = interactionSource,
onClick = {
viewModel.onClickDrawerItem(index, it)
},
modifier =
Modifier
.ifElse(
selectedIndex == index,
Modifier.focusRequester(focusRequester),
),
)
}
if (serviceState.moreItems.isNotEmpty()) {
item {
@ -481,7 +469,7 @@ fun NavDrawer(
val interactionSource = remember { MutableInteractionSource() }
NavItem(
library = NavDrawerItem.More,
selected = selectedIndex == index,
selected = false,
moreExpanded = moreExpanded,
drawerOpen = isOpen,
interactionSource = interactionSource,
@ -500,35 +488,33 @@ fun NavDrawer(
if (moreExpanded) {
itemsIndexed(serviceState.moreItems) { index, it ->
val adjustedIndex =
remember(serviceState) { (index + serviceState.items.size + 1) }
if (it !is NavDrawerItem.Discover || serviceState.discoverEnabled) {
val interactionSource = remember { MutableInteractionSource() }
NavItem(
library = it,
selected = selectedIndex == adjustedIndex,
moreExpanded = moreExpanded,
drawerOpen = isOpen,
onClick = {
viewModel.onClickDrawerItem(
adjustedIndex,
it,
)
remember(serviceState) { (index + serviceState.items.size) }
val interactionSource = remember { MutableInteractionSource() }
NavItem(
library = it,
selected = selectedIndex == adjustedIndex,
moreExpanded = moreExpanded,
drawerOpen = isOpen,
onClick = {
viewModel.onClickDrawerItem(
adjustedIndex,
it,
)
},
containerColor =
if (isOpen) {
MaterialTheme.colorScheme.surface.copy(alpha = .5f)
} else {
Color.Unspecified
},
containerColor =
if (isOpen) {
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)
} else {
Color.Unspecified
},
interactionSource = interactionSource,
modifier =
Modifier
.ifElse(
selectedIndex == adjustedIndex,
Modifier.focusRequester(focusRequester),
),
)
}
interactionSource = interactionSource,
modifier =
Modifier
.ifElse(
selectedIndex == adjustedIndex,
Modifier.focusRequester(focusRequester),
),
)
}
}
item {

View file

@ -31,7 +31,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.datastore.core.DataStore
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -44,9 +43,7 @@ import com.github.damontecres.wholphin.data.ServerPreferencesDao
import com.github.damontecres.wholphin.data.ServerRepository
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
import com.github.damontecres.wholphin.data.model.NavPinType
import com.github.damontecres.wholphin.preferences.AppPreferences
import com.github.damontecres.wholphin.services.BackdropService
import com.github.damontecres.wholphin.services.NavDrawerItemState
import com.github.damontecres.wholphin.services.NavDrawerService
import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.SeerrServerRepository
@ -60,7 +57,6 @@ import com.github.damontecres.wholphin.ui.main.settings.MoveDirection
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
import com.github.damontecres.wholphin.util.ExceptionHandler
import com.github.damontecres.wholphin.util.RememberTabManager
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
@ -69,7 +65,6 @@ import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient
import javax.inject.Inject
data class NavDrawerPin(
@ -304,11 +299,8 @@ class NavDrawerPreferencesViewModel
@Inject
constructor(
@param:ApplicationContext private val context: Context,
private val api: ApiClient,
val preferenceDataStore: DataStore<AppPreferences>,
val navigationManager: NavigationManager,
val backdropService: BackdropService,
private val rememberTabManager: RememberTabManager,
private val serverRepository: ServerRepository,
private val navDrawerService: NavDrawerService,
private val serverPreferencesDao: ServerPreferencesDao,
@ -321,7 +313,7 @@ class NavDrawerPreferencesViewModel
val state = navDrawerService.state.value
val user = serverRepository.currentUser
val seerr = seerrServerRepository.active.firstOrNull()
if (state == NavDrawerItemState.EMPTY || user == null || seerr == null) {
if (user == null || seerr == null) {
return@launchDefault
}
val navDrawerPins =
@ -372,7 +364,8 @@ class NavDrawerPreferencesViewModel
)
}
serverPreferencesDao.saveNavDrawerPinnedItems(*toSave.toTypedArray())
navDrawerService.updateNavDrawer(user, userDto)
val discoverActive = seerrServerRepository.active.firstOrNull() == true
navDrawerService.updateNavDrawer(user, userDto, discoverActive)
} else {
throw IllegalStateException("User IDs do not match")
}