mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-14 06:10:31 +05:30
Merge pull request #2180 from Bnyro/channel-share
Option to shar channels and play their latest videos
This commit is contained in:
commit
974ecb04a4
@ -22,7 +22,6 @@ import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
|
||||
import com.github.libretube.constants.PreferenceKeys
|
||||
import com.github.libretube.db.DatabaseHolder.Companion.Database
|
||||
import com.github.libretube.db.obj.WatchPosition
|
||||
import com.github.libretube.enums.PlaylistType
|
||||
import com.github.libretube.extensions.awaitQuery
|
||||
import com.github.libretube.extensions.query
|
||||
import com.github.libretube.extensions.toID
|
||||
@ -51,10 +50,10 @@ class BackgroundMode : Service() {
|
||||
private lateinit var videoId: String
|
||||
|
||||
/**
|
||||
*PlaylistId for autoplay
|
||||
* PlaylistId/ChannelId for autoplay
|
||||
*/
|
||||
private var playlistId: String? = null
|
||||
private var playlistType: PlaylistType? = null
|
||||
private var channelId: String? = null
|
||||
|
||||
/**
|
||||
* The response that gets when called the Api.
|
||||
@ -162,11 +161,14 @@ class BackgroundMode : Service() {
|
||||
}
|
||||
|
||||
// add the playlist video to the queue
|
||||
if (playlistId != null && PlayingQueue.isEmpty()) {
|
||||
streams?.toStreamItem(videoId)
|
||||
?.let {
|
||||
PlayingQueue.insertPlaylist(playlistId!!, it)
|
||||
}
|
||||
if (PlayingQueue.isEmpty() && playlistId != null) {
|
||||
streams?.toStreamItem(videoId)?.let {
|
||||
PlayingQueue.insertPlaylist(playlistId!!, it)
|
||||
}
|
||||
} else if (PlayingQueue.isEmpty() && channelId != null) {
|
||||
streams?.toStreamItem(videoId)?.let {
|
||||
PlayingQueue.insertChannel(channelId!!, it)
|
||||
}
|
||||
} else {
|
||||
streams?.toStreamItem(videoId)?.let {
|
||||
PlayingQueue.updateCurrent(it)
|
||||
|
@ -5,6 +5,8 @@ import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.databinding.LegacySubscriptionChannelBinding
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.base.BaseActivity
|
||||
import com.github.libretube.ui.sheets.ChannelOptionsBottomSheet
|
||||
import com.github.libretube.ui.viewholders.LegacySubscriptionViewHolder
|
||||
import com.github.libretube.util.ImageHelper
|
||||
import com.github.libretube.util.NavigationHelper
|
||||
@ -36,6 +38,12 @@ class LegacySubscriptionAdapter(
|
||||
subscription.url!!.toID()
|
||||
)
|
||||
}
|
||||
|
||||
root.setOnLongClickListener {
|
||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
||||
.show((root.context as BaseActivity).supportFragmentManager)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import com.github.libretube.ui.base.BaseActivity
|
||||
import com.github.libretube.ui.extensions.setFormattedDuration
|
||||
import com.github.libretube.ui.extensions.setWatchProgressLength
|
||||
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
||||
import com.github.libretube.ui.sheets.ChannelOptionsBottomSheet
|
||||
import com.github.libretube.ui.sheets.PlaylistOptionsBottomSheet
|
||||
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
|
||||
import com.github.libretube.ui.viewholders.SearchViewHolder
|
||||
@ -127,6 +128,12 @@ class SearchAdapter(
|
||||
NavigationHelper.navigateChannel(root.context, item.url)
|
||||
}
|
||||
|
||||
root.setOnLongClickListener {
|
||||
ChannelOptionsBottomSheet(item.url!!.toID(), item.name)
|
||||
.show((root.context as BaseActivity).supportFragmentManager)
|
||||
true
|
||||
}
|
||||
|
||||
binding.searchSubButton.setupSubscriptionButton(item.url?.toID(), item.name?.toID())
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.libretube.api.obj.Subscription
|
||||
import com.github.libretube.databinding.ChannelSubscriptionRowBinding
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.base.BaseActivity
|
||||
import com.github.libretube.ui.extensions.setupSubscriptionButton
|
||||
import com.github.libretube.ui.sheets.ChannelOptionsBottomSheet
|
||||
import com.github.libretube.ui.viewholders.SubscriptionChannelViewHolder
|
||||
import com.github.libretube.util.ImageHelper
|
||||
import com.github.libretube.util.NavigationHelper
|
||||
@ -36,6 +38,12 @@ class SubscriptionChannelAdapter(
|
||||
root.setOnClickListener {
|
||||
NavigationHelper.navigateChannel(root.context, subscription.url)
|
||||
}
|
||||
root.setOnLongClickListener {
|
||||
ChannelOptionsBottomSheet(subscription.url!!.toID(), subscription.name)
|
||||
.show((root.context as BaseActivity).supportFragmentManager)
|
||||
true
|
||||
}
|
||||
|
||||
subscriptionSubscribe.setupSubscriptionButton(
|
||||
subscription.url?.toID(),
|
||||
subscription.name,
|
||||
|
@ -127,6 +127,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
*/
|
||||
private var videoId: String? = null
|
||||
private var playlistId: String? = null
|
||||
private var channelId: String? = null
|
||||
private var isLive = false
|
||||
private lateinit var streams: Streams
|
||||
|
||||
@ -172,6 +173,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
arguments?.let {
|
||||
videoId = it.getString(IntentData.videoId)!!.toID()
|
||||
playlistId = it.getString(IntentData.playlistId)
|
||||
channelId = it.getString(IntentData.channelId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,7 +401,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
requireContext(),
|
||||
videoId!!,
|
||||
exoPlayer.currentPosition,
|
||||
playlistId
|
||||
playlistId,
|
||||
channelId
|
||||
)
|
||||
}
|
||||
|
||||
@ -593,6 +596,8 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (playlistId != null) {
|
||||
PlayingQueue.insertPlaylist(playlistId!!, streams.toStreamItem(videoId!!))
|
||||
} else if (channelId != null) {
|
||||
PlayingQueue.insertChannel(channelId!!, streams.toStreamItem(videoId!!))
|
||||
} else {
|
||||
PlayingQueue.updateCurrent(streams.toStreamItem(videoId!!))
|
||||
if (PlayerHelper.autoInsertRelatedVideos) {
|
||||
|
@ -0,0 +1,77 @@
|
||||
package com.github.libretube.ui.sheets
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.enums.ShareObjectType
|
||||
import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.obj.ShareData
|
||||
import com.github.libretube.ui.dialogs.ShareDialog
|
||||
import com.github.libretube.util.BackgroundHelper
|
||||
import com.github.libretube.util.NavigationHelper
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
/**
|
||||
* Dialog with different options for a selected video.
|
||||
*
|
||||
* Needs the [videoId] to load the content from the right video.
|
||||
*/
|
||||
class ChannelOptionsBottomSheet(
|
||||
private val channelId: String,
|
||||
private val channelName: String?
|
||||
) : BaseBottomSheet() {
|
||||
private val shareData = ShareData(currentChannel = channelName)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// List that stores the different menu options. In the future could be add more options here.
|
||||
val optionsList = mutableListOf(
|
||||
getString(R.string.share),
|
||||
getString(R.string.play_latest_videos),
|
||||
getString(R.string.playOnBackground)
|
||||
)
|
||||
|
||||
setSimpleItems(optionsList) { which ->
|
||||
when (optionsList[which]) {
|
||||
getString(R.string.share) -> {
|
||||
ShareDialog(channelId, ShareObjectType.CHANNEL, shareData)
|
||||
.show(parentFragmentManager, null)
|
||||
}
|
||||
getString(R.string.play_latest_videos) -> {
|
||||
try {
|
||||
val channel = runBlocking {
|
||||
RetrofitInstance.api.getChannel(channelId)
|
||||
}
|
||||
channel.relatedStreams?.firstOrNull()?.url?.toID()?.let {
|
||||
NavigationHelper.navigateVideo(
|
||||
requireContext(),
|
||||
it,
|
||||
channelId = channelId
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
}
|
||||
}
|
||||
getString(R.string.playOnBackground) -> {
|
||||
try {
|
||||
val channel = runBlocking {
|
||||
RetrofitInstance.api.getChannel(channelId)
|
||||
}
|
||||
channel.relatedStreams?.firstOrNull()?.url?.toID()?.let {
|
||||
BackgroundHelper.playOnBackground(
|
||||
requireContext(),
|
||||
videoId = it,
|
||||
channelId = channelId
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG(), e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,13 +20,15 @@ object BackgroundHelper {
|
||||
context: Context,
|
||||
videoId: String,
|
||||
position: Long? = null,
|
||||
playlistId: String? = null
|
||||
playlistId: String? = null,
|
||||
channelId: String? = null
|
||||
) {
|
||||
// create an intent for the background mode service
|
||||
val intent = Intent(context, BackgroundMode::class.java)
|
||||
intent.putExtra(IntentData.videoId, videoId)
|
||||
if (playlistId != null) intent.putExtra(IntentData.playlistId, playlistId)
|
||||
if (position != null) intent.putExtra("position", position)
|
||||
intent.putExtra(IntentData.playlistId, playlistId)
|
||||
intent.putExtra(IntentData.channelId, channelId)
|
||||
intent.putExtra("position", position)
|
||||
|
||||
// start the background mode as foreground service
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
||||
|
@ -48,13 +48,16 @@ object NavigationHelper {
|
||||
fun navigateVideo(
|
||||
context: Context,
|
||||
videoId: String?,
|
||||
playlistId: String? = null
|
||||
playlistId: String? = null,
|
||||
channelId: String? = null
|
||||
) {
|
||||
if (videoId == null) return
|
||||
|
||||
val bundle = Bundle()
|
||||
bundle.putString(IntentData.videoId, videoId.toID())
|
||||
if (playlistId != null) bundle.putString(IntentData.playlistId, playlistId)
|
||||
bundle.putString(IntentData.playlistId, playlistId)
|
||||
bundle.putString(IntentData.channelId, channelId)
|
||||
|
||||
val frag = PlayerFragment()
|
||||
frag.arguments = bundle
|
||||
val activity = context as AppCompatActivity
|
||||
|
@ -110,13 +110,8 @@ object PlayingQueue {
|
||||
fun insertPlaylist(playlistId: String, newCurrentStream: StreamItem) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val playlistType = PlaylistsHelper.getPrivatePlaylistType(playlistId)
|
||||
val playlist = PlaylistsHelper.getPlaylist(playlistId)
|
||||
add(
|
||||
*playlist.relatedStreams
|
||||
.orEmpty()
|
||||
.toTypedArray()
|
||||
)
|
||||
add(*playlist.relatedStreams.orEmpty().toTypedArray())
|
||||
updateCurrent(newCurrentStream)
|
||||
if (playlist.nextpage == null) return@launch
|
||||
fetchMoreFromPlaylist(playlistId, playlist.nextpage)
|
||||
@ -126,6 +121,32 @@ object PlayingQueue {
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchMoreFromChannel(channelId: String, nextPage: String?) {
|
||||
var channelNextPage: String? = nextPage
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
while (channelNextPage != null) {
|
||||
RetrofitInstance.api.getChannelNextPage(channelId, nextPage!!).apply {
|
||||
add(*relatedStreams.orEmpty().toTypedArray())
|
||||
channelNextPage = this.nextpage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun insertChannel(channelId: String, newCurrentStream: StreamItem) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
val channel = RetrofitInstance.api.getChannel(channelId)
|
||||
add(*channel.relatedStreams.orEmpty().toTypedArray())
|
||||
updateCurrent(newCurrentStream)
|
||||
if (channel.nextpage == null) return@launch
|
||||
fetchMoreFromChannel(channelId, channel.nextpage)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onQueueItemSelected(index: Int) {
|
||||
try {
|
||||
val streamItem = queue[index]
|
||||
|
@ -414,6 +414,7 @@
|
||||
<string name="privacy_alert">Privacy alert</string>
|
||||
<string name="username_email">Proceed with an e-mail address that isn\'t recommended\?</string>
|
||||
<string name="proceed">Proceed</string>
|
||||
<string name="play_latest_videos">Play latest videos</string>
|
||||
|
||||
<!-- Notification channel strings -->
|
||||
<string name="download_channel_name">Download Service</string>
|
||||
|
Loading…
Reference in New Issue
Block a user