Refactor slideshow to use new player creation

This commit is contained in:
Damontecres 2026-03-05 20:58:36 -05:00
parent 271cb0ca20
commit fc5babac45
No known key found for this signature in database
2 changed files with 464 additions and 435 deletions

View file

@ -67,6 +67,7 @@ import com.github.damontecres.wholphin.ui.playback.isDirectionalDpad
import com.github.damontecres.wholphin.ui.playback.isDpad import com.github.damontecres.wholphin.ui.playback.isDpad
import com.github.damontecres.wholphin.ui.playback.isEnterKey import com.github.damontecres.wholphin.ui.playback.isEnterKey
import com.github.damontecres.wholphin.ui.tryRequestFocus import com.github.damontecres.wholphin.ui.tryRequestFocus
import com.github.damontecres.wholphin.util.LoadingState
import org.jellyfin.sdk.model.api.MediaType import org.jellyfin.sdk.model.api.MediaType
import timber.log.Timber import timber.log.Timber
import kotlin.math.abs import kotlin.math.abs
@ -88,7 +89,20 @@ fun SlideshowPage(
), ),
) { ) {
val context = LocalContext.current val context = LocalContext.current
val loading by viewModel.loading.collectAsState()
when (val st = loading) {
is LoadingState.Error -> {
ErrorMessage(st, modifier)
}
LoadingState.Loading,
LoadingState.Pending,
-> {
LoadingPage(modifier)
}
LoadingState.Success -> {
val loadingState by viewModel.loadingState.observeAsState(ImageLoadingState.Loading) val loadingState by viewModel.loadingState.observeAsState(ImageLoadingState.Loading)
val imageFilter by viewModel.imageFilter.observeAsState(VideoFilter()) val imageFilter by viewModel.imageFilter.observeAsState(VideoFilter())
val position by viewModel.position.observeAsState(0) val position by viewModel.position.observeAsState(0)
@ -395,7 +409,8 @@ fun SlideshowPage(
) )
} }
transformOrigin = TransformOrigin(xTransform, yTransform) transformOrigin =
TransformOrigin(xTransform, yTransform)
}.rotate(rotateAnimation), }.rotate(rotateAnimation),
model = model =
ImageRequest ImageRequest
@ -498,3 +513,5 @@ fun SlideshowPage(
} }
} }
} }
}
}

View file

@ -16,6 +16,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.PlaybackEffect import com.github.damontecres.wholphin.data.model.PlaybackEffect
import com.github.damontecres.wholphin.data.model.VideoFilter import com.github.damontecres.wholphin.data.model.VideoFilter
import com.github.damontecres.wholphin.preferences.AppPreference import com.github.damontecres.wholphin.preferences.AppPreference
import com.github.damontecres.wholphin.preferences.PlayerBackend
import com.github.damontecres.wholphin.services.ImageUrlService import com.github.damontecres.wholphin.services.ImageUrlService
import com.github.damontecres.wholphin.services.PlayerFactory import com.github.damontecres.wholphin.services.PlayerFactory
import com.github.damontecres.wholphin.services.ScreensaverService import com.github.damontecres.wholphin.services.ScreensaverService
@ -30,6 +31,7 @@ import com.github.damontecres.wholphin.ui.util.ThrottledLiveData
import com.github.damontecres.wholphin.util.ApiRequestPager import com.github.damontecres.wholphin.util.ApiRequestPager
import com.github.damontecres.wholphin.util.ExceptionHandler import com.github.damontecres.wholphin.util.ExceptionHandler
import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler
import com.github.damontecres.wholphin.util.LoadingState
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -77,9 +79,8 @@ class SlideshowViewModel
fun create(slideshow: Destination.Slideshow): SlideshowViewModel fun create(slideshow: Destination.Slideshow): SlideshowViewModel
} }
val player by lazy { lateinit var player: Player
playerFactory.createVideoPlayer() private set
}
private var saveFilters = true private var saveFilters = true
@ -104,6 +105,8 @@ class SlideshowViewModel
private val _image = MutableLiveData<ImageState>() private val _image = MutableLiveData<ImageState>()
val image: LiveData<ImageState> = _image val image: LiveData<ImageState> = _image
val loading = MutableStateFlow<LoadingState>(LoadingState.Pending)
val loadingState = MutableLiveData<ImageLoadingState>(ImageLoadingState.Loading) val loadingState = MutableLiveData<ImageLoadingState>(ImageLoadingState.Loading)
private val _imageFilter = MutableLiveData(VideoFilter()) private val _imageFilter = MutableLiveData(VideoFilter())
val imageFilter = ThrottledLiveData(_imageFilter, 500L) val imageFilter = ThrottledLiveData(_imageFilter, 500L)
@ -113,22 +116,26 @@ class SlideshowViewModel
init { init {
addCloseable { addCloseable {
screensaverService.keepScreenOn(false) screensaverService.keepScreenOn(false)
if (this@SlideshowViewModel::player.isInitialized) {
player.removeListener(this@SlideshowViewModel) player.removeListener(this@SlideshowViewModel)
player.release() player.release()
} }
player.addListener(this@SlideshowViewModel) }
viewModelScope.launchIO { viewModelScope.launchIO {
val photoPrefs = userPreferencesService.getCurrent().appPreferences.photoPreferences try {
val appPreferences = userPreferencesService.getCurrent().appPreferences
val playerCreation =
playerFactory.createVideoPlayer(
backend = PlayerBackend.EXO_PLAYER,
appPreferences.playbackPreferences,
)
player = playerCreation.player
player.addListener(this@SlideshowViewModel)
val photoPrefs = appPreferences.photoPreferences
slideshowDelay = slideshowDelay =
photoPrefs.slideshowDuration.takeIf { it >= AppPreference.SlideshowDuration.min } photoPrefs.slideshowDuration.takeIf { it >= AppPreference.SlideshowDuration.min }
?: AppPreference.SlideshowDuration.defaultValue ?: AppPreference.SlideshowDuration.defaultValue
// val album =
// api.userLibraryApi
// .getItem(
// itemId = slideshowSettings.parentId,
// ).content
// .let { BaseItem(it, false) }
// this@SlideshowViewModel.album.setValueOnMain(album)
val includeItemTypes = val includeItemTypes =
if (photoPrefs.slideshowPlayVideos) { if (photoPrefs.slideshowPlayVideos) {
listOf(BaseItemKind.PHOTO, BaseItemKind.VIDEO) listOf(BaseItemKind.PHOTO, BaseItemKind.VIDEO)
@ -163,8 +170,13 @@ class SlideshowViewModel
ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope) ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
.init(slideshowSettings.index) .init(slideshowSettings.index)
this@SlideshowViewModel._pager.setValueOnMain(pager) this@SlideshowViewModel._pager.setValueOnMain(pager)
loading.update { LoadingState.Success }
updatePosition(slideshowSettings.index)?.join() updatePosition(slideshowSettings.index)?.join()
if (slideshowSettings.startSlideshow) onMain { startSlideshow() } if (slideshowSettings.startSlideshow) onMain { startSlideshow() }
} catch (ex: Exception) {
Timber.e(ex, "Error")
loading.update { LoadingState.Error(ex) }
}
} }
} }