From 8c039a3c81afb0c9c9cfb116fcc2648da743054b Mon Sep 17 00:00:00 2001 From: Jarne Demeulemeester <32322857+jarnedemeulemeester@users.noreply.github.com> Date: Sat, 11 Jun 2022 21:39:08 +0200 Subject: [PATCH] Upgrade to jellyfin-sdk 1.3.0 (#122) Uses BaseItemKind to specify the item type --- app/build.gradle.kts | 2 +- .../dev/jdtech/jellyfin/BindingAdapters.kt | 7 ++++--- .../adapters/HomeEpisodeListAdapter.kt | 5 +++-- .../jellyfin/adapters/ViewItemListAdapter.kt | 3 ++- .../jellyfin/fragments/DownloadFragment.kt | 2 +- .../jellyfin/fragments/FavoriteFragment.kt | 2 +- .../jdtech/jellyfin/fragments/HomeFragment.kt | 18 +++++++----------- .../jellyfin/fragments/LibraryFragment.kt | 2 +- .../jellyfin/fragments/MediaInfoFragment.kt | 16 +++------------- .../jellyfin/fragments/PersonDetailFragment.kt | 2 +- .../jellyfin/fragments/SearchResultFragment.kt | 2 +- .../dev/jdtech/jellyfin/models/ContentType.kt | 8 -------- .../dev/jdtech/jellyfin/models/DownloadItem.kt | 3 ++- .../jellyfin/repository/JellyfinRepository.kt | 10 +++------- .../repository/JellyfinRepositoryImpl.kt | 18 ++++++++++-------- .../dev/jdtech/jellyfin/tv/ui/HomeFragment.kt | 2 +- .../jellyfin/tv/ui/MediaSectionPresenter.kt | 7 ++++--- .../jdtech/jellyfin/utils/DownloadUtilities.kt | 7 ++++--- .../dev/jdtech/jellyfin/utils/extensions.kt | 8 -------- .../jellyfin/viewmodels/DownloadViewModel.kt | 6 +++--- .../jellyfin/viewmodels/FavoriteViewModel.kt | 7 ++++--- .../jellyfin/viewmodels/LibraryViewModel.kt | 5 +++-- .../jellyfin/viewmodels/MediaInfoViewModel.kt | 5 +++-- .../viewmodels/PersonDetailViewModel.kt | 10 ++++------ .../jellyfin/viewmodels/PlayerViewModel.kt | 7 ++++--- .../viewmodels/SearchResultViewModel.kt | 7 ++++--- .../viewmodels/SettingsDeviceViewModel.kt | 4 ++-- app/src/main/res/navigation/app_navigation.xml | 4 ++-- app/src/main/res/navigation/tv_navigation.xml | 4 ++-- 29 files changed, 80 insertions(+), 103 deletions(-) delete mode 100644 app/src/main/java/dev/jdtech/jellyfin/models/ContentType.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a742b2b5..271e722e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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 diff --git a/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt index 5aa03e73..73650944 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt @@ -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?) { @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 } diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt index a56e4f0b..41ecf2ea 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/HomeEpisodeListAdapter.kt @@ -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(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 } diff --git a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt index 77e503bd..d4779c09 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/adapters/ViewItemListAdapter.kt @@ -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) { diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt index df8b7c8d..5c4261b3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/DownloadFragment.kt @@ -99,7 +99,7 @@ class DownloadFragment : Fragment() { DownloadFragmentDirections.actionDownloadFragmentToMediaInfoFragment( UUID.randomUUID(), item.name, - item.item?.type?.type ?: "Unkown", + item.item!!.type, item, isOffline = true ) diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt index 1e6cdfa1..c74ae6d4 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/FavoriteFragment.kt @@ -98,7 +98,7 @@ class FavoriteFragment : Fragment() { FavoriteFragmentDirections.actionFavoriteFragmentToMediaInfoFragment( item.id, item.name, - item.type ?: "Unknown" + item.type ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt index 55ba0c72..c1c3159a 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/HomeFragment.kt @@ -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 ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt index 8d287761..f0e9fb34 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/LibraryFragment.kt @@ -144,7 +144,7 @@ class LibraryFragment : Fragment() { LibraryFragmentDirections.actionLibraryFragmentToMediaInfoFragment( item.id, item.name, - item.type ?: "Unknown" + item.type ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt index b89e4cff..2ee2a5a7 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt @@ -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 { diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt index db14d493..862318af 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/PersonDetailFragment.kt @@ -137,7 +137,7 @@ internal class PersonDetailFragment : Fragment() { PersonDetailFragmentDirections.actionPersonDetailFragmentToMediaInfoFragment( itemId = item.id, itemName = item.name, - itemType = item.type ?: "Unknown" + itemType = item.type ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt index dfd6a137..f02166ff 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/SearchResultFragment.kt @@ -102,7 +102,7 @@ class SearchResultFragment : Fragment() { FavoriteFragmentDirections.actionFavoriteFragmentToMediaInfoFragment( item.id, item.name, - item.type ?: "Unknown" + item.type ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/ContentType.kt b/app/src/main/java/dev/jdtech/jellyfin/models/ContentType.kt deleted file mode 100644 index aaeb6731..00000000 --- a/app/src/main/java/dev/jdtech/jellyfin/models/ContentType.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.jdtech.jellyfin.models - -enum class ContentType(val type: String) { - MOVIE("Movie"), - TVSHOW("Series"), - EPISODE("Episode"), - UNKNOWN("") -} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt index 42320509..4664e8f3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/models/DownloadItem.kt @@ -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, diff --git a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt index 731d19f8..0c5ba0f8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepository.kt @@ -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? = null, + includeTypes: List? = null, recursive: Boolean = false, sortBy: SortBy = SortBy.defaultValue, sortOrder: SortOrder = SortOrder.ASCENDING @@ -24,7 +20,7 @@ interface JellyfinRepository { suspend fun getPersonItems( personIds: List, - includeTypes: List? = null, + includeTypes: List? = null, recursive: Boolean = true ): List diff --git a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt index 7f95fc80..d1edacbd 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt @@ -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?, + includeTypes: List?, recursive: Boolean, sortBy: SortBy, sortOrder: SortOrder @@ -37,13 +36,13 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep override suspend fun getPersonItems( personIds: List, - includeTypes: List?, + includeTypes: List?, recursive: Boolean ): List = 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 = 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 = diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt index 2de4a6c1..885211ba 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/HomeFragment.kt @@ -109,7 +109,7 @@ internal class HomeFragment : BrowseSupportFragment() { HomeFragmentDirections.actionHomeFragmentToMediaDetailFragment( item.id, item.seriesName ?: item.name, - item.type ?: "Unknown" + item.type ) ) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt index f70a0524..f7707a25 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/tv/ui/MediaSectionPresenter.kt @@ -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(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 } diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt index cdaa2f30..d96ebd45 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/DownloadUtilities.kt @@ -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 ) diff --git a/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt b/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt index 5242a2c5..a121adfb 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/utils/extensions.kt @@ -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")) { diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt index b60e8c7c..d547b1af 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/DownloadViewModel.kt @@ -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>() - 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 diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt index 04b405b6..a45344e8 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/FavoriteViewModel.kt @@ -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 ) diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt index 3c7189a2..0380fd94 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/LibraryViewModel.kt @@ -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 { diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt index 8cf7dd68..788d1d3c 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt @@ -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) } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt index dda24c7c..7f8bbe12 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PersonDetailViewModel.kt @@ -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) diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt index dcd02964..c0b401ef 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerViewModel.kt @@ -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 = 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() } diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt index e2ceaaeb..a857db39 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SearchResultViewModel.kt @@ -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 ) diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt index 5ba864f2..f9ccf4c3 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/SettingsDeviceViewModel.kt @@ -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)) } } } diff --git a/app/src/main/res/navigation/app_navigation.xml b/app/src/main/res/navigation/app_navigation.xml index a83d5497..ee45ac80 100644 --- a/app/src/main/res/navigation/app_navigation.xml +++ b/app/src/main/res/navigation/app_navigation.xml @@ -114,8 +114,8 @@ app:nullable="true" /> + app:argType="org.jellyfin.sdk.model.api.BaseItemKind" + android:defaultValue="MOVIE" /> + app:argType="org.jellyfin.sdk.model.api.BaseItemKind" + android:defaultValue="MOVIE" />