mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-05 15:49:22 +00:00
add support for channel playlists on the channel page
This commit is contained in:
parent
152b9b23cd
commit
1ccae84933
3 changed files with 385 additions and 2 deletions
|
@ -0,0 +1,353 @@
|
||||||
|
package com.futo.platformplayer.fragment.channel.tab
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.Settings
|
||||||
|
import com.futo.platformplayer.UIDialogs
|
||||||
|
import com.futo.platformplayer.api.media.models.PlatformAuthorLink
|
||||||
|
import com.futo.platformplayer.api.media.models.channels.IPlatformChannel
|
||||||
|
import com.futo.platformplayer.api.media.models.contents.ContentType
|
||||||
|
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||||
|
import com.futo.platformplayer.api.media.platforms.js.models.JSPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.IAsyncPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.IPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.IRefreshPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.IReplacerPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.MultiPager
|
||||||
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.constructs.Event2
|
||||||
|
import com.futo.platformplayer.constructs.TaskHandler
|
||||||
|
import com.futo.platformplayer.engine.exceptions.PluginException
|
||||||
|
import com.futo.platformplayer.engine.exceptions.ScriptCaptchaRequiredException
|
||||||
|
import com.futo.platformplayer.exceptions.ChannelException
|
||||||
|
import com.futo.platformplayer.fragment.mainactivity.main.FeedView
|
||||||
|
import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile
|
||||||
|
import com.futo.platformplayer.logging.Logger
|
||||||
|
import com.futo.platformplayer.states.StateCache
|
||||||
|
import com.futo.platformplayer.states.StatePlatform
|
||||||
|
import com.futo.platformplayer.states.StateSubscriptions
|
||||||
|
import com.futo.platformplayer.views.FeedStyle
|
||||||
|
import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder
|
||||||
|
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||||
|
import com.futo.platformplayer.views.adapters.feedtypes.PreviewContentListAdapter
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ChannelPlaylistsFragment : Fragment(), IChannelTabFragment {
|
||||||
|
private var _recyclerResults: RecyclerView? = null
|
||||||
|
private var _llmVideo: LinearLayoutManager? = null
|
||||||
|
private var _loading = false
|
||||||
|
private var _pagerParent: IPager<IPlatformContent>? = null
|
||||||
|
private var _pager: IPager<IPlatformContent>? = null
|
||||||
|
private var _cache: FeedView.ItemCache<IPlatformContent>? = null
|
||||||
|
private var _channel: IPlatformChannel? = null
|
||||||
|
private var _results: ArrayList<IPlatformContent> = arrayListOf()
|
||||||
|
private var _adapterResults: InsertedViewAdapterWithLoader<ContentPreviewViewHolder>? = null
|
||||||
|
private var _lastPolycentricProfile: PolycentricProfile? = null
|
||||||
|
|
||||||
|
val onContentClicked = Event2<IPlatformContent, Long>()
|
||||||
|
val onContentUrlClicked = Event2<String, ContentType>()
|
||||||
|
val onUrlClicked = Event1<String>()
|
||||||
|
val onChannelClicked = Event1<PlatformAuthorLink>()
|
||||||
|
val onAddToClicked = Event1<IPlatformContent>()
|
||||||
|
val onAddToQueueClicked = Event1<IPlatformContent>()
|
||||||
|
val onAddToWatchLaterClicked = Event1<IPlatformContent>()
|
||||||
|
val onLongPress = Event1<IPlatformContent>()
|
||||||
|
|
||||||
|
private fun getPlaylistPager(channel: IPlatformChannel): IPager<IPlatformContent> {
|
||||||
|
Logger.i(TAG, "getPlaylistPager")
|
||||||
|
|
||||||
|
return StatePlatform.instance.getChannelPlaylists(channel.url) as IPager<IPlatformContent>
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _taskLoadVideos =
|
||||||
|
TaskHandler<IPlatformChannel, IPager<IPlatformContent>>({ lifecycleScope }, {
|
||||||
|
val livePager = getPlaylistPager(it)
|
||||||
|
return@TaskHandler if (_channel?.let { channel ->
|
||||||
|
StateSubscriptions.instance.isSubscribed(
|
||||||
|
channel
|
||||||
|
)
|
||||||
|
} == true)
|
||||||
|
StateCache.cachePagerResults(lifecycleScope, livePager)
|
||||||
|
else livePager
|
||||||
|
}).success { livePager ->
|
||||||
|
setLoading(false)
|
||||||
|
|
||||||
|
setPager(livePager)
|
||||||
|
}
|
||||||
|
.exception<ScriptCaptchaRequiredException> { }
|
||||||
|
.exception<Throwable> {
|
||||||
|
Logger.w(TAG, "Failed to load initial videos.", it)
|
||||||
|
UIDialogs.showGeneralRetryErrorDialog(
|
||||||
|
requireContext(),
|
||||||
|
it.message ?: "",
|
||||||
|
it,
|
||||||
|
{ loadNextPage() })
|
||||||
|
}
|
||||||
|
|
||||||
|
private var _nextPageHandler: TaskHandler<IPager<IPlatformContent>, List<IPlatformContent>> =
|
||||||
|
TaskHandler<IPager<IPlatformContent>, List<IPlatformContent>>({ lifecycleScope }, {
|
||||||
|
if (it is IAsyncPager<*>)
|
||||||
|
it.nextPageAsync()
|
||||||
|
else
|
||||||
|
it.nextPage()
|
||||||
|
|
||||||
|
processPagerExceptions(it)
|
||||||
|
return@TaskHandler it.getResults()
|
||||||
|
}).success {
|
||||||
|
setLoading(false)
|
||||||
|
val posBefore = _results.size
|
||||||
|
//val toAdd = it.filter { it is IPlatformVideo }.map { it as IPlatformVideo }
|
||||||
|
_results.addAll(it)
|
||||||
|
_adapterResults?.let { adapterVideo ->
|
||||||
|
adapterVideo.notifyItemRangeInserted(
|
||||||
|
adapterVideo.childToParentPosition(
|
||||||
|
posBefore
|
||||||
|
), it.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.exception<Throwable> {
|
||||||
|
Logger.w(TAG, "Failed to load next page.", it)
|
||||||
|
UIDialogs.showGeneralRetryErrorDialog(
|
||||||
|
requireContext(),
|
||||||
|
it.message ?: "",
|
||||||
|
it,
|
||||||
|
{ loadNextPage() })
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _scrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
|
||||||
|
val recyclerResults = _recyclerResults ?: return
|
||||||
|
val llmVideo = _llmVideo ?: return
|
||||||
|
|
||||||
|
val visibleItemCount = recyclerResults.childCount
|
||||||
|
val firstVisibleItem = llmVideo.findFirstVisibleItemPosition()
|
||||||
|
val visibleThreshold = 15
|
||||||
|
if (!_loading && firstVisibleItem + visibleItemCount + visibleThreshold >= _results.size) {
|
||||||
|
loadNextPage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChannel(channel: IPlatformChannel) {
|
||||||
|
val c = _channel
|
||||||
|
if (c != null && c.url == channel.url) {
|
||||||
|
Logger.i(TAG, "setChannel skipped because previous was same")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.i(TAG, "setChannel setChannel=${channel}")
|
||||||
|
|
||||||
|
_taskLoadVideos.cancel()
|
||||||
|
|
||||||
|
_channel = channel
|
||||||
|
_results.clear()
|
||||||
|
_adapterResults?.notifyDataSetChanged()
|
||||||
|
|
||||||
|
loadInitial()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
val view = inflater.inflate(R.layout.fragment_channel_videos, container, false)
|
||||||
|
|
||||||
|
_recyclerResults = view.findViewById(R.id.recycler_videos)
|
||||||
|
|
||||||
|
_adapterResults = PreviewContentListAdapter(
|
||||||
|
view.context,
|
||||||
|
FeedStyle.THUMBNAIL,
|
||||||
|
_results,
|
||||||
|
null,
|
||||||
|
Settings.instance.channel.progressBar
|
||||||
|
).apply {
|
||||||
|
this.onContentUrlClicked.subscribe(this@ChannelPlaylistsFragment.onContentUrlClicked::emit)
|
||||||
|
this.onUrlClicked.subscribe(this@ChannelPlaylistsFragment.onUrlClicked::emit)
|
||||||
|
this.onContentClicked.subscribe(this@ChannelPlaylistsFragment.onContentClicked::emit)
|
||||||
|
this.onChannelClicked.subscribe(this@ChannelPlaylistsFragment.onChannelClicked::emit)
|
||||||
|
this.onAddToClicked.subscribe(this@ChannelPlaylistsFragment.onAddToClicked::emit)
|
||||||
|
this.onAddToQueueClicked.subscribe(this@ChannelPlaylistsFragment.onAddToQueueClicked::emit)
|
||||||
|
this.onAddToWatchLaterClicked.subscribe(this@ChannelPlaylistsFragment.onAddToWatchLaterClicked::emit)
|
||||||
|
this.onLongPress.subscribe(this@ChannelPlaylistsFragment.onLongPress::emit)
|
||||||
|
}
|
||||||
|
|
||||||
|
_llmVideo = LinearLayoutManager(view.context)
|
||||||
|
_recyclerResults?.adapter = _adapterResults
|
||||||
|
_recyclerResults?.layoutManager = _llmVideo
|
||||||
|
_recyclerResults?.addOnScrollListener(_scrollListener)
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_recyclerResults?.removeOnScrollListener(_scrollListener)
|
||||||
|
_recyclerResults = null
|
||||||
|
_pager = null
|
||||||
|
|
||||||
|
_taskLoadVideos.cancel()
|
||||||
|
_nextPageHandler.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setPager(
|
||||||
|
pager: IPager<IPlatformContent>,
|
||||||
|
cache: FeedView.ItemCache<IPlatformContent>? = null
|
||||||
|
) {
|
||||||
|
if (_pagerParent != null && _pagerParent is IRefreshPager<*>) {
|
||||||
|
(_pagerParent as IRefreshPager<*>).onPagerError.remove(this)
|
||||||
|
(_pagerParent as IRefreshPager<*>).onPagerChanged.remove(this)
|
||||||
|
_pagerParent = null
|
||||||
|
}
|
||||||
|
if (_pager is IReplacerPager<*>)
|
||||||
|
(_pager as IReplacerPager<*>).onReplaced.remove(this)
|
||||||
|
|
||||||
|
val pagerToSet: IPager<IPlatformContent>?
|
||||||
|
if (pager is IRefreshPager<*>) {
|
||||||
|
_pagerParent = pager
|
||||||
|
pagerToSet = pager.getCurrentPager() as IPager<IPlatformContent>
|
||||||
|
pager.onPagerChanged.subscribe(this) {
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
try {
|
||||||
|
loadPagerInternal(it as IPager<IPlatformContent>)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Logger.e(TAG, "loadPagerInternal failed.", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pager.onPagerError.subscribe(this) {
|
||||||
|
Logger.e(TAG, "Search pager failed: ${it.message}", it)
|
||||||
|
if (it is PluginException)
|
||||||
|
UIDialogs.toast("Plugin [${it.config.name}] failed due to:\n${it.message}")
|
||||||
|
else
|
||||||
|
UIDialogs.toast("Plugin failed due to:\n${it.message}")
|
||||||
|
}
|
||||||
|
} else pagerToSet = pager
|
||||||
|
|
||||||
|
loadPagerInternal(pagerToSet, cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadPagerInternal(
|
||||||
|
pager: IPager<IPlatformContent>,
|
||||||
|
cache: FeedView.ItemCache<IPlatformContent>? = null
|
||||||
|
) {
|
||||||
|
_cache = cache
|
||||||
|
|
||||||
|
if (_pager is IReplacerPager<*>)
|
||||||
|
(_pager as IReplacerPager<*>).onReplaced.remove(this)
|
||||||
|
if (pager is IReplacerPager<*>) {
|
||||||
|
pager.onReplaced.subscribe(this) { oldItem, newItem ->
|
||||||
|
if (_pager != pager)
|
||||||
|
return@subscribe
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
val toReplaceIndex = _results.indexOfFirst { it == oldItem }
|
||||||
|
if (toReplaceIndex >= 0) {
|
||||||
|
_results[toReplaceIndex] = newItem as IPlatformContent
|
||||||
|
_adapterResults?.let {
|
||||||
|
it.notifyItemChanged(it.childToParentPosition(toReplaceIndex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_pager = pager
|
||||||
|
|
||||||
|
processPagerExceptions(pager)
|
||||||
|
|
||||||
|
_results.clear()
|
||||||
|
val toAdd = pager.getResults()
|
||||||
|
_results.addAll(toAdd)
|
||||||
|
_adapterResults?.notifyDataSetChanged()
|
||||||
|
_recyclerResults?.scrollToPosition(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadInitial() {
|
||||||
|
val channel: IPlatformChannel = _channel ?: return
|
||||||
|
setLoading(true)
|
||||||
|
_taskLoadVideos.run(channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadNextPage() {
|
||||||
|
val pager: IPager<IPlatformContent> = _pager ?: return
|
||||||
|
if (_pager?.hasMorePages() == true) {
|
||||||
|
setLoading(true)
|
||||||
|
_nextPageHandler.run(pager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setLoading(loading: Boolean) {
|
||||||
|
_loading = loading
|
||||||
|
_adapterResults?.setLoading(loading)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPolycentricProfile(polycentricProfile: PolycentricProfile?) {
|
||||||
|
val p = _lastPolycentricProfile
|
||||||
|
if (p != null && polycentricProfile != null && p.system == polycentricProfile.system) {
|
||||||
|
Logger.i(
|
||||||
|
ChannelContentsFragment.TAG,
|
||||||
|
"setPolycentricProfile skipped because previous was same"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastPolycentricProfile = polycentricProfile
|
||||||
|
|
||||||
|
if (polycentricProfile != null) {
|
||||||
|
_taskLoadVideos.cancel()
|
||||||
|
val itemsRemoved = _results.size
|
||||||
|
_results.clear()
|
||||||
|
_adapterResults?.notifyItemRangeRemoved(0, itemsRemoved)
|
||||||
|
loadInitial()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processPagerExceptions(pager: IPager<*>) {
|
||||||
|
if (pager is MultiPager<*> && pager.allowFailure) {
|
||||||
|
val ex = pager.getResultExceptions()
|
||||||
|
for (kv in ex) {
|
||||||
|
val jsVideoPager: JSPager<*>? = when (kv.key) {
|
||||||
|
is MultiPager<*> -> (kv.key as MultiPager<*>).findPager { it is JSPager<*> } as JSPager<*>?
|
||||||
|
is JSPager<*> -> kv.key as JSPager<*>
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
context?.let {
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
try {
|
||||||
|
val channel =
|
||||||
|
if (kv.value is ChannelException) (kv.value as ChannelException).channelNameOrUrl else null
|
||||||
|
if (jsVideoPager != null)
|
||||||
|
UIDialogs.toast(
|
||||||
|
it, "Plugin ${jsVideoPager.getPluginConfig().name} failed:\n" +
|
||||||
|
(if (!channel.isNullOrEmpty()) "(${channel}) " else "") +
|
||||||
|
"${kv.value.message}", false
|
||||||
|
)
|
||||||
|
else
|
||||||
|
UIDialogs.toast(it, kv.value.message ?: "", false)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Logger.e(TAG, "Failed to show toast.", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "PlaylistsFragment"
|
||||||
|
fun newInstance() = ChannelPlaylistsFragment().apply { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ import com.futo.platformplayer.fragment.channel.tab.ChannelAboutFragment
|
||||||
import com.futo.platformplayer.fragment.channel.tab.ChannelContentsFragment
|
import com.futo.platformplayer.fragment.channel.tab.ChannelContentsFragment
|
||||||
import com.futo.platformplayer.fragment.channel.tab.ChannelListFragment
|
import com.futo.platformplayer.fragment.channel.tab.ChannelListFragment
|
||||||
import com.futo.platformplayer.fragment.channel.tab.ChannelMonetizationFragment
|
import com.futo.platformplayer.fragment.channel.tab.ChannelMonetizationFragment
|
||||||
|
import com.futo.platformplayer.fragment.channel.tab.ChannelPlaylistsFragment
|
||||||
import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFragment
|
import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFragment
|
||||||
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
|
@ -57,6 +58,8 @@ import kotlinx.serialization.Serializable
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PolycentricProfile(val system: PublicKey, val systemState: SystemState, val ownedClaims: List<OwnedClaim>);
|
data class PolycentricProfile(val system: PublicKey, val systemState: SystemState, val ownedClaims: List<OwnedClaim>);
|
||||||
|
|
||||||
|
const val PLAYLIST_POSITION = 4
|
||||||
|
|
||||||
class ChannelFragment : MainFragment() {
|
class ChannelFragment : MainFragment() {
|
||||||
override val isMainView : Boolean = true;
|
override val isMainView : Boolean = true;
|
||||||
override val hasBottomBar: Boolean = true;
|
override val hasBottomBar: Boolean = true;
|
||||||
|
@ -241,6 +244,7 @@ class ChannelFragment : MainFragment() {
|
||||||
//2 -> "STORE"
|
//2 -> "STORE"
|
||||||
2 -> "SUPPORT"
|
2 -> "SUPPORT"
|
||||||
3 -> "ABOUT"
|
3 -> "ABOUT"
|
||||||
|
PLAYLIST_POSITION -> "PLAYLISTS"
|
||||||
else -> "Unknown $position"
|
else -> "Unknown $position"
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -384,6 +388,10 @@ class ChannelFragment : MainFragment() {
|
||||||
private fun showChannel(channel: IPlatformChannel) {
|
private fun showChannel(channel: IPlatformChannel) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|
||||||
|
if (!StatePlatform.instance.getChannelClient(channel.url).capabilities.hasGetChannelPlaylists) {
|
||||||
|
_tabs.removeTabAt(PLAYLIST_POSITION)
|
||||||
|
}
|
||||||
|
|
||||||
_fragment.topBar?.onShown(channel);
|
_fragment.topBar?.onShown(channel);
|
||||||
|
|
||||||
val buttons = arrayListOf(Pair(R.drawable.ic_playlist_add) {
|
val buttons = arrayListOf(Pair(R.drawable.ic_playlist_add) {
|
||||||
|
@ -435,6 +443,10 @@ class ChannelFragment : MainFragment() {
|
||||||
it.getFragment<ChannelAboutFragment>().setChannel(channel);
|
it.getFragment<ChannelAboutFragment>().setChannel(channel);
|
||||||
it.getFragment<ChannelListFragment>().setChannel(channel);
|
it.getFragment<ChannelListFragment>().setChannel(channel);
|
||||||
it.getFragment<ChannelMonetizationFragment>().setChannel(channel);
|
it.getFragment<ChannelMonetizationFragment>().setChannel(channel);
|
||||||
|
if (StatePlatform.instance.getChannelClient(channel.url).capabilities.hasGetChannelPlaylists) {
|
||||||
|
Logger.w(TAG, "Supported channel playlists??");
|
||||||
|
it.getFragment<ChannelPlaylistsFragment>().setChannel(channel);
|
||||||
|
}
|
||||||
//TODO: Call on other tabs as needed
|
//TODO: Call on other tabs as needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,6 +513,12 @@ class ChannelFragment : MainFragment() {
|
||||||
it.getFragment<ChannelMonetizationFragment>().setPolycentricProfile(profile);
|
it.getFragment<ChannelMonetizationFragment>().setPolycentricProfile(profile);
|
||||||
it.getFragment<ChannelListFragment>().setPolycentricProfile(profile);
|
it.getFragment<ChannelListFragment>().setPolycentricProfile(profile);
|
||||||
it.getFragment<ChannelContentsFragment>().setPolycentricProfile(profile);
|
it.getFragment<ChannelContentsFragment>().setPolycentricProfile(profile);
|
||||||
|
channel?.let { channel ->
|
||||||
|
if (StatePlatform.instance.getChannelClient(channel.url).capabilities.hasGetChannelPlaylists) {
|
||||||
|
Logger.w(TAG, "Supported channel playlists??");
|
||||||
|
it.getFragment<ChannelPlaylistsFragment>().setPolycentricProfile(profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
//TODO: Call on other tabs as needed
|
//TODO: Call on other tabs as needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import com.futo.platformplayer.constructs.Event2
|
||||||
import com.futo.platformplayer.fragment.channel.tab.*
|
import com.futo.platformplayer.fragment.channel.tab.*
|
||||||
|
|
||||||
class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||||
private val _cache: Array<Fragment?> = arrayOfNulls(4);
|
private val _cache: Array<Fragment?> = arrayOfNulls(5);
|
||||||
|
|
||||||
val onContentUrlClicked = Event2<String, ContentType>();
|
val onContentUrlClicked = Event2<String, ContentType>();
|
||||||
val onUrlClicked = Event1<String>();
|
val onUrlClicked = Event1<String>();
|
||||||
|
@ -39,6 +39,8 @@ class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifec
|
||||||
return createFragment(2) as T;
|
return createFragment(2) as T;
|
||||||
else if(T::class == ChannelAboutFragment::class)
|
else if(T::class == ChannelAboutFragment::class)
|
||||||
return createFragment(3) as T;
|
return createFragment(3) as T;
|
||||||
|
else if(T::class == ChannelPlaylistsFragment::class)
|
||||||
|
return createFragment(4) as T;
|
||||||
else
|
else
|
||||||
throw NotImplementedError("Implement other types");
|
throw NotImplementedError("Implement other types");
|
||||||
}
|
}
|
||||||
|
@ -64,6 +66,16 @@ class ChannelViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifec
|
||||||
//2 -> ChannelStoreFragment.newInstance();
|
//2 -> ChannelStoreFragment.newInstance();
|
||||||
2 -> ChannelMonetizationFragment.newInstance();
|
2 -> ChannelMonetizationFragment.newInstance();
|
||||||
3 -> ChannelAboutFragment.newInstance();
|
3 -> ChannelAboutFragment.newInstance();
|
||||||
|
4 -> ChannelPlaylistsFragment.newInstance().apply {
|
||||||
|
onContentClicked.subscribe(this@ChannelViewPagerAdapter.onContentClicked::emit);
|
||||||
|
onContentUrlClicked.subscribe(this@ChannelViewPagerAdapter.onContentUrlClicked::emit);
|
||||||
|
onUrlClicked.subscribe(this@ChannelViewPagerAdapter.onUrlClicked::emit);
|
||||||
|
onChannelClicked.subscribe(this@ChannelViewPagerAdapter.onChannelClicked::emit);
|
||||||
|
onAddToClicked.subscribe(this@ChannelViewPagerAdapter.onAddToClicked::emit);
|
||||||
|
onAddToQueueClicked.subscribe(this@ChannelViewPagerAdapter.onAddToQueueClicked::emit);
|
||||||
|
onAddToWatchLaterClicked.subscribe(this@ChannelViewPagerAdapter.onAddToWatchLaterClicked::emit);
|
||||||
|
onLongPress.subscribe(this@ChannelViewPagerAdapter.onLongPress::emit);
|
||||||
|
};
|
||||||
else -> throw IllegalStateException("Invalid tab position $position")
|
else -> throw IllegalStateException("Invalid tab position $position")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue