Skip to content

Commit 77515bf

Browse files
committed
refactor: split video and trending layout into different adapters
1 parent ca56ab6 commit 77515bf

10 files changed

Lines changed: 158 additions & 138 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.github.libretube.ui.adapters
2+
3+
import android.annotation.SuppressLint
4+
import android.view.LayoutInflater
5+
import android.view.ViewGroup
6+
import androidx.core.os.bundleOf
7+
import androidx.core.view.updateLayoutParams
8+
import androidx.recyclerview.widget.ListAdapter
9+
import com.github.libretube.api.obj.StreamItem
10+
import com.github.libretube.constants.IntentData
11+
import com.github.libretube.databinding.AllCaughtUpRowBinding
12+
import com.github.libretube.databinding.TrendingRowBinding
13+
import com.github.libretube.extensions.dpToPx
14+
import com.github.libretube.extensions.toID
15+
import com.github.libretube.helpers.ImageHelper
16+
import com.github.libretube.helpers.NavigationHelper
17+
import com.github.libretube.ui.adapters.callbacks.DiffUtilItemCallback
18+
import com.github.libretube.ui.base.BaseActivity
19+
import com.github.libretube.ui.extensions.setFormattedDuration
20+
import com.github.libretube.ui.extensions.setWatchProgressLength
21+
import com.github.libretube.ui.sheets.VideoOptionsBottomSheet
22+
import com.github.libretube.ui.viewholders.VideoCardsViewHolder
23+
import com.github.libretube.util.TextUtils
24+
25+
class VideoCardsAdapter(private val columnWidthDp: Float? = null) :
26+
ListAdapter<StreamItem, VideoCardsViewHolder>(DiffUtilItemCallback()) {
27+
28+
override fun getItemViewType(position: Int): Int {
29+
return if (currentList[position].type == CAUGHT_UP_STREAM_TYPE) CAUGHT_UP_TYPE else NORMAL_TYPE
30+
}
31+
32+
fun removeItemById(videoId: String) {
33+
val index = currentList.indexOfFirst {
34+
it.url?.toID() == videoId
35+
}.takeIf { it > 0 } ?: return
36+
val updatedList = currentList.toMutableList().also {
37+
it.removeAt(index)
38+
}
39+
40+
submitList(updatedList)
41+
}
42+
43+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideoCardsViewHolder {
44+
val layoutInflater = LayoutInflater.from(parent.context)
45+
return when {
46+
viewType == CAUGHT_UP_TYPE -> VideoCardsViewHolder(
47+
AllCaughtUpRowBinding.inflate(layoutInflater, parent, false)
48+
)
49+
50+
else -> VideoCardsViewHolder(
51+
TrendingRowBinding.inflate(layoutInflater, parent, false)
52+
)
53+
}
54+
}
55+
56+
@SuppressLint("SetTextI18n")
57+
override fun onBindViewHolder(holder: VideoCardsViewHolder, position: Int) {
58+
val video = getItem(holder.bindingAdapterPosition)
59+
val videoId = video.url.orEmpty().toID()
60+
61+
val context = (holder.trendingRowBinding ?: holder.allCaughtUpBinding)!!.root.context
62+
val activity = (context as BaseActivity)
63+
val fragmentManager = activity.supportFragmentManager
64+
65+
holder.trendingRowBinding?.apply {
66+
// set a fixed width for better visuals
67+
if (columnWidthDp != null) {
68+
root.updateLayoutParams {
69+
width = columnWidthDp.dpToPx()
70+
}
71+
}
72+
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
73+
74+
textViewTitle.text = video.title
75+
textViewChannel.text = TextUtils.formatViewsString(
76+
root.context,
77+
video.views ?: -1,
78+
video.uploaded,
79+
video.uploaderName
80+
)
81+
82+
video.duration?.let {
83+
thumbnailDuration.setFormattedDuration(
84+
it,
85+
video.isShort,
86+
video.uploaded
87+
)
88+
}
89+
channelImage.setOnClickListener {
90+
NavigationHelper.navigateChannel(root.context, video.uploaderUrl)
91+
}
92+
ImageHelper.loadImage(video.thumbnail, thumbnail)
93+
ImageHelper.loadImage(video.uploaderAvatar, channelImage, true)
94+
root.setOnClickListener {
95+
NavigationHelper.navigateVideo(root.context, videoId)
96+
}
97+
98+
root.setOnLongClickListener {
99+
fragmentManager.setFragmentResultListener(
100+
VideoOptionsBottomSheet.VIDEO_OPTIONS_SHEET_REQUEST_KEY,
101+
activity
102+
) { _, _ ->
103+
notifyItemChanged(position)
104+
}
105+
val sheet = VideoOptionsBottomSheet()
106+
sheet.arguments = bundleOf(IntentData.streamItem to video)
107+
sheet.show(fragmentManager, VideoCardsAdapter::class.java.name)
108+
true
109+
}
110+
}
111+
}
112+
113+
companion object {
114+
private const val NORMAL_TYPE = 0
115+
private const val CAUGHT_UP_TYPE = 1
116+
117+
const val CAUGHT_UP_STREAM_TYPE = "caught"
118+
}
119+
}

