mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	search providers settings
This commit is contained in:
		
							parent
							
								
									4780935d55
								
							
						
					
					
						commit
						3290fceb47
					
				
					 13 changed files with 289 additions and 25 deletions
				
			
		|  | @ -69,6 +69,23 @@ object APIHolder { | |||
|             setOf(apis[defProvider].name) | ||||
|         )?.toHashSet() ?: hashSetOf(apis[defProvider].name) | ||||
|     } | ||||
| 
 | ||||
|     fun Activity.getApiTypeSettings(): HashSet<TvType> { | ||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) | ||||
|         val list = settingsManager.getStringSet( | ||||
|             this.getString(R.string.search_types_list_key), | ||||
|             setOf(apis[defProvider].name) | ||||
|         ) | ||||
|         val hashSet = HashSet<TvType>() | ||||
|         hashSet.addAll(TvType.values()) | ||||
|         if(list.isNullOrEmpty()) return hashSet | ||||
| 
 | ||||
|         val names = TvType.values().map { it.name }.toHashSet() | ||||
|         val realSet = list.filter { names.contains(it) }.map { TvType.valueOf(it) }.toHashSet() | ||||
|         if(realSet.isEmpty()) return hashSet | ||||
| 
 | ||||
|         return realSet | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /**Every provider will **not** have try catch built in, so handle exceptions when calling these functions*/ | ||||
|  | @ -186,6 +203,7 @@ enum class DubStatus { | |||
| 
 | ||||
| enum class TvType { | ||||
|     Movie, | ||||
|     AnimeMovie, | ||||
|     TvSeries, | ||||
|     Cartoon, | ||||
|     Anime, | ||||
|  | @ -194,7 +212,7 @@ enum class TvType { | |||
| 
 | ||||
| // IN CASE OF FUTURE ANIME MOVIE OR SMTH | ||||
| fun TvType.isMovieType(): Boolean { | ||||
|     return this == TvType.Movie | ||||
|     return this == TvType.Movie || this == TvType.AnimeMovie | ||||
| } | ||||
| 
 | ||||
| data class SubtitleFile(val lang: String, val url: String) | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ class DubbedAnimeProvider : MainAPI() { | |||
| 
 | ||||
|     override val supportedTypes: Set<TvType> | ||||
|         get() = setOf( | ||||
|             TvType.Movie, | ||||
|             TvType.AnimeMovie, | ||||
|             TvType.Anime, | ||||
|         ) | ||||
| 
 | ||||
|  | @ -90,7 +90,7 @@ class DubbedAnimeProvider : MainAPI() { | |||
|             returnValue.add( | ||||
|                 if (getIsMovie(href)) { | ||||
|                     MovieSearchResponse( | ||||
|                         title, href, this.name, TvType.Movie, img, null | ||||
|                         title, href, this.name, TvType.AnimeMovie, img, null | ||||
|                     ) | ||||
|                 } else { | ||||
|                     AnimeSearchResponse( | ||||
|  | @ -127,7 +127,7 @@ class DubbedAnimeProvider : MainAPI() { | |||
|             returnValue.add( | ||||
|                 if (getIsMovie(href)) { | ||||
|                     MovieSearchResponse( | ||||
|                         title, href, this.name, TvType.Movie, img, null | ||||
|                         title, href, this.name, TvType.AnimeMovie, img, null | ||||
|                     ) | ||||
|                 } else { | ||||
|                     AnimeSearchResponse( | ||||
|  | @ -197,7 +197,7 @@ class DubbedAnimeProvider : MainAPI() { | |||
|                 episode.title, | ||||
|                 realSlug, | ||||
|                 this.name, | ||||
|                 TvType.Movie, | ||||
|                 TvType.AnimeMovie, | ||||
|                 episode.serversHTML, | ||||
|                 if (poster == null) null else fixUrl(poster), | ||||
|                 episode.year?.toIntOrNull(), | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ class TenshiProvider : MainAPI() { | |||
| 
 | ||||
|         fun getType(t: String): TvType { | ||||
|             return if (t.contains("OVA") || t.contains("Special")) TvType.ONA | ||||
|             else if (t.contains("Movie")) TvType.Movie | ||||
|             else if (t.contains("Movie")) TvType.AnimeMovie | ||||
|             else TvType.Anime | ||||
|         } | ||||
|     } | ||||
|  | @ -30,7 +30,7 @@ class TenshiProvider : MainAPI() { | |||
|         get() = false | ||||
| 
 | ||||
|     override val supportedTypes: Set<TvType> | ||||
|         get() = setOf(TvType.Anime, TvType.Movie, TvType.ONA) | ||||
|         get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) | ||||
| 
 | ||||
|     private fun autoLoadToken(): Boolean { | ||||
|         if (token != null) return true | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ class WcoProvider : MainAPI() { | |||
|     companion object { | ||||
|         fun getType(t: String): TvType { | ||||
|             return if (t.contains("OVA") || t.contains("Special")) TvType.ONA | ||||
|             else if (t.contains("Movie")) TvType.Movie | ||||
|             else if (t.contains("Movie")) TvType.AnimeMovie | ||||
|             else TvType.Anime | ||||
|         } | ||||
|     } | ||||
|  | @ -29,7 +29,7 @@ class WcoProvider : MainAPI() { | |||
| 
 | ||||
|     override val supportedTypes: Set<TvType> | ||||
|         get() = setOf( | ||||
|             TvType.Movie, | ||||
|             TvType.AnimeMovie, | ||||
|             TvType.Anime, | ||||
|             TvType.ONA | ||||
|         ) | ||||
|  | @ -91,9 +91,9 @@ class WcoProvider : MainAPI() { | |||
|             val type = i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() | ||||
| 
 | ||||
|             returnValue.add( | ||||
|                 if (getType(type) == TvType.Movie) { | ||||
|                 if (getType(type) == TvType.AnimeMovie) { | ||||
|                     MovieSearchResponse( | ||||
|                         title, href, this.name, TvType.Movie, img, year | ||||
|                         title, href, this.name, TvType.AnimeMovie, img, year | ||||
|                     ) | ||||
|                 } else { | ||||
|                     AnimeSearchResponse( | ||||
|  | @ -152,9 +152,9 @@ class WcoProvider : MainAPI() { | |||
|             val type = filmInfo?.select("span")?.get(1)?.text().toString() | ||||
|             if (title != "null") { | ||||
|                 returnValue.add( | ||||
|                     if (getType(type) == TvType.Movie) { | ||||
|                     if (getType(type) == TvType.AnimeMovie) { | ||||
|                         MovieSearchResponse( | ||||
|                             title, href, this.name, TvType.Movie, img, year | ||||
|                             title, href, this.name, TvType.AnimeMovie, img, year | ||||
|                         ) | ||||
|                     } else { | ||||
|                         AnimeSearchResponse( | ||||
|  |  | |||
|  | @ -9,11 +9,12 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | |||
| class APIRepository(val api: MainAPI) { | ||||
|     companion object { | ||||
|         var providersActive = HashSet<String>() | ||||
|         var typesActive = HashSet<TvType>() | ||||
|     } | ||||
| 
 | ||||
|     val name: String get() = api.name | ||||
|     val mainUrl: String get() = api.mainUrl | ||||
|     val hasQuickSearch: Boolean  get() = api.hasQuickSearch | ||||
|     val hasQuickSearch: Boolean get() = api.hasQuickSearch | ||||
| 
 | ||||
|     suspend fun load(url: String): Resource<LoadResponse> { | ||||
|         return safeApiCall { | ||||
|  | @ -22,9 +23,10 @@ class APIRepository(val api: MainAPI) { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     suspend fun search(query: String): Resource<ArrayList<SearchResponse>> { | ||||
|     suspend fun search(query: String): Resource<List<SearchResponse>> { | ||||
|         return safeApiCall { | ||||
|             api.search(query) ?: throw ErrorLoadingException() | ||||
|             return@safeApiCall (api.search(query) | ||||
|                 ?: throw ErrorLoadingException()).filter { typesActive.contains(it.type) }.toList() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ class HomeChildItemAdapter( | |||
|             textType?.text = when (card.type) { | ||||
|                 TvType.Anime -> "Anime" | ||||
|                 TvType.Movie -> "Movie" | ||||
|                 TvType.AnimeMovie -> "Movie" | ||||
|                 TvType.ONA -> "ONA" | ||||
|                 TvType.TvSeries -> "TV" | ||||
|                 TvType.Cartoon -> "Cartoon" | ||||
|  |  | |||
|  | @ -899,7 +899,7 @@ class ResultFragment : Fragment() { | |||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         if (d.type == TvType.Movie) { | ||||
|                         if (d.type.isMovieType()) { | ||||
|                             val hasDownloadSupport = api.hasDownloadSupport | ||||
|                             lateFixDownloadButton(true) | ||||
| 
 | ||||
|  |  | |||
|  | @ -91,6 +91,7 @@ class SearchAdapter( | |||
|             textType?.text = when (card.type) { | ||||
|                 TvType.Anime -> "Anime" | ||||
|                 TvType.Movie -> "Movie" | ||||
|                 TvType.AnimeMovie -> "Movie" | ||||
|                 TvType.ONA -> "ONA" | ||||
|                 TvType.TvSeries -> "TV" | ||||
|                 TvType.Cartoon -> "Cartoon" | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import android.view.View | |||
| import android.view.ViewGroup | ||||
| import android.view.WindowManager | ||||
| import android.view.inputmethod.InputMethodManager | ||||
| import android.widget.ImageView | ||||
| import android.widget.* | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.appcompat.widget.SearchView | ||||
| import androidx.fragment.app.Fragment | ||||
|  | @ -16,20 +16,28 @@ import androidx.lifecycle.ViewModelProvider | |||
| import androidx.preference.PreferenceManager | ||||
| import androidx.recyclerview.widget.GridLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import com.google.android.material.switchmaterial.SwitchMaterial | ||||
| import com.lagradost.cloudstream3.APIHolder.apis | ||||
| import com.lagradost.cloudstream3.APIHolder.getApiSettings | ||||
| import com.lagradost.cloudstream3.APIHolder.getApiTypeSettings | ||||
| import com.lagradost.cloudstream3.HomePageList | ||||
| import com.lagradost.cloudstream3.R | ||||
| import com.lagradost.cloudstream3.TvType | ||||
| import com.lagradost.cloudstream3.mvvm.Resource | ||||
| import com.lagradost.cloudstream3.mvvm.observe | ||||
| import com.lagradost.cloudstream3.ui.APIRepository.Companion.providersActive | ||||
| import com.lagradost.cloudstream3.ui.APIRepository.Companion.typesActive | ||||
| import com.lagradost.cloudstream3.ui.home.HomeFragment | ||||
| import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.loadHomepageList | ||||
| import com.lagradost.cloudstream3.ui.home.ParentItemAdapter | ||||
| import com.lagradost.cloudstream3.utils.DataStore.getKey | ||||
| import com.lagradost.cloudstream3.utils.DataStore.setKey | ||||
| import com.lagradost.cloudstream3.utils.SEARCH_PROVIDER_TOGGLE | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.getGridIsCompact | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||
| import kotlinx.android.synthetic.main.fragment_search.* | ||||
| import java.util.HashSet | ||||
| 
 | ||||
| class SearchFragment : Fragment() { | ||||
|     private lateinit var searchViewModel: SearchViewModel | ||||
|  | @ -95,10 +103,175 @@ class SearchFragment : Fragment() { | |||
|         val searchMagIcon = main_search.findViewById<ImageView>(androidx.appcompat.R.id.search_mag_icon) | ||||
|         searchMagIcon.scaleX = 0.65f | ||||
|         searchMagIcon.scaleY = 0.65f | ||||
|         search_filter.setOnClickListener { | ||||
|         search_filter.setOnClickListener { view -> | ||||
|             val apiNamesSetting = activity?.getApiSettings() | ||||
|             if (apiNamesSetting != null) { | ||||
|                 val apiNames = apis.map { it.name } | ||||
|                 val builder = | ||||
|                     AlertDialog.Builder(view.context, R.style.AlertDialogCustom).setView(R.layout.provider_list) | ||||
| 
 | ||||
|                 val dialog = builder.create() | ||||
|                 dialog.show() | ||||
| 
 | ||||
|                 val listView = dialog.findViewById<ListView>(R.id.listview1)!! | ||||
|                 val listView2 = dialog.findViewById<ListView>(R.id.listview2)!! | ||||
|                 val toggle = dialog.findViewById<SwitchMaterial>(R.id.toggle1)!! | ||||
|                 val applyButton = dialog.findViewById<TextView>(R.id.apply_btt)!! | ||||
|                 val cancelButton = dialog.findViewById<TextView>(R.id.cancel_btt)!! | ||||
|                 // val applyHolder = dialog.findViewById<LinearLayout>(R.id.apply_btt_holder)!! | ||||
| 
 | ||||
|                 toggle.text = getString(R.string.search_provider_text) | ||||
| 
 | ||||
|                 val arrayAdapter = ArrayAdapter<String>(view.context, R.layout.sort_bottom_single_choice) | ||||
|                 arrayAdapter.addAll(apiNames) | ||||
| 
 | ||||
|                 listView.adapter = arrayAdapter | ||||
|                 listView.choiceMode = AbsListView.CHOICE_MODE_MULTIPLE | ||||
| 
 | ||||
|                 val typeChoices = listOf( | ||||
|                     Pair("Movies", listOf(TvType.Movie)), | ||||
|                     Pair("TvSeries", listOf(TvType.TvSeries)), | ||||
|                     Pair("Cartoons", listOf(TvType.Cartoon)), | ||||
|                     Pair("Anime", listOf(TvType.Anime, TvType.ONA, TvType.AnimeMovie)) | ||||
|                 ) | ||||
| 
 | ||||
|                 val arrayAdapter2 = ArrayAdapter<String>(view.context, R.layout.sort_bottom_single_choice) | ||||
|                 arrayAdapter2.addAll(typeChoices.map { it.first }) | ||||
| 
 | ||||
|                 listView2.adapter = arrayAdapter2 | ||||
|                 listView2.choiceMode = AbsListView.CHOICE_MODE_MULTIPLE | ||||
| 
 | ||||
| 
 | ||||
|                 /*fun updateMulti() { | ||||
|                     val set = HashSet<TvType>() | ||||
| 
 | ||||
|                     for ((index, api) in apis.withIndex()) { | ||||
|                         if (listView?.checkedItemPositions[index]) { | ||||
|                             set.addAll(api.supportedTypes) | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if (set.size == 0) { | ||||
|                         set.addAll(TvType.values()) | ||||
|                     } | ||||
| 
 | ||||
|                     for ((index, choice) in typeChoices.withIndex()) { | ||||
|                         listView2?.setItemChecked(index, choice.second.any { set.contains(it) }) | ||||
|                     } | ||||
|                 }*/ | ||||
| 
 | ||||
|                 for ((index, item) in apiNames.withIndex()) { | ||||
|                     listView.setItemChecked(index, apiNamesSetting.contains(item)) | ||||
|                 } | ||||
| 
 | ||||
|                 for ((index, item) in typeChoices.withIndex()) { | ||||
|                     listView2.setItemChecked(index, item.second.any { typesActive.contains(it) }) | ||||
|                 } | ||||
| 
 | ||||
|                 fun toggleSearch(isOn: Boolean) { | ||||
|                     if (isOn) { | ||||
|                         listView2?.visibility = View.VISIBLE | ||||
|                         listView?.visibility = View.GONE | ||||
|                     } else { | ||||
|                         listView?.visibility = View.VISIBLE | ||||
|                         listView2?.visibility = View.GONE | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 val defVal = context?.getKey(SEARCH_PROVIDER_TOGGLE, true) ?: true | ||||
|                 toggleSearch(defVal) | ||||
| 
 | ||||
|                 toggle.isChecked = defVal | ||||
|                 toggle.setOnCheckedChangeListener { _, isOn -> | ||||
|                     toggleSearch(isOn) | ||||
|                 } | ||||
| 
 | ||||
|                 listView.setOnItemClickListener { _, _, i, _ -> | ||||
|                     val types = HashSet<TvType>() | ||||
|                     for ((index, api) in apis.withIndex()) { | ||||
|                         if (listView?.checkedItemPositions[index]) { | ||||
|                             types.addAll(api.supportedTypes) | ||||
|                         } | ||||
|                     } | ||||
|                     for ((typeIndex, type) in typeChoices.withIndex()) { | ||||
|                         listView2.setItemChecked(typeIndex, type.second.any { types.contains(it) }) | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 listView2.setOnItemClickListener { _, _, i, _ -> | ||||
|                     for ((index, api) in apis.withIndex()) { | ||||
|                         var isSupported = false | ||||
| 
 | ||||
|                         for ((typeIndex, type) in typeChoices.withIndex()) { | ||||
|                             if (listView2?.checkedItemPositions[typeIndex]) { | ||||
|                                 if (api.supportedTypes.any { type.second.contains(it) }) { | ||||
|                                     isSupported = true | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         listView?.setItemChecked( | ||||
|                             index, | ||||
|                             isSupported | ||||
|                         ) | ||||
|                     } | ||||
| 
 | ||||
|                     //updateMulti() | ||||
|                 } | ||||
| 
 | ||||
|                 dialog.setOnDismissListener { | ||||
|                     context?.setKey(SEARCH_PROVIDER_TOGGLE, toggle.isChecked ?: true) | ||||
|                 } | ||||
| 
 | ||||
|                 applyButton.setOnClickListener { | ||||
|                     val settingsManagerLocal = PreferenceManager.getDefaultSharedPreferences(activity) | ||||
| 
 | ||||
|                     val activeTypes = HashSet<TvType>() | ||||
|                     for ((index, name) in typeChoices.withIndex()) { | ||||
|                         if (listView2?.checkedItemPositions[index]) { | ||||
|                             activeTypes.addAll(typeChoices[index].second) | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if (activeTypes.size == 0) { | ||||
|                         activeTypes.addAll(TvType.values()) | ||||
|                     } | ||||
| 
 | ||||
| 
 | ||||
|                     val activeApis = HashSet<String>() | ||||
|                     for ((index, name) in apiNames.withIndex()) { | ||||
|                         if (listView?.checkedItemPositions[index]) { | ||||
|                             activeApis.add(name) | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if (activeApis.size == 0) { | ||||
|                         activeApis.addAll(apiNames) | ||||
|                     } | ||||
| 
 | ||||
|                     val edit = settingsManagerLocal.edit() | ||||
|                     edit.putStringSet( | ||||
|                         getString(R.string.search_providers_list_key), | ||||
|                         activeApis | ||||
|                     ) | ||||
|                     edit.putStringSet( | ||||
|                         getString(R.string.search_types_list_key), | ||||
|                         activeTypes.map { it.name }.toSet() | ||||
|                     ) | ||||
|                     edit.apply() | ||||
|                     providersActive = activeApis | ||||
|                     typesActive = activeTypes | ||||
| 
 | ||||
|                     dialog.dismiss() | ||||
|                 } | ||||
| 
 | ||||
|                 cancelButton.setOnClickListener { | ||||
|                     dialog.dismiss() | ||||
|                 } | ||||
| 
 | ||||
|                 //listView.setSelection(selectedIndex) | ||||
|                 // listView.setItemChecked(selectedIndex, true) | ||||
|                 /* | ||||
|                 val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext()) | ||||
| 
 | ||||
|                 builder.setMultiChoiceItems( | ||||
|  | @ -125,7 +298,7 @@ class SearchFragment : Fragment() { | |||
|                 } | ||||
|                 builder.setTitle("Search Providers") | ||||
|                 builder.setNegativeButton("Ok") { _, _ -> } | ||||
|                 builder.show() | ||||
|                 builder.show()*/ | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -178,6 +351,7 @@ class SearchFragment : Fragment() { | |||
| 
 | ||||
|         activity?.let { | ||||
|             providersActive = it.getApiSettings() | ||||
|             typesActive = it.getApiTypeSettings() | ||||
|         } | ||||
| 
 | ||||
|         main_search.setOnQueryTextFocusChangeListener { searchView, b -> | ||||
|  | @ -205,8 +379,8 @@ class SearchFragment : Fragment() { | |||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) | ||||
|         val isAdvancedSearch = settingsManager.getBoolean("advanced_search", true) | ||||
| 
 | ||||
|         search_master_recycler.visibility = if(isAdvancedSearch) View.VISIBLE else View.GONE | ||||
|         cardSpace.visibility = if(!isAdvancedSearch) View.VISIBLE else View.GONE | ||||
|         search_master_recycler.visibility = if (isAdvancedSearch) View.VISIBLE else View.GONE | ||||
|         cardSpace.visibility = if (!isAdvancedSearch) View.VISIBLE else View.GONE | ||||
| 
 | ||||
|         // SubtitlesFragment.push(activity) | ||||
|         //searchViewModel.search("iron man") | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ import kotlinx.coroutines.launch | |||
| 
 | ||||
| data class OnGoingSearch( | ||||
|     val apiName: String, | ||||
|     val data: Resource<ArrayList<SearchResponse>> | ||||
|     val data: Resource<List<SearchResponse>> | ||||
| ) | ||||
| 
 | ||||
| class SearchViewModel : ViewModel() { | ||||
|  | @ -56,7 +56,7 @@ class SearchViewModel : ViewModel() { | |||
|         if (localSearchCounter != searchCounter) return@launch | ||||
| 
 | ||||
|         val list = ArrayList<SearchResponse>() | ||||
|         val nestedList = currentList.map { it.data }.filterIsInstance<Resource.Success<ArrayList<SearchResponse>>>().map { it.value } | ||||
|         val nestedList = currentList.map { it.data }.filterIsInstance<Resource.Success<List<SearchResponse>>>().map { it.value } | ||||
| 
 | ||||
|         // I do it this way to move the relevant search results to the top | ||||
|         var index = 0 | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ const val DOWNLOAD_HEADER_CACHE = "download_header_cache" | |||
| const val DOWNLOAD_EPISODE_CACHE = "download_episode_cache" | ||||
| const val VIDEO_PLAYER_BRIGHTNESS = "video_player_alpha" | ||||
| const val HOMEPAGE_API = "home_api_used" | ||||
| const val SEARCH_PROVIDER_TOGGLE = "settings_providers_toggle" | ||||
| 
 | ||||
| const val PREFERENCES_NAME: String = "rebuild_preference" | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										65
									
								
								app/src/main/res/layout/provider_list.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/src/main/res/layout/provider_list.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout | ||||
|         xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|         xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|         android:orientation="vertical" | ||||
|         android:layout_width="match_parent" | ||||
|         android:background="?attr/bitDarkerGrayBackground" | ||||
|         android:layout_height="match_parent"> | ||||
| 
 | ||||
|     <com.google.android.material.switchmaterial.SwitchMaterial | ||||
|             android:layout_marginTop="10dp" | ||||
|             android:paddingStart="20dp" | ||||
|             android:paddingEnd="20dp" | ||||
|             android:textStyle="bold" | ||||
|             android:textSize="20sp" | ||||
|             android:textColor="?attr/textColor" | ||||
|             android:id="@+id/toggle1" | ||||
|             tools:text="Search" android:layout_width="match_parent" android:layout_height="wrap_content"> | ||||
| 
 | ||||
|     </com.google.android.material.switchmaterial.SwitchMaterial> | ||||
|     <ListView | ||||
|             android:id="@+id/listview1" | ||||
|             android:layout_marginTop="-10dp" | ||||
|             android:layout_marginBottom="60dp" | ||||
|             android:paddingTop="10dp" | ||||
|             tools:listitem="@layout/sort_bottom_single_choice" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_rowWeight="1" | ||||
|     /> | ||||
|     <ListView | ||||
|             android:id="@+id/listview2" | ||||
|             android:layout_marginTop="-10dp" | ||||
|             android:layout_marginBottom="60dp" | ||||
|             android:paddingTop="10dp" | ||||
|             tools:listitem="@layout/sort_bottom_single_choice" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_rowWeight="1" | ||||
|     /> | ||||
|     <LinearLayout | ||||
|             android:id="@+id/apply_btt_holder" | ||||
|             android:orientation="horizontal" | ||||
|             android:layout_gravity="bottom" | ||||
|             android:gravity="bottom|end" | ||||
|             android:layout_marginTop="-60dp" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="60dp"> | ||||
| 
 | ||||
|         <com.google.android.material.button.MaterialButton | ||||
|                 style="@style/WhiteButton" | ||||
|                 android:layout_gravity="center_vertical|end" | ||||
|                 android:text="@string/sort_apply" | ||||
|                 android:id="@+id/apply_btt" | ||||
|                 android:layout_width="wrap_content" | ||||
|         /> | ||||
|         <com.google.android.material.button.MaterialButton | ||||
|                 style="@style/BlackButton" | ||||
|                 android:layout_gravity="center_vertical|end" | ||||
|                 android:text="@string/sort_cancel" | ||||
|                 android:id="@+id/cancel_btt" | ||||
|                 android:layout_width="wrap_content" | ||||
|         /> | ||||
|     </LinearLayout> | ||||
| </LinearLayout> | ||||
|  | @ -4,9 +4,10 @@ | |||
|     <string name="title_search">Search</string> | ||||
|     <string name="title_downloads">Downloads</string> | ||||
|     <string name="title_settings">Settings</string> | ||||
|     <string name="search_hint">Search...</string> | ||||
|     <string name="search_hint">Search…</string> | ||||
|     <string name="change_providers_descript">Change Providers</string> | ||||
|     <string name="search_providers_list_key">search_providers_list</string> | ||||
|     <string name="search_types_list_key">search_type_list</string> | ||||
|     <string name="grid_format_key">grid_format</string> | ||||
|     <string name="search_poster_descript">Poster</string> | ||||
|     <string name="no_data">No Data</string> | ||||
|  | @ -80,4 +81,5 @@ | |||
|     <string name="subs_default_reset_toast">Reset to default value</string> | ||||
|     <string name="preview_background">Preview Background</string> | ||||
|     <string name="subs_font">Font</string> | ||||
|     <string name="search_provider_text">Search Providers</string> | ||||
| </resources> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue