mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-29 09:39:03 +03:00
Add Auto-play option (#600)
* Rewrite and clean up player controls and activity * rename crashlogs to aniyomi * Update PlayerActivity.kt * Add auto play option + clean up portrait layout * add "updateLayoutParams" import
This commit is contained in:
parent
5b40fa3d71
commit
4fee596b0a
8 changed files with 139 additions and 13 deletions
|
@ -13,6 +13,8 @@ object PreferenceKeys {
|
|||
|
||||
const val pipEpisodeToasts = "pref_pip_episode_toasts"
|
||||
|
||||
const val autoplayEnabled = "pref_auto_play_enabled"
|
||||
|
||||
const val mpvConf = "pref_mpv_conf"
|
||||
|
||||
const val defaultOrientationType = "pref_default_orientation_type_key"
|
||||
|
|
|
@ -121,6 +121,8 @@ class PreferencesHelper(val context: Context) {
|
|||
|
||||
fun pipEpisodeToasts() = prefs.getBoolean(Keys.pipEpisodeToasts, true)
|
||||
|
||||
fun autoplayEnabled() = flowPrefs.getBoolean(Keys.autoplayEnabled, false)
|
||||
|
||||
fun mpvConf() = prefs.getString(Keys.mpvConf, "")
|
||||
|
||||
fun defaultOrientationType() = prefs.getInt(Keys.defaultOrientationType, OrientationType.FREE.flagValue)
|
||||
|
|
|
@ -36,11 +36,13 @@ import android.view.animation.AnimationUtils
|
|||
import android.widget.LinearLayout
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.GestureDetectorCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
|
@ -291,7 +293,9 @@ class PlayerActivity :
|
|||
}
|
||||
|
||||
setVisibilities()
|
||||
|
||||
playerControls.showAndFadeControls()
|
||||
toggleAutoplay(preferences.autoplayEnabled().get())
|
||||
|
||||
setMpvConf()
|
||||
player.initialize(applicationContext.filesDir.path)
|
||||
|
@ -372,10 +376,44 @@ class PlayerActivity :
|
|||
if (width <= height) {
|
||||
width = height.also { height = width }
|
||||
}
|
||||
|
||||
playerControls.binding.titleMainTxt.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
rightToLeft = playerControls.binding.toggleAutoplay.id
|
||||
rightToRight = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
playerControls.binding.titleSecondaryTxt.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
rightToLeft = playerControls.binding.toggleAutoplay.id
|
||||
rightToRight = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
playerControls.binding.qualityBtn.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
topToTop = ConstraintLayout.LayoutParams.PARENT_ID
|
||||
topToBottom = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
playerControls.binding.toggleAutoplay.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
leftToLeft = ConstraintLayout.LayoutParams.UNSET
|
||||
leftToRight = playerControls.binding.titleMainTxt.id
|
||||
}
|
||||
} else {
|
||||
if (width >= height) {
|
||||
width = height.also { height = width }
|
||||
}
|
||||
|
||||
playerControls.binding.titleMainTxt.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
rightToLeft = ConstraintLayout.LayoutParams.UNSET
|
||||
rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
|
||||
}
|
||||
playerControls.binding.titleSecondaryTxt.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
rightToLeft = ConstraintLayout.LayoutParams.UNSET
|
||||
rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
|
||||
}
|
||||
playerControls.binding.qualityBtn.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
topToTop = ConstraintLayout.LayoutParams.UNSET
|
||||
topToBottom = playerControls.binding.backArrowBtn.id
|
||||
}
|
||||
playerControls.binding.toggleAutoplay.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID
|
||||
leftToRight = ConstraintLayout.LayoutParams.UNSET
|
||||
}
|
||||
}
|
||||
setupGestures()
|
||||
setViewMode()
|
||||
|
@ -424,7 +462,7 @@ class PlayerActivity :
|
|||
showLoadingIndicator(true)
|
||||
|
||||
val epTxt = switchMethod {
|
||||
if (wasPlayerPaused == false) {
|
||||
if (wasPlayerPaused == false || preferences.autoplayEnabled().get()) {
|
||||
player.paused = false
|
||||
}
|
||||
}
|
||||
|
@ -436,10 +474,37 @@ class PlayerActivity :
|
|||
}
|
||||
}
|
||||
|
||||
// Fade out Player information text
|
||||
private val playerInformationRunnable = Runnable {
|
||||
AnimationUtils.loadAnimation(this, R.anim.fade_out_medium).also { fadeAnimation ->
|
||||
playerControls.binding.playerInformation.startAnimation(fadeAnimation)
|
||||
playerControls.binding.playerInformation.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
internal fun toggleAutoplay(isAutoplay: Boolean) {
|
||||
playerControls.binding.toggleAutoplay.isChecked = isAutoplay
|
||||
playerControls.binding.toggleAutoplay.thumbDrawable = if (isAutoplay) {
|
||||
ContextCompat.getDrawable(playerControls.context, R.drawable.ic_play_circle_filled_24)
|
||||
} else ContextCompat.getDrawable(playerControls.context, R.drawable.ic_pause_circle_filled_24)
|
||||
|
||||
if (isAutoplay) {
|
||||
playerControls.binding.playerInformation.text = getString(R.string.enable_auto_play)
|
||||
} else {
|
||||
playerControls.binding.playerInformation.text = getString(R.string.disable_auto_play)
|
||||
}
|
||||
|
||||
if (!preferences.autoplayEnabled().get() == isAutoplay) {
|
||||
animationHandler.removeCallbacks(playerInformationRunnable)
|
||||
playerControls.binding.playerInformation.visibility = View.VISIBLE
|
||||
animationHandler.postDelayed(playerInformationRunnable, 1000L)
|
||||
}
|
||||
preferences.autoplayEnabled().set(isAutoplay)
|
||||
}
|
||||
|
||||
fun toggleControls() = playerControls.toggleControls()
|
||||
|
||||
private fun showLoadingIndicator(visible: Boolean) {
|
||||
if (binding.loadingIndicator.isVisible == visible) return
|
||||
playerControls.binding.playBtn.isVisible = !visible
|
||||
binding.loadingIndicator.isVisible = visible
|
||||
}
|
||||
|
@ -771,8 +836,8 @@ class PlayerActivity :
|
|||
// forces update of entire UI, used when resuming the activity
|
||||
val paused = player.paused ?: return
|
||||
updatePlaybackStatus(paused)
|
||||
player.timePos?.let { playerControls.updatePlaybackPos(it) }
|
||||
player.duration?.let { playerControls.updatePlaybackDuration(it) }
|
||||
player.timePos?.let { playerControls.updatePlaybackPos(it) }
|
||||
updatePlaylistButtons()
|
||||
updateEpisodeText()
|
||||
player.loadTracks()
|
||||
|
@ -1147,6 +1212,14 @@ class PlayerActivity :
|
|||
"pause" -> {
|
||||
if (!isFinishing) {
|
||||
setAudioFocus(value)
|
||||
|
||||
if (player.timePos != null && player.duration != null) {
|
||||
val isVideoEof = MPVLib.getPropertyBoolean("eof-reached") == true
|
||||
val isVideoCompleted = isVideoEof || (player.timePos!! >= player.duration!!)
|
||||
if (isVideoCompleted && preferences.autoplayEnabled().get()) {
|
||||
animationHandler.postDelayed({ switchEpisode(false) }, 1000L)
|
||||
}
|
||||
}
|
||||
updatePlaybackStatus(value)
|
||||
}
|
||||
}
|
||||
|
@ -1181,4 +1254,4 @@ private const val CONTROL_TYPE_PAUSE = 2
|
|||
private const val REQUEST_PREVIOUS = 3
|
||||
private const val REQUEST_NEXT = 4
|
||||
private const val CONTROL_TYPE_PREVIOUS = 3
|
||||
private const val CONTROL_TYPE_NEXT = 4
|
||||
private const val CONTROL_TYPE_NEXT = 4
|
|
@ -80,6 +80,10 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
|
|||
|
||||
binding.nextBtn.setOnClickListener { activity.switchEpisode(false) }
|
||||
binding.prevBtn.setOnClickListener { activity.switchEpisode(true) }
|
||||
|
||||
binding.toggleAutoplay.setOnCheckedChangeListener { _, isChecked ->
|
||||
activity.toggleAutoplay(isChecked)
|
||||
}
|
||||
}
|
||||
|
||||
private val animationHandler = Handler(Looper.getMainLooper())
|
||||
|
@ -290,4 +294,4 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr
|
|||
}
|
||||
picker.number = MPVLib.getPropertyDouble("speed")
|
||||
}
|
||||
}
|
||||
}
|
9
app/src/main/res/drawable/ic_pause_circle_filled_24.xml
Normal file
9
app/src/main/res/drawable/ic_pause_circle_filled_24.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:height="24dp"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnPrimarySurface"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM11,16L9,16L9,8h2v8zM15,16h-2L13,8h2v8z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_play_circle_filled_24.xml
Normal file
9
app/src/main/res/drawable/ic_play_circle_filled_24.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:height="24dp"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="?attr/colorControlActivated"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-9l6,4.5 -6,4.5z"/>
|
||||
</vector>
|
|
@ -62,7 +62,7 @@
|
|||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintLeft_toRightOf="@id/backArrowBtn"
|
||||
app:layout_constraintRight_toLeftOf="@id/cycleDecoderBtn"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
|
@ -75,7 +75,7 @@
|
|||
android:textColor="?attr/colorOnPrimarySurface"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintLeft_toRightOf="@id/backArrowBtn"
|
||||
app:layout_constraintRight_toLeftOf="@id/cycleDecoderBtn"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleMainTxt" />
|
||||
|
||||
<!-- Top Controls (Left)-->
|
||||
|
@ -90,11 +90,11 @@
|
|||
android:contentDescription="Settings"
|
||||
android:onClick="openQuality"
|
||||
android:src="@drawable/ic_video_quality_24dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/cycleSubsBtn"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/backArrowBtn"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/cycleSubsBtn"
|
||||
android:layout_width="48dp"
|
||||
|
@ -103,6 +103,7 @@
|
|||
android:contentDescription="Subtitles"
|
||||
android:onClick="cycleSub"
|
||||
android:src="@drawable/ic_subtitles_black_24dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/cycleAudioBtn"
|
||||
app:layout_constraintRight_toLeftOf="@id/qualityBtn"
|
||||
app:layout_constraintTop_toTopOf="@id/qualityBtn"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
|
@ -115,6 +116,7 @@
|
|||
android:contentDescription="Audio"
|
||||
android:onClick="cycleAudio"
|
||||
android:src="@drawable/ic_audiotrack_black_24dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/cycleDecoderBtn"
|
||||
app:layout_constraintRight_toLeftOf="@id/cycleSubsBtn"
|
||||
app:layout_constraintTop_toTopOf="@id/cycleSubsBtn"
|
||||
app:tint="?attr/colorOnPrimarySurface" />
|
||||
|
@ -127,9 +129,18 @@
|
|||
android:onClick="switchDecoder"
|
||||
android:text=".."
|
||||
android:textColor="?attr/colorOnPrimarySurface"
|
||||
app:layout_constraintLeft_toRightOf="@id/toggleAutoplay"
|
||||
app:layout_constraintRight_toLeftOf="@id/cycleAudioBtn"
|
||||
app:layout_constraintTop_toTopOf="@id/cycleAudioBtn" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/toggleAutoplay"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/cycleDecoderBtn"
|
||||
app:layout_constraintTop_toTopOf="@id/cycleDecoderBtn" />
|
||||
|
||||
<!-- Audio -->
|
||||
|
||||
<TextView
|
||||
|
@ -240,7 +251,7 @@
|
|||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:gravity="center"
|
||||
android:text="0:00:00"
|
||||
android:text="0:00"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
|
@ -264,7 +275,7 @@
|
|||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:gravity="center"
|
||||
android:text="0:00:00"
|
||||
android:text="0:00"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
@ -290,7 +301,6 @@
|
|||
android:id="@+id/play_btn"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="Play/Pause"
|
||||
android:onClick="playPause"
|
||||
|
@ -304,6 +314,21 @@
|
|||
tools:src="@drawable/ic_play_arrow_80dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/playerInformation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="left"
|
||||
android:text="Information"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/play_btn"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/nextBtn"
|
||||
android:layout_width="72dp"
|
||||
|
@ -406,4 +431,4 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
|
@ -995,6 +995,8 @@
|
|||
<string name="label_updates">Manga</string>
|
||||
<string name="label_animeupdates">Anime</string>
|
||||
<string name="player_overlay_back">Back</string>
|
||||
<string name="enable_auto_play">"Auto-play is on"</string>
|
||||
<string name="disable_auto_play">"Auto-play is off"</string>
|
||||
|
||||
<!-- Aniyomi stuff -->
|
||||
<string name="playback_speed_dialog_title">Change playback speed:</string>
|
||||
|
|
Loading…
Reference in a new issue