fix(android): MainAppBarActions sources isAdmin internally
The isAdmin parameter on MainAppBarActions defaulted to false and no call site passed it, so the Admin overflow item never appeared for actual admins — leaving the admin section unreachable from normal UI. Move the lookup into a tiny AppBarActionsViewModel that reads AuthController.currentUser, and drop the parameter from the public signature so future call sites can't recreate the dead-param hazard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
package com.fabledsword.minstrel.shared.widgets
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.fabledsword.minstrel.auth.AuthController
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val SHARE_STOP_TIMEOUT_MS = 5_000L
|
||||
|
||||
/**
|
||||
* Backs [MainAppBarActions] with the current user's admin flag so the
|
||||
* overflow "Admin" item appears for every admin without each shell
|
||||
* screen having to plumb the value through. Sourced from
|
||||
* [AuthController.currentUser] so it stays live across sign-in,
|
||||
* sign-out, and role changes pushed via rehydration.
|
||||
*/
|
||||
@HiltViewModel
|
||||
class AppBarActionsViewModel @Inject constructor(
|
||||
authController: AuthController,
|
||||
) : ViewModel() {
|
||||
val isAdmin: StateFlow<Boolean> = authController.currentUser
|
||||
.map { it?.isAdmin == true }
|
||||
.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(SHARE_STOP_TIMEOUT_MS),
|
||||
initialValue = false,
|
||||
)
|
||||
}
|
||||
+7
-2
@@ -11,6 +11,8 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavHostController
|
||||
import com.composables.icons.lucide.House
|
||||
import com.composables.icons.lucide.LibraryBig
|
||||
@@ -33,7 +35,9 @@ import com.fabledsword.minstrel.nav.Settings as SettingsRoute
|
||||
* [Home] [Library] [Search] [ ⋮ Playlists / Discover / Settings / Admin ]
|
||||
*
|
||||
* The icon for the screen the user is currently on is suppressed so
|
||||
* the action set looks contextual.
|
||||
* the action set looks contextual. The "Admin" overflow item is
|
||||
* sourced internally from [AppBarActionsViewModel] so admins see it
|
||||
* everywhere without each call site having to plumb the flag.
|
||||
*
|
||||
* `currentRouteName` is a soft string match against the destination
|
||||
* route name (route classes serialize to their FQN by default in
|
||||
@@ -43,8 +47,9 @@ import com.fabledsword.minstrel.nav.Settings as SettingsRoute
|
||||
fun MainAppBarActions(
|
||||
navController: NavHostController,
|
||||
currentRouteName: String?,
|
||||
isAdmin: Boolean = false,
|
||||
viewModel: AppBarActionsViewModel = hiltViewModel(),
|
||||
) {
|
||||
val isAdmin by viewModel.isAdmin.collectAsStateWithLifecycle()
|
||||
Row {
|
||||
if (currentRouteName != Home::class.qualifiedName) {
|
||||
IconButton(onClick = { navController.navigate(Home) }) {
|
||||
|
||||
Reference in New Issue
Block a user