Merge pull request #3037 from Isira-Seneviratne/Player_view_binding

Use view binding extensions in PlayerFragment.
This commit is contained in:
Bnyro 2023-02-13 15:43:41 +01:00 committed by GitHub
commit 16334d3bbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 45 deletions

View File

@ -122,6 +122,9 @@ dependencies {
/* Room */ /* Room */
kapt libs.room.compiler kapt libs.room.compiler
implementation libs.room implementation libs.room
/* View binding */
implementation libs.viewBindingPropertyDelegate
} }
static def getUnixTime() { static def getUnixTime() {

View File

@ -21,9 +21,7 @@ import android.text.method.LinkMovementMethod
import android.text.util.Linkify import android.text.util.Linkify
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
@ -34,11 +32,13 @@ import androidx.core.os.bundleOf
import androidx.core.os.postDelayed import androidx.core.os.postDelayed
import androidx.core.text.parseAsHtml import androidx.core.text.parseAsHtml
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.commit import androidx.fragment.app.commit
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import by.kirich1409.viewbindingdelegate.viewBinding
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.CronetHelper import com.github.libretube.api.CronetHelper
import com.github.libretube.api.JsonHelper import com.github.libretube.api.JsonHelper
@ -50,10 +50,7 @@ import com.github.libretube.api.obj.StreamItem
import com.github.libretube.api.obj.Streams import com.github.libretube.api.obj.Streams
import com.github.libretube.constants.IntentData import com.github.libretube.constants.IntentData
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.databinding.DoubleTapOverlayBinding
import com.github.libretube.databinding.ExoStyledPlayerControlViewBinding
import com.github.libretube.databinding.FragmentPlayerBinding import com.github.libretube.databinding.FragmentPlayerBinding
import com.github.libretube.databinding.PlayerGestureControlsViewBinding
import com.github.libretube.db.DatabaseHelper import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.DatabaseHolder.Database import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.db.obj.WatchPosition import com.github.libretube.db.obj.WatchPosition
@ -82,7 +79,6 @@ import com.github.libretube.services.DownloadService
import com.github.libretube.ui.activities.MainActivity import com.github.libretube.ui.activities.MainActivity
import com.github.libretube.ui.adapters.ChaptersAdapter import com.github.libretube.ui.adapters.ChaptersAdapter
import com.github.libretube.ui.adapters.VideosAdapter import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.base.BaseFragment
import com.github.libretube.ui.dialogs.AddToPlaylistDialog import com.github.libretube.ui.dialogs.AddToPlaylistDialog
import com.github.libretube.ui.dialogs.DownloadDialog import com.github.libretube.ui.dialogs.DownloadDialog
import com.github.libretube.ui.dialogs.ShareDialog import com.github.libretube.ui.dialogs.ShareDialog
@ -110,7 +106,6 @@ import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ext.cronet.CronetDataSource import com.google.android.exoplayer2.ext.cronet.CronetDataSource
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.ui.StyledPlayerView
import com.google.android.exoplayer2.upstream.DefaultDataSource import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.util.MimeTypes import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -126,12 +121,16 @@ import kotlinx.datetime.LocalDate
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import retrofit2.HttpException import retrofit2.HttpException
class PlayerFragment : BaseFragment(), OnlinePlayerOptions { class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
val binding by viewBinding(FragmentPlayerBinding::bind)
private val playerBinding by viewBinding { it.binding.player.binding }
private val doubleTapOverlayBinding by viewBinding {
it.binding.doubleTapOverlay.binding
}
private val playerGestureControlsViewBinding by viewBinding {
it.binding.playerGestureControlsView.binding
}
lateinit var binding: FragmentPlayerBinding
private lateinit var playerBinding: ExoStyledPlayerControlViewBinding
private lateinit var doubleTapOverlayBinding: DoubleTapOverlayBinding
private lateinit var playerGestureControlsViewBinding: PlayerGestureControlsViewBinding
private val viewModel: PlayerViewModel by activityViewModels() private val viewModel: PlayerViewModel by activityViewModels()
private val commentsViewModel: CommentsViewModel by activityViewModels() private val commentsViewModel: CommentsViewModel by activityViewModels()
@ -171,7 +170,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
/** /**
* for the player view * for the player view
*/ */
private lateinit var exoPlayerView: StyledPlayerView
private var subtitles = mutableListOf<SubtitleConfiguration>() private var subtitles = mutableListOf<SubtitleConfiguration>()
/** /**
@ -185,7 +183,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
private var segments = listOf<Segment>() private var segments = listOf<Segment>()
private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled private var sponsorBlockEnabled = PlayerHelper.sponsorBlockEnabled
val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
private val mainActivity get() = activity as MainActivity private val mainActivity get() = activity as MainActivity
/** /**
@ -240,21 +238,6 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
) )
} }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentPlayerBinding.inflate(layoutInflater, container, false)
exoPlayerView = binding.player
playerBinding = binding.player.binding
doubleTapOverlayBinding = binding.doubleTapOverlay.binding
playerGestureControlsViewBinding = binding.playerGestureControlsView.binding
// Inflate the layout for this fragment
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
context?.hideKeyboard(view) context?.hideKeyboard(view)
@ -279,8 +262,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
* somehow the bottom bar is invisible on low screen resolutions, this fixes it * somehow the bottom bar is invisible on low screen resolutions, this fixes it
*/ */
private fun showBottomBar() { private fun showBottomBar() {
if (this::playerBinding.isInitialized && !binding.player.isPlayerLocked) { if (isAdded && binding.player.isPlayerLocked) {
playerBinding.bottomBar.visibility = View.VISIBLE binding.player.binding.bottomBar.isVisible = true
} }
handler.postDelayed(this::showBottomBar, 100) handler.postDelayed(this::showBottomBar, 100)
} }
@ -305,8 +288,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
progress: Float progress: Float
) { ) {
mainMotionLayout.progress = abs(progress) mainMotionLayout.progress = abs(progress)
exoPlayerView.hideController() binding.player.hideController()
exoPlayerView.useController = false binding.player.useController = false
eId = endId eId = endId
sId = startId sId = startId
} }
@ -316,14 +299,14 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
viewModel.isMiniPlayerVisible.value = true viewModel.isMiniPlayerVisible.value = true
// disable captions // disable captions
updateCaptionsLanguage(null) updateCaptionsLanguage(null)
exoPlayerView.useController = false binding.player.useController = false
mainMotionLayout.progress = 1F mainMotionLayout.progress = 1F
(activity as MainActivity).requestOrientationChange() (activity as MainActivity).requestOrientationChange()
} else if (currentId == sId) { } else if (currentId == sId) {
viewModel.isMiniPlayerVisible.value = false viewModel.isMiniPlayerVisible.value = false
// re-enable captions // re-enable captions
updateCaptionsLanguage(captionLanguage) updateCaptionsLanguage(captionLanguage)
exoPlayerView.useController = true binding.player.useController = true
mainMotionLayout.progress = 0F mainMotionLayout.progress = 0F
changeOrientationMode() changeOrientationMode()
} }
@ -340,7 +323,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
if (PlayerHelper.swipeGestureEnabled) { if (PlayerHelper.swipeGestureEnabled) {
binding.playerMotionLayout.addSwipeUpListener { binding.playerMotionLayout.addSwipeUpListener {
exoPlayerView.hideController() binding.player.hideController()
setFullscreen() setFullscreen()
} }
} }
@ -403,7 +386,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
if (PlayerHelper.autoRotationEnabled) View.INVISIBLE else View.VISIBLE if (PlayerHelper.autoRotationEnabled) View.INVISIBLE else View.VISIBLE
playerBinding.fullscreen.setOnClickListener { playerBinding.fullscreen.setOnClickListener {
// hide player controller // hide player controller
exoPlayerView.hideController() binding.player.hideController()
if (viewModel.isFullscreen.value == false) { if (viewModel.isFullscreen.value == false) {
// go to fullscreen mode // go to fullscreen mode
setFullscreen() setFullscreen()
@ -717,7 +700,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
if (binding.playerMotionLayout.progress != 1.0f) { if (binding.playerMotionLayout.progress != 1.0f) {
// show controllers when not in picture in picture mode // show controllers when not in picture in picture mode
if (!(usePiP() && activity?.isInPictureInPictureMode!!)) { if (!(usePiP() && activity?.isInPictureInPictureMode!!)) {
exoPlayerView.useController = true binding.player.useController = true
} }
} }
// show the player notification // show the player notification
@ -754,7 +737,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
).segments ).segments
if (segments.isEmpty()) return@runCatching if (segments.isEmpty()) return@runCatching
playerBinding.exoProgress.setSegments(segments) playerBinding.exoProgress.setSegments(segments)
runOnUiThread { withContext(Dispatchers.Main) {
playerBinding.sbToggle.visibility = View.VISIBLE playerBinding.sbToggle.visibility = View.VISIBLE
updateDisplayedDuration() updateDisplayedDuration()
} }
@ -829,7 +812,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
} }
private fun prepareExoPlayerView() { private fun prepareExoPlayerView() {
exoPlayerView.apply { binding.player.apply {
useController = false useController = false
player = exoPlayer player = exoPlayer
} }
@ -1184,7 +1167,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
if (chapters.isEmpty()) return if (chapters.isEmpty()) return
// call the function again in 100ms // call the function again in 100ms
exoPlayerView.postDelayed(this::setCurrentChapterName, 100) binding.player.postDelayed(this::setCurrentChapterName, 100)
val chapterIndex = getCurrentChapterIndex() ?: return val chapterIndex = getCurrentChapterIndex() ?: return
val chapterName = chapters[chapterIndex].title?.trim() val chapterName = chapters[chapterIndex].title?.trim()
@ -1414,8 +1397,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
super.onPictureInPictureModeChanged(isInPictureInPictureMode) super.onPictureInPictureModeChanged(isInPictureInPictureMode)
if (isInPictureInPictureMode) { if (isInPictureInPictureMode) {
// hide and disable exoPlayer controls // hide and disable exoPlayer controls
exoPlayerView.hideController() binding.player.hideController()
exoPlayerView.useController = false binding.player.useController = false
// set portrait mode // set portrait mode
unsetFullscreen() unsetFullscreen()
@ -1440,7 +1423,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
if (lifecycle.currentState == Lifecycle.State.CREATED) exoPlayer.pause() if (lifecycle.currentState == Lifecycle.State.CREATED) exoPlayer.pause()
// enable exoPlayer controls again // enable exoPlayer controls again
exoPlayerView.useController = true binding.player.useController = true
with(binding.playerMotionLayout) { with(binding.playerMotionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0) getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)

View File

@ -20,6 +20,7 @@ room = "2.5.0"
kotlinxSerialization = "1.4.1" kotlinxSerialization = "1.4.1"
kotlinxDatetime = "0.4.0" kotlinxDatetime = "0.4.0"
kotlinxRetrofit = "0.8.0" kotlinxRetrofit = "0.8.0"
viewBindingDelegate = "1.5.8"
[libraries] [libraries]
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
@ -50,4 +51,5 @@ room = { group = "androidx.room", name="room-ktx", version.ref = "room" }
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" } kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" }
kotlinx-serialization-retrofit = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "kotlinxRetrofit" } kotlinx-serialization-retrofit = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "kotlinxRetrofit" }
viewBindingPropertyDelegate = { group = "com.github.kirich1409", name = "viewbindingpropertydelegate-noreflection", version.ref = "viewBindingDelegate" }