diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsPlayerScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsPlayerScreen.kt index a0d397b60c..f91001cd4c 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsPlayerScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsPlayerScreen.kt @@ -313,6 +313,7 @@ object SettingsPlayerScreen : SearchableSettings { val enablePip = playerPreferences.enablePip() val pipEpisodeToasts = playerPreferences.pipEpisodeToasts() val pipOnExit = playerPreferences.pipOnExit() + val pipReplaceWithPrevious = playerPreferences.pipReplaceWithPrevious() val isPipEnabled by enablePip.collectAsState() @@ -333,6 +334,11 @@ object SettingsPlayerScreen : SearchableSettings { title = stringResource(MR.strings.pref_pip_on_exit), enabled = isPipEnabled, ), + Preference.PreferenceItem.SwitchPreference( + pref = pipReplaceWithPrevious, + title = stringResource(MR.strings.pref_pip_replace_with_previous), + enabled = isPipEnabled, + ), ), ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt index 06d761e00b..4777afe20a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt @@ -1,6 +1,7 @@ package eu.kanade.tachiyomi import android.content.Context +import android.os.Build import androidx.core.content.edit import androidx.preference.PreferenceManager import eu.kanade.domain.base.BasePreferences @@ -16,6 +17,7 @@ import eu.kanade.tachiyomi.data.track.TrackerManager import eu.kanade.tachiyomi.network.NetworkPreferences import eu.kanade.tachiyomi.network.PREF_DOH_CLOUDFLARE import eu.kanade.tachiyomi.ui.player.settings.PlayerPreferences +import eu.kanade.tachiyomi.ui.player.viewer.HwDecState import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences import eu.kanade.tachiyomi.util.system.DeviceUtil @@ -566,6 +568,10 @@ object Migrations { filterPredicate = { it.key in prefsToReplace }, newKey = { Preference.appStateKey(it) }, ) + + if (Build.MODEL == "Subsystem for Android(TM)") { + playerPreferences.hwDec().set(HwDecState.SW.mpvValue) + } } return true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt index 6d9b370524..6070241d2a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt @@ -65,12 +65,13 @@ import eu.kanade.tachiyomi.ui.player.settings.sheets.subtitle.SubtitleSettingsSh import eu.kanade.tachiyomi.ui.player.settings.sheets.subtitle.toHexString import eu.kanade.tachiyomi.ui.player.viewer.ACTION_MEDIA_CONTROL import eu.kanade.tachiyomi.ui.player.viewer.AspectState -import eu.kanade.tachiyomi.ui.player.viewer.CONTROL_TYPE_NEXT -import eu.kanade.tachiyomi.ui.player.viewer.CONTROL_TYPE_PAUSE -import eu.kanade.tachiyomi.ui.player.viewer.CONTROL_TYPE_PLAY -import eu.kanade.tachiyomi.ui.player.viewer.CONTROL_TYPE_PREVIOUS import eu.kanade.tachiyomi.ui.player.viewer.EXTRA_CONTROL_TYPE import eu.kanade.tachiyomi.ui.player.viewer.GestureHandler +import eu.kanade.tachiyomi.ui.player.viewer.PIP_NEXT +import eu.kanade.tachiyomi.ui.player.viewer.PIP_PAUSE +import eu.kanade.tachiyomi.ui.player.viewer.PIP_PLAY +import eu.kanade.tachiyomi.ui.player.viewer.PIP_PREVIOUS +import eu.kanade.tachiyomi.ui.player.viewer.PIP_SKIP import eu.kanade.tachiyomi.ui.player.viewer.PictureInPictureHandler import eu.kanade.tachiyomi.ui.player.viewer.PipState import eu.kanade.tachiyomi.ui.player.viewer.SeekState @@ -86,6 +87,8 @@ import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.view.setComposeContent import `is`.xyz.mpv.MPVLib import `is`.xyz.mpv.Utils +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update @@ -397,7 +400,10 @@ class PlayerActivity : BaseActivity() { when (state.sheet) { is PlayerViewModel.Sheet.ScreenshotOptions -> { ScreenshotOptionsSheet( - screenModel = PlayerSettingsScreenModel(viewModel.playerPreferences), + screenModel = PlayerSettingsScreenModel( + preferences = viewModel.playerPreferences, + hasSubTracks = streams.subtitle.tracks.size > 1, + ), cachePath = cacheDir.path, onSetAsCover = viewModel::setAsCover, onShare = { viewModel.shareImage(it, player.timePos) }, @@ -511,8 +517,8 @@ class PlayerActivity : BaseActivity() { is PlayerViewModel.Sheet.SubtitleSettings -> { SubtitleSettingsSheet( screenModel = PlayerSettingsScreenModel( - viewModel.playerPreferences, - streams.subtitle.tracks.size > 1, + preferences = viewModel.playerPreferences, + hasSubTracks = streams.subtitle.tracks.size > 1, ), onDismissRequest = pauseForDialogSheet(fadeControls = true), ) @@ -621,19 +627,7 @@ class PlayerActivity : BaseActivity() { MPVLib.setPropertyDouble("sub-delay", subtitlesDelay().get() / 1000.0) } - // TODO: I think this is a bad hack. - // We need to find a way to let MPV access our fonts directory. - val storageManager: StorageManager = Injekt.get() - storageManager.getFontsDirectory()?.listFiles()?.forEach { font -> - val outFile = UniFile.fromFile(applicationContext.filesDir)?.createFile(font.name) - outFile?.let { - font.openInputStream().copyTo(it.openOutputStream()) - } - } - MPVLib.setPropertyString( - "sub-fonts-dir", - applicationContext.filesDir.path, - ) + copyFontsDirectory() if (playerPreferences.subtitleFont().get().trim() != "") { MPVLib.setPropertyString("sub-font", playerPreferences.subtitleFont().get()) @@ -653,6 +647,25 @@ class PlayerActivity : BaseActivity() { } } + private fun copyFontsDirectory() { + // TODO: I think this is a bad hack. + // We need to find a way to let MPV directly access our fonts directory. + CoroutineScope(Dispatchers.IO).launchIO { + val storageManager: StorageManager = Injekt.get() + storageManager.getFontsDirectory()?.listFiles()?.forEach { font -> + val outFile = UniFile.fromFile(applicationContext.filesDir)?.createFile(font.name) + outFile?.let { + font.openInputStream().copyTo(it.openOutputStream()) + } + } + MPVLib.setPropertyString( + "sub-fonts-dir", + applicationContext.filesDir.path, + ) + logcat { "FINISHED FONTS" } + } + } + private fun setupPlayerBrightness() { val useDeviceBrightness = playerPreferences.playerBrightnessValue().get() == -1.0F || @@ -834,11 +847,7 @@ class PlayerActivity : BaseActivity() { super.onResume() refreshUi() if (pip.supportedAndEnabled && PipState.mode == PipState.ON) { - player.paused?.let { - pip.update( - !it, - ) - } + player.paused?.let { pip.update(!it) } } } @@ -980,12 +989,8 @@ class PlayerActivity : BaseActivity() { val gestures = GestureHandler(this, deviceWidth.toFloat(), deviceHeight.toFloat()) val mDetector = GestureDetectorCompat(this, gestures) player.setOnTouchListener { v, event -> - try { // TODO: https://issuetracker.google.com/issues/238920463 is fixed in API 34, but for now this will do - gestures.onTouch(v, event) - mDetector.onTouchEvent(event) - } catch (_: NullPointerException) { - false - } + gestures.onTouch(v, event) + mDetector.onTouchEvent(event) } } @@ -1447,18 +1452,21 @@ class PlayerActivity : BaseActivity() { return } when (intent.getIntExtra(EXTRA_CONTROL_TYPE, 0)) { - CONTROL_TYPE_PLAY -> { + PIP_PLAY -> { player.paused = false } - CONTROL_TYPE_PAUSE -> { + PIP_PAUSE -> { player.paused = true } - CONTROL_TYPE_PREVIOUS -> { + PIP_PREVIOUS -> { changeEpisode(viewModel.getAdjacentEpisodeId(previous = true)) } - CONTROL_TYPE_NEXT -> { + PIP_NEXT -> { changeEpisode(viewModel.getAdjacentEpisodeId(previous = false)) } + PIP_SKIP -> { + doubleTapSeek(time = 10) + } } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt index b9d5934b5e..47c309197f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerViewModel.kt @@ -305,7 +305,7 @@ class PlayerViewModel @JvmOverloads constructor( fun isEpisodeOnline(): Boolean? { val anime = currentAnime ?: return null val episode = currentEpisode ?: return null - return currentSource is AnimeHttpSource && !EpisodeLoader.isDownloaded( + return currentSource is AnimeHttpSource && !EpisodeLoader.isDownload( episode.toDomainEpisode()!!, anime, ) @@ -379,8 +379,8 @@ class PlayerViewModel @JvmOverloads constructor( val nextEpisode = this.currentPlaylist[getCurrentEpisodeIndex() + 1] val episodesAreDownloaded = - EpisodeLoader.isDownloaded(currentEpisode.toDomainEpisode()!!, anime) && - EpisodeLoader.isDownloaded(nextEpisode.toDomainEpisode()!!, anime) + EpisodeLoader.isDownload(currentEpisode.toDomainEpisode()!!, anime) && + EpisodeLoader.isDownload(nextEpisode.toDomainEpisode()!!, anime) viewModelScope.launchIO { if (!episodesAreDownloaded) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/loader/EpisodeLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/loader/EpisodeLoader.kt index 269de89954..49e6186419 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/loader/EpisodeLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/loader/EpisodeLoader.kt @@ -29,16 +29,9 @@ class EpisodeLoader { * @param source the source of the anime. */ suspend fun getLinks(episode: Episode, anime: Anime, source: AnimeSource): List