Upgrade to jellyfin-sdk 1.3.0 (#122)

Uses BaseItemKind to specify the item type
This commit is contained in:
Jarne Demeulemeester 2022-06-11 21:39:08 +02:00 committed by GitHub
parent d1dcf9b343
commit 8c039a3c81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 80 additions and 103 deletions

View file

@ -95,7 +95,7 @@ dependencies {
implementation("androidx.preference:preference-ktx:$preferenceVersion")
// Jellyfin
val jellyfinVersion = "1.2.0"
val jellyfinVersion = "1.3.0"
implementation("org.jellyfin.sdk:jellyfin-core:$jellyfinVersion")
// Glide

View file

@ -13,6 +13,7 @@ import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.database.Server
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.BaseItemPerson
import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID
@ -32,7 +33,7 @@ fun bindItems(recyclerView: RecyclerView, data: List<BaseItemDto>?) {
@BindingAdapter("itemImage")
fun bindItemImage(imageView: ImageView, item: BaseItemDto) {
val itemId =
if (item.type == "Episode" || item.type == "Season" && item.imageTags.isNullOrEmpty()) item.seriesId else item.id
if (item.type == BaseItemKind.EPISODE || item.type == BaseItemKind.SEASON && item.imageTags.isNullOrEmpty()) item.seriesId else item.id
imageView
.loadImage("/items/$itemId/Images/${ImageType.PRIMARY}")
@ -75,7 +76,7 @@ fun bindBaseItemImage(imageView: ImageView, episode: BaseItemDto?) {
if (!episode.imageTags.isNullOrEmpty()) { //TODO: Downloadmetadata currently does not store imagetags, so it always uses the backdrop
when (episode.type) {
"Movie" -> {
BaseItemKind.MOVIE -> {
if (!episode.backdropImageTags.isNullOrEmpty()) {
imageType = ImageType.BACKDROP
}
@ -87,7 +88,7 @@ fun bindBaseItemImage(imageView: ImageView, episode: BaseItemDto?) {
}
}
} else {
if (episode.type == "Episode") {
if (episode.type == BaseItemKind.EPISODE) {
imageItemId = episode.seriesId!!
imageType = ImageType.BACKDROP
}

View file

@ -9,6 +9,7 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : ListAdapter<BaseItemDto, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
class EpisodeViewHolder(private var binding: HomeEpisodeItemBinding) :
@ -21,10 +22,10 @@ class HomeEpisodeListAdapter(private val onClickListener: OnClickListener) : Lis
binding.progressBar.visibility = View.VISIBLE
}
if (episode.type == "Movie") {
if (episode.type == BaseItemKind.MOVIE) {
binding.primaryName.text = episode.name
binding.secondaryName.visibility = View.GONE
} else if (episode.type == "Episode") {
} else if (episode.type == BaseItemKind.EPISODE) {
binding.primaryName.text = episode.seriesName
}

View file

@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView
import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.databinding.BaseItemBinding
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
class ViewItemListAdapter(
private val onClickListener: OnClickListener,
@ -20,7 +21,7 @@ class ViewItemListAdapter(
RecyclerView.ViewHolder(binding.root) {
fun bind(item: BaseItemDto, fixedWidth: Boolean) {
binding.item = item
binding.itemName.text = if (item.type == "Episode") item.seriesName else item.name
binding.itemName.text = if (item.type == BaseItemKind.EPISODE) item.seriesName else item.name
binding.itemCount.visibility =
if (item.userData?.unplayedItemCount != null && item.userData?.unplayedItemCount!! > 0) View.VISIBLE else View.GONE
if (fixedWidth) {

View file

@ -99,7 +99,7 @@ class DownloadFragment : Fragment() {
DownloadFragmentDirections.actionDownloadFragmentToMediaInfoFragment(
UUID.randomUUID(),
item.name,
item.item?.type?.type ?: "Unkown",
item.item!!.type,
item,
isOffline = true
)

View file

@ -98,7 +98,7 @@ class FavoriteFragment : Fragment() {
FavoriteFragmentDirections.actionFavoriteFragmentToMediaInfoFragment(
item.id,
item.name,
item.type ?: "Unknown"
item.type
)
)
}

View file

@ -23,15 +23,11 @@ import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.adapters.ViewListAdapter
import dev.jdtech.jellyfin.databinding.FragmentHomeBinding
import dev.jdtech.jellyfin.dialogs.ErrorDialogFragment
import dev.jdtech.jellyfin.models.ContentType
import dev.jdtech.jellyfin.models.ContentType.EPISODE
import dev.jdtech.jellyfin.models.ContentType.MOVIE
import dev.jdtech.jellyfin.models.ContentType.TVSHOW
import dev.jdtech.jellyfin.utils.checkIfLoginRequired
import dev.jdtech.jellyfin.utils.contentType
import dev.jdtech.jellyfin.viewmodels.HomeViewModel
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import timber.log.Timber
@AndroidEntryPoint
@ -91,9 +87,9 @@ class HomeFragment : Fragment() {
navigateToMediaInfoFragment(it)
},
onNextUpClickListener = HomeEpisodeListAdapter.OnClickListener { item ->
when (item.contentType()) {
EPISODE -> navigateToEpisodeBottomSheetFragment(item)
MOVIE -> navigateToMediaInfoFragment(item)
when (item.type) {
BaseItemKind.EPISODE -> navigateToEpisodeBottomSheetFragment(item)
BaseItemKind.MOVIE -> navigateToMediaInfoFragment(item)
else -> Toast.makeText(requireContext(), R.string.unknown_error, LENGTH_LONG)
.show()
}
@ -158,12 +154,12 @@ class HomeFragment : Fragment() {
}
private fun navigateToMediaInfoFragment(item: BaseItemDto) {
if (item.contentType() == EPISODE) {
if (item.type == BaseItemKind.EPISODE) {
findNavController().navigate(
HomeFragmentDirections.actionNavigationHomeToMediaInfoFragment(
item.seriesId!!,
item.seriesName,
TVSHOW.type
BaseItemKind.SERIES
)
)
} else {
@ -171,7 +167,7 @@ class HomeFragment : Fragment() {
HomeFragmentDirections.actionNavigationHomeToMediaInfoFragment(
item.id,
item.name,
item.type ?: ContentType.UNKNOWN.type
item.type
)
)
}

View file

@ -144,7 +144,7 @@ class LibraryFragment : Fragment() {
LibraryFragmentDirections.actionLibraryFragmentToMediaInfoFragment(
item.id,
item.name,
item.type ?: "Unknown"
item.type
)
)
}

View file

@ -7,7 +7,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@ -34,7 +33,7 @@ import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.serializer.toUUID
import org.jellyfin.sdk.model.api.BaseItemKind
import timber.log.Timber
import java.util.UUID
@ -78,7 +77,7 @@ class MediaInfoFragment : Fragment() {
}
}
if (args.itemType != "Movie") {
if (args.itemType != BaseItemKind.MOVIE) {
binding.downloadButton.visibility = View.GONE
}
@ -111,16 +110,7 @@ class MediaInfoFragment : Fragment() {
navigateToSeasonFragment(season)
}, fixedWidth = true)
binding.peopleRecyclerView.adapter = PersonListAdapter { person ->
val uuid = person.id?.toUUID()
if (uuid != null) {
navigateToPersonDetail(uuid)
} else {
Toast.makeText(
requireContext(),
R.string.error_getting_person_id,
Toast.LENGTH_SHORT
).show()
}
navigateToPersonDetail(person.id)
}
binding.playButton.setOnClickListener {

View file

@ -137,7 +137,7 @@ internal class PersonDetailFragment : Fragment() {
PersonDetailFragmentDirections.actionPersonDetailFragmentToMediaInfoFragment(
itemId = item.id,
itemName = item.name,
itemType = item.type ?: "Unknown"
itemType = item.type
)
)
}

View file

@ -102,7 +102,7 @@ class SearchResultFragment : Fragment() {
FavoriteFragmentDirections.actionFavoriteFragmentToMediaInfoFragment(
item.id,
item.name,
item.type ?: "Unknown"
item.type
)
)
}

View file

@ -1,8 +0,0 @@
package dev.jdtech.jellyfin.models
enum class ContentType(val type: String) {
MOVIE("Movie"),
TVSHOW("Series"),
EPISODE("Episode"),
UNKNOWN("")
}

View file

@ -4,6 +4,7 @@ import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.*
@Parcelize
@ -11,7 +12,7 @@ import java.util.*
data class DownloadItem(
@PrimaryKey
val id: UUID,
val type: ContentType,
val type: BaseItemKind,
val name: String,
val played: Boolean,
val overview: String? = null,

View file

@ -1,12 +1,8 @@
package dev.jdtech.jellyfin.repository
import dev.jdtech.jellyfin.models.ContentType
import dev.jdtech.jellyfin.utils.SortBy
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.ItemFields
import org.jellyfin.sdk.model.api.MediaSourceInfo
import org.jellyfin.sdk.model.api.SortOrder
import org.jellyfin.sdk.model.api.*
import java.util.*
interface JellyfinRepository {
@ -16,7 +12,7 @@ interface JellyfinRepository {
suspend fun getItems(
parentId: UUID? = null,
includeTypes: List<String>? = null,
includeTypes: List<BaseItemKind>? = null,
recursive: Boolean = false,
sortBy: SortBy = SortBy.defaultValue,
sortOrder: SortOrder = SortOrder.ASCENDING
@ -24,7 +20,7 @@ interface JellyfinRepository {
suspend fun getPersonItems(
personIds: List<UUID>,
includeTypes: List<ContentType>? = null,
includeTypes: List<BaseItemKind>? = null,
recursive: Boolean = true
): List<BaseItemDto>

View file

@ -1,7 +1,6 @@
package dev.jdtech.jellyfin.repository
import dev.jdtech.jellyfin.api.JellyfinApi
import dev.jdtech.jellyfin.models.ContentType
import dev.jdtech.jellyfin.utils.SortBy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -20,7 +19,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
override suspend fun getItems(
parentId: UUID?,
includeTypes: List<String>?,
includeTypes: List<BaseItemKind>?,
recursive: Boolean,
sortBy: SortBy,
sortOrder: SortOrder
@ -37,13 +36,13 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
override suspend fun getPersonItems(
personIds: List<UUID>,
includeTypes: List<ContentType>?,
includeTypes: List<BaseItemKind>?,
recursive: Boolean
): List<BaseItemDto> = withContext(Dispatchers.IO) {
jellyfinApi.itemsApi.getItems(
jellyfinApi.userId!!,
personIds = personIds,
includeItemTypes = includeTypes?.map { it.type },
includeItemTypes = includeTypes,
recursive = recursive
).content.items.orEmpty()
}
@ -52,7 +51,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
jellyfinApi.itemsApi.getItems(
jellyfinApi.userId!!,
filters = listOf(ItemFilter.IS_FAVORITE),
includeItemTypes = listOf("Movie", "Series", "Episode"),
includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES, BaseItemKind.EPISODE),
recursive = true
).content.items.orEmpty()
}
@ -62,7 +61,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
jellyfinApi.itemsApi.getItems(
jellyfinApi.userId!!,
searchTerm = searchQuery,
includeItemTypes = listOf("Movie", "Series", "Episode"),
includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES, BaseItemKind.EPISODE),
recursive = true
).content.items.orEmpty()
}
@ -70,7 +69,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
override suspend fun getResumeItems(): List<BaseItemDto> = withContext(Dispatchers.IO) {
jellyfinApi.itemsApi.getResumeItems(
jellyfinApi.userId!!,
includeItemTypes = listOf("Movie", "Episode"),
includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.EPISODE),
).content.items.orEmpty()
}
@ -128,6 +127,9 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
),
transcodingProfiles = emptyList(),
responseProfiles = emptyList(),
subtitleProfiles = emptyList(),
xmlRootAttributes = emptyList(),
supportedMediaTypes = "",
enableAlbumArtInDidl = false,
enableMsMediaReceiverRegistrar = false,
enableSingleAlbumArtLimit = false,
@ -144,7 +146,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
subtitleStreamIndex = null,
maxStreamingBitrate = 1_000_000_000,
)
).content.mediaSources.orEmpty()
).content.mediaSources
}
override suspend fun getStreamUrl(itemId: UUID, mediaSourceId: String): String =

View file

@ -109,7 +109,7 @@ internal class HomeFragment : BrowseSupportFragment() {
HomeFragmentDirections.actionHomeFragmentToMediaDetailFragment(
item.id,
item.seriesName ?: item.name,
item.type ?: "Unknown"
item.type
)
)
}

View file

@ -12,6 +12,7 @@ import dev.jdtech.jellyfin.R
import dev.jdtech.jellyfin.databinding.BaseItemBinding
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
class MediaItemPresenter(private val onClick: (BaseItemDto) -> Unit) : Presenter() {
@ -27,7 +28,7 @@ class MediaItemPresenter(private val onClick: (BaseItemDto) -> Unit) : Presenter
if (item is BaseItemDto) {
DataBindingUtil.getBinding<BaseItemBinding>(viewHolder.view)?.apply {
this.item = item
this.itemName.text = if (item.type == "Episode") item.seriesName else item.name
this.itemName.text = if (item.type == BaseItemKind.EPISODE) item.seriesName else item.name
this.itemCount.visibility =
if (item.userData?.unplayedItemCount != null && item.userData?.unplayedItemCount!! > 0) View.VISIBLE else View.GONE
this.itemLayout.layoutParams.width =
@ -62,10 +63,10 @@ class DynamicMediaItemPresenter(private val onClick: (BaseItemDto) -> Unit) : Pr
progressBar.isVisible = true
}
if (item.type == "Movie") {
if (item.type == BaseItemKind.MOVIE) {
primaryName.text = item.name
secondaryName.visibility = View.GONE
} else if (item.type == "Episode") {
} else if (item.type == BaseItemKind.EPISODE) {
primaryName.text = item.seriesName
}

View file

@ -13,6 +13,7 @@ import dev.jdtech.jellyfin.models.DownloadSeriesMetadata
import dev.jdtech.jellyfin.models.PlayerItem
import dev.jdtech.jellyfin.repository.JellyfinRepository
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.UserItemDataDto
import timber.log.Timber
import java.io.File
@ -149,7 +150,7 @@ fun downloadMetadataToBaseItemDto(item: DownloadItem): BaseItemDto {
return BaseItemDto(
id = item.id,
type = item.type.type,
type = item.type,
seriesName = item.seriesName,
name = item.name,
parentIndexNumber = item.parentIndexNumber,
@ -163,7 +164,7 @@ fun downloadMetadataToBaseItemDto(item: DownloadItem): BaseItemDto {
fun baseItemDtoToDownloadMetadata(item: BaseItemDto): DownloadItem {
return DownloadItem(
id = item.id,
type = item.contentType(),
type = item.type,
name = item.name.orEmpty(),
played = item.userData?.played ?: false,
seriesId = item.seriesId,
@ -188,7 +189,7 @@ fun downloadSeriesMetadataToBaseItemDto(metadata: DownloadSeriesMetadata): BaseI
return BaseItemDto(
id = metadata.itemId,
type = "Series",
type = BaseItemKind.SERIES,
name = metadata.name,
userData = userData
)

View file

@ -12,7 +12,6 @@ import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import dev.jdtech.jellyfin.AppNavigationDirections
import dev.jdtech.jellyfin.models.ContentType
import dev.jdtech.jellyfin.models.View
import org.jellyfin.sdk.model.api.BaseItemDto
import timber.log.Timber
@ -25,13 +24,6 @@ fun BaseItemDto.toView(): View {
)
}
fun BaseItemDto.contentType() = when (type) {
"Movie" -> ContentType.MOVIE
"Series" -> ContentType.TVSHOW
"Episode" -> ContentType.EPISODE
else -> ContentType.UNKNOWN
}
fun Fragment.checkIfLoginRequired(error: String?) {
if (error != null) {
if (error.contains("401")) {

View file

@ -3,7 +3,6 @@ package dev.jdtech.jellyfin.viewmodels
import androidx.lifecycle.*
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.database.DownloadDatabaseDao
import dev.jdtech.jellyfin.models.ContentType
import dev.jdtech.jellyfin.models.DownloadSection
import dev.jdtech.jellyfin.models.DownloadSeriesMetadata
import dev.jdtech.jellyfin.models.PlayerItem
@ -11,6 +10,7 @@ import dev.jdtech.jellyfin.utils.loadDownloadedEpisodes
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.*
import javax.inject.Inject
@ -43,7 +43,7 @@ constructor(
val items = loadDownloadedEpisodes(downloadDatabase)
val showsMap = mutableMapOf<UUID, MutableList<PlayerItem>>()
items.filter { it.item?.type == ContentType.EPISODE }.forEach {
items.filter { it.item?.type == BaseItemKind.EPISODE }.forEach {
showsMap.computeIfAbsent(it.item!!.seriesId!!) { mutableListOf() } += it
}
val shows = showsMap.map { DownloadSeriesMetadata(it.key, it.value[0].item!!.seriesName, it.value) }
@ -53,7 +53,7 @@ constructor(
DownloadSection(
UUID.randomUUID(),
"Movies",
items.filter { it.item?.type == ContentType.MOVIE }
items.filter { it.item?.type == BaseItemKind.MOVIE }
).let {
if (it.items!!.isNotEmpty()) downloadSections.add(
it

View file

@ -10,6 +10,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.*
import javax.inject.Inject
@ -52,7 +53,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Movies",
items.filter { it.type == "Movie" }).let {
items.filter { it.type == BaseItemKind.MOVIE }).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
@ -60,7 +61,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Shows",
items.filter { it.type == "Series" }).let {
items.filter { it.type == BaseItemKind.SERIES }).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)
@ -68,7 +69,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Episodes",
items.filter { it.type == "Episode" }).let {
items.filter { it.type == BaseItemKind.EPISODE }).let {
if (it.items.isNotEmpty()) favoriteSections.add(
it
)

View file

@ -7,6 +7,7 @@ import dev.jdtech.jellyfin.utils.SortBy
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.SortOrder
import timber.log.Timber
import java.util.*
@ -38,8 +39,8 @@ constructor(
) {
Timber.d("$libraryType")
val itemType = when (libraryType) {
"movies" -> "Movie"
"tvshows" -> "Series"
"movies" -> BaseItemKind.MOVIE
"tvshows" -> BaseItemKind.SERIES
else -> null
}
viewModelScope.launch {

View file

@ -17,6 +17,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.exception.ApiClientException
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.BaseItemPerson
import timber.log.Timber
import java.util.UUID
@ -80,7 +81,7 @@ constructor(
lateinit var playerItem: PlayerItem
fun loadData(itemId: UUID, itemType: String) {
fun loadData(itemId: UUID, itemType: BaseItemKind) {
viewModelScope.launch {
uiState.emit(UiState.Loading)
try {
@ -97,7 +98,7 @@ constructor(
favorite = tempItem.userData?.isFavorite ?: false
canDownload = tempItem.canDownload == true
downloaded = isItemDownloaded(downloadDatabase, itemId)
if (itemType == "Series") {
if (itemType == BaseItemKind.SERIES) {
nextUp = getNextUp(itemId)
seasons = jellyfinRepository.getSeasons(itemId)
}

View file

@ -4,13 +4,11 @@ import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.models.ContentType.MOVIE
import dev.jdtech.jellyfin.models.ContentType.TVSHOW
import dev.jdtech.jellyfin.repository.JellyfinRepository
import dev.jdtech.jellyfin.utils.contentType
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.UUID
import javax.inject.Inject
@ -45,12 +43,12 @@ internal class PersonDetailViewModel @Inject internal constructor(
val items = jellyfinRepository.getPersonItems(
personIds = listOf(personId),
includeTypes = listOf(MOVIE, TVSHOW),
includeTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES),
recursive = true
)
val movies = items.filter { it.contentType() == MOVIE }
val shows = items.filter { it.contentType() == TVSHOW }
val movies = items.filter { it.type == BaseItemKind.MOVIE }
val shows = items.filter { it.type == BaseItemKind.SERIES }
val starredIn = StarredIn(movies, shows)

View file

@ -13,6 +13,7 @@ import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.ItemFields
import org.jellyfin.sdk.model.api.LocationType.VIRTUAL
import org.jellyfin.sdk.model.api.MediaProtocol
@ -98,9 +99,9 @@ class PlayerViewModel @Inject internal constructor(
playbackPosition: Long,
mediaSourceIndex: Int
): List<PlayerItem> = when (item.type) {
"Movie" -> itemToMoviePlayerItems(item, playbackPosition, mediaSourceIndex)
"Series" -> seriesToPlayerItems(item, playbackPosition, mediaSourceIndex)
"Episode" -> episodeToPlayerItems(item, playbackPosition, mediaSourceIndex)
BaseItemKind.MOVIE -> itemToMoviePlayerItems(item, playbackPosition, mediaSourceIndex)
BaseItemKind.SERIES -> seriesToPlayerItems(item, playbackPosition, mediaSourceIndex)
BaseItemKind.EPISODE -> episodeToPlayerItems(item, playbackPosition, mediaSourceIndex)
else -> emptyList()
}

View file

@ -10,6 +10,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemKind
import java.util.*
import javax.inject.Inject
@ -48,7 +49,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Movies",
items.filter { it.type == "Movie" }).let {
items.filter { it.type == BaseItemKind.MOVIE }).let {
if (it.items.isNotEmpty()) sections.add(
it
)
@ -56,7 +57,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Shows",
items.filter { it.type == "Series" }).let {
items.filter { it.type == BaseItemKind.SERIES }).let {
if (it.items.isNotEmpty()) sections.add(
it
)
@ -64,7 +65,7 @@ constructor(
FavoriteSection(
UUID.randomUUID(),
"Episodes",
items.filter { it.type == "Episode" }).let {
items.filter { it.type == BaseItemKind.EPISODE }).let {
if (it.items.isNotEmpty()) sections.add(
it
)

View file

@ -6,7 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.api.JellyfinApi
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.DeviceOptions
import org.jellyfin.sdk.model.api.DeviceOptionsDto
import javax.inject.Inject
@HiltViewModel
@ -17,7 +17,7 @@ internal class SettingsDeviceViewModel @Inject internal constructor(
fun updateDeviceName(name: String) {
api.jellyfin.deviceInfo?.id?.let { id ->
viewModelScope.launch(IO) {
api.devicesApi.updateDeviceOptions(id, DeviceOptions(name))
api.devicesApi.updateDeviceOptions(id, DeviceOptionsDto(0, customName = name))
}
}
}

View file

@ -114,8 +114,8 @@
app:nullable="true" />
<argument
android:name="itemType"
android:defaultValue="unknown"
app:argType="string" />
app:argType="org.jellyfin.sdk.model.api.BaseItemKind"
android:defaultValue="MOVIE" />
<argument
android:name="playerItem"
android:defaultValue="@null"

View file

@ -45,8 +45,8 @@
app:nullable="true" />
<argument
android:name="itemType"
android:defaultValue="unknown"
app:argType="string" />
app:argType="org.jellyfin.sdk.model.api.BaseItemKind"
android:defaultValue="MOVIE" />
<action
android:id="@+id/action_mediaDetailFragment_to_playerActivity"