@@ -4,44 +4,35 @@ import android.annotation.SuppressLint
44import android.content.res.Configuration
55import android.os.Bundle
66import android.view.View
7- import android.view.ViewGroup.MarginLayoutParams
87import androidx.core.os.bundleOf
98import androidx.core.view.children
109import androidx.core.view.isGone
1110import androidx.core.view.isVisible
12- import androidx.core.view.updateLayoutParams
1311import androidx.fragment.app.activityViewModels
1412import androidx.lifecycle.lifecycleScope
1513import androidx.recyclerview.widget.GridLayoutManager
16- import androidx.recyclerview.widget.LinearLayoutManager
1714import androidx.recyclerview.widget.RecyclerView
1815import com.github.libretube.R
1916import com.github.libretube.api.obj.StreamItem
20- import com.github.libretube.api.obj.Subscription
2117import com.github.libretube.constants.IntentData
2218import com.github.libretube.constants.PreferenceKeys
2319import com.github.libretube.databinding.FragmentSubscriptionsBinding
2420import com.github.libretube.db.DatabaseHelper
2521import com.github.libretube.db.DatabaseHolder
26- import com.github.libretube.extensions.dpToPx
27- import com.github.libretube.extensions.formatShort
2822import com.github.libretube.extensions.toID
2923import com.github.libretube.helpers.NavBarHelper
3024import com.github.libretube.helpers.NavigationHelper
3125import com.github.libretube.helpers.PreferenceHelper
3226import com.github.libretube.obj.SelectableOption
33- import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
34- import com.github.libretube.ui.adapters.SubscriptionChannelAdapter
3527import com.github.libretube.ui.adapters.VideoCardsAdapter
3628import com.github.libretube.ui.base.DynamicLayoutManagerFragment
37- import com.github.libretube.ui.extensions.addOnBottomReachedListener
3829import com.github.libretube.ui.extensions.setupFragmentAnimation
39- import com.github.libretube.ui.models.CommonPlayerViewModel
4030import com.github.libretube.ui.models.EditChannelGroupsModel
4131import com.github.libretube.ui.models.SubscriptionsViewModel
4232import com.github.libretube.ui.sheets.ChannelGroupsSheet
4333import com.github.libretube.ui.sheets.FilterSortBottomSheet
4434import com.github.libretube.ui.sheets.FilterSortBottomSheet.Companion.FILTER_SORT_REQUEST_KEY
35+ import com.github.libretube.ui.sheets.SubscriptionsBottomSheet
4536import com.github.libretube.util.PlayingQueue
4637import com.google.android.material.chip.Chip
4738import kotlinx.coroutines.Dispatchers
@@ -52,7 +43,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
5243 private val binding get() = _binding !!
5344
5445 private val viewModel: SubscriptionsViewModel by activityViewModels()
55- private val playerModel: CommonPlayerViewModel by activityViewModels()
5646 private val channelGroupsModel: EditChannelGroupsModel by activityViewModels()
5747 private var selectedFilterGroup
5848 set(value) = PreferenceHelper .putInt(PreferenceKeys .SELECTED_CHANNEL_GROUP , value)
@@ -81,9 +71,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
8171 field = value
8272 }
8373
84- private val legacySubscriptionsAdapter = LegacySubscriptionAdapter ()
85- private val channelsAdapter = SubscriptionChannelAdapter ()
86-
8774 override fun setLayoutManagers (gridItems : Int ) {
8875 _binding ?.subFeed?.layoutManager = GridLayoutManager (context, gridItems)
8976 }
@@ -97,25 +84,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
9784
9885 binding.subFeed.adapter = feedAdapter
9986
100- val legacySubscriptions = PreferenceHelper .getBoolean(
101- PreferenceKeys .LEGACY_SUBSCRIPTIONS ,
102- false
103- )
104-
105- if (legacySubscriptions) {
106- binding.subChannels.layoutManager = GridLayoutManager (
107- context,
108- PreferenceHelper .getString(
109- PreferenceKeys .LEGACY_SUBSCRIPTIONS_COLUMNS ,
110- " 3"
111- ).toInt()
112- )
113- binding.subChannels.adapter = legacySubscriptionsAdapter
114- } else {
115- binding.subChannels.layoutManager = LinearLayoutManager (context)
116- binding.subChannels.adapter = channelsAdapter
117- }
118-
11987 // Check if the AppBarLayout is fully expanded
12088 binding.subscriptionsAppBar.addOnOffsetChangedListener { _, verticalOffset ->
12189 isAppBarFullyExpanded = verticalOffset == 0
@@ -141,7 +109,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
141109 // position to zero
142110 var alreadyShowedFeedOnce = false
143111 viewModel.videoFeed.observe(viewLifecycleOwner) { feed ->
144- if (! viewModel.isCurrentTabSubChannels && feed != null ) {
112+ if (feed != null ) {
145113 lifecycleScope.launch {
146114 showFeed(! alreadyShowedFeedOnce)
147115 }
@@ -153,15 +121,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
153121 }
154122 }
155123
156- // restore the scroll position, same conditions as above
157- var alreadyShowedSubscriptionsOnce = false
158- viewModel.subscriptions.observe(viewLifecycleOwner) {
159- if (viewModel.isCurrentTabSubChannels && it != null ) {
160- showSubscriptions(! alreadyShowedSubscriptionsOnce)
161- alreadyShowedSubscriptionsOnce = true
162- }
163- }
164-
165124 viewModel.feedProgress.observe(viewLifecycleOwner) { progress ->
166125 if (progress == null || progress.currentProgress == progress.total) {
167126 binding.feedProgressContainer.isGone = true
@@ -181,40 +140,15 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
181140 binding.toggleSubs.isVisible = true
182141
183142 binding.toggleSubs.setOnClickListener {
184- binding.subProgress.isVisible = true
185- binding.subRefresh.isRefreshing = true
186- viewModel.isCurrentTabSubChannels = ! viewModel.isCurrentTabSubChannels
187-
188- lifecycleScope.launch {
189- if (viewModel.isCurrentTabSubChannels) showSubscriptions() else showFeed()
190- }
191-
192- binding.subChannels.isVisible = viewModel.isCurrentTabSubChannels
193- binding.subFeed.isGone = viewModel.isCurrentTabSubChannels
194- }
195-
196- binding.subChannels.addOnBottomReachedListener {
197- val binding = _binding ? : return @addOnBottomReachedListener
198-
199- if (viewModel.subscriptions.value != null && viewModel.isCurrentTabSubChannels) {
200- binding.subRefresh.isRefreshing = true
201- binding.subRefresh.isRefreshing = false
202- }
203- }
204-
205- // add some extra margin to the subscribed channels while the mini player is visible
206- // otherwise the last channel would be invisible
207- playerModel.isMiniPlayerVisible.observe(viewLifecycleOwner) {
208- binding.subChannels.updateLayoutParams<MarginLayoutParams > {
209- bottomMargin = (if (it) 64f else 0f ).dpToPx()
210- }
143+ SubscriptionsBottomSheet ()
144+ .show(childFragmentManager)
211145 }
212146
213147 binding.channelGroups.setOnCheckedStateChangeListener { group, _ ->
214148 selectedFilterGroup = group.children.indexOfFirst { it.id == group.checkedChipId }
215149
216150 lifecycleScope.launch {
217- if (viewModel.isCurrentTabSubChannels) showSubscriptions() else showFeed()
151+ showFeed()
218152 }
219153 }
220154
@@ -226,17 +160,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
226160 ChannelGroupsSheet ().show(childFragmentManager, null )
227161 }
228162
229- // manually restore the recyclerview state due to https://github.com/material-components/material-components-android/issues/3473
230- binding.subChannels.addOnScrollListener(object : RecyclerView .OnScrollListener () {
231- override fun onScrollStateChanged (recyclerView : RecyclerView , newState : Int ) {
232- super .onScrollStateChanged(recyclerView, newState)
233- viewModel.subChannelsRecyclerViewState =
234- binding.subChannels.layoutManager?.onSaveInstanceState()?.takeIf {
235- binding.subChannels.computeVerticalScrollOffset() != 0
236- }
237- }
238- })
239-
240163 binding.subFeed.addOnScrollListener(object : RecyclerView .OnScrollListener () {
241164 override fun onScrollStateChanged (recyclerView : RecyclerView , newState : Int ) {
242165 super .onScrollStateChanged(recyclerView, newState)
@@ -353,14 +276,6 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
353276 }
354277 }
355278
356- @JvmName(" filterSubsByGroup" )
357- private fun List<Subscription>.filterByGroup (groupIndex : Int ): List <Subscription > {
358- if (groupIndex == 0 ) return this
359-
360- val group = channelGroupsModel.groups.value?.getOrNull(groupIndex - 1 )
361- return filter { group?.channels?.contains(it.url.toID()) != false }
362- }
363-
364279 private fun List<StreamItem>.sortedBySelectedOrder () = when (selectedSortOrder) {
365280 0 -> this
366281 1 -> this .reversed()
@@ -399,7 +314,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
399314 }
400315 }
401316
402- binding.subChannels.isGone = true
317+
403318 binding.subProgress.isGone = true
404319
405320 val notLoaded = viewModel.videoFeed.value.isNullOrEmpty()
@@ -421,42 +336,9 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
421336 }
422337 }
423338
424- @SuppressLint(" SetTextI18n" )
425- private fun showSubscriptions (restoreScrollState : Boolean = true) {
426- val subscriptions =
427- viewModel.subscriptions.value?.filterByGroup(selectedFilterGroup) ? : return
428-
429- val legacySubscriptions = PreferenceHelper .getBoolean(
430- PreferenceKeys .LEGACY_SUBSCRIPTIONS ,
431- false
432- )
433-
434- val adapter = if (legacySubscriptions) legacySubscriptionsAdapter else channelsAdapter
435- adapter.submitList(subscriptions) {
436- if (restoreScrollState) {
437- binding.subFeed.layoutManager?.onRestoreInstanceState(viewModel.subChannelsRecyclerViewState)
438- binding.subscriptionsAppBar.setExpanded(viewModel.subChannelsRecyclerViewState == null )
439- } else {
440- binding.subFeed.scrollToPosition(0 )
441- }
442- }
443-
444- binding.subRefresh.isRefreshing = false
445- binding.subProgress.isGone = true
446- binding.subFeed.isGone = true
447-
448- val notLoaded = viewModel.subscriptions.value.isNullOrEmpty()
449- binding.subChannels.isGone = notLoaded
450- binding.emptyFeed.isVisible = notLoaded
451-
452- val subCount = subscriptions.size.toLong().formatShort()
453- binding.toggleSubs.text = " ${getString(R .string.subscriptions)} ($subCount )"
454- }
455-
456339 override fun onConfigurationChanged (newConfig : Configuration ) {
457340 super .onConfigurationChanged(newConfig)
458341 // manually restore the recyclerview state after rotation due to https://github.com/material-components/material-components-android/issues/3473
459- binding.subChannels.layoutManager?.onRestoreInstanceState(viewModel.subChannelsRecyclerViewState)
460342 binding.subFeed.layoutManager?.onRestoreInstanceState(viewModel.subFeedRecyclerViewState)
461343 }
462344
0 commit comments