forked from recloudstream/cloudstream
		
	added site cloner
This commit is contained in:
		
							parent
							
								
									86aed5b830
								
							
						
					
					
						commit
						5f542ec81a
					
				
					 58 changed files with 391 additions and 82 deletions
				
			
		|  | @ -155,11 +155,11 @@ | |||
|         <service | ||||
|                 android:name=".services.VideoDownloadService" | ||||
|                 android:enabled="true" | ||||
|                 android:exported="false"></service> | ||||
|                 android:exported="false" /> | ||||
| 
 | ||||
|         <activity | ||||
|                 android:exported="false" | ||||
|                 android:name=".ui.ControllerActivity"></activity> | ||||
|                 android:name=".ui.ControllerActivity" /> | ||||
| 
 | ||||
|         <provider | ||||
|                 android:name="androidx.core.content.FileProvider" | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ object APIHolder { | |||
| 
 | ||||
|     private const val defProvider = 0 | ||||
| 
 | ||||
|     val allProviders by lazy { | ||||
|     val allProviders = | ||||
|         arrayListOf( | ||||
|             // Movie providers | ||||
|             ElifilmsProvider(), | ||||
|  | @ -132,7 +132,7 @@ object APIHolder { | |||
|             NginxProvider(), | ||||
|             OlgplyProvider(), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     fun initAll() { | ||||
|         for (api in allProviders) { | ||||
|  | @ -142,7 +142,7 @@ object APIHolder { | |||
|     } | ||||
| 
 | ||||
|     var apis: List<MainAPI> = arrayListOf() | ||||
|     private var apiMap: Map<String, Int>? = null | ||||
|     var apiMap: Map<String, Int>? = null | ||||
| 
 | ||||
|     private fun initMap() { | ||||
|         if (apiMap == null) | ||||
|  | @ -357,6 +357,7 @@ abstract class MainAPI { | |||
|     } | ||||
| 
 | ||||
|     fun overrideWithNewData(data: ProvidersInfoJson) { | ||||
|         if (!canBeOverridden) return | ||||
|         this.name = data.name | ||||
|         if (data.url.isNotBlank() && data.url != "NONE") | ||||
|             this.mainUrl = data.url | ||||
|  | @ -366,10 +367,11 @@ abstract class MainAPI { | |||
|     open var name = "NONE" | ||||
|     open var mainUrl = "NONE" | ||||
|     open var storedCredentials: String? = null | ||||
|     open var canBeOverridden: Boolean = true | ||||
| 
 | ||||
|     //open val uniqueId : Int by lazy { this.name.hashCode() } // in case of duplicate providers you can have a shared id | ||||
| 
 | ||||
|     open val lang = "en" // ISO_639_1 check SubtitleHelper | ||||
|     open var lang = "en" // ISO_639_1 check SubtitleHelper | ||||
| 
 | ||||
|     /**If link is stored in the "data" string, so links can be instantly loaded*/ | ||||
|     open val instantLinkLoading = false | ||||
|  | @ -908,7 +910,7 @@ interface LoadResponse { | |||
|         } | ||||
| 
 | ||||
|         fun LoadResponse.addTrailer(trailerUrls: List<String>?) { | ||||
|             if(trailerUrls == null) return | ||||
|             if (trailerUrls == null) return | ||||
|             if (this.trailers == null) { | ||||
|                 this.trailers = trailerUrls | ||||
|             } else { | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ import com.lagradost.cloudstream3.ui.result.ResultFragment | |||
| import com.lagradost.cloudstream3.ui.search.SearchResultBuilder | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsGeneral | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.loadCache | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.loadResult | ||||
|  | @ -68,6 +69,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor | |||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.navigate | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.requestRW | ||||
| import com.lagradost.cloudstream3.utils.USER_PROVIDER_API | ||||
| import com.lagradost.nicehttp.Requests | ||||
| import kotlinx.android.synthetic.main.activity_main.* | ||||
| import kotlinx.android.synthetic.main.fragment_result_swipe.* | ||||
|  | @ -515,6 +517,26 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | |||
|             apis = allProviders | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             getKey<Array<SettingsGeneral.CustomSite>>(USER_PROVIDER_API)?.let { list -> | ||||
|                 list.forEach { custom -> | ||||
|                     allProviders.firstOrNull { it.javaClass.simpleName == custom.parentJavaClass } | ||||
|                         ?.let { | ||||
|                             allProviders.add(it.javaClass.newInstance().apply { | ||||
|                                 name = custom.name | ||||
|                                 lang = custom.lang | ||||
|                                 mainUrl = custom.url.trimEnd('/') | ||||
|                                 canBeOverridden = false | ||||
|                             }) | ||||
|                         } | ||||
|                 } | ||||
|             } | ||||
|             apis = allProviders | ||||
|             APIHolder.apiMap = null | ||||
|         } catch (e: Exception) { | ||||
|             logError(e) | ||||
|         } | ||||
| 
 | ||||
|         loadThemes(this) | ||||
|         updateLocale() | ||||
|         app.initClient(this) | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ import org.jsoup.nodes.Element | |||
| class AnimeWorldProvider : MainAPI() { | ||||
|     override var mainUrl = "https://www.animeworld.tv" | ||||
|     override var name = "AnimeWorld" | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override val hasMainPage = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ class AnimefenixProvider:MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://animefenix.com" | ||||
|     override var name = "Animefenix" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import kotlin.collections.ArrayList | |||
| class AnimeflvIOProvider:MainAPI() { | ||||
|     override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to | ||||
|     override var name = "Animeflv.io" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ class AnimeflvnetProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://www3.animeflv.net" | ||||
|     override var name = "Animeflv.net" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import org.jsoup.nodes.Element | |||
| class DreamSubProvider : MainAPI() { | ||||
|     override var mainUrl = "https://dreamsub.me" | ||||
|     override var name = "DreamSub" | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override val hasMainPage = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ class GomunimeProvider : MainAPI() { | |||
|     override var name = "Gomunime" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ class JKAnimeProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://jkanime.net" | ||||
|     override var name = "JKAnime" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class KuramanimeProvider : MainAPI() { | |||
|     override var name = "Kuramanime" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ class KuronimeProvider : MainAPI() { | |||
|     override var name = "Kuronime" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ class MonoschinosProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://monoschinos2.com" | ||||
|     override var name = "Monoschinos" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ class MundoDonghuaProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://www.mundodonghua.com" | ||||
|     override var name = "MundoDonghua" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ class NeonimeProvider : MainAPI() { | |||
|     override var name = "Neonime" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ class NontonAnimeIDProvider : MainAPI() { | |||
|     override var name = "NontonAnimeID" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ class OploverzProvider : MainAPI() { | |||
|     override var name = "Oploverz" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
| 
 | ||||
|     override val supportedTypes = setOf( | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | |||
| class CrossTmdbProvider : TmdbProvider() { | ||||
|     override var name = "MultiMovie" | ||||
|     override val apiName = "MultiMovie" | ||||
|     override val lang = "en" | ||||
|     override var lang = "en" | ||||
|     override val useMetaLoadResponse = true | ||||
|     override val usesWebView = true | ||||
|     override val supportedTypes = setOf(TvType.Movie) | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ import com.lagradost.cloudstream3.utils.SyncUtil | |||
| // wont be implemented | ||||
| class MultiAnimeProvider : MainAPI() { | ||||
|     override var name = "MultiAnime" | ||||
|     override val lang = "en" | ||||
|     override var lang = "en" | ||||
|     override val usesWebView = true | ||||
|     override val supportedTypes = setOf(TvType.Anime) | ||||
|     private val syncApi: SyncAPI = aniListApi | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.Qualities | |||
| import org.jsoup.nodes.Element | ||||
| 
 | ||||
| class AkwamProvider : MainAPI() { | ||||
|     override val lang = "ar" | ||||
|     override var lang = "ar" | ||||
|     override var mainUrl = "https://akwam.to" | ||||
|     override var name = "Akwam" | ||||
|     override val usesWebView = false | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import com.lagradost.cloudstream3.app | |||
| import com.lagradost.cloudstream3.utils.* | ||||
| 
 | ||||
| class AltadefinizioneProvider : MainAPI() { | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override var mainUrl = "https://altadefinizione.hair" | ||||
|     override var name = "Altadefinizione" | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | |||
| import com.lagradost.cloudstream3.utils.loadExtractor | ||||
| 
 | ||||
| class CineblogProvider : MainAPI() { | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override var mainUrl = "https://cb01.rip" | ||||
|     override var name = "CineBlog" | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class CinecalidadProvider:MainAPI() { | ||||
|     override var mainUrl = "https://cinecalidad.lol" | ||||
|     override var name = "Cinecalidad" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class CuevanaProvider : MainAPI() { | ||||
|     override var mainUrl = "https://cuevana3.me" | ||||
|     override var name = "Cuevana" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ class DoramasYTProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://doramasyt.com" | ||||
|     override var name = "DoramasYT" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ class DramaidProvider : MainAPI() { | |||
|     override var name = "DramaId" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
|     override val hasChromecastSupport = false | ||||
|     override val supportedTypes = setOf(TvType.AsianDrama) | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | |||
| import org.jsoup.nodes.Element | ||||
| 
 | ||||
| class EgyBestProvider : MainAPI() { | ||||
|     override val lang = "ar" | ||||
|     override var lang = "ar" | ||||
|     override var mainUrl = "https://www.egy.best" | ||||
|     override var name = "EgyBest" | ||||
|     override val usesWebView = false | ||||
|  |  | |||
|  | @ -1,19 +1,20 @@ | |||
| package com.lagradost.cloudstream3.movieproviders | ||||
| 
 | ||||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.utils.* | ||||
| import kotlin.collections.ArrayList | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
| import com.lagradost.cloudstream3.utils.loadExtractor | ||||
| 
 | ||||
| class ElifilmsProvider:MainAPI() { | ||||
| class ElifilmsProvider : MainAPI() { | ||||
|     override var mainUrl: String = "https://elifilms.net" | ||||
|     override var name: String = "Elifilms" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|     override val supportedTypes = setOf( | ||||
|         TvType.Movie, | ||||
|     ) | ||||
| 
 | ||||
|     override suspend fun getMainPage(): HomePageResponse { | ||||
|         val items = ArrayList<HomePageList>() | ||||
|         val newest = app.get(mainUrl).document.selectFirst("a.fav_link.premiera")?.attr("href") | ||||
|  | @ -42,6 +43,7 @@ class ElifilmsProvider:MainAPI() { | |||
|         if (items.size <= 0) throw ErrorLoadingException() | ||||
|         return HomePageResponse(items) | ||||
|     } | ||||
| 
 | ||||
|     override suspend fun search(query: String): List<SearchResponse> { | ||||
|         val url = "$mainUrl/?s=$query" | ||||
|         val doc = app.get(url).document | ||||
|  | @ -52,6 +54,7 @@ class ElifilmsProvider:MainAPI() { | |||
|             (MovieSearchResponse(name, href, this.name, TvType.Movie, poster, null)) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override suspend fun load(url: String): LoadResponse { | ||||
|         val document = app.get(url, timeout = 120).document | ||||
|         val title = document.selectFirst(".post_title h1")?.text() ?: "" | ||||
|  | @ -73,6 +76,7 @@ class ElifilmsProvider:MainAPI() { | |||
|             tags | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     override suspend fun loadLinks( | ||||
|         data: String, | ||||
|         isCasting: Boolean, | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class EntrepeliculasyseriesProvider:MainAPI() { | ||||
|     override var mainUrl = "https://entrepeliculasyseries.nu" | ||||
|     override var name = "EntrePeliculasySeries" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ class EstrenosDoramasProvider : MainAPI() { | |||
| 
 | ||||
|     override var mainUrl = "https://www23.estrenosdoramas.net" | ||||
|     override var name = "EstrenosDoramas" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | |||
| import org.jsoup.nodes.Element | ||||
| 
 | ||||
| class FaselHDProvider : MainAPI() { | ||||
|     override val lang = "ar" | ||||
|     override var lang = "ar" | ||||
|     override var mainUrl = "https://faselhd.io" | ||||
|     override var name = "FaselHD" | ||||
|     override val usesWebView = false | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ import org.jsoup.select.Elements | |||
| class FilmanProvider : MainAPI() { | ||||
|     override var mainUrl = "https://filman.cc" | ||||
|     override var name = "filman.cc" | ||||
|     override val lang = "pl" | ||||
|     override var lang = "pl" | ||||
|     override val hasMainPage = true | ||||
|     override val supportedTypes = setOf( | ||||
|         TvType.Movie, | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class FrenchStreamProvider : MainAPI() { | |||
|     override var name = "French Stream" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "fr" | ||||
|     override var lang = "fr" | ||||
|     override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) | ||||
| 
 | ||||
|     override suspend fun search(query: String): List<SearchResponse> { | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ import org.jsoup.Jsoup | |||
| class HDMovie5 : MainAPI() { | ||||
|     override var mainUrl = "https://hdmovie5.mba" | ||||
|     override var name = "HDMovie" | ||||
|     override val lang = "hi" | ||||
|     override var lang = "hi" | ||||
| 
 | ||||
|     override val hasQuickSearch = true | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ class LayarKacaProvider : MainAPI() { | |||
|     override var mainUrl = "https://149.56.24.226" | ||||
|     override var name = "LayarKaca" | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
|     override val supportedTypes = setOf( | ||||
|         TvType.Movie, | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import org.jsoup.Jsoup | |||
| import org.jsoup.nodes.Element | ||||
| 
 | ||||
| class MyCimaProvider : MainAPI() { | ||||
|     override val lang = "ar" | ||||
|     override var lang = "ar" | ||||
|     override var mainUrl = "https://mycima.tv" | ||||
|     override var name = "MyCima" | ||||
|     override val usesWebView = false | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class PeliSmartProvider: MainAPI() { | ||||
|     override var mainUrl = "https://pelismart.com" | ||||
|     override var name = "PeliSmart" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class PelisflixProvider : MainAPI() { | ||||
|     override var mainUrl = "https://pelisflix.li" | ||||
|     override var name = "Pelisflix" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import org.jsoup.nodes.Element | |||
| class PelisplusHDProvider:MainAPI() { | ||||
|     override var mainUrl = "https://pelisplushd.net" | ||||
|     override var name = "PelisplusHD" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ import org.jsoup.Jsoup | |||
|  */ | ||||
| 
 | ||||
| open class PelisplusProviderTemplate : MainAPI() { | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     open val homePageUrlList = listOf<String>() | ||||
| 
 | ||||
| //    // mainUrl is good to have as a holder for the url to make future changes easier. | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class PinoyHDXyzProvider : MainAPI() { | ||||
|     override var name = "Pinoy-HD" | ||||
|     override var mainUrl = "https://www.pinoy-hd.xyz" | ||||
|     override val lang = "tl" | ||||
|     override var lang = "tl" | ||||
|     override val supportedTypes = setOf(TvType.AsianDrama) | ||||
|     override val hasDownloadSupport = true | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class PinoyMoviePediaProvider : MainAPI() { | ||||
|     override var name = "Pinoy Moviepedia" | ||||
|     override var mainUrl = "https://pinoymoviepedia.ru" | ||||
|     override val lang = "tl" | ||||
|     override var lang = "tl" | ||||
|     override val supportedTypes = setOf(TvType.AsianDrama) | ||||
|     override val hasDownloadSupport = true | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ import org.jsoup.select.Elements | |||
| class PinoyMoviesEsProvider : MainAPI() { | ||||
|     override var name = "Pinoy Movies" | ||||
|     override var mainUrl = "https://pinoymovies.es" | ||||
|     override val lang = "tl" | ||||
|     override var lang = "tl" | ||||
|     override val supportedTypes = setOf(TvType.AsianDrama) | ||||
|     override val hasDownloadSupport = false | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ class RebahinProvider : MainAPI() { | |||
|     override var mainUrl = "http://167.88.14.149" | ||||
|     override var name = "Rebahin" | ||||
|     override val hasMainPage = true | ||||
|     override val lang = "id" | ||||
|     override var lang = "id" | ||||
|     override val hasDownloadSupport = true | ||||
|     override val supportedTypes = setOf( | ||||
|         TvType.Movie, | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor | |||
| class SeriesflixProvider : MainAPI() { | ||||
|     override var mainUrl = "https://seriesflix.video" | ||||
|     override var name = "Seriesflix" | ||||
|     override val lang = "es" | ||||
|     override var lang = "es" | ||||
|     override val hasMainPage = true | ||||
|     override val hasChromecastSupport = true | ||||
|     override val hasDownloadSupport = true | ||||
|  |  | |||
|  | @ -127,7 +127,7 @@ data class TrailerElement( | |||
| 
 | ||||
| 
 | ||||
| class StreamingcommunityProvider : MainAPI() { | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override var mainUrl = "https://streamingcommunity.press" | ||||
|     override var name = "Streamingcommunity" | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import com.lagradost.cloudstream3.app | |||
| import com.lagradost.cloudstream3.utils.* | ||||
| 
 | ||||
| class TantifilmProvider : MainAPI() { | ||||
|     override val lang = "it" | ||||
|     override var lang = "it" | ||||
|     override var mainUrl = "https://www.tantifilm.rodeo" | ||||
|     override var name = "Tantifilm" | ||||
|     override val hasMainPage = true | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import org.jsoup.Jsoup | |||
| class VfFilmProvider : MainAPI() { | ||||
|     override var mainUrl = "https://vf-film.me" | ||||
|     override var name = "vf-film.me" | ||||
|     override val lang = "fr" | ||||
|     override var lang = "fr" | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = false | ||||
|     override val hasChromecastSupport = false | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import org.jsoup.Jsoup | |||
| class VfSerieProvider : MainAPI() { | ||||
|     override var mainUrl = "https://vf-serie.org" | ||||
|     override var name = "vf-serie.org" | ||||
|     override val lang = "fr" | ||||
|     override var lang = "fr" | ||||
| 
 | ||||
|     override val hasQuickSearch = false | ||||
|     override val hasMainPage = false | ||||
|  |  | |||
|  | @ -13,12 +13,12 @@ class APIRepository(val api: MainAPI) { | |||
|         val noneApi = object : MainAPI() { | ||||
|             override var name = "None" | ||||
|             override val supportedTypes = emptySet<TvType>() | ||||
|             override val lang = "" | ||||
|             override var lang = "" | ||||
|         } | ||||
|         val randomApi = object : MainAPI() { | ||||
|             override var name = "Random" | ||||
|             override val supportedTypes = emptySet<TvType>() | ||||
|             override val lang = "" | ||||
|             override var lang = "" | ||||
|         } | ||||
| 
 | ||||
|         fun isInvalidData(data: String): Boolean { | ||||
|  |  | |||
|  | @ -6,12 +6,18 @@ import android.os.Build | |||
| import android.os.Bundle | ||||
| import android.os.Environment | ||||
| import android.view.View | ||||
| import android.widget.Toast | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.preference.PreferenceFragmentCompat | ||||
| import androidx.preference.PreferenceManager | ||||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import com.hippo.unifile.UniFile | ||||
| import com.lagradost.cloudstream3.APIHolder.allProviders | ||||
| import com.lagradost.cloudstream3.AcraApplication | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.getKey | ||||
| import com.lagradost.cloudstream3.AcraApplication.Companion.setKey | ||||
| import com.lagradost.cloudstream3.CommonActivity.showToast | ||||
| import com.lagradost.cloudstream3.R | ||||
| import com.lagradost.cloudstream3.app | ||||
| import com.lagradost.cloudstream3.mvvm.logError | ||||
|  | @ -20,9 +26,15 @@ import com.lagradost.cloudstream3.network.initClient | |||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref | ||||
| import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar | ||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog | ||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard | ||||
| import com.lagradost.cloudstream3.utils.USER_PROVIDER_API | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath | ||||
| import kotlinx.android.synthetic.main.add_remove_sites.* | ||||
| import kotlinx.android.synthetic.main.add_site_input.* | ||||
| import java.io.File | ||||
| 
 | ||||
| class SettingsGeneral : PreferenceFragmentCompat() { | ||||
|  | @ -31,6 +43,17 @@ class SettingsGeneral : PreferenceFragmentCompat() { | |||
|         setUpToolbar(R.string.category_general) | ||||
|     } | ||||
| 
 | ||||
|     data class CustomSite( | ||||
|         @JsonProperty("parentJavaClass") // javaClass.simpleName | ||||
|         val parentJavaClass: String, | ||||
|         @JsonProperty("name") | ||||
|         val name: String, | ||||
|         @JsonProperty("url") | ||||
|         val url: String, | ||||
|         @JsonProperty("lang") | ||||
|         val lang: String, | ||||
|     ) | ||||
| 
 | ||||
|     // Open file picker | ||||
|     private val pathPicker = | ||||
|         registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> | ||||
|  | @ -64,6 +87,94 @@ class SettingsGeneral : PreferenceFragmentCompat() { | |||
|         setPreferencesFromResource(R.xml.settins_general, rootKey) | ||||
|         val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) | ||||
| 
 | ||||
|         fun getCurrent(): MutableList<CustomSite> { | ||||
|             return getKey<Array<CustomSite>>(USER_PROVIDER_API)?.toMutableList() | ||||
|                 ?: mutableListOf() | ||||
|         } | ||||
| 
 | ||||
|         fun showAdd() { | ||||
|             val providers = allProviders.distinctBy { it.javaClass }.sortedBy { it.name } | ||||
|             activity?.showDialog( | ||||
|                 providers.map { "${it.name} (${it.mainUrl})" }, | ||||
|                 -1, | ||||
|                 context?.getString(R.string.add_site_pref) ?: return, | ||||
|                 true, | ||||
|                 {}) { selection -> | ||||
|                 val provider = providers.getOrNull(selection) ?: return@showDialog | ||||
| 
 | ||||
|                 val builder = | ||||
|                     AlertDialog.Builder(context ?: return@showDialog, R.style.AlertDialogCustom) | ||||
|                         .setView(R.layout.add_site_input) | ||||
| 
 | ||||
|                 val dialog = builder.create() | ||||
|                 dialog.show() | ||||
| 
 | ||||
|                 dialog.text2?.text = provider.name | ||||
|                 dialog.apply_btt?.setOnClickListener { | ||||
|                     val name = dialog.site_name_input?.text?.toString() | ||||
|                     val url = dialog.site_url_input?.text?.toString() | ||||
|                     val lang = dialog.site_lang_input?.text?.toString() | ||||
|                     val realLang = if (lang.isNullOrBlank()) provider.lang else lang | ||||
|                     if (url.isNullOrBlank() || name.isNullOrBlank() || realLang.length != 2) { | ||||
|                         showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT) | ||||
|                         return@setOnClickListener | ||||
|                     } | ||||
| 
 | ||||
|                     val current = getCurrent() | ||||
|                     val newSite = CustomSite(provider.javaClass.simpleName, name, url, realLang) | ||||
|                     current.add(newSite) | ||||
|                     setKey(USER_PROVIDER_API, current.toTypedArray()) | ||||
| 
 | ||||
|                     dialog.dismissSafe(activity) | ||||
|                 } | ||||
|                 dialog.cancel_btt?.setOnClickListener { | ||||
|                     dialog.dismissSafe(activity) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         fun showDelete() { | ||||
|             val current = getCurrent() | ||||
| 
 | ||||
|             activity?.showMultiDialog( | ||||
|                 current.map { it.name }, | ||||
|                 listOf(), | ||||
|                 context?.getString(R.string.remove_site_pref) ?: return, | ||||
|                 {}) { indexes -> | ||||
|                 current.removeAll(indexes.map { current[it] }) | ||||
|                 setKey(USER_PROVIDER_API, current.toTypedArray()) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         fun showAddOrDelete() { | ||||
|             val builder = | ||||
|                 AlertDialog.Builder(context ?: return, R.style.AlertDialogCustom) | ||||
|                     .setView(R.layout.add_remove_sites) | ||||
| 
 | ||||
|             val dialog = builder.create() | ||||
|             dialog.show() | ||||
| 
 | ||||
|             dialog.add_site?.setOnClickListener { | ||||
|                 showAdd() | ||||
|                 dialog.dismissSafe(activity) | ||||
|             } | ||||
|             dialog.remove_site?.setOnClickListener { | ||||
|                 showDelete() | ||||
|                 dialog.dismissSafe(activity) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         getPref(R.string.override_site_key)?.setOnPreferenceClickListener { _ -> | ||||
| 
 | ||||
|             if (getCurrent().isEmpty()) { | ||||
|                 showAdd() | ||||
|             } else { | ||||
|                 showAddOrDelete() | ||||
|             } | ||||
| 
 | ||||
|             return@setOnPreferenceClickListener true | ||||
|         } | ||||
| 
 | ||||
|         getPref(R.string.legal_notice_key)?.setOnPreferenceClickListener { | ||||
|             val builder: AlertDialog.Builder = | ||||
|                 AlertDialog.Builder(it.context, R.style.AlertDialogCustom) | ||||
|  | @ -72,7 +183,7 @@ class SettingsGeneral : PreferenceFragmentCompat() { | |||
|             builder.show() | ||||
|             return@setOnPreferenceClickListener true | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         getPref(R.string.dns_key)?.setOnPreferenceClickListener { | ||||
|             val prefNames = resources.getStringArray(R.array.dns_pref) | ||||
|             val prefValues = resources.getIntArray(R.array.dns_pref_values) | ||||
|  | @ -177,6 +288,5 @@ class SettingsGeneral : PreferenceFragmentCompat() { | |||
|         } catch (e: Exception) { | ||||
|             e.printStackTrace() | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|  | @ -14,6 +14,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_key" | ||||
| const val HOMEPAGE_API = "home_api_used" | ||||
| const val USER_PROVIDER_API = "user_custom_sites" | ||||
| 
 | ||||
| const val PREFERENCES_NAME = "rebuild_preference" | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,23 +14,33 @@ import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes | |||
| import com.lagradost.cloudstream3.utils.UIHelper.setImage | ||||
| 
 | ||||
| object SingleSelectionHelper { | ||||
|     fun Activity.showOptionSelectStringRes( | ||||
|     fun Activity?.showOptionSelectStringRes( | ||||
|         view: View?, | ||||
|         poster: String?, | ||||
|         options: List<Int>, | ||||
|         tvOptions: List<Int> = listOf(), | ||||
|         callback: (Pair<Boolean, Int>) -> Unit | ||||
|     ) { | ||||
|         this.showOptionSelect(view, poster, options.map { this.getString(it) },tvOptions.map { this.getString(it) }, callback) | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         this.showOptionSelect( | ||||
|             view, | ||||
|             poster, | ||||
|             options.map { this.getString(it) }, | ||||
|             tvOptions.map { this.getString(it) }, | ||||
|             callback | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     private fun Activity.showOptionSelect( | ||||
|     private fun Activity?.showOptionSelect( | ||||
|         view: View?, | ||||
|         poster: String?, | ||||
|         options: List<String>, | ||||
|         tvOptions: List<String>, | ||||
|         callback: (Pair<Boolean, Int>) -> Unit | ||||
|     ) { | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         if (this.isTvSettings()) { | ||||
|             val builder = | ||||
|                 AlertDialog.Builder(this, R.style.AlertDialogCustom) | ||||
|  | @ -41,12 +51,13 @@ object SingleSelectionHelper { | |||
| 
 | ||||
|             dialog.findViewById<ListView>(R.id.listview1)?.let { listView -> | ||||
|                 listView.choiceMode = AbsListView.CHOICE_MODE_SINGLE | ||||
|                 listView.adapter = ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice_color).apply { | ||||
|                     addAll(tvOptions) | ||||
|                 } | ||||
|                 listView.adapter = | ||||
|                     ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice_color).apply { | ||||
|                         addAll(tvOptions) | ||||
|                     } | ||||
| 
 | ||||
|                 listView.setOnItemClickListener { _, _, i, _ -> | ||||
|                     callback.invoke(Pair(true,i)) | ||||
|                     callback.invoke(Pair(true, i)) | ||||
|                     dialog.dismissSafe(this) | ||||
|                 } | ||||
|             } | ||||
|  | @ -62,12 +73,12 @@ object SingleSelectionHelper { | |||
|                     s | ||||
|                 ) | ||||
|             }) { | ||||
|                 callback(Pair(false,this.itemId)) | ||||
|                 callback(Pair(false, this.itemId)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun Activity.showDialog( | ||||
|     fun Activity?.showDialog( | ||||
|         dialog: Dialog, | ||||
|         items: List<String>, | ||||
|         selectedIndex: List<Int>, | ||||
|  | @ -77,6 +88,8 @@ object SingleSelectionHelper { | |||
|         callback: (List<Int>) -> Unit, | ||||
|         dismissCallback: () -> Unit | ||||
|     ) { | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         val realShowApply = showApply || isMultiSelect | ||||
|         val listView = dialog.findViewById<ListView>(R.id.listview1)!! | ||||
|         val textView = dialog.findViewById<TextView>(R.id.text1)!! | ||||
|  | @ -145,8 +158,7 @@ object SingleSelectionHelper { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     private fun Activity.showInputDialog( | ||||
|     private fun Activity?.showInputDialog( | ||||
|         dialog: Dialog, | ||||
|         value: String, | ||||
|         name: String, | ||||
|  | @ -154,6 +166,8 @@ object SingleSelectionHelper { | |||
|         callback: (String) -> Unit, | ||||
|         dismissCallback: () -> Unit | ||||
|     ) { | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         val inputView = dialog.findViewById<EditText>(R.id.nginx_text_input)!! | ||||
|         val textView = dialog.findViewById<TextView>(R.id.text1)!! | ||||
|         val applyButton = dialog.findViewById<TextView>(R.id.apply_btt)!! | ||||
|  | @ -184,13 +198,15 @@ object SingleSelectionHelper { | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     fun Activity.showMultiDialog( | ||||
|     fun Activity?.showMultiDialog( | ||||
|         items: List<String>, | ||||
|         selectedIndex: List<Int>, | ||||
|         name: String, | ||||
|         dismissCallback: () -> Unit, | ||||
|         callback: (List<Int>) -> Unit, | ||||
|     ) { | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         val builder = | ||||
|             AlertDialog.Builder(this, R.style.AlertDialogCustom) | ||||
|                 .setView(R.layout.bottom_selection_dialog) | ||||
|  | @ -200,7 +216,7 @@ object SingleSelectionHelper { | |||
|         showDialog(dialog, items, selectedIndex, name, true, true, callback, dismissCallback) | ||||
|     } | ||||
| 
 | ||||
|     fun Activity.showDialog( | ||||
|     fun Activity?.showDialog( | ||||
|         items: List<String>, | ||||
|         selectedIndex: Int, | ||||
|         name: String, | ||||
|  | @ -208,6 +224,8 @@ object SingleSelectionHelper { | |||
|         dismissCallback: () -> Unit, | ||||
|         callback: (Int) -> Unit, | ||||
|     ) { | ||||
|         if(this == null) return | ||||
| 
 | ||||
|         val builder = | ||||
|             AlertDialog.Builder(this, R.style.AlertDialogCustom) | ||||
|                 .setView(R.layout.bottom_selection_dialog) | ||||
|  | @ -227,14 +245,15 @@ object SingleSelectionHelper { | |||
|     } | ||||
| 
 | ||||
|     /** Only for a low amount of items */ | ||||
|     fun Activity.showBottomDialog( | ||||
|     fun Activity?.showBottomDialog( | ||||
|         items: List<String>, | ||||
|         selectedIndex: Int, | ||||
|         name: String, | ||||
|         showApply: Boolean, | ||||
|          dismissCallback: () -> Unit, | ||||
|         dismissCallback: () -> Unit, | ||||
|         callback: (Int) -> Unit, | ||||
|     ) { | ||||
|         if (this == null) return | ||||
|         val builder = | ||||
|             BottomSheetDialog(this) | ||||
|         builder.setContentView(R.layout.bottom_selection_dialog) | ||||
|  | @ -252,12 +271,12 @@ object SingleSelectionHelper { | |||
|         ) | ||||
|     } | ||||
| 
 | ||||
|         fun Activity.showNginxTextInputDialog( | ||||
|             name: String, | ||||
|             value: String, | ||||
|             textInputType: Int?, | ||||
|             dismissCallback: () -> Unit, | ||||
|             callback: (String) -> Unit, | ||||
|     fun Activity.showNginxTextInputDialog( | ||||
|         name: String, | ||||
|         value: String, | ||||
|         textInputType: Int?, | ||||
|         dismissCallback: () -> Unit, | ||||
|         callback: (String) -> Unit, | ||||
|     ) { | ||||
|         val builder = BottomSheetDialog(this)  // probably the stuff at the bottom | ||||
|         builder.setContentView(R.layout.bottom_input_dialog)  // input layout | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
| <vector android:height="24dp" android:tint="?attr/white" | ||||
|     android:viewportHeight="24" android:viewportWidth="24" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> | ||||
|  |  | |||
							
								
								
									
										19
									
								
								app/src/main/res/layout/add_remove_sites.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/src/main/res/layout/add_remove_sites.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|         android:orientation="vertical" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent"> | ||||
| 
 | ||||
|     <TextView | ||||
|             android:id="@+id/add_site" | ||||
|             android:text="@string/add_site_pref" | ||||
|             style="@style/SettingsItem"> | ||||
| 
 | ||||
|         <requestFocus /> | ||||
|     </TextView> | ||||
| 
 | ||||
|     <TextView | ||||
|             android:id="@+id/remove_site" | ||||
|             android:text="@string/remove_site_pref" | ||||
|             style="@style/SettingsItem" /> | ||||
| </LinearLayout> | ||||
							
								
								
									
										117
									
								
								app/src/main/res/layout/add_site_input.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								app/src/main/res/layout/add_site_input.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,117 @@ | |||
| <?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:layout_height="match_parent"> | ||||
| 
 | ||||
|     <TextView | ||||
|             android:layout_marginTop="20dp" | ||||
|             android:layout_marginBottom="10dp" | ||||
|             android:id="@+id/text1" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
| 
 | ||||
|             android:layout_gravity="center_vertical" | ||||
|             android:layout_rowWeight="1" | ||||
| 
 | ||||
|             android:paddingStart="?android:attr/listPreferredItemPaddingStart" | ||||
|             android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" | ||||
|             android:textColor="?attr/textColor" | ||||
|             android:textSize="20sp" | ||||
|             android:textStyle="bold" | ||||
|             android:text="@string/add_site_pref" /> | ||||
| 
 | ||||
|     <TextView | ||||
|             android:layout_marginBottom="10dp" | ||||
| 
 | ||||
|             android:id="@+id/text2" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
| 
 | ||||
|             android:layout_gravity="center_vertical" | ||||
|             android:layout_rowWeight="1" | ||||
| 
 | ||||
|             android:paddingStart="?android:attr/listPreferredItemPaddingStart" | ||||
|             android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" | ||||
|             android:textColor="?attr/grayTextColor" | ||||
|             android:textSize="15sp" | ||||
|             tools:text="Gogoanime" /> | ||||
| 
 | ||||
|     <LinearLayout | ||||
|             android:orientation="vertical" | ||||
|             android:layout_marginBottom="60dp" | ||||
|             android:layout_marginHorizontal="10dp" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content"> | ||||
| 
 | ||||
|         <EditText | ||||
|                 android:textColorHint="?attr/grayTextColor" | ||||
|                 android:hint="@string/example_site_name" | ||||
|                 android:autofillHints="username" | ||||
|                 android:id="@+id/site_name_input" | ||||
|                 android:nextFocusRight="@id/cancel_btt" | ||||
|                 android:nextFocusLeft="@id/apply_btt" | ||||
|                 android:nextFocusDown="@id/site_url_input" | ||||
|                 android:requiresFadingEdge="vertical" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:inputType="text" | ||||
|                 tools:ignore="LabelFor" /> | ||||
| 
 | ||||
|         <EditText | ||||
|                 android:textColorHint="?attr/grayTextColor" | ||||
|                 android:hint="@string/example_site_url" | ||||
|                 android:id="@+id/site_url_input" | ||||
|                 android:nextFocusRight="@id/cancel_btt" | ||||
|                 android:nextFocusLeft="@id/apply_btt" | ||||
|                 android:nextFocusUp="@id/site_name_input" | ||||
|                 android:nextFocusDown="@id/site_lang_input" | ||||
| 
 | ||||
|                 android:requiresFadingEdge="vertical" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:inputType="textUri" | ||||
|                 tools:ignore="LabelFor" /> | ||||
| 
 | ||||
|         <EditText | ||||
|                 android:textColorHint="?attr/grayTextColor" | ||||
|                 android:hint="@string/example_lang_name" | ||||
|                 android:autofillHints="username" | ||||
|                 android:id="@+id/site_lang_input" | ||||
|                 android:nextFocusUp="@id/site_url_input" | ||||
|                 android:nextFocusRight="@id/cancel_btt" | ||||
|                 android:nextFocusLeft="@id/apply_btt" | ||||
|                 android:nextFocusDown="@id/apply_btt" | ||||
|                 android:requiresFadingEdge="vertical" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:inputType="text" | ||||
|                 tools:ignore="LabelFor" /> | ||||
|     </LinearLayout> | ||||
| 
 | ||||
|     <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/add_site_pref" | ||||
|                 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> | ||||
|  | @ -50,6 +50,7 @@ | |||
|     <string name="bottom_title_key" translatable="false">bottom_title_key</string> | ||||
|     <string name="poster_ui_key" translatable="false">poster_ui_key</string> | ||||
|     <string name="subtitles_encoding_key" translatable="false">subtitles_encoding_key</string> | ||||
|     <string name="override_site_key" translatable="false">override_site_key</string> | ||||
| 
 | ||||
|     <!-- FORMAT MIGHT TRANSLATE, WILL CAUSE CRASH IF APPLIED WRONG --> | ||||
|     <string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string> | ||||
|  | @ -382,6 +383,10 @@ | |||
|     <string name="dns_pref">DNS over HTTPS</string> | ||||
|     <string name="dns_pref_summary">Useful for bypassing ISP blocks</string> | ||||
| 
 | ||||
|     <string name="add_site_pref">Add site</string> | ||||
|     <string name="remove_site_pref">Remove site</string> | ||||
|     <string name="add_site_summary">Add a clone of an existing site, with a different url</string> | ||||
| 
 | ||||
|     <string name="download_path_pref">Download path</string> | ||||
| 
 | ||||
|     <string name="nginx_url_pref">Nginx server url</string> | ||||
|  | @ -440,6 +445,9 @@ | |||
|     <string name="example_username">MyCoolUsername</string> | ||||
|     <string name="example_email">hello@world.com</string> | ||||
|     <string name="example_ip">127.0.0.1</string> | ||||
|     <string name="example_site_name">MyCoolSite</string> | ||||
|     <string name="example_site_url">example.com</string> | ||||
|     <string name="example_lang_name">Language code (en)</string> | ||||
| 
 | ||||
|     <!-- | ||||
|     <string name="mal_account_settings" translatable="false">MAL</string> | ||||
|  | @ -529,6 +537,8 @@ | |||
|     <string name="title">Title</string> | ||||
|     <string name="resolution">Resolution</string> | ||||
|     <string name="error_invalid_id">Invalid id</string> | ||||
|     <string name="error_invalid_data">Invalid data</string> | ||||
|     <string name="error">Error</string> | ||||
|     <string name="subtitles_remove_captions">Remove closed captions from subtitles</string> | ||||
|     <string name="subtitles_remove_bloat">Remove bloat from subtitles</string> | ||||
|     <string name="extras">Extras</string> | ||||
|  |  | |||
|  | @ -1,6 +1,11 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|         xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||
|     <Preference | ||||
|             android:key="@string/override_site_key" | ||||
|             android:title="@string/add_site_pref" | ||||
|             android:summary="@string/add_site_summary" | ||||
|             android:icon="@drawable/ic_baseline_add_24" /> | ||||
| 
 | ||||
|     <Preference | ||||
|             android:key="@string/dns_key" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue