mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Move data loading to HomeSettingsService
This commit is contained in:
parent
a174d981a8
commit
9834991392
3 changed files with 275 additions and 262 deletions
|
|
@ -3,15 +3,24 @@ package com.github.damontecres.wholphin.services
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.NavDrawerItemRepository
|
import com.github.damontecres.wholphin.data.NavDrawerItemRepository
|
||||||
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.data.model.HomePageResolvedSettings
|
import com.github.damontecres.wholphin.data.model.HomePageResolvedSettings
|
||||||
import com.github.damontecres.wholphin.data.model.HomePageSettings
|
import com.github.damontecres.wholphin.data.model.HomePageSettings
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowConfig
|
import com.github.damontecres.wholphin.data.model.HomeRowConfig
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowConfigDisplay
|
import com.github.damontecres.wholphin.data.model.HomeRowConfigDisplay
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
||||||
|
import com.github.damontecres.wholphin.preferences.HomePagePreferences
|
||||||
|
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.components.getGenreImageMap
|
||||||
import com.github.damontecres.wholphin.ui.main.settings.Library
|
import com.github.damontecres.wholphin.ui.main.settings.Library
|
||||||
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
||||||
import com.github.damontecres.wholphin.ui.toServerString
|
import com.github.damontecres.wholphin.ui.toServerString
|
||||||
|
import com.github.damontecres.wholphin.util.GetGenresRequestHandler
|
||||||
|
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||||
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
|
@ -22,6 +31,12 @@ import org.jellyfin.sdk.api.client.ApiClient
|
||||||
import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi
|
import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
||||||
import org.jellyfin.sdk.model.UUID
|
import org.jellyfin.sdk.model.UUID
|
||||||
|
import org.jellyfin.sdk.model.api.ItemSortBy
|
||||||
|
import org.jellyfin.sdk.model.api.SortOrder
|
||||||
|
import org.jellyfin.sdk.model.api.UserDto
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetGenresRequest
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest
|
||||||
import org.jellyfin.sdk.model.serializer.toUUID
|
import org.jellyfin.sdk.model.serializer.toUUID
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -36,6 +51,8 @@ class HomeSettingsService
|
||||||
private val api: ApiClient,
|
private val api: ApiClient,
|
||||||
private val userPreferencesService: UserPreferencesService,
|
private val userPreferencesService: UserPreferencesService,
|
||||||
private val navDrawerItemRepository: NavDrawerItemRepository,
|
private val navDrawerItemRepository: NavDrawerItemRepository,
|
||||||
|
private val latestNextUpService: LatestNextUpService,
|
||||||
|
private val imageUrlService: ImageUrlService,
|
||||||
) {
|
) {
|
||||||
val jsonParser =
|
val jsonParser =
|
||||||
Json {
|
Json {
|
||||||
|
|
@ -285,6 +302,244 @@ class HomeSettingsService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun fetchDataForRow(
|
||||||
|
row: HomeRowConfig,
|
||||||
|
scope: CoroutineScope,
|
||||||
|
prefs: HomePagePreferences,
|
||||||
|
userDto: UserDto,
|
||||||
|
libraries: List<Library>,
|
||||||
|
limit: Int = prefs.maxItemsPerRow,
|
||||||
|
): List<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,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.NextUp -> {
|
||||||
|
val nextUp =
|
||||||
|
latestNextUpService.getNextUp(
|
||||||
|
userDto.id,
|
||||||
|
limit,
|
||||||
|
prefs.enableRewatchingNextUp,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title = context.getString(R.string.next_up),
|
||||||
|
items = nextUp,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.ContinueWatchingCombined -> {
|
||||||
|
val resume =
|
||||||
|
latestNextUpService.getResume(userDto.id, limit, true)
|
||||||
|
val nextUp =
|
||||||
|
latestNextUpService.getNextUp(
|
||||||
|
userDto.id,
|
||||||
|
limit,
|
||||||
|
prefs.enableRewatchingNextUp,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title = context.getString(R.string.continue_watching),
|
||||||
|
items =
|
||||||
|
latestNextUpService.buildCombined(
|
||||||
|
resume,
|
||||||
|
nextUp,
|
||||||
|
),
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.Genres -> {
|
||||||
|
val request =
|
||||||
|
GetGenresRequest(
|
||||||
|
parentId = row.parentId,
|
||||||
|
userId = userDto.id,
|
||||||
|
limit = limit,
|
||||||
|
)
|
||||||
|
val items =
|
||||||
|
GetGenresRequestHandler
|
||||||
|
.execute(api, request)
|
||||||
|
.content.items
|
||||||
|
val genreIds = items.map { it.id }
|
||||||
|
val genreImages =
|
||||||
|
getGenreImageMap(
|
||||||
|
api = api,
|
||||||
|
scope = scope,
|
||||||
|
imageUrlService = imageUrlService,
|
||||||
|
genres = genreIds,
|
||||||
|
parentId = row.parentId,
|
||||||
|
includeItemTypes = null,
|
||||||
|
cardWidthPx = null,
|
||||||
|
)
|
||||||
|
val genres =
|
||||||
|
items.map {
|
||||||
|
BaseItem(it, false, genreImages[it.id])
|
||||||
|
}
|
||||||
|
|
||||||
|
val name =
|
||||||
|
libraries
|
||||||
|
.firstOrNull { it.itemId == row.parentId }
|
||||||
|
?.name
|
||||||
|
val title =
|
||||||
|
name?.let { context.getString(R.string.genres_in, it) }
|
||||||
|
?: context.getString(R.string.genres)
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title,
|
||||||
|
genres,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.RecentlyAdded -> {
|
||||||
|
val name =
|
||||||
|
libraries
|
||||||
|
.firstOrNull { it.itemId == row.parentId }
|
||||||
|
?.name
|
||||||
|
val title =
|
||||||
|
name?.let { context.getString(R.string.recently_added_in, it) }
|
||||||
|
?: context.getString(R.string.recently_added)
|
||||||
|
val request =
|
||||||
|
GetLatestMediaRequest(
|
||||||
|
fields = SlimItemFields,
|
||||||
|
imageTypeLimit = 1,
|
||||||
|
parentId = row.parentId,
|
||||||
|
groupItems = true,
|
||||||
|
limit = limit,
|
||||||
|
isPlayed = null, // Server will handle user's preference
|
||||||
|
)
|
||||||
|
val latest =
|
||||||
|
api.userLibraryApi
|
||||||
|
.getLatestMedia(request)
|
||||||
|
.content
|
||||||
|
.map { BaseItem.Companion.from(it, api, true) }
|
||||||
|
.let {
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title,
|
||||||
|
it,
|
||||||
|
row.viewOptions,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
listOf(latest)
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.RecentlyReleased -> {
|
||||||
|
val name =
|
||||||
|
libraries
|
||||||
|
.firstOrNull { it.itemId == row.parentId }
|
||||||
|
?.name
|
||||||
|
val title =
|
||||||
|
name?.let {
|
||||||
|
context.getString(R.string.recently_released_in, it)
|
||||||
|
} ?: context.getString(R.string.recently_released)
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
parentId = row.parentId,
|
||||||
|
limit = limit,
|
||||||
|
sortBy = listOf(ItemSortBy.PREMIERE_DATE),
|
||||||
|
sortOrder = listOf(SortOrder.DESCENDING),
|
||||||
|
fields = DefaultItemFields,
|
||||||
|
recursive = true,
|
||||||
|
)
|
||||||
|
GetItemsRequestHandler
|
||||||
|
.execute(api, request)
|
||||||
|
.content.items
|
||||||
|
.map { BaseItem.Companion.from(it, api, true) }
|
||||||
|
.let {
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title,
|
||||||
|
it,
|
||||||
|
row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.ByParent -> {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
userId = userDto.id,
|
||||||
|
parentId = row.parentId,
|
||||||
|
recursive = row.recursive,
|
||||||
|
sortBy = row.sort?.let { listOf(it.sort) },
|
||||||
|
sortOrder = row.sort?.let { listOf(it.direction) },
|
||||||
|
limit = limit,
|
||||||
|
fields = DefaultItemFields,
|
||||||
|
)
|
||||||
|
val name =
|
||||||
|
api.userLibraryApi
|
||||||
|
.getItem(itemId = row.parentId)
|
||||||
|
.content.name
|
||||||
|
GetItemsRequestHandler
|
||||||
|
.execute(api, request)
|
||||||
|
.content.items
|
||||||
|
.map { BaseItem(it, true) }
|
||||||
|
.let {
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
name ?: context.getString(R.string.collection),
|
||||||
|
it,
|
||||||
|
row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is HomeRowConfig.GetItems -> {
|
||||||
|
val request =
|
||||||
|
row.getItems.let {
|
||||||
|
if (it.limit == null) {
|
||||||
|
it.copy(
|
||||||
|
userId = userDto.id,
|
||||||
|
limit = limit,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
it.copy(
|
||||||
|
userId = userDto.id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val name =
|
||||||
|
if (row.name == null && request.parentId != null) {
|
||||||
|
// If a name was not provided, use the parent's name if available
|
||||||
|
api.userLibraryApi
|
||||||
|
.getItem(itemId = request.parentId!!)
|
||||||
|
.content.name
|
||||||
|
} else {
|
||||||
|
row.name
|
||||||
|
}
|
||||||
|
GetItemsRequestHandler
|
||||||
|
.execute(api, request)
|
||||||
|
.content.items
|
||||||
|
.map { BaseItem.Companion.from(it, api, true) }
|
||||||
|
.let {
|
||||||
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
name ?: context.getString(R.string.collection),
|
||||||
|
it,
|
||||||
|
row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DISPLAY_PREF_ID = "default"
|
const val DISPLAY_PREF_ID = "default"
|
||||||
const val CUSTOM_PREF_ID = "home_settings"
|
const val CUSTOM_PREF_ID = "home_settings"
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
|
|
@ -111,6 +112,7 @@ class GenreViewModel
|
||||||
val genreToUrl =
|
val genreToUrl =
|
||||||
getGenreImageMap(
|
getGenreImageMap(
|
||||||
api = api,
|
api = api,
|
||||||
|
scope = viewModelScope,
|
||||||
imageUrlService = imageUrlService,
|
imageUrlService = imageUrlService,
|
||||||
genres = genres.map { it.id },
|
genres = genres.map { it.id },
|
||||||
parentId = itemId,
|
parentId = itemId,
|
||||||
|
|
@ -141,8 +143,9 @@ class GenreViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun ViewModel.getGenreImageMap(
|
suspend fun getGenreImageMap(
|
||||||
api: ApiClient,
|
api: ApiClient,
|
||||||
|
scope: CoroutineScope,
|
||||||
imageUrlService: ImageUrlService,
|
imageUrlService: ImageUrlService,
|
||||||
genres: List<UUID>,
|
genres: List<UUID>,
|
||||||
parentId: UUID,
|
parentId: UUID,
|
||||||
|
|
@ -153,7 +156,7 @@ suspend fun ViewModel.getGenreImageMap(
|
||||||
val semaphore = Semaphore(4)
|
val semaphore = Semaphore(4)
|
||||||
genres
|
genres
|
||||||
.map { genreId ->
|
.map { genreId ->
|
||||||
viewModelScope.async(Dispatchers.IO) {
|
scope.async(Dispatchers.IO) {
|
||||||
semaphore.withPermit {
|
semaphore.withPermit {
|
||||||
val item =
|
val item =
|
||||||
GetItemsRequestHandler
|
GetItemsRequestHandler
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,12 @@ import com.github.damontecres.wholphin.data.model.HomePageSettings
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowConfig
|
import com.github.damontecres.wholphin.data.model.HomeRowConfig
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowConfigDisplay
|
import com.github.damontecres.wholphin.data.model.HomeRowConfigDisplay
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
||||||
import com.github.damontecres.wholphin.preferences.HomePagePreferences
|
|
||||||
import com.github.damontecres.wholphin.services.BackdropService
|
import com.github.damontecres.wholphin.services.BackdropService
|
||||||
import com.github.damontecres.wholphin.services.HomeSettingsService
|
import com.github.damontecres.wholphin.services.HomeSettingsService
|
||||||
import com.github.damontecres.wholphin.services.ImageUrlService
|
|
||||||
import com.github.damontecres.wholphin.services.LatestNextUpService
|
|
||||||
import com.github.damontecres.wholphin.services.UserPreferencesService
|
import com.github.damontecres.wholphin.services.UserPreferencesService
|
||||||
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
|
||||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
|
||||||
import com.github.damontecres.wholphin.ui.components.getGenreImageMap
|
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
||||||
import com.github.damontecres.wholphin.ui.showToast
|
import com.github.damontecres.wholphin.ui.showToast
|
||||||
import com.github.damontecres.wholphin.util.GetGenresRequestHandler
|
|
||||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
|
@ -36,15 +28,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
|
||||||
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
|
||||||
import org.jellyfin.sdk.model.api.CollectionType
|
import org.jellyfin.sdk.model.api.CollectionType
|
||||||
import org.jellyfin.sdk.model.api.ItemSortBy
|
|
||||||
import org.jellyfin.sdk.model.api.SortOrder
|
|
||||||
import org.jellyfin.sdk.model.api.UserDto
|
|
||||||
import org.jellyfin.sdk.model.api.request.GetGenresRequest
|
|
||||||
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
|
||||||
import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -54,14 +38,11 @@ class HomeSettingsViewModel
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
@param:ApplicationContext private val context: Context,
|
@param:ApplicationContext private val context: Context,
|
||||||
private val api: ApiClient,
|
|
||||||
private val homeSettingsService: HomeSettingsService,
|
private val homeSettingsService: HomeSettingsService,
|
||||||
private val serverRepository: ServerRepository,
|
private val serverRepository: ServerRepository,
|
||||||
private val userPreferencesService: UserPreferencesService,
|
private val userPreferencesService: UserPreferencesService,
|
||||||
private val navDrawerItemRepository: NavDrawerItemRepository,
|
private val navDrawerItemRepository: NavDrawerItemRepository,
|
||||||
private val backdropService: BackdropService,
|
private val backdropService: BackdropService,
|
||||||
private val latestNextUpService: LatestNextUpService,
|
|
||||||
private val imageUrlService: ImageUrlService,
|
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _state = MutableStateFlow(HomePageSettingsState.EMPTY)
|
private val _state = MutableStateFlow(HomePageSettingsState.EMPTY)
|
||||||
val state: StateFlow<HomePageSettingsState> = _state
|
val state: StateFlow<HomePageSettingsState> = _state
|
||||||
|
|
@ -102,13 +83,22 @@ class HomeSettingsViewModel
|
||||||
val rows =
|
val rows =
|
||||||
serverRepository.currentUserDto.value?.let { userDto ->
|
serverRepository.currentUserDto.value?.let { userDto ->
|
||||||
val prefs = userPreferencesService.getCurrent().appPreferences.homePagePreferences
|
val prefs = userPreferencesService.getCurrent().appPreferences.homePagePreferences
|
||||||
state.value.rows
|
state.value.let { state ->
|
||||||
|
state.rows
|
||||||
.map { it.config }
|
.map { it.config }
|
||||||
.map { row ->
|
.map { row ->
|
||||||
// TODO parallelize
|
// TODO parallelize
|
||||||
parseRow(prefs, userDto, row, limit)
|
homeSettingsService.fetchDataForRow(
|
||||||
|
row = row,
|
||||||
|
scope = viewModelScope,
|
||||||
|
prefs = prefs,
|
||||||
|
userDto = userDto,
|
||||||
|
libraries = state.libraries,
|
||||||
|
limit = limit,
|
||||||
|
)
|
||||||
}.flatten()
|
}.flatten()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rows?.let { rows ->
|
rows?.let { rows ->
|
||||||
_state.update {
|
_state.update {
|
||||||
it.copy(loading = LoadingState.Success, rowData = rows)
|
it.copy(loading = LoadingState.Success, rowData = rows)
|
||||||
|
|
@ -116,241 +106,6 @@ class HomeSettingsViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun parseRow(
|
|
||||||
prefs: HomePagePreferences,
|
|
||||||
userDto: UserDto,
|
|
||||||
row: HomeRowConfig,
|
|
||||||
limit: Int,
|
|
||||||
): List<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,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.NextUp -> {
|
|
||||||
val nextUp =
|
|
||||||
latestNextUpService.getNextUp(
|
|
||||||
userDto.id,
|
|
||||||
limit,
|
|
||||||
prefs.enableRewatchingNextUp,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
title = context.getString(R.string.next_up),
|
|
||||||
items = nextUp,
|
|
||||||
viewOptions = row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.ContinueWatchingCombined -> {
|
|
||||||
val resume =
|
|
||||||
latestNextUpService.getResume(userDto.id, limit, true)
|
|
||||||
val nextUp =
|
|
||||||
latestNextUpService.getNextUp(
|
|
||||||
userDto.id,
|
|
||||||
limit,
|
|
||||||
prefs.enableRewatchingNextUp,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
title = context.getString(R.string.continue_watching),
|
|
||||||
items =
|
|
||||||
latestNextUpService.buildCombined(
|
|
||||||
resume,
|
|
||||||
nextUp,
|
|
||||||
),
|
|
||||||
viewOptions = row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.Genres -> {
|
|
||||||
val request =
|
|
||||||
GetGenresRequest(
|
|
||||||
parentId = row.parentId,
|
|
||||||
userId = userDto.id,
|
|
||||||
limit = limit,
|
|
||||||
)
|
|
||||||
val items =
|
|
||||||
GetGenresRequestHandler
|
|
||||||
.execute(api, request)
|
|
||||||
.content.items
|
|
||||||
val genreIds = items.map { it.id }
|
|
||||||
val genreImages =
|
|
||||||
getGenreImageMap(
|
|
||||||
api = api,
|
|
||||||
imageUrlService = imageUrlService,
|
|
||||||
genres = genreIds,
|
|
||||||
parentId = row.parentId,
|
|
||||||
includeItemTypes = null,
|
|
||||||
cardWidthPx = null,
|
|
||||||
)
|
|
||||||
val genres =
|
|
||||||
items.map {
|
|
||||||
BaseItem(it, false, genreImages[it.id])
|
|
||||||
}
|
|
||||||
|
|
||||||
val name =
|
|
||||||
_state.value.libraries
|
|
||||||
.firstOrNull { it.itemId == row.parentId }
|
|
||||||
?.name
|
|
||||||
val title =
|
|
||||||
name?.let { context.getString(R.string.genres_in, it) }
|
|
||||||
?: context.getString(R.string.genres)
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
title,
|
|
||||||
genres,
|
|
||||||
viewOptions = row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.RecentlyAdded -> {
|
|
||||||
val name =
|
|
||||||
_state.value.libraries
|
|
||||||
.firstOrNull { it.itemId == row.parentId }
|
|
||||||
?.name
|
|
||||||
val title =
|
|
||||||
name?.let { context.getString(R.string.recently_added_in, it) }
|
|
||||||
?: context.getString(R.string.recently_added)
|
|
||||||
val request =
|
|
||||||
GetLatestMediaRequest(
|
|
||||||
fields = SlimItemFields,
|
|
||||||
imageTypeLimit = 1,
|
|
||||||
parentId = row.parentId,
|
|
||||||
groupItems = true,
|
|
||||||
limit = limit,
|
|
||||||
isPlayed = null, // Server will handle user's preference
|
|
||||||
)
|
|
||||||
val latest =
|
|
||||||
api.userLibraryApi
|
|
||||||
.getLatestMedia(request)
|
|
||||||
.content
|
|
||||||
.map { BaseItem.Companion.from(it, api, true) }
|
|
||||||
.let {
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
title,
|
|
||||||
it,
|
|
||||||
row.viewOptions,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
listOf(latest)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.RecentlyReleased -> {
|
|
||||||
val name =
|
|
||||||
_state.value.libraries
|
|
||||||
.firstOrNull { it.itemId == row.parentId }
|
|
||||||
?.name
|
|
||||||
val title =
|
|
||||||
name?.let {
|
|
||||||
context.getString(R.string.recently_released_in, it)
|
|
||||||
} ?: context.getString(R.string.recently_released)
|
|
||||||
val request =
|
|
||||||
GetItemsRequest(
|
|
||||||
parentId = row.parentId,
|
|
||||||
limit = limit,
|
|
||||||
sortBy = listOf(ItemSortBy.PREMIERE_DATE),
|
|
||||||
sortOrder = listOf(SortOrder.DESCENDING),
|
|
||||||
fields = DefaultItemFields,
|
|
||||||
recursive = true,
|
|
||||||
)
|
|
||||||
GetItemsRequestHandler
|
|
||||||
.execute(api, request)
|
|
||||||
.content.items
|
|
||||||
.map { BaseItem.Companion.from(it, api, true) }
|
|
||||||
.let {
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
title,
|
|
||||||
it,
|
|
||||||
row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.ByParent -> {
|
|
||||||
val request =
|
|
||||||
GetItemsRequest(
|
|
||||||
userId = userDto.id,
|
|
||||||
parentId = row.parentId,
|
|
||||||
recursive = row.recursive,
|
|
||||||
sortBy = row.sort?.let { listOf(it.sort) },
|
|
||||||
sortOrder = row.sort?.let { listOf(it.direction) },
|
|
||||||
limit = limit,
|
|
||||||
fields = DefaultItemFields,
|
|
||||||
)
|
|
||||||
val name =
|
|
||||||
api.userLibraryApi
|
|
||||||
.getItem(itemId = row.parentId)
|
|
||||||
.content.name
|
|
||||||
GetItemsRequestHandler
|
|
||||||
.execute(api, request)
|
|
||||||
.content.items
|
|
||||||
.map { BaseItem(it, true) }
|
|
||||||
.let {
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
name ?: context.getString(R.string.collection),
|
|
||||||
it,
|
|
||||||
row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRowConfig.GetItems -> {
|
|
||||||
val request =
|
|
||||||
row.getItems.let {
|
|
||||||
if (it.limit == null) {
|
|
||||||
it.copy(
|
|
||||||
userId = userDto.id,
|
|
||||||
limit = limit,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
it.copy(
|
|
||||||
userId = userDto.id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val name =
|
|
||||||
if (row.name == null && request.parentId != null) {
|
|
||||||
// If a name was not provided, use the parent's name if available
|
|
||||||
api.userLibraryApi
|
|
||||||
.getItem(itemId = request.parentId!!)
|
|
||||||
.content.name
|
|
||||||
} else {
|
|
||||||
row.name
|
|
||||||
}
|
|
||||||
GetItemsRequestHandler
|
|
||||||
.execute(api, request)
|
|
||||||
.content.items
|
|
||||||
.map { BaseItem.Companion.from(it, api, true) }
|
|
||||||
.let {
|
|
||||||
listOf(
|
|
||||||
HomeRowLoadingState.Success(
|
|
||||||
name ?: context.getString(R.string.collection),
|
|
||||||
it,
|
|
||||||
row.viewOptions,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T> List<T>.move(
|
private fun <T> List<T>.move(
|
||||||
direction: MoveDirection,
|
direction: MoveDirection,
|
||||||
index: Int,
|
index: Int,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue