diff --git a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt index c44ea4f8d..bddcb5fde 100644 --- a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt +++ b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt @@ -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) diff --git a/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt index b0639128d..d339f00ba 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/LegacySubscriptionAdapter.kt @@ -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 + } } } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/SearchAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/SearchAdapter.kt index 4f8a4e141..5f8b325fa 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/SearchAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/SearchAdapter.kt @@ -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()) } } diff --git a/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt b/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt index 91675f16f..c0e2c37e1 100644 --- a/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt +++ b/app/src/main/java/com/github/libretube/ui/adapters/SubscriptionChannelAdapter.kt @@ -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, diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 20fd982e7..b44c89105 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -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) { diff --git a/app/src/main/java/com/github/libretube/ui/sheets/ChannelOptionsBottomSheet.kt b/app/src/main/java/com/github/libretube/ui/sheets/ChannelOptionsBottomSheet.kt new file mode 100644 index 000000000..987cfbf7a --- /dev/null +++ b/app/src/main/java/com/github/libretube/ui/sheets/ChannelOptionsBottomSheet.kt @@ -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()) + } + } + } + } + } +} diff --git a/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt b/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt index 39ce8e869..2b5f942c9 100644 --- a/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt +++ b/app/src/main/java/com/github/libretube/util/BackgroundHelper.kt @@ -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) { diff --git a/app/src/main/java/com/github/libretube/util/NavigationHelper.kt b/app/src/main/java/com/github/libretube/util/NavigationHelper.kt index c198279d8..313178668 100644 --- a/app/src/main/java/com/github/libretube/util/NavigationHelper.kt +++ b/app/src/main/java/com/github/libretube/util/NavigationHelper.kt @@ -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 diff --git a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt index fe64f85fd..8c183c7b2 100644 --- a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt +++ b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt @@ -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] diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f5bc65eca..adbe50fbc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -414,6 +414,7 @@ Privacy alert Proceed with an e-mail address that isn\'t recommended\? Proceed + Play latest videos Download Service