feat: add online status handling to navigation and UI components

This commit is contained in:
2026-05-14 12:39:20 +02:00
parent a92c10a07c
commit 83730188eb
6 changed files with 44 additions and 15 deletions

View File

@@ -13,23 +13,26 @@ import androidx.compose.runtime.Composable
@Composable
fun AppBottomBar(
selectedTab: Int,
isOnline: Boolean,
onTabSelected: (Int) -> Unit
) {
NavigationBar {
if (isOnline) {
NavigationBarItem(
selected = selectedTab == 0,
onClick = { onTabSelected(0) },
icon = { Icon(Icons.Outlined.Home, contentDescription = "Home") },
label = { Text("Home") }
)
NavigationBarItem(
selected = selectedTab == 1,
onClick = { onTabSelected(1) },
icon = { Icon(Icons.Outlined.Collections, contentDescription = "Libraries") },
label = { Text("Libraries") }
)
}
NavigationBarItem(
selected = selectedTab == 0,
onClick = { onTabSelected(0) },
icon = { Icon(Icons.Outlined.Home, contentDescription = "Home") },
label = { Text("Home") }
)
NavigationBarItem(
selected = selectedTab == 1,
onClick = { onTabSelected(1) },
icon = { Icon(Icons.Outlined.Collections, contentDescription = "Libraries") },
label = { Text("Libraries") }
)
NavigationBarItem(
selected = selectedTab == 2,
selected = !isOnline || selectedTab == 2,
onClick = { onTabSelected(2) },
icon = { Icon(Icons.Outlined.Download, contentDescription = "Downloads") },
label = { Text("Downloads") }

View File

@@ -44,6 +44,7 @@ fun AppScreen(
val continueWatching by viewModel.continueWatching.collectAsState()
val nextUp by viewModel.nextUp.collectAsState()
val isRefreshing by viewModel.isRefreshing.collectAsState()
val isOnline by viewModel.isOnline.collectAsState()
val isCheckingForUpdates by updateViewModel.isCheckingForUpdates.collectAsState()
val availableUpdate by updateViewModel.availableUpdate.collectAsState()
val navigationManager = LocalNavigationManager.current
@@ -54,6 +55,13 @@ fun AppScreen(
val currentRoute = backStack.lastOrNull() ?: AppTabRoute.Home
val selectedTab = currentRoute.toTabIndex()
LaunchedEffect(isOnline, currentRoute, backStack) {
if (!isOnline && currentRoute != AppTabRoute.Downloads) {
backStack.clear()
backStack.add(AppTabRoute.Downloads)
}
}
LifecycleResumeEffect(Unit) {
viewModel.onResumed()
onPauseOrDispose { }
@@ -69,9 +77,9 @@ fun AppScreen(
}
}
val onTabSelected = remember(backStack) {
val onTabSelected = remember(backStack, isOnline) {
{ selectedIndex: Int ->
val route = selectedIndex.toAppTabRoute()
val route = if (isOnline) selectedIndex.toAppTabRoute() else AppTabRoute.Downloads
if (backStack.lastOrNull() != route) {
backStack.add(route)
}
@@ -104,6 +112,7 @@ fun AppScreen(
onSearchClick = viewModel::openSearch,
snackbarHostState = snackbarHostState,
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected,
modifier = Modifier.fillMaxSize()
)
@@ -114,6 +123,7 @@ fun AppScreen(
onLibrarySelected = { item -> viewModel.onLibrarySelected(item.id, item.name) },
onSearchClick = viewModel::openSearch,
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected,
modifier = Modifier.fillMaxSize()
)
@@ -121,6 +131,7 @@ fun AppScreen(
entry<AppTabRoute.Downloads>(metadata = appTabMetadata(AppTabRoute.Downloads)) {
DownloadsScreen(
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected,
modifier = Modifier.fillMaxSize()
)

View File

@@ -12,6 +12,7 @@ import hu.bbara.purefin.ui.screen.AppBottomBar
@Composable
fun DownloadsScreen(
selectedTab: Int,
isOnline: Boolean,
onTabSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
@@ -22,6 +23,7 @@ fun DownloadsScreen(
bottomBar = {
AppBottomBar(
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected
)
}

View File

@@ -35,6 +35,7 @@ fun HomeScreen(
onSearchClick: () -> Unit,
snackbarHostState: SnackbarHostState,
selectedTab: Int,
isOnline: Boolean,
onTabSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
@@ -57,6 +58,7 @@ fun HomeScreen(
bottomBar = {
AppBottomBar(
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected
)
}

View File

@@ -17,6 +17,7 @@ fun LibrariesScreen(
onLibrarySelected: (LibraryUiModel) -> Unit,
onSearchClick: () -> Unit,
selectedTab: Int,
isOnline: Boolean,
onTabSelected: (Int) -> Unit,
modifier: Modifier = Modifier
) {
@@ -32,6 +33,7 @@ fun LibrariesScreen(
bottomBar = {
AppBottomBar(
selectedTab = selectedTab,
isOnline = isOnline,
onTabSelected = onTabSelected
)
}

View File

@@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import hu.bbara.purefin.core.data.HomeRepository
import hu.bbara.purefin.core.data.LocalMediaRepository
import hu.bbara.purefin.core.data.NetworkMonitor
import hu.bbara.purefin.core.data.UserSessionRepository
import hu.bbara.purefin.core.download.MediaDownloadController
import hu.bbara.purefin.core.jellyfin.JellyfinMediaMetadataUpdater
@@ -40,11 +41,19 @@ class AppViewModel @Inject constructor(
private val jellyfinMediaMetadataUpdater: JellyfinMediaMetadataUpdater,
private val navigationManager: NavigationManager,
private val mediaDownloadManager: MediaDownloadController,
networkMonitor: NetworkMonitor,
) : ViewModel() {
private val _isRefreshing = MutableStateFlow(false)
val isRefreshing: StateFlow<Boolean> = _isRefreshing.asStateFlow()
val isOnline: StateFlow<Boolean> = networkMonitor.isOnline
.stateIn(
viewModelScope,
SharingStarted.Eagerly,
false
)
val serverUrl: StateFlow<String> = userSessionRepository.serverUrl
.stateIn(
viewModelScope,