app/src/main/java/com/github/libretube/ui/adapters/VideosAdapter.kt

Lines changed: 6 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,11 @@ import android.view.ViewGroup
66
import androidx.core.os.bundleOf
77
import androidx.core.view.isGone
88
import androidx.core.view.isVisible
9-
import androidx.core.view.updateLayoutParams
109
import androidx.recyclerview.widget.ListAdapter
1110
import com.github.libretube.api.obj.StreamItem
1211
import com.github.libretube.constants.IntentData
13-
import com.github.libretube.databinding.AllCaughtUpRowBinding
14-
import com.github.libretube.databinding.TrendingRowBinding
1512
import com.github.libretube.databinding.VideoRowBinding
1613
import com.github.libretube.db.DatabaseHolder
17-
import com.github.libretube.extensions.dpToPx
1814
import com.github.libretube.extensions.toID
1915
import com.github.libretube.helpers.ImageHelper
2016
import com.github.libretube.helpers.NavigationHelper
@@ -31,13 +27,9 @@ import kotlinx.coroutines.launch
3127
import kotlinx.coroutines.withContext
3228

3329
class VideosAdapter(
34-
private val forceMode: LayoutMode = LayoutMode.RESPECT_PREF
30+
private val showChannelInfo: Boolean = true
3531
) : ListAdapter<StreamItem, VideosViewHolder>(DiffUtilItemCallback()) {
3632

37-
override fun getItemViewType(position: Int): Int {
38-
return if (currentList[position].type == CAUGHT_UP_STREAM_TYPE) CAUGHT_UP_TYPE else NORMAL_TYPE
39-
}
40-
4133
fun insertItems(newItems: List<StreamItem>) {
4234
val updatedList = currentList.toMutableList().also {
4335
it.addAll(newItems)
@@ -46,97 +38,30 @@ class VideosAdapter(
4638
submitList(updatedList)
4739
}
4840

49-
fun removeItemById(videoId: String) {
50-
val index = currentList.indexOfFirst {
51-
it.url?.toID() == videoId
52-
}.takeIf { it > 0 } ?: return
53-
val updatedList = currentList.toMutableList().also {
54-
it.removeAt(index)
55-
}
56-
57-
submitList(updatedList)
58-
}
59-
6041
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideosViewHolder {
6142
val layoutInflater = LayoutInflater.from(parent.context)
62-
return when {
63-
viewType == CAUGHT_UP_TYPE -> VideosViewHolder(
64-
AllCaughtUpRowBinding.inflate(layoutInflater, parent, false)
65-
)
66-
67-
forceMode in listOf(
68-
LayoutMode.TRENDING_ROW,
69-
LayoutMode.RELATED_COLUMN
70-
) -> VideosViewHolder(
71-
TrendingRowBinding.inflate(layoutInflater, parent, false)
72-
)
73-
74-
forceMode == LayoutMode.CHANNEL_ROW -> VideosViewHolder(
75-
VideoRowBinding.inflate(layoutInflater, parent, false)
76-
)
77-
78-
else -> VideosViewHolder(TrendingRowBinding.inflate(layoutInflater, parent, false))
79-
}
43+
val binding = VideoRowBinding.inflate(layoutInflater, parent, false)
44+
return VideosViewHolder(binding)
8045
}
8146

8247
@SuppressLint("SetTextI18n")
8348
override fun onBindViewHolder(holder: VideosViewHolder, position: Int) {
8449
val video = getItem(holder.bindingAdapterPosition)
8550
val videoId = video.url.orEmpty().toID()
8651

87-
val context = (
88-
holder.videoRowBinding ?: holder.trendingRowBinding ?: holder.allCaughtUpBinding
89-
)!!.root.context
52+
val context = holder.binding.root.context
9053
val activity = (context as BaseActivity)
9154
val fragmentManager = activity.supportFragmentManager
9255

93-
// Trending layout
94-
holder.trendingRowBinding?.apply {
95-
// set a fixed width for better visuals
96-
if (forceMode == LayoutMode.RELATED_COLUMN) {
97-
root.updateLayoutParams {
98-
width = 250f.dpToPx()
99-
}
100-
}
101-
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
102-
103-
textViewTitle.text = video.title
104-
textViewChannel.text = TextUtils.formatViewsString(root.context, video.views ?: -1, video.uploaded, video.uploaderName)
105-
106-
video.duration?.let { thumbnailDuration.setFormattedDuration(it, video.isShort, video.uploaded) }
107-
channelImage.setOnClickListener {
108-
NavigationHelper.navigateChannel(root.context, video.uploaderUrl)
109-
}
110-
ImageHelper.loadImage(video.thumbnail, thumbnail)
111-
ImageHelper.loadImage(video.uploaderAvatar, channelImage, true)
112-
root.setOnClickListener {
113-
NavigationHelper.navigateVideo(root.context, videoId)
114-
}
115-
116-
root.setOnLongClickListener {
117-
fragmentManager.setFragmentResultListener(
118-
VideoOptionsBottomSheet.VIDEO_OPTIONS_SHEET_REQUEST_KEY,
119-
activity
120-
) { _, _ ->
121-
notifyItemChanged(position)
122-
}
123-
val sheet = VideoOptionsBottomSheet()
124-
sheet.arguments = bundleOf(IntentData.streamItem to video)
125-
sheet.show(fragmentManager, VideosAdapter::class.java.name)
126-
true
127-
}
128-
}
129-
130-
// Normal videos row layout
131-
holder.videoRowBinding?.apply {
56+
with(holder.binding) {
13257
videoTitle.text = video.title
13358
videoInfo.text = TextUtils.formatViewsString(root.context, video.views ?: -1, video.uploaded)
13459

13560
video.duration?.let { thumbnailDuration.setFormattedDuration(it, video.isShort, video.uploaded) }
13661
watchProgress.setWatchProgressLength(videoId, video.duration ?: 0L)
13762
ImageHelper.loadImage(video.thumbnail, thumbnail)
13863

139-
if (forceMode != LayoutMode.CHANNEL_ROW) {
64+
if (showChannelInfo) {
14065
ImageHelper.loadImage(video.uploaderAvatar, channelImage, true)
14166
channelName.text = video.uploaderName
14267

@@ -174,19 +99,4 @@ class VideosAdapter(
17499
}
175100
}
176101
}
177-
178-
companion object {
179-
enum class LayoutMode {
180-
RESPECT_PREF,
181-
TRENDING_ROW,
182-
VIDEO_ROW,
183-
CHANNEL_ROW,
184-
RELATED_COLUMN
185-
}
186-
187-
private const val NORMAL_TYPE = 0
188-
private const val CAUGHT_UP_TYPE = 1
189-
190-
const val CAUGHT_UP_STREAM_TYPE = "caught"
191-
}
192102
}

app/src/main/java/com/github/libretube/ui/fragments/ChannelContentFragment.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ class ChannelContentFragment : DynamicLayoutManagerFragment(R.layout.fragment_ch
6060
var nextPage = arguments.getString(IntentData.nextPage)
6161
var isLoading = false
6262

63-
val channelAdapter = VideosAdapter(
64-
forceMode = VideosAdapter.Companion.LayoutMode.CHANNEL_ROW
65-
).also {
63+
val channelAdapter = VideosAdapter(showChannelInfo = false).also {
6664
it.submitList(arguments.parcelableArrayList<StreamItem>(IntentData.videoList)!!)
6765
}
6866
binding.channelRecView.adapter = channelAdapter

app/src/main/java/com/github/libretube/ui/fragments/ChannelFragment.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,7 @@ class ChannelFragment : Fragment(R.layout.fragment_channel) {
234234
tab.text = tabList[position].name
235235
}.attach()
236236

237-
channelAdapter = VideosAdapter(
238-
forceMode = VideosAdapter.Companion.LayoutMode.CHANNEL_ROW
239-
).also {
237+
channelAdapter = VideosAdapter(showChannelInfo = false).also {
240238
it.submitList(response.relatedStreams)
241239
}
242240
tabList.clear()

app/src/main/java/com/github/libretube/ui/fragments/HomeFragment.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ import com.github.libretube.helpers.PreferenceHelper
2323
import com.github.libretube.ui.activities.SettingsActivity
2424
import com.github.libretube.ui.adapters.PlaylistBookmarkAdapter
2525
import com.github.libretube.ui.adapters.PlaylistsAdapter
26-
import com.github.libretube.ui.adapters.VideosAdapter
27-
import com.github.libretube.ui.adapters.VideosAdapter.Companion.LayoutMode
26+
import com.github.libretube.ui.adapters.VideoCardsAdapter
2827
import com.github.libretube.ui.extensions.setupFragmentAnimation
2928
import com.github.libretube.ui.models.HomeViewModel
3029
import com.github.libretube.ui.models.SubscriptionsViewModel
@@ -38,9 +37,9 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
3837
private val subscriptionsViewModel: SubscriptionsViewModel by activityViewModels()
3938
private val homeViewModel: HomeViewModel by activityViewModels()
4039

41-
private val trendingAdapter = VideosAdapter(forceMode = LayoutMode.TRENDING_ROW)
42-
private val feedAdapter = VideosAdapter(forceMode = LayoutMode.RELATED_COLUMN)
43-
private val watchingAdapter = VideosAdapter(forceMode = LayoutMode.RELATED_COLUMN)
40+
private val trendingAdapter = VideoCardsAdapter()
41+
private val feedAdapter = VideoCardsAdapter(columnWidthDp = 250f)
42+
private val watchingAdapter = VideoCardsAdapter(columnWidthDp = 250f)
4443
private val bookmarkAdapter = PlaylistBookmarkAdapter(PlaylistBookmarkAdapter.Companion.BookmarkMode.HOME)
4544
private val playlistAdapter = PlaylistsAdapter(playlistType = PlaylistsHelper.getPrivatePlaylistType())
4645

app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ import com.github.libretube.parcelable.PlayerData
8989
import com.github.libretube.services.AbstractPlayerService
9090
import com.github.libretube.services.OnlinePlayerService
9191
import com.github.libretube.ui.activities.MainActivity
92-
import com.github.libretube.ui.adapters.VideosAdapter
92+
import com.github.libretube.ui.adapters.VideoCardsAdapter
9393
import com.github.libretube.ui.base.BaseActivity
9494
import com.github.libretube.ui.dialogs.AddToPlaylistDialog
9595
import com.github.libretube.ui.dialogs.PlayOfflineDialog
@@ -1127,12 +1127,8 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
11271127

11281128
if (PlayerHelper.relatedStreamsEnabled) {
11291129
val relatedLayoutManager = binding.relatedRecView.layoutManager as LinearLayoutManager
1130-
binding.relatedRecView.adapter = VideosAdapter(
1131-
forceMode = if (relatedLayoutManager.orientation == LinearLayoutManager.HORIZONTAL) {
1132-
VideosAdapter.Companion.LayoutMode.RELATED_COLUMN
1133-
} else {
1134-
VideosAdapter.Companion.LayoutMode.TRENDING_ROW
1135-
}
1130+
binding.relatedRecView.adapter = VideoCardsAdapter(
1131+
columnWidthDp = if (relatedLayoutManager.orientation == LinearLayoutManager.HORIZONTAL) 250f else null
11361132
).also { adapter ->
11371133
adapter.submitList(streams.relatedStreams.filter { !it.title.isNullOrBlank() })
11381134
}

app/src/main/java/com/github/libretube/ui/fragments/SubscriptionsFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import com.github.libretube.helpers.PreferenceHelper
3232
import com.github.libretube.obj.SelectableOption
3333
import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
3434
import com.github.libretube.ui.adapters.SubscriptionChannelAdapter
35-
import com.github.libretube.ui.adapters.VideosAdapter
35+
import com.github.libretube.ui.adapters.VideoCardsAdapter
3636
import com.github.libretube.ui.base.DynamicLayoutManagerFragment
3737
import com.github.libretube.ui.extensions.addOnBottomReachedListener
3838
import com.github.libretube.ui.extensions.setupFragmentAnimation
@@ -62,7 +62,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
6262

6363
private var isAppBarFullyExpanded = true
6464

65-
private var feedAdapter = VideosAdapter()
65+
private var feedAdapter = VideoCardsAdapter()
6666
private var selectedSortOrder = PreferenceHelper.getInt(PreferenceKeys.FEED_SORT_ORDER, 0)
6767
set(value) {
6868
PreferenceHelper.putInt(PreferenceKeys.FEED_SORT_ORDER, value)
@@ -393,7 +393,7 @@ class SubscriptionsFragment : DynamicLayoutManagerFragment(R.layout.fragment_sub
393393
if (caughtUpIndex > 0 && !feed[caughtUpIndex-1].isUpcoming) {
394394
sorted.add(
395395
caughtUpIndex,
396-
StreamItem(type = VideosAdapter.CAUGHT_UP_STREAM_TYPE)
396+
StreamItem(type = VideoCardsAdapter.CAUGHT_UP_STREAM_TYPE)
397397
)
398398
}
399399
}

app/src/main/java/com/github/libretube/ui/fragments/TrendsFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.github.libretube.R
1212
import com.github.libretube.databinding.FragmentTrendsBinding
1313
import com.github.libretube.helpers.NavBarHelper
1414
import com.github.libretube.ui.activities.SettingsActivity
15-
import com.github.libretube.ui.adapters.VideosAdapter
15+
import com.github.libretube.ui.adapters.VideoCardsAdapter
1616
import com.github.libretube.ui.base.DynamicLayoutManagerFragment
1717
import com.github.libretube.ui.extensions.setupFragmentAnimation
1818
import com.github.libretube.ui.models.TrendsViewModel
@@ -31,7 +31,7 @@ class TrendsFragment : DynamicLayoutManagerFragment(R.layout.fragment_trends) {
3131
_binding = FragmentTrendsBinding.bind(view)
3232
super.onViewCreated(view, savedInstanceState)
3333

34-
val adapter = VideosAdapter()
34+
val adapter = VideoCardsAdapter()
3535
binding.recview.adapter = adapter
3636
binding.recview.layoutManager?.onRestoreInstanceState(viewModel.recyclerViewState)
3737

0 commit comments

Comments
 (0)