mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-15 06:40:30 +05:30
Layout and skip+prev functionality
This commit is contained in:
parent
c3645cb4d2
commit
59697caebf
@ -8,7 +8,7 @@ object IntentData {
|
|||||||
const val timeStamp = "timeStamp"
|
const val timeStamp = "timeStamp"
|
||||||
const val position = "position"
|
const val position = "position"
|
||||||
const val fileName = "fileName"
|
const val fileName = "fileName"
|
||||||
const val openQueueOnce = "openQueue"
|
|
||||||
const val keepQueue = "keepQueue"
|
const val keepQueue = "keepQueue"
|
||||||
const val playlistType = "playlistType"
|
const val playlistType = "playlistType"
|
||||||
|
const val openAudioPlayer = "openAudioPlayer"
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,6 @@ object PreferenceKeys {
|
|||||||
* Background mode
|
* Background mode
|
||||||
*/
|
*/
|
||||||
const val BACKGROUND_PLAYBACK_SPEED = "background_playback_speed"
|
const val BACKGROUND_PLAYBACK_SPEED = "background_playback_speed"
|
||||||
const val NOTIFICATION_OPEN_QUEUE = "notification_open_queue"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifications
|
* Notifications
|
||||||
|
@ -391,6 +391,11 @@ class MainActivity : BaseActivity() {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (intent?.getBooleanExtra(IntentData.openAudioPlayer, false) == true) {
|
||||||
|
navController.navigate(R.id.audioPlayerFragment)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
intent?.getStringExtra(IntentData.channelId)?.let {
|
intent?.getStringExtra(IntentData.channelId)?.let {
|
||||||
navController.navigate(
|
navController.navigate(
|
||||||
R.id.channelFragment,
|
R.id.channelFragment,
|
||||||
@ -412,6 +417,7 @@ class MainActivity : BaseActivity() {
|
|||||||
intent?.getStringExtra(IntentData.videoId)?.let {
|
intent?.getStringExtra(IntentData.videoId)?.let {
|
||||||
loadVideo(it, intent?.getLongExtra(IntentData.timeStamp, 0L))
|
loadVideo(it, intent?.getLongExtra(IntentData.timeStamp, 0L))
|
||||||
}
|
}
|
||||||
|
|
||||||
when (intent?.getStringExtra("fragmentToOpen")) {
|
when (intent?.getStringExtra("fragmentToOpen")) {
|
||||||
"home" ->
|
"home" ->
|
||||||
navController.navigate(R.id.homeFragment)
|
navController.navigate(R.id.homeFragment)
|
||||||
@ -422,10 +428,6 @@ class MainActivity : BaseActivity() {
|
|||||||
"library" ->
|
"library" ->
|
||||||
navController.navigate(R.id.libraryFragment)
|
navController.navigate(R.id.libraryFragment)
|
||||||
}
|
}
|
||||||
if (intent?.getBooleanExtra(IntentData.openQueueOnce, false) == true) {
|
|
||||||
PlayingQueueSheet()
|
|
||||||
.show(supportFragmentManager)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadVideo(videoId: String, timeStamp: Long?) {
|
private fun loadVideo(videoId: String, timeStamp: Long?) {
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.github.libretube.ui.fragments
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.github.libretube.api.obj.StreamItem
|
||||||
|
import com.github.libretube.databinding.FragmentAudioPlayerBinding
|
||||||
|
import com.github.libretube.extensions.toID
|
||||||
|
import com.github.libretube.ui.base.BaseFragment
|
||||||
|
import com.github.libretube.util.ImageHelper
|
||||||
|
import com.github.libretube.util.NavigationHelper
|
||||||
|
import com.github.libretube.util.PlayingQueue
|
||||||
|
|
||||||
|
class AudioPlayerFragment : BaseFragment() {
|
||||||
|
private lateinit var binding: FragmentAudioPlayerBinding
|
||||||
|
private val onTrackChangeListener: (StreamItem) -> Unit = {
|
||||||
|
updateStreamInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
binding = FragmentAudioPlayerBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
binding.prev.setOnClickListener {
|
||||||
|
val currentIndex = PlayingQueue.currentIndex()
|
||||||
|
PlayingQueue.onQueueItemSelected(currentIndex - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.next.setOnClickListener {
|
||||||
|
val currentIndex = PlayingQueue.currentIndex()
|
||||||
|
PlayingQueue.onQueueItemSelected(currentIndex + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayingQueue.addOnTrackChangedListener(onTrackChangeListener)
|
||||||
|
|
||||||
|
updateStreamInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateStreamInfo() {
|
||||||
|
val current = PlayingQueue.getCurrent()
|
||||||
|
current ?: return
|
||||||
|
|
||||||
|
binding.title.text = current.title
|
||||||
|
binding.uploader.text = current.uploaderName
|
||||||
|
binding.uploader.setOnClickListener {
|
||||||
|
NavigationHelper.navigateChannel(requireContext(), current.uploaderUrl?.toID())
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageHelper.loadImage(current.thumbnail, binding.thumbnail)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
|
||||||
|
// unregister the listener
|
||||||
|
PlayingQueue.removeOnTrackChangedListener(onTrackChangeListener)
|
||||||
|
}
|
||||||
|
}
|
@ -75,11 +75,7 @@ class NowPlayingNotification(
|
|||||||
// that's the only way to launch back into the previous activity (e.g. the player view
|
// that's the only way to launch back into the previous activity (e.g. the player view
|
||||||
val intent = Intent(context, MainActivity::class.java).apply {
|
val intent = Intent(context, MainActivity::class.java).apply {
|
||||||
if (isBackgroundPlayerNotification) {
|
if (isBackgroundPlayerNotification) {
|
||||||
if (PreferenceHelper.getBoolean(PreferenceKeys.NOTIFICATION_OPEN_QUEUE, true)) {
|
putExtra(IntentData.openAudioPlayer, true)
|
||||||
putExtra(IntentData.openQueueOnce, true)
|
|
||||||
} else {
|
|
||||||
putExtra(IntentData.videoId, videoId)
|
|
||||||
}
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,16 @@ import kotlinx.coroutines.launch
|
|||||||
object PlayingQueue {
|
object PlayingQueue {
|
||||||
private val queue = mutableListOf<StreamItem>()
|
private val queue = mutableListOf<StreamItem>()
|
||||||
private var currentStream: StreamItem? = null
|
private var currentStream: StreamItem? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that gets called when the user selects an item from the queue
|
||||||
|
*/
|
||||||
private var onQueueTapListener: (StreamItem) -> Unit = {}
|
private var onQueueTapListener: (StreamItem) -> Unit = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that gets called when the current playing video changes
|
||||||
|
*/
|
||||||
|
private val onTrackChangedListeners: MutableList<(StreamItem) -> Unit> = mutableListOf()
|
||||||
var repeatQueue: Boolean = false
|
var repeatQueue: Boolean = false
|
||||||
|
|
||||||
fun add(vararg streamItem: StreamItem) {
|
fun add(vararg streamItem: StreamItem) {
|
||||||
@ -58,6 +67,9 @@ object PlayingQueue {
|
|||||||
|
|
||||||
fun updateCurrent(streamItem: StreamItem) {
|
fun updateCurrent(streamItem: StreamItem) {
|
||||||
currentStream = streamItem
|
currentStream = streamItem
|
||||||
|
onTrackChangedListeners.forEach {
|
||||||
|
it.invoke(streamItem)
|
||||||
|
}
|
||||||
if (!contains(streamItem)) queue.add(streamItem)
|
if (!contains(streamItem)) queue.add(streamItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +89,8 @@ object PlayingQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCurrent(): StreamItem? = currentStream
|
||||||
|
|
||||||
fun contains(streamItem: StreamItem) = queue.any { it.url?.toID() == streamItem.url?.toID() }
|
fun contains(streamItem: StreamItem) = queue.any { it.url?.toID() == streamItem.url?.toID() }
|
||||||
|
|
||||||
// only returns a copy of the queue, no write access
|
// only returns a copy of the queue, no write access
|
||||||
@ -162,9 +176,18 @@ object PlayingQueue {
|
|||||||
onQueueTapListener = listener
|
onQueueTapListener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addOnTrackChangedListener(listener: (StreamItem) -> Unit) {
|
||||||
|
onTrackChangedListeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeOnTrackChangedListener(listener: (StreamItem) -> Unit) {
|
||||||
|
onTrackChangedListeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
fun resetToDefaults() {
|
fun resetToDefaults() {
|
||||||
repeatQueue = false
|
repeatQueue = false
|
||||||
onQueueTapListener = {}
|
onQueueTapListener = {}
|
||||||
|
onTrackChangedListeners.clear()
|
||||||
queue.clear()
|
queue.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
99
app/src/main/res/layout/fragment_audio_player.xml
Normal file
99
app/src/main/res/layout/fragment_audio_player.xml
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/thumbnail"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:layout_marginVertical="10dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Small"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="20dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:marqueeRepeatLimit="marquee_forever"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/uploader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="10dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.slider.Slider
|
||||||
|
android:id="@+id/time_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:labelBehavior="gone"
|
||||||
|
android:layout_marginHorizontal="20dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginVertical="50dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/prev"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_prev" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/play_pause"
|
||||||
|
android:layout_width="72dp"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:insetLeft="0dp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetRight="0dp"
|
||||||
|
android:insetBottom="0dp"
|
||||||
|
app:icon="@drawable/ic_play"
|
||||||
|
app:iconSize="24dp"
|
||||||
|
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Full" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/next"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginHorizontal="20dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_next" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -54,4 +54,9 @@
|
|||||||
android:name="com.github.libretube.ui.fragments.DownloadsFragment"
|
android:name="com.github.libretube.ui.fragments.DownloadsFragment"
|
||||||
android:label="@string/downloads"
|
android:label="@string/downloads"
|
||||||
tools:layout="@layout/fragment_downloads" />
|
tools:layout="@layout/fragment_downloads" />
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/audioPlayerFragment"
|
||||||
|
android:name="com.github.libretube.ui.fragments.AudioPlayerFragment"
|
||||||
|
android:label="@string/audio_player"
|
||||||
|
tools:layout="@layout/fragment_audio_player" />
|
||||||
</navigation>
|
</navigation>
|
@ -430,6 +430,7 @@
|
|||||||
<string name="pause">Pause</string>
|
<string name="pause">Pause</string>
|
||||||
<string name="alternative_pip_controls">Alternative PiP controls</string>
|
<string name="alternative_pip_controls">Alternative PiP controls</string>
|
||||||
<string name="alternative_pip_controls_summary">Show audio only and skip controls in PiP instead of forward and rewind</string>
|
<string name="alternative_pip_controls_summary">Show audio only and skip controls in PiP instead of forward and rewind</string>
|
||||||
|
<string name="audio_player">Audio player</string>
|
||||||
|
|
||||||
<!-- Notification channel strings -->
|
<!-- Notification channel strings -->
|
||||||
<string name="download_channel_name">Download Service</string>
|
<string name="download_channel_name">Download Service</string>
|
||||||
|
@ -89,12 +89,6 @@
|
|||||||
app:valueFrom="0.2"
|
app:valueFrom="0.2"
|
||||||
app:valueTo="4.0" />
|
app:valueTo="4.0" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:icon="@drawable/ic_grid"
|
|
||||||
android:title="@string/open_queue_from_notification"
|
|
||||||
app:key="notification_open_queue" />
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user