mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Add in-app & Android TV screensaver (#946)
## Description Adds both an optional in-app and Android TV OS (DreamService) screensaver Has settings for: - Starting delay, options from 30s to 1 hour - Duration to show each image, 30s to 2 minutes - Show clock (separate from app-wide clock) - Toggle animated zooming - Set a max age rating to limit what content is shown - Included media types: movies, tv shows, and/or photos By default only Movies & TV Shows are included. But if you have like family albums on your server, you could enable Photos too. There's also an button to start the screensaver so you can see what it looks like. ### Related issues Closes #230 ### Testing Emulator, Onn 4k pro, nvidia shield using both in-app and OS screensavers ## Screenshots  ## AI or LLM usage None ## Acknowledgements Some of the skeleton code for setting up the `DreamService` with the right lifecycle was copied and modified from the [official app's implementation](https://github.com/jellyfin/jellyfin-androidtv/blob/master/app/src/main/java/org/jellyfin/androidtv/integration/dream/DreamServiceCompat.kt).
This commit is contained in:
parent
536e8d366c
commit
a7e86fbc15
25 changed files with 954 additions and 78 deletions
|
|
@ -3,10 +3,12 @@ package com.github.damontecres.wholphin
|
|||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
|
@ -49,6 +51,7 @@ import com.github.damontecres.wholphin.services.ImageUrlService
|
|||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.services.PlaybackLifecycleObserver
|
||||
import com.github.damontecres.wholphin.services.RefreshRateService
|
||||
import com.github.damontecres.wholphin.services.ScreensaverService
|
||||
import com.github.damontecres.wholphin.services.ServerEventListener
|
||||
import com.github.damontecres.wholphin.services.SetupDestination
|
||||
import com.github.damontecres.wholphin.services.SetupNavigationManager
|
||||
|
|
@ -59,8 +62,10 @@ import com.github.damontecres.wholphin.services.hilt.AuthOkHttpClient
|
|||
import com.github.damontecres.wholphin.services.tvprovider.TvProviderSchedulerService
|
||||
import com.github.damontecres.wholphin.ui.CoilConfig
|
||||
import com.github.damontecres.wholphin.ui.LocalImageUrlService
|
||||
import com.github.damontecres.wholphin.ui.components.AppScreensaver
|
||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||
import com.github.damontecres.wholphin.ui.detail.series.SeasonEpisodeIds
|
||||
import com.github.damontecres.wholphin.ui.launchDefault
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.nav.ApplicationContent
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
|
|
@ -134,6 +139,9 @@ class MainActivity : AppCompatActivity() {
|
|||
@Inject
|
||||
lateinit var datePlayedInvalidationService: DatePlayedInvalidationService
|
||||
|
||||
@Inject
|
||||
lateinit var screensaverService: ScreensaverService
|
||||
|
||||
private var signInAuto = true
|
||||
|
||||
@OptIn(ExperimentalTvMaterial3Api::class)
|
||||
|
|
@ -317,6 +325,15 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
},
|
||||
)
|
||||
val screenSaverState by screensaverService.state.collectAsState()
|
||||
if (screenSaverState.enabled || screenSaverState.enabledTemp) {
|
||||
AnimatedVisibility(
|
||||
screenSaverState.show,
|
||||
Modifier.fillMaxSize(),
|
||||
) {
|
||||
AppScreensaver(appPreferences, Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,10 +341,22 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||
if (screensaverService.state.value.show) {
|
||||
screensaverService.stop(false)
|
||||
screensaverService.pulse()
|
||||
return true
|
||||
} else {
|
||||
screensaverService.pulse()
|
||||
return super.dispatchKeyEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
Timber.d("onResume")
|
||||
lifecycleScope.launchIO {
|
||||
lifecycleScope.launchDefault {
|
||||
screensaverService.pulse()
|
||||
appUpgradeHandler.run()
|
||||
}
|
||||
}
|
||||
|
|
@ -341,6 +370,7 @@ class MainActivity : AppCompatActivity() {
|
|||
override fun onStop() {
|
||||
super.onStop()
|
||||
Timber.d("onStop")
|
||||
screensaverService.stop(true)
|
||||
tvProviderSchedulerService.launchOneTimeRefresh()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue