Clean up
This commit is contained in:
parent
293e71fc27
commit
1e9ddd1173
9 changed files with 36 additions and 128 deletions
|
@ -6,16 +6,11 @@ import androidx.databinding.BindingAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
import dev.jdtech.jellyfin.adapters.DownloadsListAdapter
|
|
||||||
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
|
import dev.jdtech.jellyfin.adapters.HomeEpisodeListAdapter
|
||||||
import dev.jdtech.jellyfin.adapters.HomeItem
|
|
||||||
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
|
||||||
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
||||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
||||||
import dev.jdtech.jellyfin.adapters.ViewListAdapter
|
|
||||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||||
import dev.jdtech.jellyfin.database.Server
|
import dev.jdtech.jellyfin.database.Server
|
||||||
import dev.jdtech.jellyfin.models.DownloadSection
|
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
import org.jellyfin.sdk.model.api.BaseItemPerson
|
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
|
@ -57,12 +52,6 @@ fun bindItemBackdropById(imageView: ImageView, itemId: UUID) {
|
||||||
imageView.loadImage("/items/$itemId/Images/${ImageType.BACKDROP}")
|
imageView.loadImage("/items/$itemId/Images/${ImageType.BACKDROP}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("people")
|
|
||||||
fun bindPeople(recyclerView: RecyclerView, data: List<BaseItemPerson>?) {
|
|
||||||
val adapter = recyclerView.adapter as PersonListAdapter
|
|
||||||
adapter.submitList(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
@BindingAdapter("personImage")
|
@BindingAdapter("personImage")
|
||||||
fun bindPersonImage(imageView: ImageView, person: BaseItemPerson) {
|
fun bindPersonImage(imageView: ImageView, person: BaseItemPerson) {
|
||||||
imageView
|
imageView
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.util.UUID
|
||||||
* Jellyfin API class using org.jellyfin.sdk:jellyfin-platform-android
|
* Jellyfin API class using org.jellyfin.sdk:jellyfin-platform-android
|
||||||
*
|
*
|
||||||
* @param androidContext The context
|
* @param androidContext The context
|
||||||
* @param baseUrl The url of the server
|
|
||||||
* @constructor Creates a new [JellyfinApi] instance
|
* @constructor Creates a new [JellyfinApi] instance
|
||||||
*/
|
*/
|
||||||
class JellyfinApi(androidContext: Context) {
|
class JellyfinApi(androidContext: Context) {
|
||||||
|
|
|
@ -815,11 +815,11 @@ class MPVPlayer(
|
||||||
override fun seekTo(windowIndex: Int, positionMs: Long) {
|
override fun seekTo(windowIndex: Int, positionMs: Long) {
|
||||||
if (windowIndex == 0) {
|
if (windowIndex == 0) {
|
||||||
val seekTo = if (positionMs != C.TIME_UNSET) positionMs / C.MILLIS_PER_SECOND else initialSeekTo
|
val seekTo = if (positionMs != C.TIME_UNSET) positionMs / C.MILLIS_PER_SECOND else initialSeekTo
|
||||||
if (isPlayerReady) {
|
initialSeekTo = if (isPlayerReady) {
|
||||||
MPVLib.command(arrayOf("seek", "$seekTo", "absolute"))
|
MPVLib.command(arrayOf("seek", "$seekTo", "absolute"))
|
||||||
initialSeekTo = 0L
|
0L
|
||||||
} else {
|
} else {
|
||||||
initialSeekTo = seekTo
|
seekTo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.widget.ImageButton
|
||||||
import android.widget.PopupWindow
|
import android.widget.PopupWindow
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.navigation.navArgs
|
import androidx.navigation.navArgs
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
@ -69,12 +70,14 @@ internal class TvPlayerActivity : BasePlayerActivity() {
|
||||||
when {
|
when {
|
||||||
viewModel.player.isPlaying -> {
|
viewModel.player.isPlaying -> {
|
||||||
viewModel.player.pause()
|
viewModel.player.pause()
|
||||||
setImageDrawable(resources.getDrawable(R.drawable.ic_play))
|
setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
viewModel.player.isLoading -> Unit
|
viewModel.player.isLoading -> Unit
|
||||||
else -> {
|
else -> {
|
||||||
viewModel.player.play()
|
viewModel.player.play()
|
||||||
setImageDrawable(resources.getDrawable(R.drawable.ic_pause))
|
setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_play, theme)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +94,7 @@ internal class TvPlayerActivity : BasePlayerActivity() {
|
||||||
private fun bindAudioControl() {
|
private fun bindAudioControl() {
|
||||||
val audioBtn = binding.playerView.findViewById<ImageButton>(R.id.btn_audio_track)
|
val audioBtn = binding.playerView.findViewById<ImageButton>(R.id.btn_audio_track)
|
||||||
|
|
||||||
audioBtn.setOnFocusChangeListener { v, hasFocus ->
|
audioBtn.setOnFocusChangeListener { _, hasFocus ->
|
||||||
displayedPopup = if (hasFocus) {
|
displayedPopup = if (hasFocus) {
|
||||||
val items = viewModel.currentSubtitleTracks.toUiTrack()
|
val items = viewModel.currentSubtitleTracks.toUiTrack()
|
||||||
audioBtn.showPopupWindowAbove(items, AUDIO)
|
audioBtn.showPopupWindowAbove(items, AUDIO)
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
package dev.jdtech.jellyfin.tv.ui
|
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import dev.jdtech.jellyfin.R
|
|
||||||
import dev.jdtech.jellyfin.models.ContentType.MOVIE
|
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
internal class MediaDetailViewModel @Inject internal constructor() : ViewModel() {
|
|
||||||
|
|
||||||
fun transformData(
|
|
||||||
data: BaseItemDto,
|
|
||||||
resources: Resources,
|
|
||||||
transformed: (State) -> Unit
|
|
||||||
): State {
|
|
||||||
return State(
|
|
||||||
dto = data,
|
|
||||||
description = data.overview.orEmpty(),
|
|
||||||
year = data.productionYear.toString(),
|
|
||||||
officialRating = data.officialRating.orEmpty(),
|
|
||||||
communityRating = data.communityRating.toString(),
|
|
||||||
runtimeMinutes = String.format(
|
|
||||||
resources.getString(R.string.runtime_minutes),
|
|
||||||
data.runTimeTicks?.div(600_000_000)
|
|
||||||
),
|
|
||||||
genres = data.genres?.joinToString(" / ").orEmpty(),
|
|
||||||
trailerUrl = data.remoteTrailers?.firstOrNull()?.url,
|
|
||||||
isPlayed = data.userData?.played == true,
|
|
||||||
isFavorite = data.userData?.isFavorite == true,
|
|
||||||
media = if (data.type == MOVIE.type) {
|
|
||||||
State.Movie(
|
|
||||||
title = data.name.orEmpty()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
State.TvShow(
|
|
||||||
episode = data.episodeTitle ?: data.name.orEmpty(),
|
|
||||||
show = data.seriesName.orEmpty()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
).also(transformed)
|
|
||||||
}
|
|
||||||
|
|
||||||
data class State(
|
|
||||||
val dto: BaseItemDto,
|
|
||||||
val description: String,
|
|
||||||
val year: String,
|
|
||||||
val officialRating: String,
|
|
||||||
val communityRating: String,
|
|
||||||
val runtimeMinutes: String,
|
|
||||||
val genres: String,
|
|
||||||
val trailerUrl: String?,
|
|
||||||
val isPlayed: Boolean,
|
|
||||||
val isFavorite: Boolean,
|
|
||||||
val media: Media
|
|
||||||
) {
|
|
||||||
|
|
||||||
sealed class Media
|
|
||||||
|
|
||||||
data class Movie(val title: String): Media()
|
|
||||||
data class TvShow(val episode: String, val show: String): Media()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package dev.jdtech.jellyfin.utils
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.media.AudioManager
|
|
||||||
import android.media.AudioManager.ADJUST_LOWER
|
|
||||||
import android.media.AudioManager.ADJUST_RAISE
|
|
||||||
import android.media.AudioManager.ADJUST_SAME
|
|
||||||
import android.media.AudioManager.FLAG_SHOW_UI
|
|
||||||
import android.media.AudioManager.STREAM_MUSIC
|
|
||||||
|
|
||||||
internal class AudioController internal constructor(context: Context) {
|
|
||||||
|
|
||||||
private val manager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
||||||
|
|
||||||
fun volumeUp() = manager.adjustStreamVolume(STREAM_MUSIC, ADJUST_RAISE, FLAG_SHOW_UI)
|
|
||||||
fun volumeDown() = manager.adjustStreamVolume(STREAM_MUSIC, ADJUST_LOWER, FLAG_SHOW_UI)
|
|
||||||
fun showVolumeSlider() = manager.adjustStreamVolume(STREAM_MUSIC, ADJUST_SAME, FLAG_SHOW_UI)
|
|
||||||
}
|
|
|
@ -241,7 +241,7 @@ fun parseMetadataFile(metadataFile: List<String>): DownloadMetadata {
|
||||||
|
|
||||||
suspend fun syncPlaybackProgress(jellyfinRepository: JellyfinRepository) {
|
suspend fun syncPlaybackProgress(jellyfinRepository: JellyfinRepository) {
|
||||||
val items = loadDownloadedEpisodes()
|
val items = loadDownloadedEpisodes()
|
||||||
items.forEach() {
|
items.forEach {
|
||||||
try {
|
try {
|
||||||
val localPlaybackProgress = it.metadata?.playbackPosition
|
val localPlaybackProgress = it.metadata?.playbackPosition
|
||||||
val localPlayedPercentage = it.metadata?.playedPercentage
|
val localPlayedPercentage = it.metadata?.playedPercentage
|
||||||
|
|
|
@ -80,22 +80,27 @@ constructor(
|
||||||
|
|
||||||
recommended
|
recommended
|
||||||
.onCompletion {
|
.onCompletion {
|
||||||
if (greatServers.isNotEmpty()) {
|
when {
|
||||||
connectToServer(greatServers.first())
|
greatServers.isNotEmpty() -> {
|
||||||
} else if (goodServers.isNotEmpty()) {
|
connectToServer(greatServers.first())
|
||||||
val issuesString = createIssuesString(goodServers.first())
|
}
|
||||||
Toast.makeText(
|
goodServers.isNotEmpty() -> {
|
||||||
application,
|
val issuesString = createIssuesString(goodServers.first())
|
||||||
issuesString,
|
Toast.makeText(
|
||||||
Toast.LENGTH_LONG
|
application,
|
||||||
).show()
|
issuesString,
|
||||||
connectToServer(goodServers.first())
|
Toast.LENGTH_LONG
|
||||||
} else if (okServers.isNotEmpty()) {
|
).show()
|
||||||
val okServer = okServers.first()
|
connectToServer(goodServers.first())
|
||||||
val issuesString = createIssuesString(okServer)
|
}
|
||||||
throw Exception(issuesString)
|
okServers.isNotEmpty() -> {
|
||||||
} else {
|
val okServer = okServers.first()
|
||||||
throw Exception(resources.getString(R.string.add_server_error_not_found))
|
val issuesString = createIssuesString(okServer)
|
||||||
|
throw Exception(issuesString)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw Exception(resources.getString(R.string.add_server_error_not_found))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.collect { recommendedServerInfo ->
|
.collect { recommendedServerInfo ->
|
||||||
|
|
|
@ -49,15 +49,15 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
var item: BaseItemDto? = null
|
var item: BaseItemDto? = null
|
||||||
var runTime: String = ""
|
private var runTime: String = ""
|
||||||
var dateString: String = ""
|
private var dateString: String = ""
|
||||||
var played: Boolean = false
|
var played: Boolean = false
|
||||||
var favorite: Boolean = false
|
var favorite: Boolean = false
|
||||||
var downloaded: Boolean = false
|
private var downloaded: Boolean = false
|
||||||
var downloadEpisode: Boolean = false
|
private var downloadEpisode: Boolean = false
|
||||||
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
var playerItems: MutableList<PlayerItem> = mutableListOf()
|
||||||
|
|
||||||
lateinit var downloadRequestItem: DownloadRequestItem
|
private lateinit var downloadRequestItem: DownloadRequestItem
|
||||||
|
|
||||||
fun loadEpisode(episodeId: UUID) {
|
fun loadEpisode(episodeId: UUID) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -161,9 +161,4 @@ constructor(
|
||||||
item.premiereDate.toString()
|
item.premiereDate.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doneDownloadEpisode() {
|
|
||||||
downloadEpisode = false
|
|
||||||
downloaded = true
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue