mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-27 23:40:33 +05:30
198 lines
7.8 KiB
Kotlin
198 lines
7.8 KiB
Kotlin
package com.github.libretube.adapters
|
|
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import androidx.fragment.app.FragmentManager
|
|
import androidx.recyclerview.widget.RecyclerView
|
|
import com.github.libretube.R
|
|
import com.github.libretube.databinding.ChannelRowBinding
|
|
import com.github.libretube.databinding.PlaylistSearchRowBinding
|
|
import com.github.libretube.databinding.VideoRowBinding
|
|
import com.github.libretube.dialogs.PlaylistOptionsDialog
|
|
import com.github.libretube.dialogs.VideoOptionsDialog
|
|
import com.github.libretube.extensions.setFormattedDuration
|
|
import com.github.libretube.obj.SearchItem
|
|
import com.github.libretube.util.ConnectionHelper
|
|
import com.github.libretube.util.NavigationHelper
|
|
import com.github.libretube.util.SubscriptionHelper
|
|
import com.github.libretube.util.formatShort
|
|
import com.github.libretube.util.setWatchProgressLength
|
|
import com.github.libretube.util.toID
|
|
import kotlinx.coroutines.CoroutineScope
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.launch
|
|
|
|
class SearchAdapter(
|
|
private val searchItems: MutableList<SearchItem>,
|
|
private val childFragmentManager: FragmentManager
|
|
) :
|
|
RecyclerView.Adapter<SearchViewHolder>() {
|
|
|
|
fun updateItems(newItems: List<SearchItem>) {
|
|
val searchItemsSize = searchItems.size
|
|
searchItems.addAll(newItems)
|
|
notifyItemRangeInserted(searchItemsSize, newItems.size)
|
|
}
|
|
|
|
override fun getItemCount(): Int {
|
|
return searchItems.size
|
|
}
|
|
|
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchViewHolder {
|
|
val layoutInflater = LayoutInflater.from(parent.context)
|
|
|
|
return when (viewType) {
|
|
0 -> SearchViewHolder(
|
|
VideoRowBinding.inflate(layoutInflater, parent, false)
|
|
)
|
|
1 -> SearchViewHolder(
|
|
ChannelRowBinding.inflate(layoutInflater, parent, false)
|
|
)
|
|
2 -> SearchViewHolder(
|
|
PlaylistSearchRowBinding.inflate(layoutInflater, parent, false)
|
|
)
|
|
else -> throw IllegalArgumentException("Invalid type")
|
|
}
|
|
}
|
|
|
|
override fun onBindViewHolder(holder: SearchViewHolder, position: Int) {
|
|
val searchItem = searchItems[position]
|
|
|
|
val videoRowBinding = holder.videoRowBinding
|
|
val channelRowBinding = holder.channelRowBinding
|
|
val playlistRowBinding = holder.playlistRowBinding
|
|
|
|
if (videoRowBinding != null) bindWatch(searchItem, videoRowBinding)
|
|
else if (channelRowBinding != null) bindChannel(searchItem, channelRowBinding)
|
|
else if (playlistRowBinding != null) bindPlaylist(searchItem, playlistRowBinding)
|
|
}
|
|
|
|
override fun getItemViewType(position: Int): Int {
|
|
return when {
|
|
searchItems[position].url!!.startsWith("/watch", false) -> 0
|
|
searchItems[position].url!!.startsWith("/channel", false) -> 1
|
|
searchItems[position].url!!.startsWith("/playlist", false) -> 2
|
|
else -> 3
|
|
}
|
|
}
|
|
|
|
private fun bindWatch(item: SearchItem, binding: VideoRowBinding) {
|
|
binding.apply {
|
|
ConnectionHelper.loadImage(item.thumbnail, thumbnail)
|
|
thumbnailDuration.setFormattedDuration(item.duration!!)
|
|
ConnectionHelper.loadImage(item.uploaderAvatar, channelImage)
|
|
videoTitle.text = item.title
|
|
val viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else ""
|
|
val uploadDate = if (item.uploadedDate != null) item.uploadedDate else ""
|
|
videoInfo.text =
|
|
if (viewsString != "" && uploadDate != "") {
|
|
"$viewsString • $uploadDate"
|
|
} else {
|
|
viewsString + uploadDate
|
|
}
|
|
channelName.text = item.uploaderName
|
|
root.setOnClickListener {
|
|
NavigationHelper.navigateVideo(root.context, item.url)
|
|
}
|
|
val videoId = item.url.toID()
|
|
root.setOnLongClickListener {
|
|
VideoOptionsDialog(videoId)
|
|
.show(childFragmentManager, VideoOptionsDialog::class.java.name)
|
|
true
|
|
}
|
|
channelImage.setOnClickListener {
|
|
NavigationHelper.navigateChannel(root.context, item.uploaderUrl)
|
|
}
|
|
watchProgress.setWatchProgressLength(videoId, item.duration!!)
|
|
}
|
|
}
|
|
|
|
private fun bindChannel(item: SearchItem, binding: ChannelRowBinding) {
|
|
binding.apply {
|
|
ConnectionHelper.loadImage(item.thumbnail, searchChannelImage)
|
|
searchChannelName.text = item.name
|
|
searchViews.text = root.context.getString(
|
|
R.string.subscribers,
|
|
item.subscribers.formatShort()
|
|
) + " • " + root.context.getString(R.string.videoCount, item.videos.toString())
|
|
root.setOnClickListener {
|
|
NavigationHelper.navigateChannel(root.context, item.url)
|
|
}
|
|
val channelId = item.url.toID()
|
|
|
|
isSubscribed(channelId, binding)
|
|
}
|
|
}
|
|
|
|
private fun isSubscribed(channelId: String, binding: ChannelRowBinding) {
|
|
// check whether the user subscribed to the channel
|
|
CoroutineScope(Dispatchers.Main).launch {
|
|
var isSubscribed = SubscriptionHelper.isSubscribed(channelId)
|
|
|
|
// if subscribed change text to unsubscribe
|
|
if (isSubscribed == true) {
|
|
binding.searchSubButton.text = binding.root.context.getString(R.string.unsubscribe)
|
|
}
|
|
|
|
// make sub button visible and set the on click listeners to (un)subscribe
|
|
if (isSubscribed == null) return@launch
|
|
binding.searchSubButton.visibility = View.VISIBLE
|
|
|
|
binding.searchSubButton.setOnClickListener {
|
|
if (isSubscribed == false) {
|
|
SubscriptionHelper.subscribe(channelId)
|
|
binding.searchSubButton.text =
|
|
binding.root.context.getString(R.string.unsubscribe)
|
|
isSubscribed = true
|
|
} else {
|
|
SubscriptionHelper.unsubscribe(channelId)
|
|
binding.searchSubButton.text =
|
|
binding.root.context.getString(R.string.subscribe)
|
|
isSubscribed = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun bindPlaylist(item: SearchItem, binding: PlaylistSearchRowBinding) {
|
|
binding.apply {
|
|
ConnectionHelper.loadImage(item.thumbnail, searchThumbnail)
|
|
if (item.videos?.toInt() != -1) searchPlaylistNumber.text = item.videos.toString()
|
|
searchDescription.text = item.name
|
|
searchName.text = item.uploaderName
|
|
if (item.videos?.toInt() != -1) {
|
|
searchPlaylistVideos.text =
|
|
root.context.getString(R.string.videoCount, item.videos.toString())
|
|
}
|
|
root.setOnClickListener {
|
|
NavigationHelper.navigatePlaylist(root.context, item.url, false)
|
|
}
|
|
root.setOnLongClickListener {
|
|
val playlistId = item.url!!.toID()
|
|
PlaylistOptionsDialog(playlistId, false)
|
|
.show(childFragmentManager, PlaylistOptionsDialog::class.java.name)
|
|
true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class SearchViewHolder : RecyclerView.ViewHolder {
|
|
var videoRowBinding: VideoRowBinding? = null
|
|
var channelRowBinding: ChannelRowBinding? = null
|
|
var playlistRowBinding: PlaylistSearchRowBinding? = null
|
|
|
|
constructor(binding: VideoRowBinding) : super(binding.root) {
|
|
videoRowBinding = binding
|
|
}
|
|
|
|
constructor(binding: ChannelRowBinding) : super(binding.root) {
|
|
channelRowBinding = binding
|
|
}
|
|
|
|
constructor(binding: PlaylistSearchRowBinding) : super(binding.root) {
|
|
playlistRowBinding = binding
|
|
}
|
|
}
|