mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-27 15:30:31 +05:30
UI for channel tabs
This commit is contained in:
parent
36e2da52fb
commit
18eebe663b
@ -6,11 +6,13 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.children
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.RetrofitInstance
|
||||
import com.github.libretube.api.SubscriptionHelper
|
||||
import com.github.libretube.api.obj.ChannelTab
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.constants.ShareObjectType
|
||||
import com.github.libretube.databinding.FragmentChannelBinding
|
||||
@ -18,9 +20,14 @@ import com.github.libretube.extensions.TAG
|
||||
import com.github.libretube.extensions.formatShort
|
||||
import com.github.libretube.extensions.toID
|
||||
import com.github.libretube.ui.adapters.ChannelAdapter
|
||||
import com.github.libretube.ui.adapters.SearchAdapter
|
||||
import com.github.libretube.ui.base.BaseFragment
|
||||
import com.github.libretube.ui.dialogs.ShareDialog
|
||||
import com.github.libretube.util.ImageHelper
|
||||
import com.google.android.material.chip.Chip
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
@ -35,6 +42,10 @@ class ChannelFragment : BaseFragment() {
|
||||
private var isLoading = true
|
||||
private var isSubscribed: Boolean? = false
|
||||
|
||||
private var onScrollEnd: () -> Unit = {}
|
||||
|
||||
val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
@ -73,11 +84,10 @@ class ChannelFragment : BaseFragment() {
|
||||
if (binding.channelScrollView.getChildAt(0).bottom
|
||||
== (binding.channelScrollView.height + binding.channelScrollView.scrollY)
|
||||
) {
|
||||
// scroll view is at bottom
|
||||
if (nextPage != null && !isLoading) {
|
||||
isLoading = true
|
||||
binding.channelRefresh.isRefreshing = true
|
||||
fetchChannelNextPage()
|
||||
try {
|
||||
onScrollEnd.invoke()
|
||||
} catch (e: Exception) {
|
||||
Log.e("tabs failed", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,6 +113,14 @@ class ChannelFragment : BaseFragment() {
|
||||
// needed if the channel gets loaded by the ID
|
||||
channelId = response.id
|
||||
|
||||
onScrollEnd = {
|
||||
if (nextPage != null && !isLoading) {
|
||||
isLoading = true
|
||||
binding.channelRefresh.isRefreshing = true
|
||||
fetchChannelNextPage()
|
||||
}
|
||||
}
|
||||
|
||||
// fetch and update the subscription status
|
||||
isSubscribed = SubscriptionHelper.isSubscribed(channelId!!)
|
||||
if (isSubscribed == null) return@launchWhenCreated
|
||||
@ -166,17 +184,68 @@ class ChannelFragment : BaseFragment() {
|
||||
|
||||
// recyclerview of the videos by the channel
|
||||
channelAdapter = ChannelAdapter(
|
||||
response.relatedStreams!!.toMutableList(),
|
||||
response.relatedStreams.orEmpty().toMutableList(),
|
||||
childFragmentManager
|
||||
)
|
||||
binding.channelRecView.adapter = channelAdapter
|
||||
}
|
||||
|
||||
response.tabs?.forEach {
|
||||
try {
|
||||
RetrofitInstance.api.getChannelTab(it.data!!).toString()
|
||||
binding.videos.setOnClickListener {
|
||||
binding.channelRecView.adapter = channelAdapter
|
||||
}
|
||||
|
||||
response.tabs?.firstOrNull { it.name == "Playlists" }?.let {
|
||||
setupTab(binding.playlists, it)
|
||||
}
|
||||
|
||||
response.tabs?.firstOrNull { it.name == "Channels" }?.let {
|
||||
setupTab(binding.channels, it)
|
||||
}
|
||||
|
||||
response.tabs?.firstOrNull { it.name == "Livestreams" }?.let {
|
||||
setupTab(binding.livestreams, it)
|
||||
}
|
||||
|
||||
response.tabs?.firstOrNull { it.name == "Shorts" }?.let {
|
||||
setupTab(binding.shorts, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupTab(chip: Chip, tab: ChannelTab) {
|
||||
chip.visibility = View.VISIBLE
|
||||
chip.setOnClickListener {
|
||||
binding.tabChips.children.forEach {
|
||||
if (it != chip) it.isSelected = false
|
||||
}
|
||||
scope.launch {
|
||||
val response = try {
|
||||
RetrofitInstance.api.getChannelTab(tab.data!!)
|
||||
} catch (e: Exception) {
|
||||
Log.e("error", e.toString())
|
||||
return@launch
|
||||
}
|
||||
|
||||
val adapter = SearchAdapter(
|
||||
response.content.toMutableList(),
|
||||
childFragmentManager
|
||||
)
|
||||
|
||||
runOnUiThread {
|
||||
binding.channelRecView.adapter = adapter
|
||||
}
|
||||
|
||||
onScrollEnd = {
|
||||
if (response.nextpage != null) {
|
||||
scope.launch {
|
||||
val newContent = try {
|
||||
RetrofitInstance.api.getChannelTab(tab.data, response.nextpage)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
newContent?.content?.let { adapter.updateItems(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,47 @@
|
||||
android:maxLines="2"
|
||||
android:padding="10dp" />
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/tab_chips"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:scrollbars="none">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/videos"
|
||||
style="@style/channelChip"
|
||||
android:text="@string/videos"
|
||||
android:visibility="visible" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/playlists"
|
||||
style="@style/channelChip"
|
||||
android:text="@string/playlists" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/shorts"
|
||||
style="@style/channelChip"
|
||||
android:text="@string/yt_shorts" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/channels"
|
||||
style="@style/channelChip"
|
||||
android:text="@string/channels" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/livestreams"
|
||||
style="@style/channelChip"
|
||||
android:text="@string/livestreams" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -352,6 +352,7 @@
|
||||
<string name="queue">Queue</string>
|
||||
<string name="sb_markers">Markers</string>
|
||||
<string name="sb_markers_summary">Mark the segments on the time bar.</string>
|
||||
<string name="livestreams">Livestreams</string>
|
||||
|
||||
<!-- Notification channel strings -->
|
||||
<string name="download_channel_name">Download Service</string>
|
||||
|
@ -179,4 +179,13 @@
|
||||
<item name="animationMode">slide</item>
|
||||
</style>
|
||||
|
||||
<style name="channelChip" parent="@style/Widget.Material3.Chip.Filter.Elevated">
|
||||
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:visibility">gone</item>
|
||||
|
||||
</style>
|
||||
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user