feat: parse YouTube links in the search bar

This commit is contained in:
Bnyro 2023-09-19 11:26:43 +02:00
parent cd97e847d4
commit 7ae5865ba2
4 changed files with 26 additions and 10 deletions

View File

@ -30,7 +30,8 @@ import com.github.libretube.util.TextUtils
import kotlinx.serialization.encodeToString
class SearchAdapter(
private val isChannelAdapter: Boolean = false
private val isChannelAdapter: Boolean = false,
private val timeStamp: Long = 0,
) : ListAdapter<ContentItem, SearchViewHolder>(SearchCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
@ -97,7 +98,7 @@ class SearchAdapter(
ImageHelper.loadImage(item.uploaderAvatar, channelImage)
}
root.setOnClickListener {
NavigationHelper.navigateVideo(root.context, item.url)
NavigationHelper.navigateVideo(root.context, item.url, timestamp = timeStamp)
}
val videoId = item.url.toID()

View File

@ -1127,7 +1127,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
*/
private fun handleLink(link: String) {
// get video id if the link is a valid youtube video link
val videoId = TextUtils.getVideoIdFromUri(link)
val videoId = TextUtils.getVideoIdFromUrl(link)
if (videoId.isNullOrEmpty()) {
// not a YouTube video link, thus handle normally
val intent = Intent(Intent.ACTION_VIEW, link.toUri())

View File

@ -21,13 +21,18 @@ import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.obj.SearchHistoryItem
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.ui.adapters.SearchAdapter
import com.github.libretube.ui.dialogs.ShareDialog
import com.github.libretube.util.TextUtils
import com.github.libretube.util.TextUtils.toTimeInSeconds
import com.github.libretube.util.deArrow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
class SearchResultFragment : Fragment() {
private var _binding: FragmentSearchResultBinding? = null
@ -37,7 +42,7 @@ class SearchResultFragment : Fragment() {
private var query = ""
private lateinit var searchAdapter: SearchAdapter
private var apiSearchFilter = "all"
private var searchFilter = "all"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -63,7 +68,7 @@ class SearchResultFragment : Fragment() {
// filter options
binding.filterChipGroup.setOnCheckedStateChangeListener { _, _ ->
apiSearchFilter = when (
searchFilter = when (
binding.filterChipGroup.checkedChipId
) {
R.id.chip_all -> "all"
@ -95,11 +100,20 @@ class SearchResultFragment : Fragment() {
_binding?.searchResultsLayout?.isGone = true
lifecycleScope.launch {
var timeStamp: Long? = null
// parse search URLs from YouTube entered in the search bar
val searchQuery = query.toHttpUrlOrNull()?.let {
val videoId = TextUtils.getVideoIdFromUrl(it.toString()) ?: query
timeStamp = it.queryParameter("t")?.toTimeInSeconds()
"${ShareDialog.YOUTUBE_FRONTEND_URL}/watch?v=${videoId}"
} ?: query
repeatOnLifecycle(Lifecycle.State.CREATED) {
view?.let { context?.hideKeyboard(it) }
val response = try {
withContext(Dispatchers.IO) {
RetrofitInstance.api.getSearchResults(query, apiSearchFilter).apply {
RetrofitInstance.api.getSearchResults(searchQuery, searchFilter).apply {
items = items.deArrow()
}
}
@ -110,9 +124,10 @@ class SearchResultFragment : Fragment() {
}
val binding = _binding ?: return@repeatOnLifecycle
searchAdapter = SearchAdapter()
searchAdapter = SearchAdapter(timeStamp = timeStamp ?: 0)
binding.searchRecycler.adapter = searchAdapter
searchAdapter.submitList(response.items)
binding.searchResultsLayout.isVisible = true
binding.progress.isGone = true
binding.noSearchResult.isVisible = response.items.isEmpty()
@ -129,7 +144,7 @@ class SearchResultFragment : Fragment() {
withContext(Dispatchers.IO) {
RetrofitInstance.api.getSearchResultsNextPage(
query,
apiSearchFilter,
searchFilter,
nextPage!!
).apply {
items = items.deArrow()

View File

@ -52,10 +52,10 @@ object TextUtils {
/**
* Get video id if the link is a valid youtube video link
*/
fun getVideoIdFromUri(link: String): String? {
fun getVideoIdFromUrl(link: String): String? {
return link.toHttpUrlOrNull()?.let {
when (it.host) {
"www.youtube.com" -> it.queryParameter("v")
"www.youtube.com", "m.youtube.com" -> it.queryParameter("v")
"youtu.be" -> it.pathSegments.lastOrNull()
else -> null
}