Move home page over to use custom settings

This commit is contained in:
Damontecres 2026-01-24 21:54:57 -05:00
parent 9834991392
commit ce4f8475b0
No known key found for this signature in database
5 changed files with 150 additions and 60 deletions

View file

@ -265,8 +265,7 @@ class MainActivity : AppCompatActivity() {
server = current.server,
startDestination =
requestedDestination
// TODO Undo
?: Destination.HomeSettings,
?: Destination.Home(),
navigationManager = navigationManager,
preferences = preferences,
modifier = Modifier.fillMaxSize(),

View file

@ -309,16 +309,15 @@ class HomeSettingsService
userDto: UserDto,
libraries: List<Library>,
limit: Int = prefs.maxItemsPerRow,
): List<HomeRowLoadingState> =
): HomeRowLoadingState =
when (row) {
is HomeRowConfig.ContinueWatching -> {
val resume = latestNextUpService.getResume(userDto.id, limit, true)
listOf(
HomeRowLoadingState.Success(
title = context.getString(R.string.continue_watching),
items = resume,
viewOptions = row.viewOptions,
),
)
}
@ -330,12 +329,11 @@ class HomeSettingsService
prefs.enableRewatchingNextUp,
false,
)
listOf(
HomeRowLoadingState.Success(
title = context.getString(R.string.next_up),
items = nextUp,
viewOptions = row.viewOptions,
),
)
}
@ -350,7 +348,6 @@ class HomeSettingsService
false,
)
listOf(
HomeRowLoadingState.Success(
title = context.getString(R.string.continue_watching),
items =
@ -359,7 +356,6 @@ class HomeSettingsService
nextUp,
),
viewOptions = row.viewOptions,
),
)
}
@ -397,12 +393,11 @@ class HomeSettingsService
val title =
name?.let { context.getString(R.string.genres_in, it) }
?: context.getString(R.string.genres)
listOf(
HomeRowLoadingState.Success(
title,
genres,
viewOptions = row.viewOptions,
),
)
}
@ -435,7 +430,7 @@ class HomeSettingsService
row.viewOptions,
)
}
listOf(latest)
latest
}
is HomeRowConfig.RecentlyReleased -> {
@ -461,12 +456,10 @@ class HomeSettingsService
.content.items
.map { BaseItem.Companion.from(it, api, true) }
.let {
listOf(
HomeRowLoadingState.Success(
title,
it,
row.viewOptions,
),
)
}
}
@ -491,12 +484,10 @@ class HomeSettingsService
.content.items
.map { BaseItem(it, true) }
.let {
listOf(
HomeRowLoadingState.Success(
name ?: context.getString(R.string.collection),
it,
row.viewOptions,
),
)
}
}
@ -529,12 +520,10 @@ class HomeSettingsService
.content.items
.map { BaseItem.Companion.from(it, api, true) }
.let {
listOf(
HomeRowLoadingState.Success(
name ?: context.getString(R.string.collection),
it,
row.viewOptions,
),
)
}
}

View file

