mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge branch 'master' into track_selection
This commit is contained in:
commit
60968f2244
38 changed files with 582 additions and 174 deletions
|
@ -6,7 +6,6 @@ import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Looper
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -20,12 +19,12 @@ import com.google.android.gms.cast.framework.CastSession
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.ui.player.PlayerEventType
|
import com.lagradost.cloudstream3.ui.player.PlayerEventType
|
||||||
import com.lagradost.cloudstream3.ui.result.UiText
|
import com.lagradost.cloudstream3.ui.result.UiText
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
|
||||||
import com.lagradost.cloudstream3.utils.Event
|
import com.lagradost.cloudstream3.utils.Event
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper
|
import com.lagradost.cloudstream3.utils.UIHelper
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
|
import com.lagradost.cloudstream3.utils.UIHelper.hasPIPPermission
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
|
import com.lagradost.cloudstream3.utils.UIHelper.shouldShowPIPMode
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
||||||
import kotlinx.coroutines.currentCoroutineContext
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe
|
import org.schabi.newpipe.extractor.NewPipe
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ object CommonActivity {
|
||||||
act.hasPIPPermission() // CHECK IF FEATURE IS ENABLED IN SETTINGS
|
act.hasPIPPermission() // CHECK IF FEATURE IS ENABLED IN SETTINGS
|
||||||
|
|
||||||
act.updateLocale()
|
act.updateLocale()
|
||||||
|
act.updateTv()
|
||||||
NewPipe.init(DownloaderTestImpl.getInstance())
|
NewPipe.init(DownloaderTestImpl.getInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ object APIHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Context.getHasTrailers(): Boolean {
|
private fun Context.getHasTrailers(): Boolean {
|
||||||
if (this.isTvSettings()) return false
|
if (isTvSettings()) return false
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
return settingsManager.getBoolean(this.getString(R.string.show_trailers_key), true)
|
return settingsManager.getBoolean(this.getString(R.string.show_trailers_key), true)
|
||||||
}
|
}
|
||||||
|
@ -315,6 +315,10 @@ data class ProvidersInfoJson(
|
||||||
@JsonProperty("status") var status: Int,
|
@JsonProperty("status") var status: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class SettingsJson(
|
||||||
|
@JsonProperty("enableAdult") var enableAdult: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
data class MainPageData(
|
data class MainPageData(
|
||||||
val name: String,
|
val name: String,
|
||||||
|
@ -354,6 +358,7 @@ fun newHomePageResponse(list: List<HomePageList>, hasNext: Boolean? = null): Hom
|
||||||
abstract class MainAPI {
|
abstract class MainAPI {
|
||||||
companion object {
|
companion object {
|
||||||
var overrideData: HashMap<String, ProvidersInfoJson>? = null
|
var overrideData: HashMap<String, ProvidersInfoJson>? = null
|
||||||
|
var settingsForProvider: SettingsJson = SettingsJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
|
|
|
@ -456,6 +456,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
app.initClient(this)
|
app.initClient(this)
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
|
val settingsForProvider = SettingsJson()
|
||||||
|
settingsForProvider.enableAdult = settingsManager.getBoolean(getString(R.string.enable_nsfw_on_providers_key), false)
|
||||||
|
|
||||||
|
MainAPI.settingsForProvider = settingsForProvider
|
||||||
|
|
||||||
loadThemes(this)
|
loadThemes(this)
|
||||||
updateLocale()
|
updateLocale()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
|
@ -7,6 +7,10 @@ import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
|
||||||
|
class Sbthe : StreamSB() {
|
||||||
|
override var mainUrl = "https://sbthe.com"
|
||||||
|
}
|
||||||
|
|
||||||
class Ssbstream : StreamSB() {
|
class Ssbstream : StreamSB() {
|
||||||
override var mainUrl = "https://ssbstream.net"
|
override var mainUrl = "https://ssbstream.net"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.lagradost.cloudstream3.extractors
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
|
||||||
|
import com.lagradost.cloudstream3.ErrorLoadingException
|
||||||
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
|
import com.lagradost.cloudstream3.app
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
|
|
||||||
|
class Zorofile : ExtractorApi() {
|
||||||
|
override val name = "Zorofile"
|
||||||
|
override val mainUrl = "https://zorofile.com"
|
||||||
|
override val requiresReferer = true
|
||||||
|
|
||||||
|
override suspend fun getUrl(
|
||||||
|
url: String,
|
||||||
|
referer: String?,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val id = url.split("?").first().split("/").last()
|
||||||
|
val token = app.get(
|
||||||
|
url,
|
||||||
|
referer = referer
|
||||||
|
).document.select("button.g-recaptcha").attr("data-sitekey").let { captchaKey ->
|
||||||
|
getCaptchaToken(
|
||||||
|
url,
|
||||||
|
captchaKey,
|
||||||
|
referer = referer
|
||||||
|
)
|
||||||
|
} ?: throw ErrorLoadingException("can't bypass captcha")
|
||||||
|
|
||||||
|
val data = app.post(
|
||||||
|
"$mainUrl/dl",
|
||||||
|
data = mapOf(
|
||||||
|
"op" to "embed",
|
||||||
|
"file_code" to id,
|
||||||
|
"auto" to "1",
|
||||||
|
"referer" to "$referer/",
|
||||||
|
"g-recaptcha-response" to token
|
||||||
|
),
|
||||||
|
referer = url,
|
||||||
|
headers = mapOf(
|
||||||
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
|
"Content-Type" to "application/x-www-form-urlencoded",
|
||||||
|
"Origin" to mainUrl,
|
||||||
|
"Sec-Fetch-Dest" to "iframe",
|
||||||
|
"Sec-Fetch-Mode" to "navigate",
|
||||||
|
"Sec-Fetch-Site" to "same-origin",
|
||||||
|
"Sec-Fetch-User" to "?1",
|
||||||
|
"Upgrade-Insecure-Requests" to "1",
|
||||||
|
)
|
||||||
|
).document.select("script").find { it.data().contains("var holaplayer;") }?.data()
|
||||||
|
?.substringAfter("sources: [")?.substringBefore("],")?.replace("src", "\"src\"")
|
||||||
|
?.replace("type", "\"type\"")
|
||||||
|
|
||||||
|
tryParseJson<Sources>("$data")?.let { res ->
|
||||||
|
return M3u8Helper.generateM3u8(
|
||||||
|
name,
|
||||||
|
res.src ?: return@let,
|
||||||
|
"$mainUrl/",
|
||||||
|
headers = mapOf(
|
||||||
|
"Origin" to mainUrl,
|
||||||
|
)
|
||||||
|
).forEach(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class Sources(
|
||||||
|
@JsonProperty("src") val src: String? = null,
|
||||||
|
@JsonProperty("type") val type: String? = null,
|
||||||
|
)
|
||||||
|
}
|
|
@ -175,7 +175,7 @@ class DownloadFragment : Fragment() {
|
||||||
|
|
||||||
download_list?.adapter = adapter
|
download_list?.adapter = adapter
|
||||||
download_list?.layoutManager = GridLayoutManager(context, 1)
|
download_list?.layoutManager = GridLayoutManager(context, 1)
|
||||||
download_stream_button?.isGone = context?.isTvSettings() == true
|
download_stream_button?.isGone = isTvSettings()
|
||||||
download_stream_button?.setOnClickListener {
|
download_stream_button?.setOnClickListener {
|
||||||
val dialog =
|
val dialog =
|
||||||
Dialog(it.context ?: return@setOnClickListener, R.style.AlertDialogCustom)
|
Dialog(it.context ?: return@setOnClickListener, R.style.AlertDialogCustom)
|
||||||
|
|
|
@ -400,7 +400,7 @@ class HomeFragment : Fragment() {
|
||||||
//homeViewModel =
|
//homeViewModel =
|
||||||
// ViewModelProvider(this).get(HomeViewModel::class.java)
|
// ViewModelProvider(this).get(HomeViewModel::class.java)
|
||||||
val layout =
|
val layout =
|
||||||
if (context?.isTvSettings() == true) R.layout.fragment_home_tv else R.layout.fragment_home
|
if (isTvSettings()) R.layout.fragment_home_tv else R.layout.fragment_home
|
||||||
return inflater.inflate(layout, container, false)
|
return inflater.inflate(layout, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ class HomeFragment : Fragment() {
|
||||||
|
|
||||||
val randomSize = items.size
|
val randomSize = items.size
|
||||||
tempAdapter?.updateList(items)
|
tempAdapter?.updateList(items)
|
||||||
if (context?.isTvSettings() == false) {
|
if (!isTvSettings()) {
|
||||||
home_main_poster_recyclerview?.post {
|
home_main_poster_recyclerview?.post {
|
||||||
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
(home_main_poster_recyclerview?.layoutManager as CenterZoomLayoutManager?)?.let { manager ->
|
||||||
manager.updateSize(forceUpdate = true)
|
manager.updateSize(forceUpdate = true)
|
||||||
|
@ -939,7 +939,7 @@ class HomeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
|
} // GridLayoutManager(context, 1).also { it.supportsPredictiveItemAnimations() }
|
||||||
|
|
||||||
if (context?.isTvSettings() == false) {
|
if (!isTvSettings()) {
|
||||||
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap
|
LinearSnapHelper().attachToRecyclerView(home_main_poster_recyclerview) // snap
|
||||||
val centerLayoutManager =
|
val centerLayoutManager =
|
||||||
CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
CenterZoomLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||||
|
@ -975,7 +975,7 @@ class HomeFragment : Fragment() {
|
||||||
home_api_fab?.shrink() // hide
|
home_api_fab?.shrink() // hide
|
||||||
home_random?.shrink()
|
home_random?.shrink()
|
||||||
} else if (dy < -5) {
|
} else if (dy < -5) {
|
||||||
if (v.context?.isTvSettings() == false) {
|
if (!isTvSettings()) {
|
||||||
home_api_fab?.extend() // show
|
home_api_fab?.extend() // show
|
||||||
home_random?.extend()
|
home_random?.extend()
|
||||||
}
|
}
|
||||||
|
@ -984,12 +984,11 @@ class HomeFragment : Fragment() {
|
||||||
|
|
||||||
// nice profile pic on homepage
|
// nice profile pic on homepage
|
||||||
home_profile_picture_holder?.isVisible = false
|
home_profile_picture_holder?.isVisible = false
|
||||||
context?.let { ctx ->
|
|
||||||
// just in case
|
// just in case
|
||||||
if (ctx.isTvSettings()) {
|
if (isTvSettings()) {
|
||||||
home_api_fab?.isVisible = false
|
home_api_fab?.isVisible = false
|
||||||
home_change_api?.isVisible = true
|
home_change_api?.isVisible = true
|
||||||
if (ctx.isTrueTvSettings()) {
|
if (isTrueTvSettings()) {
|
||||||
home_change_api_loading?.isVisible = true
|
home_change_api_loading?.isVisible = true
|
||||||
home_change_api_loading?.isFocusable = true
|
home_change_api_loading?.isFocusable = true
|
||||||
home_change_api_loading?.isFocusableInTouchMode = true
|
home_change_api_loading?.isFocusableInTouchMode = true
|
||||||
|
@ -1017,5 +1016,4 @@ class HomeFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ class ParentItemAdapter(
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, i: Int): ParentViewHolder {
|
||||||
//println("onCreateViewHolder $i")
|
//println("onCreateViewHolder $i")
|
||||||
val layout =
|
val layout =
|
||||||
if (parent.context.isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
|
if (isTvSettings()) R.layout.homepage_parent_tv else R.layout.homepage_parent
|
||||||
return ParentViewHolder(
|
return ParentViewHolder(
|
||||||
LayoutInflater.from(parent.context).inflate(layout, parent, false),
|
LayoutInflater.from(parent.context).inflate(layout, parent, false),
|
||||||
clickCallback,
|
clickCallback,
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// this is used instead of layout-television to follow the settings and some TV devices are not classified as TV for some reason
|
// this is used instead of layout-television to follow the settings and some TV devices are not classified as TV for some reason
|
||||||
isTv = context?.isTvSettings() == true
|
isTv = isTvSettings()
|
||||||
layout =
|
layout =
|
||||||
if (isTv) R.layout.fragment_player_tv else R.layout.fragment_player
|
if (isTv) R.layout.fragment_player_tv else R.layout.fragment_player
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ class PlayerEpisodeAdapter(
|
||||||
clickCallback.invoke(PlayerEpisodeClickEvent(0, card))
|
clickCallback.invoke(PlayerEpisodeClickEvent(0, card))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentView.context.isTrueTvSettings()) {
|
if (isTrueTvSettings()) {
|
||||||
parentView.isFocusable = true
|
parentView.isFocusable = true
|
||||||
parentView.isFocusableInTouchMode = true
|
parentView.isFocusableInTouchMode = true
|
||||||
parentView.touchscreenBlocksFocus = false
|
parentView.touchscreenBlocksFocus = false
|
||||||
|
|
|
@ -166,7 +166,7 @@ class EpisodeAdapter(
|
||||||
fun bind(card: ResultEpisode) {
|
fun bind(card: ResultEpisode) {
|
||||||
localCard = card
|
localCard = card
|
||||||
|
|
||||||
val isTrueTv = itemView.context?.isTrueTvSettings() == true
|
val isTrueTv = isTrueTvSettings()
|
||||||
|
|
||||||
val (parentView, otherView) = if (card.poster == null) {
|
val (parentView, otherView) = if (card.poster == null) {
|
||||||
itemView.episode_holder to itemView.episode_holder_large
|
itemView.episode_holder to itemView.episode_holder_large
|
||||||
|
|
|
@ -83,7 +83,7 @@ class ImageAdapter(
|
||||||
this.nextFocusUpId = nextFocusUp
|
this.nextFocusUpId = nextFocusUp
|
||||||
}
|
}
|
||||||
if (clickCallback != null) {
|
if (clickCallback != null) {
|
||||||
if (context.isTrueTvSettings()) {
|
if (isTrueTvSettings()) {
|
||||||
isClickable = true
|
isClickable = true
|
||||||
isLongClickable = true
|
isLongClickable = true
|
||||||
isFocusable = true
|
isFocusable = true
|
||||||
|
|
|
@ -293,7 +293,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
result_reload_connection_open_in_browser?.isVisible = true
|
result_reload_connection_open_in_browser?.isVisible = true
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
result_bookmark_fab?.isGone = result_bookmark_fab?.context?.isTvSettings() == true
|
result_bookmark_fab?.isGone = isTvSettings()
|
||||||
result_bookmark_fab?.extend()
|
result_bookmark_fab?.extend()
|
||||||
//if (result_bookmark_button?.context?.isTrueTvSettings() == true) {
|
//if (result_bookmark_button?.context?.isTrueTvSettings() == true) {
|
||||||
// when {
|
// when {
|
||||||
|
@ -551,7 +551,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is to band-aid FireTV navigation
|
// This is to band-aid FireTV navigation
|
||||||
val isTv = context?.isTvSettings() == true
|
val isTv = isTvSettings()
|
||||||
result_season_button?.isFocusableInTouchMode = isTv
|
result_season_button?.isFocusableInTouchMode = isTv
|
||||||
result_episode_select?.isFocusableInTouchMode = isTv
|
result_episode_select?.isFocusableInTouchMode = isTv
|
||||||
result_dub_select?.isFocusableInTouchMode = isTv
|
result_dub_select?.isFocusableInTouchMode = isTv
|
||||||
|
@ -794,7 +794,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
result_next_airing_time.setText(d.nextAiringDate)
|
result_next_airing_time.setText(d.nextAiringDate)
|
||||||
result_poster.setImage(d.posterImage)
|
result_poster.setImage(d.posterImage)
|
||||||
|
|
||||||
if (d.posterImage != null && context?.isTrueTvSettings() == false)
|
if (d.posterImage != null && !isTrueTvSettings())
|
||||||
result_poster_holder?.setOnClickListener {
|
result_poster_holder?.setOnClickListener {
|
||||||
try {
|
try {
|
||||||
context?.let { ctx ->
|
context?.let { ctx ->
|
||||||
|
@ -883,7 +883,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
result_tag_holder?.isVisible = tags.isNotEmpty()
|
result_tag_holder?.isVisible = tags.isNotEmpty()
|
||||||
if (tags.isNotEmpty()) {
|
if (tags.isNotEmpty()) {
|
||||||
//result_tag_holder?.visibility = VISIBLE
|
//result_tag_holder?.visibility = VISIBLE
|
||||||
val isOnTv = context?.isTrueTvSettings() == true
|
val isOnTv = isTrueTvSettings()
|
||||||
for ((index, tag) in tags.withIndex()) {
|
for ((index, tag) in tags.withIndex()) {
|
||||||
val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
|
val viewBtt = layoutInflater.inflate(R.layout.result_tag, null)
|
||||||
val btt = viewBtt.findViewById<MaterialButton>(R.id.result_tag_card)
|
val btt = viewBtt.findViewById<MaterialButton>(R.id.result_tag_card)
|
||||||
|
@ -941,7 +941,7 @@ open class ResultFragment : ResultTrailerPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bloats the navigation on tv
|
// bloats the navigation on tv
|
||||||
if (context?.isTrueTvSettings() == false) {
|
if (!isTrueTvSettings()) {
|
||||||
result_meta_site?.setOnClickListener {
|
result_meta_site?.setOnClickListener {
|
||||||
it.context?.openBrowser(storedData.url)
|
it.context?.openBrowser(storedData.url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ class SelectAdaptor(val callback: (Any) -> Unit) : RecyclerView.Adapter<Recycler
|
||||||
fun bind(
|
fun bind(
|
||||||
data: SelectData, isSelected: Boolean, callback: (Any) -> Unit
|
data: SelectData, isSelected: Boolean, callback: (Any) -> Unit
|
||||||
) {
|
) {
|
||||||
val isTrueTv = itemView.context?.isTrueTvSettings() == true
|
val isTrueTv = isTrueTvSettings()
|
||||||
if (isTrueTv) {
|
if (isTrueTv) {
|
||||||
item.isFocusable = true
|
item.isFocusable = true
|
||||||
item.isFocusableInTouchMode = true
|
item.isFocusableInTouchMode = true
|
||||||
|
|
|
@ -386,7 +386,7 @@ class SearchFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context?.isTrueTvSettings() == true) {
|
if (isTrueTvSettings()) {
|
||||||
search_filter.isFocusable = true
|
search_filter.isFocusable = true
|
||||||
search_filter.isFocusableInTouchMode = true
|
search_filter.isFocusableInTouchMode = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,7 @@ object SearchResultBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bg.context.isTrueTvSettings()) {
|
if (isTrueTvSettings()) {
|
||||||
bg.isFocusable = true
|
bg.isFocusable = true
|
||||||
bg.isFocusableInTouchMode = true
|
bg.isFocusableInTouchMode = true
|
||||||
bg.touchscreenBlocksFocus = false
|
bg.touchscreenBlocksFocus = false
|
||||||
|
|
|
@ -117,7 +117,7 @@ class SettingsAccount : PreferenceFragmentCompat() {
|
||||||
dialog.login_username_input to api.requiresUsername
|
dialog.login_username_input to api.requiresUsername
|
||||||
)
|
)
|
||||||
|
|
||||||
if (activity.isTvSettings()) {
|
if (isTvSettings()) {
|
||||||
visibilityMap.forEach { (input, isVisible) ->
|
visibilityMap.forEach { (input, isVisible) ->
|
||||||
input.isVisible = isVisible
|
input.isVisible = isVisible
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ class SettingsFragment : Fragment() {
|
||||||
companion object {
|
companion object {
|
||||||
var beneneCount = 0
|
var beneneCount = 0
|
||||||
|
|
||||||
|
private var isTv : Boolean = false
|
||||||
|
private var isTrueTv : Boolean = false
|
||||||
|
|
||||||
fun PreferenceFragmentCompat?.getPref(id: Int): Preference? {
|
fun PreferenceFragmentCompat?.getPref(id: Int): Preference? {
|
||||||
if (this == null) return null
|
if (this == null) return null
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ class SettingsFragment : Fragment() {
|
||||||
* On TV you cannot properly scroll to the bottom of settings, this fixes that.
|
* On TV you cannot properly scroll to the bottom of settings, this fixes that.
|
||||||
* */
|
* */
|
||||||
fun PreferenceFragmentCompat.setPaddingBottom() {
|
fun PreferenceFragmentCompat.setPaddingBottom() {
|
||||||
if (this.context?.isTvSettings() == true) {
|
if (isTvSettings()) {
|
||||||
listView?.setPadding(0, 0, 0, 100.toPx)
|
listView?.setPadding(0, 0, 0, 100.toPx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +96,7 @@ class SettingsFragment : Fragment() {
|
||||||
return settingsManager.getInt(this.getString(R.string.app_layout_key), -1)
|
return settingsManager.getInt(this.getString(R.string.app_layout_key), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.isTvSettings(): Boolean {
|
private fun Context.isTvSettings(): Boolean {
|
||||||
var value = getLayoutInt()
|
var value = getLayoutInt()
|
||||||
if (value == -1) {
|
if (value == -1) {
|
||||||
value = if (isAutoTv()) 1 else 0
|
value = if (isAutoTv()) 1 else 0
|
||||||
|
@ -101,7 +104,7 @@ class SettingsFragment : Fragment() {
|
||||||
return value == 1 || value == 2
|
return value == 1 || value == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.isTrueTvSettings(): Boolean {
|
private fun Context.isTrueTvSettings(): Boolean {
|
||||||
var value = getLayoutInt()
|
var value = getLayoutInt()
|
||||||
if (value == -1) {
|
if (value == -1) {
|
||||||
value = if (isAutoTv()) 1 else 0
|
value = if (isAutoTv()) 1 else 0
|
||||||
|
@ -109,6 +112,19 @@ class SettingsFragment : Fragment() {
|
||||||
return value == 1
|
return value == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.updateTv() {
|
||||||
|
isTrueTv = isTrueTvSettings()
|
||||||
|
isTv = isTvSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isTrueTvSettings(): Boolean {
|
||||||
|
return isTrueTv
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isTvSettings(): Boolean {
|
||||||
|
return isTv
|
||||||
|
}
|
||||||
|
|
||||||
fun Context.isEmulatorSettings(): Boolean {
|
fun Context.isEmulatorSettings(): Boolean {
|
||||||
return getLayoutInt() == 2
|
return getLayoutInt() == 2
|
||||||
}
|
}
|
||||||
|
@ -136,7 +152,7 @@ class SettingsFragment : Fragment() {
|
||||||
activity?.navigate(id, Bundle())
|
activity?.navigate(id, Bundle())
|
||||||
}
|
}
|
||||||
|
|
||||||
val isTrueTv = context?.isTrueTvSettings() == true
|
val isTrueTv = isTrueTvSettings()
|
||||||
|
|
||||||
for (syncApi in accountManagers) {
|
for (syncApi in accountManagers) {
|
||||||
val login = syncApi.loginInfo()
|
val login = syncApi.loginInfo()
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
|
||||||
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.setPaddingBottom
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setPaddingBottom
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
|
||||||
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.showDialog
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog
|
||||||
|
@ -22,6 +23,7 @@ class SettingsUI : PreferenceFragmentCompat() {
|
||||||
setUpToolbar(R.string.category_ui)
|
setUpToolbar(R.string.category_ui)
|
||||||
setPaddingBottom()
|
setPaddingBottom()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
setPreferencesFromResource(R.xml.settins_ui, rootKey)
|
setPreferencesFromResource(R.xml.settins_ui, rootKey)
|
||||||
|
@ -71,6 +73,7 @@ class SettingsUI : PreferenceFragmentCompat() {
|
||||||
settingsManager.edit()
|
settingsManager.edit()
|
||||||
.putInt(getString(R.string.app_layout_key), prefValues[it])
|
.putInt(getString(R.string.app_layout_key), prefValues[it])
|
||||||
.apply()
|
.apply()
|
||||||
|
context?.updateTv()
|
||||||
activity?.recreate()
|
activity?.recreate()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
|
@ -130,7 +133,10 @@ class SettingsUI : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
getPref(R.string.pref_filter_search_quality_key)?.setOnPreferenceClickListener {
|
getPref(R.string.pref_filter_search_quality_key)?.setOnPreferenceClickListener {
|
||||||
val names = enumValues<SearchQuality>().sorted().map { it.name }
|
val names = enumValues<SearchQuality>().sorted().map { it.name }
|
||||||
val currentList = settingsManager.getStringSet(getString(R.string.pref_filter_search_quality_key), setOf())?.map {
|
val currentList = settingsManager.getStringSet(
|
||||||
|
getString(R.string.pref_filter_search_quality_key),
|
||||||
|
setOf()
|
||||||
|
)?.map {
|
||||||
it.toInt()
|
it.toInt()
|
||||||
} ?: listOf()
|
} ?: listOf()
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
@ -23,12 +24,14 @@ import com.lagradost.cloudstream3.mvvm.Some
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||||
import com.lagradost.cloudstream3.ui.result.setText
|
import com.lagradost.cloudstream3.ui.result.setText
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.downloadAllPluginsDialog
|
import com.lagradost.cloudstream3.utils.AppUtils.downloadAllPluginsDialog
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
|
import com.lagradost.cloudstream3.widget.LinearRecycleViewLayoutManager
|
||||||
import kotlinx.android.synthetic.main.add_repo_input.*
|
import kotlinx.android.synthetic.main.add_repo_input.*
|
||||||
import kotlinx.android.synthetic.main.fragment_extensions.*
|
import kotlinx.android.synthetic.main.fragment_extensions.*
|
||||||
import kotlinx.android.synthetic.main.fragment_extensions.list_repositories
|
import kotlinx.android.synthetic.main.fragment_extensions.list_repositories
|
||||||
|
@ -119,9 +122,15 @@ class ExtensionsFragment : Fragment() {
|
||||||
(repo_recycler_view?.adapter as? RepoAdapter)?.updateList(it)
|
(repo_recycler_view?.adapter as? RepoAdapter)?.updateList(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo_recycler_view?.apply {
|
||||||
|
context?.let { ctx ->
|
||||||
|
layoutManager = LinearRecycleViewLayoutManager(ctx, nextFocusUpId, nextFocusDownId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list_repositories?.setOnClickListener {
|
list_repositories?.setOnClickListener {
|
||||||
// Open webview on tv if browser fails
|
// Open webview on tv if browser fails
|
||||||
val isTv = it.context.isTvSettings()
|
val isTv = isTvSettings()
|
||||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
||||||
|
|
||||||
// Set clipboard on TV because the browser might not exist or work properly
|
// Set clipboard on TV because the browser might not exist or work properly
|
||||||
|
@ -170,9 +179,9 @@ class ExtensionsFragment : Fragment() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
add_repo_button?.setOnClickListener {
|
val addRepositoryClick = View.OnClickListener {
|
||||||
val builder =
|
val builder =
|
||||||
AlertDialog.Builder(context ?: return@setOnClickListener, R.style.AlertDialogCustom)
|
AlertDialog.Builder(context ?: return@OnClickListener, R.style.AlertDialogCustom)
|
||||||
.setView(R.layout.add_repo_input)
|
.setView(R.layout.add_repo_input)
|
||||||
|
|
||||||
val dialog = builder.create()
|
val dialog = builder.create()
|
||||||
|
@ -193,8 +202,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
|
|
||||||
dialog.list_repositories?.setOnClickListener {
|
dialog.list_repositories?.setOnClickListener {
|
||||||
// Open webview on tv if browser fails
|
// Open webview on tv if browser fails
|
||||||
val isTv = it.context.isTvSettings()
|
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dialog.text2?.text = provider.name
|
// dialog.text2?.text = provider.name
|
||||||
|
@ -223,6 +231,12 @@ class ExtensionsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isTv = isTrueTvSettings()
|
||||||
|
add_repo_button?.isGone = isTv
|
||||||
|
add_repo_button_imageview_holder?.isVisible = isTv
|
||||||
|
add_repo_button?.setOnClickListener(addRepositoryClick)
|
||||||
|
add_repo_button_imageview?.setOnClickListener(addRepositoryClick)
|
||||||
|
|
||||||
reloadRepositories()
|
reloadRepositories()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@ import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
import com.lagradost.cloudstream3.ui.result.setText
|
import com.lagradost.cloudstream3.ui.result.setText
|
||||||
import com.lagradost.cloudstream3.ui.result.txt
|
import com.lagradost.cloudstream3.ui.result.txt
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
import com.lagradost.cloudstream3.utils.AppUtils.html
|
||||||
import com.lagradost.cloudstream3.utils.GlideApp
|
import com.lagradost.cloudstream3.utils.GlideApp
|
||||||
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
|
import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage
|
||||||
|
@ -36,8 +37,9 @@ class PluginAdapter(
|
||||||
private val plugins: MutableList<PluginViewData> = mutableListOf()
|
private val plugins: MutableList<PluginViewData> = mutableListOf()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val layout = if(isTrueTvSettings()) R.layout.repository_item_tv else R.layout.repository_item
|
||||||
return PluginViewHolder(
|
return PluginViewHolder(
|
||||||
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
|
LayoutInflater.from(parent.context).inflate(layout, parent, false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +125,6 @@ class PluginAdapter(
|
||||||
itemView.action_button?.setOnClickListener {
|
itemView.action_button?.setOnClickListener {
|
||||||
iconClickCallback.invoke(data.plugin)
|
iconClickCallback.invoke(data.plugin)
|
||||||
}
|
}
|
||||||
testFindClosestBase2()
|
|
||||||
//if (itemView.context?.isTrueTvSettings() == false) {
|
//if (itemView.context?.isTrueTvSettings() == false) {
|
||||||
// val siteUrl = metadata.repositoryUrl
|
// val siteUrl = metadata.repositoryUrl
|
||||||
// if (siteUrl != null && siteUrl.isNotBlank() && siteUrl != "NONE") {
|
// if (siteUrl != null && siteUrl.isNotBlank() && siteUrl != "NONE") {
|
||||||
|
|
|
@ -128,7 +128,7 @@ class PluginsFragment : Fragment() {
|
||||||
pluginViewModel.handlePluginAction(activity, url, it, isLocal)
|
pluginViewModel.handlePluginAction(activity, url, it, isLocal)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context?.isTvSettings() == true) {
|
if (isTvSettings()) {
|
||||||
// Scrolling down does not reveal the whole RecyclerView on TV, add to bypass that.
|
// Scrolling down does not reveal the whole RecyclerView on TV, add to bypass that.
|
||||||
plugin_recycler_view?.setPadding(0, 0, 0, 200.toPx)
|
plugin_recycler_view?.setPadding(0, 0, 0, 200.toPx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import kotlinx.android.synthetic.main.repository_item.view.*
|
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||||
|
|
||||||
class RepoAdapter(
|
class RepoAdapter(
|
||||||
|
@ -19,8 +20,9 @@ class RepoAdapter(
|
||||||
private val repositories: MutableList<RepositoryData> = mutableListOf()
|
private val repositories: MutableList<RepositoryData> = mutableListOf()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val layout = if(isTrueTvSettings()) R.layout.repository_item_tv else R.layout.repository_item
|
||||||
return RepoViewHolder(
|
return RepoViewHolder(
|
||||||
LayoutInflater.from(parent.context).inflate(R.layout.repository_item, parent, false)
|
LayoutInflater.from(parent.context).inflate(layout, parent, false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,7 @@ class SetupFragmentExtensions : Fragment() {
|
||||||
} else {
|
} else {
|
||||||
list_repositories?.setOnClickListener {
|
list_repositories?.setOnClickListener {
|
||||||
// Open webview on tv if browser fails
|
// Open webview on tv if browser fails
|
||||||
val isTv = it.context.isTvSettings()
|
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,8 +85,7 @@ class SetupFragmentExtensions : Fragment() {
|
||||||
val isSetup = arguments?.getBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP) ?: false
|
val isSetup = arguments?.getBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP) ?: false
|
||||||
|
|
||||||
view_public_repositories_button?.setOnClickListener {
|
view_public_repositories_button?.setOnClickListener {
|
||||||
val isTv = it.context.isTvSettings()
|
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
with(context) {
|
with(context) {
|
||||||
|
|
|
@ -164,7 +164,7 @@ class ChromecastSubtitlesFragment : Fragment() {
|
||||||
state = getCurrentSavedStyle()
|
state = getCurrentSavedStyle()
|
||||||
context?.updateState()
|
context?.updateState()
|
||||||
|
|
||||||
val isTvSettings = context?.isTvSettings() == true
|
val isTvSettings = isTvSettings()
|
||||||
|
|
||||||
fun View.setFocusableInTv() {
|
fun View.setFocusableInTv() {
|
||||||
this.isFocusableInTouchMode = isTvSettings
|
this.isFocusableInTouchMode = isTvSettings
|
||||||
|
|
|
@ -243,7 +243,7 @@ class SubtitlesFragment : Fragment() {
|
||||||
state = getCurrentSavedStyle()
|
state = getCurrentSavedStyle()
|
||||||
context?.updateState()
|
context?.updateState()
|
||||||
|
|
||||||
val isTvTrueSettings = context?.isTrueTvSettings() == true
|
val isTvTrueSettings = isTrueTvSettings()
|
||||||
|
|
||||||
fun View.setFocusableInTv() {
|
fun View.setFocusableInTv() {
|
||||||
this.isFocusableInTouchMode = isTvTrueSettings
|
this.isFocusableInTouchMode = isTvTrueSettings
|
||||||
|
|
|
@ -407,8 +407,8 @@ object AppUtils {
|
||||||
|
|
||||||
//private val viewModel: ResultViewModel by activityViewModels()
|
//private val viewModel: ResultViewModel by activityViewModels()
|
||||||
|
|
||||||
private fun getResultsId(context: Context): Int {
|
private fun getResultsId(): Int {
|
||||||
return if (context.isTrueTvSettings()) {
|
return if (isTrueTvSettings()) {
|
||||||
R.id.global_to_navigation_results_tv
|
R.id.global_to_navigation_results_tv
|
||||||
} else {
|
} else {
|
||||||
R.id.global_to_navigation_results_phone
|
R.id.global_to_navigation_results_phone
|
||||||
|
@ -424,7 +424,7 @@ object AppUtils {
|
||||||
this.runOnUiThread {
|
this.runOnUiThread {
|
||||||
// viewModelStore.clear()
|
// viewModelStore.clear()
|
||||||
this.navigate(
|
this.navigate(
|
||||||
getResultsId(this.applicationContext ?: return@runOnUiThread),
|
getResultsId(),
|
||||||
ResultFragment.newInstance(url, apiName, startAction, startValue)
|
ResultFragment.newInstance(url, apiName, startAction, startValue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ object AppUtils {
|
||||||
this?.runOnUiThread {
|
this?.runOnUiThread {
|
||||||
// viewModelStore.clear()
|
// viewModelStore.clear()
|
||||||
this.navigate(
|
this.navigate(
|
||||||
getResultsId(this),
|
getResultsId(),
|
||||||
ResultFragment.newInstance(card, startAction, startValue)
|
ResultFragment.newInstance(card, startAction, startValue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
||||||
// Streamhub(), cause Streamhub2() works
|
// Streamhub(), cause Streamhub2() works
|
||||||
Streamhub2(),
|
Streamhub2(),
|
||||||
Ssbstream(),
|
Ssbstream(),
|
||||||
|
Sbthe(),
|
||||||
|
|
||||||
Fastream(),
|
Fastream(),
|
||||||
|
|
||||||
|
@ -312,6 +313,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
||||||
Linkbox(),
|
Linkbox(),
|
||||||
Acefile(),
|
Acefile(),
|
||||||
SpeedoStream(),
|
SpeedoStream(),
|
||||||
|
Zorofile(),
|
||||||
|
|
||||||
YoutubeExtractor(),
|
YoutubeExtractor(),
|
||||||
YoutubeShortLinkExtractor(),
|
YoutubeShortLinkExtractor(),
|
||||||
|
|
|
@ -44,7 +44,7 @@ object SingleSelectionHelper {
|
||||||
) {
|
) {
|
||||||
if (this == null) return
|
if (this == null) return
|
||||||
|
|
||||||
if (this.isTvSettings()) {
|
if (isTvSettings()) {
|
||||||
val builder =
|
val builder =
|
||||||
AlertDialog.Builder(this, R.style.AlertDialogCustom)
|
AlertDialog.Builder(this, R.style.AlertDialogCustom)
|
||||||
.setView(R.layout.options_popup_tv)
|
.setView(R.layout.options_popup_tv)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.lagradost.cloudstream3.widget
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
|
||||||
|
class LinearRecycleViewLayoutManager(
|
||||||
|
val context: Context,
|
||||||
|
val nextFocusUp: Int,
|
||||||
|
val nextFocusDown: Int
|
||||||
|
) : LinearLayoutManager(context) {
|
||||||
|
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
|
||||||
|
return try {
|
||||||
|
val position = getPosition(focused)
|
||||||
|
val count = itemCount
|
||||||
|
//println("onInterceptFocusSearch position=$position count=$count focused=$focused direction=$direction")
|
||||||
|
|
||||||
|
(if (position == count - 1 && direction == View.FOCUS_DOWN) {
|
||||||
|
focused.rootView.findViewById(nextFocusDown)
|
||||||
|
} else if (position == 0 && direction == View.FOCUS_UP) {
|
||||||
|
focused.rootView.findViewById(nextFocusUp)
|
||||||
|
} else {
|
||||||
|
super.onInterceptFocusSearch(focused, direction)
|
||||||
|
}) ?: super.onInterceptFocusSearch(focused, direction)
|
||||||
|
} catch (t : Throwable) {
|
||||||
|
super.onInterceptFocusSearch(focused, direction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,10 @@
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:nextFocusDown="@id/repo_name_input"
|
||||||
android:id="@+id/list_repositories"
|
android:id="@+id/list_repositories"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
style="@style/WhiteButton"
|
style="@style/WhiteButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
@ -67,6 +70,7 @@
|
||||||
android:autofillHints="username"
|
android:autofillHints="username"
|
||||||
android:hint="@string/repository_name_hint"
|
android:hint="@string/repository_name_hint"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
|
android:nextFocusUp="@id/list_repositories"
|
||||||
android:nextFocusLeft="@id/apply_btt"
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
android:nextFocusRight="@id/cancel_btt"
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
android:nextFocusDown="@id/site_url_input"
|
android:nextFocusDown="@id/site_url_input"
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
<include layout="@layout/standard_toolbar" />
|
<include layout="@layout/standard_toolbar" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:nextFocusUp="@id/settings_toolbar"
|
||||||
|
android:nextFocusDown="@id/plugin_storage_appbar"
|
||||||
android:id="@+id/repo_recycler_view"
|
android:id="@+id/repo_recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -23,13 +25,13 @@
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
tools:visibility="gone"
|
|
||||||
android:id="@+id/blank_repo_screen"
|
android:id="@+id/blank_repo_screen"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="20dp"
|
android:layout_margin="20dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
tools:visibility="gone">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="30dp"
|
android:layout_width="30dp"
|
||||||
|
@ -38,36 +40,40 @@
|
||||||
android:src="@drawable/ic_baseline_extension_24" />
|
android:src="@drawable/ic_baseline_extension_24" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_marginBottom="20dp"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/blank_repo_message"
|
android:text="@string/blank_repo_message"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/list_repositories"
|
android:id="@+id/list_repositories"
|
||||||
android:nextFocusDown="@id/add_repo_button"
|
|
||||||
style="@style/WhiteButton"
|
style="@style/WhiteButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:nextFocusDown="@id/add_repo_button"
|
||||||
android:text="@string/view_public_repositories_button" />
|
android:text="@string/view_public_repositories_button" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:foreground="@drawable/outline_drawable"
|
|
||||||
android:nextFocusUp="@id/add_repo_button"
|
|
||||||
android:id="@+id/plugin_storage_appbar"
|
android:id="@+id/plugin_storage_appbar"
|
||||||
|
android:nextFocusRight="@id/add_repo_button_imageview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:background="?attr/primaryGrayBackground"
|
android:background="?attr/primaryGrayBackground"
|
||||||
android:orientation="vertical"
|
android:foreground="@drawable/outline_drawable"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:orientation="horizontal">
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent">
|
<LinearLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -160,12 +166,42 @@
|
||||||
tools:text="Not downloaded 3" />
|
tools:text="Not downloaded 3" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/add_repo_button_imageview_holder"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
|
||||||
|
android:text="@string/add_repository"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<ImageView
|
||||||
|
android:background="@drawable/outline_drawable"
|
||||||
|
android:nextFocusLeft="@id/plugin_storage_appbar"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
|
||||||
|
android:id="@+id/add_repo_button_imageview"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@drawable/ic_baseline_add_24"
|
||||||
|
android:contentDescription="@string/add_repository"
|
||||||
|
app:tint="?attr/textColor">
|
||||||
|
</ImageView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
android:id="@+id/add_repo_button"
|
android:id="@+id/add_repo_button"
|
||||||
|
style="@style/ExtendedFloatingActionButton"
|
||||||
android:foreground="@drawable/outline_drawable"
|
android:foreground="@drawable/outline_drawable"
|
||||||
android:nextFocusDown="@id/plugin_storage_appbar"
|
android:nextFocusDown="@id/plugin_storage_appbar"
|
||||||
style="@style/ExtendedFloatingActionButton"
|
|
||||||
android:text="@string/add_repository"
|
android:text="@string/add_repository"
|
||||||
android:textColor="?attr/textColor"
|
android:textColor="?attr/textColor"
|
||||||
android:translationY="-80dp"
|
android:translationY="-80dp"
|
||||||
|
|
122
app/src/main/res/layout/repository_item_tv.xml
Normal file
122
app/src/main/res/layout/repository_item_tv.xml
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/repository_item_root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/outline_drawable"
|
||||||
|
android:nextFocusRight="@id/action_button"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/entry_icon"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_gravity="start|center_vertical"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
app:srcCompat="@drawable/ic_github_logo" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/main_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="Test repository" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/lang_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:text="🇷🇼"
|
||||||
|
|
||||||
|
android:textColor="?attr/grayTextColor"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ext_version"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:text="v1"
|
||||||
|
android:textColor="?attr/grayTextColor"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ext_filesize"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:text="100MB"
|
||||||
|
android:textColor="?attr/grayTextColor"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/nsfw_marker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/is_adult"
|
||||||
|
android:textColor="@color/adultColor"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/sub_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="?attr/grayTextColor"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:text="https://github.com/..." />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/action_settings"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:background="@drawable/outline_drawable"
|
||||||
|
android:contentDescription="@string/title_settings"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:srcCompat="@drawable/ic_baseline_tune_24"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/action_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:background="@drawable/outline_drawable"
|
||||||
|
android:clickable="true"
|
||||||
|
android:contentDescription="@string/download"
|
||||||
|
android:focusable="true"
|
||||||
|
android:nextFocusLeft="@id/repository_item_root"
|
||||||
|
android:padding="12dp"
|
||||||
|
tools:src="@drawable/ic_baseline_add_24" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -468,9 +468,48 @@
|
||||||
<string name="resolution">Resolução</string>
|
<string name="resolution">Resolução</string>
|
||||||
<string name="error_invalid_id">Id invalida</string>
|
<string name="error_invalid_id">Id invalida</string>
|
||||||
<string name="error_invalid_data">Dado invalido</string>
|
<string name="error_invalid_data">Dado invalido</string>
|
||||||
|
<string name="error_invalid_url">URL invalido</string>
|
||||||
<string name="error">Erro</string>
|
<string name="error">Erro</string>
|
||||||
<string name="subtitles_remove_captions">Remover legendas ocultas(CC) das legendas</string>
|
<string name="subtitles_remove_captions">Remover legendas ocultas(CC) das legendas</string>
|
||||||
<string name="subtitles_remove_bloat">Remover bloat das legendas</string>
|
<string name="subtitles_remove_bloat">Remover bloat das legendas</string>
|
||||||
|
<string name="subtitles_filter_lang">Filtrar por linguagem preferida</string>
|
||||||
<string name="extras">Extras</string>
|
<string name="extras">Extras</string>
|
||||||
<string name="trailer">Trailer</string>
|
<string name="trailer">Trailer</string>
|
||||||
|
|
||||||
|
<string name="next">Próximo</string>
|
||||||
|
<string name="provider_languages_tip">Ver vídeos nestas linguagens</string>
|
||||||
|
<string name="previous">Anterior</string>
|
||||||
|
<string name="skip_setup">Saltar setup</string>
|
||||||
|
|
||||||
|
<string name="app_layout_subtext">Change the look of the app to suit your device</string>
|
||||||
|
<string name="crash_reporting_title">Crash reporting</string>
|
||||||
|
<string name="preferred_media_subtext">What do you want to see</string>
|
||||||
|
<string name="setup_done">Feito</string>
|
||||||
|
<string name="extensions">Extensões</string>
|
||||||
|
<string name="add_repository">Adicionar repositório</string>
|
||||||
|
<string name="repository_name_hint">Nome do repositório</string>
|
||||||
|
<string name="repository_url_hint">URL do repositório</string>
|
||||||
|
<string name="plugin_loaded">Plugin Carregado</string>
|
||||||
|
<string name="plugin_deleted">Plugin Apagado</string>
|
||||||
|
<string name="plugin_load_fail" formatted="true">Falha ao carregar %s</string>
|
||||||
|
|
||||||
|
<string name="batch_download_start_format" formatted="true">Iniciada a transferência %d %s</string>
|
||||||
|
<string name="batch_download_finish_format" formatted="true">Transferido %d %s com sucesso</string>
|
||||||
|
<string name="batch_download_nothing_to_download_format" formatted="true">Tudo %s já transferido</string>
|
||||||
|
<string name="batch_download">Transferência em batch</string>
|
||||||
|
<string name="plugin_singular">plugin</string>
|
||||||
|
<string name="plugin">plugins</string>
|
||||||
|
<string name="delete_repository_plugins">Isto irá apagar todos os repositórios de plugins</string>
|
||||||
|
<string name="delete_repository">Apagar repositório</string>
|
||||||
|
<string name="setup_extensions_subtext">Transferir lista de sites a usar</string>
|
||||||
|
<string name="plugins_downloaded" formatted="true">Transferido: %d</string>
|
||||||
|
<string name="plugins_disabled" formatted="true">Desativado: %d</string>
|
||||||
|
<string name="plugins_not_downloaded" formatted="true">Não transferido: %d</string>
|
||||||
|
<string name="blank_repo_message">Adicionar um repositório para instalar extensões de sites</string>
|
||||||
|
<string name="view_public_repositories_button">Ver repositórios da comunidade</string>
|
||||||
|
<string name="view_public_repositories_button_short">Lista pública</string>
|
||||||
|
<string name="uppercase_all_subtitles">Todas as legendas em maiúsculas</string>
|
||||||
|
|
||||||
|
<string name="download_all_plugins_from_repo">Transferir todos os plugins deste repositório?</string>
|
||||||
|
<string name="single_plugin_disabled" formatted="true">%s (Desativado)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<string name="popup_resume_download">डाउनलोड फिर शुरू करे</string>
|
<string name="popup_resume_download">डाउनलोड फिर शुरू करे</string>
|
||||||
<string name="popup_pause_download">डाउनलोड रोके</string>
|
<string name="popup_pause_download">डाउनलोड रोके</string>
|
||||||
|
|
||||||
<string name="pref_disable_acra">Disable automatic bug reporting</string>
|
<string name="pref_disable_acra">स्वचालित त्रुटि रिपोर्ट रोकें</string>
|
||||||
<string name="home_more_info">और जानकारी</string>
|
<string name="home_more_info">और जानकारी</string>
|
||||||
<string name="home_expanded_hide">छिपाये</string>
|
<string name="home_expanded_hide">छिपाये</string>
|
||||||
<string name="home_play">चलाये</string>
|
<string name="home_play">चलाये</string>
|
||||||
|
@ -149,7 +149,7 @@
|
||||||
<string name="video_lock">ताला</string>
|
<string name="video_lock">ताला</string>
|
||||||
<string name="video_aspect_ratio_resize">आकार</string>
|
<string name="video_aspect_ratio_resize">आकार</string>
|
||||||
<string name="video_source">सूत्र</string>
|
<string name="video_source">सूत्र</string>
|
||||||
<string name="video_skip_op">OP टालें</string>
|
<string name="video_skip_op">OP स्किप करें</string>
|
||||||
|
|
||||||
<string name="dont_show_again">फिरसे ना दिखाए</string>
|
<string name="dont_show_again">फिरसे ना दिखाए</string>
|
||||||
<string name="update">अपडेट</string>
|
<string name="update">अपडेट</string>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<string name="title_home">Início</string>
|
<string name="title_home">Início</string>
|
||||||
<string name="title_search">Pesquisa</string>
|
<string name="title_search">Pesquisa</string>
|
||||||
<string name="title_downloads">Transferências</string>
|
<string name="title_downloads">Transferências</string>
|
||||||
<string name="title_settings">Configurações</string>
|
<string name="title_settings">Opções</string>
|
||||||
|
|
||||||
<string name="search_hint">Procurar…</string>
|
<string name="search_hint">Procurar…</string>
|
||||||
<string name="search_hint_site" formatted="true">Procurar em %s…</string>
|
<string name="search_hint_site" formatted="true">Procurar em %s…</string>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
<string name="download_failed">Transferência Falhou</string>
|
<string name="download_failed">Transferência Falhou</string>
|
||||||
<string name="download_canceled">Transferência Cancelada</string>
|
<string name="download_canceled">Transferência Cancelada</string>
|
||||||
<string name="download_done">Transferência Completa</string>
|
<string name="download_done">Transferência Completa</string>
|
||||||
<string name="stream">Transmitir</string>
|
<string name="stream">Stream</string>
|
||||||
|
|
||||||
<string name="error_loading_links_toast">Erro a Carregar Links</string>
|
<string name="error_loading_links_toast">Erro a Carregar Links</string>
|
||||||
<string name="download_storage_text">Armazenamento Interno</string>
|
<string name="download_storage_text">Armazenamento Interno</string>
|
||||||
|
@ -189,7 +189,7 @@
|
||||||
<string name="benene">Dar um benene aos devs</string>
|
<string name="benene">Dar um benene aos devs</string>
|
||||||
<string name="benene_des">Benene dada</string>
|
<string name="benene_des">Benene dada</string>
|
||||||
|
|
||||||
<string name="app_language">Linguagem da App</string>
|
<string name="app_language">Idioma da App</string>
|
||||||
|
|
||||||
<string name="no_chromecast_support_toast">Este fornecedor não tem suporte para Chromecast</string>
|
<string name="no_chromecast_support_toast">Este fornecedor não tem suporte para Chromecast</string>
|
||||||
<string name="no_links_found_toast">Nenhum Link Encontrado</string>
|
<string name="no_links_found_toast">Nenhum Link Encontrado</string>
|
||||||
|
@ -422,11 +422,52 @@
|
||||||
<string name="resolution_and_title">Resolução e título</string>
|
<string name="resolution_and_title">Resolução e título</string>
|
||||||
<string name="title">Título</string>
|
<string name="title">Título</string>
|
||||||
<string name="resolution">Resolução</string>
|
<string name="resolution">Resolução</string>
|
||||||
<string name="error_invalid_id">Id invalida</string>
|
<string name="error_invalid_id">Id inválida</string>
|
||||||
<string name="error_invalid_data">Dado invalido</string>
|
<string name="error_invalid_data">Dado inválido</string>
|
||||||
|
|
||||||
|
<string name="error_invalid_url">URL inválido</string>
|
||||||
<string name="error">Erro</string>
|
<string name="error">Erro</string>
|
||||||
<string name="subtitles_remove_captions">Remover legendas ocultas(CC) das legendas</string>
|
<string name="subtitles_remove_captions">Remover legendas ocultas(CC) das legendas</string>
|
||||||
<string name="subtitles_remove_bloat">Remover bloat das legendas</string>
|
<string name="subtitles_remove_bloat">Remover bloat das legendas</string>
|
||||||
|
|
||||||
|
<string name="subtitles_filter_lang">Filtrar por linguagem preferida</string>
|
||||||
<string name="extras">Extras</string>
|
<string name="extras">Extras</string>
|
||||||
<string name="trailer">Trailer</string>
|
<string name="trailer">Trailer</string>
|
||||||
|
|
||||||
|
<string name="next">Próximo</string>
|
||||||
|
<string name="provider_languages_tip">Ver vídeos nestas linguagens</string>
|
||||||
|
<string name="previous">Anterior</string>
|
||||||
|
<string name="skip_setup">Saltar setup</string>
|
||||||
|
|
||||||
|
<string name="app_layout_subtext">Change the look of the app to suit your device</string>
|
||||||
|
<string name="crash_reporting_title">Crash reporting</string>
|
||||||
|
<string name="preferred_media_subtext">What do you want to see</string>
|
||||||
|
<string name="setup_done">Feito</string>
|
||||||
|
<string name="extensions">Extensões</string>
|
||||||
|
<string name="add_repository">Adicionar repositório</string>
|
||||||
|
<string name="repository_name_hint">Nome do repositório</string>
|
||||||
|
<string name="repository_url_hint">URL do repositório</string>
|
||||||
|
<string name="plugin_loaded">Plugin Carregado</string>
|
||||||
|
<string name="plugin_deleted">Plugin Apagado</string>
|
||||||
|
<string name="plugin_load_fail" formatted="true">Falha ao carregar %s</string>
|
||||||
|
|
||||||
|
<string name="batch_download_start_format" formatted="true">Iniciada a transferência %d %s</string>
|
||||||
|
<string name="batch_download_finish_format" formatted="true">Transferido %d %s com sucesso</string>
|
||||||
|
<string name="batch_download_nothing_to_download_format" formatted="true">Tudo %s já transferido</string>
|
||||||
|
<string name="batch_download">Transferência em batch</string>
|
||||||
|
<string name="plugin_singular">plugin</string>
|
||||||
|
<string name="plugin">plugins</string>
|
||||||
|
<string name="delete_repository_plugins">Isto irá apagar todos os repositórios de plugins</string>
|
||||||
|
<string name="delete_repository">Apagar repositório</string>
|
||||||
|
<string name="setup_extensions_subtext">Transferir lista de sites a usar</string>
|
||||||
|
<string name="plugins_downloaded" formatted="true">Transferido: %d</string>
|
||||||
|
<string name="plugins_disabled" formatted="true">Desativado: %d</string>
|
||||||
|
<string name="plugins_not_downloaded" formatted="true">Não transferido: %d</string>
|
||||||
|
<string name="blank_repo_message">Adicionar um repositório para instalar extensões de sites</string>
|
||||||
|
<string name="view_public_repositories_button">Ver repositórios da comunidade</string>
|
||||||
|
<string name="view_public_repositories_button_short">Lista pública</string>
|
||||||
|
<string name="uppercase_all_subtitles">Todas as legendas em maiúsculas</string>
|
||||||
|
|
||||||
|
<string name="download_all_plugins_from_repo">Transferir todos os plugins deste repositório?</string>
|
||||||
|
<string name="single_plugin_disabled" formatted="true">%s (Desativado)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
<string name="redo_setup_key" translatable="false">redo_setup_key</string>
|
<string name="redo_setup_key" translatable="false">redo_setup_key</string>
|
||||||
<string name="filter_sub_lang_key" translatable="false">filter_sub_lang_key</string>
|
<string name="filter_sub_lang_key" translatable="false">filter_sub_lang_key</string>
|
||||||
<string name="pref_filter_search_quality_key" translatable="false">pref_filter_search_quality_key</string>
|
<string name="pref_filter_search_quality_key" translatable="false">pref_filter_search_quality_key</string>
|
||||||
|
<string name="enable_nsfw_on_providers_key" translatable="false">enable_nsfw_on_providers_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" formatted="true" translatable="false">%d %s | %s</string>
|
<string name="extra_info_format" formatted="true" translatable="false">%d %s | %s</string>
|
||||||
|
@ -444,6 +445,7 @@
|
||||||
<string name="provider_lang_settings">Provider languages</string>
|
<string name="provider_lang_settings">Provider languages</string>
|
||||||
<string name="app_layout">App Layout</string>
|
<string name="app_layout">App Layout</string>
|
||||||
<string name="preferred_media_settings">Preferred media</string>
|
<string name="preferred_media_settings">Preferred media</string>
|
||||||
|
<string name="enable_nsfw_on_providers">Enable NSFW on supported providers</string>
|
||||||
<string name="subtitles_encoding">Subtitle encoding</string>
|
<string name="subtitles_encoding">Subtitle encoding</string>
|
||||||
<string name="category_preferred_media_and_lang">Language</string>
|
<string name="category_preferred_media_and_lang">Language</string>
|
||||||
<string name="category_ui">Layout</string>
|
<string name="category_ui">Layout</string>
|
||||||
|
@ -610,4 +612,5 @@
|
||||||
<string name="tracks">Tracks</string>
|
<string name="tracks">Tracks</string>
|
||||||
<string name="audio_tracks">Audio tracks</string>
|
<string name="audio_tracks">Audio tracks</string>
|
||||||
<string name="video_tracks">Video tracks</string>
|
<string name="video_tracks">Video tracks</string>
|
||||||
|
<string name="apply_on_restart">Apply on Restart</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -18,4 +18,11 @@
|
||||||
android:key="@string/display_sub_key"
|
android:key="@string/display_sub_key"
|
||||||
android:title="@string/display_subbed_dubbed_settings"
|
android:title="@string/display_subbed_dubbed_settings"
|
||||||
android:icon="@drawable/ic_outline_voice_over_off_24" />
|
android:icon="@drawable/ic_outline_voice_over_off_24" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="@string/enable_nsfw_on_providers_key"
|
||||||
|
android:title="@string/enable_nsfw_on_providers"
|
||||||
|
android:icon="@drawable/ic_baseline_extension_24"
|
||||||
|
android:summary="@string/apply_on_restart"
|
||||||
|
app:defaultValue="false"/>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
Add table
Add a link
Reference in a new issue