added site cloner

This commit is contained in:
LagradOst 2022-06-17 00:07:07 +02:00
parent 86aed5b830
commit 5f542ec81a
58 changed files with 391 additions and 82 deletions

View File

@ -155,11 +155,11 @@
<service <service
android:name=".services.VideoDownloadService" android:name=".services.VideoDownloadService"
android:enabled="true" android:enabled="true"
android:exported="false"></service> android:exported="false" />
<activity <activity
android:exported="false" android:exported="false"
android:name=".ui.ControllerActivity"></activity> android:name=".ui.ControllerActivity" />
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"

View File

@ -39,7 +39,7 @@ object APIHolder {
private const val defProvider = 0 private const val defProvider = 0
val allProviders by lazy { val allProviders =
arrayListOf( arrayListOf(
// Movie providers // Movie providers
ElifilmsProvider(), ElifilmsProvider(),
@ -132,7 +132,7 @@ object APIHolder {
NginxProvider(), NginxProvider(),
OlgplyProvider(), OlgplyProvider(),
) )
}
fun initAll() { fun initAll() {
for (api in allProviders) { for (api in allProviders) {
@ -142,7 +142,7 @@ object APIHolder {
} }
var apis: List<MainAPI> = arrayListOf() var apis: List<MainAPI> = arrayListOf()
private var apiMap: Map<String, Int>? = null var apiMap: Map<String, Int>? = null
private fun initMap() { private fun initMap() {
if (apiMap == null) if (apiMap == null)
@ -357,6 +357,7 @@ abstract class MainAPI {
} }
fun overrideWithNewData(data: ProvidersInfoJson) { fun overrideWithNewData(data: ProvidersInfoJson) {
if (!canBeOverridden) return
this.name = data.name this.name = data.name
if (data.url.isNotBlank() && data.url != "NONE") if (data.url.isNotBlank() && data.url != "NONE")
this.mainUrl = data.url this.mainUrl = data.url
@ -366,10 +367,11 @@ abstract class MainAPI {
open var name = "NONE" open var name = "NONE"
open var mainUrl = "NONE" open var mainUrl = "NONE"
open var storedCredentials: String? = null 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 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*/ /**If link is stored in the "data" string, so links can be instantly loaded*/
open val instantLinkLoading = false open val instantLinkLoading = false
@ -908,7 +910,7 @@ interface LoadResponse {
} }
fun LoadResponse.addTrailer(trailerUrls: List<String>?) { fun LoadResponse.addTrailer(trailerUrls: List<String>?) {
if(trailerUrls == null) return if (trailerUrls == null) return
if (this.trailers == null) { if (this.trailers == null) {
this.trailers = trailerUrls this.trailers = trailerUrls
} else { } else {

View File

@ -47,6 +47,7 @@ import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings 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.isCastApiAvailable
import com.lagradost.cloudstream3.utils.AppUtils.loadCache import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.AppUtils.loadResult 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.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.requestRW import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.cloudstream3.utils.USER_PROVIDER_API
import com.lagradost.nicehttp.Requests import com.lagradost.nicehttp.Requests
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.android.synthetic.main.fragment_result_swipe.*
@ -515,6 +517,26 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
apis = allProviders 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) loadThemes(this)
updateLocale() updateLocale()
app.initClient(this) app.initClient(this)

View File

@ -16,7 +16,7 @@ import org.jsoup.nodes.Element
class AnimeWorldProvider : MainAPI() { class AnimeWorldProvider : MainAPI() {
override var mainUrl = "https://www.animeworld.tv" override var mainUrl = "https://www.animeworld.tv"
override var name = "AnimeWorld" override var name = "AnimeWorld"
override val lang = "it" override var lang = "it"
override val hasMainPage = true override val hasMainPage = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -13,7 +13,7 @@ class AnimefenixProvider:MainAPI() {
override var mainUrl = "https://animefenix.com" override var mainUrl = "https://animefenix.com"
override var name = "Animefenix" override var name = "Animefenix"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -11,7 +11,7 @@ import kotlin.collections.ArrayList
class AnimeflvIOProvider:MainAPI() { class AnimeflvIOProvider:MainAPI() {
override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to override var mainUrl = "https://animeflv.io" //Also scrapes from animeid.to
override var name = "Animeflv.io" override var name = "Animeflv.io"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -24,7 +24,7 @@ class AnimeflvnetProvider : MainAPI() {
override var mainUrl = "https://www3.animeflv.net" override var mainUrl = "https://www3.animeflv.net"
override var name = "Animeflv.net" override var name = "Animeflv.net"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -11,7 +11,7 @@ import org.jsoup.nodes.Element
class DreamSubProvider : MainAPI() { class DreamSubProvider : MainAPI() {
override var mainUrl = "https://dreamsub.me" override var mainUrl = "https://dreamsub.me"
override var name = "DreamSub" override var name = "DreamSub"
override val lang = "it" override var lang = "it"
override val hasMainPage = true override val hasMainPage = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -14,7 +14,7 @@ class GomunimeProvider : MainAPI() {
override var name = "Gomunime" override var name = "Gomunime"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -22,7 +22,7 @@ class JKAnimeProvider : MainAPI() {
override var mainUrl = "https://jkanime.net" override var mainUrl = "https://jkanime.net"
override var name = "JKAnime" override var name = "JKAnime"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -12,7 +12,7 @@ class KuramanimeProvider : MainAPI() {
override var name = "Kuramanime" override var name = "Kuramanime"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -13,7 +13,7 @@ class KuronimeProvider : MainAPI() {
override var name = "Kuronime" override var name = "Kuronime"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -24,7 +24,7 @@ class MonoschinosProvider : MainAPI() {
override var mainUrl = "https://monoschinos2.com" override var mainUrl = "https://monoschinos2.com"
override var name = "Monoschinos" override var name = "Monoschinos"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -15,7 +15,7 @@ class MundoDonghuaProvider : MainAPI() {
override var mainUrl = "https://www.mundodonghua.com" override var mainUrl = "https://www.mundodonghua.com"
override var name = "MundoDonghua" override var name = "MundoDonghua"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -11,7 +11,7 @@ class NeonimeProvider : MainAPI() {
override var name = "Neonime" override var name = "Neonime"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -15,7 +15,7 @@ class NontonAnimeIDProvider : MainAPI() {
override var name = "NontonAnimeID" override var name = "NontonAnimeID"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -13,7 +13,7 @@ class OploverzProvider : MainAPI() {
override var name = "Oploverz" override var name = "Oploverz"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(

View File

@ -12,7 +12,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
class CrossTmdbProvider : TmdbProvider() { class CrossTmdbProvider : TmdbProvider() {
override var name = "MultiMovie" override var name = "MultiMovie"
override val apiName = "MultiMovie" override val apiName = "MultiMovie"
override val lang = "en" override var lang = "en"
override val useMetaLoadResponse = true override val useMetaLoadResponse = true
override val usesWebView = true override val usesWebView = true
override val supportedTypes = setOf(TvType.Movie) override val supportedTypes = setOf(TvType.Movie)

View File

@ -12,7 +12,7 @@ import com.lagradost.cloudstream3.utils.SyncUtil
// wont be implemented // wont be implemented
class MultiAnimeProvider : MainAPI() { class MultiAnimeProvider : MainAPI() {
override var name = "MultiAnime" override var name = "MultiAnime"
override val lang = "en" override var lang = "en"
override val usesWebView = true override val usesWebView = true
override val supportedTypes = setOf(TvType.Anime) override val supportedTypes = setOf(TvType.Anime)
private val syncApi: SyncAPI = aniListApi private val syncApi: SyncAPI = aniListApi

View File

@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.Qualities
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
class AkwamProvider : MainAPI() { class AkwamProvider : MainAPI() {
override val lang = "ar" override var lang = "ar"
override var mainUrl = "https://akwam.to" override var mainUrl = "https://akwam.to"
override var name = "Akwam" override var name = "Akwam"
override val usesWebView = false override val usesWebView = false

View File

@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
class AltadefinizioneProvider : MainAPI() { class AltadefinizioneProvider : MainAPI() {
override val lang = "it" override var lang = "it"
override var mainUrl = "https://altadefinizione.hair" override var mainUrl = "https://altadefinizione.hair"
override var name = "Altadefinizione" override var name = "Altadefinizione"
override val hasMainPage = true override val hasMainPage = true

View File

@ -6,7 +6,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.loadExtractor
class CineblogProvider : MainAPI() { class CineblogProvider : MainAPI() {
override val lang = "it" override var lang = "it"
override var mainUrl = "https://cb01.rip" override var mainUrl = "https://cb01.rip"
override var name = "CineBlog" override var name = "CineBlog"
override val hasMainPage = true override val hasMainPage = true

View File

@ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class CinecalidadProvider:MainAPI() { class CinecalidadProvider:MainAPI() {
override var mainUrl = "https://cinecalidad.lol" override var mainUrl = "https://cinecalidad.lol"
override var name = "Cinecalidad" override var name = "Cinecalidad"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class CuevanaProvider : MainAPI() { class CuevanaProvider : MainAPI() {
override var mainUrl = "https://cuevana3.me" override var mainUrl = "https://cuevana3.me"
override var name = "Cuevana" override var name = "Cuevana"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -23,7 +23,7 @@ class DoramasYTProvider : MainAPI() {
override var mainUrl = "https://doramasyt.com" override var mainUrl = "https://doramasyt.com"
override var name = "DoramasYT" override var name = "DoramasYT"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -15,7 +15,7 @@ class DramaidProvider : MainAPI() {
override var name = "DramaId" override var name = "DramaId"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val hasChromecastSupport = false override val hasChromecastSupport = false
override val supportedTypes = setOf(TvType.AsianDrama) override val supportedTypes = setOf(TvType.AsianDrama)

View File

@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
class EgyBestProvider : MainAPI() { class EgyBestProvider : MainAPI() {
override val lang = "ar" override var lang = "ar"
override var mainUrl = "https://www.egy.best" override var mainUrl = "https://www.egy.best"
override var name = "EgyBest" override var name = "EgyBest"
override val usesWebView = false override val usesWebView = false

View File

@ -1,19 +1,20 @@
package com.lagradost.cloudstream3.movieproviders package com.lagradost.cloudstream3.movieproviders
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.ExtractorLink
import kotlin.collections.ArrayList import com.lagradost.cloudstream3.utils.loadExtractor
class ElifilmsProvider:MainAPI() { class ElifilmsProvider : MainAPI() {
override var mainUrl: String = "https://elifilms.net" override var mainUrl: String = "https://elifilms.net"
override var name: String = "Elifilms" override var name: String = "Elifilms"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(
TvType.Movie, TvType.Movie,
) )
override suspend fun getMainPage(): HomePageResponse { override suspend fun getMainPage(): HomePageResponse {
val items = ArrayList<HomePageList>() val items = ArrayList<HomePageList>()
val newest = app.get(mainUrl).document.selectFirst("a.fav_link.premiera")?.attr("href") 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() if (items.size <= 0) throw ErrorLoadingException()
return HomePageResponse(items) return HomePageResponse(items)
} }
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
val url = "$mainUrl/?s=$query" val url = "$mainUrl/?s=$query"
val doc = app.get(url).document val doc = app.get(url).document
@ -52,6 +54,7 @@ class ElifilmsProvider:MainAPI() {
(MovieSearchResponse(name, href, this.name, TvType.Movie, poster, null)) (MovieSearchResponse(name, href, this.name, TvType.Movie, poster, null))
} }
} }
override suspend fun load(url: String): LoadResponse { override suspend fun load(url: String): LoadResponse {
val document = app.get(url, timeout = 120).document val document = app.get(url, timeout = 120).document
val title = document.selectFirst(".post_title h1")?.text() ?: "" val title = document.selectFirst(".post_title h1")?.text() ?: ""
@ -73,6 +76,7 @@ class ElifilmsProvider:MainAPI() {
tags tags
) )
} }
override suspend fun loadLinks( override suspend fun loadLinks(
data: String, data: String,
isCasting: Boolean, isCasting: Boolean,

View File

@ -8,7 +8,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class EntrepeliculasyseriesProvider:MainAPI() { class EntrepeliculasyseriesProvider:MainAPI() {
override var mainUrl = "https://entrepeliculasyseries.nu" override var mainUrl = "https://entrepeliculasyseries.nu"
override var name = "EntrePeliculasySeries" override var name = "EntrePeliculasySeries"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -20,7 +20,7 @@ class EstrenosDoramasProvider : MainAPI() {
override var mainUrl = "https://www23.estrenosdoramas.net" override var mainUrl = "https://www23.estrenosdoramas.net"
override var name = "EstrenosDoramas" override var name = "EstrenosDoramas"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -5,7 +5,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
class FaselHDProvider : MainAPI() { class FaselHDProvider : MainAPI() {
override val lang = "ar" override var lang = "ar"
override var mainUrl = "https://faselhd.io" override var mainUrl = "https://faselhd.io"
override var name = "FaselHD" override var name = "FaselHD"
override val usesWebView = false override val usesWebView = false

View File

@ -11,7 +11,7 @@ import org.jsoup.select.Elements
class FilmanProvider : MainAPI() { class FilmanProvider : MainAPI() {
override var mainUrl = "https://filman.cc" override var mainUrl = "https://filman.cc"
override var name = "filman.cc" override var name = "filman.cc"
override val lang = "pl" override var lang = "pl"
override val hasMainPage = true override val hasMainPage = true
override val supportedTypes = setOf( override val supportedTypes = setOf(
TvType.Movie, TvType.Movie,

View File

@ -12,7 +12,7 @@ class FrenchStreamProvider : MainAPI() {
override var name = "French Stream" override var name = "French Stream"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = true override val hasMainPage = true
override val lang = "fr" override var lang = "fr"
override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) override val supportedTypes = setOf(TvType.AnimeMovie, TvType.TvSeries, TvType.Movie)
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {

View File

@ -10,7 +10,7 @@ import org.jsoup.Jsoup
class HDMovie5 : MainAPI() { class HDMovie5 : MainAPI() {
override var mainUrl = "https://hdmovie5.mba" override var mainUrl = "https://hdmovie5.mba"
override var name = "HDMovie" override var name = "HDMovie"
override val lang = "hi" override var lang = "hi"
override val hasQuickSearch = true override val hasQuickSearch = true
override val hasMainPage = true override val hasMainPage = true

View File

@ -11,7 +11,7 @@ class LayarKacaProvider : MainAPI() {
override var mainUrl = "https://149.56.24.226" override var mainUrl = "https://149.56.24.226"
override var name = "LayarKaca" override var name = "LayarKaca"
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(
TvType.Movie, TvType.Movie,

View File

@ -8,7 +8,7 @@ import org.jsoup.Jsoup
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
class MyCimaProvider : MainAPI() { class MyCimaProvider : MainAPI() {
override val lang = "ar" override var lang = "ar"
override var mainUrl = "https://mycima.tv" override var mainUrl = "https://mycima.tv"
override var name = "MyCima" override var name = "MyCima"
override val usesWebView = false override val usesWebView = false

View File

@ -7,7 +7,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class PeliSmartProvider: MainAPI() { class PeliSmartProvider: MainAPI() {
override var mainUrl = "https://pelismart.com" override var mainUrl = "https://pelismart.com"
override var name = "PeliSmart" override var name = "PeliSmart"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class PelisflixProvider : MainAPI() { class PelisflixProvider : MainAPI() {
override var mainUrl = "https://pelisflix.li" override var mainUrl = "https://pelisflix.li"
override var name = "Pelisflix" override var name = "Pelisflix"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -8,7 +8,7 @@ import org.jsoup.nodes.Element
class PelisplusHDProvider:MainAPI() { class PelisplusHDProvider:MainAPI() {
override var mainUrl = "https://pelisplushd.net" override var mainUrl = "https://pelisplushd.net"
override var name = "PelisplusHD" override var name = "PelisplusHD"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -12,7 +12,7 @@ import org.jsoup.Jsoup
*/ */
open class PelisplusProviderTemplate : MainAPI() { open class PelisplusProviderTemplate : MainAPI() {
override val lang = "es" override var lang = "es"
open val homePageUrlList = listOf<String>() open val homePageUrlList = listOf<String>()
// // mainUrl is good to have as a holder for the url to make future changes easier. // // mainUrl is good to have as a holder for the url to make future changes easier.

View File

@ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class PinoyHDXyzProvider : MainAPI() { class PinoyHDXyzProvider : MainAPI() {
override var name = "Pinoy-HD" override var name = "Pinoy-HD"
override var mainUrl = "https://www.pinoy-hd.xyz" override var mainUrl = "https://www.pinoy-hd.xyz"
override val lang = "tl" override var lang = "tl"
override val supportedTypes = setOf(TvType.AsianDrama) override val supportedTypes = setOf(TvType.AsianDrama)
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val hasMainPage = true override val hasMainPage = true

View File

@ -10,7 +10,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class PinoyMoviePediaProvider : MainAPI() { class PinoyMoviePediaProvider : MainAPI() {
override var name = "Pinoy Moviepedia" override var name = "Pinoy Moviepedia"
override var mainUrl = "https://pinoymoviepedia.ru" override var mainUrl = "https://pinoymoviepedia.ru"
override val lang = "tl" override var lang = "tl"
override val supportedTypes = setOf(TvType.AsianDrama) override val supportedTypes = setOf(TvType.AsianDrama)
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val hasMainPage = true override val hasMainPage = true

View File

@ -15,7 +15,7 @@ import org.jsoup.select.Elements
class PinoyMoviesEsProvider : MainAPI() { class PinoyMoviesEsProvider : MainAPI() {
override var name = "Pinoy Movies" override var name = "Pinoy Movies"
override var mainUrl = "https://pinoymovies.es" override var mainUrl = "https://pinoymovies.es"
override val lang = "tl" override var lang = "tl"
override val supportedTypes = setOf(TvType.AsianDrama) override val supportedTypes = setOf(TvType.AsianDrama)
override val hasDownloadSupport = false override val hasDownloadSupport = false
override val hasMainPage = true override val hasMainPage = true

View File

@ -15,7 +15,7 @@ class RebahinProvider : MainAPI() {
override var mainUrl = "http://167.88.14.149" override var mainUrl = "http://167.88.14.149"
override var name = "Rebahin" override var name = "Rebahin"
override val hasMainPage = true override val hasMainPage = true
override val lang = "id" override var lang = "id"
override val hasDownloadSupport = true override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(
TvType.Movie, TvType.Movie,

View File

@ -9,7 +9,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor
class SeriesflixProvider : MainAPI() { class SeriesflixProvider : MainAPI() {
override var mainUrl = "https://seriesflix.video" override var mainUrl = "https://seriesflix.video"
override var name = "Seriesflix" override var name = "Seriesflix"
override val lang = "es" override var lang = "es"
override val hasMainPage = true override val hasMainPage = true
override val hasChromecastSupport = true override val hasChromecastSupport = true
override val hasDownloadSupport = true override val hasDownloadSupport = true

View File

@ -127,7 +127,7 @@ data class TrailerElement(
class StreamingcommunityProvider : MainAPI() { class StreamingcommunityProvider : MainAPI() {
override val lang = "it" override var lang = "it"
override var mainUrl = "https://streamingcommunity.press" override var mainUrl = "https://streamingcommunity.press"
override var name = "Streamingcommunity" override var name = "Streamingcommunity"
override val hasMainPage = true override val hasMainPage = true

View File

@ -6,7 +6,7 @@ import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
class TantifilmProvider : MainAPI() { class TantifilmProvider : MainAPI() {
override val lang = "it" override var lang = "it"
override var mainUrl = "https://www.tantifilm.rodeo" override var mainUrl = "https://www.tantifilm.rodeo"
override var name = "Tantifilm" override var name = "Tantifilm"
override val hasMainPage = true override val hasMainPage = true

View File

@ -9,7 +9,7 @@ import org.jsoup.Jsoup
class VfFilmProvider : MainAPI() { class VfFilmProvider : MainAPI() {
override var mainUrl = "https://vf-film.me" override var mainUrl = "https://vf-film.me"
override var name = "vf-film.me" override var name = "vf-film.me"
override val lang = "fr" override var lang = "fr"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = false override val hasMainPage = false
override val hasChromecastSupport = false override val hasChromecastSupport = false

View File

@ -9,7 +9,7 @@ import org.jsoup.Jsoup
class VfSerieProvider : MainAPI() { class VfSerieProvider : MainAPI() {
override var mainUrl = "https://vf-serie.org" override var mainUrl = "https://vf-serie.org"
override var name = "vf-serie.org" override var name = "vf-serie.org"
override val lang = "fr" override var lang = "fr"
override val hasQuickSearch = false override val hasQuickSearch = false
override val hasMainPage = false override val hasMainPage = false

View File

@ -13,12 +13,12 @@ class APIRepository(val api: MainAPI) {
val noneApi = object : MainAPI() { val noneApi = object : MainAPI() {
override var name = "None" override var name = "None"
override val supportedTypes = emptySet<TvType>() override val supportedTypes = emptySet<TvType>()
override val lang = "" override var lang = ""
} }
val randomApi = object : MainAPI() { val randomApi = object : MainAPI() {
override var name = "Random" override var name = "Random"
override val supportedTypes = emptySet<TvType>() override val supportedTypes = emptySet<TvType>()
override val lang = "" override var lang = ""
} }
fun isInvalidData(data: String): Boolean { fun isInvalidData(data: String): Boolean {

View File

@ -6,12 +6,18 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.view.View import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.fasterxml.jackson.annotation.JsonProperty
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import com.lagradost.cloudstream3.APIHolder.allProviders
import com.lagradost.cloudstream3.AcraApplication 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.R
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError 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.getPref
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog 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.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.USER_PROVIDER_API
import com.lagradost.cloudstream3.utils.VideoDownloadManager import com.lagradost.cloudstream3.utils.VideoDownloadManager
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getBasePath 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 import java.io.File
class SettingsGeneral : PreferenceFragmentCompat() { class SettingsGeneral : PreferenceFragmentCompat() {
@ -31,6 +43,17 @@ class SettingsGeneral : PreferenceFragmentCompat() {
setUpToolbar(R.string.category_general) 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 // Open file picker
private val pathPicker = private val pathPicker =
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
@ -64,6 +87,94 @@ class SettingsGeneral : PreferenceFragmentCompat() {
setPreferencesFromResource(R.xml.settins_general, rootKey) setPreferencesFromResource(R.xml.settins_general, rootKey)
val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext()) 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 { getPref(R.string.legal_notice_key)?.setOnPreferenceClickListener {
val builder: AlertDialog.Builder = val builder: AlertDialog.Builder =
AlertDialog.Builder(it.context, R.style.AlertDialogCustom) AlertDialog.Builder(it.context, R.style.AlertDialogCustom)
@ -72,7 +183,7 @@ class SettingsGeneral : PreferenceFragmentCompat() {
builder.show() builder.show()
return@setOnPreferenceClickListener true return@setOnPreferenceClickListener true
} }
getPref(R.string.dns_key)?.setOnPreferenceClickListener { getPref(R.string.dns_key)?.setOnPreferenceClickListener {
val prefNames = resources.getStringArray(R.array.dns_pref) val prefNames = resources.getStringArray(R.array.dns_pref)
val prefValues = resources.getIntArray(R.array.dns_pref_values) val prefValues = resources.getIntArray(R.array.dns_pref_values)
@ -177,6 +288,5 @@ class SettingsGeneral : PreferenceFragmentCompat() {
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
} }
} }

View File

@ -14,6 +14,7 @@ const val DOWNLOAD_HEADER_CACHE = "download_header_cache"
const val DOWNLOAD_EPISODE_CACHE = "download_episode_cache" const val DOWNLOAD_EPISODE_CACHE = "download_episode_cache"
const val VIDEO_PLAYER_BRIGHTNESS = "video_player_alpha_key" const val VIDEO_PLAYER_BRIGHTNESS = "video_player_alpha_key"
const val HOMEPAGE_API = "home_api_used" const val HOMEPAGE_API = "home_api_used"
const val USER_PROVIDER_API = "user_custom_sites"
const val PREFERENCES_NAME = "rebuild_preference" const val PREFERENCES_NAME = "rebuild_preference"

View File

@ -14,23 +14,33 @@ import com.lagradost.cloudstream3.utils.UIHelper.popupMenuNoIconsAndNoStringRes
import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.UIHelper.setImage
object SingleSelectionHelper { object SingleSelectionHelper {
fun Activity.showOptionSelectStringRes( fun Activity?.showOptionSelectStringRes(
view: View?, view: View?,
poster: String?, poster: String?,
options: List<Int>, options: List<Int>,
tvOptions: List<Int> = listOf(), tvOptions: List<Int> = listOf(),
callback: (Pair<Boolean, Int>) -> Unit 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?, view: View?,
poster: String?, poster: String?,
options: List<String>, options: List<String>,
tvOptions: List<String>, tvOptions: List<String>,
callback: (Pair<Boolean, Int>) -> Unit callback: (Pair<Boolean, Int>) -> Unit
) { ) {
if(this == null) return
if (this.isTvSettings()) { if (this.isTvSettings()) {
val builder = val builder =
AlertDialog.Builder(this, R.style.AlertDialogCustom) AlertDialog.Builder(this, R.style.AlertDialogCustom)
@ -41,12 +51,13 @@ object SingleSelectionHelper {
dialog.findViewById<ListView>(R.id.listview1)?.let { listView -> dialog.findViewById<ListView>(R.id.listview1)?.let { listView ->
listView.choiceMode = AbsListView.CHOICE_MODE_SINGLE listView.choiceMode = AbsListView.CHOICE_MODE_SINGLE
listView.adapter = ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice_color).apply { listView.adapter =
addAll(tvOptions) ArrayAdapter<String>(this, R.layout.sort_bottom_single_choice_color).apply {
} addAll(tvOptions)
}
listView.setOnItemClickListener { _, _, i, _ -> listView.setOnItemClickListener { _, _, i, _ ->
callback.invoke(Pair(true,i)) callback.invoke(Pair(true, i))
dialog.dismissSafe(this) dialog.dismissSafe(this)
} }
} }
@ -62,12 +73,12 @@ object SingleSelectionHelper {
s s
) )
}) { }) {
callback(Pair(false,this.itemId)) callback(Pair(false, this.itemId))
} }
} }
} }
fun Activity.showDialog( fun Activity?.showDialog(
dialog: Dialog, dialog: Dialog,
items: List<String>, items: List<String>,
selectedIndex: List<Int>, selectedIndex: List<Int>,
@ -77,6 +88,8 @@ object SingleSelectionHelper {
callback: (List<Int>) -> Unit, callback: (List<Int>) -> Unit,
dismissCallback: () -> Unit dismissCallback: () -> Unit
) { ) {
if(this == null) return
val realShowApply = showApply || isMultiSelect val realShowApply = showApply || isMultiSelect
val listView = dialog.findViewById<ListView>(R.id.listview1)!! val listView = dialog.findViewById<ListView>(R.id.listview1)!!
val textView = dialog.findViewById<TextView>(R.id.text1)!! val textView = dialog.findViewById<TextView>(R.id.text1)!!
@ -145,8 +158,7 @@ object SingleSelectionHelper {
} }
private fun Activity?.showInputDialog(
private fun Activity.showInputDialog(
dialog: Dialog, dialog: Dialog,
value: String, value: String,
name: String, name: String,
@ -154,6 +166,8 @@ object SingleSelectionHelper {
callback: (String) -> Unit, callback: (String) -> Unit,
dismissCallback: () -> Unit dismissCallback: () -> Unit
) { ) {
if(this == null) return
val inputView = dialog.findViewById<EditText>(R.id.nginx_text_input)!! val inputView = dialog.findViewById<EditText>(R.id.nginx_text_input)!!
val textView = dialog.findViewById<TextView>(R.id.text1)!! val textView = dialog.findViewById<TextView>(R.id.text1)!!
val applyButton = dialog.findViewById<TextView>(R.id.apply_btt)!! val applyButton = dialog.findViewById<TextView>(R.id.apply_btt)!!
@ -184,13 +198,15 @@ object SingleSelectionHelper {
} }
fun Activity.showMultiDialog( fun Activity?.showMultiDialog(
items: List<String>, items: List<String>,
selectedIndex: List<Int>, selectedIndex: List<Int>,
name: String, name: String,
dismissCallback: () -> Unit, dismissCallback: () -> Unit,
callback: (List<Int>) -> Unit, callback: (List<Int>) -> Unit,
) { ) {
if(this == null) return
val builder = val builder =
AlertDialog.Builder(this, R.style.AlertDialogCustom) AlertDialog.Builder(this, R.style.AlertDialogCustom)
.setView(R.layout.bottom_selection_dialog) .setView(R.layout.bottom_selection_dialog)
@ -200,7 +216,7 @@ object SingleSelectionHelper {
showDialog(dialog, items, selectedIndex, name, true, true, callback, dismissCallback) showDialog(dialog, items, selectedIndex, name, true, true, callback, dismissCallback)
} }
fun Activity.showDialog( fun Activity?.showDialog(
items: List<String>, items: List<String>,
selectedIndex: Int, selectedIndex: Int,
name: String, name: String,
@ -208,6 +224,8 @@ object SingleSelectionHelper {
dismissCallback: () -> Unit, dismissCallback: () -> Unit,
callback: (Int) -> Unit, callback: (Int) -> Unit,
) { ) {
if(this == null) return
val builder = val builder =
AlertDialog.Builder(this, R.style.AlertDialogCustom) AlertDialog.Builder(this, R.style.AlertDialogCustom)
.setView(R.layout.bottom_selection_dialog) .setView(R.layout.bottom_selection_dialog)
@ -227,14 +245,15 @@ object SingleSelectionHelper {
} }
/** Only for a low amount of items */ /** Only for a low amount of items */
fun Activity.showBottomDialog( fun Activity?.showBottomDialog(
items: List<String>, items: List<String>,
selectedIndex: Int, selectedIndex: Int,
name: String, name: String,
showApply: Boolean, showApply: Boolean,
dismissCallback: () -> Unit, dismissCallback: () -> Unit,
callback: (Int) -> Unit, callback: (Int) -> Unit,
) { ) {
if (this == null) return
val builder = val builder =
BottomSheetDialog(this) BottomSheetDialog(this)
builder.setContentView(R.layout.bottom_selection_dialog) builder.setContentView(R.layout.bottom_selection_dialog)
@ -252,12 +271,12 @@ object SingleSelectionHelper {
) )
} }
fun Activity.showNginxTextInputDialog( fun Activity.showNginxTextInputDialog(
name: String, name: String,
value: String, value: String,
textInputType: Int?, textInputType: Int?,
dismissCallback: () -> Unit, dismissCallback: () -> Unit,
callback: (String) -> Unit, callback: (String) -> Unit,
) { ) {
val builder = BottomSheetDialog(this) // probably the stuff at the bottom val builder = BottomSheetDialog(this) // probably the stuff at the bottom
builder.setContentView(R.layout.bottom_input_dialog) // input layout builder.setContentView(R.layout.bottom_input_dialog) // input layout

View File

@ -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:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 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"/> <path android:fillColor="@android:color/white" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>

View 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>

View 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>

View File

@ -50,6 +50,7 @@
<string name="bottom_title_key" translatable="false">bottom_title_key</string> <string name="bottom_title_key" translatable="false">bottom_title_key</string>
<string name="poster_ui_key" translatable="false">poster_ui_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="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 --> <!-- FORMAT MIGHT TRANSLATE, WILL CAUSE CRASH IF APPLIED WRONG -->
<string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string> <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">DNS over HTTPS</string>
<string name="dns_pref_summary">Useful for bypassing ISP blocks</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="download_path_pref">Download path</string>
<string name="nginx_url_pref">Nginx server url</string> <string name="nginx_url_pref">Nginx server url</string>
@ -440,6 +445,9 @@
<string name="example_username">MyCoolUsername</string> <string name="example_username">MyCoolUsername</string>
<string name="example_email">hello@world.com</string> <string name="example_email">hello@world.com</string>
<string name="example_ip">127.0.0.1</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> <string name="mal_account_settings" translatable="false">MAL</string>
@ -529,6 +537,8 @@
<string name="title">Title</string> <string name="title">Title</string>
<string name="resolution">Resolution</string> <string name="resolution">Resolution</string>
<string name="error_invalid_id">Invalid id</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_captions">Remove closed captions from subtitles</string>
<string name="subtitles_remove_bloat">Remove bloat from subtitles</string> <string name="subtitles_remove_bloat">Remove bloat from subtitles</string>
<string name="extras">Extras</string> <string name="extras">Extras</string>

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> 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 <Preference
android:key="@string/dns_key" android:key="@string/dns_key"