@ -21,6 +21,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
@ -90,12 +91,10 @@ fun HomePage(
LaunchedEffect(Unit) {
viewModel.init()
}
val loading by viewModel.loadingState.observeAsState(LoadingState.Loading)
val refreshing by viewModel.refreshState.observeAsState(LoadingState.Loading)
val watchingRows by viewModel.watchingRows.observeAsState(listOf())
val latestRows by viewModel.latestRows.observeAsState(listOf())
val homeRows = remember(watchingRows, latestRows) { watchingRows + latestRows }
val state by viewModel.state.collectAsState()
val loading = state.loadingState
val refreshing = state.refreshState
val homeRows = state.homeRows
when (val state = loading) {
is LoadingState.Error -> {

View file

@ -8,14 +8,16 @@ import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.NavDrawerItemRepository
import com.github.damontecres.wholphin.data.ServerRepository
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.data.model.HomePageResolvedSettings
import com.github.damontecres.wholphin.services.BackdropService
import com.github.damontecres.wholphin.services.DatePlayedService
import com.github.damontecres.wholphin.services.FavoriteWatchManager
import com.github.damontecres.wholphin.services.HomeSettingsService
import com.github.damontecres.wholphin.services.LatestNextUpService
import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.main.settings.Library
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
import com.github.damontecres.wholphin.ui.setValueOnMain
import com.github.damontecres.wholphin.ui.showToast
@ -26,7 +28,15 @@ import com.github.damontecres.wholphin.util.LoadingState
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.api.CollectionType
@ -44,6 +54,7 @@ class HomeViewModel
val navigationManager: NavigationManager,
val serverRepository: ServerRepository,
val navDrawerItemRepository: NavDrawerItemRepository,
private val homeSettingsService: HomeSettingsService,
private val favoriteWatchManager: FavoriteWatchManager,
private val datePlayedService: DatePlayedService,
private val latestNextUpService: LatestNextUpService,
@ -55,7 +66,8 @@ class HomeViewModel
val watchingRows = MutableLiveData<List<HomeRowLoadingState>>(listOf())
val latestRows = MutableLiveData<List<HomeRowLoadingState>>(listOf())
private lateinit var preferences: UserPreferences
private val _state = MutableStateFlow(HomeState.EMPTY)
val state: StateFlow<HomeState> = _state
init {
datePlayedService.invalidateAll()
@ -76,12 +88,86 @@ class HomeViewModel
loadingState.setValueOnMain(LoadingState.Loading)
}
refreshState.setValueOnMain(LoadingState.Loading)
this@HomeViewModel.preferences = userPreferencesService.getCurrent()
val preferences = userPreferencesService.getCurrent()
val prefs = preferences.appPreferences.homePagePreferences
val limit = prefs.maxItemsPerRow
if (reload) {
backdropService.clearBackdrop()
}
val navDrawerItems =
navDrawerItemRepository
.getNavDrawerItems()
val libraries =
navDrawerItems
.filter { it is ServerNavDrawerItem }
.map {
it as ServerNavDrawerItem
Library(it.itemId, it.name, it.type)
}
serverRepository.currentUserDto.value?.let { userDto ->
val settings =
homeSettingsService.currentSettings.first { it != HomePageResolvedSettings.EMPTY }
val state = state.value
// Refreshing if a load has already occurred and the rows haven't significantly changed
val refresh =
state.loadingState == LoadingState.Success && state.settings == settings
val semaphore = Semaphore(4)
val loadingRows =
if (refresh) {
state.homeRows
} else {
mutableListOf()
}
val deferred =
settings.rows.mapIndexed { index, row ->
if (refresh) {
(loadingRows as MutableList).add(HomeRowLoadingState.Loading(row.title))
}
viewModelScope.async(Dispatchers.IO) {
semaphore.withPermit {
Timber.v("Fetching row: %s", row)
try {
homeSettingsService.fetchDataForRow(
row = row.config,
scope = viewModelScope,
prefs = prefs,
userDto = userDto,
libraries = libraries,
limit = prefs.maxItemsPerRow,
)
} catch (ex: Exception) {
Timber.e(ex, "Error on row %s", row)
HomeRowLoadingState.Error(row.title, exception = ex)
}
}
}
}
if (refresh) {
deferred.firstOrNull()?.await()?.let {
(loadingRows as MutableList)[0] = it
}
_state.update {
it.copy(
loadingState = LoadingState.Success,
homeRows = loadingRows,
)
}
}
val rows = deferred.awaitAll()
Timber.v("Got all rows")
_state.update {
it.copy(
loadingState = LoadingState.Success,
refreshState = LoadingState.Success,
homeRows = rows,
)
}
}
try {
serverRepository.currentUserDto.value?.let { userDto ->
val includedIds =
@ -192,3 +278,20 @@ data class LatestData(
val title: String,
val request: GetLatestMediaRequest,
)
data class HomeState(
val loadingState: LoadingState,
val refreshState: LoadingState,
val homeRows: List<HomeRowLoadingState>,
val settings: HomePageResolvedSettings,
) {
companion object {
val EMPTY =
HomeState(
LoadingState.Pending,
LoadingState.Pending,
listOf(),
HomePageResolvedSettings.EMPTY,
)
}
}

View file

@ -96,7 +96,7 @@ class HomeSettingsViewModel
libraries = state.libraries,
limit = limit,
)
}.flatten()
}
}
}
rows?.let { rows ->