mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-28 16:00:31 +05:30
Merge pull request #218 from Bnyro/filter
Search Filters, Nextpage in Search, Search History Settings
This commit is contained in:
commit
8a6ec7b30a
@ -41,7 +41,7 @@ WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OP
|
||||
| Search Suggestions | ✅ |
|
||||
| Subtitles | ✅ |
|
||||
| Comments | ✅ |
|
||||
| Search Filters | 🔴 |
|
||||
| Search Filters | ✅ |
|
||||
|
||||
|
||||
## Contributing
|
||||
|
@ -25,6 +25,13 @@ interface PipedApi {
|
||||
@Query("filter") filter: String
|
||||
): SearchResult
|
||||
|
||||
@GET("nextpage/search")
|
||||
suspend fun getSearchResultsNextPage(
|
||||
@Query("q") searchQuery: String,
|
||||
@Query("filter") filter: String,
|
||||
@Query("nextpage") nextPage: String
|
||||
): SearchResult
|
||||
|
||||
@GET("suggestions")
|
||||
suspend fun getSuggestions(@Query("query") query: String): List<String>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.github.libretube
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
@ -11,9 +12,9 @@ import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.*
|
||||
import android.widget.TextView.*
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceManager
|
||||
@ -28,9 +29,15 @@ import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
class SearchFragment : Fragment() {
|
||||
private val TAG = "SearchFragment"
|
||||
private var selectedFilter = 0
|
||||
private var apiSearchFilter = "all"
|
||||
private var nextPage : String? = null
|
||||
private lateinit var searchRecView : RecyclerView
|
||||
private var searchAdapter : SearchAdapter? = null
|
||||
private var isLoading : Boolean = true
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
@ -49,31 +56,71 @@ class SearchFragment : Fragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val recyclerView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
||||
searchRecView = view.findViewById<RecyclerView>(R.id.search_recycler)
|
||||
|
||||
val autoTextView = view.findViewById<AutoCompleteTextView>(R.id.autoCompleteTextView)
|
||||
|
||||
val historyRecycler = view.findViewById<RecyclerView>(R.id.history_recycler)
|
||||
|
||||
val filterImageView = view.findViewById<ImageView>(R.id.filterMenu_imageView)
|
||||
|
||||
var tempSelectedItem = 0
|
||||
|
||||
filterImageView.setOnClickListener {
|
||||
val filterOptions = arrayOf(
|
||||
getString(R.string.all),
|
||||
getString(R.string.videos),
|
||||
getString(R.string.channels),
|
||||
getString(R.string.playlists),
|
||||
getString(R.string.music_songs),
|
||||
getString(R.string.music_videos),
|
||||
getString(R.string.music_albums),
|
||||
getString(R.string.music_playlists)
|
||||
)
|
||||
|
||||
AlertDialog.Builder(view.context)
|
||||
.setTitle(getString(R.string.choose_filter))
|
||||
.setSingleChoiceItems(filterOptions, selectedFilter, DialogInterface.OnClickListener {
|
||||
_, id -> tempSelectedItem = id
|
||||
})
|
||||
.setPositiveButton(getString(R.string.okay), DialogInterface.OnClickListener { _, _ ->
|
||||
selectedFilter = tempSelectedItem
|
||||
apiSearchFilter = when (selectedFilter) {
|
||||
0 -> "all"
|
||||
1 -> "videos"
|
||||
2 -> "channels"
|
||||
3 -> "playlists"
|
||||
4 -> "music_songs"
|
||||
5 -> "music_videos"
|
||||
6 -> "music_albums"
|
||||
7 -> "music_playlists"
|
||||
else -> "all"
|
||||
}
|
||||
fetchSearch(autoTextView.text.toString())
|
||||
})
|
||||
.setNegativeButton(getString(R.string.cancel), null)
|
||||
.create()
|
||||
.show()
|
||||
}
|
||||
|
||||
//show search history
|
||||
|
||||
recyclerView.visibility = GONE
|
||||
searchRecView.visibility = GONE
|
||||
historyRecycler.visibility = VISIBLE
|
||||
|
||||
historyRecycler.layoutManager = LinearLayoutManager(view.context)
|
||||
|
||||
var historylist = getHistory()
|
||||
if (historylist.size != 0) {
|
||||
if (historylist.isNotEmpty()) {
|
||||
historyRecycler.adapter =
|
||||
SearchHistoryAdapter(requireContext(), historylist, autoTextView)
|
||||
}
|
||||
|
||||
recyclerView.layoutManager = GridLayoutManager(view.context, 1)
|
||||
searchRecView.layoutManager = GridLayoutManager(view.context, 1)
|
||||
autoTextView.requestFocus()
|
||||
val imm =
|
||||
requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm!!.showSoftInput(autoTextView, InputMethodManager.SHOW_IMPLICIT)
|
||||
imm.showSoftInput(autoTextView, InputMethodManager.SHOW_IMPLICIT)
|
||||
autoTextView.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(
|
||||
s: CharSequence?,
|
||||
@ -86,27 +133,34 @@ class SearchFragment : Fragment() {
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
if (s!! != "") {
|
||||
recyclerView.visibility = VISIBLE
|
||||
searchRecView.visibility = VISIBLE
|
||||
historyRecycler.visibility = GONE
|
||||
recyclerView.adapter = null
|
||||
searchRecView.adapter = null
|
||||
|
||||
searchRecView.viewTreeObserver
|
||||
.addOnScrollChangedListener {
|
||||
if (!searchRecView.canScrollVertically(1)) {
|
||||
fetchNextSearchItems(autoTextView.text.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GlobalScope.launch {
|
||||
fetchSuggestions(s.toString(), autoTextView)
|
||||
delay(3000)
|
||||
addtohistory(s.toString())
|
||||
fetchSearch(s.toString(), recyclerView)
|
||||
delay(1000)
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
if (sharedPreferences.getBoolean("search_history_toggle", true)) addtohistory(s.toString())
|
||||
fetchSearch(s.toString())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
if (s!!.isEmpty()) {
|
||||
recyclerView.visibility = GONE
|
||||
searchRecView.visibility = GONE
|
||||
historyRecycler.visibility = VISIBLE
|
||||
var historylist = getHistory()
|
||||
if (historylist.size != 0) {
|
||||
if (historylist.isNotEmpty()) {
|
||||
historyRecycler.adapter =
|
||||
SearchHistoryAdapter(requireContext(), historylist, autoTextView)
|
||||
}
|
||||
@ -116,8 +170,8 @@ class SearchFragment : Fragment() {
|
||||
})
|
||||
autoTextView.setOnEditorActionListener(OnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
hideKeyboard();
|
||||
autoTextView.dismissDropDown();
|
||||
hideKeyboard()
|
||||
autoTextView.dismissDropDown()
|
||||
return@OnEditorActionListener true
|
||||
}
|
||||
false
|
||||
@ -143,10 +197,10 @@ class SearchFragment : Fragment() {
|
||||
autoTextView.setAdapter(adapter)
|
||||
}
|
||||
}
|
||||
private fun fetchSearch(query: String, recyclerView: RecyclerView){
|
||||
private fun fetchSearch(query: String){
|
||||
lifecycleScope.launchWhenCreated {
|
||||
val response = try {
|
||||
RetrofitInstance.api.getSearchResults(query, "all")
|
||||
RetrofitInstance.api.getSearchResults(query, apiSearchFilter)
|
||||
} catch (e: IOException) {
|
||||
println(e)
|
||||
Log.e(TAG, "IOException, you might not have internet connection $e")
|
||||
@ -155,15 +209,38 @@ class SearchFragment : Fragment() {
|
||||
Log.e(TAG, "HttpException, unexpected response")
|
||||
return@launchWhenCreated
|
||||
}
|
||||
nextPage = response.nextpage
|
||||
if(response.items!!.isNotEmpty()){
|
||||
runOnUiThread {
|
||||
recyclerView.adapter = SearchAdapter(response.items)
|
||||
searchAdapter = SearchAdapter(response.items)
|
||||
searchRecView.adapter = searchAdapter
|
||||
}
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchNextSearchItems(query: String){
|
||||
lifecycleScope.launchWhenCreated {
|
||||
if (!isLoading) {
|
||||
isLoading = true
|
||||
val response = try {
|
||||
RetrofitInstance.api.getSearchResultsNextPage(query,apiSearchFilter,nextPage!!)
|
||||
} catch (e: IOException) {
|
||||
println(e)
|
||||
Log.e(TAG, "IOException, you might not have internet connection")
|
||||
return@launchWhenCreated
|
||||
} catch (e: HttpException) {
|
||||
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||
return@launchWhenCreated
|
||||
}
|
||||
nextPage = response.nextpage
|
||||
searchAdapter?.updateItems(response.items!!)
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment?.runOnUiThread(action: () -> Unit) {
|
||||
this ?: return
|
||||
if (!isAdded) return // Fragment not attached to an Activity
|
||||
|
@ -9,6 +9,7 @@ import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.system.Os.remove
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
@ -235,6 +236,13 @@ class SettingsActivity : AppCompatActivity(),
|
||||
true
|
||||
}
|
||||
|
||||
val clearHistory = findPreference<Preference>("clear_history")
|
||||
clearHistory?.setOnPreferenceClickListener {
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
sharedPreferences.edit().remove("search_history").commit()
|
||||
true
|
||||
}
|
||||
|
||||
val about = findPreference<Preference>("about")
|
||||
about?.setOnPreferenceClickListener {
|
||||
val uri = Uri.parse("https://libre-tube.github.io/")
|
||||
|
@ -18,7 +18,14 @@ import com.github.libretube.obj.SearchItem
|
||||
import com.squareup.picasso.Picasso
|
||||
|
||||
|
||||
class SearchAdapter(private val searchItems: List<SearchItem>): RecyclerView.Adapter<CustomViewHolder1>() {
|
||||
class SearchAdapter(private val searchItems: MutableList<SearchItem>): RecyclerView.Adapter<CustomViewHolder1>() {
|
||||
|
||||
fun updateItems(newItems: List<SearchItem>){
|
||||
var searchItemsSize = searchItems.size
|
||||
searchItems.addAll(newItems)
|
||||
notifyItemRangeInserted(searchItemsSize, newItems.size)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return searchItems.size
|
||||
}
|
||||
@ -52,19 +59,17 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
||||
|
||||
private fun bindWatch(item: SearchItem) {
|
||||
val thumbnailImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
||||
Picasso.get().load(item.thumbnail).into(thumbnailImage)
|
||||
Picasso.get().load(item.thumbnail).fit().centerCrop().into(thumbnailImage)
|
||||
val thumbnailDuration = v.findViewById<TextView>(R.id.search_thumbnail_duration)
|
||||
thumbnailDuration.text = DateUtils.formatElapsedTime(item.duration!!)
|
||||
val channelImage = v.findViewById<ImageView>(R.id.search_channel_image)
|
||||
Picasso.get().load(item.uploaderAvatar).into(channelImage)
|
||||
Picasso.get().load(item.uploaderAvatar).fit().centerCrop().into(channelImage)
|
||||
val title = v.findViewById<TextView>(R.id.search_description)
|
||||
if (item.title!!.length > 60) {
|
||||
title.text = item.title?.substring(0, 60) + "..."
|
||||
} else {
|
||||
title.text = item.title
|
||||
}
|
||||
title.text = if (item.title!!.length > 60) item.title?.substring(0, 60) + "..." else item.title
|
||||
val views = v.findViewById<TextView>(R.id.search_views)
|
||||
views.text = item.views.formatShort() +" • "+item.uploadedDate
|
||||
val viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else ""
|
||||
val uploadDate = if (item.uploadedDate != null) item.uploadedDate else ""
|
||||
views.text = if (viewsString != "" && uploadDate != "") viewsString + " • " + uploadDate else viewsString + uploadDate
|
||||
val channelName = v.findViewById<TextView>(R.id.search_channel_name)
|
||||
channelName.text = item.uploaderName
|
||||
v.setOnClickListener{
|
||||
@ -88,7 +93,7 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
||||
}
|
||||
private fun bindChannel(item: SearchItem) {
|
||||
val channelImage = v.findViewById<ImageView>(R.id.search_channel_image)
|
||||
Picasso.get().load(item.thumbnail).into(channelImage)
|
||||
Picasso.get().load(item.thumbnail).fit().centerCrop().into(channelImage)
|
||||
val channelName = v.findViewById<TextView>(R.id.search_channel_name)
|
||||
channelName.text = item.name
|
||||
val channelViews = v.findViewById<TextView>(R.id.search_views)
|
||||
@ -102,15 +107,15 @@ class CustomViewHolder1(private val v: View): RecyclerView.ViewHolder(v){
|
||||
}
|
||||
private fun bindPlaylist(item: SearchItem) {
|
||||
val playlistImage = v.findViewById<ImageView>(R.id.search_thumbnail)
|
||||
Picasso.get().load(item.thumbnail).into(playlistImage)
|
||||
Picasso.get().load(item.thumbnail).fit().centerCrop().into(playlistImage)
|
||||
val playlistNumber = v.findViewById<TextView>(R.id.search_playlist_number)
|
||||
playlistNumber.text = item.videos.toString()
|
||||
if (item.videos?.toInt() != -1) playlistNumber.text = item.videos.toString()
|
||||
val playlistName = v.findViewById<TextView>(R.id.search_description)
|
||||
playlistName.text = item.name
|
||||
val playlistChannelName = v.findViewById<TextView>(R.id.search_name)
|
||||
playlistChannelName.text = item.uploaderName
|
||||
val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos)
|
||||
playlistVideosNumber.text = item.videos.toString()+" videos"
|
||||
if (item.videos?.toInt() != -1) playlistVideosNumber.text = v.context.getString(R.string.videoCount, item.videos.toString())
|
||||
v.setOnClickListener {
|
||||
//playlist clicked
|
||||
val activity = v.context as MainActivity
|
||||
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class SearchResult(
|
||||
val items: List<SearchItem>? = listOf(),
|
||||
val items: MutableList<SearchItem>? = arrayListOf(),
|
||||
val nextpage: String? ="",
|
||||
val suggestion: String?="",
|
||||
val corrected: Boolean? = null
|
||||
|
10
app/src/main/res/drawable/ic_filter.xml
Normal file
10
app/src/main/res/drawable/ic_filter.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_trash.xml
Normal file
10
app/src/main/res/drawable/ic_trash.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
|
||||
</vector>
|
@ -6,41 +6,63 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".SearchFragment">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/outlinedTextField"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
<LinearLayout
|
||||
android:id="@+id/searchbar_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:cardCornerRadius="27dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/outlinedTextField"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:background="@android:color/transparent"
|
||||
app:hintEnabled="false">
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardCornerRadius="27dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/autoCompleteTextView"
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:hint="@string/search_hint"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp" />
|
||||
app:hintEnabled="false">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/autoCompleteTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:hint="@string/search_hint"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:dropDownWidth="match_parent" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/filterMenu_imageView"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="0"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:src="@drawable/ic_filter" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/tv_genres"-->
|
||||
@ -297,21 +319,18 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/outlinedTextField"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchbar_holder"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/search_recycler"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_margin="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/outlinedTextField"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchbar_holder"
|
||||
/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
6
app/src/main/res/layout/layout_empty.xml
Normal file
6
app/src/main/res/layout/layout_empty.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -43,21 +43,17 @@
|
||||
android:id="@+id/search_playlist_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="10"
|
||||
android:textColor="#ECE4E4"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
/>
|
||||
android:textColor="#ECE4E4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@drawable/ic_playlist"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_below="@+id/search_playlist_number"
|
||||
/>
|
||||
android:layout_centerInParent="true"
|
||||
app:srcCompat="@drawable/ic_playlist" />
|
||||
|
||||
</RelativeLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@ -67,7 +63,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_playlist"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -77,7 +72,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_playlist"
|
||||
app:layout_constraintTop_toBottomOf="@+id/search_description" />
|
||||
@ -86,7 +80,6 @@
|
||||
android:id="@+id/search_playlist_videos"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
|
@ -50,7 +50,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_search_thumbnail"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -60,7 +59,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_search_thumbnail"
|
||||
app:layout_constraintTop_toBottomOf="@+id/channel_description" />
|
||||
|
@ -53,7 +53,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_search_thumbnail"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -63,7 +62,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card_search_thumbnail"
|
||||
app:layout_constraintTop_toBottomOf="@+id/search_description" />
|
||||
@ -83,7 +81,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/search_channel_image"
|
||||
app:layout_constraintTop_toBottomOf="@+id/search_views" />
|
||||
|
@ -72,6 +72,18 @@
|
||||
<string name="noInternet">No Internet Connection</string>
|
||||
<string name="retry">Retry</string>
|
||||
<string name="comments">Comments</string>
|
||||
<string name="choose_filter">Choose search filter</string>
|
||||
<string name="channels">Channels</string>
|
||||
<string name="all">All</string>
|
||||
<string name="playlists">Playlists</string>
|
||||
<string name="okay">Ok</string>
|
||||
<string name="history">History</string>
|
||||
<string name="search_history">Search History</string>
|
||||
<string name="clear_history">Clear History</string>
|
||||
<string name="music_songs">Music Songs</string>
|
||||
<string name="music_videos">Music Videos</string>
|
||||
<string name="music_albums">Music Albums</string>
|
||||
<string name="music_playlists">Music Playlists</string>
|
||||
<string name="defaultTab">Default Tab</string>
|
||||
<string name="sponsorblock">SponsorBlock</string>
|
||||
<string name="sponsorblock_summary">Uses API from https://sponsor.ajay.app/</string>
|
||||
|
@ -109,6 +109,21 @@
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/history">
|
||||
|
||||
<SwitchPreference
|
||||
app:title="@string/search_history"
|
||||
app:key="search_history_toggle"
|
||||
android:defaultValue="true"
|
||||
android:icon="@drawable/ic_history" />
|
||||
|
||||
<Preference
|
||||
app:title="@string/clear_history"
|
||||
app:key="clear_history"
|
||||
android:icon="@drawable/ic_trash" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory app:title="@string/about">
|
||||
|
||||
<Preference
|
||||
|
Loading…
x
Reference in New Issue
Block a user