feat: mixed libraries (#628)
* mixed collection * Mixed libraries to show up in "Latest" Co-authored-by: Freya Winters <freya@justgamingtld.nl> * Do not recurse if folders are shown * Added folder navigation for tv * Removed assumption that folder == mixed * refactor: add default values to `FindroidFolder` * fix: add chapters to findroidfolder --------- Co-authored-by: Freya Winters <freya@justgamingtld.nl> Co-authored-by: Jarne Demeulemeester <jarnedemeulemeester@gmail.com>
This commit is contained in:
parent
4ec3b2e40c
commit
9cd3295d2d
8 changed files with 64 additions and 4 deletions
|
@ -25,6 +25,7 @@ import dev.jdtech.jellyfin.databinding.FragmentLibraryBinding
|
||||||
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
|
||||||
import dev.jdtech.jellyfin.dialogs.SortDialogFragment
|
import dev.jdtech.jellyfin.dialogs.SortDialogFragment
|
||||||
import dev.jdtech.jellyfin.models.FindroidBoxSet
|
import dev.jdtech.jellyfin.models.FindroidBoxSet
|
||||||
|
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||||
import dev.jdtech.jellyfin.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import dev.jdtech.jellyfin.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
|
@ -222,6 +223,15 @@ class LibraryFragment : Fragment() {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is FindroidFolder -> {
|
||||||
|
findNavController().navigate(
|
||||||
|
LibraryFragmentDirections.actionLibraryFragmentSelf(
|
||||||
|
item.id,
|
||||||
|
item.name,
|
||||||
|
args.libraryType,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,9 @@
|
||||||
<argument
|
<argument
|
||||||
android:name="libraryType"
|
android:name="libraryType"
|
||||||
app:argType="dev.jdtech.jellyfin.models.CollectionType" />
|
app:argType="dev.jdtech.jellyfin.models.CollectionType" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_libraryFragment_self"
|
||||||
|
app:destination="@id/libraryFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/showFragment"
|
android:id="@+id/showFragment"
|
||||||
|
|
|
@ -23,9 +23,11 @@ import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
|
import dev.jdtech.jellyfin.destinations.LibraryScreenDestination
|
||||||
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
import dev.jdtech.jellyfin.destinations.MovieScreenDestination
|
||||||
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
import dev.jdtech.jellyfin.destinations.ShowScreenDestination
|
||||||
import dev.jdtech.jellyfin.models.CollectionType
|
import dev.jdtech.jellyfin.models.CollectionType
|
||||||
|
import dev.jdtech.jellyfin.models.FindroidFolder
|
||||||
import dev.jdtech.jellyfin.models.FindroidItem
|
import dev.jdtech.jellyfin.models.FindroidItem
|
||||||
import dev.jdtech.jellyfin.models.FindroidMovie
|
import dev.jdtech.jellyfin.models.FindroidMovie
|
||||||
import dev.jdtech.jellyfin.models.FindroidShow
|
import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
|
@ -65,6 +67,9 @@ fun LibraryScreen(
|
||||||
is FindroidShow -> {
|
is FindroidShow -> {
|
||||||
navigator.navigate(ShowScreenDestination(item.id))
|
navigator.navigate(ShowScreenDestination(item.id))
|
||||||
}
|
}
|
||||||
|
is FindroidFolder -> {
|
||||||
|
navigator.navigate(LibraryScreenDestination(item.id, item.name, libraryType))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -93,7 +93,7 @@ class HomeViewModel @Inject internal constructor(
|
||||||
|
|
||||||
private suspend fun loadViews() = repository
|
private suspend fun loadViews() = repository
|
||||||
.getUserViews()
|
.getUserViews()
|
||||||
.filter { view -> CollectionType.supported.any { it.type == view.collectionType } }
|
.filter { view -> CollectionType.fromString(view.collectionType) in CollectionType.supported }
|
||||||
.map { view -> view to repository.getLatestMedia(view.id) }
|
.map { view -> view to repository.getLatestMedia(view.id) }
|
||||||
.filter { (_, latest) -> latest.isNotEmpty() }
|
.filter { (_, latest) -> latest.isNotEmpty() }
|
||||||
.map { (view, latest) -> view.toView().apply { items = latest } }
|
.map { (view, latest) -> view.toView().apply { items = latest } }
|
||||||
|
|
|
@ -48,15 +48,19 @@ constructor(
|
||||||
CollectionType.Movies -> listOf(BaseItemKind.MOVIE)
|
CollectionType.Movies -> listOf(BaseItemKind.MOVIE)
|
||||||
CollectionType.TvShows -> listOf(BaseItemKind.SERIES)
|
CollectionType.TvShows -> listOf(BaseItemKind.SERIES)
|
||||||
CollectionType.BoxSets -> listOf(BaseItemKind.BOX_SET)
|
CollectionType.BoxSets -> listOf(BaseItemKind.BOX_SET)
|
||||||
|
CollectionType.Mixed -> listOf(BaseItemKind.FOLDER, BaseItemKind.MOVIE, BaseItemKind.SERIES)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val recursive = itemType == null || !itemType.contains(BaseItemKind.FOLDER)
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_uiState.emit(UiState.Loading)
|
_uiState.emit(UiState.Loading)
|
||||||
try {
|
try {
|
||||||
val items = jellyfinRepository.getItemsPaging(
|
val items = jellyfinRepository.getItemsPaging(
|
||||||
parentId = parentId,
|
parentId = parentId,
|
||||||
includeTypes = itemType,
|
includeTypes = itemType,
|
||||||
recursive = true,
|
recursive = recursive,
|
||||||
sortBy = sortBy,
|
sortBy = sortBy,
|
||||||
sortOrder = sortOrder,
|
sortOrder = sortOrder,
|
||||||
).cachedIn(viewModelScope)
|
).cachedIn(viewModelScope)
|
||||||
|
|
|
@ -9,6 +9,7 @@ enum class CollectionType(val type: String) {
|
||||||
Books("books"),
|
Books("books"),
|
||||||
LiveTv("livetv"),
|
LiveTv("livetv"),
|
||||||
BoxSets("boxsets"),
|
BoxSets("boxsets"),
|
||||||
|
Mixed("null"),
|
||||||
Unknown("unknown"),
|
Unknown("unknown"),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -19,11 +20,12 @@ enum class CollectionType(val type: String) {
|
||||||
Movies,
|
Movies,
|
||||||
TvShows,
|
TvShows,
|
||||||
BoxSets,
|
BoxSets,
|
||||||
|
Mixed,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun fromString(string: String?): CollectionType {
|
fun fromString(string: String?): CollectionType {
|
||||||
if (string == null) {
|
if (string == null) { // TODO jellyfin returns null as the collectiontype for mixed libraries. This is obviously wrong, but probably an upstream issue. Should be fixed whenever upstream fixes this
|
||||||
return defaultValue
|
return Mixed
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package dev.jdtech.jellyfin.models
|
||||||
|
|
||||||
|
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
data class FindroidFolder(
|
||||||
|
override val id: UUID,
|
||||||
|
override val name: String,
|
||||||
|
override val originalTitle: String? = null,
|
||||||
|
override val overview: String = "",
|
||||||
|
override val played: Boolean,
|
||||||
|
override val favorite: Boolean,
|
||||||
|
override val canPlay: Boolean = false,
|
||||||
|
override val canDownload: Boolean = false,
|
||||||
|
override val sources: List<FindroidSource> = emptyList(),
|
||||||
|
override val runtimeTicks: Long = 0L,
|
||||||
|
override val playbackPositionTicks: Long = 0L,
|
||||||
|
override val unplayedItemCount: Int?,
|
||||||
|
override val images: FindroidImages,
|
||||||
|
override val chapters: List<FindroidChapter>? = null,
|
||||||
|
) : FindroidItem
|
||||||
|
|
||||||
|
fun BaseItemDto.toFindroidFolder(
|
||||||
|
jellyfinRepository: JellyfinRepository,
|
||||||
|
): FindroidFolder {
|
||||||
|
return FindroidFolder(
|
||||||
|
id = id,
|
||||||
|
name = name.orEmpty(),
|
||||||
|
played = userData?.played ?: false,
|
||||||
|
favorite = userData?.isFavorite ?: false,
|
||||||
|
unplayedItemCount = userData?.unplayedItemCount,
|
||||||
|
images = toFindroidImages(jellyfinRepository),
|
||||||
|
)
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ suspend fun BaseItemDto.toFindroidItem(
|
||||||
BaseItemKind.SEASON -> toFindroidSeason(jellyfinRepository)
|
BaseItemKind.SEASON -> toFindroidSeason(jellyfinRepository)
|
||||||
BaseItemKind.SERIES -> toFindroidShow(jellyfinRepository)
|
BaseItemKind.SERIES -> toFindroidShow(jellyfinRepository)
|
||||||
BaseItemKind.BOX_SET -> toFindroidBoxSet(jellyfinRepository)
|
BaseItemKind.BOX_SET -> toFindroidBoxSet(jellyfinRepository)
|
||||||
|
BaseItemKind.FOLDER -> toFindroidFolder(jellyfinRepository)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue