refactor: upgrade to jellyfin 10.9 (#757)
* refactor: upgrade to jellyfin 10.9 * chore: upgrade to jellyfin sdk 1.5.0-beta.2 * fix: don't show resumable items in next up * chore: upgrade to jellyfin sdk 1.5.0-beta.3 * fix: sync offline playback progress * refactor: initialize BrandingApi in JellyfinApi * refactor: speed up quick connect auth * perf: load home data on Default dispatcher
This commit is contained in:
parent
ebfa81e053
commit
ba20b2fd37
22 changed files with 97 additions and 83 deletions
|
@ -325,8 +325,8 @@ class MovieFragment : Fragment() {
|
|||
it.displayProfiles.firstOrNull()?.apply {
|
||||
videoProfileChip.text = this.raw
|
||||
videoProfileChip.isVisible = when (this) {
|
||||
DisplayProfile.HDR,
|
||||
DisplayProfile.HDR10,
|
||||
DisplayProfile.HDR10_PLUS,
|
||||
DisplayProfile.HLG,
|
||||
-> {
|
||||
videoProfileChip.chipStartPadding = .0f
|
||||
|
|
|
@ -61,6 +61,7 @@ import dev.jdtech.jellyfin.viewmodels.MovieViewModel
|
|||
import dev.jdtech.jellyfin.viewmodels.PlayerItemsEvent
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerViewModel
|
||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||
import org.jellyfin.sdk.model.api.PersonKind
|
||||
import java.util.UUID
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
|
||||
|
@ -343,6 +344,7 @@ private fun MovieScreenLayoutPreview() {
|
|||
director = BaseItemPerson(
|
||||
id = UUID.randomUUID(),
|
||||
name = "Robert Rodriguez",
|
||||
type = PersonKind.DIRECTOR,
|
||||
),
|
||||
writers = emptyList(),
|
||||
videoMetadata = VideoMetadata(
|
||||
|
|
|
@ -35,8 +35,10 @@ object ApiModule {
|
|||
val user = serverWithAddressAndUser.user
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = serverAddress.address
|
||||
api.accessToken = user?.accessToken
|
||||
api.update(
|
||||
baseUrl = serverAddress.address,
|
||||
accessToken = user?.accessToken,
|
||||
)
|
||||
userId = user?.id
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class SortDialogFragment(
|
|||
when (sortType) {
|
||||
"sortBy" -> {
|
||||
val sortByOptions = resources.getStringArray(R.array.sort_by_options)
|
||||
val sortByValues = SortBy.values()
|
||||
val sortByValues = SortBy.entries
|
||||
builder
|
||||
.setTitle(getString(R.string.sort_by))
|
||||
.setSingleChoiceItems(
|
||||
|
@ -64,7 +64,7 @@ class SortDialogFragment(
|
|||
}
|
||||
"sortOrder" -> {
|
||||
val sortByOptions = resources.getStringArray(R.array.sort_order_options)
|
||||
val sortOrderValues = SortOrder.values()
|
||||
val sortOrderValues = SortOrder.entries
|
||||
|
||||
builder
|
||||
.setTitle(getString(R.string.sort_order))
|
||||
|
|
|
@ -18,7 +18,7 @@ fun BaseItemDto.toView(): View {
|
|||
return View(
|
||||
id = id,
|
||||
name = name ?: "",
|
||||
type = CollectionType.fromString(collectionType),
|
||||
type = CollectionType.fromString(collectionType?.serialName),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -202,8 +202,10 @@ constructor(
|
|||
appPreferences.currentServer = server.id
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = recommendedServerInfo.address
|
||||
api.accessToken = null
|
||||
api.update(
|
||||
baseUrl = recommendedServerInfo.address,
|
||||
accessToken = null,
|
||||
)
|
||||
}
|
||||
|
||||
_uiState.emit(UiState.Normal)
|
||||
|
|
|
@ -11,6 +11,7 @@ import dev.jdtech.jellyfin.models.HomeSection
|
|||
import dev.jdtech.jellyfin.models.UiText
|
||||
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||
import dev.jdtech.jellyfin.utils.toView
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -41,13 +42,12 @@ class HomeViewModel @Inject internal constructor(
|
|||
viewModelScope.launch {
|
||||
try {
|
||||
repository.postCapabilities()
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
} catch (_: Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
fun loadData() {
|
||||
viewModelScope.launch {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
_uiState.emit(UiState.Loading)
|
||||
try {
|
||||
val items = mutableListOf<HomeItem>()
|
||||
|
@ -93,7 +93,7 @@ class HomeViewModel @Inject internal constructor(
|
|||
|
||||
private suspend fun loadViews() = repository
|
||||
.getUserViews()
|
||||
.filter { view -> CollectionType.fromString(view.collectionType) in CollectionType.supported }
|
||||
.filter { view -> CollectionType.fromString(view.collectionType?.serialName) in CollectionType.supported }
|
||||
.map { view -> view to repository.getLatestMedia(view.id) }
|
||||
.filter { (_, latest) -> latest.isNotEmpty() }
|
||||
.map { (view, latest) -> view.toView().apply { items = latest } }
|
||||
|
|
|
@ -19,7 +19,6 @@ import kotlinx.coroutines.flow.receiveAsFlow
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.extensions.authenticateWithQuickConnect
|
||||
import org.jellyfin.sdk.api.client.extensions.brandingApi
|
||||
import org.jellyfin.sdk.model.api.AuthenticateUserByName
|
||||
import org.jellyfin.sdk.model.api.AuthenticationResult
|
||||
import javax.inject.Inject
|
||||
|
@ -72,7 +71,7 @@ constructor(
|
|||
|
||||
private fun loadDisclaimer() {
|
||||
viewModelScope.launch {
|
||||
loginDisclaimer = jellyfinApi.api.brandingApi.getBrandingOptions().content.loginDisclaimer
|
||||
loginDisclaimer = jellyfinApi.brandingApi.getBrandingOptions().content.loginDisclaimer
|
||||
_uiState.emit(UiState.Normal(loginDisclaimer))
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +103,7 @@ constructor(
|
|||
private fun loadQuickConnectAvailable() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val isEnabled by jellyfinApi.quickConnectApi.getEnabled()
|
||||
val isEnabled by jellyfinApi.quickConnectApi.getQuickConnectEnabled()
|
||||
if (isEnabled) {
|
||||
_quickConnectUiState.emit(QuickConnectUiState.Normal)
|
||||
}
|
||||
|
@ -155,12 +154,12 @@ constructor(
|
|||
}
|
||||
quickConnectJob = viewModelScope.launch {
|
||||
try {
|
||||
var quickConnectState = jellyfinApi.quickConnectApi.initiate().content
|
||||
var quickConnectState = jellyfinApi.quickConnectApi.initiateQuickConnect().content
|
||||
_quickConnectUiState.emit(QuickConnectUiState.Waiting(quickConnectState.code))
|
||||
|
||||
while (!quickConnectState.authenticated) {
|
||||
quickConnectState = jellyfinApi.quickConnectApi.connect(quickConnectState.secret).content
|
||||
delay(5000L)
|
||||
quickConnectState = jellyfinApi.quickConnectApi.getQuickConnectState(quickConnectState.secret).content
|
||||
}
|
||||
val authenticationResult by jellyfinApi.userApi.authenticateWithQuickConnect(
|
||||
secret = quickConnectState.secret,
|
||||
|
@ -189,7 +188,7 @@ constructor(
|
|||
insertUser(appPreferences.currentServer!!, user)
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.accessToken = authenticationResult.accessToken
|
||||
api.update(accessToken = authenticationResult.accessToken)
|
||||
userId = authenticationResult.user?.id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ import kotlinx.coroutines.withContext
|
|||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||
import org.jellyfin.sdk.model.api.MediaStream
|
||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||
import org.jellyfin.sdk.model.api.PersonKind
|
||||
import org.jellyfin.sdk.model.api.VideoRangeType
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
@ -119,7 +121,7 @@ constructor(
|
|||
private suspend fun getActors(item: FindroidMovie): List<BaseItemPerson> {
|
||||
val actors: List<BaseItemPerson>
|
||||
withContext(Dispatchers.Default) {
|
||||
actors = item.people.filter { it.type == "Actor" }
|
||||
actors = item.people.filter { it.type == PersonKind.ACTOR }
|
||||
}
|
||||
return actors
|
||||
}
|
||||
|
@ -127,7 +129,7 @@ constructor(
|
|||
private suspend fun getDirector(item: FindroidMovie): BaseItemPerson? {
|
||||
val director: BaseItemPerson?
|
||||
withContext(Dispatchers.Default) {
|
||||
director = item.people.firstOrNull { it.type == "Director" }
|
||||
director = item.people.firstOrNull { it.type == PersonKind.DIRECTOR }
|
||||
}
|
||||
return director
|
||||
}
|
||||
|
@ -135,7 +137,7 @@ constructor(
|
|||
private suspend fun getWriters(item: FindroidMovie): List<BaseItemPerson> {
|
||||
val writers: List<BaseItemPerson>
|
||||
withContext(Dispatchers.Default) {
|
||||
writers = item.people.filter { it.type == "Writer" }
|
||||
writers = item.people.filter { it.type == PersonKind.WRITER }
|
||||
}
|
||||
return writers
|
||||
}
|
||||
|
@ -213,9 +215,9 @@ constructor(
|
|||
DisplayProfile.DOLBY_VISION
|
||||
} else {
|
||||
when (videoRangeType) {
|
||||
DisplayProfile.HDR.raw -> DisplayProfile.HDR
|
||||
DisplayProfile.HDR10.raw -> DisplayProfile.HDR10
|
||||
DisplayProfile.HLG.raw -> DisplayProfile.HLG
|
||||
VideoRangeType.HDR10 -> DisplayProfile.HDR10
|
||||
VideoRangeType.HDR10_PLUS -> DisplayProfile.HDR10_PLUS
|
||||
VideoRangeType.HLG -> DisplayProfile.HLG
|
||||
else -> DisplayProfile.SDR
|
||||
}
|
||||
},
|
||||
|
|
|
@ -74,7 +74,9 @@ constructor(
|
|||
server.currentServerAddressId = address.id
|
||||
database.update(server)
|
||||
|
||||
jellyfinApi.api.baseUrl = address.address
|
||||
jellyfinApi.api.update(
|
||||
baseUrl = address.address,
|
||||
)
|
||||
|
||||
eventsChannel.send(ServerAddressesEvent.NavigateToHome)
|
||||
}
|
||||
|
@ -84,7 +86,9 @@ constructor(
|
|||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val jellyfinApi = JellyfinApi(context)
|
||||
jellyfinApi.api.baseUrl = address
|
||||
jellyfinApi.api.update(
|
||||
baseUrl = address,
|
||||
)
|
||||
val systemInfo by jellyfinApi.systemApi.getPublicSystemInfo()
|
||||
if (systemInfo.id != currentServerId) {
|
||||
return@launch
|
||||
|
|
|
@ -101,8 +101,10 @@ constructor(
|
|||
// If server has no selected user, navigate to login fragment
|
||||
if (user == null) {
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = serverAddress.address
|
||||
api.accessToken = null
|
||||
api.update(
|
||||
baseUrl = serverAddress.address,
|
||||
accessToken = null,
|
||||
)
|
||||
userId = null
|
||||
}
|
||||
appPreferences.currentServer = server.id
|
||||
|
@ -111,8 +113,10 @@ constructor(
|
|||
}
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = serverAddress.address
|
||||
api.accessToken = user.accessToken
|
||||
api.update(
|
||||
baseUrl = serverAddress.address,
|
||||
accessToken = user.accessToken,
|
||||
)
|
||||
userId = user.id
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.receiveAsFlow
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||
import org.jellyfin.sdk.model.api.PersonKind
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -100,7 +101,7 @@ constructor(
|
|||
private suspend fun getActors(item: FindroidShow): List<BaseItemPerson> {
|
||||
val actors: List<BaseItemPerson>
|
||||
withContext(Dispatchers.Default) {
|
||||
actors = item.people.filter { it.type == "Actor" }
|
||||
actors = item.people.filter { it.type == PersonKind.ACTOR }
|
||||
}
|
||||
return actors
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ constructor(
|
|||
private suspend fun getDirector(item: FindroidShow): BaseItemPerson? {
|
||||
val director: BaseItemPerson?
|
||||
withContext(Dispatchers.Default) {
|
||||
director = item.people.firstOrNull { it.type == "Director" }
|
||||
director = item.people.firstOrNull { it.type == PersonKind.DIRECTOR }
|
||||
}
|
||||
return director
|
||||
}
|
||||
|
@ -116,7 +117,7 @@ constructor(
|
|||
private suspend fun getWriters(item: FindroidShow): List<BaseItemPerson> {
|
||||
val writers: List<BaseItemPerson>
|
||||
withContext(Dispatchers.Default) {
|
||||
writers = item.people.filter { it.type == "Writer" }
|
||||
writers = item.people.filter { it.type == PersonKind.WRITER }
|
||||
}
|
||||
return writers
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import javax.inject.Inject
|
|||
class UserSelectViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val appPreferences: AppPreferences,
|
||||
appPreferences: AppPreferences,
|
||||
private val jellyfinApi: JellyfinApi,
|
||||
private val database: ServerDatabaseDao,
|
||||
) : ViewModel() {
|
||||
|
@ -71,7 +71,9 @@ constructor(
|
|||
database.update(server)
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.accessToken = user.accessToken
|
||||
api.update(
|
||||
accessToken = user.accessToken,
|
||||
)
|
||||
userId = user.id
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,9 @@ constructor(
|
|||
database.update(server)
|
||||
|
||||
jellyfinApi.apply {
|
||||
api.accessToken = user.accessToken
|
||||
api.update(
|
||||
accessToken = user.accessToken,
|
||||
)
|
||||
userId = user.id
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@ class SyncWorker @AssistedInject constructor(
|
|||
val serverAddress = serverWithAddressesAndUsers.addresses.firstOrNull { it.id == server.currentServerAddressId } ?: continue
|
||||
for (user in serverWithAddressesAndUsers.users) {
|
||||
jellyfinApi.apply {
|
||||
api.baseUrl = serverAddress.address
|
||||
api.accessToken = user.accessToken
|
||||
api.update(
|
||||
baseUrl = serverAddress.address,
|
||||
accessToken = user.accessToken,
|
||||
)
|
||||
userId = user.id
|
||||
}
|
||||
val movies = database.getMoviesByServerId(server.id).map { it.toFindroidMovie(database, user.id) }
|
||||
|
@ -66,17 +68,16 @@ class SyncWorker @AssistedInject constructor(
|
|||
|
||||
try {
|
||||
when (userData.played) {
|
||||
true -> jellyfinApi.playStateApi.markPlayedItem(user.id, item.id)
|
||||
false -> jellyfinApi.playStateApi.markUnplayedItem(user.id, item.id)
|
||||
true -> jellyfinApi.playStateApi.markPlayedItem(item.id, user.id)
|
||||
false -> jellyfinApi.playStateApi.markUnplayedItem(item.id, user.id)
|
||||
}
|
||||
|
||||
when (userData.favorite) {
|
||||
true -> jellyfinApi.userLibraryApi.markFavoriteItem(user.id, item.id)
|
||||
false -> jellyfinApi.userLibraryApi.unmarkFavoriteItem(user.id, item.id)
|
||||
true -> jellyfinApi.userLibraryApi.markFavoriteItem(item.id, user.id)
|
||||
false -> jellyfinApi.userLibraryApi.unmarkFavoriteItem(item.id, user.id)
|
||||
}
|
||||
|
||||
jellyfinApi.playStateApi.onPlaybackStopped(
|
||||
userId = user.id,
|
||||
itemId = item.id,
|
||||
positionTicks = userData.playbackPositionTicks,
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import dev.jdtech.jellyfin.Constants
|
||||
import dev.jdtech.jellyfin.data.BuildConfig
|
||||
import org.jellyfin.sdk.api.client.HttpClientOptions
|
||||
import org.jellyfin.sdk.api.client.extensions.brandingApi
|
||||
import org.jellyfin.sdk.api.client.extensions.devicesApi
|
||||
import org.jellyfin.sdk.api.client.extensions.itemsApi
|
||||
import org.jellyfin.sdk.api.client.extensions.mediaInfoApi
|
||||
|
@ -19,6 +20,8 @@ import org.jellyfin.sdk.api.client.extensions.videosApi
|
|||
import org.jellyfin.sdk.createJellyfin
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
import java.util.UUID
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.toDuration
|
||||
|
||||
/**
|
||||
* Jellyfin API class using org.jellyfin.sdk:jellyfin-platform-android
|
||||
|
@ -40,25 +43,26 @@ class JellyfinApi(
|
|||
}
|
||||
val api = jellyfin.createApi(
|
||||
httpClientOptions = HttpClientOptions(
|
||||
requestTimeout = requestTimeout,
|
||||
connectTimeout = connectTimeout,
|
||||
socketTimeout = socketTimeout,
|
||||
requestTimeout = requestTimeout.toDuration(DurationUnit.MILLISECONDS),
|
||||
connectTimeout = connectTimeout.toDuration(DurationUnit.MILLISECONDS),
|
||||
socketTimeout = socketTimeout.toDuration(DurationUnit.MILLISECONDS),
|
||||
),
|
||||
)
|
||||
var userId: UUID? = null
|
||||
|
||||
val brandingApi = api.brandingApi
|
||||
val devicesApi = api.devicesApi
|
||||
val systemApi = api.systemApi
|
||||
val userApi = api.userApi
|
||||
val viewsApi = api.userViewsApi
|
||||
val itemsApi = api.itemsApi
|
||||
val userLibraryApi = api.userLibraryApi
|
||||
val showsApi = api.tvShowsApi
|
||||
val sessionApi = api.sessionApi
|
||||
val videosApi = api.videosApi
|
||||
val mediaInfoApi = api.mediaInfoApi
|
||||
val playStateApi = api.playStateApi
|
||||
val quickConnectApi = api.quickConnectApi
|
||||
val sessionApi = api.sessionApi
|
||||
val showsApi = api.tvShowsApi
|
||||
val systemApi = api.systemApi
|
||||
val userApi = api.userApi
|
||||
val userLibraryApi = api.userLibraryApi
|
||||
val videosApi = api.videosApi
|
||||
val viewsApi = api.userViewsApi
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
|
|
|
@ -25,7 +25,7 @@ data class FindroidCollection(
|
|||
fun BaseItemDto.toFindroidCollection(
|
||||
jellyfinRepository: JellyfinRepository,
|
||||
): FindroidCollection? {
|
||||
val type = CollectionType.fromString(collectionType)
|
||||
val type = CollectionType.fromString(collectionType?.serialName)
|
||||
|
||||
if (type !in CollectionType.supported) {
|
||||
return null
|
||||
|
|
|
@ -3,6 +3,7 @@ package dev.jdtech.jellyfin.models
|
|||
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||
import org.jellyfin.sdk.model.api.MediaStream
|
||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||
import org.jellyfin.sdk.model.api.VideoRangeType
|
||||
|
||||
data class FindroidMediaStream(
|
||||
val title: String,
|
||||
|
@ -13,7 +14,7 @@ data class FindroidMediaStream(
|
|||
val isExternal: Boolean,
|
||||
val path: String?,
|
||||
val channelLayout: String?,
|
||||
val videoRangeType: String?,
|
||||
val videoRangeType: VideoRangeType?,
|
||||
val height: Int?,
|
||||
val width: Int?,
|
||||
val videoDoViTitle: String?,
|
||||
|
@ -46,7 +47,7 @@ fun FindroidMediaStreamDto.toFindroidMediaStream(): FindroidMediaStream {
|
|||
isExternal = isExternal,
|
||||
path = path,
|
||||
channelLayout = channelLayout,
|
||||
videoRangeType = videoRangeType,
|
||||
videoRangeType = VideoRangeType.fromNameOrNull(videoRangeType ?: ""),
|
||||
height = height,
|
||||
width = width,
|
||||
videoDoViTitle = videoDoViTitle,
|
||||
|
|
|
@ -39,7 +39,7 @@ fun FindroidMediaStream.toFindroidMediaStreamDto(id: UUID, sourceId: String, pat
|
|||
isExternal = isExternal,
|
||||
path = path,
|
||||
channelLayout = channelLayout,
|
||||
videoRangeType = videoRangeType,
|
||||
videoRangeType = videoRangeType?.name,
|
||||
height = height,
|
||||
width = width,
|
||||
videoDoViTitle = videoDoViTitle,
|
||||
|
|
|
@ -18,8 +18,8 @@ enum class Resolution(val raw: String) {
|
|||
|
||||
enum class DisplayProfile(val raw: String) {
|
||||
SDR("SDR"),
|
||||
HDR("HDR"),
|
||||
HDR10("HDR10"),
|
||||
HDR10_PLUS("HDR10+"),
|
||||
DOLBY_VISION("Vision"),
|
||||
HLG("HLG"),
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.jellyfin.sdk.model.api.DlnaProfileType
|
|||
import org.jellyfin.sdk.model.api.GeneralCommandType
|
||||
import org.jellyfin.sdk.model.api.ItemFields
|
||||
import org.jellyfin.sdk.model.api.ItemFilter
|
||||
import org.jellyfin.sdk.model.api.ItemSortBy
|
||||
import org.jellyfin.sdk.model.api.MediaType
|
||||
import org.jellyfin.sdk.model.api.PlaybackInfoDto
|
||||
import org.jellyfin.sdk.model.api.PublicSystemInfo
|
||||
import org.jellyfin.sdk.model.api.SortOrder
|
||||
|
@ -66,38 +68,38 @@ class JellyfinRepositoryImpl(
|
|||
}
|
||||
|
||||
override suspend fun getItem(itemId: UUID): BaseItemDto = withContext(Dispatchers.IO) {
|
||||
jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, itemId).content
|
||||
jellyfinApi.userLibraryApi.getItem(itemId, jellyfinApi.userId!!).content
|
||||
}
|
||||
|
||||
override suspend fun getEpisode(itemId: UUID): FindroidEpisode =
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.userLibraryApi.getItem(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
jellyfinApi.userId!!,
|
||||
).content.toFindroidEpisode(this@JellyfinRepositoryImpl, database)!!
|
||||
}
|
||||
|
||||
override suspend fun getMovie(itemId: UUID): FindroidMovie =
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.userLibraryApi.getItem(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
jellyfinApi.userId!!,
|
||||
).content.toFindroidMovie(this@JellyfinRepositoryImpl, database)
|
||||
}
|
||||
|
||||
override suspend fun getShow(itemId: UUID): FindroidShow =
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.userLibraryApi.getItem(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
jellyfinApi.userId!!,
|
||||
).content.toFindroidShow(this@JellyfinRepositoryImpl)
|
||||
}
|
||||
|
||||
override suspend fun getSeason(itemId: UUID): FindroidSeason =
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.userLibraryApi.getItem(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
jellyfinApi.userId!!,
|
||||
).content.toFindroidSeason(this@JellyfinRepositoryImpl)
|
||||
}
|
||||
|
||||
|
@ -125,7 +127,7 @@ class JellyfinRepositoryImpl(
|
|||
parentId = parentId,
|
||||
includeItemTypes = includeTypes,
|
||||
recursive = recursive,
|
||||
sortBy = listOf(sortBy.sortString),
|
||||
sortBy = listOf(ItemSortBy.fromName(sortBy.sortString)),
|
||||
sortOrder = listOf(sortOrder),
|
||||
startIndex = startIndex,
|
||||
limit = limit,
|
||||
|
@ -251,7 +253,8 @@ class JellyfinRepositoryImpl(
|
|||
jellyfinApi.showsApi.getNextUp(
|
||||
jellyfinApi.userId!!,
|
||||
limit = 24,
|
||||
seriesId = seriesId?.toString(),
|
||||
seriesId = seriesId,
|
||||
enableResumable = false,
|
||||
).content.items
|
||||
.orEmpty()
|
||||
.mapNotNull { it.toFindroidEpisode(this@JellyfinRepositoryImpl) }
|
||||
|
@ -301,23 +304,10 @@ class JellyfinRepositoryImpl(
|
|||
DirectPlayProfile(type = DlnaProfileType.AUDIO),
|
||||
),
|
||||
transcodingProfiles = emptyList(),
|
||||
responseProfiles = emptyList(),
|
||||
subtitleProfiles = listOf(
|
||||
SubtitleProfile("srt", SubtitleDeliveryMethod.EXTERNAL),
|
||||
SubtitleProfile("ass", SubtitleDeliveryMethod.EXTERNAL),
|
||||
),
|
||||
xmlRootAttributes = emptyList(),
|
||||
supportedMediaTypes = "",
|
||||
enableAlbumArtInDidl = false,
|
||||
enableMsMediaReceiverRegistrar = false,
|
||||
enableSingleAlbumArtLimit = false,
|
||||
enableSingleSubtitleLimit = false,
|
||||
ignoreTranscodeByteRangeRequests = false,
|
||||
maxAlbumArtHeight = 1_000_000_000,
|
||||
maxAlbumArtWidth = 1_000_000_000,
|
||||
requiresPlainFolders = false,
|
||||
requiresPlainVideoItems = false,
|
||||
timelineOffsetSeconds = 0,
|
||||
),
|
||||
maxStreamingBitrate = 1_000_000_000,
|
||||
),
|
||||
|
@ -420,7 +410,7 @@ class JellyfinRepositoryImpl(
|
|||
Timber.d("Sending capabilities")
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.sessionApi.postCapabilities(
|
||||
playableMediaTypes = listOf("Video"),
|
||||
playableMediaTypes = listOf(MediaType.VIDEO),
|
||||
supportedCommands = listOf(
|
||||
GeneralCommandType.VOLUME_UP,
|
||||
GeneralCommandType.VOLUME_DOWN,
|
||||
|
@ -444,7 +434,7 @@ class JellyfinRepositoryImpl(
|
|||
override suspend fun postPlaybackStart(itemId: UUID) {
|
||||
Timber.d("Sending start $itemId")
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.playStateApi.onPlaybackStart(jellyfinApi.userId!!, itemId)
|
||||
jellyfinApi.playStateApi.onPlaybackStart(itemId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,7 +461,6 @@ class JellyfinRepositoryImpl(
|
|||
}
|
||||
try {
|
||||
jellyfinApi.playStateApi.onPlaybackStopped(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
positionTicks = positionTicks,
|
||||
)
|
||||
|
@ -491,7 +480,6 @@ class JellyfinRepositoryImpl(
|
|||
database.setPlaybackPositionTicks(itemId, jellyfinApi.userId!!, positionTicks)
|
||||
try {
|
||||
jellyfinApi.playStateApi.onPlaybackProgress(
|
||||
jellyfinApi.userId!!,
|
||||
itemId,
|
||||
positionTicks = positionTicks,
|
||||
isPaused = isPaused,
|
||||
|
|
|
@ -28,7 +28,7 @@ androidx-work = "2.9.0"
|
|||
coil = "2.6.0"
|
||||
hilt = "2.51.1"
|
||||
compose-destinations = "1.10.2"
|
||||
jellyfin = "1.4.7"
|
||||
jellyfin = "1.5.0-beta.3"
|
||||
junit = "4.13.2"
|
||||
kotlin = "2.0.0"
|
||||
kotlinx-serialization = "1.7.0"
|
||||
|
|
Loading…
Reference in a new issue