mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 14:20:30 +05:30
Merge pull request #3037 from Isira-Seneviratne/Player_view_binding
Use view binding extensions in PlayerFragment.
This commit is contained in:
commit
16334d3bbe
@ -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() {
|
||||||
|
@ -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)
|
||||||
|
@ -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" }
|
Loading…
Reference in New Issue
Block a user