Merge remote-tracking branch 'origin/master'

# Conflicts:
#	app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt
This commit is contained in:
Stormunblessed 2023-02-10 15:20:33 -06:00
commit f42e00f4c5
No known key found for this signature in database
GPG key ID: CE92471F93C0CAB4
114 changed files with 5302 additions and 1325 deletions

5
.github/locales.py vendored
View file

@ -7,7 +7,7 @@ SETTINGS_PATH = "app/src/main/java/com/lagradost/cloudstream3/ui/settings/Settin
START_MARKER = "/* begin language list */" START_MARKER = "/* begin language list */"
END_MARKER = "/* end language list */" END_MARKER = "/* end language list */"
XML_NAME = "app/src/main/res/values-" XML_NAME = "app/src/main/res/values-"
ISO_MAP_URL = "https://gist.githubusercontent.com/Josantonius/b455e315bc7f790d14b136d61d9ae469/raw" ISO_MAP_URL = "https://raw.githubusercontent.com/haliaeetus/iso-639/master/data/iso_639-1.min.json"
INDENT = " "*4 INDENT = " "*4
iso_map = requests.get(ISO_MAP_URL, timeout=300).json() iso_map = requests.get(ISO_MAP_URL, timeout=300).json()
@ -27,7 +27,8 @@ for lang in re.finditer(r'Triple\("(.*)", "(.*)", "(.*)"\)', rest):
for folder in glob.glob(f"{XML_NAME}*"): for folder in glob.glob(f"{XML_NAME}*"):
iso = folder[len(XML_NAME):] iso = folder[len(XML_NAME):]
if iso not in languages.keys(): if iso not in languages.keys():
languages[iso] = ("", iso_map.get(iso.lower(),iso)) entry = iso_map.get(iso.lower(),{'nativeName':iso})
languages[iso] = ("", entry['nativeName'].split(',')[0])
# Create triples # Create triples
triples = [] triples = []

View file

@ -15,6 +15,7 @@ jobs:
app_id: ${{ secrets.GH_APP_ID }} app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_KEY }} private_key: ${{ secrets.GH_APP_KEY }}
- name: Similarity analysis - name: Similarity analysis
id: similarity
uses: actions-cool/issues-similarity-analysis@v1 uses: actions-cool/issues-similarity-analysis@v1
with: with:
token: ${{ steps.generate_token.outputs.token }} token: ${{ steps.generate_token.outputs.token }}
@ -24,6 +25,18 @@ jobs:
### Your issue looks similar to these issues: ### Your issue looks similar to these issues:
Please close if duplicate. Please close if duplicate.
comment-body: '${index}. ${similarity} #${number}' comment-body: '${index}. ${similarity} #${number}'
- name: Label if possible duplicate
if: steps.similarity.outputs.similar-issues-found =='true'
uses: actions/github-script@v6
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ["possible duplicate"]
})
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Automatically close issues that dont follow the issue template - name: Automatically close issues that dont follow the issue template
uses: lucasbento/auto-close-issues@v1.0.2 uses: lucasbento/auto-close-issues@v1.0.2
@ -53,6 +66,18 @@ jobs:
Please do not report any provider bugs here. This repository does not contain any providers. Please find the appropriate repository and report your issue there or join the [discord](https://discord.gg/5Hus6fM). Please do not report any provider bugs here. This repository does not contain any providers. Please find the appropriate repository and report your issue there or join the [discord](https://discord.gg/5Hus6fM).
Found provider name: `${{ steps.provider_check.outputs.name }}` Found provider name: `${{ steps.provider_check.outputs.name }}`
- name: Label if mentions provider
if: steps.provider_check.outputs.name != 'none'
uses: actions/github-script@v6
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ["possible provider issue"]
})
- name: Add eyes reaction to all issues - name: Add eyes reaction to all issues
uses: actions-cool/emoji-helper@v1.0.0 uses: actions-cool/emoji-helper@v1.0.0
with: with:

View file

@ -47,8 +47,8 @@ android {
minSdk = 21 minSdk = 21
targetSdk = 33 targetSdk = 33
versionCode = 55 versionCode = 57
versionName = "3.4.0" versionName = "4.0.0"
resValue("string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}") resValue("string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}")
@ -190,7 +190,7 @@ dependencies {
// Networking // Networking
// implementation("com.squareup.okhttp3:okhttp:4.9.2") // implementation("com.squareup.okhttp3:okhttp:4.9.2")
// implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.1") // implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.1")
implementation("com.github.Blatzar:NiceHttp:0.4.1") implementation("com.github.Blatzar:NiceHttp:0.4.2")
// To fix SSL fuckery on android 9 // To fix SSL fuckery on android 9
implementation("org.conscrypt:conscrypt-android:2.2.1") implementation("org.conscrypt:conscrypt-android:2.2.1")
// Util to skip the URI file fuckery 🙏 // Util to skip the URI file fuckery 🙏
@ -220,6 +220,9 @@ dependencies {
// Library/extensions searching with Levenshtein distance // Library/extensions searching with Levenshtein distance
implementation("me.xdrop:fuzzywuzzy:1.4.0") implementation("me.xdrop:fuzzywuzzy:1.4.0")
// color pallette for images -> colors
implementation("androidx.palette:palette-ktx:1.0.0")
} }
tasks.register("androidSourcesJar", Jar::class) { tasks.register("androidSourcesJar", Jar::class) {
@ -250,4 +253,4 @@ tasks.withType<DokkaTask>().configureEach {
} }
} }
} }
} }

View file

@ -43,9 +43,9 @@ class CustomReportSender : ReportSender {
override fun send(context: Context, errorContent: CrashReportData) { override fun send(context: Context, errorContent: CrashReportData) {
println("Sending report") println("Sending report")
val url = val url =
"https://docs.google.com/forms/u/0/d/e/1FAIpQLSe9Vff8oHGMRXcjgCXZwkjvx3eBdNpn4DzjO0FkcWEU1gEQpA/formResponse" "https://docs.google.com/forms/d/e/1FAIpQLSdOlbgCx7NeaxjvEGyEQlqdh2nCvwjm2vwpP1VwW7REj9Ri3Q/formResponse"
val data = mapOf( val data = mapOf(
"entry.1586460852" to errorContent.toJSON() "entry.753293084" to errorContent.toJSON()
) )
thread { // to not run it on main thread thread { // to not run it on main thread

View file

@ -13,11 +13,11 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.ui.player.SubtitleData import com.lagradost.cloudstream3.ui.player.SubtitleData
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf
import com.lagradost.cloudstream3.utils.ExtractorLink
import okhttp3.Interceptor import okhttp3.Interceptor
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -81,8 +81,8 @@ object APIHolder {
synchronized(allProviders) { synchronized(allProviders) {
initMap() initMap()
return apiMap?.get(apiName)?.let { apis.getOrNull(it) } return apiMap?.get(apiName)?.let { apis.getOrNull(it) }
// Leave the ?. null check, it can crash regardless // Leave the ?. null check, it can crash regardless
?: allProviders.firstOrNull { it?.name == apiName } ?: allProviders.firstOrNull { it.name == apiName }
} }
} }
@ -160,6 +160,53 @@ object APIHolder {
return null return null
} }
private var trackerCache: HashMap<String, AniSearch> = hashMapOf()
/**
* Get anime tracker information based on title, year and type.
* Both titles are attempted to be matched with both Romaji and English title.
* Uses the consumet api.
*
* @param titles uses first index to search, but if you have multiple titles and want extra guarantee to match you can also have that
* @param types Optional parameter to narrow down the scope to Movies, TV, etc. See TrackerType.getTypes()
* @param year Optional parameter to only get anime with a specific year
**/
suspend fun getTracker(
titles: List<String>,
types: Set<TrackerType>?,
year: Int?
): Tracker? {
return try {
require(titles.isNotEmpty()) { "titles must no be empty when calling getTracker" }
val mainTitle = titles[0]
val search =
trackerCache[mainTitle]
?: app.get("https://api.consumet.org/meta/anilist/$mainTitle")
.parsedSafe<AniSearch>()?.also {
trackerCache[mainTitle] = it
} ?: return null
val res = search.results?.find { media ->
val matchingYears = year == null || media.releaseDate == year
val matchingTitles = media.title?.let { title ->
titles.any { userTitle ->
title.isMatchingTitles(userTitle)
}
} ?: false
val matchingTypes = types?.any { it.name.equals(media.type, true) } == true
matchingTitles && matchingTypes && matchingYears
} ?: return null
Tracker(res.malId, res.aniId, res.image, res.cover)
} catch (t: Throwable) {
logError(t)
null
}
}
fun Context.getApiSettings(): HashSet<String> { fun Context.getApiSettings(): HashSet<String> {
//val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) //val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
@ -318,6 +365,57 @@ object APIHolder {
} }
} }
/*
// THIS IS WORK IN PROGRESS API
interface ITag {
val name: UiText
}
data class SimpleTag(override val name: UiText, val data: String) : ITag
enum class SelectType {
SingleSelect,
MultiSelect,
MultiSelectAndExclude,
}
enum class SelectValue {
Selected,
Excluded,
}
interface GenreSelector {
val title: UiText
val id : Int
}
data class TagSelector(
override val title: UiText,
override val id : Int,
val tags: Set<ITag>,
val defaultTags : Set<ITag> = setOf(),
val selectType: SelectType = SelectType.SingleSelect,
) : GenreSelector
data class BoolSelector(
override val title: UiText,
override val id : Int,
val defaultValue : Boolean = false,
) : GenreSelector
data class InputField(
override val title: UiText,
override val id : Int,
val hint : UiText? = null,
) : GenreSelector
// This response describes how a user might filter the homepage or search results
data class GenreResponse(
val searchSelectors : List<GenreSelector>,
val filterSelectors: List<GenreSelector> = searchSelectors
) */
/* /*
0 = Site not good 0 = Site not good
@ -459,6 +557,20 @@ abstract class MainAPI {
open val hasMainPage = false open val hasMainPage = false
open val hasQuickSearch = false open val hasQuickSearch = false
/**
* A set of which ids the provider can open with getLoadUrl()
* If the set contains SyncIdName.Imdb then getLoadUrl() can be started with
* an Imdb class which inherits from SyncId.
*
* getLoadUrl() is then used to get page url based on that ID.
*
* Example:
* "tt6723592" -> getLoadUrl(ImdbSyncId("tt6723592")) -> "mainUrl/imdb/tt6723592" -> load("mainUrl/imdb/tt6723592")
*
* This is used to launch pages from personal lists or recommendations using IDs.
**/
open val supportedSyncNames = setOf<SyncIdName>()
open val supportedTypes = setOf( open val supportedTypes = setOf(
TvType.Movie, TvType.Movie,
TvType.TvSeries, TvType.TvSeries,
@ -529,6 +641,14 @@ abstract class MainAPI {
open fun getVideoInterceptor(extractorLink: ExtractorLink): Interceptor? { open fun getVideoInterceptor(extractorLink: ExtractorLink): Interceptor? {
return null return null
} }
/**
* Get the load() url based on a sync ID like IMDb or MAL.
* Only contains SyncIds based on supportedSyncUrls.
**/
open suspend fun getLoadUrl(name: SyncIdName, id: String): String? {
return null
}
} }
/** Might need a different implementation for desktop*/ /** Might need a different implementation for desktop*/
@ -1514,3 +1634,61 @@ fun fetchUrls(text: String?): List<String> {
fun String?.toRatingInt(): Int? = fun String?.toRatingInt(): Int? =
this?.replace(" ", "")?.trim()?.toDoubleOrNull()?.absoluteValue?.times(1000f)?.toInt() this?.replace(" ", "")?.trim()?.toDoubleOrNull()?.absoluteValue?.times(1000f)?.toInt()
data class Tracker(
val malId: Int? = null,
val aniId: String? = null,
val image: String? = null,
val cover: String? = null,
)
data class Title(
@JsonProperty("romaji") val romaji: String? = null,
@JsonProperty("english") val english: String? = null,
) {
fun isMatchingTitles(title: String?): Boolean {
if (title == null) return false
return english.equals(title, true) || romaji.equals(title, true)
}
}
data class Results(
@JsonProperty("id") val aniId: String? = null,
@JsonProperty("malId") val malId: Int? = null,
@JsonProperty("title") val title: Title? = null,
@JsonProperty("releaseDate") val releaseDate: Int? = null,
@JsonProperty("type") val type: String? = null,
@JsonProperty("image") val image: String? = null,
@JsonProperty("cover") val cover: String? = null,
)
data class AniSearch(
@JsonProperty("results") val results: ArrayList<Results>? = arrayListOf()
)
/**
* used for the getTracker() method
**/
enum class TrackerType {
MOVIE,
TV,
TV_SHORT,
ONA,
OVA,
SPECIAL,
MUSIC;
companion object {
fun getTypes(type: TvType): Set<TrackerType> {
return when (type) {
TvType.Movie -> setOf(MOVIE)
TvType.AnimeMovie -> setOf(MOVIE)
TvType.TvSeries -> setOf(TV, TV_SHORT)
TvType.Anime -> setOf(TV, TV_SHORT, ONA, OVA)
TvType.OVA -> setOf(OVA, SPECIAL, ONA)
TvType.Others -> setOf(MUSIC)
else -> emptySet()
}
}
}
}

View file

@ -1,16 +1,14 @@
package com.lagradost.cloudstream3 package com.lagradost.cloudstream3
import android.content.ComponentName import android.content.ComponentName
import android.content.DialogInterface import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.KeyEvent import android.view.*
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.IdRes import androidx.annotation.IdRes
@ -19,6 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavDestination.Companion.hierarchy
@ -31,6 +30,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.google.android.gms.cast.framework.* import com.google.android.gms.cast.framework.*
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.navigationrail.NavigationRailView import com.google.android.material.navigationrail.NavigationRailView
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import com.lagradost.cloudstream3.APIHolder.allProviders import com.lagradost.cloudstream3.APIHolder.allProviders
@ -46,8 +46,7 @@ import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.CommonActivity.updateLocale import com.lagradost.cloudstream3.CommonActivity.updateLocale
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.*
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.network.initClient import com.lagradost.cloudstream3.network.initClient
import com.lagradost.cloudstream3.plugins.PluginManager import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.plugins.PluginManager.loadAllOnlinePlugins import com.lagradost.cloudstream3.plugins.PluginManager.loadAllOnlinePlugins
@ -61,9 +60,13 @@ import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStri
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringSearch import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringSearch
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
import com.lagradost.cloudstream3.ui.home.HomeViewModel import com.lagradost.cloudstream3.ui.home.HomeViewModel
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.result.setImage
import com.lagradost.cloudstream3.ui.result.setText
import com.lagradost.cloudstream3.ui.search.SearchFragment import com.lagradost.cloudstream3.ui.search.SearchFragment
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
@ -74,6 +77,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsGeneral
import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY
import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.html
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.loadRepository import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
@ -86,9 +90,11 @@ import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.setKey import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
import com.lagradost.cloudstream3.utils.UIHelper.checkWrite import com.lagradost.cloudstream3.utils.UIHelper.checkWrite
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor 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
@ -96,6 +102,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.nicehttp.Requests import com.lagradost.nicehttp.Requests
import com.lagradost.nicehttp.ResponseParser import com.lagradost.nicehttp.ResponseParser
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.bottom_resultview_preview.*
import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.android.synthetic.main.fragment_result_swipe.*
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
@ -244,6 +251,10 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
Event<Boolean>() // homepage api, used to speed up time to load for homepage Event<Boolean>() // homepage api, used to speed up time to load for homepage
val afterRepositoryLoadedEvent = Event<Boolean>() val afterRepositoryLoadedEvent = Event<Boolean>()
// kinda shitty solution, but cant com main->home otherwise for popups
val bookmarksUpdatedEvent = Event<Boolean>()
/** /**
* @return true if the str has launched an app task (be it successful or not) * @return true if the str has launched an app task (be it successful or not)
* @param isWebview does not handle providers and opening download page if true. Can still add repos and login. * @param isWebview does not handle providers and opening download page if true. Can still add repos and login.
@ -336,6 +347,16 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
} }
} }
var lastPopup: SearchResponse? = null
fun loadPopup(result: SearchResponse) {
lastPopup = result
viewModel.load(
this, result.url, result.apiName, false, if (getApiDubstatusSettings()
.contains(DubStatus.Dubbed)
) DubStatus.Dubbed else DubStatus.Subbed, null
)
}
override fun onColorSelected(dialogId: Int, color: Int) { override fun onColorSelected(dialogId: Int, color: Int) {
onColorSelectedEvent.invoke(Pair(dialogId, color)) onColorSelectedEvent.invoke(Pair(dialogId, color))
} }
@ -367,6 +388,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
val isNavVisible = listOf( val isNavVisible = listOf(
R.id.navigation_home, R.id.navigation_home,
R.id.navigation_search, R.id.navigation_search,
R.id.navigation_library,
R.id.navigation_downloads, R.id.navigation_downloads,
R.id.navigation_settings, R.id.navigation_settings,
R.id.navigation_download_child, R.id.navigation_download_child,
@ -417,6 +439,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
nav_view?.isVisible = isNavVisible && !landscape nav_view?.isVisible = isNavVisible && !landscape
nav_rail_view?.isVisible = isNavVisible && landscape nav_rail_view?.isVisible = isNavVisible && landscape
// Hide library on TV since it is not supported yet :(
val isTrueTv = isTrueTvSettings()
nav_view?.menu?.findItem(R.id.navigation_library)?.isVisible = !isTrueTv
nav_rail_view?.menu?.findItem(R.id.navigation_library)?.isVisible = !isTrueTv
} }
//private var mCastSession: CastSession? = null //private var mCastSession: CastSession? = null
@ -619,6 +646,37 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
} }
} }
lateinit var viewModel: ResultViewModel2
override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
viewModel =
ViewModelProvider(this)[ResultViewModel2::class.java]
return super.onCreateView(name, context, attrs)
}
private fun hidePreviewPopupDialog() {
viewModel.clear()
bottomPreviewPopup.dismissSafe(this)
}
var bottomPreviewPopup: BottomSheetDialog? = null
private fun showPreviewPopupDialog(): BottomSheetDialog {
val ret = (bottomPreviewPopup ?: run {
val builder =
BottomSheetDialog(this)
builder.setContentView(R.layout.bottom_resultview_preview)
builder.setOnDismissListener {
bottomPreviewPopup = null
viewModel.clear()
}
builder.setCanceledOnTouchOutside(true)
builder.show()
builder
})
bottomPreviewPopup = ret
return ret
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
app.initClient(this) app.initClient(this)
@ -658,7 +716,12 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
changeStatusBarState(isEmulatorSettings()) changeStatusBarState(isEmulatorSettings())
if (lastError == null) {
if (PluginManager.checkSafeModeFile()) {
normalSafeApiCall {
showToast(this, R.string.safe_mode_file, Toast.LENGTH_LONG)
}
} else if (lastError == null) {
ioSafe { ioSafe {
getKey<String>(USER_SELECTED_HOMEPAGE_API)?.let { homeApi -> getKey<String>(USER_SELECTED_HOMEPAGE_API)?.let { homeApi ->
mainPluginsLoadedEvent.invoke(loadSinglePlugin(this@MainActivity, homeApi)) mainPluginsLoadedEvent.invoke(loadSinglePlugin(this@MainActivity, homeApi))
@ -708,6 +771,78 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
builder.show().setDefaultFocus() builder.show().setDefaultFocus()
} }
observeNullable(viewModel.page) { resource ->
if (resource == null) {
bottomPreviewPopup.dismissSafe(this)
return@observeNullable
}
when (resource) {
is Resource.Failure -> {
showToast(this, R.string.error)
hidePreviewPopupDialog()
}
is Resource.Loading -> {
showPreviewPopupDialog().apply {
resultview_preview_loading?.isVisible = true
resultview_preview_result?.isVisible = false
resultview_preview_loading_shimmer?.startShimmer()
}
}
is Resource.Success -> {
val d = resource.value
showPreviewPopupDialog().apply {
resultview_preview_loading?.isVisible = false
resultview_preview_result?.isVisible = true
resultview_preview_loading_shimmer?.stopShimmer()
resultview_preview_title?.text = d.title
resultview_preview_meta_type.setText(d.typeText)
resultview_preview_meta_year.setText(d.yearText)
resultview_preview_meta_duration.setText(d.durationText)
resultview_preview_meta_rating.setText(d.ratingText)
resultview_preview_description?.setText(d.plotText)
resultview_preview_poster?.setImage(
d.posterImage ?: d.posterBackgroundImage
)
resultview_preview_poster?.setOnClickListener {
//viewModel.updateWatchStatus(WatchType.PLANTOWATCH)
val value = viewModel.watchStatus.value ?: WatchType.NONE
this@MainActivity.showBottomDialog(
WatchType.values().map { getString(it.stringRes) }.toList(),
value.ordinal,
this@MainActivity.getString(R.string.action_add_to_bookmarks),
showApply = false,
{}) {
viewModel.updateWatchStatus(WatchType.values()[it])
bookmarksUpdatedEvent(true)
}
}
if (!isTvSettings()) // dont want this clickable on tv layout
resultview_preview_description?.setOnClickListener { view ->
view.context?.let { ctx ->
val builder: AlertDialog.Builder =
AlertDialog.Builder(ctx, R.style.AlertDialogCustom)
builder.setMessage(d.plotText.asString(ctx).html())
.setTitle(d.plotHeaderText.asString(ctx))
.show()
}
}
resultview_preview_more_info?.setOnClickListener {
hidePreviewPopupDialog()
lastPopup?.let {
loadSearchResult(it)
}
}
}
}
}
}
// ioSafe { // ioSafe {
// val plugins = // val plugins =

View file

@ -0,0 +1,23 @@
package com.lagradost.cloudstream3.extractors
import com.lagradost.cloudstream3.utils.*
open class ByteShare : ExtractorApi() {
override val name = "ByteShare"
override val mainUrl = "https://byteshare.net"
override val requiresReferer = false
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> {
val sources = mutableListOf<ExtractorLink>()
sources.add(
ExtractorLink(
name,
name,
url.replace("/embed/", "/download/"),
"",
Qualities.Unknown.value,
)
)
return sources
}
}

View file

@ -1,32 +1,51 @@
package com.lagradost.cloudstream3.extractors package com.lagradost.cloudstream3.extractors
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import java.net.URI
class FileMoon : Filesim() {
override val mainUrl = "https://filemoon.to"
override val name = "FileMoon"
}
open class Filesim : ExtractorApi() { open class Filesim : ExtractorApi() {
override val name = "Filesim" override val name = "Filesim"
override val mainUrl = "https://files.im" override val mainUrl = "https://files.im"
override val requiresReferer = false override val requiresReferer = false
override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> { override suspend fun getUrl(
val sources = mutableListOf<ExtractorLink>() url: String,
referer: String?,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
with(app.get(url).document) { with(app.get(url).document) {
this.select("script").map { script -> this.select("script").forEach { script ->
if (script.data().contains("eval(function(p,a,c,k,e,d)")) { if (script.data().contains("eval(function(p,a,c,k,e,d)")) {
val data = getAndUnpack(script.data()).substringAfter("sources:[").substringBefore("]") val data = getAndUnpack(script.data())
tryParseJson<List<ResponseSource>>("[$data]")?.map { val foundData = Regex("""sources:\[(.*?)]""").find(data)?.groupValues?.get(1) ?: return@forEach
M3u8Helper.generateM3u8( val fixedData = foundData.replace("file:", """"file":""")
name,
it.file, parseJson<List<ResponseSource>>("[$fixedData]").forEach {
"$mainUrl/", callback.invoke(
).forEach { m3uData -> sources.add(m3uData) } ExtractorLink(
name,
name,
it.file,
"$mainUrl/",
Qualities.Unknown.value,
URI(it.file).path.endsWith(".m3u8")
)
)
} }
} }
} }
} }
return sources
} }
private data class ResponseSource( private data class ResponseSource(

View file

@ -6,6 +6,11 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
class Vanfem : GuardareStream() {
override var name = "Vanfem"
override var mainUrl = "https://vanfem.com/"
}
class CineGrabber : GuardareStream() { class CineGrabber : GuardareStream() {
override var name = "CineGrabber" override var name = "CineGrabber"
override var mainUrl = "https://cinegrabber.com" override var mainUrl = "https://cinegrabber.com"

View file

@ -59,8 +59,8 @@ open class VidSrcExtractor : ExtractorApi() {
if (datahash.isNotBlank()) { if (datahash.isNotBlank()) {
val links = try { val links = try {
app.get( app.get(
"$absoluteUrl/src/$datahash", "$absoluteUrl/srcrcp/$datahash",
referer = "https://source.vidsrc.me/" referer = "https://rcp.vidsrc.me/"
).url ).url
} catch (e: Exception) { } catch (e: Exception) {
"" ""
@ -71,7 +71,7 @@ open class VidSrcExtractor : ExtractorApi() {
serverslist.amap { server -> serverslist.amap { server ->
val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/") val linkfixed = server.replace("https://vidsrc.xyz/", "https://embedsito.com/")
if (linkfixed.contains("/pro")) { if (linkfixed.contains("/prorcp")) {
val srcresponse = app.get(server, referer = absoluteUrl).text val srcresponse = app.get(server, referer = absoluteUrl).text
val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)") val m3u8Regex = Regex("((https:|http:)//.*\\.m3u8)")
val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@amap val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@amap

View file

@ -1,30 +0,0 @@
package com.lagradost.cloudstream3.metaproviders
import com.lagradost.cloudstream3.ErrorLoadingException
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.aniListApi
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.malApi
import com.lagradost.cloudstream3.utils.SyncUtil
object SyncRedirector {
val syncApis = SyncApis
suspend fun redirect(url: String, preferredUrl: String): String {
for (api in syncApis) {
if (url.contains(api.mainUrl)) {
val otherApi = when (api.name) {
aniListApi.name -> "anilist"
malApi.name -> "myanimelist"
else -> return url
}
return SyncUtil.getUrlsFromId(api.getIdFromUrl(url), otherApi).firstOrNull { realUrl ->
realUrl.contains(preferredUrl)
} ?: run {
throw ErrorLoadingException("Page does not exist on $preferredUrl")
}
}
}
return url
}
}

View file

@ -0,0 +1,56 @@
package com.lagradost.cloudstream3.metaproviders
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
import com.lagradost.cloudstream3.syncproviders.SyncIdName
object SyncRedirector {
val syncApis = SyncApis
private val syncIds =
listOf(
SyncIdName.MyAnimeList to Regex("""myanimelist\.net\/anime\/(\d+)"""),
SyncIdName.Anilist to Regex("""anilist\.co\/anime\/(\d+)""")
)
suspend fun redirect(
url: String,
providerApi: MainAPI
): String {
// Deprecated since providers should do this instead!
// Tries built in ID -> ProviderUrl
/*
for (api in syncApis) {
if (url.contains(api.mainUrl)) {
val otherApi = when (api.name) {
aniListApi.name -> "anilist"
malApi.name -> "myanimelist"
else -> return url
}
SyncUtil.getUrlsFromId(api.getIdFromUrl(url), otherApi).firstOrNull { realUrl ->
realUrl.contains(providerApi.mainUrl)
}?.let {
return it
}
// ?: run {
// throw ErrorLoadingException("Page does not exist on $preferredUrl")
// }
}
}
*/
// Tries provider solution
// This goes through all sync ids and finds supported id by said provider
return syncIds.firstNotNullOfOrNull { (syncName, syncRegex) ->
if (providerApi.supportedSyncNames.contains(syncName)) {
syncRegex.find(url)?.value?.let {
suspendSafeApiCall {
providerApi.getLoadUrl(syncName, it)
}
}
} else null
} ?: url
}
}

View file

@ -64,7 +64,9 @@ class CloudflareKiller : Interceptor {
} }
private fun getWebViewCookie(url: String): String? { private fun getWebViewCookie(url: String): String? {
return CookieManager.getInstance()?.getCookie(url) return normalSafeApiCall {
CookieManager.getInstance()?.getCookie(url)
}
} }
/** /**

View file

@ -144,8 +144,10 @@ object PluginManager {
return getKey(PLUGINS_KEY_LOCAL) ?: emptyArray() return getKey(PLUGINS_KEY_LOCAL) ?: emptyArray()
} }
private val LOCAL_PLUGINS_PATH = private val CLOUD_STREAM_FOLDER =
Environment.getExternalStorageDirectory().absolutePath + "/Cloudstream3/plugins" Environment.getExternalStorageDirectory().absolutePath + "/Cloudstream3/"
private val LOCAL_PLUGINS_PATH = CLOUD_STREAM_FOLDER + "plugins"
public var currentlyLoading: String? = null public var currentlyLoading: String? = null
@ -421,6 +423,21 @@ object PluginManager {
afterPluginsLoadedEvent.invoke(forceReload) afterPluginsLoadedEvent.invoke(forceReload)
} }
/**
* This can be used to override any extension loading to fix crashes!
* @return true if safe mode file is present
**/
fun checkSafeModeFile(): Boolean {
return normalSafeApiCall {
val folder = File(CLOUD_STREAM_FOLDER)
if (!folder.exists()) return@normalSafeApiCall false
val files = folder.listFiles { _, name ->
name.equals("safe", ignoreCase = true)
}
files?.any()
} ?: false
}
/** /**
* @return True if successful, false if not * @return True if successful, false if not
* */ * */

View file

@ -13,6 +13,7 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
val openSubtitlesApi = OpenSubtitlesApi(0) val openSubtitlesApi = OpenSubtitlesApi(0)
val indexSubtitlesApi = IndexSubtitleApi() val indexSubtitlesApi = IndexSubtitleApi()
val addic7ed = Addic7ed() val addic7ed = Addic7ed()
val localListApi = LocalList()
// used to login via app intent // used to login via app intent
val OAuth2Apis val OAuth2Apis
@ -29,7 +30,7 @@ abstract class AccountManager(private val defIndex: Int) : AuthAPI {
// used for active syncing // used for active syncing
val SyncApis val SyncApis
get() = listOf( get() = listOf(
SyncRepo(malApi), SyncRepo(aniListApi) SyncRepo(malApi), SyncRepo(aniListApi), SyncRepo(localListApi)
) )
val inAppAuths val inAppAuths

View file

@ -1,10 +1,31 @@
package com.lagradost.cloudstream3.syncproviders package com.lagradost.cloudstream3.syncproviders
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.ui.library.ListSorting
import com.lagradost.cloudstream3.ui.result.UiText
import me.xdrop.fuzzywuzzy.FuzzySearch
enum class SyncIdName {
Anilist,
MyAnimeList,
Trakt,
Imdb,
LocalList
}
interface SyncAPI : OAuth2API { interface SyncAPI : OAuth2API {
/**
* Set this to true if the user updates something on the list like watch status or score
**/
var requireLibraryRefresh: Boolean
val mainUrl: String val mainUrl: String
/**
* Allows certain providers to open pages from
* library links.
**/
val syncIdName: SyncIdName
/** /**
-1 -> None -1 -> None
0 -> Watching 0 -> Watching
@ -22,7 +43,9 @@ interface SyncAPI : OAuth2API {
suspend fun search(name: String): List<SyncSearchResult>? suspend fun search(name: String): List<SyncSearchResult>?
fun getIdFromUrl(url : String) : String suspend fun getPersonalLibrary(): LibraryMetadata?
fun getIdFromUrl(url: String): String
data class SyncSearchResult( data class SyncSearchResult(
override val name: String, override val name: String,
@ -42,7 +65,7 @@ interface SyncAPI : OAuth2API {
val score: Int?, val score: Int?,
val watchedEpisodes: Int?, val watchedEpisodes: Int?,
var isFavorite: Boolean? = null, var isFavorite: Boolean? = null,
var maxEpisodes : Int? = null, var maxEpisodes: Int? = null,
) )
data class SyncResult( data class SyncResult(
@ -63,9 +86,9 @@ interface SyncAPI : OAuth2API {
var genres: List<String>? = null, var genres: List<String>? = null,
var synonyms: List<String>? = null, var synonyms: List<String>? = null,
var trailers: List<String>? = null, var trailers: List<String>? = null,
var isAdult : Boolean? = null, var isAdult: Boolean? = null,
var posterUrl: String? = null, var posterUrl: String? = null,
var backgroundPosterUrl : String? = null, var backgroundPosterUrl: String? = null,
/** In unixtime */ /** In unixtime */
var startDate: Long? = null, var startDate: Long? = null,
@ -76,4 +99,61 @@ interface SyncAPI : OAuth2API {
var prevSeason: SyncSearchResult? = null, var prevSeason: SyncSearchResult? = null,
var actors: List<ActorData>? = null, var actors: List<ActorData>? = null,
) )
data class Page(
val title: UiText, var items: List<LibraryItem>
) {
fun sort(method: ListSorting?, query: String? = null) {
items = when (method) {
ListSorting.Query ->
if (query != null) {
items.sortedBy {
-FuzzySearch.partialRatio(
query.lowercase(), it.name.lowercase()
)
}
} else items
ListSorting.RatingHigh -> items.sortedBy { -(it.personalRating ?: 0) }
ListSorting.RatingLow -> items.sortedBy { (it.personalRating ?: 0) }
ListSorting.AlphabeticalA -> items.sortedBy { it.name }
ListSorting.AlphabeticalZ -> items.sortedBy { it.name }.reversed()
ListSorting.UpdatedNew -> items.sortedBy { it.lastUpdatedUnixTime?.times(-1) }
ListSorting.UpdatedOld -> items.sortedBy { it.lastUpdatedUnixTime }
else -> items
}
}
}
data class LibraryMetadata(
val allLibraryLists: List<LibraryList>,
val supportedListSorting: Set<ListSorting>
)
data class LibraryList(
val name: UiText,
val items: List<LibraryItem>
)
data class LibraryItem(
override val name: String,
override val url: String,
/**
* Unique unchanging string used for data storage.
* This should be the actual id when you change scores and status
* since score changes from library might get added in the future.
**/
val syncId: String,
val episodesCompleted: Int?,
val episodesTotal: Int?,
/** Out of 100 */
val personalRating: Int?,
val lastUpdatedUnixTime: Long?,
override val apiName: String,
override var type: TvType?,
override var posterUrl: String?,
override var posterHeaders: Map<String, String>?,
override var quality: SearchQuality?,
override var id: Int? = null,
) : SearchResponse
} }

View file

@ -11,26 +11,38 @@ class SyncRepo(private val repo: SyncAPI) {
val icon = repo.icon val icon = repo.icon
val mainUrl = repo.mainUrl val mainUrl = repo.mainUrl
val requiresLogin = repo.requiresLogin val requiresLogin = repo.requiresLogin
val syncIdName = repo.syncIdName
var requireLibraryRefresh: Boolean
get() = repo.requireLibraryRefresh
set(value) {
repo.requireLibraryRefresh = value
}
suspend fun score(id: String, status: SyncAPI.SyncStatus): Resource<Boolean> { suspend fun score(id: String, status: SyncAPI.SyncStatus): Resource<Boolean> {
return safeApiCall { repo.score(id, status) } return safeApiCall { repo.score(id, status) }
} }
suspend fun getStatus(id : String) : Resource<SyncAPI.SyncStatus> { suspend fun getStatus(id: String): Resource<SyncAPI.SyncStatus> {
return safeApiCall { repo.getStatus(id) ?: throw ErrorLoadingException("No data") } return safeApiCall { repo.getStatus(id) ?: throw ErrorLoadingException("No data") }
} }
suspend fun getResult(id : String) : Resource<SyncAPI.SyncResult> { suspend fun getResult(id: String): Resource<SyncAPI.SyncResult> {
return safeApiCall { repo.getResult(id) ?: throw ErrorLoadingException("No data") } return safeApiCall { repo.getResult(id) ?: throw ErrorLoadingException("No data") }
} }
suspend fun search(query : String) : Resource<List<SyncAPI.SyncSearchResult>> { suspend fun search(query: String): Resource<List<SyncAPI.SyncSearchResult>> {
return safeApiCall { repo.search(query) ?: throw ErrorLoadingException() } return safeApiCall { repo.search(query) ?: throw ErrorLoadingException() }
} }
fun hasAccount() : Boolean { suspend fun getPersonalLibrary(): Resource<SyncAPI.LibraryMetadata> {
return safeApiCall { repo.getPersonalLibrary() ?: throw ErrorLoadingException() }
}
fun hasAccount(): Boolean {
return normalSafeApiCall { repo.loginInfo() != null } ?: false return normalSafeApiCall { repo.loginInfo() != null } ?: false
} }
fun getIdFromUrl(url : String) : String = repo.getIdFromUrl(url) fun getIdFromUrl(url: String): String? = normalSafeApiCall {
repo.getIdFromUrl(url)
}
} }

View file

@ -1,10 +1,10 @@
package com.lagradost.cloudstream3.syncproviders.providers package com.lagradost.cloudstream3.syncproviders.providers
import androidx.annotation.StringRes
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
@ -12,6 +12,9 @@ import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.AuthAPI import com.lagradost.cloudstream3.syncproviders.AuthAPI
import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.ui.library.ListSorting
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.toJson
@ -27,10 +30,12 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
override val key = "6871" override val key = "6871"
override val redirectUrl = "anilistlogin" override val redirectUrl = "anilistlogin"
override val idPrefix = "anilist" override val idPrefix = "anilist"
override var requireLibraryRefresh = true
override var mainUrl = "https://anilist.co" override var mainUrl = "https://anilist.co"
override val icon = R.drawable.ic_anilist_icon override val icon = R.drawable.ic_anilist_icon
override val requiresLogin = false override val requiresLogin = false
override val createAccountUrl = "$mainUrl/signup" override val createAccountUrl = "$mainUrl/signup"
override val syncIdName = SyncIdName.Anilist
override fun loginInfo(): AuthAPI.LoginInfo? { override fun loginInfo(): AuthAPI.LoginInfo? {
// context.getUser(true)?. // context.getUser(true)?.
@ -45,6 +50,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
} }
override fun logOut() { override fun logOut() {
requireLibraryRefresh = true
removeAccountKeys() removeAccountKeys()
} }
@ -64,8 +70,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
switchToNewAccount() switchToNewAccount()
setKey(accountId, ANILIST_UNIXTIME_KEY, endTime) setKey(accountId, ANILIST_UNIXTIME_KEY, endTime)
setKey(accountId, ANILIST_TOKEN_KEY, token) setKey(accountId, ANILIST_TOKEN_KEY, token)
setKey(ANILIST_SHOULD_UPDATE_LIST, true)
val user = getUser() val user = getUser()
requireLibraryRefresh = true
return user != null return user != null
} }
@ -140,7 +146,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
this.name, this.name,
recMedia.id?.toString() ?: return@mapNotNull null, recMedia.id?.toString() ?: return@mapNotNull null,
getUrlFromId(recMedia.id), getUrlFromId(recMedia.id),
recMedia.coverImage?.large ?: recMedia.coverImage?.medium recMedia.coverImage?.extraLarge ?: recMedia.coverImage?.large
?: recMedia.coverImage?.medium
) )
}, },
trailers = when (season.trailer?.site?.lowercase()?.trim()) { trailers = when (season.trailer?.site?.lowercase()?.trim()) {
@ -170,7 +177,9 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
fromIntToAnimeStatus(status.status), fromIntToAnimeStatus(status.status),
status.score, status.score,
status.watchedEpisodes status.watchedEpisodes
) ).also {
requireLibraryRefresh = requireLibraryRefresh || it
}
} }
companion object { companion object {
@ -181,7 +190,6 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
const val ANILIST_TOKEN_KEY: String = "anilist_token" // anilist token for api const val ANILIST_TOKEN_KEY: String = "anilist_token" // anilist token for api
const val ANILIST_USER_KEY: String = "anilist_user" // user data like profile const val ANILIST_USER_KEY: String = "anilist_user" // user data like profile
const val ANILIST_CACHED_LIST: String = "anilist_cached_list" const val ANILIST_CACHED_LIST: String = "anilist_cached_list"
const val ANILIST_SHOULD_UPDATE_LIST: String = "anilist_should_update_list"
private fun fixName(name: String): String { private fun fixName(name: String): String {
return name.lowercase(Locale.ROOT).replace(" ", "") return name.lowercase(Locale.ROOT).replace(" ", "")
@ -219,7 +227,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
romaji romaji
} }
idMal idMal
coverImage { medium large } coverImage { medium large extraLarge }
averageScore averageScore
} }
} }
@ -232,7 +240,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
format format
id id
idMal idMal
coverImage { medium large } coverImage { medium large extraLarge }
averageScore averageScore
title { title {
english english
@ -292,15 +300,13 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
val shows = searchShows(name.replace(blackListRegex, "")) val shows = searchShows(name.replace(blackListRegex, ""))
shows?.data?.Page?.media?.find { shows?.data?.Page?.media?.find {
malId ?: "NONE" == it.idMal.toString() (malId ?: "NONE") == it.idMal.toString()
}?.let { return it } }?.let { return it }
val filtered = val filtered =
shows?.data?.Page?.media?.filter { shows?.data?.Page?.media?.filter {
( (((it.startDate.year ?: year.toString()) == year.toString()
it.startDate.year ?: year.toString() == year.toString() || year == null))
|| year == null
)
} }
filtered?.forEach { filtered?.forEach {
it.title.romaji?.let { romaji -> it.title.romaji?.let { romaji ->
@ -312,14 +318,14 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
} }
// Changing names of these will show up in UI // Changing names of these will show up in UI
enum class AniListStatusType(var value: Int) { enum class AniListStatusType(var value: Int, @StringRes val stringRes: Int) {
Watching(0), Watching(0, R.string.type_watching),
Completed(1), Completed(1, R.string.type_completed),
Paused(2), Paused(2, R.string.type_on_hold),
Dropped(3), Dropped(3, R.string.type_dropped),
Planning(4), Planning(4, R.string.type_plan_to_watch),
ReWatching(5), ReWatching(5, R.string.type_re_watching),
None(-1) None(-1, R.string.none)
} }
fun fromIntToAnimeStatus(inp: Int): AniListStatusType {//= AniListStatusType.values().first { it.value == inp } fun fromIntToAnimeStatus(inp: Int): AniListStatusType {//= AniListStatusType.values().first { it.value == inp }
@ -335,7 +341,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
} }
} }
fun convertAnilistStringToStatus(string: String): AniListStatusType { fun convertAniListStringToStatus(string: String): AniListStatusType {
return fromIntToAnimeStatus(aniListStatusString.indexOf(string)) return fromIntToAnimeStatus(aniListStatusString.indexOf(string))
} }
@ -526,7 +532,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
app.post( app.post(
"https://graphql.anilist.co/", "https://graphql.anilist.co/",
headers = mapOf( headers = mapOf(
"Authorization" to "Bearer " + (getAuth() ?: return@suspendSafeApiCall null), "Authorization" to "Bearer " + (getAuth()
?: return@suspendSafeApiCall null),
if (cache) "Cache-Control" to "max-stale=$maxStale" else "Cache-Control" to "no-cache" if (cache) "Cache-Control" to "max-stale=$maxStale" else "Cache-Control" to "no-cache"
), ),
cacheTime = 0, cacheTime = 0,
@ -575,7 +582,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
data class CoverImage( data class CoverImage(
@JsonProperty("medium") val medium: String?, @JsonProperty("medium") val medium: String?,
@JsonProperty("large") val large: String? @JsonProperty("large") val large: String?,
@JsonProperty("extraLarge") val extraLarge: String?
) )
data class Media( data class Media(
@ -602,7 +610,29 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
@JsonProperty("score") val score: Int, @JsonProperty("score") val score: Int,
@JsonProperty("private") val private: Boolean, @JsonProperty("private") val private: Boolean,
@JsonProperty("media") val media: Media @JsonProperty("media") val media: Media
) ) {
fun toLibraryItem(): SyncAPI.LibraryItem {
return SyncAPI.LibraryItem(
// English title first
this.media.title.english ?: this.media.title.romaji
?: this.media.synonyms.firstOrNull()
?: "",
"https://anilist.co/anime/${this.media.id}/",
this.media.id.toString(),
this.progress,
this.media.episodes,
this.score,
this.updatedAt.toLong(),
"AniList",
TvType.Anime,
this.media.coverImage.extraLarge ?: this.media.coverImage.large
?: this.media.coverImage.medium,
null,
null,
null
)
}
}
data class Lists( data class Lists(
@JsonProperty("status") val status: String?, @JsonProperty("status") val status: String?,
@ -617,40 +647,59 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
@JsonProperty("MediaListCollection") val MediaListCollection: MediaListCollection @JsonProperty("MediaListCollection") val MediaListCollection: MediaListCollection
) )
fun getAnilistListCached(): Array<Lists>? { private fun getAniListListCached(): Array<Lists>? {
return getKey(ANILIST_CACHED_LIST) as? Array<Lists> return getKey(ANILIST_CACHED_LIST) as? Array<Lists>
} }
suspend fun getAnilistAnimeListSmart(): Array<Lists>? { private suspend fun getAniListAnimeListSmart(): Array<Lists>? {
if (getAuth() == null) return null if (getAuth() == null) return null
if (checkToken()) return null if (checkToken()) return null
return if (getKey(ANILIST_SHOULD_UPDATE_LIST, true) == true) { return if (requireLibraryRefresh) {
val list = getFullAnilistList()?.data?.MediaListCollection?.lists?.toTypedArray() val list = getFullAniListList()?.data?.MediaListCollection?.lists?.toTypedArray()
if (list != null) { if (list != null) {
setKey(ANILIST_CACHED_LIST, list) setKey(ANILIST_CACHED_LIST, list)
setKey(ANILIST_SHOULD_UPDATE_LIST, false)
} }
list list
} else { } else {
getAnilistListCached() getAniListListCached()
} }
} }
private suspend fun getFullAnilistList(): FullAnilistList? { override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata {
var userID: Int? = null val list = getAniListAnimeListSmart()?.groupBy {
/** WARNING ASSUMES ONE USER! **/ convertAniListStringToStatus(it.status ?: "").stringRes
getKeys(ANILIST_USER_KEY)?.forEach { key -> }?.mapValues { group ->
getKey<AniListUser>(key, null)?.let { group.value.map { it.entries.map { entry -> entry.toLibraryItem() } }.flatten()
userID = it.id } ?: emptyMap()
}
}
val fixedUserID = userID ?: return null // To fill empty lists when AniList does not return them
val baseMap =
AniListStatusType.values().filter { it.value >= 0 }.associate {
it.stringRes to emptyList<SyncAPI.LibraryItem>()
}
return SyncAPI.LibraryMetadata(
(baseMap + list).map { SyncAPI.LibraryList(txt(it.key), it.value) },
setOf(
ListSorting.AlphabeticalA,
ListSorting.AlphabeticalZ,
ListSorting.UpdatedNew,
ListSorting.UpdatedOld,
ListSorting.RatingHigh,
ListSorting.RatingLow,
)
)
}
private suspend fun getFullAniListList(): FullAnilistList? {
/** WARNING ASSUMES ONE USER! **/
val userID = getKey<AniListUser>(accountId, ANILIST_USER_KEY)?.id ?: return null
val mediaType = "ANIME" val mediaType = "ANIME"
val query = """ val query = """
query (${'$'}userID: Int = $fixedUserID, ${'$'}MEDIA: MediaType = $mediaType) { query (${'$'}userID: Int = $userID, ${'$'}MEDIA: MediaType = $mediaType) {
MediaListCollection (userId: ${'$'}userID, type: ${'$'}MEDIA) { MediaListCollection (userId: ${'$'}userID, type: ${'$'}MEDIA) {
lists { lists {
status status
@ -661,7 +710,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
startedAt { year month day } startedAt { year month day }
updatedAt updatedAt
progress progress
score score (format: POINT_100)
private private
media media
{ {
@ -677,7 +726,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
english english
romaji romaji
} }
coverImage { medium } coverImage { extraLarge large medium }
synonyms synonyms
nextAiringEpisode { nextAiringEpisode {
timeUntilAiring timeUntilAiring

View file

@ -0,0 +1,100 @@
package com.lagradost.cloudstream3.syncproviders.providers
import androidx.fragment.app.FragmentActivity
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.syncproviders.AuthAPI
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.library.ListSorting
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.Coroutines.ioWork
import com.lagradost.cloudstream3.utils.DataStoreHelper.getAllWatchStateIds
import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
class LocalList : SyncAPI {
override val name = "Local"
override val icon: Int = R.drawable.ic_baseline_storage_24
override val requiresLogin = false
override val createAccountUrl: Nothing? = null
override val idPrefix = "local"
override var requireLibraryRefresh = true
override fun loginInfo(): AuthAPI.LoginInfo {
return AuthAPI.LoginInfo(
null,
null,
0
)
}
override fun logOut() {
}
override val key: String = ""
override val redirectUrl = ""
override suspend fun handleRedirect(url: String): Boolean {
return true
}
override fun authenticate(activity: FragmentActivity?) {
}
override val mainUrl = ""
override val syncIdName = SyncIdName.LocalList
override suspend fun score(id: String, status: SyncAPI.SyncStatus): Boolean {
return true
}
override suspend fun getStatus(id: String): SyncAPI.SyncStatus? {
return null
}
override suspend fun getResult(id: String): SyncAPI.SyncResult? {
return null
}
override suspend fun search(name: String): List<SyncAPI.SyncSearchResult>? {
return null
}
override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata? {
val watchStatusIds = ioWork {
getAllWatchStateIds()?.map { id ->
Pair(id, getResultWatchState(id))
}
}?.distinctBy { it.first } ?: return null
val list = ioWork {
watchStatusIds.groupBy {
it.second.stringRes
}.mapValues { group ->
group.value.mapNotNull {
getBookmarkedData(it.first)?.toLibraryItem(it.first.toString())
}
}
}
val baseMap = WatchType.values().filter { it != WatchType.NONE }.associate {
// None is not something to display
it.stringRes to emptyList<SyncAPI.LibraryItem>()
}
return SyncAPI.LibraryMetadata(
(baseMap + list).map { SyncAPI.LibraryList(txt(it.key), it.value) },
setOf(
ListSorting.AlphabeticalA,
ListSorting.AlphabeticalZ,
// ListSorting.UpdatedNew,
// ListSorting.UpdatedOld,
// ListSorting.RatingHigh,
// ListSorting.RatingLow,
)
)
}
override fun getIdFromUrl(url: String): String {
return url
}
}

View file

@ -1,6 +1,7 @@
package com.lagradost.cloudstream3.syncproviders.providers package com.lagradost.cloudstream3.syncproviders.providers
import android.util.Base64 import android.util.Base64
import androidx.annotation.StringRes
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
@ -8,11 +9,15 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ShowStatus import com.lagradost.cloudstream3.ShowStatus
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.AuthAPI import com.lagradost.cloudstream3.syncproviders.AuthAPI
import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.ui.library.ListSorting
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
@ -31,13 +36,15 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
override val redirectUrl = "mallogin" override val redirectUrl = "mallogin"
override val idPrefix = "mal" override val idPrefix = "mal"
override var mainUrl = "https://myanimelist.net" override var mainUrl = "https://myanimelist.net"
val apiUrl = "https://api.myanimelist.net" private val apiUrl = "https://api.myanimelist.net"
override val icon = R.drawable.mal_logo override val icon = R.drawable.mal_logo
override val requiresLogin = false override val requiresLogin = false
override val syncIdName = SyncIdName.MyAnimeList
override var requireLibraryRefresh = true
override val createAccountUrl = "$mainUrl/register.php" override val createAccountUrl = "$mainUrl/register.php"
override fun logOut() { override fun logOut() {
requireLibraryRefresh = true
removeAccountKeys() removeAccountKeys()
} }
@ -90,7 +97,9 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
fromIntToAnimeStatus(status.status), fromIntToAnimeStatus(status.status),
status.score, status.score,
status.watchedEpisodes status.watchedEpisodes
) ).also {
requireLibraryRefresh = requireLibraryRefresh || it
}
} }
data class MalAnime( data class MalAnime(
@ -248,10 +257,45 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
const val MAL_USER_KEY: String = "mal_user" // user data like profile const val MAL_USER_KEY: String = "mal_user" // user data like profile
const val MAL_CACHED_LIST: String = "mal_cached_list" const val MAL_CACHED_LIST: String = "mal_cached_list"
const val MAL_SHOULD_UPDATE_LIST: String = "mal_should_update_list"
const val MAL_UNIXTIME_KEY: String = "mal_unixtime" // When token expires const val MAL_UNIXTIME_KEY: String = "mal_unixtime" // When token expires
const val MAL_REFRESH_TOKEN_KEY: String = "mal_refresh_token" // refresh token const val MAL_REFRESH_TOKEN_KEY: String = "mal_refresh_token" // refresh token
const val MAL_TOKEN_KEY: String = "mal_token" // anilist token for api const val MAL_TOKEN_KEY: String = "mal_token" // anilist token for api
fun convertToStatus(string: String): MalStatusType {
return fromIntToAnimeStatus(malStatusAsString.indexOf(string))
}
enum class MalStatusType(var value: Int, @StringRes val stringRes: Int) {
Watching(0, R.string.type_watching),
Completed(1, R.string.type_completed),
OnHold(2, R.string.type_on_hold),
Dropped(3, R.string.type_dropped),
PlanToWatch(4, R.string.type_plan_to_watch),
None(-1, R.string.type_none)
}
private fun fromIntToAnimeStatus(inp: Int): MalStatusType {//= AniListStatusType.values().first { it.value == inp }
return when (inp) {
-1 -> MalStatusType.None
0 -> MalStatusType.Watching
1 -> MalStatusType.Completed
2 -> MalStatusType.OnHold
3 -> MalStatusType.Dropped
4 -> MalStatusType.PlanToWatch
5 -> MalStatusType.Watching
else -> MalStatusType.None
}
}
private fun parseDateLong(string: String?): Long? {
return try {
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(
string ?: return null
)?.time?.div(1000)
} catch (e: Exception) {
null
}
}
} }
override suspend fun handleRedirect(url: String): Boolean { override suspend fun handleRedirect(url: String): Boolean {
@ -275,7 +319,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
switchToNewAccount() switchToNewAccount()
storeToken(res) storeToken(res)
val user = getMalUser() val user = getMalUser()
setKey(MAL_SHOULD_UPDATE_LIST, true) requireLibraryRefresh = true
return user != null return user != null
} }
} }
@ -308,9 +352,10 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
setKey(accountId, MAL_UNIXTIME_KEY, (token.expires_in + unixTime)) setKey(accountId, MAL_UNIXTIME_KEY, (token.expires_in + unixTime))
setKey(accountId, MAL_REFRESH_TOKEN_KEY, token.refresh_token) setKey(accountId, MAL_REFRESH_TOKEN_KEY, token.refresh_token)
setKey(accountId, MAL_TOKEN_KEY, token.access_token) setKey(accountId, MAL_TOKEN_KEY, token.access_token)
requireLibraryRefresh = true
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() logError(e)
} }
} }
@ -329,7 +374,7 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
).text ).text
storeToken(res) storeToken(res)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() logError(e)
} }
} }
@ -382,7 +427,24 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
data class Data( data class Data(
@JsonProperty("node") val node: Node, @JsonProperty("node") val node: Node,
@JsonProperty("list_status") val list_status: ListStatus?, @JsonProperty("list_status") val list_status: ListStatus?,
) ) {
fun toLibraryItem(): SyncAPI.LibraryItem {
return SyncAPI.LibraryItem(
this.node.title,
"https://myanimelist.net/anime/${this.node.id}/",
this.node.id.toString(),
this.list_status?.num_episodes_watched,
this.node.num_episodes,
this.list_status?.score?.times(10),
parseDateLong(this.list_status?.updated_at),
"MAL",
TvType.Anime,
this.node.main_picture?.large ?: this.node.main_picture?.medium,
null,
null,
)
}
}
data class Paging( data class Paging(
@JsonProperty("next") val next: String? @JsonProperty("next") val next: String?
@ -413,18 +475,43 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
return getKey(MAL_CACHED_LIST) as? Array<Data> return getKey(MAL_CACHED_LIST) as? Array<Data>
} }
suspend fun getMalAnimeListSmart(): Array<Data>? { private suspend fun getMalAnimeListSmart(): Array<Data>? {
if (getAuth() == null) return null if (getAuth() == null) return null
return if (getKey(MAL_SHOULD_UPDATE_LIST, true) == true) { return if (requireLibraryRefresh) {
val list = getMalAnimeList() val list = getMalAnimeList()
setKey(MAL_CACHED_LIST, list) setKey(MAL_CACHED_LIST, list)
setKey(MAL_SHOULD_UPDATE_LIST, false)
list list
} else { } else {
getMalAnimeListCached() getMalAnimeListCached()
} }
} }
override suspend fun getPersonalLibrary(): SyncAPI.LibraryMetadata {
val list = getMalAnimeListSmart()?.groupBy {
convertToStatus(it.list_status?.status ?: "").stringRes
}?.mapValues { group ->
group.value.map { it.toLibraryItem() }
} ?: emptyMap()
// To fill empty lists when MAL does not return them
val baseMap =
MalStatusType.values().filter { it.value >= 0 }.associate {
it.stringRes to emptyList<SyncAPI.LibraryItem>()
}
return SyncAPI.LibraryMetadata(
(baseMap + list).map { SyncAPI.LibraryList(txt(it.key), it.value) },
setOf(
ListSorting.AlphabeticalA,
ListSorting.AlphabeticalZ,
ListSorting.UpdatedNew,
ListSorting.UpdatedOld,
ListSorting.RatingHigh,
ListSorting.RatingLow,
)
)
}
private suspend fun getMalAnimeList(): Array<Data> { private suspend fun getMalAnimeList(): Array<Data> {
checkMalToken() checkMalToken()
var offset = 0 var offset = 0
@ -440,10 +527,6 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
return fullList.toTypedArray() return fullList.toTypedArray()
} }
fun convertToStatus(string: String): MalStatusType {
return fromIntToAnimeStatus(malStatusAsString.indexOf(string))
}
private suspend fun getMalAnimeListSlice(offset: Int = 0): MalList? { private suspend fun getMalAnimeListSlice(offset: Int = 0): MalList? {
val user = "@me" val user = "@me"
val auth = getAuth() ?: return null val auth = getAuth() ?: return null
@ -557,28 +640,6 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
return user return user
} }
enum class MalStatusType(var value: Int) {
Watching(0),
Completed(1),
OnHold(2),
Dropped(3),
PlanToWatch(4),
None(-1)
}
private fun fromIntToAnimeStatus(inp: Int): MalStatusType {//= AniListStatusType.values().first { it.value == inp }
return when (inp) {
-1 -> MalStatusType.None
0 -> MalStatusType.Watching
1 -> MalStatusType.Completed
2 -> MalStatusType.OnHold
3 -> MalStatusType.Dropped
4 -> MalStatusType.PlanToWatch
5 -> MalStatusType.Watching
else -> MalStatusType.None
}
}
private suspend fun setScoreRequest( private suspend fun setScoreRequest(
id: Int, id: Int,
status: MalStatusType? = null, status: MalStatusType? = null,

View file

@ -166,7 +166,7 @@ class OpenSubtitlesApi(index: Int) : InAppAuthAPIManager(index), AbstractSubApi
val fixedLang = fixLanguage(query.lang) val fixedLang = fixLanguage(query.lang)
val imdbId = query.imdb ?: 0 val imdbId = query.imdb ?: 0
val queryText = query.query.replace(" ", "+") val queryText = query.query
val epNum = query.epNumber ?: 0 val epNum = query.epNumber ?: 0
val seasonNum = query.seasonNumber ?: 0 val seasonNum = query.seasonNumber ?: 0
val yearNum = query.year ?: 0 val yearNum = query.year ?: 0
@ -177,7 +177,7 @@ class OpenSubtitlesApi(index: Int) : InAppAuthAPIManager(index), AbstractSubApi
val searchQueryUrl = when (imdbId > 0) { val searchQueryUrl = when (imdbId > 0) {
//Use imdb_id to search if its valid //Use imdb_id to search if its valid
true -> "$host/subtitles?imdb_id=$imdbId&languages=${fixedLang}$yearQuery$epQuery$seasonQuery" true -> "$host/subtitles?imdb_id=$imdbId&languages=${fixedLang}$yearQuery$epQuery$seasonQuery"
false -> "$host/subtitles?query=${URLEncoder.encode(queryText.lowercase(), StandardCharsets.UTF_8.toString())}&languages=${fixedLang}$yearQuery$epQuery$seasonQuery" false -> "$host/subtitles?query=${queryText}&languages=${fixedLang}$yearQuery$epQuery$seasonQuery"
} }
val req = app.get( val req = app.get(

View file

@ -7,7 +7,8 @@ import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs import kotlin.math.abs
class GrdLayoutManager(val context: Context, _spanCount: Int) : GridLayoutManager(context, _spanCount) { class GrdLayoutManager(val context: Context, _spanCount: Int) :
GridLayoutManager(context, _spanCount) {
override fun onFocusSearchFailed( override fun onFocusSearchFailed(
focused: View, focused: View,
focusDirection: Int, focusDirection: Int,
@ -34,7 +35,7 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) : GridLayoutManage
val pos = maxOf(0, getPosition(focused!!) - 2) val pos = maxOf(0, getPosition(focused!!) - 2)
parent.scrollToPosition(pos) parent.scrollToPosition(pos)
super.onRequestChildFocus(parent, state, child, focused) super.onRequestChildFocus(parent, state, child, focused)
} catch (e: Exception){ } catch (e: Exception) {
false false
} }
} }

View file

@ -32,6 +32,7 @@ import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia
import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
import com.lagradost.cloudstream3.MainActivity.Companion.bookmarksUpdatedEvent
import com.lagradost.cloudstream3.MainActivity.Companion.mainPluginsLoadedEvent import com.lagradost.cloudstream3.MainActivity.Companion.mainPluginsLoadedEvent
import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
@ -435,6 +436,11 @@ class HomeFragment : Fragment() {
return inflater.inflate(layout, container, false) return inflater.inflate(layout, container, false)
} }
override fun onDestroyView() {
bottomSheetDialog?.ownHide()
super.onDestroyView()
}
private fun fixGrid() { private fun fixGrid() {
activity?.getSpanCount()?.let { activity?.getSpanCount()?.let {
currentSpan = it currentSpan = it
@ -461,14 +467,20 @@ class HomeFragment : Fragment() {
fixGrid() fixGrid()
} }
fun bookmarksUpdated(_data : Boolean) {
reloadStored()
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
reloadStored() reloadStored()
bookmarksUpdatedEvent += ::bookmarksUpdated
afterPluginsLoadedEvent += ::afterPluginsLoaded afterPluginsLoadedEvent += ::afterPluginsLoaded
mainPluginsLoadedEvent += ::afterMainPluginsLoaded mainPluginsLoadedEvent += ::afterMainPluginsLoaded
} }
override fun onStop() { override fun onStop() {
bookmarksUpdatedEvent -= ::bookmarksUpdated
afterPluginsLoadedEvent -= ::afterPluginsLoaded afterPluginsLoadedEvent -= ::afterPluginsLoaded
mainPluginsLoadedEvent -= ::afterMainPluginsLoaded mainPluginsLoadedEvent -= ::afterMainPluginsLoaded
super.onStop() super.onStop()
@ -557,7 +569,7 @@ class HomeFragment : Fragment() {
val mutableListOfResponse = mutableListOf<SearchResponse>() val mutableListOfResponse = mutableListOf<SearchResponse>()
listHomepageItems.clear() listHomepageItems.clear()
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList( (home_master_recycler?.adapter as? ParentItemAdapter)?.updateList(
d.values.toMutableList(), d.values.toMutableList(),
home_master_recycler home_master_recycler
) )
@ -609,7 +621,7 @@ class HomeFragment : Fragment() {
//home_loaded?.isVisible = false //home_loaded?.isVisible = false
} }
is Resource.Loading -> { is Resource.Loading -> {
(home_master_recycler?.adapter as? ParentItemAdapter?)?.updateList(listOf()) (home_master_recycler?.adapter as? ParentItemAdapter)?.updateList(listOf())
home_loading_shimmer?.startShimmer() home_loading_shimmer?.startShimmer()
home_loading?.isVisible = true home_loading?.isVisible = true
home_loading_error?.isVisible = false home_loading_error?.isVisible = false

View file

@ -184,9 +184,8 @@ open class ParentItemAdapter(
private val expandCallback: ((String) -> Unit)? = null, private val expandCallback: ((String) -> Unit)? = null,
) : ) :
RecyclerView.ViewHolder(itemView) { RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.home_parent_item_title val title: TextView = itemView.home_child_more_info
val recyclerView: RecyclerView = itemView.home_child_recyclerview val recyclerView: RecyclerView = itemView.home_child_recyclerview
private val moreInfo: FrameLayout? = itemView.home_child_more_info
fun update(expand: HomeViewModel.ExpandableHomepageList) { fun update(expand: HomeViewModel.ExpandableHomepageList) {
val info = expand.list val info = expand.list
@ -248,9 +247,10 @@ open class ParentItemAdapter(
}) })
//(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged() //(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
if (!isTvSettings()) {
moreInfo?.setOnClickListener { title.setOnClickListener {
moreInfoClickCallback.invoke(expand) moreInfoClickCallback.invoke(expand)
}
} }
} }
} }

View file

@ -14,6 +14,7 @@ import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipDrawable import com.google.android.material.chip.ChipDrawable
import com.lagradost.cloudstream3.APIHolder.getId import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity import com.lagradost.cloudstream3.AcraApplication.Companion.getActivity
import com.lagradost.cloudstream3.HomePageList
import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
@ -31,9 +32,10 @@ import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showOptionSelectSt
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbarView
import com.lagradost.cloudstream3.utils.UIHelper.setImage import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.android.synthetic.main.activity_main_tv.view.* import kotlinx.android.synthetic.main.activity_main.view.*
import kotlinx.android.synthetic.main.fragment_home_head.view.* import kotlinx.android.synthetic.main.fragment_home_head.view.*
import kotlinx.android.synthetic.main.fragment_home_head.view.home_bookmarked_child_recyclerview import kotlinx.android.synthetic.main.fragment_home_head.view.home_bookmarked_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home_head.view.home_watch_parent_item_title
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.* import kotlinx.android.synthetic.main.fragment_home_head_tv.view.*
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_bookmarked_holder import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_bookmarked_holder
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_none_padding import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_none_padding
@ -46,11 +48,12 @@ import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_on_ho
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_watching_btt import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_type_watching_btt
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_child_recyclerview import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_child_recyclerview
import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_holder import kotlinx.android.synthetic.main.fragment_home_head_tv.view.home_watch_holder
import kotlinx.android.synthetic.main.toast.view.*
class HomeParentItemAdapterPreview( class HomeParentItemAdapterPreview(
items: MutableList<HomeViewModel.ExpandableHomepageList>, items: MutableList<HomeViewModel.ExpandableHomepageList>,
val clickCallback: (SearchClickCallback) -> Unit, val clickCallback: (SearchClickCallback) -> Unit,
moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit, private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit,
expandCallback: ((String) -> Unit)? = null, expandCallback: ((String) -> Unit)? = null,
private val loadCallback: (LoadClickCallback) -> Unit, private val loadCallback: (LoadClickCallback) -> Unit,
private val loadMoreCallback: (() -> Unit), private val loadMoreCallback: (() -> Unit),
@ -136,7 +139,8 @@ class HomeParentItemAdapterPreview(
clickCallback, clickCallback,
reloadStored, reloadStored,
loadStoredData, loadStoredData,
searchQueryCallback searchQueryCallback,
moreInfoClickCallback
).also { ).also {
this.holder = it this.holder = it
} }
@ -182,7 +186,8 @@ class HomeParentItemAdapterPreview(
private val searchClickCallback: (SearchClickCallback) -> Unit, private val searchClickCallback: (SearchClickCallback) -> Unit,
private val reloadStored: () -> Unit, private val reloadStored: () -> Unit,
private val loadStoredData: ((Set<WatchType>) -> Unit), private val loadStoredData: ((Set<WatchType>) -> Unit),
private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit) private val searchQueryCallback: ((Pair<Boolean, String>) -> Unit),
private val moreInfoClickCallback: (HomeViewModel.ExpandableHomepageList) -> Unit
) : RecyclerView.ViewHolder(itemView) { ) : RecyclerView.ViewHolder(itemView) {
private var previewAdapter: HomeScrollAdapter? = null private var previewAdapter: HomeScrollAdapter? = null
private val previewViewpager: ViewPager2? = itemView.home_preview_viewpager private val previewViewpager: ViewPager2? = itemView.home_preview_viewpager
@ -602,11 +607,43 @@ class HomeParentItemAdapterPreview(
fun updateResume(resumeWatching: List<SearchResponse>) { fun updateResume(resumeWatching: List<SearchResponse>) {
resumeHolder?.isVisible = resumeWatching.isNotEmpty() resumeHolder?.isVisible = resumeWatching.isNotEmpty()
resumeAdapter?.updateList(resumeWatching) resumeAdapter?.updateList(resumeWatching)
if (!isTvSettings()) {
itemView.home_watch_parent_item_title?.setOnClickListener {
moreInfoClickCallback.invoke(
HomeViewModel.ExpandableHomepageList(
HomePageList(
itemView.home_watch_parent_item_title?.text.toString(),
resumeWatching,
false
), 1, false
)
)
}
}
} }
fun updateBookmarks(data: Pair<Boolean, List<SearchResponse>>) { fun updateBookmarks(data: Pair<Boolean, List<SearchResponse>>) {
bookmarkHolder?.isVisible = data.first bookmarkHolder?.isVisible = data.first
bookmarkAdapter?.updateList(data.second) bookmarkAdapter?.updateList(data.second)
if (!isTvSettings()) {
itemView.home_bookmark_parent_item_title?.setOnClickListener {
val items = toggleList.mapNotNull { it.first }.filter { it.isChecked }
if (items.isEmpty()) return@setOnClickListener // we don't want to show an empty dialog
val textSum = items
.mapNotNull { it.text }.joinToString()
moreInfoClickCallback.invoke(
HomeViewModel.ExpandableHomepageList(
HomePageList(
textSum,
data.second,
false
), 1, false
)
)
}
}
} }
fun setAvailableWatchStatusTypes(availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>>) { fun setAvailableWatchStatusTypes(availableWatchStatusTypes: Pair<Set<WatchType>, Set<WatchType>>) {

View file

@ -0,0 +1,395 @@
package com.lagradost.cloudstream3.ui.library
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import androidx.annotation.StringRes
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import com.google.android.material.tabs.TabLayoutMediator
import com.lagradost.cloudstream3.APIHolder
import com.lagradost.cloudstream3.APIHolder.allProviders
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.debugAssert
import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.SyncIdName
import com.lagradost.cloudstream3.ui.quicksearch.QuickSearchFragment
import com.lagradost.cloudstream3.ui.result.txt
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.AppUtils.reduceDragSensitivity
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import kotlinx.android.synthetic.main.fragment_library.*
import kotlin.math.abs
const val LIBRARY_FOLDER = "library_folder"
enum class LibraryOpenerType(@StringRes val stringRes: Int) {
Default(R.string.default_subtitles), // TODO FIX AFTER MERGE
Provider(R.string.none),
Browser(R.string.browser),
Search(R.string.search),
None(R.string.none),
}
/** Used to store how the user wants to open said poster */
data class LibraryOpener(
val openType: LibraryOpenerType,
val providerData: ProviderLibraryData?,
)
data class ProviderLibraryData(
val apiName: String
)
class LibraryFragment : Fragment() {
companion object {
fun newInstance() = LibraryFragment()
/**
* Store which page was last seen when exiting the fragment and returning
**/
const val VIEWPAGER_ITEM_KEY = "viewpager_item"
}
private val libraryViewModel: LibraryViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_library, container, false)
}
override fun onSaveInstanceState(outState: Bundle) {
viewpager?.currentItem?.let { currentItem ->
outState.putInt(VIEWPAGER_ITEM_KEY, currentItem)
}
super.onSaveInstanceState(outState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
context?.fixPaddingStatusbar(search_status_bar_padding)
sort_fab?.setOnClickListener {
val methods = libraryViewModel.sortingMethods.map {
txt(it.stringRes).asString(view.context)
}
activity?.showBottomDialog(methods,
libraryViewModel.sortingMethods.indexOf(libraryViewModel.currentSortingMethod),
txt(R.string.sort_by).asString(view.context),
false,
{},
{
val method = libraryViewModel.sortingMethods[it]
libraryViewModel.sort(method)
})
}
main_search?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
libraryViewModel.sort(ListSorting.Query, query)
return true
}
// This is required to prevent the first text change
// When this is attached it'll immediately send a onQueryTextChange("")
// Which we do not want
var hasInitialized = false
override fun onQueryTextChange(newText: String?): Boolean {
if (!hasInitialized) {
hasInitialized = true
return true
}
libraryViewModel.sort(ListSorting.Query, newText)
return true
}
})
libraryViewModel.reloadPages(false)
list_selector?.setOnClickListener {
val items = libraryViewModel.availableApiNames
val currentItem = libraryViewModel.currentApiName.value
activity?.showBottomDialog(items,
items.indexOf(currentItem),
txt(R.string.select_library).asString(it.context),
false,
{}) { index ->
val selectedItem = items.getOrNull(index) ?: return@showBottomDialog
libraryViewModel.switchList(selectedItem)
}
}
/**
* Shows a plugin selection dialogue and saves the response
**/
fun Activity.showPluginSelectionDialog(
key: String,
syncId: SyncIdName,
apiName: String? = null,
) {
val availableProviders = allProviders.filter {
it.supportedSyncNames.contains(syncId)
}.map { it.name } +
// Add the api if it exists
(APIHolder.getApiFromNameNull(apiName)?.let { listOf(it.name) } ?: emptyList())
val baseOptions = listOf(
LibraryOpenerType.Default,
LibraryOpenerType.None,
LibraryOpenerType.Browser,
LibraryOpenerType.Search
)
val items = baseOptions.map { txt(it.stringRes).asString(this) } + availableProviders
val savedSelection = getKey<LibraryOpener>(LIBRARY_FOLDER, key)
val selectedIndex =
when {
savedSelection == null -> 0
// If provider
savedSelection.openType == LibraryOpenerType.Provider
&& savedSelection.providerData?.apiName != null -> {
availableProviders.indexOf(savedSelection.providerData.apiName)
.takeIf { it != -1 }
?.plus(baseOptions.size) ?: 0
}
// Else base option
else -> baseOptions.indexOf(savedSelection.openType)
}
this.showBottomDialog(
items,
selectedIndex,
txt(R.string.open_with).asString(this),
false,
{},
) {
val savedData = if (it < baseOptions.size) {
LibraryOpener(
baseOptions[it],
null
)
} else {
LibraryOpener(
LibraryOpenerType.Provider,
ProviderLibraryData(items[it])
)
}
setKey(
LIBRARY_FOLDER,
key,
savedData,
)
}
}
provider_selector?.setOnClickListener {
val syncName = libraryViewModel.currentSyncApi?.syncIdName ?: return@setOnClickListener
activity?.showPluginSelectionDialog(syncName.name, syncName)
}
viewpager?.setPageTransformer(LibraryScrollTransformer())
viewpager?.adapter =
viewpager.adapter ?: ViewpagerAdapter(mutableListOf(), { isScrollingDown: Boolean ->
if (isScrollingDown) {
sort_fab?.shrink()
} else {
sort_fab?.extend()
}
}) callback@{ searchClickCallback ->
// To prevent future accidents
debugAssert({
searchClickCallback.card !is SyncAPI.LibraryItem
}, {
"searchClickCallback ${searchClickCallback.card} is not a LibraryItem"
})
val syncId = (searchClickCallback.card as SyncAPI.LibraryItem).syncId
val syncName =
libraryViewModel.currentSyncApi?.syncIdName ?: return@callback
when (searchClickCallback.action) {
SEARCH_ACTION_SHOW_METADATA -> {
activity?.showPluginSelectionDialog(
syncId,
syncName,
searchClickCallback.card.apiName
)
}
SEARCH_ACTION_LOAD -> {
// This basically first selects the individual opener and if that is default then
// selects the whole list opener
val savedListSelection =
getKey<LibraryOpener>(LIBRARY_FOLDER, syncName.name)
val savedSelection = getKey<LibraryOpener>(LIBRARY_FOLDER, syncId).takeIf {
it?.openType != LibraryOpenerType.Default
} ?: savedListSelection
when (savedSelection?.openType) {
null, LibraryOpenerType.Default -> {
// Prevents opening MAL/AniList as a provider
if (APIHolder.getApiFromNameNull(searchClickCallback.card.apiName) != null) {
activity?.loadSearchResult(
searchClickCallback.card
)
} else {
// Search when no provider can open
QuickSearchFragment.pushSearch(
activity,
searchClickCallback.card.name
)
}
}
LibraryOpenerType.None -> {}
LibraryOpenerType.Provider ->
savedSelection.providerData?.apiName?.let { apiName ->
activity?.loadResult(
searchClickCallback.card.url,
apiName,
)
}
LibraryOpenerType.Browser ->
openBrowser(searchClickCallback.card.url)
LibraryOpenerType.Search -> {
QuickSearchFragment.pushSearch(
activity,
searchClickCallback.card.name
)
}
}
}
}
}
viewpager?.offscreenPageLimit = 2
viewpager?.reduceDragSensitivity()
val startLoading = Runnable {
gridview?.numColumns = context?.getSpanCount() ?: 3
gridview?.adapter =
context?.let { LoadingPosterAdapter(it, 6 * 3) }
library_loading_overlay?.isVisible = true
library_loading_shimmer?.startShimmer()
empty_list_textview?.isVisible = false
}
val stopLoading = Runnable {
gridview?.adapter = null
library_loading_overlay?.isVisible = false
library_loading_shimmer?.stopShimmer()
}
val handler = Handler(Looper.getMainLooper())
observe(libraryViewModel.pages) { resource ->
when (resource) {
is Resource.Success -> {
handler.removeCallbacks(startLoading)
val pages = resource.value
val showNotice = pages.all { it.items.isEmpty() }
empty_list_textview?.isVisible = showNotice
if (showNotice) {
if (libraryViewModel.availableApiNames.size > 1) {
empty_list_textview?.setText(R.string.empty_library_logged_in_message)
} else {
empty_list_textview?.setText(R.string.empty_library_no_accounts_message)
}
}
(viewpager.adapter as? ViewpagerAdapter)?.pages = pages
// Using notifyItemRangeChanged keeps the animations when sorting
viewpager.adapter?.notifyItemRangeChanged(0, viewpager.adapter?.itemCount ?: 0)
// Only stop loading after 300ms to hide the fade effect the viewpager produces when updating
// Without this there would be a flashing effect:
// loading -> show old viewpager -> black screen -> show new viewpager
handler.postDelayed(stopLoading, 300)
savedInstanceState?.getInt(VIEWPAGER_ITEM_KEY)?.let { currentPos ->
if (currentPos < 0) return@let
viewpager?.setCurrentItem(currentPos, false)
// Using remove() sets the key to 0 instead of removing it
savedInstanceState.putInt(VIEWPAGER_ITEM_KEY, -1)
}
// Since the animation to scroll multiple items is so much its better to just hide
// the viewpager a bit while the fastest animation is running
fun hideViewpager(distance: Int) {
if (distance < 3) return
val hideAnimation = AlphaAnimation(1f, 0f).apply {
duration = distance * 50L
fillAfter = true
}
val showAnimation = AlphaAnimation(0f, 1f).apply {
duration = distance * 50L
startOffset = distance * 100L
fillAfter = true
}
viewpager?.startAnimation(hideAnimation)
viewpager?.startAnimation(showAnimation)
}
TabLayoutMediator(
library_tab_layout,
viewpager,
) { tab, position ->
tab.text = pages.getOrNull(position)?.title?.asStringNull(context)
tab.view.setOnClickListener {
val currentItem = viewpager?.currentItem ?: return@setOnClickListener
val distance = abs(position - currentItem)
hideViewpager(distance)
}
}.attach()
}
is Resource.Loading -> {
// Only start loading after 200ms to prevent loading cached lists
handler.postDelayed(startLoading, 200)
}
is Resource.Failure -> {
stopLoading.run()
// No user indication it failed :(
// TODO
}
}
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
(viewpager.adapter as? ViewpagerAdapter)?.rebind()
super.onConfigurationChanged(newConfig)
}
}
class MenuSearchView(context: Context) : SearchView(context) {
override fun onActionViewCollapsed() {
super.onActionViewCollapsed()
}
}

View file

@ -0,0 +1,17 @@
package com.lagradost.cloudstream3.ui.library
import android.view.View
import androidx.viewpager2.widget.ViewPager2
import kotlinx.android.synthetic.main.library_viewpager_page.view.*
import kotlin.math.roundToInt
class LibraryScrollTransformer : ViewPager2.PageTransformer {
override fun transformPage(page: View, position: Float) {
val padding = (-position * page.width).roundToInt()
page.page_recyclerview.setPadding(
padding, 0,
-padding, 0
)
}
}

View file

@ -0,0 +1,104 @@
package com.lagradost.cloudstream3.ui.library
import androidx.annotation.StringRes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.SyncApis
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import kotlinx.coroutines.delay
enum class ListSorting(@StringRes val stringRes: Int) {
Query(R.string.none),
RatingHigh(R.string.sort_rating_desc),
RatingLow(R.string.sort_rating_asc),
UpdatedNew(R.string.sort_updated_new),
UpdatedOld(R.string.sort_updated_old),
AlphabeticalA(R.string.sort_alphabetical_a),
AlphabeticalZ(R.string.sort_alphabetical_z),
}
const val LAST_SYNC_API_KEY = "last_sync_api"
class LibraryViewModel : ViewModel() {
private val _pages: MutableLiveData<Resource<List<SyncAPI.Page>>> = MutableLiveData(null)
val pages: LiveData<Resource<List<SyncAPI.Page>>> = _pages
private val _currentApiName: MutableLiveData<String> = MutableLiveData("")
val currentApiName: LiveData<String> = _currentApiName
private val availableSyncApis
get() = SyncApis.filter { it.hasAccount() }
var currentSyncApi = availableSyncApis.let { allApis ->
val lastSelection = getKey<String>(LAST_SYNC_API_KEY)
availableSyncApis.firstOrNull { it.name == lastSelection } ?: allApis.firstOrNull()
}
private set(value) {
field = value
setKey(LAST_SYNC_API_KEY, field?.name)
}
val availableApiNames: List<String>
get() = availableSyncApis.map { it.name }
var sortingMethods = emptyList<ListSorting>()
private set
var currentSortingMethod: ListSorting? = sortingMethods.firstOrNull()
private set
fun switchList(name: String) {
currentSyncApi = availableSyncApis[availableApiNames.indexOf(name)]
_currentApiName.postValue(currentSyncApi?.name)
reloadPages(true)
}
fun sort(method: ListSorting, query: String? = null) {
val currentList = pages.value ?: return
currentSortingMethod = method
(currentList as? Resource.Success)?.value?.forEachIndexed { _, page ->
page.sort(method, query)
}
_pages.postValue(currentList)
}
fun reloadPages(forceReload: Boolean) {
// Only skip loading if its not forced and pages is not empty
if (!forceReload && (pages.value as? Resource.Success)?.value?.isNotEmpty() == true &&
currentSyncApi?.requireLibraryRefresh != true
) return
ioSafe {
currentSyncApi?.let { repo ->
_currentApiName.postValue(repo.name)
_pages.postValue(Resource.Loading())
val libraryResource = repo.getPersonalLibrary()
if (libraryResource is Resource.Failure) {
_pages.postValue(libraryResource)
return@let
}
val library = (libraryResource as? Resource.Success)?.value ?: return@let
sortingMethods = library.supportedListSorting.toList()
currentSortingMethod = null
repo.requireLibraryRefresh = false
val pages = library.allLibraryLists.map {
SyncAPI.Page(
it.name,
it.items
)
}
_pages.postValue(Resource.Success(pages))
}
}
}
}

View file

@ -0,0 +1,37 @@
package com.lagradost.cloudstream3.ui.library
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.ListPopupWindow.MATCH_PARENT
import android.widget.RelativeLayout
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.android.synthetic.main.loading_poster_dynamic.view.*
import kotlin.math.roundToInt
import kotlin.math.sqrt
class LoadingPosterAdapter(context: Context, private val itemCount: Int) :
BaseAdapter() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
override fun getCount(): Int {
return itemCount
}
override fun getItem(position: Int): Any? {
return null
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
return convertView ?: inflater.inflate(R.layout.loading_poster_dynamic, parent, false)
}
}

View file

@ -0,0 +1,130 @@
package com.lagradost.cloudstream3.ui.library
import android.content.res.ColorStateList
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.android.synthetic.main.search_result_grid_expanded.view.*
import kotlin.math.roundToInt
class PageAdapter(
override val items: MutableList<SyncAPI.LibraryItem>,
private val resView: AutofitRecyclerView,
val clickCallback: (SearchClickCallback) -> Unit
) :
AppUtils.DiffAdapter<SyncAPI.LibraryItem>(items) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return LibraryItemViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.search_result_grid_expanded, parent, false)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is LibraryItemViewHolder -> {
holder.bind(items[position], position)
}
}
}
private fun isDark(color: Int): Boolean {
return ColorUtils.calculateLuminance(color) < 0.5
}
fun getDifferentColor(color: Int, ratio: Float = 0.7f): Int {
return if (isDark(color)) {
ColorUtils.blendARGB(color, Color.WHITE, ratio)
} else {
ColorUtils.blendARGB(color, Color.BLACK, ratio)
}
}
inner class LibraryItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardView: ImageView = itemView.imageView
private val compactView = false//itemView.context.getGridIsCompact()
private val coverHeight: Int =
if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(item: SyncAPI.LibraryItem, position: Int) {
/** https://stackoverflow.com/questions/8817522/how-to-get-color-code-of-image-view */
SearchResultBuilder.bind(
this@PageAdapter.clickCallback,
item,
position,
itemView,
colorCallback = { palette ->
AcraApplication.context?.let { ctx ->
val defColor = ContextCompat.getColor(ctx, R.color.ratingColorBg)
var bg = palette.getDarkVibrantColor(defColor)
if (bg == defColor) {
bg = palette.getDarkMutedColor(defColor)
}
if (bg == defColor) {
bg = palette.getVibrantColor(defColor)
}
val fg =
getDifferentColor(bg)//palette.getVibrantColor(ContextCompat.getColor(ctx,R.color.ratingColor))
itemView.text_rating.apply {
setTextColor(ColorStateList.valueOf(fg))
}
itemView.text_rating_holder?.backgroundTintList = ColorStateList.valueOf(bg)
itemView.watchProgress?.apply {
progressTintList = ColorStateList.valueOf(fg)
progressBackgroundTintList = ColorStateList.valueOf(bg)
}
}
}
)
// See searchAdaptor for this, it basically fixes the height
if (!compactView) {
cardView.apply {
layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
coverHeight
)
}
}
val showProgress = item.episodesCompleted != null && item.episodesTotal != null
itemView.watchProgress.isVisible = showProgress
if (showProgress) {
itemView.watchProgress.max = item.episodesTotal!!
itemView.watchProgress.progress = item.episodesCompleted!!
}
itemView.imageText.text = item.name
val showRating = (item.personalRating ?: 0) != 0
itemView.text_rating_holder.isVisible = showRating
if (showRating) {
// We want to show 8.5 but not 8.0 hence the replace
val rating = ((item.personalRating ?: 0).toDouble() / 10).toString()
.replace(".0", "")
itemView.text_rating.text = "$rating"
}
}
}
}

View file

@ -0,0 +1,90 @@
package com.lagradost.cloudstream3.ui.library
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.doOnAttach
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnFlingListener
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.utils.UIHelper.getSpanCount
import kotlinx.android.synthetic.main.library_viewpager_page.view.*
class ViewpagerAdapter(
var pages: List<SyncAPI.Page>,
val scrollCallback: (isScrollingDown: Boolean) -> Unit,
val clickCallback: (SearchClickCallback) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return PageViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.library_viewpager_page, parent, false)
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is PageViewHolder -> {
holder.bind(pages[position], unbound.remove(position))
}
}
}
private val unbound = mutableSetOf<Int>()
/**
* Used to mark all pages for re-binding and forces all items to be refreshed
* Without this the pages will still use the same adapters
**/
fun rebind() {
unbound.addAll(0..pages.size)
this.notifyItemRangeChanged(0, pages.size)
}
inner class PageViewHolder(private val itemViewTest: View) :
RecyclerView.ViewHolder(itemViewTest) {
fun bind(page: SyncAPI.Page, rebind: Boolean) {
itemView.page_recyclerview?.spanCount =
this@PageViewHolder.itemView.context.getSpanCount() ?: 3
if (itemViewTest.page_recyclerview?.adapter == null || rebind) {
// Only add the items after it has been attached since the items rely on ItemWidth
// Which is only determined after the recyclerview is attached.
// If this fails then item height becomes 0 when there is only one item
itemViewTest.page_recyclerview?.doOnAttach {
itemViewTest.page_recyclerview?.adapter = PageAdapter(
page.items.toMutableList(),
itemViewTest.page_recyclerview,
clickCallback
)
}
} else {
(itemViewTest.page_recyclerview?.adapter as? PageAdapter)?.updateList(page.items)
itemViewTest.page_recyclerview?.scrollToPosition(0)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
itemViewTest.page_recyclerview.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
val diff = scrollY - oldScrollY
if (diff == 0) return@setOnScrollChangeListener
scrollCallback.invoke(diff > 0)
}
} else {
itemViewTest.page_recyclerview.onFlingListener = object : OnFlingListener() {
override fun onFling(velocityX: Int, velocityY: Int): Boolean {
scrollCallback.invoke(velocityY > 0)
return false
}
}
}
}
}
override fun getItemCount(): Int {
return pages.size
}
}

View file

@ -109,6 +109,8 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
protected var currentPrefQuality = protected var currentPrefQuality =
Qualities.P2160.value // preferred maximum quality, used for ppl w bad internet or on cell Qualities.P2160.value // preferred maximum quality, used for ppl w bad internet or on cell
protected var fastForwardTime = 10000L protected var fastForwardTime = 10000L
protected var androidTVInterfaceOffSeekTime = 10000L;
protected var androidTVInterfaceOnSeekTime = 30000L;
protected var swipeHorizontalEnabled = false protected var swipeHorizontalEnabled = false
protected var swipeVerticalEnabled = false protected var swipeVerticalEnabled = false
protected var playBackSpeedEnabled = false protected var playBackSpeedEnabled = false
@ -605,7 +607,7 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
player_top_holder?.isGone = isGone player_top_holder?.isGone = isGone
//player_episodes_button?.isVisible = !isGone && hasEpisodes //player_episodes_button?.isVisible = !isGone && hasEpisodes
player_video_title?.isGone = togglePlayerTitleGone player_video_title?.isGone = togglePlayerTitleGone
player_video_title_rez?.isGone = isGone // player_video_title_rez?.isGone = isGone
player_episode_filler?.isGone = isGone player_episode_filler?.isGone = isGone
player_center_menu?.isGone = isGone player_center_menu?.isGone = isGone
player_lock?.isGone = !isShowing player_lock?.isGone = !isShowing
@ -1051,19 +1053,19 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
} }
KeyEvent.KEYCODE_DPAD_LEFT -> { KeyEvent.KEYCODE_DPAD_LEFT -> {
if (!isShowing && !isLocked) { if (!isShowing && !isLocked) {
player.seekTime(-10000L) player.seekTime(-androidTVInterfaceOffSeekTime)
return true return true
} else if (player_pause_play?.isFocused == true) { } else if (player_pause_play?.isFocused == true) {
player.seekTime(-30000L) player.seekTime(-androidTVInterfaceOnSeekTime)
return true return true
} }
} }
KeyEvent.KEYCODE_DPAD_RIGHT -> { KeyEvent.KEYCODE_DPAD_RIGHT -> {
if (!isShowing && !isLocked) { if (!isShowing && !isLocked) {
player.seekTime(10000L) player.seekTime(androidTVInterfaceOffSeekTime)
return true return true
} else if (player_pause_play?.isFocused == true) { } else if (player_pause_play?.isFocused == true) {
player.seekTime(30000L) player.seekTime(androidTVInterfaceOnSeekTime)
return true return true
} }
} }
@ -1207,6 +1209,13 @@ open class FullScreenPlayer : AbstractPlayerFragment() {
settingsManager.getInt(ctx.getString(R.string.double_tap_seek_time_key), 10) settingsManager.getInt(ctx.getString(R.string.double_tap_seek_time_key), 10)
.toLong() * 1000L .toLong() * 1000L
androidTVInterfaceOffSeekTime =
settingsManager.getInt(ctx.getString(R.string.android_tv_interface_off_seek_key), 10)
.toLong() * 1000L
androidTVInterfaceOnSeekTime =
settingsManager.getInt(ctx.getString(R.string.android_tv_interface_on_seek_key), 10)
.toLong() * 1000L
navigationBarHeight = ctx.getNavigationBarHeight() navigationBarHeight = ctx.getNavigationBarHeight()
statusBarHeight = ctx.getStatusBarHeight() statusBarHeight = ctx.getStatusBarHeight()

View file

@ -11,9 +11,7 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.* import android.widget.*
import android.widget.TextView.OnEditorActionListener
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.animation.addListener import androidx.core.animation.addListener
@ -528,7 +526,7 @@ class GeneratorPlayer : FullScreenPlayer() {
} }
} }
var selectSourceDialog: AlertDialog? = null var selectSourceDialog: Dialog? = null
// var selectTracksDialog: AlertDialog? = null // var selectTracksDialog: AlertDialog? = null
override fun showMirrorsDialogue() { override fun showMirrorsDialogue() {
@ -540,10 +538,8 @@ class GeneratorPlayer : FullScreenPlayer() {
player.handleEvent(CSPlayerEvent.Pause) player.handleEvent(CSPlayerEvent.Pause)
val currentSubtitles = sortSubs(currentSubs) val currentSubtitles = sortSubs(currentSubs)
val sourceBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack) val sourceDialog = Dialog(ctx, R.style.AlertDialogCustomBlack)
.setView(R.layout.player_select_source_and_subs) sourceDialog.setContentView(R.layout.player_select_source_and_subs)
val sourceDialog = sourceBuilder.create()
selectSourceDialog = sourceDialog selectSourceDialog = sourceDialog
@ -1149,13 +1145,15 @@ class GeneratorPlayer : FullScreenPlayer() {
val source = currentSelectedLink?.first?.name ?: currentSelectedLink?.second?.name ?: "NULL" val source = currentSelectedLink?.first?.name ?: currentSelectedLink?.second?.name ?: "NULL"
player_video_title_rez?.text = when (titleRez) { val title = when (titleRez) {
0 -> "" 0 -> ""
1 -> extra 1 -> extra
2 -> source 2 -> source
3 -> "$source - $extra" 3 -> "$source - $extra"
else -> "" else -> ""
} }
player_video_title_rez?.text = title
player_video_title_rez?.isVisible = title.isNotBlank()
} }
override fun playerDimensionsLoaded(widthHeight: Pair<Int, Int>) { override fun playerDimensionsLoaded(widthHeight: Pair<Int, Int>) {

View file

@ -220,7 +220,7 @@ class QuickSearchFragment : Fragment() {
when (it) { when (it) {
is Resource.Success -> { is Resource.Success -> {
it.value.let { data -> it.value.let { data ->
(quick_search_autofit_results?.adapter as? SearchAdapter?)?.updateList( (quick_search_autofit_results?.adapter as? SearchAdapter)?.updateList(
context?.filterSearchResultByFilmQuality(data) ?: data context?.filterSearchResultByFilmQuality(data) ?: data
) )
} }

View file

@ -277,7 +277,7 @@ open class ResultFragment : ResultTrailerPlayer() {
private var downloadButton: EasyDownloadButton? = null private var downloadButton: EasyDownloadButton? = null
override fun onDestroyView() { override fun onDestroyView() {
updateUIListener = null updateUIListener = null
(result_episodes?.adapter as EpisodeAdapter?)?.killAdapter() (result_episodes?.adapter as? EpisodeAdapter)?.killAdapter()
downloadButton?.dispose() downloadButton?.dispose()
super.onDestroyView() super.onDestroyView()
@ -458,7 +458,7 @@ open class ResultFragment : ResultTrailerPlayer() {
temporary_no_focus?.requestFocus() temporary_no_focus?.requestFocus()
} }
(result_episodes?.adapter as? EpisodeAdapter?)?.updateList(episodes.value) (result_episodes?.adapter as? EpisodeAdapter)?.updateList(episodes.value)
if (isTv && hasEpisodes) main { if (isTv && hasEpisodes) main {
delay(500) delay(500)
@ -687,7 +687,7 @@ open class ResultFragment : ResultTrailerPlayer() {
val newList = list.filter { it.isSynced && it.hasAccount } val newList = list.filter { it.isSynced && it.hasAccount }
result_mini_sync?.isVisible = newList.isNotEmpty() result_mini_sync?.isVisible = newList.isNotEmpty()
(result_mini_sync?.adapter as? ImageAdapter?)?.updateList(newList.mapNotNull { it.icon }) (result_mini_sync?.adapter as? ImageAdapter)?.updateList(newList.mapNotNull { it.icon })
} }
var currentSyncProgress = 0 var currentSyncProgress = 0
@ -850,6 +850,7 @@ open class ResultFragment : ResultTrailerPlayer() {
} }
observe(viewModel.page) { data -> observe(viewModel.page) { data ->
if(data == null) return@observe
when (data) { when (data) {
is Resource.Success -> { is Resource.Success -> {
val d = data.value val d = data.value
@ -899,7 +900,7 @@ open class ResultFragment : ResultTrailerPlayer() {
result_cast_items?.isVisible = d.actors != null result_cast_items?.isVisible = d.actors != null
(result_cast_items?.adapter as ActorAdaptor?)?.apply { (result_cast_items?.adapter as? ActorAdaptor)?.apply {
updateList(d.actors ?: emptyList()) updateList(d.actors ?: emptyList())
} }
@ -973,6 +974,7 @@ open class ResultFragment : ResultTrailerPlayer() {
chip.isCheckable = false chip.isCheckable = false
chip.isFocusable = false chip.isFocusable = false
chip.isClickable = false chip.isClickable = false
chip.setTextColor(context.colorFromAttribute(R.attr.textColor))
addView(chip) addView(chip)
} }
} }

View file

@ -485,7 +485,7 @@ class ResultFragmentPhone : ResultFragment() {
result_recommendations?.post { result_recommendations?.post {
rec?.let { list -> rec?.let { list ->
(result_recommendations?.adapter as SearchAdapter?)?.updateList(list.filter { it.apiName == matchAgainst }) (result_recommendations?.adapter as? SearchAdapter)?.updateList(list.filter { it.apiName == matchAgainst })
} }
} }
} }

View file

@ -107,7 +107,7 @@ class ResultFragmentTv : ResultFragment() {
result_recommendations?.isGone = isInvalid result_recommendations?.isGone = isInvalid
result_recommendations_holder?.isGone = isInvalid result_recommendations_holder?.isGone = isInvalid
val matchAgainst = validApiName ?: rec?.firstOrNull()?.apiName val matchAgainst = validApiName ?: rec?.firstOrNull()?.apiName
(result_recommendations?.adapter as SearchAdapter?)?.updateList(rec?.filter { it.apiName == matchAgainst } (result_recommendations?.adapter as? SearchAdapter)?.updateList(rec?.filter { it.apiName == matchAgainst }
?: emptyList()) ?: emptyList())
rec?.map { it.apiName }?.distinct()?.let { apiNames -> rec?.map { it.apiName }?.distinct()?.let { apiNames ->

View file

@ -13,6 +13,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.getId import com.lagradost.cloudstream3.APIHolder.getId
import com.lagradost.cloudstream3.APIHolder.unixTime import com.lagradost.cloudstream3.APIHolder.unixTime
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
@ -24,6 +25,7 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.getMalId
import com.lagradost.cloudstream3.LoadResponse.Companion.isMovie import com.lagradost.cloudstream3.LoadResponse.Companion.isMovie
import com.lagradost.cloudstream3.metaproviders.SyncRedirector import com.lagradost.cloudstream3.metaproviders.SyncRedirector
import com.lagradost.cloudstream3.mvvm.* import com.lagradost.cloudstream3.mvvm.*
import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.syncproviders.providers.Kitsu import com.lagradost.cloudstream3.syncproviders.providers.Kitsu
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
@ -55,7 +57,6 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultSeason
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.File import java.io.File
import java.lang.Math.abs
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -314,6 +315,11 @@ data class ExtractedTrailerData(
class ResultViewModel2 : ViewModel() { class ResultViewModel2 : ViewModel() {
private var currentResponse: LoadResponse? = null private var currentResponse: LoadResponse? = null
fun clear() {
currentResponse = null
_page.postValue(null)
}
data class EpisodeIndexer( data class EpisodeIndexer(
val dubStatus: DubStatus, val dubStatus: DubStatus,
val season: Int, val season: Int,
@ -340,9 +346,9 @@ class ResultViewModel2 : ViewModel() {
//private val currentHeaderName get() = currentResponse?.name //private val currentHeaderName get() = currentResponse?.name
private val _page: MutableLiveData<Resource<ResultData>> = private val _page: MutableLiveData<Resource<ResultData>?> =
MutableLiveData(Resource.Loading()) MutableLiveData(null)
val page: LiveData<Resource<ResultData>> = _page val page: LiveData<Resource<ResultData>?> = _page
private val _episodes: MutableLiveData<ResourceSome<List<ResultEpisode>>> = private val _episodes: MutableLiveData<ResourceSome<List<ResultEpisode>>> =
MutableLiveData(ResourceSome.Loading()) MutableLiveData(ResourceSome.Loading())
@ -398,7 +404,6 @@ class ResultViewModel2 : ViewModel() {
private val _selectedDubStatusIndex: MutableLiveData<Int> = MutableLiveData(-1) private val _selectedDubStatusIndex: MutableLiveData<Int> = MutableLiveData(-1)
val selectedDubStatusIndex: LiveData<Int> = _selectedDubStatusIndex val selectedDubStatusIndex: LiveData<Int> = _selectedDubStatusIndex
private val _loadedLinks: MutableLiveData<Some<LinkProgress>> = MutableLiveData(Some.None) private val _loadedLinks: MutableLiveData<Some<LinkProgress>> = MutableLiveData(Some.None)
val loadedLinks: LiveData<Some<LinkProgress>> = _loadedLinks val loadedLinks: LiveData<Some<LinkProgress>> = _loadedLinks
@ -421,7 +426,6 @@ class ResultViewModel2 : ViewModel() {
fun updateWatchStatus(currentResponse: LoadResponse, status: WatchType) { fun updateWatchStatus(currentResponse: LoadResponse, status: WatchType) {
val currentId = currentResponse.getId() val currentId = currentResponse.getId()
val resultPage = currentResponse
DataStoreHelper.setResultWatchState(currentId, status.internalId) DataStoreHelper.setResultWatchState(currentId, status.internalId)
val current = DataStoreHelper.getBookmarkedData(currentId) val current = DataStoreHelper.getBookmarkedData(currentId)
@ -432,12 +436,12 @@ class ResultViewModel2 : ViewModel() {
currentId, currentId,
current?.bookmarkedTime ?: currentTime, current?.bookmarkedTime ?: currentTime,
currentTime, currentTime,
resultPage.name, currentResponse.name,
resultPage.url, currentResponse.url,
resultPage.apiName, currentResponse.apiName,
resultPage.type, currentResponse.type,
resultPage.posterUrl, currentResponse.posterUrl,
resultPage.year currentResponse.year
) )
) )
} }
@ -1419,79 +1423,127 @@ class ResultViewModel2 : ViewModel() {
meta: SyncAPI.SyncResult?, meta: SyncAPI.SyncResult?,
syncs: Map<String, String>? = null syncs: Map<String, String>? = null
): Pair<LoadResponse, Boolean> { ): Pair<LoadResponse, Boolean> {
if (meta == null) return resp to false //if (meta == null) return resp to false
var updateEpisodes = false var updateEpisodes = false
val out = resp.apply { val out = resp.apply {
Log.i(TAG, "applyMeta") Log.i(TAG, "applyMeta")
duration = duration ?: meta.duration if (meta != null) {
rating = rating ?: meta.publicScore duration = duration ?: meta.duration
tags = tags ?: meta.genres rating = rating ?: meta.publicScore
plot = if (plot.isNullOrBlank()) meta.synopsis else plot tags = tags ?: meta.genres
posterUrl = posterUrl ?: meta.posterUrl ?: meta.backgroundPosterUrl plot = if (plot.isNullOrBlank()) meta.synopsis else plot
actors = actors ?: meta.actors posterUrl = posterUrl ?: meta.posterUrl ?: meta.backgroundPosterUrl
actors = actors ?: meta.actors
if (this is EpisodeResponse) { if (this is EpisodeResponse) {
nextAiring = nextAiring ?: meta.nextAiring nextAiring = nextAiring ?: meta.nextAiring
}
val realRecommendations = ArrayList<SearchResponse>()
val apiNames = apis.filter {
it.name.contains("gogoanime", true) ||
it.name.contains("9anime", true)
}.map {
it.name
}
meta.recommendations?.forEach { rec ->
apiNames.forEach { name ->
realRecommendations.add(rec.copy(apiName = name))
}
}
recommendations = recommendations?.union(realRecommendations)?.toList()
?: realRecommendations
} }
for ((k, v) in syncs ?: emptyMap()) { for ((k, v) in syncs ?: emptyMap()) {
syncData[k] = v syncData[k] = v
} }
val realRecommendations = ArrayList<SearchResponse>() argamap(
// TODO: fix {
//val apiNames = listOf(GogoanimeProvider().name, NineAnimeProvider().name) if (this !is AnimeLoadResponse) return@argamap
// meta.recommendations?.forEach { rec -> // already exist, no need to run getTracker
// apiNames.forEach { name -> if (this.getAniListId() != null && this.getMalId() != null) return@argamap
// realRecommendations.add(rec.copy(apiName = name))
// }
// }
recommendations = recommendations?.union(realRecommendations)?.toList() val res = APIHolder.getTracker(
?: realRecommendations listOfNotNull(
this.engName,
argamap({ this.name,
addTrailer(meta.trailers) this.japName
}, { ).filter { it.length > 2 }.distinct(), // the reason why we filter is due to not wanting smth like " " or "?"
if (this !is AnimeLoadResponse) return@argamap TrackerType.getTypes(this.type),
val map = this.year
Kitsu.getEpisodesDetails(
getMalId(),
getAniListId(),
isResponseRequired = false
) )
if (map.isNullOrEmpty()) return@argamap
updateEpisodes = DubStatus.values().map { dubStatus -> val ids = arrayOf(
val current = AccountManager.malApi.idPrefix to res?.malId?.toString(),
this.episodes[dubStatus]?.mapIndexed { index, episode -> AccountManager.aniListApi.idPrefix to res?.aniId
episode.apply { )
this.episode = this.episode ?: (index + 1)
} if (ids.any { (id, new) ->
}?.sortedBy { it.episode ?: 0 }?.toMutableList() val current = syncData[id]
if (current.isNullOrEmpty()) return@map false new != null && current != null && current != new
val episodeNumbers = current.map { ep -> ep.episode!! } }
var updateCount = 0 ) {
map.forEach { (episode, node) -> // getTracker fucked up as it conflicts with current implementation
episodeNumbers.binarySearch(episode).let { index -> return@argamap
current.getOrNull(index)?.let { currentEp -> }
current[index] = currentEp.apply {
updateCount++ // set all the new data, prioritise old correct data
val currentBack = this ids.forEach { (id, new) ->
this.description = this.description ?: node.description?.en new?.let {
this.name = this.name ?: node.titles?.canonical syncData[id] = syncData[id] ?: it
this.episode = }
this.episode ?: node.num ?: episodeNumbers[index] }
this.posterUrl =
this.posterUrl ?: node.thumbnail?.original?.url // set posters, might fuck up due to headers idk
posterUrl = posterUrl ?: res?.image
backgroundPosterUrl = backgroundPosterUrl ?: res?.cover
},
{
if (meta == null) return@argamap
addTrailer(meta.trailers)
}, {
if (this !is AnimeLoadResponse) return@argamap
val map =
Kitsu.getEpisodesDetails(
getMalId(),
getAniListId(),
isResponseRequired = false
)
if (map.isNullOrEmpty()) return@argamap
updateEpisodes = DubStatus.values().map { dubStatus ->
val current =
this.episodes[dubStatus]?.mapIndexed { index, episode ->
episode.apply {
this.episode = this.episode ?: (index + 1)
}
}?.sortedBy { it.episode ?: 0 }?.toMutableList()
if (current.isNullOrEmpty()) return@map false
val episodeNumbers = current.map { ep -> ep.episode!! }
var updateCount = 0
map.forEach { (episode, node) ->
episodeNumbers.binarySearch(episode).let { index ->
current.getOrNull(index)?.let { currentEp ->
current[index] = currentEp.apply {
updateCount++
this.description = this.description ?: node.description?.en
this.name = this.name ?: node.titles?.canonical
this.episode =
this.episode ?: node.num ?: episodeNumbers[index]
this.posterUrl =
this.posterUrl ?: node.thumbnail?.original?.url
}
} }
} }
} }
} this.episodes[dubStatus] = current
this.episodes[dubStatus] = current updateCount > 0
updateCount > 0 }.any { it }
}.any { it } })
})
} }
return out to updateEpisodes return out to updateEpisodes
} }
@ -1628,10 +1680,11 @@ class ResultViewModel2 : ViewModel() {
if (ranges?.contains(range) != true) { if (ranges?.contains(range) != true) {
// if the current ranges does not include the range then select the range with the closest matching start episode // if the current ranges does not include the range then select the range with the closest matching start episode
// this usually happends when dub has less episodes then sub -> the range does not exist // this usually happends when dub has less episodes then sub -> the range does not exist
ranges?.minByOrNull { abs(it.startEpisode - range.startEpisode) }?.let { r -> ranges?.minByOrNull { kotlin.math.abs(it.startEpisode - range.startEpisode) }
postEpisodeRange(indexer, r) ?.let { r ->
return postEpisodeRange(indexer, r)
} return
}
} }
val isMovie = currentResponse?.isMovie() == true val isMovie = currentResponse?.isMovie() == true
@ -2112,8 +2165,9 @@ class ResultViewModel2 : ViewModel() {
showFillers: Boolean, showFillers: Boolean,
dubStatus: DubStatus, dubStatus: DubStatus,
autostart: AutoResume?, autostart: AutoResume?,
loadTrailers: Boolean = true,
) = ) =
viewModelScope.launchSafe { ioSafe {
_page.postValue(Resource.Loading(url)) _page.postValue(Resource.Loading(url))
_episodes.postValue(ResourceSome.Loading()) _episodes.postValue(ResourceSome.Loading())
@ -2131,7 +2185,7 @@ class ResultViewModel2 : ViewModel() {
"This provider does not exist" "This provider does not exist"
) )
) )
return@launchSafe return@ioSafe
} }
@ -2139,24 +2193,18 @@ class ResultViewModel2 : ViewModel() {
val validUrlResource = safeApiCall { val validUrlResource = safeApiCall {
SyncRedirector.redirect( SyncRedirector.redirect(
url, url,
api.mainUrl api
) )
} }
// TODO: fix
// val validUrlResource = safeApiCall {
// SyncRedirector.redirect(
// url,
// api.mainUrl.replace(NineAnimeProvider().mainUrl, "9anime")
// .replace(GogoanimeProvider().mainUrl, "gogoanime")
// )
// }
if (validUrlResource !is Resource.Success) { if (validUrlResource !is Resource.Success) {
if (validUrlResource is Resource.Failure) { if (validUrlResource is Resource.Failure) {
_page.postValue(validUrlResource) _page.postValue(validUrlResource)
} }
return@launchSafe return@ioSafe
} }
val validUrl = validUrlResource.value val validUrl = validUrlResource.value
val repo = APIRepository(api) val repo = APIRepository(api)
currentRepo = repo currentRepo = repo
@ -2166,11 +2214,11 @@ class ResultViewModel2 : ViewModel() {
_page.postValue(data) _page.postValue(data)
} }
is Resource.Success -> { is Resource.Success -> {
if (!isActive) return@launchSafe if (!isActive) return@ioSafe
val loadResponse = ioWork { val loadResponse = ioWork {
applyMeta(data.value, currentMeta, currentSync).first applyMeta(data.value, currentMeta, currentSync).first
} }
if (!isActive) return@launchSafe if (!isActive) return@ioSafe
val mainId = loadResponse.getId() val mainId = loadResponse.getId()
preferDubStatus = getDub(mainId) ?: preferDubStatus preferDubStatus = getDub(mainId) ?: preferDubStatus
@ -2190,15 +2238,15 @@ class ResultViewModel2 : ViewModel() {
System.currentTimeMillis(), System.currentTimeMillis(),
) )
) )
if (loadTrailers)
loadTrailers(data.value) loadTrailers(data.value)
postSuccessful( postSuccessful(
data.value, data.value,
updateEpisodes = true, updateEpisodes = true,
updateFillers = showFillers, updateFillers = showFillers,
apiRepository = repo apiRepository = repo
) )
if (!isActive) return@launchSafe if (!isActive) return@ioSafe
handleAutoStart(activity, autostart) handleAutoStart(activity, autostart)
} }
is Resource.Loading -> { is Resource.Loading -> {

View file

@ -10,12 +10,16 @@ import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.ui.AutofitRecyclerView import com.lagradost.cloudstream3.ui.AutofitRecyclerView
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.UIHelper.IsBottomLayout import com.lagradost.cloudstream3.utils.UIHelper.IsBottomLayout
import com.lagradost.cloudstream3.utils.UIHelper.toPx import com.lagradost.cloudstream3.utils.UIHelper.toPx
import kotlinx.android.synthetic.main.search_result_compact.view.* import kotlinx.android.synthetic.main.search_result_compact.view.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** Click */
const val SEARCH_ACTION_LOAD = 0 const val SEARCH_ACTION_LOAD = 0
/** Long press */
const val SEARCH_ACTION_SHOW_METADATA = 1 const val SEARCH_ACTION_SHOW_METADATA = 1
const val SEARCH_ACTION_PLAY_FILE = 2 const val SEARCH_ACTION_PLAY_FILE = 2
const val SEARCH_ACTION_FOCUSED = 4 const val SEARCH_ACTION_FOCUSED = 4

View file

@ -45,6 +45,7 @@ import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.updateChips
import com.lagradost.cloudstream3.ui.home.ParentItemAdapter import com.lagradost.cloudstream3.ui.home.ParentItemAdapter
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings 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.utils.AppUtils.ownHide
import com.lagradost.cloudstream3.utils.AppUtils.ownShow import com.lagradost.cloudstream3.utils.AppUtils.ownShow
import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.Coroutines.main
@ -121,6 +122,7 @@ class SearchFragment : Fragment() {
override fun onDestroyView() { override fun onDestroyView() {
hideKeyboard() hideKeyboard()
bottomSheetDialog?.ownHide()
super.onDestroyView() super.onDestroyView()
} }
@ -418,7 +420,7 @@ class SearchFragment : Fragment() {
is Resource.Success -> { is Resource.Success -> {
it.value.let { data -> it.value.let { data ->
if (data.isNotEmpty()) { if (data.isNotEmpty()) {
(search_autofit_results?.adapter as SearchAdapter?)?.updateList(data) (search_autofit_results?.adapter as? SearchAdapter)?.updateList(data)
} }
} }
searchExitIcon.alpha = 1f searchExitIcon.alpha = 1f

View file

@ -3,11 +3,13 @@ package com.lagradost.cloudstream3.ui.search
import android.app.Activity import android.app.Activity
import android.widget.Toast import android.widget.Toast
import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.MainActivity
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_PLAY_FILE import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_PLAY_FILE
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup.handleDownloadClick
import com.lagradost.cloudstream3.ui.download.DownloadClickEvent import com.lagradost.cloudstream3.ui.download.DownloadClickEvent
import com.lagradost.cloudstream3.ui.result.START_ACTION_LOAD_EP import com.lagradost.cloudstream3.ui.result.START_ACTION_LOAD_EP
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.DataStoreHelper import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.VideoDownloadHelper import com.lagradost.cloudstream3.utils.VideoDownloadHelper
@ -54,7 +56,15 @@ object SearchHelper {
} }
} }
SEARCH_ACTION_SHOW_METADATA -> { SEARCH_ACTION_SHOW_METADATA -> {
showToast(activity, callback.card.name, Toast.LENGTH_SHORT) if(!isTvSettings()) { // we only want this on phone as UI is not done yet on tv
(activity as? MainActivity?)?.apply {
loadPopup(callback.card)
} ?: kotlin.run {
showToast(activity, callback.card.name, Toast.LENGTH_SHORT)
}
} else {
showToast(activity, callback.card.name, Toast.LENGTH_SHORT)
}
} }
} }
} }

View file

@ -1,12 +1,14 @@
package com.lagradost.cloudstream3.ui.search package com.lagradost.cloudstream3.ui.search
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.palette.graphics.Palette
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
@ -41,6 +43,7 @@ object SearchResultBuilder {
nextFocusBehavior: Boolean? = null, nextFocusBehavior: Boolean? = null,
nextFocusUp: Int? = null, nextFocusUp: Int? = null,
nextFocusDown: Int? = null, nextFocusDown: Int? = null,
colorCallback : ((Palette) -> Unit)? = null
) { ) {
val cardView: ImageView = itemView.imageView val cardView: ImageView = itemView.imageView
val cardText: TextView? = itemView.imageText val cardText: TextView? = itemView.imageText
@ -100,7 +103,7 @@ object SearchResultBuilder {
cardText?.isVisible = showTitle cardText?.isVisible = showTitle
cardView.isVisible = true cardView.isVisible = true
if (!cardView.setImage(card.posterUrl, card.posterHeaders)) { if (!cardView.setImage(card.posterUrl, card.posterHeaders, colorCallback = colorCallback)) {
cardView.setImageResource(R.drawable.default_cover) cardView.setImageResource(R.drawable.default_cover)
} }

View file

@ -56,46 +56,48 @@ fun getCurrentLocale(context: Context): String {
// https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes leave blank for auto // https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes leave blank for auto
val appLanguages = arrayListOf( val appLanguages = arrayListOf(
/* begin language list */ /* begin language list */
Triple("", "Arabic", "ar"), Triple("", "العربية", "ar"),
Triple("", "Bulgarian", "bg"), Triple("", "български", "bg"),
Triple("", "Bengali", "bn"), Triple("", "বাংলা", "bn"),
Triple("\uD83C\uDDE7\uD83C\uDDF7", "Brazilian Portuguese", "bp"), Triple("\uD83C\uDDE7\uD83C\uDDF7", "português brasileiro", "bp"),
Triple("", "Czech", "cs"), Triple("", "čeština", "cs"),
Triple("", "German", "de"), Triple("", "Deutsch", "de"),
Triple("", "Greek", "el"), Triple("", "Ελληνικά", "el"),
Triple("", "English", "en"), Triple("", "English", "en"),
Triple("", "Esperanto", "eo"), Triple("", "Esperanto", "eo"),
Triple("", "Spanish", "es"), Triple("", "español", "es"),
Triple("", "Farsi", "fa"), Triple("", "فارسی", "fa"),
Triple("", "French", "fr"), Triple("", "français", "fr"),
Triple("", "Hindi", "hi"), Triple("\uD83C\uDDEE\uD83C\uDDF1", "עברית", "iw"),
Triple("", "Croatian", "hr"), Triple("", "हिन्दी", "hi"),
Triple("", "Hungarian", "hu"), Triple("", "hrvatski", "hr"),
Triple("\uD83C\uDDEE\uD83C\uDDE9", "Indonesian", "in"), Triple("", "magyar", "hu"),
Triple("", "Italian", "it"), Triple("\uD83C\uDDEE\uD83C\uDDE9", "Bahasa Indonesia", "in"),
Triple("\uD83C\uDDEE\uD83C\uDDF1", "Hebrew", "iw"), Triple("", "italiano", "it"),
Triple("", "Kannada", "kn"), Triple("", "ಕನ್ನಡ", "kn"),
Triple("", "Macedonian", "mk"), Triple("", "македонски", "mk"),
Triple("", "Malayalam", "ml"), Triple("", "മലയാളം", "ml"),
Triple("", "Moldavian", "mo"), Triple("", "Nederlands", "nl"),
Triple("", "Dutch", "nl"), Triple("", "norsk nynorsk", "nn"),
Triple("", "Norwegian Nynorsk", "nn"), Triple("", "norsk bokmål", "no"),
Triple("", "Norwegian", "no"), Triple("", "polski", "pl"),
Triple("", "Polish", "pl"), Triple("\uD83C\uDDF5\uD83C\uDDF9", "português", "pt"),
Triple("\uD83C\uDDF5\uD83C\uDDF9", "Portuguese", "pt"), Triple("🦍", "mmmm... monke", "qt"),
Triple("", "Romanian", "ro"), Triple("", "română", "ro"),
Triple("", "Russian", "ru"), Triple("", "русский", "ru"),
Triple("", "Swedish", "sv"), Triple("", "slovenčina", "sk"),
Triple("", "Tamil", "ta"), Triple("", "Soomaaliga", "so"),
Triple("", "svenska", "sv"),
Triple("", "தமிழ்", "ta"),
Triple("", "Tagalog", "tl"), Triple("", "Tagalog", "tl"),
Triple("", "Turkish", "tr"), Triple("", "Türkçe", "tr"),
Triple("", "Ukrainian", "uk"), Triple("", "українська", "uk"),
Triple("", "Urdu", "ur"), Triple("", "اردو", "ur"),
Triple("", "Viet Nam", "vi"), Triple("", "Tiếng Việt", "vi"),
Triple("", "Chinese Simplified", "zh"), Triple("", "中文", "zh"),
Triple("\uD83C\uDDF9\uD83C\uDDFC", "Chinese Traditional", "zh-rTW"), Triple("\uD83C\uDDF9\uD83C\uDDFC", "文言", "zh-rTW"),
/* end language list */ /* end language list */
).sortedBy { it.second } //ye, we go alphabetical, so ppl don't put their lang on top ).sortedBy { it.second?.toLowerCase() } //ye, we go alphabetical, so ppl don't put their lang on top
class SettingsGeneral : PreferenceFragmentCompat() { class SettingsGeneral : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View file

@ -143,7 +143,7 @@ class PluginsFragment : Fragment() {
} }
observe(pluginViewModel.filteredPlugins) { (scrollToTop, list) -> observe(pluginViewModel.filteredPlugins) { (scrollToTop, list) ->
(plugin_recycler_view?.adapter as? PluginAdapter?)?.updateList(list) (plugin_recycler_view?.adapter as? PluginAdapter)?.updateList(list)
if (scrollToTop) if (scrollToTop)
plugin_recycler_view?.scrollToPosition(0) plugin_recycler_view?.scrollToPosition(0)

View file

@ -67,7 +67,7 @@ class SetupFragmentLayout : Fragment() {
crash_reporting_text?.text = getText(text) crash_reporting_text?.text = getText(text)
} }
val enableCrashReporting = !settingsManager.getBoolean(ACRA.PREF_DISABLE_ACRA, false) val enableCrashReporting = !settingsManager.getBoolean(ACRA.PREF_DISABLE_ACRA, true)
acra_switch.isChecked = enableCrashReporting acra_switch.isChecked = enableCrashReporting
crash_reporting_text.text = crash_reporting_text.text =
getText( getText(

View file

@ -28,10 +28,12 @@ import androidx.core.text.toSpanned
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.tvprovider.media.tv.* import androidx.tvprovider.media.tv.*
import androidx.tvprovider.media.tv.WatchNextProgram.fromCursor import androidx.tvprovider.media.tv.WatchNextProgram.fromCursor
import androidx.viewpager2.widget.ViewPager2
import com.fasterxml.jackson.module.kotlin.readValue import com.fasterxml.jackson.module.kotlin.readValue
import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState import com.google.android.gms.cast.framework.CastState
@ -65,6 +67,7 @@ import okhttp3.Cache
import java.io.* import java.io.*
import java.net.URL import java.net.URL
import java.net.URLDecoder import java.net.URLDecoder
import kotlin.system.measureTimeMillis
object AppUtils { object AppUtils {
fun RecyclerView.setMaxViewPoolSize(maxViewTypeId: Int, maxPoolSize: Int) { fun RecyclerView.setMaxViewPoolSize(maxViewTypeId: Int, maxPoolSize: Int) {
@ -164,6 +167,18 @@ object AppUtils {
return builder.build() return builder.build()
} }
// https://stackoverflow.com/a/67441735/13746422
fun ViewPager2.reduceDragSensitivity(f: Int = 4) {
val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
recyclerViewField.isAccessible = true
val recyclerView = recyclerViewField.get(this) as RecyclerView
val touchSlopField = RecyclerView::class.java.getDeclaredField("mTouchSlop")
touchSlopField.isAccessible = true
val touchSlop = touchSlopField.get(recyclerView) as Int
touchSlopField.set(recyclerView, touchSlop * f) // "8" was obtained experimentally
}
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
fun getAllWatchNextPrograms(context: Context): Set<Long> { fun getAllWatchNextPrograms(context: Context): Set<Long> {
val COLUMN_WATCH_NEXT_ID_INDEX = 0 val COLUMN_WATCH_NEXT_ID_INDEX = 0
@ -329,6 +344,46 @@ object AppUtils {
} }
} }
abstract class DiffAdapter<T>(
open val items: MutableList<T>,
val comparison: (first: T, second: T) -> Boolean = { first, second ->
first.hashCode() == second.hashCode()
}
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun getItemCount(): Int {
return items.size
}
fun updateList(newList: List<T>) {
val diffResult = DiffUtil.calculateDiff(
GenericDiffCallback(this.items, newList)
)
items.clear()
items.addAll(newList)
diffResult.dispatchUpdatesTo(this)
}
inner class GenericDiffCallback(
private val oldList: List<T>,
private val newList: List<T>
) :
DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
comparison(oldList[oldItemPosition], newList[newItemPosition])
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
oldList[oldItemPosition] == newList[newItemPosition]
}
}
fun Activity.downloadAllPluginsDialog(repositoryUrl: String, repositoryName: String) { fun Activity.downloadAllPluginsDialog(repositoryUrl: String, repositoryName: String) {
runOnUiThread { runOnUiThread {
val context = this val context = this

View file

@ -9,6 +9,7 @@ import android.provider.MediaStore
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.WorkerThread
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.module.kotlin.readValue import com.fasterxml.jackson.module.kotlin.readValue
@ -18,17 +19,17 @@ import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY import com.lagradost.cloudstream3.plugins.PLUGINS_KEY
import com.lagradost.cloudstream3.plugins.PLUGINS_KEY_LOCAL import com.lagradost.cloudstream3.plugins.PLUGINS_KEY_LOCAL
import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_CACHED_LIST import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_CACHED_LIST
import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_SHOULD_UPDATE_LIST
import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_TOKEN_KEY import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_TOKEN_KEY
import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_UNIXTIME_KEY import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_UNIXTIME_KEY
import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_USER_KEY import com.lagradost.cloudstream3.syncproviders.providers.AniListApi.Companion.ANILIST_USER_KEY
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_CACHED_LIST import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_CACHED_LIST
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_REFRESH_TOKEN_KEY import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_REFRESH_TOKEN_KEY
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_SHOULD_UPDATE_LIST
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_TOKEN_KEY import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_TOKEN_KEY
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_UNIXTIME_KEY import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_UNIXTIME_KEY
import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_USER_KEY import com.lagradost.cloudstream3.syncproviders.providers.MALApi.Companion.MAL_USER_KEY
import com.lagradost.cloudstream3.syncproviders.providers.OpenSubtitlesApi.Companion.OPEN_SUBTITLES_USER_KEY import com.lagradost.cloudstream3.syncproviders.providers.OpenSubtitlesApi.Companion.OPEN_SUBTITLES_USER_KEY
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getDefaultSharedPrefs import com.lagradost.cloudstream3.utils.DataStore.getDefaultSharedPrefs
import com.lagradost.cloudstream3.utils.DataStore.getSharedPrefs import com.lagradost.cloudstream3.utils.DataStore.getSharedPrefs
import com.lagradost.cloudstream3.utils.DataStore.mapper import com.lagradost.cloudstream3.utils.DataStore.mapper
@ -52,12 +53,10 @@ object BackupUtils {
// When sharing backup we do not want to transfer what is essentially the password // When sharing backup we do not want to transfer what is essentially the password
ANILIST_TOKEN_KEY, ANILIST_TOKEN_KEY,
ANILIST_CACHED_LIST, ANILIST_CACHED_LIST,
ANILIST_SHOULD_UPDATE_LIST,
ANILIST_UNIXTIME_KEY, ANILIST_UNIXTIME_KEY,
ANILIST_USER_KEY, ANILIST_USER_KEY,
MAL_TOKEN_KEY, MAL_TOKEN_KEY,
MAL_REFRESH_TOKEN_KEY, MAL_REFRESH_TOKEN_KEY,
MAL_SHOULD_UPDATE_LIST,
MAL_CACHED_LIST, MAL_CACHED_LIST,
MAL_UNIXTIME_KEY, MAL_UNIXTIME_KEY,
MAL_USER_KEY, MAL_USER_KEY,
@ -121,6 +120,7 @@ object BackupUtils {
) )
} }
@WorkerThread
fun Context.restore( fun Context.restore(
backupFile: BackupFile, backupFile: BackupFile,
restoreSettings: Boolean, restoreSettings: Boolean,
@ -223,31 +223,29 @@ object BackupUtils {
try { try {
restoreFileSelector = restoreFileSelector =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? -> registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? ->
this.let { activity -> if (uri == null) return@registerForActivityResult
uri?.let { val activity = this
try { ioSafe {
val input = try {
activity.contentResolver.openInputStream(uri) val input = activity.contentResolver.openInputStream(uri)
?: return@registerForActivityResult ?: return@ioSafe
val restoredValue = val restoredValue =
mapper.readValue<BackupFile>(input) mapper.readValue<BackupFile>(input)
activity.restore(
restoredValue, activity.restore(
restoreSettings = true, restoredValue,
restoreDataStore = true restoreSettings = true,
restoreDataStore = true
)
activity.runOnUiThread { activity.recreate() }
} catch (e: Exception) {
logError(e)
main { // smth can fail in .format
showToast(
activity,
getString(R.string.restore_failed_format).format(e.toString())
) )
activity.recreate()
} catch (e: Exception) {
logError(e)
try { // smth can fail in .format
showToast(
activity,
getString(R.string.restore_failed_format).format(e.toString())
)
} catch (e: Exception) {
logError(e)
}
} }
} }
} }

View file

@ -1,6 +1,7 @@
package com.lagradost.cloudstream3.utils package com.lagradost.cloudstream3.utils
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.APIHolder.capitalize
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
@ -10,6 +11,8 @@ import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.SearchQuality import com.lagradost.cloudstream3.SearchQuality
import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.TvType import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.syncproviders.AccountManager
import com.lagradost.cloudstream3.syncproviders.SyncAPI
import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.result.VideoWatchState import com.lagradost.cloudstream3.ui.result.VideoWatchState
@ -51,7 +54,20 @@ object DataStoreHelper {
@JsonProperty("year") val year: Int?, @JsonProperty("year") val year: Int?,
@JsonProperty("quality") override var quality: SearchQuality? = null, @JsonProperty("quality") override var quality: SearchQuality? = null,
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null, @JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
) : SearchResponse ) : SearchResponse {
fun toLibraryItem(id: String): SyncAPI.LibraryItem {
return SyncAPI.LibraryItem(
name,
url,
id,
null,
null,
null,
null,
apiName, type, posterUrl, posterHeaders, quality, this.id
)
}
}
data class ResumeWatchingResult( data class ResumeWatchingResult(
@JsonProperty("name") override val name: String, @JsonProperty("name") override val name: String,
@ -71,6 +87,9 @@ object DataStoreHelper {
@JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null, @JsonProperty("posterHeaders") override var posterHeaders: Map<String, String>? = null,
) : SearchResponse ) : SearchResponse
/**
* A datastore wide account for future implementations of a multiple account system
**/
private var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION private var currentAccount: String = "0" //TODO ACCOUNT IMPLEMENTATION
fun getAllWatchStateIds(): List<Int>? { fun getAllWatchStateIds(): List<Int>? {
@ -177,6 +196,7 @@ object DataStoreHelper {
fun setBookmarkedData(id: Int?, data: BookmarkedData) { fun setBookmarkedData(id: Int?, data: BookmarkedData) {
if (id == null) return if (id == null) return
setKey("$currentAccount/$RESULT_WATCH_STATE_DATA", id.toString(), data) setKey("$currentAccount/$RESULT_WATCH_STATE_DATA", id.toString(), data)
AccountManager.localListApi.requireLibraryRefresh = true
} }
fun getBookmarkedData(id: Int?): BookmarkedData? { fun getBookmarkedData(id: Int?): BookmarkedData? {

View file

@ -265,8 +265,6 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
OkRu(), OkRu(),
OkRuHttps(), OkRuHttps(),
Okrulink(), Okrulink(),
Sendvid(),
SendvidHttps(),
// dood extractors // dood extractors
DoodCxExtractor(), DoodCxExtractor(),
@ -293,6 +291,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Supervideo(), Supervideo(),
GuardareStream(), GuardareStream(),
CineGrabber(), CineGrabber(),
Vanfem(),
// StreamSB.kt works // StreamSB.kt works
// SBPlay(), // SBPlay(),
@ -323,6 +322,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
DesuDrive(), DesuDrive(),
Filesim(), Filesim(),
FileMoon(),
Linkbox(), Linkbox(),
Acefile(), Acefile(),
SpeedoStream(), SpeedoStream(),
@ -363,6 +363,7 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
Cda(), Cda(),
Dailymotion(), Dailymotion(),
ByteShare(),
) )

View file

@ -91,7 +91,7 @@ class ApkInstaller(private val service: PackageInstallerService) {
session.openWrite(context.packageName, 0, size) session.openWrite(context.packageName, 0, size)
.use { outputStream -> .use { outputStream ->
val buffer = ByteArray(1024) val buffer = ByteArray(4 * 1024)
var bytesRead = inputStream.read(buffer) var bytesRead = inputStream.read(buffer)
while (bytesRead >= 0) { while (bytesRead >= 0) {
@ -100,6 +100,7 @@ class ApkInstaller(private val service: PackageInstallerService) {
installProgress.invoke(bytesRead) installProgress.invoke(bytesRead)
} }
session.fsync(outputStream)
inputStream.close() inputStream.close()
} }

View file

@ -4,6 +4,7 @@ package com.lagradost.cloudstream3.utils
import android.util.Log import android.util.Log
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.APIHolder.apis
//import com.lagradost.cloudstream3.animeproviders.AniflixProvider //import com.lagradost.cloudstream3.animeproviders.AniflixProvider
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
@ -78,17 +79,21 @@ object SyncUtil {
return null return null
} }
suspend fun getUrlsFromId(id: String, type: String = "anilist") : List<String> { suspend fun getUrlsFromId(id: String, type: String = "anilist"): List<String> {
return arrayListOf() val url =
// val url = "https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/$type/anime/$id.json"
// "https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/$type/anime/$id.json" val response = app.get(url, cacheTime = 1, cacheUnit = TimeUnit.DAYS).parsed<SyncPage>()
// val response = app.get(url, cacheTime = 1, cacheUnit = TimeUnit.DAYS).parsed<SyncPage>() val pages = response.pages ?: return emptyList()
// val pages = response.pages ?: return emptyList() val current =
// val current = pages.gogoanime.values.union(pages.nineanime.values).union(pages.twistmoe.values).mapNotNull { it.url }.toMutableList() pages.gogoanime.values.union(pages.nineanime.values).union(pages.twistmoe.values)
// if(type == "anilist") { // TODO MAKE BETTER .mapNotNull { it.url }.toMutableList()
// current.add("${AniflixProvider().mainUrl}/anime/$id")
// } if (type == "anilist") { // TODO MAKE BETTER
// return current apis.filter { it.name.contains("Aniflix", ignoreCase = true) }.forEach {
current.add("${it.mainUrl}/anime/$id")
}
}
return current
} }
data class SyncPage( data class SyncPage(

View file

@ -9,7 +9,9 @@ import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
@ -28,15 +30,21 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.alpha import androidx.core.graphics.alpha
import androidx.core.graphics.blue import androidx.core.graphics.blue
import androidx.core.graphics.drawable.toBitmapOrNull
import androidx.core.graphics.green import androidx.core.graphics.green
import androidx.core.graphics.red import androidx.core.graphics.red
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import androidx.palette.graphics.Palette
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
@ -105,7 +113,7 @@ object UIHelper {
listView.requestLayout() listView.requestLayout()
} }
fun Activity?.getSpanCount(): Int? { fun Context?.getSpanCount(): Int? {
val compactView = false val compactView = false
val spanCountLandscape = if (compactView) 2 else 6 val spanCountLandscape = if (compactView) 2 else 6
val spanCountPortrait = if (compactView) 1 else 3 val spanCountPortrait = if (compactView) 1 else 3
@ -158,12 +166,27 @@ object UIHelper {
return color return color
} }
var createPaletteAsyncCache: HashMap<String, Palette> = hashMapOf()
fun createPaletteAsync(url: String, bitmap: Bitmap, callback: (Palette) -> Unit) {
createPaletteAsyncCache[url]?.let { palette ->
callback.invoke(palette)
return
}
Palette.from(bitmap).generate { paletteNull ->
paletteNull?.let { palette ->
createPaletteAsyncCache[url] = palette
callback(palette)
}
}
}
fun ImageView?.setImage( fun ImageView?.setImage(
url: String?, url: String?,
headers: Map<String, String>? = null, headers: Map<String, String>? = null,
@DrawableRes @DrawableRes
errorImageDrawable: Int? = null, errorImageDrawable: Int? = null,
fadeIn: Boolean = true fadeIn: Boolean = true,
colorCallback: ((Palette) -> Unit)? = null
): Boolean { ): Boolean {
if (this == null || url.isNullOrBlank()) return false if (this == null || url.isNullOrBlank()) return false
@ -177,6 +200,33 @@ object UIHelper {
else req else req
} }
if (colorCallback != null) {
builder.listener(object : RequestListener<Drawable> {
@SuppressLint("CheckResult")
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
resource?.toBitmapOrNull()
?.let { bitmap -> createPaletteAsync(url, bitmap, colorCallback) }
return false
}
@SuppressLint("CheckResult")
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
return false
}
})
}
val res = if (errorImageDrawable != null) val res = if (errorImageDrawable != null)
builder.error(errorImageDrawable).into(this) builder.error(errorImageDrawable).into(this)
else else

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_checked="true"/> <item android:color="?attr/colorPrimary" android:state_checked="true"/>
<item android:color="?attr/colorPrimary" android:state_focused="true"/>
<item android:color="?attr/colorPrimary" android:state_selected="true"/>
<item android:color="?attr/grayTextColor" android:state_checked="false"/> <item android:color="?attr/grayTextColor" android:state_checked="false"/>
</selector> </selector>

View file

@ -0,0 +1,6 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/>
<path android:fillColor="@android:color/white" android:pathData="M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/white" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>

View file

@ -1,5 +1,5 @@
<vector android:height="24dp" android:tint="?attr/white" <vector android:height="12dp" 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="12dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/> <path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
</vector> </vector>

View file

@ -0,0 +1,6 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM7.35,18.5C8.66,17.56 10.26,17 12,17s3.34,0.56 4.65,1.5C15.34,19.44 13.74,20 12,20S8.66,19.44 7.35,18.5zM18.14,17.12L18.14,17.12C16.45,15.8 14.32,15 12,15s-4.45,0.8 -6.14,2.12l0,0C4.7,15.73 4,13.95 4,12c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,13.95 19.3,15.73 18.14,17.12z"/>
<path android:fillColor="@android:color/white" android:pathData="M12,6c-1.93,0 -3.5,1.57 -3.5,3.5S10.07,13 12,13s3.5,-1.57 3.5,-3.5S13.93,6 12,6zM12,11c-0.83,0 -1.5,-0.67 -1.5,-1.5S11.17,8 12,8s1.5,0.67 1.5,1.5S12.83,11 12,11z"/>
</vector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/textColor"/>
<corners android:radius="16dp" />
</shape>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/ratingColorBg"/>
<corners android:radius="@dimen/rounded_image_radius"/>
<!-- <stroke android:color="@color/subColor" android:width="2dp"/>-->
</shape>

View file

@ -35,9 +35,9 @@
--> -->
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
android:layout_height="wrap_content" android:layout_height="70dp"
android:layout_width="0dp" android:layout_width="0dp"
app:labelVisibilityMode="labeled" app:labelVisibilityMode="unlabeled"
android:background="?attr/primaryGrayBackground" android:background="?attr/primaryGrayBackground"
app:itemIconTint="@color/item_select_color" app:itemIconTint="@color/item_select_color"

View file

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/resultview_preview_result"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="@dimen/rounded_image_radius">
<ImageView
android:id="@+id/resultview_preview_poster"
android:layout_width="88dp"
android:layout_height="138dp"
android:contentDescription="@string/poster_image"
android:scaleType="centerCrop"
tools:src="@drawable/example_poster" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="138dp"
android:layout_marginStart="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/resultview_preview_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/textColor"
android:textSize="16sp"
android:textStyle="bold"
tools:text="The Perfect Run">
</TextView>
<com.lagradost.cloudstream3.widget.FlowLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemSpacing="10dp">
<TextView
android:id="@+id/resultview_preview_meta_type"
style="@style/ResultInfoText"
tools:text="Movie" />
<TextView
android:id="@+id/resultview_preview_meta_year"
style="@style/ResultInfoText"
tools:text="2022" />
<TextView
android:id="@+id/resultview_preview_meta_rating"
style="@style/ResultInfoText"
tools:text="Rated: 8.5/10.0" />
<TextView
android:id="@+id/resultview_preview_meta_status"
style="@style/ResultInfoText"
tools:text="Ongoing" />
<TextView
android:id="@+id/resultview_preview_meta_duration"
style="@style/ResultInfoText"
tools:text="121min" />
</com.lagradost.cloudstream3.widget.FlowLayout>
<!-- <TextView
android:id="@+id/resultview_preview_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/grayTextColor"
tools:text="2023" />-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/resultview_preview_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:textColor="?attr/textColor"
tools:text="Ryan Quicksave Romano is an eccentric adventurer with a strange power: he can create a save-point in time and redo his life whenever he dies. Arriving in New Rome, the glitzy capital of sin of a rebuilding Europe, he finds the city torn between mega-corporations, sponsored heroes, superpowered criminals, and true monsters. It's a time of chaos, where potions can grant the power to rule the world and dangers lurk everywhere. " />
<View
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_gravity="bottom"
android:background="@drawable/background_shadow" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/resultview_preview_more_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:gravity="start|center_vertical"
android:padding="12dp"
android:text="@string/home_more_info"
android:textColor="?attr/textColor"
app:drawableRightCompat="@drawable/ic_baseline_arrow_forward_24"
app:drawableTint="?attr/white" />
</LinearLayout>
<FrameLayout
android:id="@+id/resultview_preview_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/resultview_preview_loading_shimmer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical"
app:shimmer_auto_start="true"
app:shimmer_base_alpha="0.2"
app:shimmer_duration="@integer/loading_time"
app:shimmer_highlight_alpha="0.3">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/result_padding"
android:layout_marginTop="@dimen/result_padding"
android:layout_marginEnd="@dimen/result_padding"
android:orientation="horizontal">
<include layout="@layout/loading_poster" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<include layout="@layout/loading_line" />
<include layout="@layout/loading_line_short" />
<include layout="@layout/loading_line" />
<include layout="@layout/loading_line" />
<include layout="@layout/loading_line" />
</LinearLayout>
</LinearLayout>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="26dp"
android:layout_margin="@dimen/result_padding"
android:layout_marginBottom="@dimen/loading_margin"
android:background="@color/grayShimmer"
app:cardCornerRadius="@dimen/loading_radius"
tools:ignore="ContentDescription" />
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
</FrameLayout>
</FrameLayout>

View file

@ -5,7 +5,6 @@
android:id="@+id/download_root" android:id="@+id/download_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryGrayBackground"
android:orientation="vertical" android:orientation="vertical"
tools:context=".ui.download.DownloadFragment"> tools:context=".ui.download.DownloadFragment">
@ -132,7 +131,8 @@
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/download_list" android:id="@+id/download_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:paddingBottom="100dp"
android:clipToPadding="false"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground" android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants" android:descendantFocusability="afterDescendants"

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_header" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/primaryBlackBackground" android:background="?attr/primaryBlackBackground"
xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical">
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<View <View
android:id="@+id/home_none_padding" android:id="@+id/home_none_padding"
@ -45,18 +45,17 @@
<androidx.appcompat.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/home_search" android:id="@+id/home_search"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="60dp"
android:layout_gravity="start" android:layout_gravity="start"
android:editTextColor="@color/white" android:editTextColor="@color/white"
android:gravity="start" android:gravity="start"
android:iconifiedByDefault="true" android:iconifiedByDefault="true"
android:textColor="@color/white" android:textColor="@color/white"
android:textColorHint="@color/white" android:textColorHint="@color/white"
app:closeIcon="@drawable/ic_baseline_close_24"
app:iconifiedByDefault="true" app:iconifiedByDefault="true"
app:queryBackground="@color/transparent" app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint" app:queryHint="@string/search_hint"
app:closeIcon="@drawable/ic_baseline_close_24"
app:searchIcon="@drawable/search_icon" app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry" /> tools:ignore="RtlSymmetry" />
</LinearLayout> </LinearLayout>
@ -80,7 +79,6 @@
--> -->
<LinearLayout <LinearLayout
android:id="@+id/home_preview_title_holder" android:id="@+id/home_preview_title_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="100dp" android:layout_height="100dp"
@ -156,7 +154,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="0dp" android:layout_marginEnd="0dp"
android:padding="12dp" android:padding="12dp"
android:text="@string/continue_watching" /> android:text="@string/continue_watching"
app:drawableRightCompat="@drawable/ic_baseline_arrow_forward_24"
app:drawableTint="?attr/white"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/home_more_info"/>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_watch_child_recyclerview" android:id="@+id/home_watch_child_recyclerview"
@ -179,77 +181,96 @@
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
<HorizontalScrollView <FrameLayout
android:id="@+id/home_bookmark_parent_item_title"
android:background="?android:attr/selectableItemBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:fadingEdge="horizontal"
android:foreground="?android:attr/selectableItemBackgroundBorderless" <HorizontalScrollView
android:nextFocusLeft="@id/nav_rail_view" android:layout_width="match_parent"
android:nextFocusUp="@id/home_watch_child_recyclerview"
android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_marginEnd="50dp"
android:fadingEdge="horizontal"
<com.google.android.material.chip.Chip android:nextFocusLeft="@id/nav_rail_view"
android:id="@+id/home_type_watching_btt" android:nextFocusUp="@id/home_watch_child_recyclerview"
style="@style/ChipFilled" android:nextFocusForward="@id/home_bookmarked_child_recyclerview"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp"
android:requiresFadingEdge="horizontal">
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal">
android:nextFocusLeft="@id/nav_rail_view" <com.google.android.material.chip.Chip
android:nextFocusRight="@id/home_plan_to_watch_btt" android:id="@+id/home_type_watching_btt"
android:text="@string/type_watching" /> style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<com.google.android.material.chip.Chip android:nextFocusLeft="@id/nav_rail_view"
android:id="@+id/home_plan_to_watch_btt" android:nextFocusRight="@id/home_plan_to_watch_btt"
style="@style/ChipFilled" android:text="@string/type_watching" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_watching_btt" <com.google.android.material.chip.Chip
android:nextFocusRight="@id/home_type_on_hold_btt" android:id="@+id/home_plan_to_watch_btt"
android:text="@string/type_plan_to_watch" /> style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<com.google.android.material.chip.Chip android:nextFocusLeft="@id/home_type_watching_btt"
android:id="@+id/home_type_on_hold_btt" android:nextFocusRight="@id/home_type_on_hold_btt"
style="@style/ChipFilled" android:text="@string/type_plan_to_watch" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_plan_to_watch_btt" <com.google.android.material.chip.Chip
android:nextFocusRight="@id/home_type_dropped_btt" android:id="@+id/home_type_on_hold_btt"
android:text="@string/type_on_hold" /> style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<com.google.android.material.chip.Chip android:nextFocusLeft="@id/home_plan_to_watch_btt"
android:id="@+id/home_type_dropped_btt" android:nextFocusRight="@id/home_type_dropped_btt"
style="@style/ChipFilled" android:text="@string/type_on_hold" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_on_hold_btt" <com.google.android.material.chip.Chip
android:nextFocusRight="@id/home_type_completed_btt" android:id="@+id/home_type_dropped_btt"
android:text="@string/type_dropped" /> style="@style/ChipFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<com.google.android.material.chip.Chip android:nextFocusLeft="@id/home_type_on_hold_btt"
android:id="@+id/home_type_completed_btt" android:nextFocusRight="@id/home_type_completed_btt"
style="@style/ChipFilled" android:text="@string/type_dropped" />
android:layout_width="wrap_content"
android:layout_height="wrap_content" <com.google.android.material.chip.Chip
android:nextFocusLeft="@id/home_type_dropped_btt" android:id="@+id/home_type_completed_btt"
android:text="@string/type_completed" /> style="@style/ChipFilled"
</com.google.android.material.chip.ChipGroup> android:layout_width="wrap_content"
</HorizontalScrollView>
android:layout_height="wrap_content"
android:nextFocusLeft="@id/home_type_dropped_btt"
android:text="@string/type_completed" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>
<ImageView
android:layout_marginEnd="12dp"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_baseline_arrow_forward_24"
app:drawableTint="?attr/white"
android:contentDescription="@string/home_more_info"/>
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_bookmarked_child_recyclerview" android:id="@+id/home_bookmarked_child_recyclerview"

View file

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/library_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/empty_list_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="30dp"
android:gravity="center"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryGrayBackground">
<LinearLayout
android:id="@+id/search_status_bar_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_scrollFlags="scroll|enterAlways">
<ImageView
android:id="@+id/provider_selector"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="end|center_vertical"
android:layout_marginStart="10dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/change_providers_img_des"
android:src="@drawable/ic_baseline_extension_24"
app:tint="?attr/textColor" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_margin="10dp"
android:background="@drawable/search_background"
android:visibility="visible"
app:layout_scrollFlags="scroll|enterAlways">
<androidx.appcompat.widget.SearchView
android:id="@+id/main_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch"
android:inputType="text"
android:nextFocusLeft="@id/nav_rail_view"
android:nextFocusRight="@id/search_filter"
android:paddingStart="-10dp"
app:iconifiedByDefault="false"
app:queryBackground="@color/transparent"
app:queryHint="@string/search_hint"
app:searchIcon="@drawable/search_icon"
tools:ignore="RtlSymmetry">
</androidx.appcompat.widget.SearchView>
<ImageView
android:id="@+id/list_selector"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="end|center_vertical"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/change_providers_img_des"
android:nextFocusLeft="@id/main_search"
android:nextFocusRight="@id/main_search"
android:padding="10dp"
android:src="@drawable/ic_baseline_filter_list_24"
app:tint="?attr/textColor" />
</FrameLayout>
</LinearLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="40dp"
tools:listitem="@layout/library_viewpager_page" />
<LinearLayout
android:id="@+id/library_loading_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:visibility="gone"
tools:visibility="visible">
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/library_loading_shimmer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="2dp"
app:shimmer_auto_start="true"
app:shimmer_base_alpha="0.2"
app:shimmer_duration="@integer/loading_time"
app:shimmer_highlight_alpha="0.3">
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:paddingBottom="120dp"
android:verticalSpacing="10dp"
tools:listitem="@layout/loading_poster_dynamic" />
</com.facebook.shimmer.ShimmerFrameLayout>
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="40dp">
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/sort_fab"
style="@style/ExtendedFloatingActionButton"
android:text="@string/sort"
android:textColor="?attr/textColor"
app:icon="@drawable/ic_baseline_sort_24"
tools:ignore="ContentDescription" />
</FrameLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/library_tab_layout"
style="@style/Theme.Widget.Tabs"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:background="?attr/primaryGrayBackground"
android:descendantFocusability="blocksDescendants"
android:focusable="false"
android:paddingHorizontal="5dp"
app:layout_scrollFlags="noScroll"
app:tabGravity="center"
app:tabIndicator="@drawable/indicator_background"
app:tabIndicatorColor="?attr/white"
app:tabIndicatorGravity="center"
app:tabIndicatorHeight="30dp"
app:tabMode="scrollable"
app:tabSelectedTextColor="?attr/primaryBlackBackground"
app:tabTextAppearance="@style/TabNoCaps"
app:tabTextColor="?attr/textColor" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -129,9 +129,9 @@
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/result_scroll" android:id="@+id/result_scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:paddingBottom="100dp"
android:layout_height="wrap_content" android:clipToPadding="false"
android:background="?attr/primaryGrayBackground"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -6,27 +6,18 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<FrameLayout <TextView
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:id="@+id/home_child_more_info"
android:id="@+id/home_child_more_info" style="@style/WatchHeaderText"
android:padding="12dp" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content"> android:layout_marginEnd="0dp"
android:padding="12dp"
<TextView tools:text="@string/continue_watching"
android:id="@+id/home_parent_item_title" app:drawableRightCompat="@drawable/ic_baseline_arrow_forward_24"
style="@style/WatchHeaderText" app:drawableTint="?attr/white"
tools:text="Trending" /> android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/home_more_info"/>
<ImageView
app:tint="?attr/textColor"
android:layout_marginEnd="5dp"
android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_width="30dp"
android:layout_height="match_parent"
android:contentDescription="@string/home_more_info" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:nextFocusUp="@id/home_child_more_info" android:nextFocusUp="@id/home_child_more_info"

View file

@ -8,7 +8,7 @@
<TextView <TextView
android:layout_marginStart="@dimen/navbar_width" android:layout_marginStart="@dimen/navbar_width"
android:id="@+id/home_parent_item_title" android:id="@+id/home_child_more_info"
android:padding="12dp" android:padding="12dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<com.lagradost.cloudstream3.ui.AutofitRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/page_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:listitem="@layout/home_result_grid_expanded" />

View file

@ -1,59 +1,59 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:paddingTop="@dimen/loading_margin" android:layout_height="200dp"
android:paddingBottom="@dimen/loading_margin" android:orientation="vertical"
android:layout_height="200dp" android:paddingTop="@dimen/loading_margin"
android:layout_width="match_parent"> android:paddingBottom="@dimen/loading_margin">
<include layout="@layout/loading_line_short" /> <include layout="@layout/loading_line_short" />
<LinearLayout <LinearLayout
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content"> android:orientation="horizontal">
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="match_parent" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="match_parent" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
<View <View
android:layout_height="wrap_content" android:layout_width="@dimen/loading_margin"
android:layout_width="@dimen/loading_margin" /> android:layout_height="wrap_content" />
<include layout="@layout/loading_poster" /> <include layout="@layout/loading_poster" />
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,37 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="10dp"
android:background="@color/grayShimmer"
app:cardCornerRadius="@dimen/loading_radius"
app:layout_constraintDimensionRatio="1:1.414"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
layout="@layout/loading_line_short_center"
android:layout_width="match_parent"
android:layout_height="15dp"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp" />
</LinearLayout>

View file

@ -96,33 +96,36 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <LinearLayout
android:id="@+id/player_video_title" android:clipToPadding="false"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="80dp" android:layout_marginStart="80dp"
android:layout_marginTop="35dp" android:paddingTop="20dp"
android:layout_marginEnd="80dp" android:layout_marginEnd="80dp"
android:gravity="center" android:orientation="vertical"
android:textColor="@color/white"
android:textStyle="bold"
android:visibility="visible"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent">
tools:text="Hello world" />
<TextView <TextView
android:id="@+id/player_video_title_rez" android:id="@+id/player_video_title_rez"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="80dp" android:layout_marginBottom="2.5dp"
android:layout_marginTop="20dp" android:gravity="center"
android:layout_marginEnd="80dp" android:textColor="@color/white"
android:gravity="center" tools:text="1920x1080" />
android:textColor="@color/white"
app:layout_constraintLeft_toLeftOf="parent" <TextView
app:layout_constraintTop_toBottomOf="@+id/player_video_title" android:id="@+id/player_video_title"
tools:text="1920x1080" /> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/white"
android:textStyle="bold"
android:visibility="visible"
tools:text="Hello world" />
</LinearLayout>
<!-- Removed as it has no use anymore--> <!-- Removed as it has no use anymore-->
@ -319,23 +322,23 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
tools:visibility="visible"
android:id="@+id/skip_chapter_button" android:id="@+id/skip_chapter_button"
style="@style/NiceButton" style="@style/NiceButton"
android:layout_width="150dp" android:layout_width="150dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginEnd="100dp" android:layout_marginEnd="100dp"
android:visibility="gone"
android:maxLines="1"
android:backgroundTint="@color/skipOpTransparent" android:backgroundTint="@color/skipOpTransparent"
android:maxLines="1"
android:padding="10dp" android:padding="10dp"
android:textColor="@color/white" android:textColor="@color/white"
android:visibility="gone"
app:cornerRadius="@dimen/rounded_button_radius" app:cornerRadius="@dimen/rounded_button_radius"
app:layout_constraintBottom_toTopOf="@+id/bottom_player_bar" app:layout_constraintBottom_toTopOf="@+id/bottom_player_bar"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:strokeColor="@color/white" app:strokeColor="@color/white"
app:strokeWidth="1dp" app:strokeWidth="1dp"
tools:text="Skip Opening" /> tools:text="Skip Opening"
tools:visibility="visible" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -44,6 +44,7 @@
android:nextFocusLeft="@id/sort_subtitles" android:nextFocusLeft="@id/sort_subtitles"
android:nextFocusRight="@id/apply_btt" android:nextFocusRight="@id/apply_btt"
android:requiresFadingEdge="vertical" android:requiresFadingEdge="vertical"
tools:layout_height="100dp"
tools:listitem="@layout/sort_bottom_single_choice" /> tools:listitem="@layout/sort_bottom_single_choice" />
</LinearLayout> </LinearLayout>
@ -117,6 +118,7 @@
android:nextFocusLeft="@id/sort_providers" android:nextFocusLeft="@id/sort_providers"
android:nextFocusRight="@id/cancel_btt" android:nextFocusRight="@id/cancel_btt"
android:requiresFadingEdge="vertical" android:requiresFadingEdge="vertical"
tools:layout_height="200dp"
tools:listfooter="@layout/sort_bottom_footer_add_choice" tools:listfooter="@layout/sort_bottom_footer_add_choice"
tools:listitem="@layout/sort_bottom_single_choice" /> tools:listitem="@layout/sort_bottom_single_choice" />
</LinearLayout> </LinearLayout>

View file

@ -5,62 +5,109 @@
android:id="@+id/search_result_root" android:id="@+id/search_result_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:foreground="@drawable/outline_drawable" android:foreground="@drawable/outline_drawable"
android:orientation="vertical"> android:orientation="vertical">
<androidx.cardview.widget.CardView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/background_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_margin="2dp"
android:layout_marginBottom="2dp"
android:elevation="10dp"
app:cardBackgroundColor="?attr/primaryGrayBackground"
app:cardCornerRadius="@dimen/rounded_image_radius">
<ImageView <androidx.cardview.widget.CardView
android:id="@+id/imageView" android:id="@+id/background_card"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="2dp"
android:layout_marginBottom="2dp"
android:elevation="10dp"
app:cardBackgroundColor="?attr/primaryGrayBackground"
app:cardCornerRadius="@dimen/rounded_image_radius"
app:layout_constraintDimensionRatio="1:1.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_height="match_parent" <ImageView
android:contentDescription="@string/search_poster_img_des" android:id="@+id/imageView"
android:duplicateParentState="true" android:layout_width="match_parent"
android:foreground="?android:attr/selectableItemBackgroundBorderless" android:layout_height="match_parent"
android:scaleType="centerCrop" android:contentDescription="@string/search_poster_img_des"
tools:src="@drawable/example_poster" /> android:duplicateParentState="true"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
<TextView android:id="@+id/text_quality" style="@style/TypeButton" /> android:scaleType="centerCrop"
tools:src="@drawable/example_poster" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:orientation="vertical">
<TextView <TextView
android:id="@+id/text_is_dub" android:id="@+id/text_quality"
style="@style/DubButton" style="@style/TypeButton" />
android:layout_gravity="end" />
<TextView <LinearLayout
android:id="@+id/text_is_sub" android:layout_width="match_parent"
style="@style/SubButton" android:layout_height="match_parent"
android:layout_gravity="end" />
<TextView
android:id="@+id/text_flag"
style="@style/SearchBox"
android:layout_gravity="end" android:layout_gravity="end"
android:background="@color/transparent" android:orientation="vertical">
android:textSize="20sp"
<TextView
android:id="@+id/text_is_dub"
style="@style/DubButton"
android:layout_gravity="end" />
<TextView
android:id="@+id/text_is_sub"
style="@style/SubButton"
android:layout_gravity="end" />
<androidx.cardview.widget.CardView
android:id="@+id/text_rating_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_margin="2dp"
android:backgroundTint="@color/ratingColorBg"
android:elevation="0dp"
android:visibility="gone"
app:cardCornerRadius="@dimen/rounded_image_radius"
app:cardElevation="0dp"
tools:visibility="visible">
<TextView
android:id="@+id/text_rating"
style="@style/SearchBox"
android:layout_margin="0dp"
android:minWidth="40dp"
android:textColor="@color/ratingColor"
tools:text="★ 7.7" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/text_flag"
style="@style/SearchBox"
android:layout_gravity="end"
android:background="@color/transparent"
android:textSize="20sp"
android:visibility="gone"
tools:text="🇸🇪"
tools:visibility="visible" />
</LinearLayout>
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/watchProgress"
style="@android:style/Widget.Material.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:layout_marginBottom="-1.5dp"
android:progressBackgroundTint="?attr/colorPrimary"
android:progressTint="?attr/colorPrimary"
android:visibility="gone" android:visibility="gone"
tools:text="🇸🇪" tools:progress="50"
tools:visibility="visible" /> tools:visibility="visible" />
</LinearLayout> </androidx.cardview.widget.CardView>
</androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
<TextView <TextView
android:id="@+id/imageText" android:id="@+id/imageText"
@ -78,4 +125,4 @@
android:textColor="?attr/textColor" android:textColor="?attr/textColor"
android:textSize="13sp" android:textSize="13sp"
tools:text="The Perfect Run\nThe Perfect Run" /> tools:text="The Perfect Run\nThe Perfect Run" />
</LinearLayout> </LinearLayout>

View file

@ -1,20 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:id="@+id/navigation_home" android:id="@+id/navigation_home"
android:icon="@drawable/home_alt" android:icon="@drawable/home_alt"
android:title="@string/title_home"/> android:title="@string/title_home" />
<item <item
android:id="@+id/navigation_search" android:id="@+id/navigation_search"
android:icon="@drawable/search_icon" android:icon="@drawable/search_icon"
android:title="@string/title_search"/> android:title="@string/title_search" />
<item <item
android:id="@+id/navigation_downloads" android:id="@+id/navigation_library"
android:icon="@drawable/netflix_download" android:icon="@drawable/ic_outline_account_circle_24"
android:title="@string/title_downloads"/> android:title="@string/library" />
<item <item
android:id="@+id/navigation_settings" android:id="@+id/navigation_downloads"
android:icon="@drawable/settings_alt" android:icon="@drawable/netflix_download"
android:title="@string/title_settings"/> android:title="@string/title_downloads" />
<item
android:id="@+id/navigation_settings"
android:icon="@drawable/ic_outline_settings_24"
android:title="@string/title_settings" />
</menu> </menu>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search_button"
android:icon="@drawable/search_icon"
android:title="@string/title_search"
app:searchHintIcon="@drawable/search_icon"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="com.lagradost.cloudstream3.ui.library.MenuSearchView" />
<item
android:id="@+id/sort_button"
android:icon="@drawable/ic_baseline_sort_24"
android:title="Sort"
app:showAsAction="collapseActionView|ifRoom" />
</menu>

View file

@ -144,6 +144,15 @@
app:popEnterAnim="@anim/enter_anim" app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" /> app:popExitAnim="@anim/exit_anim" />
<fragment
android:id="@+id/navigation_library"
android:name="com.lagradost.cloudstream3.ui.library.LibraryFragment"
android:label="@string/library"
app:enterAnim="@anim/enter_anim"
app:exitAnim="@anim/exit_anim"
app:popEnterAnim="@anim/enter_anim"
app:popExitAnim="@anim/exit_anim" />
<fragment <fragment
android:id="@+id/navigation_settings_general" android:id="@+id/navigation_settings_general"
android:name="com.lagradost.cloudstream3.ui.settings.SettingsGeneral" android:name="com.lagradost.cloudstream3.ui.settings.SettingsGeneral"

View file

@ -102,7 +102,7 @@
<string name="action_remove_watching">حذف</string> <string name="action_remove_watching">حذف</string>
<string name="action_open_watching">مزيد من المعلومات</string> <string name="action_open_watching">مزيد من المعلومات</string>
<string name="vpn_might_be_needed">قد تكون هناك حاجة إلى VPN لكي يعمل هذا المزود بشكل صحيح</string> <string name="vpn_might_be_needed">قد تكون هناك حاجة إلى VPN لكي يعمل هذا المزود بشكل صحيح</string>
<string name="vpn_torrent">هذا المزود هو تورنت ، يوصى باستخدام شبكة ظاهرية خاصة</string> <string name="vpn_torrent">هذا المزود هو تورنت ، يوصى باستخدام شبكة ظاهرية خاصة</string>
<string name="provider_info_meta">لا يتم توفير البيانات الوصفية بواسطة الموقع ، وسيفشل تحميل الفيديو إذا لم يكن موجودًا في الموقع.</string> <string name="provider_info_meta">لا يتم توفير البيانات الوصفية بواسطة الموقع ، وسيفشل تحميل الفيديو إذا لم يكن موجودًا في الموقع.</string>
<string name="torrent_plot">الوصف</string> <string name="torrent_plot">الوصف</string>
<string name="normal_no_plot">لم يتم العثور على وصف</string> <string name="normal_no_plot">لم يتم العثور على وصف</string>
@ -184,8 +184,10 @@
<string name="resume">إستئناف</string> <string name="resume">إستئناف</string>
<string name="go_back_30">-٣٠</string> <string name="go_back_30">-٣٠</string>
<string name="go_forward_30">+٣٠</string> <string name="go_forward_30">+٣٠</string>
<string name="delete_message">سوف يتم الحذف نهائيا %s\nهل أنت متأكد?</string> <string name="delete_message">سوف يتم الحذف نهائيا %s
<string name="resume_time_left" formatted="true">%dm\nمتبقية</string> \nهل أنت متأكد\?</string>
<string name="resume_time_left" formatted="true">%dm
\nمتبقية</string>
<string name="status_ongoing">جاري التنفيذ</string> <string name="status_ongoing">جاري التنفيذ</string>
<string name="status_completed">اكتمل</string> <string name="status_completed">اكتمل</string>
<string name="status">الحالة</string> <string name="status">الحالة</string>
@ -233,7 +235,7 @@
<string name="episode_action_chromecast_mirror">مرآة كروم كاست</string> <string name="episode_action_chromecast_mirror">مرآة كروم كاست</string>
<string name="episode_action_play_in_app">تشغيل في التطبيق</string> <string name="episode_action_play_in_app">تشغيل في التطبيق</string>
<string name="episode_action_play_in_format">%s تشغيل في</string> <string name="episode_action_play_in_format">%s تشغيل في</string>
<string name="episode_action_play_in_browser">تشغيل في الويب </string> <string name="episode_action_play_in_browser">تشغيل في الويب</string>
<string name="episode_action_copy_link">نسخ الرابط</string> <string name="episode_action_copy_link">نسخ الرابط</string>
<string name="episode_action_auto_download">التحميل التلقائي</string> <string name="episode_action_auto_download">التحميل التلقائي</string>
<string name="episode_action_download_mirror">تحميل بجودات مختلفة</string> <string name="episode_action_download_mirror">تحميل بجودات مختلفة</string>
@ -279,22 +281,7 @@
<string name="resize_zoom">تكبير</string> <string name="resize_zoom">تكبير</string>
<string name="legal_notice">إخلاء مسؤولية</string> <string name="legal_notice">إخلاء مسؤولية</string>
<string name="legal_notice_key" translatable="false">legal_notice_key</string> <string name="legal_notice_key" translatable="false">legal_notice_key</string>
<string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application <string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application should be taken up with the actual file hosts and providers themselves as we are not affiliated with them. In case of copyright infringement, please directly contact the responsible parties or the streaming websites. The app is purely for educational and personal use. CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down. CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient, user-friendly interface. It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk.</string>
should be taken up with the actual file hosts and providers themselves as we are not affiliated with them.
In case of copyright infringement, please directly contact the responsible parties or the streaming websites.
The app is purely for educational and personal use.
CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down.
CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or
manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient,
user-friendly interface.
It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the
responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use
CloudStream 3 at your own risk.
</string>
<string name="category_general">عام</string> <string name="category_general">عام</string>
<string name="random_button_settings">زر العشوائي</string> <string name="random_button_settings">زر العشوائي</string>
<string name="random_button_settings_desc">إظهار زر العشوائي على الصفحة الرئيسية</string> <string name="random_button_settings_desc">إظهار زر العشوائي على الصفحة الرئيسية</string>
@ -345,7 +332,7 @@
<string name="upload_sync">مزامنة</string> <string name="upload_sync">مزامنة</string>
<string name="sync_score">تقييم</string> <string name="sync_score">تقييم</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s تم التوثيق</string> <string name="authenticated_user" formatted="true">%s تم التوثيق</string>
<string name="authenticated_user_fail" formatted="true">تعذر تسجيل الدخول في %s</string> <string name="authenticated_user_fail" formatted="true">تعذر تسجيل الدخول في %s</string>
@ -355,7 +342,7 @@
<string name="all">الكل</string> <string name="all">الكل</string>
<string name="max">الحد الاقصي</string> <string name="max">الحد الاقصي</string>
<string name="min">الحد الأدنى</string> <string name="min">الحد الأدنى</string>
<string name="subtitles_none" translatable="false">@string/none</string> <string name="subtitles_none" translatable="false">\@string/none</string>
<string name="subtitles_outline">الخطوط المحيطة</string> <string name="subtitles_outline">الخطوط المحيطة</string>
<string name="subtitles_depressed">النمط المنخفض</string> <string name="subtitles_depressed">النمط المنخفض</string>
<string name="subtitles_shadow">ظل</string> <string name="subtitles_shadow">ظل</string>
@ -452,7 +439,7 @@
<string name="view_public_repositories_button">عرض مستودعات المجتمع</string> <string name="view_public_repositories_button">عرض مستودعات المجتمع</string>
<string name="view_public_repositories_button_short">قائمة عامة</string> <string name="view_public_repositories_button_short">قائمة عامة</string>
<string name="uppercase_all_subtitles">جميع الترجمات حروف كبيرة</string> <string name="uppercase_all_subtitles">جميع الترجمات حروف كبيرة</string>
<string name="download_all_plugins_from_repo">تحميل جميع الإضافات من هذا المستودع?</string> <string name="download_all_plugins_from_repo">تحميل جميع الإضافات من هذا المستودع\?</string>
<string name="single_plugin_disabled" formatted="true">%s (معطل)</string> <string name="single_plugin_disabled" formatted="true">%s (معطل)</string>
<string name="tracks">المسارات</string> <string name="tracks">المسارات</string>
<string name="audio_tracks">مسار الصوت</string> <string name="audio_tracks">مسار الصوت</string>
@ -533,4 +520,27 @@
<string name="delayed_update_notice">سيتم تحديث التطبيق عند الخروج</string> <string name="delayed_update_notice">سيتم تحديث التطبيق عند الخروج</string>
<string name="update_started">بدأ التحديث</string> <string name="update_started">بدأ التحديث</string>
<string name="plugin_downloaded">تم تنزيل الإضافة</string> <string name="plugin_downloaded">تم تنزيل الإضافة</string>
<string name="action_remove_from_watched">إزالة من المشاهدة</string>
<string name="sort_alphabetical_a">الترتيب الأبجدي (من الألف إلى الياء)</string>
<string name="select_library">اختر المكتبة</string>
<string name="browser">المتصفح</string>
<string name="sort_updated_new">محدث (من الأحدث إلى الأقدم)</string>
<string name="empty_library_logged_in_message">يبدو أن هذه القائمة فارغة ، حاول التبديل إلى قائمة أخرى</string>
<string name="sort_rating_desc">التقييم (من الأعلى إلى الأدنى)</string>
<string name="sort_rating_asc">التقييم (من الأدنى إلى الأعلى)</string>
<string name="sort_alphabetical_z">الترتيب الأبجدي (من ي إلى أ)</string>
<string name="empty_library_no_accounts_message">يبدو أن مكتبتك فارغة :(
\nتسجيل الدخول إلى حساب مكتبة أو إضافة عروض إلى مكتبتك المحلية</string>
<string name="sort_updated_old">محدث (من القديم إلى الجديد)</string>
<string name="sort_by">فرز حسب</string>
<string name="sort">افرز</string>
<string name="open_with">فتح بواسطة</string>
<string name="library">المكتبة</string>
<string name="safe_mode_file">تم العثور على ملف الوضع الآمن!
\nلا يتم تحميل أي ملحقات عند بدء التشغيل حتى تتم إزالة الملف.</string>
<string name="android_tv_interface_off_seek_settings_summary">مدة التقديم عنما يكون المشغل مخفيا</string>
<string name="android_tv_interface_off_seek_settings">مدة التقديم - المشغل مخفي</string>
<string name="pref_category_android_tv">تلفزيون أندرويد</string>
<string name="android_tv_interface_on_seek_settings_summary">مدة التقديم عنما يكون المشغل مرئيا</string>
<string name="android_tv_interface_on_seek_settings">مدة التقديم- المشغل المرئي</string>
</resources> </resources>

View file

@ -8,7 +8,6 @@
<string formatted="true" name="next_episode_time_hour_format">%dh %dm</string> <string formatted="true" name="next_episode_time_hour_format">%dh %dm</string>
<string formatted="true" name="next_episode_time_min_format">%dm</string> <string formatted="true" name="next_episode_time_min_format">%dm</string>
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="episode_poster_img_des">Episode Poster</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Main Poster</string>
<string name="home_next_random_img_des">Следващ произволен</string> <string name="home_next_random_img_des">Следващ произволен</string>
@ -17,7 +16,8 @@
<string name="preview_background_img_des">Визуализация на фона</string> <string name="preview_background_img_des">Визуализация на фона</string>
<string formatted="true" name="player_speed_text_format">Скорост (%.2fx)</string> <string formatted="true" name="player_speed_text_format">Скорост (%.2fx)</string>
<string formatted="true" name="rated_format">Оценка: %.1f</string> <string formatted="true" name="rated_format">Оценка: %.1f</string>
<string formatted="true" name="new_update_format">Намерена е нова актуализация!\n%s -&gt; %s</string> <string formatted="true" name="new_update_format">Намерена е нова актуализация!
\n%s -&gt; %s</string>
<string formatted="true" name="filler">Шаблон</string> <string formatted="true" name="filler">Шаблон</string>
<string formatted="true" name="duration_format">%d мин</string> <string formatted="true" name="duration_format">%d мин</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -105,7 +105,7 @@
<string name="continue_watching">Продължете да гледате</string> <string name="continue_watching">Продължете да гледате</string>
<string name="action_remove_watching">Премахване</string> <string name="action_remove_watching">Премахване</string>
<string name="action_open_watching">Повече информация</string> <string name="action_open_watching">Повече информация</string>
<string name="action_open_play">@string/home_play</string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Може да е необходим VPN, за да работи правилно този доставчик</string> <string name="vpn_might_be_needed">Може да е необходим VPN, за да работи правилно този доставчик</string>
<string name="vpn_torrent">Този доставчик е торент, препоръчва се VPN</string> <string name="vpn_torrent">Този доставчик е торент, препоръчва се VPN</string>
<string name="provider_info_meta">Метаданните не се предоставят от сайта, зареждането на видео ще бъде неуспешно, ако не съществува на сайта.</string> <string name="provider_info_meta">Метаданните не се предоставят от сайта, зареждането на видео ще бъде неуспешно, ако не съществува на сайта.</string>
@ -135,8 +135,7 @@
<string name="double_tap_to_seek_settings_des">Докоснете два пъти от дясната или лявата страна, за да превъртите напред или назад</string> <string name="double_tap_to_seek_settings_des">Докоснете два пъти от дясната или лявата страна, за да превъртите напред или назад</string>
<string name="double_tap_to_pause_settings_des">Докоснете в средата, за да направите пауза</string> <string name="double_tap_to_pause_settings_des">Докоснете в средата, за да направите пауза</string>
<string name="use_system_brightness_settings">Използвайте яркостта на системата</string> <string name="use_system_brightness_settings">Използвайте яркостта на системата</string>
<string name="use_system_brightness_settings_des">Използвайте системна яркост в плейъра на приложението вместо тъмно <string name="use_system_brightness_settings_des">Използвайте системна яркост в плейъра на приложението вместо тъмно наслагване</string>
наслагване</string>
<string name="episode_sync_settings">Актуализирайте прогреса на гледане</string> <string name="episode_sync_settings">Актуализирайте прогреса на гледане</string>
<string name="episode_sync_settings_des">Автоматично синхронизирайте прогреса на текущия си епизод</string> <string name="episode_sync_settings_des">Автоматично синхронизирайте прогреса на текущия си епизод</string>
<string name="restore_settings">Възстановете данните от архив</string> <string name="restore_settings">Възстановете данните от архив</string>
@ -175,8 +174,7 @@
<string name="copy_link_toast">Връзката е копирана в клипборда</string> <string name="copy_link_toast">Връзката е копирана в клипборда</string>
<string name="play_episode_toast">Пусни епизода</string> <string name="play_episode_toast">Пусни епизода</string>
<string name="subs_default_reset_toast">Възстановяване на стойността по подразбиране</string> <string name="subs_default_reset_toast">Възстановяване на стойността по подразбиране</string>
<string name="acra_report_toast">За съжаление приложението се срина. Анонимен доклад за грешка ще бъде изпратен до <string name="acra_report_toast">За съжаление приложението се срина. Анонимен доклад за грешка ще бъде изпратен до разработчиците</string>
разработчиците</string>
<string name="season">Сезон</string> <string name="season">Сезон</string>
<string name="season_format">%s %d%s</string> <string name="season_format">%s %d%s</string>
<string name="no_season">Без сезон</string> <string name="no_season">Без сезон</string>
@ -193,8 +191,10 @@
<string name="resume">Продължи</string> <string name="resume">Продължи</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">30</string> <string name="go_forward_30">30</string>
<string formatted="true" name="delete_message">Това ще изтрие за постоянно %s\nСигурни ли сте?</string> <string formatted="true" name="delete_message">Това ще изтрие за постоянно %s
<string formatted="true" name="resume_time_left">%dm\nостава</string> \nСигурни ли сте\?</string>
<string formatted="true" name="resume_time_left">%dm
\nостава</string>
<string name="status_ongoing">Продължава</string> <string name="status_ongoing">Продължава</string>
<string name="status_completed">Завършен</string> <string name="status_completed">Завършен</string>
<string name="status">Статус</string> <string name="status">Статус</string>
@ -223,8 +223,8 @@
<string name="movies_singular">Филм</string> <string name="movies_singular">Филм</string>
<string name="tv_series_singular">Серия</string> <string name="tv_series_singular">Серия</string>
<string name="cartoons_singular">Анимационен филм</string> <string name="cartoons_singular">Анимационен филм</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Торент</string> <string name="torrent_singular">Торент</string>
<string name="documentaries_singular">Документален филм</string> <string name="documentaries_singular">Документален филм</string>
<string name="asian_drama_singular">Азиатска драма</string> <string name="asian_drama_singular">Азиатска драма</string>
@ -320,7 +320,7 @@
<string name="upload_sync">Синхронизиране</string> <string name="upload_sync">Синхронизиране</string>
<string name="sync_score">Оценен</string> <string name="sync_score">Оценен</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string formatted="true" name="authenticated_user">%s удостоверен</string> <string formatted="true" name="authenticated_user">%s удостоверен</string>
<string formatted="true" name="authenticated_user_fail">Не можах да вляза в %s</string> <string formatted="true" name="authenticated_user_fail">Не можах да вляза в %s</string>
@ -426,7 +426,7 @@
<string name="view_public_repositories_button">Вижте хранилищата на общността</string> <string name="view_public_repositories_button">Вижте хранилищата на общността</string>
<string name="view_public_repositories_button_short">Публичен списък</string> <string name="view_public_repositories_button_short">Публичен списък</string>
<string name="uppercase_all_subtitles">Всички субтитри с главни букви</string> <string name="uppercase_all_subtitles">Всички субтитри с главни букви</string>
<string name="download_all_plugins_from_repo">Изтегляне на всички добавки от това хранилище?</string> <string name="download_all_plugins_from_repo">Изтегляне на всички добавки от това хранилище\?</string>
<string name="single_plugin_disabled" formatted="true">%s (Деактивиран)</string> <string name="single_plugin_disabled" formatted="true">%s (Деактивиран)</string>
<string name="tracks">Потоци</string> <string name="tracks">Потоци</string>
<string name="audio_tracks">Аудио потоци</string> <string name="audio_tracks">Аудио потоци</string>
@ -496,4 +496,5 @@
<string name="plugin_downloaded">Приставката е изтеглена</string> <string name="plugin_downloaded">Приставката е изтеглена</string>
<string name="delayed_update_notice">Приложението ще се актуализира при изход от него</string> <string name="delayed_update_notice">Приложението ще се актуализира при изход от него</string>
<string name="update_started">Започна Актуализация</string> <string name="update_started">Започна Актуализация</string>
<string name="action_remove_from_watched">Премахване от гледани</string>
</resources> </resources>

View file

@ -10,7 +10,7 @@
<string name="next_episode_time_min_format" formatted="true">%dm</string> <string name="next_episode_time_min_format" formatted="true">%dm</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="episode_poster_img_des">Episode Poster</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Main Poster</string>
<string name="home_next_random_img_des">Next Random</string> <string name="home_next_random_img_des">Next Random</string>
@ -20,7 +20,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Velocidade (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Velocidade (%.2fx)</string>
<string name="rated_format" formatted="true">Nota: %.1f</string> <string name="rated_format" formatted="true">Nota: %.1f</string>
<string name="new_update_format" formatted="true">Nova atualização encontrada!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Nova atualização encontrada!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -107,7 +108,7 @@
<string name="continue_watching">Continue Assistindo</string> <string name="continue_watching">Continue Assistindo</string>
<string name="action_remove_watching">Remover</string> <string name="action_remove_watching">Remover</string>
<string name="action_open_watching">Mais Info</string> <string name="action_open_watching">Mais Info</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Uma VPN pode ser necessária para esse fornecedor funcionar corretamente</string> <string name="vpn_might_be_needed">Uma VPN pode ser necessária para esse fornecedor funcionar corretamente</string>
<string name="vpn_torrent">Esse fornecedor é um torrent, uma VPN é recomendada</string> <string name="vpn_torrent">Esse fornecedor é um torrent, uma VPN é recomendada</string>
<string name="provider_info_meta">Metadados não são oferecidas pelo site, o carregamento do video pode falhar se ele não existir no site.</string> <string name="provider_info_meta">Metadados não são oferecidas pelo site, o carregamento do video pode falhar se ele não existir no site.</string>
@ -174,9 +175,7 @@
<string name="copy_link_toast">Link copiado para área de transferência</string> <string name="copy_link_toast">Link copiado para área de transferência</string>
<string name="play_episode_toast">Assistir Episódio</string> <string name="play_episode_toast">Assistir Episódio</string>
<string name="subs_default_reset_toast">Restaurar para o padrão</string> <string name="subs_default_reset_toast">Restaurar para o padrão</string>
<string name="acra_report_toast">Desculpe, a aplicação travou. Um relatório de erro anônimo será enviado para os <string name="acra_report_toast">Desculpe, a aplicação travou. Um relatório de erro anônimo será enviado para os desenvolvedores</string>
desenvolvedores
</string>
<string name="season">Temporada</string> <string name="season">Temporada</string>
<string name="no_season">Nenhuma Temporada</string> <string name="no_season">Nenhuma Temporada</string>
<string name="episode">Episódio</string> <string name="episode">Episódio</string>
@ -190,8 +189,10 @@
<string name="resume">Retomar</string> <string name="resume">Retomar</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Isso apagará %s permanentemente\nVocê tem certeza?</string> <string name="delete_message" formatted="true">Isso apagará %s permanentemente
<string name="resume_time_left" formatted="true">%dm\nsobrando</string> \nVocê tem certeza\?</string>
<string name="resume_time_left" formatted="true">%dm
\nsobrando</string>
<string name="status_ongoing">Em andamento</string> <string name="status_ongoing">Em andamento</string>
<string name="status_completed">Concluído</string> <string name="status_completed">Concluído</string>
<string name="status">Estado</string> <string name="status">Estado</string>
@ -221,8 +222,8 @@
<string name="movies_singular">Filme</string> <string name="movies_singular">Filme</string>
<string name="tv_series_singular">Série</string> <string name="tv_series_singular">Série</string>
<string name="cartoons_singular">Desenho Animado</string> <string name="cartoons_singular">Desenho Animado</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Documentário</string> <string name="documentaries_singular">Documentário</string>
<string name="asian_drama_singular">Drama Asiático</string> <string name="asian_drama_singular">Drama Asiático</string>
@ -277,22 +278,7 @@
<string name="resize_fill">Esticar</string> <string name="resize_fill">Esticar</string>
<string name="resize_zoom">Zoom</string> <string name="resize_zoom">Zoom</string>
<string name="legal_notice">Aviso Legal</string> <string name="legal_notice">Aviso Legal</string>
<string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application <string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application should be taken up with the actual file hosts and providers themselves as we are not affiliated with them. In case of copyright infringement, please directly contact the responsible parties or the streaming websites. The app is purely for educational and personal use. CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down. CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient, user-friendly interface. It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk.</string>
should be taken up with the actual file hosts and providers themselves as we are not affiliated with them.
In case of copyright infringement, please directly contact the responsible parties or the streaming websites.
The app is purely for educational and personal use.
CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down.
CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or
manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient,
user-friendly interface.
It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the
responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use
CloudStream 3 at your own risk.
</string>
<string name="category_general">Geral</string> <string name="category_general">Geral</string>
<string name="random_button_settings">Botão Aleatório</string> <string name="random_button_settings">Botão Aleatório</string>
<string name="random_button_settings_desc">Mostra o botão Aleatório na página inicial</string> <string name="random_button_settings_desc">Mostra o botão Aleatório na página inicial</string>
@ -337,7 +323,7 @@
<string name="upload_sync">Sincronizar</string> <string name="upload_sync">Sincronizar</string>
<string name="sync_score">Nota</string> <string name="sync_score">Nota</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s autenticado</string> <string name="authenticated_user" formatted="true">%s autenticado</string>
<string name="authenticated_user_fail" formatted="true">Falha em autenticar para %s</string> <string name="authenticated_user_fail" formatted="true">Falha em autenticar para %s</string>
@ -436,7 +422,7 @@
<string name="view_public_repositories_button">Ver repositórios da comunidade</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="view_public_repositories_button_short">Lista pública</string>
<string name="uppercase_all_subtitles">Todas as legendas em maiúsculas</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="download_all_plugins_from_repo">Transferir todos os plugins deste repositório\?</string>
<string name="single_plugin_disabled" formatted="true">%s (Desativado)</string> <string name="single_plugin_disabled" formatted="true">%s (Desativado)</string>
<string name="autoplay_next_settings">Reproduzir automaticamente próximo episódio</string> <string name="autoplay_next_settings">Reproduzir automaticamente próximo episódio</string>
<string name="autoplay_next_settings_des">Começa o próximo episódio quando o atual termina</string> <string name="autoplay_next_settings_des">Começa o próximo episódio quando o atual termina</string>

View file

@ -6,7 +6,7 @@
<string name="cast_format" formatted="true">Hrají: %s</string> <string name="cast_format" formatted="true">Hrají: %s</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Plakát</string> <string name="result_poster_img_des">Plakát</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">Plakát</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="episode_poster_img_des">Episode Poster</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Main Poster</string>
<string name="home_next_random_img_des">Next Random</string> <string name="home_next_random_img_des">Next Random</string>
@ -16,7 +16,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Rychlost (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Rychlost (%.2fx)</string>
<string name="rated_format" formatted="true">Hodnocení: %.1f</string> <string name="rated_format" formatted="true">Hodnocení: %.1f</string>
<string name="new_update_format" formatted="true">Nalezena nová aktualizace!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Nalezena nová aktualizace!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Výplň</string> <string name="filler" formatted="true">Výplň</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -102,7 +103,7 @@
<string name="continue_watching">Pokračovat ve sledování</string> <string name="continue_watching">Pokračovat ve sledování</string>
<string name="action_remove_watching">Odebrat</string> <string name="action_remove_watching">Odebrat</string>
<string name="action_open_watching">Další informace</string> <string name="action_open_watching">Další informace</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Aby tento poskytovatel fungoval správně, budete možná potřebovat VPN</string> <string name="vpn_might_be_needed">Aby tento poskytovatel fungoval správně, budete možná potřebovat VPN</string>
<string name="vpn_torrent">Tento poskytovatel je torrent, je doporučená VPN</string> <string name="vpn_torrent">Tento poskytovatel je torrent, je doporučená VPN</string>
<string name="provider_info_meta">Web neposkytnul žádná metadata, načítání videa selže, pokud na webu neexistuje.</string> <string name="provider_info_meta">Web neposkytnul žádná metadata, načítání videa selže, pokud na webu neexistuje.</string>
@ -127,21 +128,18 @@
<string name="double_tap_to_seek_settings">Dvojité klepnutí pro posun</string> <string name="double_tap_to_seek_settings">Dvojité klepnutí pro posun</string>
<string name="double_tap_to_pause_settings">Dvojité klepnutí pro pozastavení</string> <string name="double_tap_to_pause_settings">Dvojité klepnutí pro pozastavení</string>
<string name="double_tap_to_seek_amount_settings">Množství času k posunu</string> <string name="double_tap_to_seek_amount_settings">Množství času k posunu</string>
<string name="double_tap_to_seek_settings_des">Klepněte dvakrát vpravo nebo vlevo pro posun vpřed nebo vzad <string name="double_tap_to_seek_settings_des">Klepněte dvakrát vpravo nebo vlevo pro posun vpřed nebo vzad</string>
</string>
<string name="double_tap_to_pause_settings_des">Klepněte doprostřed pro pozastavení</string> <string name="double_tap_to_pause_settings_des">Klepněte doprostřed pro pozastavení</string>
<string name="use_system_brightness_settings">Použít systémový jas</string> <string name="use_system_brightness_settings">Použít systémový jas</string>
<string name="use_system_brightness_settings_des">V přehrávači použít systémov <string name="use_system_brightness_settings_des">V přehrávači použít systémov překrytí</string>
překrytí
</string>
<string name="episode_sync_settings">Aktualizovat postup sledování</string> <string name="episode_sync_settings">Aktualizovat postup sledování</string>
<string name="episode_sync_settings_des">Automaticky synchronizovat postup sledování současné epizody</string> <string name="episode_sync_settings_des">Automaticky synchronizovat postup sledování současné epizody</string>
<string name="restore_settings">Obnovit data ze zálohy</string> <string name="restore_settings">Obnovit data ze zálohy</string>
<string name="backup_settings">Zálohovat data</string> <string name="backup_settings">Zálohovat data</string>
<string name="restore_success">Načten soubor zálohy</string> <string name="restore_success">Načten soubor zálohy</string>
<string name="restore_failed_format" formatted="true">Nepodařilo se obnovit data ze soubory %s</string> <string name="restore_failed_format" formatted="true">Nepodařilo se obnovit data ze soubory %s</string>
<string name="backup_success">Data úspěšně uložena</string> <string name="backup_success">Data uložena</string>
<string name="backup_failed">Chybí oprávnění k úložišti, zkuste to prosím znovu</string> <string name="backup_failed">Chybí oprávnění k úložišti. Zkuste to prosím znovu.</string>
<string name="backup_failed_error_format">Chyba při zálohování %s</string> <string name="backup_failed_error_format">Chyba při zálohování %s</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="category_account">Účty</string> <string name="category_account">Účty</string>
@ -168,9 +166,7 @@
<string name="copy_link_toast">Odkaz zkopírován do schránky</string> <string name="copy_link_toast">Odkaz zkopírován do schránky</string>
<string name="play_episode_toast">Přehrát epizodu</string> <string name="play_episode_toast">Přehrát epizodu</string>
<string name="subs_default_reset_toast">Obnovit na výchozí hodnoty</string> <string name="subs_default_reset_toast">Obnovit na výchozí hodnoty</string>
<string name="acra_report_toast">Omlouváme se, aplikace spadla. Vývojářům bude odesláno anonymní hlášení <string name="acra_report_toast">Omlouváme se, aplikace spadla. Vývojářům bude odesláno anonymní hlášení o pádu</string>
o pádu
</string>
<string name="season">Sezóna</string> <string name="season">Sezóna</string>
<string name="no_season">Žádná sezóna</string> <string name="no_season">Žádná sezóna</string>
<string name="episode">Epizoda</string> <string name="episode">Epizoda</string>
@ -184,8 +180,10 @@
<string name="resume">Pokračovat</string> <string name="resume">Pokračovat</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Toto nevratně smaže %s\nJste si jisti?</string> <string name="delete_message" formatted="true">Toto nevratně smaže %s
<string name="resume_time_left" formatted="true">%dm\nzbývá</string> \nJste si jisti\?</string>
<string name="resume_time_left" formatted="true">%dm
\nzbývá</string>
<string name="status_ongoing">Probíhající</string> <string name="status_ongoing">Probíhající</string>
<string name="status_completed">Dokončena</string> <string name="status_completed">Dokončena</string>
<string name="status">Stav</string> <string name="status">Stav</string>
@ -213,8 +211,8 @@
<string name="movies_singular">Film</string> <string name="movies_singular">Film</string>
<string name="tv_series_singular">Seriál</string> <string name="tv_series_singular">Seriál</string>
<string name="cartoons_singular">Animovaný</string> <string name="cartoons_singular">Animovaný</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Dokument</string> <string name="documentaries_singular">Dokument</string>
<string name="asian_drama_singular">Asijské drama</string> <string name="asian_drama_singular">Asijské drama</string>
@ -254,33 +252,18 @@
<string name="video_buffer_length_settings">Délka vyrovnávací paměti videa</string> <string name="video_buffer_length_settings">Délka vyrovnávací paměti videa</string>
<string name="video_buffer_disk_settings">Mezipaměť videa na disku</string> <string name="video_buffer_disk_settings">Mezipaměť videa na disku</string>
<string name="video_buffer_clear_settings">Vymazat mezipamět videí a obrázků</string> <string name="video_buffer_clear_settings">Vymazat mezipamět videí a obrázků</string>
<string name="video_ram_description">Při nastavení příliš vysoké hodnoty způsobí náhodné pády. Neměňte, pokud máte málo paměti RAM, například u televize s Androidem nebo starého telefonu.</string> <string name="video_ram_description">Při nastavení příliš vysoké hodnoty na zařízeních s malou pamětí, jako je například Android TV, může způsobit pády.</string>
<string name="video_disk_description">Pokud ji nastavíte příliš vysoko, může způsobit problémy v systémech s malým úložným prostorem, například v zařízeních Android TV.</string> <string name="video_disk_description">Při nastavení příliš vysoké hodnoty na zařízeních s malým dostupným úložištěm, jako je například Android TV, může způsobit pády.</string>
<string name="dns_pref">DNS přes HTTPS</string> <string name="dns_pref">DNS přes HTTPS</string>
<string name="dns_pref_summary">Užitečné pro obcházení blokací ISP</string> <string name="dns_pref_summary">Užitečné pro obcházení blokací ISP</string>
<string name="download_path_pref">Cesta stahování</string> <string name="download_path_pref">Cesta stahování</string>
<string name="nginx_url_pref">URL serveru Nginx</string> <string name="nginx_url_pref">URL serveru NGINX</string>
<string name="display_subbed_dubbed_settings">Zobrazit dabované anime/anime s titulky</string> <string name="display_subbed_dubbed_settings">Zobrazit dabované anime/anime s titulky</string>
<string name="resize_fit">Vyplnit na obrazovku</string> <string name="resize_fit">Vyplnit na obrazovku</string>
<string name="resize_fill">Roztáhnout</string> <string name="resize_fill">Roztáhnout</string>
<string name="resize_zoom">Přiblížit</string> <string name="resize_zoom">Přiblížit</string>
<string name="legal_notice">Odmítnutí odpovědnosti</string> <string name="legal_notice">Odmítnutí odpovědnosti</string>
<string name="legal_notice_text" translatable="false">Jakékoli právní otázky týkající se obsahu této aplikace <string name="legal_notice_text" translatable="false">Jakékoli právní otázky týkající se obsahu této aplikace je třeba řešit se samotnými hostiteli a poskytovateli souborů, protože s nimi nejsme nijak spojeni. V případě porušení autorských práv se obraťte přímo na odpovědné strany nebo na webové stránky, na kterých se streamování odehrává. Aplikace je určena výhradně pro vzdělávací a osobní účely. CloudStream 3 v aplikaci nehostuje žádný obsah a nemá žádnou kontrolu nad tím, jaká média jsou v aplikaci umístěna nebo odstraněna. CloudStream 3 funguje jako jakýkoli jiný vyhledávač, například Google. Služba CloudStream 3 nehostuje, nenahrává ani nespravuje žádná videa, filmy ani obsah. Pouze vyhledává, agreguje a zobrazuje odkazy v pohodlném, uživatelsky přívětivém rozhraní. Pouze shromažďuje webové stránky třetích stran, které jsou veřejně přístupné prostřednictvím jakéhokoli běžného webového prohlížeče. Je odpovědností uživatele, aby se vyvaroval jakýchkoli akcí, které by mohly porušovat zákony platné v jeho lokalitě. Použijte CloudStream 3 na vlastní nebezpečí.</string>
je třeba řešit se samotnými hostiteli a poskytovateli souborů, protože s nimi nejsme nijak spojeni.
V případě porušení autorských práv se obraťte přímo na odpovědné strany nebo na webové stránky, na kterých se streamování odehrává.
Aplikace je určena výhradně pro vzdělávací a osobní účely.
CloudStream 3 v aplikaci nehostuje žádný obsah a nemá žádnou kontrolu nad tím, jaká média jsou v aplikaci umístěna nebo odstraněna.
CloudStream 3 funguje jako jakýkoli jiný vyhledávač, například Google. Služba CloudStream 3 nehostuje, nenahrává ani
nespravuje žádná videa, filmy ani obsah. Pouze vyhledává, agreguje a zobrazuje odkazy v pohodlném,
uživatelsky přívětivém rozhraní.
Pouze shromažďuje webové stránky třetích stran, které jsou veřejně přístupné prostřednictvím jakéhokoli běžného webového prohlížeče. Je
odpovědností uživatele, aby se vyvaroval jakýchkoli akcí, které by mohly porušovat zákony platné v jeho lokalitě. Použijte
CloudStream 3 na vlastní nebezpečí.
</string>
<string name="category_general">Obecné</string> <string name="category_general">Obecné</string>
<string name="random_button_settings">Náhodné tlačítko</string> <string name="random_button_settings">Náhodné tlačítko</string>
<string name="random_button_settings_desc">Zobrazit na domovské stránce náhodné tlačítko</string> <string name="random_button_settings_desc">Zobrazit na domovské stránce náhodné tlačítko</string>
@ -322,7 +305,7 @@
<string name="upload_sync">Synchronizovat</string> <string name="upload_sync">Synchronizovat</string>
<string name="sync_score">Hodnoceno</string> <string name="sync_score">Hodnoceno</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">Přihlášeno k %s</string> <string name="authenticated_user" formatted="true">Přihlášeno k %s</string>
<string name="authenticated_user_fail" formatted="true">Nepodařilo se přihlásit k %s</string> <string name="authenticated_user_fail" formatted="true">Nepodařilo se přihlásit k %s</string>
@ -337,10 +320,10 @@
<string name="subtitles_shadow">Stín</string> <string name="subtitles_shadow">Stín</string>
<string name="subtitles_raised">Vyvýšené</string> <string name="subtitles_raised">Vyvýšené</string>
<string name="subtitle_offset">Synch. titulky</string> <string name="subtitle_offset">Synch. titulky</string>
<string name="subtitle_offset_hint">1000ms</string> <string name="subtitle_offset_hint">1000 ms</string>
<string name="subtitle_offset_title">Zpoždění titulků</string> <string name="subtitle_offset_title">Zpoždění titulků</string>
<string name="subtitle_offset_extra_hint_later_format">Toto použijte, pokud jsou titulky zobrazeny o %dms dříve</string> <string name="subtitle_offset_extra_hint_later_format">Toto použijte, pokud jsou titulky zobrazeny o %d ms dříve</string>
<string name="subtitle_offset_extra_hint_before_format">Toto použijte, pokud jsou titulky zobrazeny o %dms později</string> <string name="subtitle_offset_extra_hint_before_format">Toto použijte, pokud jsou titulky zobrazeny o %d ms později</string>
<string name="subtitle_offset_extra_hint_none_format">Žádné zpoždění titulků</string> <string name="subtitle_offset_extra_hint_none_format">Žádné zpoždění titulků</string>
<!-- <!--
Example text (pangram) can optionally be translated; if you do, include all the letters in the alphabet, Example text (pangram) can optionally be translated; if you do, include all the letters in the alphabet,
@ -387,4 +370,169 @@
<string name="extras">Extra</string> <string name="extras">Extra</string>
<string name="action_mark_as_watched">Označit jako zhlédnuté</string> <string name="action_mark_as_watched">Označit jako zhlédnuté</string>
<string name="history">Historie</string> <string name="history">Historie</string>
<string name="next_episode_time_min_format" formatted="true">%dm</string>
<string name="play_with_app_name">Přehrát s CloudStream</string>
<string name="autoplay_next_settings_des">Přehrát další epizodu po skončení aktuální</string>
<string name="show_trailers_settings">Zobrazit trailery</string>
<string name="pref_filter_search_quality">Skrýt vybranou kvalitu videa ve výsledcích vyhledávání</string>
<string name="automatic_plugin_updates">Automatické aktualizace doplňků</string>
<string name="remove_site_pref">Odebrat web</string>
<string name="error_invalid_data">Neplatné údaje</string>
<string name="error">Chyba</string>
<string name="repository_name_hint">Název repozitáře</string>
<string name="plugin_loaded">Doplněk načten</string>
<string name="setup_extensions_subtext">Stáhněte si seznam webů, které chcete používat</string>
<string name="plugins_downloaded" formatted="true">Staženo: %d</string>
<string name="audio_tracks">Zvukové stopy</string>
<string name="video_tracks">Videostopy</string>
<string name="apply_on_restart">Použít při restartu</string>
<string name="safe_mode_title">Bezpečný režim povolen</string>
<string name="extension_size">Velikost</string>
<string name="extension_authors">Autoři</string>
<string name="repository_url_hint">Adresa URL repozitáře</string>
<string name="error_invalid_url">Neplatná adresa URL</string>
<string name="automatic_plugin_download_summary">Automaticky instalovat všechny dosud nenainstalované doplňky z přidaných repozitářů.</string>
<string name="others">Ostatní</string>
<string name="trailer">Trailer</string>
<string name="network_adress_example">Odkaz na stream</string>
<string name="skip_setup">Přeskočit nastavení</string>
<string name="add_repository">Přidat repozitář</string>
<string name="plugin_deleted">Doplněk odstraněn</string>
<string name="plugin_load_fail" formatted="true">Nepodařilo se načíst %s</string>
<string name="view_public_repositories_button_short">Veřejný seznam</string>
<string name="uppercase_all_subtitles">Velká písmena u všech titulků</string>
<string name="hls_playlist">Playlist HLS</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="player_settings_play_in_web">Webové vysílání videa</string>
<string name="app_not_found_error">Aplikace nenalezena</string>
<string name="skip_type_format" formatted="true">Přeskočit %s</string>
<string name="skip_type_op">Úvod</string>
<string name="skip_type_ed">Konec</string>
<string name="clipboard_too_large">Příliš mnoho textu. Nepodařilo se uložit do schránky.</string>
<string name="yes">Ano</string>
<string name="browser">Prohlížeč</string>
<string name="episodes_range">%d-%d</string>
<string name="library">Knihovna</string>
<string name="kitsu_settings">Zobrazit plakáty z Kitsu</string>
<string name="automatic_plugin_download">Automaticky stahovat doplňky</string>
<string name="redo_setup_process">Znovu provést proces nastavení</string>
<string name="apk_installer_settings">Instalátor APK</string>
<string name="episode_format" formatted="true">%d %s</string>
<string name="apk_installer_settings_des">Některé telefony nepodporují nový instalátor balíčků. Pokud se aktualizace nenainstalují, zkuste použít starší možnost.</string>
<string name="pref_category_cache">Mezipaměť</string>
<string name="next_episode_format" formatted="true">Epizoda %d bude vydána za</string>
<string name="next_episode_time_hour_format" formatted="true">%dh %dm</string>
<string name="play_livestream_button">Přehrát přímý přenos</string>
<string name="pref_category_extensions">Rozšíření</string>
<string name="pref_category_actions">Akce</string>
<string name="pref_category_looks">Vzhled</string>
<string name="pref_category_links">Odkazy</string>
<string name="pref_category_ui_features">Funkce</string>
<string name="example_site_name">MůjSuperWeb</string>
<string name="enable_nsfw_on_providers">Povolit NSFW u podporovaných poskytovatelů</string>
<string name="category_providers">Poskytovatelé</string>
<string name="crash_reporting_title">Hlášení pádů</string>
<string name="previous">Předchozí</string>
<string name="app_layout_subtext">Změnit vzhled aplikace tak, aby vám vyhovoval</string>
<string name="preferred_media_subtext">Co chcete vidět</string>
<string name="plugin_downloaded">Doplněk stažen</string>
<string name="is_adult">18+</string>
<string name="batch_download_start_format" formatted="true">Spuštěno stahování %d %s…</string>
<string name="blank_repo_message">CloudStream nemá ve výchozím nastavení nainstalované žádné weby. Stránky je třeba nainstalovat z úložišť.
\n
\nKvůli nesmyslnému podání stížnosti DMCA společností Sky UK Limited 🤮 nemůžeme v aplikaci propojit stránky repozitářů.
\n
\nPřipojte se k našemu Discordu nebo hledejte na internetu.</string>
<string name="plugins_disabled" formatted="true">Zakázáno: %d</string>
<string name="plugins_updated" formatted="true">Aktualizováno %d doplňků</string>
<string name="safe_mode_crash_info">Zobrazit informace o pádu</string>
<string name="extension_rating" formatted="true">Hodnocení: %s</string>
<string name="action_remove_from_watched">Odebrat ze zhlédnutých</string>
<string name="update_notification_installing">Instalace aktualizace aplikace…</string>
<string name="safe_mode_description">Všechna rozšíření byla vypnuta z důvodu pádu, abyste mohli najít to, které způsobuje potíže.</string>
<string name="extension_version">Verze</string>
<string name="player_pref">Preferovaný přehrávač videí</string>
<string name="extension_description">Popis</string>
<string name="extension_status">Stav</string>
<string name="extension_install_first">Nejprve nainstalujte rozšíření</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="skip_type_mixed_ed">Smíšený konec</string>
<string name="extension_language">Jazyk</string>
<string name="player_settings_play_in_app">Interní přehrávač</string>
<string name="skip_type_recap">Rekapitulace</string>
<string name="clear_history">Vymazat historii</string>
<string name="player_settings_play_in_browser">Webový prohlížeč</string>
<string name="all_languages_preference">Všechny jazyky</string>
<string name="skip_type_mixed_op">Smíšený úvod</string>
<string name="skip_type_creddits">Poděkování</string>
<string name="skip_type_intro">Znělka</string>
<string name="enable_skip_op_from_database_des">Zobrazit vyskakovací okna pro přeskočení úvodu/konce</string>
<string name="update_notification_downloading">Stahování aktualizace aplikace…</string>
<string name="confirm_exit_dialog">Opravdu chcete opustit aplikaci\?</string>
<string name="update_notification_failed">Nepodařilo se nainstalovat novou verzi aplikace</string>
<string name="apk_installer_legacy">Původní</string>
<string name="delayed_update_notice">Aplikace bude po ukončení aktualizována</string>
<string name="empty_library_no_accounts_message">Vypadá to, že vaše knihovna je prázdná :(
\nPřihlaste se k účtu v knihovně nebo přidejte pořady do místní knihovny</string>
<string name="select_library">Vybrat knihovnu</string>
<string name="sort_rating_desc">Hodnocení (od nejvyššího)</string>
<string name="sort_rating_asc">Hodnocení (od nejnižšího)</string>
<string name="sort_alphabetical_z">Abecedně (od Z do A)</string>
<string name="sort_by">Seřadit podle</string>
<string name="sort">Řazení</string>
<string name="empty_library_logged_in_message">Vypadá to, že tento seznam je prázdný, zkuste přepnout na jiný</string>
<string name="safe_mode_file">Nalezen soubor bezpečného režimu!
\nDo odebrání souboru nebudeme načítat žádná rozšíření.</string>
<string name="sort_updated_new">Aktualizováno (od nejnovějšího)</string>
<string name="sort_updated_old">Aktualizováno (od nejstaršího)</string>
<string name="sort_alphabetical_a">Abecedně (od A do Z)</string>
<string name="open_with">Otevřít pomocí</string>
<string name="pref_category_backup">Záloha</string>
<string name="pref_category_gestures">Gesta</string>
<string name="add_site_pref">Klonovat web</string>
<string name="add_site_summary">Přidat klon existujícího webu s jinou adresou URL</string>
<string name="example_site_url">example.com</string>
<string name="example_lang_name">Kód jazyka (cs)</string>
<string name="download_all_plugins_from_repo">Stáhnout všechny doplňky z tohoto repozitáře\?</string>
<string name="single_plugin_disabled" formatted="true">%s (zakázáno)</string>
<string name="tracks">Stopy</string>
<string name="nsfw">NSFW</string>
<string name="other_singular">Video</string>
<string name="pref_category_player_features">Funkce přehrávače</string>
<string name="pref_category_subtitles">Titulky</string>
<string name="pref_category_player_layout">Rozložení</string>
<string name="pref_category_defaults">Výchozí hodnoty</string>
<string name="apk_installer_package_installer">Instalátor balíčků</string>
<string name="pref_category_app_updates">Aktualizace aplikace</string>
<string name="setup_done">Hotovo</string>
<string name="extension_types">Podporováno</string>
<string name="season_format">%s %d%s</string>
<string name="live_singular">Živý přenos</string>
<string name="nsfw_singular">NSFW</string>
<string name="extensions">Rozšíření</string>
<string name="play_trailer_button">Přehrát trailer</string>
<string name="next_episode_time_day_format" formatted="true">%dd %dh %dm</string>
<string name="view_public_repositories_button">Zobrazit komunitní repozitáře</string>
<string name="update_started">Aktualizace zahájena</string>
<string name="stream">Stream</string>
<string name="autoplay_next_settings">Automaticky přehrát další epizodu</string>
<string name="livestreams">Živé přenosy</string>
<string name="subtitles_filter_lang">Filtrování podle preferovaného jazyka médií</string>
<string name="referer">Referent</string>
<string name="next">Další</string>
<string name="provider_languages_tip">Sledovat videa v těchto jazycích</string>
<string name="batch_download_finish_format" formatted="true">Staženo %d %s</string>
<string name="batch_download_nothing_to_download_format" formatted="true">Všechny %s jsou již staženy</string>
<string name="batch_download">Hromadné stahování</string>
<string name="plugin_singular">doplněk</string>
<string name="plugin">doplňků</string>
<string name="delete_repository_plugins">Tímto také odstraníte všechny doplňky repozitářů</string>
<string name="delete_repository">Odstranit repozitář</string>
<string name="plugins_not_downloaded" formatted="true">Nestaženo: %d</string>
<string name="no">Ne</string>
<string name="android_tv_interface_off_seek_settings">Skrytý přehrávač - doba hledání</string>
<string name="android_tv_interface_off_seek_settings_summary">Množství vyhledávané doby při skrytém přehrávači</string>
<string name="android_tv_interface_on_seek_settings">Zobrazený přehrávač - doba hledání</string>
<string name="pref_category_android_tv">Android TV</string>
<string name="android_tv_interface_on_seek_settings_summary">Množství vyhledávané doby při zobrazeném přehrávači</string>
</resources> </resources>

View file

@ -4,7 +4,7 @@
<string name="cast_format" formatted="true">Besetzung: %s</string> <string name="cast_format" formatted="true">Besetzung: %s</string>
<string name="next_episode_format" formatted="true">Episode %d wird veröffentlicht in</string> <string name="next_episode_format" formatted="true">Episode %d wird veröffentlicht in</string>
<string name="result_poster_img_des">Vorschaubild</string> <string name="result_poster_img_des">Vorschaubild</string>
<string name="search_poster_img_des">\@string/result_poster_img_des</string> <string name="search_poster_img_des">Vorschaubild</string>
<string name="subs_hold_to_reset_to_default">Halten, um auf die Standardeinstellungen zurückzusetzen</string> <string name="subs_hold_to_reset_to_default">Halten, um auf die Standardeinstellungen zurückzusetzen</string>
<string name="restore_failed_format" formatted="true">Wiederherstellung der Daten aus der Datei %s fehlgeschlagen</string> <string name="restore_failed_format" formatted="true">Wiederherstellung der Daten aus der Datei %s fehlgeschlagen</string>
<string name="backup_success">Daten erfolgreich gesichert</string> <string name="backup_success">Daten erfolgreich gesichert</string>
@ -17,7 +17,7 @@
<string name="skip_type_intro">Intro</string> <string name="skip_type_intro">Intro</string>
<string name="clear_history">Verlauf löschen</string> <string name="clear_history">Verlauf löschen</string>
<string name="history">Verlauf</string> <string name="history">Verlauf</string>
<string name="enable_skip_op_from_database_des">Überspringen Button für Openings/Endings anzeigen</string> <string name="enable_skip_op_from_database_des">Überspringen Knopf für Openings/Endings anzeigen</string>
<string name="clipboard_too_large">Zu viel Text. Kann nicht in der Zwischenablage gespeichert werden.</string> <string name="clipboard_too_large">Zu viel Text. Kann nicht in der Zwischenablage gespeichert werden.</string>
<string name="episode_poster_img_des">Episodenvorschaubild</string> <string name="episode_poster_img_des">Episodenvorschaubild</string>
<string name="home_main_poster_img_des">Medienvorschaubild</string> <string name="home_main_poster_img_des">Medienvorschaubild</string>
@ -228,8 +228,8 @@
<string name="movies_singular">Film</string> <string name="movies_singular">Film</string>
<string name="tv_series_singular">Serie</string> <string name="tv_series_singular">Serie</string>
<string name="cartoons_singular">Trickfilm</string> <string name="cartoons_singular">Trickfilm</string>
<string name="anime_singular">\@string/anime</string> <string name="anime_singular">Anime</string>
<string name="ova_singular">\@string/ova</string> <string name="ova_singular">OVA</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Dokumentation</string> <string name="documentaries_singular">Dokumentation</string>
<string name="asian_drama_singular">Asiatisches Drama</string> <string name="asian_drama_singular">Asiatisches Drama</string>
@ -487,4 +487,23 @@
<string name="apk_installer_package_installer">PackageInstaller</string> <string name="apk_installer_package_installer">PackageInstaller</string>
<string name="update_started">Aktualisierung gestartet</string> <string name="update_started">Aktualisierung gestartet</string>
<string name="delayed_update_notice">Die Anwendung wird beim Beenden aktualisiert</string> <string name="delayed_update_notice">Die Anwendung wird beim Beenden aktualisiert</string>
<string name="plugin_downloaded">Das Plugin wurde heruntergeladen</string>
<string name="action_remove_from_watched">Von geschaut entfernen</string>
<string name="library">Bibliothek</string>
<string name="browser">Browser</string>
<string name="sort_by">Sortieren nach</string>
<string name="sort">Sortieren</string>
<string name="sort_rating_desc">Bewertung (gut bis schlecht)</string>
<string name="sort_rating_asc">Bewertung (schlecht bis gut)</string>
<string name="sort_updated_new">Aktualisiert (neu bis alt)</string>
<string name="sort_updated_old">Aktualisiert (alt bis neu)</string>
<string name="sort_alphabetical_a">Alphabetisch (A bis Z)</string>
<string name="sort_alphabetical_z">Alphabetisch (Z bis A)</string>
<string name="select_library">Bibliothek auswählen</string>
<string name="open_with">Öffnen mit</string>
<string name="empty_library_no_accounts_message">Sieht aus, als wäre deine Bibliothek leer :(
\nMelde dich mit einem Bibliothekskonto an oder füge Titel zu deiner lokalen Bibliothek hinzu</string>
<string name="empty_library_logged_in_message">Diese Liste scheint leer zu sein. Versuche, zu einer anderen Liste zu wechseln.</string>
<string name="safe_mode_file">Datei für abgesicherten Modus gefunden!
\nBeim Start werden keine Erweiterungen geladen, bis die Datei entfernt wird.</string>
</resources> </resources>

View file

@ -159,7 +159,8 @@
<string name="resume">Συνέχιση</string> <string name="resume">Συνέχιση</string>
<string name="delete_message" formatted="true">Αυτό θα διαγράψει μόνιμα το %s <string name="delete_message" formatted="true">Αυτό θα διαγράψει μόνιμα το %s
\nΕίστε σίγουροι πως θέλετε να προχωρήσετε;</string> \nΕίστε σίγουροι πως θέλετε να προχωρήσετε;</string>
<string name="resume_time_left" formatted="true">%dm\nαπομένουν</string> <string name="resume_time_left" formatted="true">%dm
\nαπομένουν</string>
<string name="status_ongoing">Σε εξέλιξη</string> <string name="status_ongoing">Σε εξέλιξη</string>
<string name="status">Κατάσταση</string> <string name="status">Κατάσταση</string>
<string name="year">Έτος</string> <string name="year">Έτος</string>
@ -313,7 +314,7 @@
<string name="crash_reporting_title">Αναφορά κατάρρευσης</string> <string name="crash_reporting_title">Αναφορά κατάρρευσης</string>
<string name="preferred_media_subtext">Τι θα θέλατε να δείτε</string> <string name="preferred_media_subtext">Τι θα θέλατε να δείτε</string>
<string name="setup_done">Έγινε</string> <string name="setup_done">Έγινε</string>
<string name="extensions">Πρόσθετα</string> <string name="extensions">Extensions</string>
<string name="add_repository">Προσθήκη αποθετηρίου</string> <string name="add_repository">Προσθήκη αποθετηρίου</string>
<string name="repository_name_hint">Όνομα αποθετηρίου</string> <string name="repository_name_hint">Όνομα αποθετηρίου</string>
<string name="repository_url_hint">Σύνδεσμος αποθετηρίου</string> <string name="repository_url_hint">Σύνδεσμος αποθετηρίου</string>
@ -489,4 +490,22 @@
<string name="plugin_downloaded">Το πρόσθετο κατέβει</string> <string name="plugin_downloaded">Το πρόσθετο κατέβει</string>
<string name="update_started">Ενημέρωση ξεκίνησε</string> <string name="update_started">Ενημέρωση ξεκίνησε</string>
<string name="delayed_update_notice">Η εφαρμογή θα ενημερωθεί κατά την έξοδο</string> <string name="delayed_update_notice">Η εφαρμογή θα ενημερωθεί κατά την έξοδο</string>
<string name="sort_alphabetical_z">Αλφαβητικά (Ω προς Α)</string>
<string name="sort">Ταξινόμηση</string>
<string name="sort_rating_asc">Κριτική (Χαμηλή προς Υψηλή)</string>
<string name="sort_updated_new">Ενημερωμένο (Καινούριο προς παλιό)</string>
<string name="sort_updated_old">Ενημερωμένο (Παλιό προς Καινούργιο)</string>
<string name="library">Βιβλιοθήκη</string>
<string name="sort_rating_desc">Κριτική (Υψηλή προς χαμηλή)</string>
<string name="sort_by">Ταξινόμηση με βάση</string>
<string name="sort_alphabetical_a">Αλφαβητικά (Α προς Ω)</string>
<string name="select_library">Διάλεξε βιβλιοθήκη</string>
<string name="empty_library_logged_in_message">Φαίνεται πως η λίστα είναι άδεια, δοκίμασε να μεταβείς σε μία άλλη</string>
<string name="action_remove_from_watched">Αφαίρεση από παρακολουθημένα</string>
<string name="browser">Περιηγητής</string>
<string name="open_with">Άνοιγμα με</string>
<string name="empty_library_no_accounts_message">Φαίνεται πως η βιβλιοθήκη σου είναι άδεια :(
\nΣυνδέσου σε έναν λογαριασμό που έχει βιβλιοθήκη, ή πρόσθεσε σειρές στην τοπική βιβλιοθήκη σου</string>
<string name="safe_mode_file">Βρέθηκε αρχείο Ασφαλούς Λειτουργίας!
\nΔεν πρόκειται να φορτωθούν extensions κατά το ξεκίνημα μέχρι να διαγραφεί το αρχείο.</string>
</resources> </resources>

View file

@ -86,7 +86,7 @@
<string name="episode_action_reload_links">Recargar enlaces</string> <string name="episode_action_reload_links">Recargar enlaces</string>
<string name="sync_total_episodes_none">/\?\?</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="delete_message" formatted="true">Esto eliminará %s permanentemente <string name="delete_message" formatted="true">Esto eliminará %s permanentemente
\nEstá seguro\?</string> \nEstá seguro\?</string>
<string name="confirm_exit_dialog">Está seguro que quiere salir\?</string> <string name="confirm_exit_dialog">Está seguro que quiere salir\?</string>
<string name="popup_resume_download">Continuar Descarga</string> <string name="popup_resume_download">Continuar Descarga</string>
@ -94,7 +94,7 @@
<string name="home_main_poster_img_des">Poster Principal</string> <string name="home_main_poster_img_des">Poster Principal</string>
<string name="app_language">Idioma de la aplicación</string> <string name="app_language">Idioma de la aplicación</string>
<string name="provider_languages_tip">Ver videos en estos idiomas</string> <string name="provider_languages_tip">Ver videos en estos idiomas</string>
<string name="search_poster_img_des">\@string/result_poster_img_des</string> <string name="search_poster_img_des">Cartel</string>
<string name="home_next_random_img_des">Siguiente al azar</string> <string name="home_next_random_img_des">Siguiente al azar</string>
<string name="all_languages_preference">Todos los Idiomas</string> <string name="all_languages_preference">Todos los Idiomas</string>
<string name="go_back_img_des">Volver</string> <string name="go_back_img_des">Volver</string>
@ -488,4 +488,27 @@
<string name="delayed_update_notice">La aplicación se actualizará al salir</string> <string name="delayed_update_notice">La aplicación se actualizará al salir</string>
<string name="update_started">Actualización iniciada</string> <string name="update_started">Actualización iniciada</string>
<string name="plugin_downloaded">Complemento descargado</string> <string name="plugin_downloaded">Complemento descargado</string>
<string name="action_remove_from_watched">Quitar de visto</string>
<string name="sort_by">Ordenar por</string>
<string name="sort">Ordenar</string>
<string name="sort_rating_desc">Valoración (más a menos)</string>
<string name="sort_rating_asc">Valoración (menos a más)</string>
<string name="sort_updated_new">Actualizado (nuevo a viejo)</string>
<string name="sort_updated_old">Actualizado (viejo a nuevo)</string>
<string name="sort_alphabetical_a">Alfabéticamente (A a Z)</string>
<string name="browser">Navegador</string>
<string name="library">Biblioteca</string>
<string name="empty_library_logged_in_message">Parece que esta lista está vacía, intenta cambiar a otra</string>
<string name="sort_alphabetical_z">Alfabéticamente (Z a A)</string>
<string name="select_library">Seleccionar biblioteca</string>
<string name="open_with">Abrir con</string>
<string name="empty_library_no_accounts_message">Parece que tu biblioteca está vacía :(
\nInicia sesión en una cuenta de biblioteca o añade series desde tu biblioteca local</string>
<string name="safe_mode_file">¡Se encontró un archivo en modo seguro!
\nNo cargar ninguna extensión al inicio hasta que se elimine el archivo.</string>
<string name="android_tv_interface_on_seek_settings">Jugadora mostrada - buscar cantidad</string>
<string name="android_tv_interface_off_seek_settings">Jugadora oculta - buscar cantidad</string>
<string name="pref_category_android_tv">Android TV</string>
<string name="android_tv_interface_on_seek_settings_summary">La cantidad de búsqueda utilizada cuando la jugadora es visible</string>
<string name="android_tv_interface_off_seek_settings_summary">La cantidad de búsqueda utilizada cuando el jugador está oculto</string>
</resources> </resources>

View file

@ -4,7 +4,11 @@
<string name="pause">مکث</string> <string name="pause">مکث</string>
<string name="queued">در صف</string> <string name="queued">در صف</string>
<string name="download">بارگیری</string> <string name="download">بارگیری</string>
<string name="downloading">در حال بارگیری</string>
<string name="download_done">اتمام بارگیری</string>
<string name="stream">پخش آنلاین</string>
<string name="download_failed">بارگیری ناموفق بود</string> <string name="download_failed">بارگیری ناموفق بود</string>
<string name="filter_bookmarks">فیلتر کردن علاقه مندی ها</string>
<string name="search">جست‌وجو</string> <string name="search">جست‌وجو</string>
<string name="resize_fit">اندازه‌کردن</string> <string name="resize_fit">اندازه‌کردن</string>
<string name="resize_fill">پر کردن</string> <string name="resize_fill">پر کردن</string>
@ -19,4 +23,14 @@
<string name="none">هیچ‌کدام</string> <string name="none">هیچ‌کدام</string>
<string name="title">عنوان</string> <string name="title">عنوان</string>
<string name="history">تاریخچه</string> <string name="history">تاریخچه</string>
<string name="search_poster_img_des">پوستر</string>
<string name="result_poster_img_des">پوستر</string>
<string name="episode_poster_img_des">پوستر قسمت</string>
<string name="next_episode_time_day_format" formatted="true">%dروز %dساعت %dدقیقه</string>
<string name="app_dub_sub_episode_text_format" formatted="true">%s قسمت %d</string>
<string name="cast_format" formatted="true">بازیگران: %s</string>
<string name="next_episode_format" formatted="true">قسمت %d پخش خواهد شد</string>
<string name="next_episode_time_hour_format" formatted="true">%dساعت %dدقیقه</string>
<string name="next_episode_time_min_format" formatted="true">%dدقیقه</string>
<string name="home_main_poster_img_des">پوستر اصلی</string>
</resources> </resources>

View file

@ -82,7 +82,8 @@
<string name="delete">Supprimer</string> <string name="delete">Supprimer</string>
<string name="pause">Pause</string> <string name="pause">Pause</string>
<string name="resume">Reprendre</string> <string name="resume">Reprendre</string>
<string name="delete_message">Cela va supprimer définitivement %s\nÊtes-vous sûr ?</string> <string name="delete_message">Cela va supprimer définitivement %s
\nÊtes-vous sûr \?</string>
<string name="status_ongoing">En cours</string> <string name="status_ongoing">En cours</string>
<string name="status_completed">Terminé</string> <string name="status_completed">Terminé</string>
<string name="status">Statut</string> <string name="status">Statut</string>
@ -239,7 +240,7 @@
<string name="continue_watching">Continuer à regarder</string> <string name="continue_watching">Continuer à regarder</string>
<string name="action_remove_watching">Retirer</string> <string name="action_remove_watching">Retirer</string>
<string name="action_open_watching">Plus d\'informations</string> <string name="action_open_watching">Plus d\'informations</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Un VPN peut être nécessaire pour que ce fournisseur fonctionne correctement</string> <string name="vpn_might_be_needed">Un VPN peut être nécessaire pour que ce fournisseur fonctionne correctement</string>
<string name="vpn_torrent">Ce fournisseur est un torrent, un VPN est recommandé</string> <string name="vpn_torrent">Ce fournisseur est un torrent, un VPN est recommandé</string>
<string name="provider_info_meta">Les métadonnées ne sont pas fournies par le site, le chargement de la vidéo échouera si elles n\'existent pas sur le site.</string> <string name="provider_info_meta">Les métadonnées ne sont pas fournies par le site, le chargement de la vidéo échouera si elles n\'existent pas sur le site.</string>
@ -269,9 +270,7 @@
<string name="double_tap_to_seek_settings_des">Tapez deux fois sur le côté droit ou gauche pour aller en avant ou en arrière</string> <string name="double_tap_to_seek_settings_des">Tapez deux fois sur le côté droit ou gauche pour aller en avant ou en arrière</string>
<string name="double_tap_to_pause_settings_des">Tapez au milieu pour mettre en pause</string> <string name="double_tap_to_pause_settings_des">Tapez au milieu pour mettre en pause</string>
<string name="use_system_brightness_settings">Utiliser la luminosité du système</string> <string name="use_system_brightness_settings">Utiliser la luminosité du système</string>
<string name="use_system_brightness_settings_des">Utiliser la luminosité du système dans le lecteur d\'applications au lieu du <string name="use_system_brightness_settings_des">Utiliser la luminosité du système dans le lecteur d\'applications au lieu du sombre</string>
sombre
</string>
<string name="episode_sync_settings">Mise à jour de la progression de la veille</string> <string name="episode_sync_settings">Mise à jour de la progression de la veille</string>
<string name="episode_sync_settings_des">Synchronisation automatique de la progression de votre épisode en cours</string> <string name="episode_sync_settings_des">Synchronisation automatique de la progression de votre épisode en cours</string>
<string name="restore_settings">Restaurer des données à partir d\'une sauvegarde</string> <string name="restore_settings">Restaurer des données à partir d\'une sauvegarde</string>
@ -490,4 +489,5 @@
<string name="update_started">Mise à jour commencée</string> <string name="update_started">Mise à jour commencée</string>
<string name="delayed_update_notice">L\'application sera mise à jour dès la fin de la session</string> <string name="delayed_update_notice">L\'application sera mise à jour dès la fin de la session</string>
<string name="plugin_downloaded">Plugin Téléchargé</string> <string name="plugin_downloaded">Plugin Téléchargé</string>
<string name="action_remove_from_watched">Retirer de la vue</string>
</resources> </resources>

View file

@ -2,7 +2,8 @@
<!--https://newbedev.com/concatenate-multiple-strings-in-xml--><resources> <!--https://newbedev.com/concatenate-multiple-strings-in-xml--><resources>
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">रफ्तार (%.2fx)</string> <string name="player_speed_text_format" formatted="true">रफ्तार (%.2fx)</string>
<string name="new_update_format" formatted="true">नया अपडेट आया है!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">नया अपडेट आया है!
\n%s -&gt; %s</string>
<string name="title_home">होम</string> <string name="title_home">होम</string>
<string name="title_search">खोजें</string> <string name="title_search">खोजें</string>
<string name="title_downloads">डाउनलोड</string> <string name="title_downloads">डाउनलोड</string>
@ -69,8 +70,7 @@
<string name="eigengraumode_settings_des">प्लेयर में वीडियो की रफ्तार धिमी या तेज़ करता है</string> <string name="eigengraumode_settings_des">प्लेयर में वीडियो की रफ्तार धिमी या तेज़ करता है</string>
<string name="swipe_to_seek_settings_des">दाएं या बाएं तरफ स्वाइप करने से वीडियो को आगे पीछे करता है</string> <string name="swipe_to_seek_settings_des">दाएं या बाएं तरफ स्वाइप करने से वीडियो को आगे पीछे करता है</string>
<string name="swipe_to_change_settings_des">दाएं तरफ या बाएं तरफ स्वाइप करने से रोशिनी और आवाज़ को ऊपर नीचे करता है</string> <string name="swipe_to_change_settings_des">दाएं तरफ या बाएं तरफ स्वाइप करने से रोशिनी और आवाज़ को ऊपर नीचे करता है</string>
<string name="double_tap_to_seek_settings_des">दो बार दाएं या बाएं तरफ दबाने से वीडियो को आगे या पीछे करा जा सकता है <string name="double_tap_to_seek_settings_des">दो बार दाएं या बाएं तरफ दबाने से वीडियो को आगे या पीछे करा जा सकता है</string>
</string>
<string name="search">खोजें</string> <string name="search">खोजें</string>
<string name="settings_info">जानकारी</string> <string name="settings_info">जानकारी</string>
<string name="advanced_search_des">नतीजों को सूत्रों के हिसाब से बांटकर दिखता है</string> <string name="advanced_search_des">नतीजों को सूत्रों के हिसाब से बांटकर दिखता है</string>
@ -88,13 +88,13 @@
<string name="no_links_found_toast">कोई लिंक नही मिले</string> <string name="no_links_found_toast">कोई लिंक नही मिले</string>
<string name="copy_link_toast">लिंक को क्लिपबोर्ड पे कॉपी करदिया गया</string> <string name="copy_link_toast">लिंक को क्लिपबोर्ड पे कॉपी करदिया गया</string>
<string name="play_episode_toast">चलाये</string> <string name="play_episode_toast">चलाये</string>
<string name="acra_report_toast">असुविधा के लिए खेद है, यह एप्प क्रैश हो गया है । एक गुमनाम रिपोर्ट निर्माताओं को भेज दी गयी है । <string name="acra_report_toast">असुविधा के लिए खेद है, यह एप्प क्रैश हो गया है । एक गुमनाम रिपोर्ट निर्माताओं को भेज दी गयी है ।</string>
</string>
<string name="delete_file">फ़ाइल डिलीट करें</string> <string name="delete_file">फ़ाइल डिलीट करें</string>
<string name="delete">डिलीट</string> <string name="delete">डिलीट</string>
<string name="pause">रोके</string> <string name="pause">रोके</string>
<string name="resume">वापिस चलाये</string> <string name="resume">वापिस चलाये</string>
<string name="delete_message">एज इस चीज़ को हमेशा के लिए नष्ट कर देगा %s\nक्या आपका निर्णय निश्चित है ?</string> <string name="delete_message">एज इस चीज़ को हमेशा के लिए नष्ट कर देगा %s
\nक्या आपका निर्णय निश्चित है \?</string>
<string name="status_ongoing">अभी चालू है</string> <string name="status_ongoing">अभी चालू है</string>
<string name="status_completed">खत्म हो गया है</string> <string name="status_completed">खत्म हो गया है</string>
<string name="status">स्तिथि</string> <string name="status">स्तिथि</string>
@ -132,8 +132,8 @@
<string name="dns_pref_summary">ISP ब्लॉक से छुटकारा पाएं</string> <string name="dns_pref_summary">ISP ब्लॉक से छुटकारा पाएं</string>
<string name="provider_lang_settings">सूत्र की भाषाएं</string> <string name="provider_lang_settings">सूत्र की भाषाएं</string>
<string name="app_layout">ऐप का लेआउट</string> <string name="app_layout">ऐप का लेआउट</string>
<string name="preferred_media_settings">पसंदीदा मीडिया </string> <string name="preferred_media_settings">पसंदीदा मीडिया</string>
<string name="download_path_pref"> डाउनलोड करने का मार्ग</string> <string name="download_path_pref">डाउनलोड करने का मार्ग</string>
<string name="display_subbed_dubbed_settings">Dubbed या Subbed Anime दिखाये</string> <string name="display_subbed_dubbed_settings">Dubbed या Subbed Anime दिखाये</string>
<string name="tv_layout">टीवी लेआउट</string> <string name="tv_layout">टीवी लेआउट</string>
<string name="phone_layout">फ़ोन लेआउट</string> <string name="phone_layout">फ़ोन लेआउट</string>

View file

@ -19,7 +19,7 @@
<string name="next_episode_time_min_format" formatted="true">%dm</string> <string name="next_episode_time_min_format" formatted="true">%dm</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">Poster</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="episode_poster_img_des">Episode Poster</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Main Poster</string>
<string name="home_next_random_img_des">Next Random</string> <string name="home_next_random_img_des">Next Random</string>
@ -29,7 +29,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Brzina (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Brzina (%.2fx)</string>
<string name="rated_format" formatted="true">Ocijenjeno: %.1f</string> <string name="rated_format" formatted="true">Ocijenjeno: %.1f</string>
<string name="new_update_format" formatted="true">Pronađeno novo ažuriranje!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Pronađeno novo ažuriranje!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Umetak</string> <string name="filler" formatted="true">Umetak</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -118,7 +119,7 @@
<string name="continue_watching">Nastavite s gledanjem</string> <string name="continue_watching">Nastavite s gledanjem</string>
<string name="action_remove_watching">Makni</string> <string name="action_remove_watching">Makni</string>
<string name="action_open_watching">Više informacija</string> <string name="action_open_watching">Više informacija</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Za ispravan rad ovog pružatelja usluga može biti potreban VPN</string> <string name="vpn_might_be_needed">Za ispravan rad ovog pružatelja usluga može biti potreban VPN</string>
<string name="vpn_torrent">Ovaj pružatelj usluga je torrent, preporučuje se VPN</string> <string name="vpn_torrent">Ovaj pružatelj usluga je torrent, preporučuje se VPN</string>
<string name="provider_info_meta">Stranica ne daje metapodatke, učitavanje videozapisa neće uspjeti ako ne postoji na stranici.</string> <string name="provider_info_meta">Stranica ne daje metapodatke, učitavanje videozapisa neće uspjeti ako ne postoji na stranici.</string>
@ -145,13 +146,10 @@
<string name="double_tap_to_seek_settings">Dodirni dvaput za traženje</string> <string name="double_tap_to_seek_settings">Dodirni dvaput za traženje</string>
<string name="double_tap_to_pause_settings">Dodirni dvaput za pauziranje</string> <string name="double_tap_to_pause_settings">Dodirni dvaput za pauziranje</string>
<string name="double_tap_to_seek_amount_settings">Iznos preskakanja u playeru</string> <string name="double_tap_to_seek_amount_settings">Iznos preskakanja u playeru</string>
<string name="double_tap_to_seek_settings_des">Dvaput dodirni desnu ili lijevu stranu ekrana za pomicanje naprijed ili natrag <string name="double_tap_to_seek_settings_des">Dvaput dodirni desnu ili lijevu stranu ekrana za pomicanje naprijed ili natrag</string>
</string>
<string name="double_tap_to_pause_settings_des">Dodirni u sredinu zaslona za pauziranje</string> <string name="double_tap_to_pause_settings_des">Dodirni u sredinu zaslona za pauziranje</string>
<string name="use_system_brightness_settings">Koristi svijetlinu u sustavu</string> <string name="use_system_brightness_settings">Koristi svijetlinu u sustavu</string>
<string name="use_system_brightness_settings_des">Koristi svjetlinu sustava u playeru aplikacija umjesto tamnog <string name="use_system_brightness_settings_des">Koristi svjetlinu sustava u playeru aplikacija umjesto tamnog preklopa</string>
preklopa
</string>
<string name="episode_sync_settings">Ažuriraj napredak gledanja</string> <string name="episode_sync_settings">Ažuriraj napredak gledanja</string>
<string name="episode_sync_settings_des">Automatski sinkroniziraj svoj trenutni napredak u epizodi</string> <string name="episode_sync_settings_des">Automatski sinkroniziraj svoj trenutni napredak u epizodi</string>
<string name="restore_settings">Vraćanje podataka iz sigurnosne kopije</string> <string name="restore_settings">Vraćanje podataka iz sigurnosne kopije</string>
@ -190,8 +188,7 @@
<string name="copy_link_toast">Veza je kopirana u međuspremnik</string> <string name="copy_link_toast">Veza je kopirana u međuspremnik</string>
<string name="play_episode_toast">Pokreni epizodu</string> <string name="play_episode_toast">Pokreni epizodu</string>
<string name="subs_default_reset_toast">Vrati na zadanu vrijednost</string> <string name="subs_default_reset_toast">Vrati na zadanu vrijednost</string>
<string name="acra_report_toast">Nažalost, aplikacija se srušila. Anonimno izvješće o bugu bit će poslano developerima <string name="acra_report_toast">Nažalost, aplikacija se srušila. Anonimno izvješće o bugu bit će poslano developerima</string>
</string>
<string name="season">Sezona</string> <string name="season">Sezona</string>
<string name="no_season">Nema sezone</string> <string name="no_season">Nema sezone</string>
<string name="episode">Epizoda</string> <string name="episode">Epizoda</string>
@ -207,8 +204,10 @@
<string name="resume">Nastavi</string> <string name="resume">Nastavi</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Ovo će trajno izbrisati %s\nJeste li sigurni?</string> <string name="delete_message" formatted="true">Ovo će trajno izbrisati %s
<string name="resume_time_left" formatted="true">%dm\npreostalo</string> \nJeste li sigurni\?</string>
<string name="resume_time_left" formatted="true">%dm
\npreostalo</string>
<string name="status_ongoing">U tijeku</string> <string name="status_ongoing">U tijeku</string>
<string name="status_completed">Završeno</string> <string name="status_completed">Završeno</string>
<string name="status">Status</string> <string name="status">Status</string>
@ -239,8 +238,8 @@
<string name="movies_singular">Film</string> <string name="movies_singular">Film</string>
<string name="tv_series_singular">Serija</string> <string name="tv_series_singular">Serija</string>
<string name="cartoons_singular">Crtić</string> <string name="cartoons_singular">Crtić</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Dokumentarac</string> <string name="documentaries_singular">Dokumentarac</string>
<string name="asian_drama_singular">Azijska drama</string> <string name="asian_drama_singular">Azijska drama</string>
@ -297,22 +296,7 @@
<string name="resize_fill">Rastegni</string> <string name="resize_fill">Rastegni</string>
<string name="resize_zoom">Zoom</string> <string name="resize_zoom">Zoom</string>
<string name="legal_notice">Obavijest</string> <string name="legal_notice">Obavijest</string>
<string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application <string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application should be taken up with the actual file hosts and providers themselves as we are not affiliated with them. In case of copyright infringement, please directly contact the responsible parties or the streaming websites. The app is purely for educational and personal use. CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down. CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient, user-friendly interface. It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk.</string>
should be taken up with the actual file hosts and providers themselves as we are not affiliated with them.
In case of copyright infringement, please directly contact the responsible parties or the streaming websites.
The app is purely for educational and personal use.
CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down.
CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or
manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient,
user-friendly interface.
It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the
responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use
CloudStream 3 at your own risk.
</string>
<string name="category_general">Općenito</string> <string name="category_general">Općenito</string>
<string name="random_button_settings">Random gumb</string> <string name="random_button_settings">Random gumb</string>
<string name="random_button_settings_desc">Prikaži random gumb na početnoj stranici</string> <string name="random_button_settings_desc">Prikaži random gumb na početnoj stranici</string>
@ -351,7 +335,7 @@
<string name="upload_sync">Sinkroniziraj</string> <string name="upload_sync">Sinkroniziraj</string>
<string name="sync_score">Ocijenjeno</string> <string name="sync_score">Ocijenjeno</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">Ovjereno%s</string> <string name="authenticated_user" formatted="true">Ovjereno%s</string>
<string name="authenticated_user_fail" formatted="true">Nije moguće prijaviti se na %s</string> <string name="authenticated_user_fail" formatted="true">Nije moguće prijaviti se na %s</string>
@ -457,7 +441,7 @@
<string name="view_public_repositories_button">Pregledajte repozitorije zajednice</string> <string name="view_public_repositories_button">Pregledajte repozitorije zajednice</string>
<string name="view_public_repositories_button_short">Javni popis</string> <string name="view_public_repositories_button_short">Javni popis</string>
<string name="uppercase_all_subtitles">Svi titlovi pisani velikim slovima</string> <string name="uppercase_all_subtitles">Svi titlovi pisani velikim slovima</string>
<string name="download_all_plugins_from_repo">Preuzeti sve dodatke iz ovog repozitorija?</string> <string name="download_all_plugins_from_repo">Preuzeti sve dodatke iz ovog repozitorija\?</string>
<string name="single_plugin_disabled" formatted="true">%s (Onemogućeno)</string> <string name="single_plugin_disabled" formatted="true">%s (Onemogućeno)</string>
<string name="tracks">Zapis</string> <string name="tracks">Zapis</string>
<string name="audio_tracks">Audio zapis</string> <string name="audio_tracks">Audio zapis</string>
@ -529,4 +513,22 @@
<string name="update_started">Aktualiziranje započeto</string> <string name="update_started">Aktualiziranje započeto</string>
<string name="delayed_update_notice">Program če se aktualizirati tijekom zatvaranja programa</string> <string name="delayed_update_notice">Program če se aktualizirati tijekom zatvaranja programa</string>
<string name="plugin_downloaded">Dodatak preuzet</string> <string name="plugin_downloaded">Dodatak preuzet</string>
<string name="action_remove_from_watched">Ukloni iz pogledanog</string>
<string name="browser">Preglednik</string>
<string name="library">Biblioteka</string>
<string name="sort_rating_desc">Ocjena (Veća do manje)</string>
<string name="sort_by">Sortiraj prema</string>
<string name="sort">Sortiraj</string>
<string name="sort_rating_asc">Ocjena (Manja do veće)</string>
<string name="sort_updated_new">Ažurirano (Od novog do starog)</string>
<string name="sort_updated_old">Ažurirano (Od starog do novog)</string>
<string name="sort_alphabetical_a">Abecedno (A do Ž)</string>
<string name="sort_alphabetical_z">Abecedno (Ž do A)</string>
<string name="select_library">Odaberite biblioteku</string>
<string name="open_with">Otvori sa</string>
<string name="empty_library_no_accounts_message">Čini se da vam je biblioteka prazna :(
\nPrijavite se na račun biblioteke ili dodajte serije u svoju lokalnu biblioteku</string>
<string name="empty_library_logged_in_message">Čini se da je ova lista prazna, pokušajte se prebaciti na drugu</string>
<string name="safe_mode_file">Pronađena datoteka sigurnog načina rada!
\nNe učitavaju se ekstenzije pri pokretanju dok se datoteka ne ukloni.</string>
</resources> </resources>

View file

@ -5,7 +5,7 @@
<string name="cast_format" formatted="true">Pemeran: %s</string> <string name="cast_format" formatted="true">Pemeran: %s</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">Poster</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="episode_poster_img_des">Episode Poster</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Main Poster</string>
<string name="home_next_random_img_des">Next Random</string> <string name="home_next_random_img_des">Next Random</string>
@ -15,7 +15,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Kecepatan (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Kecepatan (%.2fx)</string>
<string name="rated_format" formatted="true">Dinilai: %.1f</string> <string name="rated_format" formatted="true">Dinilai: %.1f</string>
<string name="new_update_format" formatted="true">Update baru ditemukan!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Update baru ditemukan!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d mnt</string> <string name="duration_format" formatted="true">%d mnt</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -100,7 +101,7 @@
<string name="continue_watching">Lanjutkan Menonton</string> <string name="continue_watching">Lanjutkan Menonton</string>
<string name="action_remove_watching">Hapus</string> <string name="action_remove_watching">Hapus</string>
<string name="action_open_watching">Info lebih lanjut</string> <string name="action_open_watching">Info lebih lanjut</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Sebuah VPN mungkin diperlukan agar provider ini bisa bekerja dengan benar</string> <string name="vpn_might_be_needed">Sebuah VPN mungkin diperlukan agar provider ini bisa bekerja dengan benar</string>
<string name="vpn_torrent">Provider ini adalah sebuah torrent, VPN direkomendasikan</string> <string name="vpn_torrent">Provider ini adalah sebuah torrent, VPN direkomendasikan</string>
<string name="provider_info_meta">Metadata tidak disediakan oleh situs, loading video akan gagal jika tidak ada di situs.</string> <string name="provider_info_meta">Metadata tidak disediakan oleh situs, loading video akan gagal jika tidak ada di situs.</string>
@ -125,12 +126,10 @@
<string name="double_tap_to_seek_settings">Tekan dua kali untuk mengubah waktu</string> <string name="double_tap_to_seek_settings">Tekan dua kali untuk mengubah waktu</string>
<string name="double_tap_to_pause_settings">Tekan dua kali untuk menjeda</string> <string name="double_tap_to_pause_settings">Tekan dua kali untuk menjeda</string>
<string name="double_tap_to_seek_amount_settings">Jumlah pengubah waktu pemutar</string> <string name="double_tap_to_seek_amount_settings">Jumlah pengubah waktu pemutar</string>
<string name="double_tap_to_seek_settings_des">Tekan dua kali di sisi kanan atau kiri untuk mengubah waktu ke depan atau ke belakang <string name="double_tap_to_seek_settings_des">Tekan dua kali di sisi kanan atau kiri untuk mengubah waktu ke depan atau ke belakang</string>
</string>
<string name="double_tap_to_pause_settings_des">Tekan di tengah untuk menjeda</string> <string name="double_tap_to_pause_settings_des">Tekan di tengah untuk menjeda</string>
<string name="use_system_brightness_settings">Gunakan pencerahan sistem</string> <string name="use_system_brightness_settings">Gunakan pencerahan sistem</string>
<string name="use_system_brightness_settings_des">Gunakan pencerahan sistem di pemutar aplikasi dari pada hamparan gelap <string name="use_system_brightness_settings_des">Gunakan pencerahan sistem di pemutar aplikasi dari pada hamparan gelap</string>
</string>
<string name="episode_sync_settings">Update progres tontonan</string> <string name="episode_sync_settings">Update progres tontonan</string>
<string name="episode_sync_settings_des">Sinkronisasikan progres episode saat ini secara otomatis</string> <string name="episode_sync_settings_des">Sinkronisasikan progres episode saat ini secara otomatis</string>
<string name="restore_settings">Pulihkan data dari cadangan</string> <string name="restore_settings">Pulihkan data dari cadangan</string>
@ -165,8 +164,7 @@
<string name="copy_link_toast">Tautan disalin ke papan klip</string> <string name="copy_link_toast">Tautan disalin ke papan klip</string>
<string name="play_episode_toast">Putar Episode</string> <string name="play_episode_toast">Putar Episode</string>
<string name="subs_default_reset_toast">Ulang ke pengaturan default</string> <string name="subs_default_reset_toast">Ulang ke pengaturan default</string>
<string name="acra_report_toast">Maaf, aplikasi ngecrash. Laporan bug anonim akan dikirim ke developer <string name="acra_report_toast">Maaf, aplikasi ngecrash. Laporan bug anonim akan dikirim ke developer</string>
</string>
<string name="season">Season</string> <string name="season">Season</string>
<string name="no_season">Tidak Ada Season</string> <string name="no_season">Tidak Ada Season</string>
<string name="episode">Episode</string> <string name="episode">Episode</string>
@ -180,8 +178,10 @@
<string name="resume">Lanjutkan</string> <string name="resume">Lanjutkan</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Ini akan secara permanen menghapus %s\nApakah anda yakin?</string> <string name="delete_message" formatted="true">Ini akan secara permanen menghapus %s
<string name="resume_time_left" formatted="true">%dm\ntersisa</string> \nApakah anda yakin\?</string>
<string name="resume_time_left" formatted="true">%dm
\ntersisa</string>
<string name="status_ongoing">Masih Berlanjut</string> <string name="status_ongoing">Masih Berlanjut</string>
<string name="status_completed">Tamat</string> <string name="status_completed">Tamat</string>
<string name="status">Status</string> <string name="status">Status</string>
@ -209,8 +209,8 @@
<string name="movies_singular">Movie</string> <string name="movies_singular">Movie</string>
<string name="tv_series_singular">Seri</string> <string name="tv_series_singular">Seri</string>
<string name="cartoons_singular">Kartun</string> <string name="cartoons_singular">Kartun</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Film Dokumenter</string> <string name="documentaries_singular">Film Dokumenter</string>
<string name="asian_drama_singular">Drama Asia</string> <string name="asian_drama_singular">Drama Asia</string>
@ -261,22 +261,7 @@
<string name="resize_fill">Regang</string> <string name="resize_fill">Regang</string>
<string name="resize_zoom">Zoom</string> <string name="resize_zoom">Zoom</string>
<string name="legal_notice">Peringatan</string> <string name="legal_notice">Peringatan</string>
<string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application <string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application should be taken up with the actual file hosts and providers themselves as we are not affiliated with them. In case of copyright infringement, please directly contact the responsible parties or the streaming websites. The app is purely for educational and personal use. CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down. CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient, user-friendly interface. It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk.</string>
should be taken up with the actual file hosts and providers themselves as we are not affiliated with them.
In case of copyright infringement, please directly contact the responsible parties or the streaming websites.
The app is purely for educational and personal use.
CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down.
CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or
manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient,
user-friendly interface.
It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the
responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use
CloudStream 3 at your own risk.
</string>
<string name="category_general">Umum</string> <string name="category_general">Umum</string>
<string name="random_button_settings">Tombol Acak</string> <string name="random_button_settings">Tombol Acak</string>
<string name="random_button_settings_desc">Tampilkan tombol acak di Beranda</string> <string name="random_button_settings_desc">Tampilkan tombol acak di Beranda</string>
@ -312,7 +297,7 @@
<string name="upload_sync">Sinkronisasi</string> <string name="upload_sync">Sinkronisasi</string>
<string name="sync_score">Skor</string> <string name="sync_score">Skor</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s terautentikasi</string> <string name="authenticated_user" formatted="true">%s terautentikasi</string>
<string name="authenticated_user_fail" formatted="true">Gagal masuk ke %s</string> <string name="authenticated_user_fail" formatted="true">Gagal masuk ke %s</string>
@ -468,7 +453,7 @@
<string name="safe_mode_description">Semua fitur tambahkan dimatikan karena crash, untuk memudahkanmu mencari penyebab crash.</string> <string name="safe_mode_description">Semua fitur tambahkan dimatikan karena crash, untuk memudahkanmu mencari penyebab crash.</string>
<string name="example_lang_name">Kode bahasa (en)</string> <string name="example_lang_name">Kode bahasa (en)</string>
<string name="player_load_subtitles_online">Ambil dari internet</string> <string name="player_load_subtitles_online">Ambil dari internet</string>
<string name="provider_languages_tip">Putar vidio di bahasa ini</string> <string name="provider_languages_tip">Putar video di bahasa ini</string>
<string name="add_repository">Tambah Repositori</string> <string name="add_repository">Tambah Repositori</string>
<string name="delete_repository_plugins">Pilih ini untuk menghapus semua repositori plugin</string> <string name="delete_repository_plugins">Pilih ini untuk menghapus semua repositori plugin</string>
<string name="skip_setup">Lewati pengaturan</string> <string name="skip_setup">Lewati pengaturan</string>
@ -498,7 +483,7 @@
<string name="pref_category_gestures">Gerakan</string> <string name="pref_category_gestures">Gerakan</string>
<string name="apk_installer_settings_des">Beberapa perangkat tidak mendukung penginstal paket mode baru. Coba mode lama jika pembaruan tidak dapat diinstal.</string> <string name="apk_installer_settings_des">Beberapa perangkat tidak mendukung penginstal paket mode baru. Coba mode lama jika pembaruan tidak dapat diinstal.</string>
<string name="pref_category_actions">Aksi</string> <string name="pref_category_actions">Aksi</string>
<string name="referer">Sumber</string> <string name="referer">Referer</string>
<string name="yes">Ya</string> <string name="yes">Ya</string>
<string name="extension_install_first">Pasang dulu fitur tambahan</string> <string name="extension_install_first">Pasang dulu fitur tambahan</string>
<string name="all_languages_preference">Semua Bahasa</string> <string name="all_languages_preference">Semua Bahasa</string>
@ -526,4 +511,22 @@
<string name="plugin_downloaded">Plugin Terunduh</string> <string name="plugin_downloaded">Plugin Terunduh</string>
<string name="delayed_update_notice">Aplikasi akan diperbaharui pada saat keluar</string> <string name="delayed_update_notice">Aplikasi akan diperbaharui pada saat keluar</string>
<string name="update_started">Pembaharuan Dimulai</string> <string name="update_started">Pembaharuan Dimulai</string>
<string name="action_remove_from_watched">Hapus dari tontonan</string>
<string name="browser">Browser</string>
<string name="select_library">Pilih pustaka</string>
<string name="empty_library_no_accounts_message">Yahh daftar pustaka kamu kosong :(
\nMasuk ke akun pustaka atau tambah perlihatkan ke lokal pustaka kamu</string>
<string name="library">Pustaka</string>
<string name="sort_by">Urutkan berdasar</string>
<string name="sort">Urutkan</string>
<string name="sort_rating_asc">Peringkat (Rendah ke Tinggi)</string>
<string name="sort_updated_old">Update (Lama ke Terbaru)</string>
<string name="sort_rating_desc">Peringkat (Tinggi ke Rendah)</string>
<string name="sort_updated_new">Update (Terbaru ke Lama)</string>
<string name="sort_alphabetical_a">Abjad (A ke Z)</string>
<string name="sort_alphabetical_z">Abjad (Z ke A)</string>
<string name="open_with">Buka dengan</string>
<string name="empty_library_logged_in_message">Yahh daftar ini kosong, coba ganti ke yang lain</string>
<string name="safe_mode_file">Mode aman file ditemukan!
\nTidak memuat ekstensi pada startup sampai berkas dihapus.</string>
</resources> </resources>

View file

@ -9,7 +9,7 @@
<string name="next_episode_time_min_format" formatted="true">%d min</string> <string name="next_episode_time_min_format" formatted="true">%d min</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">Poster</string>
<string name="episode_poster_img_des">Poster episodio</string> <string name="episode_poster_img_des">Poster episodio</string>
<string name="home_main_poster_img_des">Poster principale</string> <string name="home_main_poster_img_des">Poster principale</string>
<string name="home_next_random_img_des">Prossimo casuale</string> <string name="home_next_random_img_des">Prossimo casuale</string>
@ -19,7 +19,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Velocità (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Velocità (%.2fx)</string>
<string name="rated_format" formatted="true">Valutato: %.1f</string> <string name="rated_format" formatted="true">Valutato: %.1f</string>
<string name="new_update_format" formatted="true">Nuovo aggiornamento trovato!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Nuovo aggiornamento trovato!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<!-- <string name="app_name">CloudStream</string> --> <!-- <string name="app_name">CloudStream</string> -->
@ -107,7 +108,7 @@
<string name="continue_watching">Continua a guardare</string> <string name="continue_watching">Continua a guardare</string>
<string name="action_remove_watching">Rimuovi</string> <string name="action_remove_watching">Rimuovi</string>
<string name="action_open_watching">Più info</string> <string name="action_open_watching">Più info</string>
<string name="action_open_play">@string/home_play</string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Potrebbe essere necessaria una VPN per far funzionare correttamente questo provider</string> <string name="vpn_might_be_needed">Potrebbe essere necessaria una VPN per far funzionare correttamente questo provider</string>
<string name="vpn_torrent">Questo provider è un torrent, si raccomanda una VPN</string> <string name="vpn_torrent">Questo provider è un torrent, si raccomanda una VPN</string>
<string name="provider_info_meta">I metadati non sono forniti dal sito, il caricamento del video fallirà se non esiste sul sito.</string> <string name="provider_info_meta">I metadati non sono forniti dal sito, il caricamento del video fallirà se non esiste sul sito.</string>
@ -193,8 +194,10 @@
<string name="resume">Riprendi</string> <string name="resume">Riprendi</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Stai per eliminare permanentemente %s\nSei sicuro?</string> <string name="delete_message" formatted="true">Stai per eliminare permanentemente %s
<string name="resume_time_left" formatted="true">%dm\nrimanenti</string> \nSei sicuro\?</string>
<string name="resume_time_left" formatted="true">%dm
\nrimanenti</string>
<string name="status_ongoing">In corso</string> <string name="status_ongoing">In corso</string>
<string name="status_completed">Completato</string> <string name="status_completed">Completato</string>
<string name="status">Stato</string> <string name="status">Stato</string>
@ -321,7 +324,7 @@
<string name="upload_sync">Sincronizza</string> <string name="upload_sync">Sincronizza</string>
<string name="sync_score">Valutato</string> <string name="sync_score">Valutato</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s autenticato</string> <string name="authenticated_user" formatted="true">%s autenticato</string>
<string name="authenticated_user_fail" formatted="true">Impossibile autenticarsi a %s</string> <string name="authenticated_user_fail" formatted="true">Impossibile autenticarsi a %s</string>
@ -428,7 +431,7 @@
<string name="view_public_repositories_button">Vedi le repository della community</string> <string name="view_public_repositories_button">Vedi le repository della community</string>
<string name="view_public_repositories_button_short">Lista pubblica</string> <string name="view_public_repositories_button_short">Lista pubblica</string>
<string name="uppercase_all_subtitles">Tutti i sottotitoli in maiuscolo</string> <string name="uppercase_all_subtitles">Tutti i sottotitoli in maiuscolo</string>
<string name="download_all_plugins_from_repo">Scaricare tutti i plugin da questa repository?</string> <string name="download_all_plugins_from_repo">Scaricare tutti i plugin da questa repository\?</string>
<string name="single_plugin_disabled" formatted="true">%s (Disabilitato)</string> <string name="single_plugin_disabled" formatted="true">%s (Disabilitato)</string>
<string name="tracks">Tracce</string> <string name="tracks">Tracce</string>
<string name="audio_tracks">Traccia audio</string> <string name="audio_tracks">Traccia audio</string>
@ -507,4 +510,22 @@
<string name="delayed_update_notice">L\'app verrà aggiornata all\'uscita</string> <string name="delayed_update_notice">L\'app verrà aggiornata all\'uscita</string>
<string name="update_started">Aggiornamento avviato</string> <string name="update_started">Aggiornamento avviato</string>
<string name="plugin_downloaded">Plugin scaricato</string> <string name="plugin_downloaded">Plugin scaricato</string>
<string name="action_remove_from_watched">Rimuovi dai già visti</string>
<string name="browser">Browser</string>
<string name="sort_by">Ordina per</string>
<string name="sort_rating_desc">Punteggio (Decrescente)</string>
<string name="sort_rating_asc">Punteggio (Crescente)</string>
<string name="sort_updated_new">Aggiornato (Da nuovo a vecchio)</string>
<string name="sort_updated_old">Aggiornato (Da vecchio a nuovo)</string>
<string name="sort_alphabetical_a">Alfabetico (A - Z)</string>
<string name="sort_alphabetical_z">Alfabetico (Z - A)</string>
<string name="empty_library_no_accounts_message">Sembra che la tua libreria sia vuota :(
\nAccedi a un account di libreria o aggiungi degli show alla tua libreria locale</string>
<string name="select_library">Seleziona libreria</string>
<string name="open_with">Apri con</string>
<string name="library">Libreria</string>
<string name="sort">Ordina</string>
<string name="empty_library_logged_in_message">Sembra che questa lista sia vuota, prova a passare a un\'altra</string>
<string name="safe_mode_file">File \"safe mode\" trovato!
\nAll\'avvio non sarà caricata alcuna estensione finchè il file non verrà rimosso.</string>
</resources> </resources>

View file

@ -34,13 +34,13 @@
<string name="type_completed">הושלם</string> <string name="type_completed">הושלם</string>
<string name="type_plan_to_watch">בתכנון לצפייה</string> <string name="type_plan_to_watch">בתכנון לצפייה</string>
<string name="type_re_watching">צופה מחדש</string> <string name="type_re_watching">צופה מחדש</string>
<string name="play_movie_button">נגן סרט</string> <string name="play_movie_button">הפעל סרט</string>
<string name="play_trailer_button">נגן קדימון</string> <string name="play_trailer_button">הפעל טריילר</string>
<string name="play_livestream_button">נגן שידור חי</string> <string name="play_livestream_button">הפעל שידור חי</string>
<string name="pick_source">מקורות</string> <string name="pick_source">מקורות</string>
<string name="reload_error">נסיון חדש לחיבור…</string> <string name="reload_error">נסיון חדש לחיבור…</string>
<string name="type_dropped">נעצר</string> <string name="type_dropped">הפסיק</string>
<string name="play_torrent_button">שידור טורנט</string> <string name="play_torrent_button">שדר טורנט</string>
<string name="go_back">חזרה</string> <string name="go_back">חזרה</string>
<string name="play_episode">נגן פרק</string> <string name="play_episode">נגן פרק</string>
<string name="downloaded">הורד</string> <string name="downloaded">הורד</string>
@ -75,7 +75,7 @@
<string name="play_with_app_name">נגן עם קלאודסטרים</string> <string name="play_with_app_name">נגן עם קלאודסטרים</string>
<string name="next_episode">פרק הבא</string> <string name="next_episode">פרק הבא</string>
<string name="loading">טוען…</string> <string name="loading">טוען…</string>
<string name="type_watching">צופה ב</string> <string name="type_watching">צופה</string>
<string name="pick_subtitle">כתוביות</string> <string name="pick_subtitle">כתוביות</string>
<string name="type_on_hold">בהמתנה</string> <string name="type_on_hold">בהמתנה</string>
<string name="type_none">ללא</string> <string name="type_none">ללא</string>
@ -102,11 +102,11 @@
<string name="vpn_torrent">הספק הזה הוא טורנט, שימוש ב-VPN הוא מומלץ</string> <string name="vpn_torrent">הספק הזה הוא טורנט, שימוש ב-VPN הוא מומלץ</string>
<string name="torrent_plot">תיאור</string> <string name="torrent_plot">תיאור</string>
<string name="normal_no_plot">עלילה לא נמצאה</string> <string name="normal_no_plot">עלילה לא נמצאה</string>
<string name="torrent_no_plot">העלילה לא נמצאה</string> <string name="torrent_no_plot">התיאור לא נמצאה</string>
<string name="picture_in_picture">מצב תמונה בתמונה</string> <string name="picture_in_picture">מצב תמונה בתמונה</string>
<string name="player_size_settings">כפתור שינוי גודל הנגן</string> <string name="player_size_settings">כפתור שינוי גודל הנגן</string>
<string name="player_size_settings_des">הסר את הגבולות השחורים</string> <string name="player_size_settings_des">הסר את הגבולות השחורים</string>
<string name="benene_count_text">%d ניתן למפתחים</string> <string name="benene_count_text">%d בנינים שניתנו למפתחים</string>
<string name="player_subtitles_settings_des">הגדרות כתוביות הנגן</string> <string name="player_subtitles_settings_des">הגדרות כתוביות הנגן</string>
<string name="chromecast_subtitles_settings_des">הגדרות כתוביות כרומקאסט</string> <string name="chromecast_subtitles_settings_des">הגדרות כתוביות כרומקאסט</string>
<string name="subs_font">גופן</string> <string name="subs_font">גופן</string>
@ -129,4 +129,381 @@
<string name="none">אין</string> <string name="none">אין</string>
<string name="all">הכל</string> <string name="all">הכל</string>
<string name="title">כותרת</string> <string name="title">כותרת</string>
<string name="update_started">העדכון התחיל</string>
<string name="settings_info">מידע</string>
<string name="automatic_plugin_download_summary">התקן אוטומטית את כל התוספים שטרם הותקנו ממאגרים שנוספו.</string>
<string name="updates_settings_des">חפש אוטומטית עדכונים חדשים בפתיחת האפליקציה</string>
<string name="updates_settings">הצג עדכונים לאפליקציה</string>
<string name="redo_setup_process">בצע מחדש את תהליך ההגדרה</string>
<string name="uprereleases_settings">עדכן למהדורות מוקדמות</string>
<string name="uprereleases_settings_des">חפש עדכוני מהדרות מוקדמות במקום מהדורות מלאות בלבד</string>
<string name="episodes">פרקים</string>
<string name="episodes_range">%d-%d</string>
<string name="episode">פרק</string>
<string name="episode_format" formatted="true">%d %s</string>
<string name="season_short">עו</string>
<string name="episode_short">פר</string>
<string name="no_episodes_found">לא נמצאו פרקים</string>
<string name="delete_file">מחק קובץ</string>
<string name="delete">מחק</string>
<string name="pause">עצור</string>
<string name="resume">המשך</string>
<string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string>
<string name="resume_time_left" formatted="true">%dדקות
\nנותרו</string>
<string name="delete_message" formatted="true">‬פעולה זאת תמחק לצמיתות את %s
\nהאם אתם בטוחים\?</string>
<string name="status_ongoing">מתמשך</string>
<string name="duration">משך זמן</string>
<string name="rating">דירוג</string>
<string name="year">שנה</string>
<string name="no_subtitles">ללא כתוביות</string>
<string name="default_subtitles">ברירת מחדל</string>
<string name="free_storage">חינם</string>
<string name="used_storage">משומש</string>
<string name="tv_series">סדרת טלוויזיה</string>
<string name="cartoons">סדרות/סרטים מצוירים</string>
<string name="anime_singular">\@string/אנימה</string>
<string name="ova_singular">\@string/אנימציית וידאו מקורית</string>
<string name="asian_drama_singular">דרמה אסייתית</string>
<string name="episode_action_chromecast_episode">כרומקאסט את הפרק</string>
<string name="episode_action_chromecast_mirror">כרומקאסט את המראה</string>
<string name="episode_action_play_in_browser">נגן בדפדפן</string>
<string name="show_sub">תווית כתוביות</string>
<string name="poster_ui_settings">החלף רכיבי ממשק משתמש בפוסטר</string>
<string name="video_skip_op">דלג על הפתיח</string>
<string name="dont_show_again">אל תראה שוב</string>
<string name="skip_update">דלג על עדכון זה</string>
<string name="update">עדכון</string>
<string name="watch_quality_pref">איכות צפייה מועדפת</string>
<string name="limit_title">נגן וידאו כותרת מקסימום תווים</string>
<string name="limit_title_rez">רזולוציית נגן וידאו</string>
<string name="add_sync">הוסף מעקב</string>
<string name="create_account">צור חשבון</string>
<string name="next">הבא</string>
<string name="library">ספריה</string>
<string name="provider_info_meta">מטא-דאטה לא מסופק על ידי האתר, טעינת הסרטון תיכשל אם הוא לא קיים באתר.</string>
<string name="swipe_to_change_settings_des">החלק על הצד השמאלי או הימני כדי לשנות את הבהירות או עוצמת הקול</string>
<string name="restore_failed_format" formatted="true">שחזור הנתונים מהקובץ נכשל %s</string>
<string name="category_updates">עדכונים וגיבויים</string>
<string name="advanced_search_des">נותן לך את תוצאות החיפוש מופרדות לפי ספק</string>
<string name="show_fillers_settings">הצג פרק פילר (לא הכרחי לעלילה) לאנימה</string>
<string name="automatic_plugin_download">הורדה אוטומטית של תוספים</string>
<string name="automatic_plugin_updates">עדכוני תוספים אוטומטיים</string>
<string name="benene_des">כמות בנינים שניתנו</string>
<string name="season">עונה</string>
<string name="acra_report_toast">מצטערים, האפליקציה קרסה. דוח באג אנונימי יישלח למפתחים</string>
<string name="torrent">טורנט</string>
<string name="nsfw">NSFW</string>
<string name="render_error">שגיאת מעבד</string>
<string name="episode_action_download_mirror">הורד מראה</string>
<string name="episode_action_download_subtitle">הורד כתוביות</string>
<string name="random_button_settings_desc">הצג כפתור אקראי בדף הבית</string>
<string name="show_dub">תווית דיבוב</string>
<string name="video_ram_description">גורם לקריסות אם מוגדר גבוה מדי במכשירים עם זיכרון נמוך, כגון Android TV.</string>
<string name="video_source">מקור</string>
<string name="category_providers">ספקים</string>
<string name="remove_site_pref">הסר אתר</string>
<string name="download_path_pref">נתיב הורדה</string>
<string name="pref_category_looks">נראה</string>
<string name="automatic">אוטומטי</string>
<string name="tv_layout">פריסת טלוויזיה</string>
<string name="login_format" formatted="true">%s %s</string>
<string name="subtitles_filter_lang">סנן לפי שפת מדיה מועדפת</string>
<string name="app_theme_settings">נושא אפליקציה</string>
<string name="bottom_title_settings">מיקום כותרת פוסטר</string>
<string name="preferred_media_subtext">מה אתם רוצים לראות</string>
<string name="quality_hq">איכות גבוהה</string>
<string name="quality_hd">HD</string>
<string name="quality_sdr">SDR</string>
<string name="plugin_loaded">תוסף טעון</string>
<string name="quality_dvd">DVD</string>
<string name="pref_category_app_updates">עדכוני אפליקציה</string>
<string name="quality_4k">4K</string>
<string name="quality_workprint">WP</string>
<string name="skip_setup">דלג על ההגדרה</string>
<string name="pref_category_player_features">תכונות נגן</string>
<string name="episode_sync_settings">עדכן התקדמות צפייה</string>
<string name="dns_pref">DNS מעל HTTPS</string>
<string name="double_tap_to_pause_settings_des">לחץ באמצע כדי לעצור</string>
<string name="swipe_to_seek_settings_des">החלק שמאלה או ימינה כדי לשלוט על זמן בנגן הסרטונים</string>
<string name="autoplay_next_settings">נגן אוטומטית את הפרק הבא</string>
<string name="autoplay_next_settings_des">התחל את הפרק הבא כאשר הפרק הנוכחי נגמר</string>
<string name="double_tap_to_seek_settings_des">לחץ פעמיים על צד ימין או שמאל כדי להציץ קדימה או אחורה</string>
<string name="use_system_brightness_settings">השתמש בבהירות המערכת</string>
<string name="backup_settings">גבה נתונים</string>
<string name="subtitle_offset">סנכרן את הכתוביות</string>
<string name="subtitle_offset_title">עיכוב כתוביות</string>
<string name="subtitle_offset_extra_hint_none_format">אין עיכוב בכתוביות</string>
<string name="recommended">מומלץ</string>
<string name="player_loaded_subtitles" formatted="true">נטען %s</string>
<string name="subtitle_offset_extra_hint_later_format">השתמש בזה אם הכתוביות מוצגות %d מילישניות מוקדם יותר</string>
<string name="home_random">אקראי</string>
<string name="resolution">רזולוציה</string>
<string name="quality_cam_hd">איכות מצלמה</string>
<string name="error_invalid_url">כתובת אתר לא מזוהה</string>
<string name="network_adress_example">קישור לשידור</string>
<string name="referer">המפנה</string>
<string name="quality_tc">TC</string>
<string name="quality_sd">SD</string>
<string name="quality_uhd">UHD</string>
<string name="repository_url_hint">כתובת אתר למאגר</string>
<string name="preferred_media_settings">מדיה מועדפת</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="play_episode_toast">נגן את הפרק</string>
<string name="no_links_found_toast">לא נמצאו קישורים</string>
<string name="example_lang_name">קוד שפה (אנגלית)</string>
<string name="error">שגיאה</string>
<string name="provider_lang_settings">שפות ספק</string>
<string name="pref_category_links">קישורים</string>
<string name="app_layout">פריסת אפליקציה</string>
<string name="advanced_search">חיפוש מתקדם</string>
<string name="is_adult">18+</string>
<string name="search_poster_img_des">פוסטר</string>
<string name="quality_cam">איכות מצלמה</string>
<string name="swipe_to_seek_settings">החלק כדי להציץ</string>
<string name="pref_category_backup">גיבוי</string>
<string name="double_tap_to_seek_amount_settings">כמות הצצת הנגן</string>
<string name="other_singular">סרטון</string>
<string name="github">גיטהאב</string>
<string name="quality_cam_rip">מצלמה</string>
<string name="swipe_to_change_settings">החלק לשינוי ההגדרות</string>
<string name="browser">‪דפדפן</string>
<string name="subs_window_color">צבע חלון</string>
<string name="show_log_cat">הצג לוג</string>
<string name="eigengraumode_settings_des">הוסף אפשרות מהירות בנגן</string>
<string name="double_tap_to_seek_settings">לחץ פעמיים כדי להציץ</string>
<string name="double_tap_to_pause_settings">לחץ פעמיים כדי לעצור</string>
<string name="use_system_brightness_settings_des">התשתמש בבהירות המערכת בנגן האפליקציה במקום שכבת-על כהה</string>
<string name="episode_sync_settings_des">סנכרן אוטומטית את התקדמות הפרק הנוכחית שלך</string>
<string name="restore_settings">שחזר נתונים מגיבוי</string>
<string name="restore_success">קובץ הגיבוי נטען</string>
<string name="backup_success">נתונים מאוחסנים</string>
<string name="backup_failed">חסרות הרשאות אחסון. אנא נסה שוב.</string>
<string name="backup_failed_error_format">שגיאה בגיבוי %s</string>
<string name="search">חיפוש</string>
<string name="category_account">חשבונות</string>
<string name="benene_count_text_none">לא ניתנו בנינים</string>
<string name="eigengraumode_settings">מצב איגנגראבי</string>
<string name="bug_report_settings_off">שולח נתונים רק בקריסות</string>
<string name="bug_report_settings_on">לא שולח נתונים</string>
<string name="show_trailers_settings">הצג טריילרים</string>
<string name="kitsu_settings">הצג פוסטרים מKitsu</string>
<string name="pref_filter_search_quality">הסתר את איכות הסרטון שנבחרה בתוצאות החיפוש</string>
<string name="apk_installer_settings">מתקין APK</string>
<string name="apk_installer_settings_des">חלק מהטלפונים אינם תומכים במתקין החבילות החדש. נסו את האפשרות מדור קודם אם העדכונים לא מתקינים.</string>
<string name="lightnovel">אפליקצית רומנים קלים על ידי אותו מפתחים</string>
<string name="anim">אפליקצית אנימה על ידי אותו מפתחים</string>
<string name="discord">הצטרפות לדיסקורד</string>
<string name="app_language">שפת האפליקציה</string>
<string name="no_chromecast_support_toast">לספק זה אין תמיכה בכרומקאסט</string>
<string name="copy_link_toast">הקישור הועתק ללוח</string>
<string name="subs_default_reset_toast">אפס לערך ברירת המחדל</string>
<string name="no_season">אין עונה</string>
<string name="status_completed">הושלם</string>
<string name="site">אתר</string>
<string name="synopsis">תקציר</string>
<string name="queued">בתור</string>
<string name="benene">לתת בניני למפתחים</string>
<string name="season_format">%s %d%s</string>
<string name="app_storage">אפליקציה</string>
<string name="movies">סרטים</string>
<string name="anime">אנימה</string>
<string name="documentaries">סרטים תיעודיים</string>
<string name="ova">אנימציית וידאו מקורית</string>
<string name="asian_drama">דרמות אסייתיות</string>
<string name="livestreams">שידורי חי</string>
<string name="others">אחר</string>
<string name="movies_singular">סרט</string>
<string name="tv_series_singular">סדרה</string>
<string name="cartoons_singular">סדרה/סרט מצויר</string>
<string name="torrent_singular">טורנט</string>
<string name="documentaries_singular">דוקומנטרי</string>
<string name="live_singular">שידור חי</string>
<string name="nsfw_singular">NSFW</string>
<string name="source_error">שגיאת מקור</string>
<string name="remote_error">שגיאה מרחוק</string>
<string name="unexpected_error">שגיאת נגן לא צפויה</string>
<string name="storage_error">שגיאת הורדה, בדוק הרשאות אחסון</string>
<string name="episode_action_play_in_app">נגן באפליקציה</string>
<string name="episode_action_play_in_format">נגן ב %s</string>
<string name="episode_action_copy_link">העתק קישור</string>
<string name="episode_action_auto_download">הורדה אוטומטית</string>
<string name="episode_action_reload_links">טען מחדש קישורים</string>
<string name="show_hd">תווית איכות</string>
<string name="no_update_found">לא נמצא עדכון</string>
<string name="check_for_update">בדוק אם יש עדכון</string>
<string name="video_lock">נעל</string>
<string name="video_aspect_ratio_resize">שינוי גודל</string>
<string name="video_buffer_size_settings">גודל מאגר וידאו</string>
<string name="video_buffer_length_settings">אורך מאגר וידאו</string>
<string name="video_buffer_disk_settings">מטמון וידאו בכונן</string>
<string name="video_buffer_clear_settings">נקה מטמון וידאו ותמונה</string>
<string name="video_disk_description">גורם לקריסות אם מוגדר גבוה מדי במכשירים עם מקום נמוך, כגון Android TV.</string>
<string name="dns_pref_summary">שימושי עבור עקיפת מחסומי ספק שירותי אינטרנט</string>
<string name="add_site_pref">אתר העתק</string>
<string name="add_site_summary">הוסף העתק של אתר קיים, עם כתובת אתר אחרת</string>
<string name="nginx_url_pref">NGINX שרת כתובת אתר</string>
<string name="display_subbed_dubbed_settings">הצג אנימות מדובבות/מתורגמות</string>
<string name="resize_fit">התאם למסך</string>
<string name="resize_fill">מתוח</string>
<string name="resize_zoom">זום</string>
<string name="legal_notice">כתב ויתור</string>
<string name="pref_category_extensions">הרחבות</string>
<string name="pref_category_actions">פעולות</string>
<string name="pref_category_cache">מטמון</string>
<string name="pref_category_gestures">מחוות</string>
<string name="pref_category_subtitles">כתוביות</string>
<string name="pref_category_player_layout">פריסה</string>
<string name="pref_category_defaults">ברירות מחדל</string>
<string name="pref_category_ui_features">תכונות</string>
<string name="category_general">כללי</string>
<string name="random_button_settings">כפתור אקראי</string>
<string name="enable_nsfw_on_providers">הרשה NSFW בספקים נתמכים</string>
<string name="subtitles_encoding">קידוד כתוביות</string>
<string name="category_ui">פריסה</string>
<string name="phone_layout">פריסת טלפון</string>
<string name="emulator_layout">פריסת אמולטור</string>
<string name="primary_color_settings">צבע ראשוני</string>
<string name="bottom_title_settings_des">שים את הכותרת מתחת לפוסטר</string>
<string name="example_password">סיסמה123</string>
<string name="example_username">שםהמשתמשהמגניבשלי</string>
<string name="example_email">hello@world.com</string>
<string name="example_ip">127.0.0.1</string>
<string name="example_site_name">האתרהמגניבשלי</string>
<string name="example_site_url">דוגמה.com</string>
<string name="account">חשבון</string>
<string name="switch_account">החלף חשבון</string>
<string name="add_account">הוסף חשבון</string>
<string name="added_sync_format" formatted="true">נוסף %s</string>
<string name="upload_sync">סנכרן</string>
<string name="sync_score">מדורג</string>
<string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/\?\?</string>
<string name="authenticated_user" formatted="true">%s מאומת</string>
<string name="authenticated_user_fail" formatted="true">לא ניתן להתחבר ב %s</string>
<string name="normal">רגיל</string>
<string name="max">מקסימום</string>
<string name="min">מינימום</string>
<string name="subtitles_outline">מתאר</string>
<string name="subtitles_depressed">מדוכא</string>
<string name="subtitles_shadow">צל</string>
<string name="subtitles_raised">הורם</string>
<string name="subtitle_offset_hint">1000 מילישניות</string>
<string name="subtitle_offset_extra_hint_before_format">השתמש בזה אם הכתוביות מוצגות %d מילישניות מאוחר יותר</string>
<string name="subtitles_example_text">השועל החום המהיר קופץ מעל הכלב העצלן</string>
<string name="player_load_subtitles">טען מקובץ</string>
<string name="player_load_subtitles_online">טען מהאינטרנט</string>
<string name="downloaded_file">קובץ שהורד</string>
<string name="actor_main">ראשי</string>
<string name="actor_supporting">משנה</string>
<string name="actor_background">רקע</string>
<string name="home_source">מקור</string>
<string name="coming_soon">בקרוב…</string>
<string name="quality_ts">TS</string>
<string name="quality_blueray">Blu-ray</string>
<string name="quality_hdr">HDR</string>
<string name="quality_webrip">Web</string>
<string name="poster_image">תמונת פוסטר</string>
<string name="category_player">נגן</string>
<string name="resolution_and_title">רזולוציה וכותרת</string>
<string name="error_invalid_id">לא מזוהה ID</string>
<string name="error_invalid_data">נתונים לא מזוהים</string>
<string name="subtitles_remove_captions">הסר כיתובים סגורים מהכתוביות</string>
<string name="subtitles_remove_bloat">הסר נפיחות מכתוביות</string>
<string name="extras">תוספות</string>
<string name="trailer">טריילר</string>
<string name="provider_languages_tip">צפה בסרטונים בשפות אלה</string>
<string name="previous">קודם</string>
<string name="app_layout_subtext">שנה את מראה האפליקציה כך שיתאים למכשירך</string>
<string name="crash_reporting_title">דיווח על קריסה</string>
<string name="setup_done">סוים</string>
<string name="extensions">הרחבות</string>
<string name="add_repository">הוסף מאגר</string>
<string name="repository_name_hint">שם מאגר</string>
<string name="plugin_downloaded">תוסף הורד</string>
<string name="plugin_deleted">התוסף נמחק</string>
<string name="plugin_load_fail" formatted="true">לא יכול לטעון %s</string>
<string name="batch_download_start_format" formatted="true">התחיל להוריד %d %s…</string>
<string name="batch_download_finish_format" formatted="true">הוריד %d %s</string>
<string name="enable_skip_op_from_database_des">הצג חלונות קופצים של דילוג בשביל פתיח/שיר סיום</string>
<string name="delete_repository">מחק מאגר</string>
<string name="skip_type_mixed_op">פתיח מעורב</string>
<string name="batch_download_nothing_to_download_format" formatted="true">כל %s כבר הורד</string>
<string name="extension_authors">מחברים</string>
<string name="extension_language">שפה</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_creddits">קרדיטים</string>
<string name="sort">מיין</string>
<string name="select_library">בחר ספרייה</string>
<string name="empty_library_no_accounts_message">נראה שהספרייה שלכם ריקה :(
\nהתחברו לחשבון ספריה או הוסף סדרות לספרייה המקומית שלך</string>
<string name="safe_mode_file">קובץ מצב בטוח נמצא!
\nלא טוען שום תוספות בהפעלה עד להסרת הקובץ.</string>
<string name="update_notification_failed">לא ניתן להתקין את הגרסה החדשה של האפליקציה</string>
<string name="batch_download">הורדת אצווה</string>
<string name="plugin_singular">תוסף</string>
<string name="download_all_plugins_from_repo">הורד את כל התוספים ממאגר זה\?</string>
<string name="audio_tracks">רצועות שמע</string>
<string name="tracks">מסלולים</string>
<string name="player_settings_play_in_web">Web Video Cast</string>
<string name="player_settings_play_in_browser">דפדפן אינטרנט</string>
<string name="safe_mode_description">כל התוספים נכבו עקב התרסקות כדי לעזור לך למצוא את האחד הגורם לצרות.</string>
<string name="apk_installer_package_installer">מוריד החבילות</string>
<string name="plugins_updated" formatted="true">עודכן %d תוספים</string>
<string name="plugin">תוספים</string>
<string name="delete_repository_plugins">פעולה זו תמחק גם את כל תוספי המאגר</string>
<string name="setup_extensions_subtext">הורד את רשימת האתרים שבהם ברצונך להשתמש</string>
<string name="plugins_downloaded" formatted="true">הורד: %d</string>
<string name="plugins_disabled" formatted="true">מוגבל: %d</string>
<string name="plugins_not_downloaded" formatted="true">לא מורד: %d</string>
<string name="blank_repo_message">לקלאודסטרים אין אתרים מותקנים כברירת מחדל. עליכם להתקין את האתרים ממאגרים.
\n
\nבגלל הסרת DMCA על ידי Sky UK LImited 🤮 אנחנו לא יכולים לקשר את אתר המאגרים באפליקציה.
\n
\nתצטרפו לדיסקורד שלנו או תחפשו באינטרנט.</string>
<string name="view_public_repositories_button">הצג מאגרים קהילתיים</string>
<string name="view_public_repositories_button_short">רשימה ציבורית</string>
<string name="uppercase_all_subtitles">לשים את הכתוביות באותיות רישיות</string>
<string name="single_plugin_disabled" formatted="true">%s (מוגבל)</string>
<string name="video_tracks">רצועות וידאו</string>
<string name="apply_on_restart">החל על הפעלה מחדש</string>
<string name="safe_mode_title">מצב בטוח מופעל</string>
<string name="safe_mode_crash_info">הצג מידע על ההתרסקות</string>
<string name="extension_rating" formatted="true">דירוג: %s</string>
<string name="extension_description">תיאור</string>
<string name="extension_version">גרסה</string>
<string name="extension_status">מצב</string>
<string name="extension_size">גודל</string>
<string name="extension_types">תומך</string>
<string name="extension_install_first">התקן תחילה את התוסף</string>
<string name="hls_playlist">פלייליסט HLS</string>
<string name="player_pref">נגן וידאו מועדף</string>
<string name="player_settings_play_in_app">נגן פנימי</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="app_not_found_error">האפליקציה לא נמצאה</string>
<string name="all_languages_preference">כל השפות</string>
<string name="skip_type_format" formatted="true">דלג %s</string>
<string name="skip_type_op">פתיח</string>
<string name="skip_type_ed">שיר סיום</string>
<string name="skip_type_recap">סיכום</string>
<string name="skip_type_mixed_ed">שיר סיום מעורב</string>
<string name="skip_type_intro">מבוא</string>
<string name="clear_history">נקה היסטוריה</string>
<string name="clipboard_too_large">יותר מדי טקסט. לא ניתן לשמור ללוח.</string>
<string name="action_remove_from_watched">הסר מצפייה</string>
<string name="confirm_exit_dialog">האם אתם בטוחים שאתם רוצים לצאת\?</string>
<string name="update_notification_downloading">מוריד עדכון אפליקציה…</string>
<string name="update_notification_installing">מתקין עדכון אפליקציה…</string>
<string name="delayed_update_notice">האפליקציה תעודכן עם היציאה</string>
<string name="sort_by">מיין לפי</string>
<string name="sort_rating_desc">דירוג (גבוה לנמוך)</string>
<string name="sort_rating_asc">דירוג (נמוך לגבוה)</string>
<string name="sort_updated_new">מעודכן (חדש לישן)</string>
<string name="sort_updated_old">מעודכן (ישן לחדש)</string>
<string name="sort_alphabetical_a">אלפביתי (א \'עד ת\')</string>
<string name="sort_alphabetical_z">אלפביתי (ת\' עד א\')</string>
<string name="open_with">פתח עם</string>
<string name="empty_library_logged_in_message">נראה שהרשימה הזו ריקה, נסו לעבור לרשימה אחרת</string>
</resources> </resources>

View file

@ -1,2 +1,3 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources></resources> <resources>
</resources>

View file

@ -3,7 +3,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Брзина (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Брзина (%.2fx)</string>
<string name="rated_format" formatted="true">Оценето: %.1f</string> <string name="rated_format" formatted="true">Оценето: %.1f</string>
<string name="new_update_format" formatted="true">Пронајдена нова верзија на апликацијата!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Пронајдена нова верзија на апликацијата!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Филтер</string> <string name="filler" formatted="true">Филтер</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="title_home">Дома</string> <string name="title_home">Дома</string>
@ -134,7 +135,8 @@
<string name="delete">Избриши</string> <string name="delete">Избриши</string>
<string name="pause">Паузирај</string> <string name="pause">Паузирај</string>
<string name="resume">Продолжи</string> <string name="resume">Продолжи</string>
<string name="delete_message">Ова трајно ќе го избрише %s\nДали си сигурен?</string> <string name="delete_message">Ова трајно ќе го избрише %s
\nДали си сигурен\?</string>
<string name="status_ongoing">Во тек</string> <string name="status_ongoing">Во тек</string>
<string name="status_completed">Завршени</string> <string name="status_completed">Завршени</string>
<string name="status">Статус</string> <string name="status">Статус</string>

View file

@ -3,7 +3,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">വേഗം (%.2fx)</string> <string name="player_speed_text_format" formatted="true">വേഗം (%.2fx)</string>
<string name="rated_format" formatted="true">റേറ്റിംഗ്: %.1f</string> <string name="rated_format" formatted="true">റേറ്റിംഗ്: %.1f</string>
<string name="new_update_format" formatted="true">പുതിയ അപ്ഡേറ്റ്\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">പുതിയ അപ്ഡേറ്റ്
\n%s -&gt; %s</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="title_home">ഹോം</string> <string name="title_home">ഹോം</string>
<string name="title_search">തിരയുക</string> <string name="title_search">തിരയുക</string>
@ -66,14 +67,14 @@
<string name="search_provider_text_providers">സ്രോതസ് അടിസ്ഥാനത്തിൽ തിരയുക</string> <string name="search_provider_text_providers">സ്രോതസ് അടിസ്ഥാനത്തിൽ തിരയുക</string>
<string name="search_provider_text_types">തരം അടിസ്ഥാനത്തിൽ തിരയുക</string> <string name="search_provider_text_types">തരം അടിസ്ഥാനത്തിൽ തിരയുക</string>
<string name="benene_count_text">%d പഴം കൊടുത്തു</string> <string name="benene_count_text">%d പഴം കൊടുത്തു</string>
<string name="benene_count_text_none">പഴം കൊടുത്തിട്ടില്ല </string> <string name="benene_count_text_none">പഴം കൊടുത്തിട്ടില്ല</string>
<!-- <string name="subs_auto_select_language">Auto Select Language</string> <!-- <string name="subs_auto_select_language">Auto Select Language</string>
<string name="subs_download_languages">Download Languages</string> --> <string name="subs_download_languages">Download Languages</string> -->
<string name="subs_hold_to_reset_to_default">റീസെറ് ചെയ്യാൻ അമർത്തിപ്പിടിക്കുക</string> <string name="subs_hold_to_reset_to_default">റീസെറ് ചെയ്യാൻ അമർത്തിപ്പിടിക്കുക</string>
<string name="continue_watching">തുടർന്നു കാണുക</string> <string name="continue_watching">തുടർന്നു കാണുക</string>
<string name="action_remove_watching">നീക്കം ചെയ്യുക</string> <string name="action_remove_watching">നീക്കം ചെയ്യുക</string>
<string name="action_open_watching">കൂടുതൽ വിവരം</string> <string name="action_open_watching">കൂടുതൽ വിവരം</string>
<string name="vpn_might_be_needed">ഈ സ്രോതസ് പ്രവൃത്തിക്കാൻ VPN ഉപയോഗിക്കേണ്ടിവന്നേക്കാം</string> <string name="vpn_might_be_needed">ഈ സ്രോതസ് പ്രവൃത്തിക്കാൻ VPN ഉപയോഗിക്കേണ്ടിവന്നേക്കാം</string>
<string name="vpn_torrent">ഈ ടോറന്റ് സ്രോതസ് ഉപയോഗിക്കാൻ VPN ശുപാർശചെയ്യുന്നു</string> <string name="vpn_torrent">ഈ ടോറന്റ് സ്രോതസ് ഉപയോഗിക്കാൻ VPN ശുപാർശചെയ്യുന്നു</string>
<string name="torrent_plot">വിവരണം</string> <string name="torrent_plot">വിവരണം</string>
<string name="normal_no_plot">വിവരണം ലഭ്യമല്ല</string> <string name="normal_no_plot">വിവരണം ലഭ്യമല്ല</string>
@ -109,7 +110,7 @@
<string name="benene">പഴം കൊടുക്കു</string> <string name="benene">പഴം കൊടുക്കു</string>
<string name="benene_des">പഴം കൊടുത്ത എണ്ണം</string> <string name="benene_des">പഴം കൊടുത്ത എണ്ണം</string>
<string name="app_language">ആപ്പിന്റെ ഭാഷ</string> <string name="app_language">ആപ്പിന്റെ ഭാഷ</string>
<string name="no_chromecast_support_toast">ഈ സ്രോതസ് ക്രോംകാസ്റ് അനുവദിക്കുന്നില്ല </string> <string name="no_chromecast_support_toast">ഈ സ്രോതസ് ക്രോംകാസ്റ് അനുവദിക്കുന്നില്ല</string>
<string name="no_links_found_toast">ലിങ്കുകൾ ലഭ്യമല്ല</string> <string name="no_links_found_toast">ലിങ്കുകൾ ലഭ്യമല്ല</string>
<string name="copy_link_toast">ലിങ്ക് പകർത്തിയിരിക്കുന്നു</string> <string name="copy_link_toast">ലിങ്ക് പകർത്തിയിരിക്കുന്നു</string>
<string name="play_episode_toast">എപ്പിസോഡ് പ്ലേയ് ചെയ്യുക</string> <string name="play_episode_toast">എപ്പിസോഡ് പ്ലേയ് ചെയ്യുക</string>
@ -122,7 +123,8 @@
<string name="delete">ഡിലീറ്റ്</string> <string name="delete">ഡിലീറ്റ്</string>
<string name="pause">നിർത്തുക</string> <string name="pause">നിർത്തുക</string>
<string name="resume">തുടരുക</string> <string name="resume">തുടരുക</string>
<string name="delete_message">സ്ഥിരമായി %sനെ ഡിലീറ്റ് ചെയ്യുക\nഉറപ്പാണോ?</string> <string name="delete_message">സ്ഥിരമായി %sനെ ഡിലീറ്റ് ചെയ്യുക
\nഉറപ്പാണോ\?</string>
<string name="status_ongoing">തുടരുന്നു</string> <string name="status_ongoing">തുടരുന്നു</string>
<string name="status_completed">പൂർത്തിയായി</string> <string name="status_completed">പൂർത്തിയായി</string>
<string name="status">അവസ്ഥ</string> <string name="status">അവസ്ഥ</string>
@ -162,7 +164,7 @@
<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>
<string name="watch_quality_pref">ഔചിത്യ വീഡിയോ ക്വാളിറ്റി</string> <string name="watch_quality_pref">ഔചിത്യ വീഡിയോ ക്വാളിറ്റി</string>
<string name="history">ചരിത്രം</string> <string name="history">ചരിത്രം</string>

View file

@ -9,7 +9,7 @@
<string name="next_episode_time_min_format" formatted="true">%dm</string> <string name="next_episode_time_min_format" formatted="true">%dm</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="episode_poster_img_des">Aflevering Poster</string> <string name="episode_poster_img_des">Aflevering Poster</string>
<string name="home_main_poster_img_des">Hoofdposter</string> <string name="home_main_poster_img_des">Hoofdposter</string>
<string name="home_next_random_img_des">Volgende willekeurig</string> <string name="home_next_random_img_des">Volgende willekeurig</string>
@ -19,7 +19,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Snelheid (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Snelheid (%.2fx)</string>
<string name="rated_format" formatted="true">Beoordeeld: %.1fAls</string> <string name="rated_format" formatted="true">Beoordeeld: %.1fAls</string>
<string name="new_update_format" formatted="true">Nieuwe update gevonden!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Nieuwe update gevonden!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
@ -108,7 +109,7 @@
<string name="continue_watching">Doorgaan met kijken</string> <string name="continue_watching">Doorgaan met kijken</string>
<string name="action_remove_watching">Verwijder</string> <string name="action_remove_watching">Verwijder</string>
<string name="action_open_watching">Meer Info</string> <string name="action_open_watching">Meer Info</string>
<string name="action_open_play">@string/home_play </string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Een VPN kan nodig zijn om deze provider correct te laten werken</string> <string name="vpn_might_be_needed">Een VPN kan nodig zijn om deze provider correct te laten werken</string>
<string name="vpn_torrent">Deze provider is een torrent, een VPN wordt aanbevolen</string> <string name="vpn_torrent">Deze provider is een torrent, een VPN wordt aanbevolen</string>
<string name="provider_info_meta">Metadata wordt niet geleverd door de site, het laden van video\'s zal mislukken als deze niet op de site bestaat.</string> <string name="provider_info_meta">Metadata wordt niet geleverd door de site, het laden van video\'s zal mislukken als deze niet op de site bestaat.</string>
@ -143,8 +144,8 @@
<string name="backup_settings">Back-up gegevens</string> <string name="backup_settings">Back-up gegevens</string>
<string name="restore_success">Geladen back-up bestand</string> <string name="restore_success">Geladen back-up bestand</string>
<string name="restore_failed_format" formatted="true">Kan gegevens uit bestand niet herstellen %s</string> <string name="restore_failed_format" formatted="true">Kan gegevens uit bestand niet herstellen %s</string>
<string name="backup_success">Gegevens succesvol opgeslagen</string> <string name="backup_success">De gegevens zijn opgeslagen</string>
<string name="backup_failed">Opslagrechten ontbreken, probeer het opnieuw</string> <string name="backup_failed">Opslagrechten ontbreken. Probeer het opnieuw.</string>
<string name="backup_failed_error_format">Fout bij het maken van een back-up %s</string> <string name="backup_failed_error_format">Fout bij het maken van een back-up %s</string>
<string name="search">Zoeken</string> <string name="search">Zoeken</string>
<string name="category_account">Accounts</string> <string name="category_account">Accounts</string>
@ -156,7 +157,7 @@
<string name="bug_report_settings_on">Verstuurt geen gegevens</string> <string name="bug_report_settings_on">Verstuurt geen gegevens</string>
<string name="show_fillers_settings">Toon filler episode voor anime</string> <string name="show_fillers_settings">Toon filler episode voor anime</string>
<string name="show_trailers_settings">Toon trailers</string> <string name="show_trailers_settings">Toon trailers</string>
<string name="kitsu_settings">Toon posters van kitsu</string> <string name="kitsu_settings">Toon posters van Kitsu</string>
<string name="updates_settings">App-updates tonen</string> <string name="updates_settings">App-updates tonen</string>
<string name="updates_settings_des">Automatisch zoeken naar nieuwe updates bij het opstarten</string> <string name="updates_settings_des">Automatisch zoeken naar nieuwe updates bij het opstarten</string>
<string name="uprereleases_settings">Update naar pre-releases</string> <string name="uprereleases_settings">Update naar pre-releases</string>
@ -173,7 +174,7 @@
<string name="copy_link_toast">Link gekopieerd naar klembord</string> <string name="copy_link_toast">Link gekopieerd naar klembord</string>
<string name="play_episode_toast">Aflevering afspelen</string> <string name="play_episode_toast">Aflevering afspelen</string>
<string name="subs_default_reset_toast">Reset naar standaardwaarde</string> <string name="subs_default_reset_toast">Reset naar standaardwaarde</string>
<string name="acra_report_toast">Sorry, de applicatie is gecrasht. Er wordt een anoniem bugrapport naar de ontwikkelaars gestuurd </string> <string name="acra_report_toast">Sorry, de applicatie is gecrasht. Er wordt een anoniem bugrapport naar de ontwikkelaars gestuurd</string>
<string name="season">Seizoen</string> <string name="season">Seizoen</string>
<string name="no_season">Geen seizoen</string> <string name="no_season">Geen seizoen</string>
<string name="episode">Aflevering</string> <string name="episode">Aflevering</string>
@ -189,8 +190,10 @@
<string name="resume">Hervatten</string> <string name="resume">Hervatten</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Dit wordt zeker permanent verwijderd %s\nWeet u het zeker?</string> <string name="delete_message" formatted="true">Dit wordt zeker permanent verwijderd %s
<string name="resume_time_left" formatted="true">%dm\nremaining</string> \nWeet u het zeker\?</string>
<string name="resume_time_left" formatted="true">%dm
\nremaining</string>
<string name="status_ongoing">Voortdurende</string> <string name="status_ongoing">Voortdurende</string>
<string name="status_completed">Voltooid</string> <string name="status_completed">Voltooid</string>
<string name="status">Status</string> <string name="status">Status</string>
@ -219,8 +222,8 @@
<string name="movies_singular">Film</string> <string name="movies_singular">Film</string>
<string name="tv_series_singular">Serie</string> <string name="tv_series_singular">Serie</string>
<string name="cartoons_singular">Tekenfilm</string> <string name="cartoons_singular">Tekenfilm</string>
<string name="anime_singular">@string/anime</string> <string name="anime_singular">\@string/anime</string>
<string name="ova_singular">@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Documentaire</string> <string name="documentaries_singular">Documentaire</string>
<string name="asian_drama_singular">Aziatisch drama</string> <string name="asian_drama_singular">Aziatisch drama</string>
@ -256,7 +259,7 @@
<string name="update">Update</string> <string name="update">Update</string>
<string name="watch_quality_pref">Gewenste kijkwaliteit</string> <string name="watch_quality_pref">Gewenste kijkwaliteit</string>
<string name="limit_title">Maximaal aantal tekens voor titel van videospeler</string> <string name="limit_title">Maximaal aantal tekens voor titel van videospeler</string>
<string name="limit_title_rez">Videospeler Resolutie </string> <string name="limit_title_rez">Videospeler Resolutie</string>
<string name="video_buffer_size_settings">Grootte videobuffer</string> <string name="video_buffer_size_settings">Grootte videobuffer</string>
<string name="video_buffer_length_settings">Lengte videobuffer</string> <string name="video_buffer_length_settings">Lengte videobuffer</string>
<string name="video_buffer_disk_settings">Video cache op schijf</string> <string name="video_buffer_disk_settings">Video cache op schijf</string>
@ -319,7 +322,7 @@
<string name="upload_sync">Sync</string> <string name="upload_sync">Sync</string>
<string name="sync_score">gewaardeerd</string> <string name="sync_score">gewaardeerd</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">Geauthenticeerd %s</string> <string name="authenticated_user" formatted="true">Geauthenticeerd %s</string>
<string name="authenticated_user_fail" formatted="true">Mislukt om te verifiëren aan %s</string> <string name="authenticated_user_fail" formatted="true">Mislukt om te verifiëren aan %s</string>
@ -394,9 +397,12 @@
<string name="skip_setup">Instelling overslaan</string> <string name="skip_setup">Instelling overslaan</string>
<string name="app_layout_subtext">Pas het uiterlijk van de app aan uw apparaat aan</string> <string name="app_layout_subtext">Pas het uiterlijk van de app aan uw apparaat aan</string>
<string name="crash_reporting_title">Crashrapportage</string> <string name="crash_reporting_title">Crashrapportage</string>
<string name="preferred_media_subtext">Wat wil je zien?</string> <string name="preferred_media_subtext">Wat wil je zien\?</string>
<string name="setup_done">Klaar</string> <string name="setup_done">Klaar</string>
<string name="action_mark_as_watched">Markeer als bekeken</string> <string name="action_mark_as_watched">Markeer als bekeken</string>
<string name="history">Geschiedenis</string> <string name="history">Geschiedenis</string>
<string name="play_trailer_button">Speel Trailer</string> <string name="play_trailer_button">Speel Trailer</string>
<string name="autoplay_next_settings_des">Start de volgende episode wanneer deze afgelopen is</string>
<string name="autoplay_next_settings">Volgende episode automatisch afspelen</string>
<string name="update_started">De update is gestart</string>
</resources> </resources>

View file

@ -2,7 +2,7 @@
<resources> <resources>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Plakat</string> <string name="result_poster_img_des">Plakat</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="episode_poster_img_des">Episode Plakat</string> <string name="episode_poster_img_des">Episode Plakat</string>
<string name="home_main_poster_img_des">Main Plakat</string> <string name="home_main_poster_img_des">Main Plakat</string>
<string name="home_next_random_img_des">Neste tilfeldig</string> <string name="home_next_random_img_des">Neste tilfeldig</string>
@ -12,7 +12,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Avspillingshastighet (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Avspillingshastighet (%.2fx)</string>
<string name="rated_format" formatted="true">Vurdert: %.1f</string> <string name="rated_format" formatted="true">Vurdert: %.1f</string>
<string name="new_update_format" formatted="true">Ny oppdatering funnet!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Ny oppdatering funnet!
\n%s -&gt; %s</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="title_home">Hjem</string> <string name="title_home">Hjem</string>
<string name="title_search">Søk</string> <string name="title_search">Søk</string>
@ -142,7 +143,8 @@
<string name="delete">Slett</string> <string name="delete">Slett</string>
<string name="pause">Stopp</string> <string name="pause">Stopp</string>
<string name="resume">Gjenoppta</string> <string name="resume">Gjenoppta</string>
<string name="delete_message">Dette vil slette %s\nEr du sikker?</string> <string name="delete_message">Dette vil slette %s
\nEr du sikker\?</string>
<string name="status_ongoing">Pågående</string> <string name="status_ongoing">Pågående</string>
<string name="status_completed">Fullført</string> <string name="status_completed">Fullført</string>
<string name="status">Posisjon</string> <string name="status">Posisjon</string>
@ -201,22 +203,7 @@
<string name="app_theme_settings">App Tema</string> <string name="app_theme_settings">App Tema</string>
<string name="preferred_media_settings">Foretrukket Videoinnhold</string> <string name="preferred_media_settings">Foretrukket Videoinnhold</string>
<string name="legal_notice" translatable="false">Disclaimer</string> <string name="legal_notice" translatable="false">Disclaimer</string>
<string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application <string name="legal_notice_text" translatable="false">Any legal issues regarding the content on this application should be taken up with the actual file hosts and providers themselves as we are not affiliated with them. In case of copyright infringement, please directly contact the responsible parties or the streaming websites. The app is purely for educational and personal use. CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down. CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient, user-friendly interface. It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk.</string>
should be taken up with the actual file hosts and providers themselves as we are not affiliated with them.
In case of copyright infringement, please directly contact the responsible parties or the streaming websites.
The app is purely for educational and personal use.
CloudStream 3 does not host any content on the app, and has no control over what media is put up or taken down.
CloudStream 3 functions like any other search engine, such as Google. CloudStream 3 does not host, upload or
manage any videos, films or content. It simply crawls, aggregates and displayes links in a convenient,
user-friendly interface.
It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the
responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use
CloudStream 3 at your own risk.
</string>
<string name="cast_format" formatted="true">Besetning: %s</string> <string name="cast_format" formatted="true">Besetning: %s</string>
<string name="next_episode_time_min_format" formatted="true">%dm</string> <string name="next_episode_time_min_format" formatted="true">%dm</string>
<string name="sort_clear">Tøm</string> <string name="sort_clear">Tøm</string>
@ -503,4 +490,6 @@
<string name="apk_installer_settings">APK-installatør</string> <string name="apk_installer_settings">APK-installatør</string>
<string name="apk_installer_settings_des">Noen enheter støtter ikke den nye pakkeinstallatøren. Prøv gammeldags alternativ hvis ting ikke installeres.</string> <string name="apk_installer_settings_des">Noen enheter støtter ikke den nye pakkeinstallatøren. Prøv gammeldags alternativ hvis ting ikke installeres.</string>
<string name="update_started">Oppdatering startet</string> <string name="update_started">Oppdatering startet</string>
<string name="plugin_downloaded">Programtillegg nedlastet</string>
<string name="delayed_update_notice">Programmet vil oppgraderes når du avslutter det</string>
</resources> </resources>

View file

@ -2,16 +2,17 @@
<!--https://newbedev.com/concatenate-multiple-strings-in-xml--><resources> <!--https://newbedev.com/concatenate-multiple-strings-in-xml--><resources>
<string name="player_speed_text_format" formatted="true">Prędkość (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Prędkość (%.2fx)</string>
<string name="rated_format" formatted="true">Ocena: %.1f</string> <string name="rated_format" formatted="true">Ocena: %.1f</string>
<string name="new_update_format" formatted="true">Znaleziono nową aktualizację!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Znaleziono nową aktualizację!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<string name="app_dub_sub_episode_text_format">%s Odc. %d</string> <string name="app_dub_sub_episode_text_format">%s Odc. %d</string>
<string name="result_poster_img_des">Plakat</string> <string name="result_poster_img_des">Obrazek</string>
<string name="episode_poster_img_des">Plakat odcinka</string> <string name="episode_poster_img_des">Obrazek odcinka</string>
<string name="home_main_poster_img_des">Główny plakat</string> <string name="home_main_poster_img_des">Główny obrazek</string>
<string name="home_next_random_img_des">Następny losowy</string> <string name="home_next_random_img_des">Następny losowy</string>
<string name="go_back_img_des">Wstecz</string> <string name="go_back_img_des">Wstecz</string>
<string name="home_change_provider_img_des">Zmień dostawcę</string> <string name="home_change_provider_img_des">Zmień źródło</string>
<string name="preview_background_img_des">Pogląd tła</string> <string name="preview_background_img_des">Pogląd tła</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="title_home">Główna</string> <string name="title_home">Główna</string>
@ -23,7 +24,7 @@
<string name="no_data">Brak danych</string> <string name="no_data">Brak danych</string>
<string name="episode_more_options_des">Więcej opcji</string> <string name="episode_more_options_des">Więcej opcji</string>
<string name="next_episode">Następny odcinek</string> <string name="next_episode">Następny odcinek</string>
<string name="next_episode_format">Odcinek %d będzie udostępniony</string> <string name="next_episode_format">Odcinek %d wyjdzie za</string>
<string name="result_tags">Gatunki</string> <string name="result_tags">Gatunki</string>
<string name="result_share">Udostępnij</string> <string name="result_share">Udostępnij</string>
<string name="result_open_in_browser">Otwórz w przeglądarce</string> <string name="result_open_in_browser">Otwórz w przeglądarce</string>
@ -52,11 +53,11 @@
<string name="download_failed">Błąd przy pobieraniu</string> <string name="download_failed">Błąd przy pobieraniu</string>
<string name="download_canceled">Anulowano pobieranie</string> <string name="download_canceled">Anulowano pobieranie</string>
<string name="download_done">Zakończono pobieranie</string> <string name="download_done">Zakończono pobieranie</string>
<string name="stream">Stream</string> <string name="stream">Odtwórz</string>
<string name="error_loading_links_toast">Błąd przy ładowaniu linków</string> <string name="error_loading_links_toast">Błąd przy ładowaniu linków</string>
<string name="download_storage_text">Pamięć wewnętrzna</string> <string name="download_storage_text">Pamięć wewnętrzna</string>
<string name="app_dubbed_text">Dub</string> <string name="app_dubbed_text">Dub</string>
<string name="app_subbed_text">Sub</string> <string name="app_subbed_text">Nap</string>
<string name="popup_delete_file">Usuń plik</string> <string name="popup_delete_file">Usuń plik</string>
<string name="popup_play_file">Odtwórz plik</string> <string name="popup_play_file">Odtwórz plik</string>
<string name="popup_resume_download">Wznów pobieranie</string> <string name="popup_resume_download">Wznów pobieranie</string>
@ -86,7 +87,7 @@
<string name="subs_subtitle_elevation">Wzniesienie napisów</string> <string name="subs_subtitle_elevation">Wzniesienie napisów</string>
<string name="subs_font">Czcionka</string> <string name="subs_font">Czcionka</string>
<string name="subs_font_size">Rozmiar czcionki</string> <string name="subs_font_size">Rozmiar czcionki</string>
<string name="search_provider_text_providers">Szukaj według dostawców</string> <string name="search_provider_text_providers">Szukaj według źródeł</string>
<string name="search_provider_text_types">Szukaj według typów</string> <string name="search_provider_text_types">Szukaj według typów</string>
<string name="benene_count_text">Dano %d bananów</string> <string name="benene_count_text">Dano %d bananów</string>
<string name="benene_count_text_none">Brak bananów</string> <string name="benene_count_text_none">Brak bananów</string>
@ -94,12 +95,12 @@
<string name="subs_download_languages">Pobieranie języków</string> <string name="subs_download_languages">Pobieranie języków</string>
<string name="subs_subtitle_languages">Język napisów</string> <string name="subs_subtitle_languages">Język napisów</string>
<string name="subs_hold_to_reset_to_default">Przytrzymaj, aby zresetować</string> <string name="subs_hold_to_reset_to_default">Przytrzymaj, aby zresetować</string>
<string name="subs_import_text" formatted="true">Importuj czcionki umieszczając je w %s</string> <string name="subs_import_text" formatted="true">Importuj czcionki, umieszczając je w %s</string>
<string name="continue_watching">Kontyntynuj oglądanie</string> <string name="continue_watching">Kontyntynuj oglądanie</string>
<string name="action_remove_watching">Usuń</string> <string name="action_remove_watching">Usuń</string>
<string name="action_open_watching">Więcej informacji</string> <string name="action_open_watching">Więcej informacji</string>
<string name="vpn_might_be_needed">Połączenie przez VPN może być wymagane</string> <string name="vpn_might_be_needed">Połączenie przez VPN może być wymagane</string>
<string name="vpn_torrent">Ten dostawca jest torrentem, wskazane jest użycie połączenia VPN</string> <string name="vpn_torrent">To źródło jest torrentem, wskazane jest użycie połączenia VPN</string>
<string name="provider_info_meta">Metadane nie są dostarczane przez witrynę, ładowanie filmu nie powiedzie się, jeśli nie ma ich w witrynie.</string> <string name="provider_info_meta">Metadane nie są dostarczane przez witrynę, ładowanie filmu nie powiedzie się, jeśli nie ma ich w witrynie.</string>
<string name="torrent_plot">Opis</string> <string name="torrent_plot">Opis</string>
<string name="normal_no_plot">Nie znaleziono opisu</string> <string name="normal_no_plot">Nie znaleziono opisu</string>
@ -107,25 +108,25 @@
<string name="show_log_cat">Pokaż Logcat 🐈</string> <string name="show_log_cat">Pokaż Logcat 🐈</string>
<string name="picture_in_picture">Obraz-w-obrazie</string> <string name="picture_in_picture">Obraz-w-obrazie</string>
<string name="picture_in_picture_des">Oglądaj w małym, pływającym okienku</string> <string name="picture_in_picture_des">Oglądaj w małym, pływającym okienku</string>
<string name="player_size_settings">Przycisk zmiany rozmiaru</string> <string name="player_size_settings">Zmień rozmiar odtwarzacza</string>
<string name="player_size_settings_des">Usuwanie czarnych ramek</string> <string name="player_size_settings_des">Usuwanie czarnych ramek</string>
<string name="player_subtitles_settings">Napisy</string> <string name="player_subtitles_settings">Napisy</string>
<string name="player_subtitles_settings_des">Ustawienia napisów</string> <string name="player_subtitles_settings_des">Ustawienia napisów</string>
<string name="chromecast_subtitles_settings">Napisy Chromecast</string> <string name="chromecast_subtitles_settings">Napisy Chromecast</string>
<string name="chromecast_subtitles_settings_des">Ustawienia napisów Chromecast</string> <string name="chromecast_subtitles_settings_des">Ustawienia napisów Chromecast</string>
<string name="eigengraumode_settings">Tryb Eigengrau</string> <string name="eigengraumode_settings">Tryb Eigengravy</string>
<string name="eigengraumode_settings_des">Ustawienia prędkości</string> <string name="eigengraumode_settings_des">Ustawienia prędkości</string>
<string name="swipe_to_seek_settings">Przesuwaj aby przeglądać</string> <string name="swipe_to_seek_settings">Przesuń aby przewinąć</string>
<string name="swipe_to_seek_settings_des">Przesuwaj w lewo lub prawo aby kontrolować czas</string> <string name="swipe_to_seek_settings_des">Przesuń w lewo lub prawo aby kontrolować czas</string>
<string name="swipe_to_change_settings">Przesuwaj aby zmienić ustawienia</string> <string name="swipe_to_change_settings">Przesuń aby zmienić ustawienia</string>
<string name="swipe_to_change_settings_des">Przesuwaj po lewej lub prawej stronie aby zmienić jasność i głośność</string> <string name="swipe_to_change_settings_des">Przesuń góra-dół z lewej lub prawej aby zmienić jasność i głośność</string>
<string name="autoplay_next_settings">Autoodtwarzanie następnego odcinka</string> <string name="autoplay_next_settings">Autoodtwarzanie następnego odcinka</string>
<string name="autoplay_next_settings_des">Rozpocznij następny odcinek po zakończeniu bieżącego</string> <string name="autoplay_next_settings_des">Rozpocznij następny odcinek po skończeniu bieżącego</string>
<string name="double_tap_to_seek_amount_settings">Wielkość skoku przy podwójnym stuknięciu</string> <string name="double_tap_to_seek_amount_settings">Czas przewinięcia przy podwójnym kliknięciu</string>
<string name="double_tap_to_seek_settings">Podwójne stuknięcie aby przeglądać</string> <string name="double_tap_to_seek_settings">Podwójne kliknięcie aby przewinąć</string>
<string name="double_tap_to_seek_settings_des">Stuknij 2 razy z prawej lub lewej strony aby przeglądać</string> <string name="double_tap_to_seek_settings_des">Kliknij 2 razy z prawej lub lewej strony aby przewinąć</string>
<string name="double_tap_to_pause_settings">Stuknij dwukrotnie, aby wstrzymać</string> <string name="double_tap_to_pause_settings">Kliknij dwukrotnie aby wstrzymać</string>
<string name="double_tap_to_pause_settings_des">Stuknij na środku, aby wstrzymać</string> <string name="double_tap_to_pause_settings_des">Kliknij na środku, aby zatrzymać wideo</string>
<string name="use_system_brightness_settings">Użyj jasności systemowej</string> <string name="use_system_brightness_settings">Użyj jasności systemowej</string>
<string name="use_system_brightness_settings_des">Użyj jasności systemowej w odtwarzaczu aplikacji zamiast ciemnej nakładki</string> <string name="use_system_brightness_settings_des">Użyj jasności systemowej w odtwarzaczu aplikacji zamiast ciemnej nakładki</string>
<string name="episode_sync_settings">Aktualizuj postęp oglądania</string> <string name="episode_sync_settings">Aktualizuj postęp oglądania</string>
@ -142,23 +143,23 @@
<string name="category_updates">Aktualizacje i kopia zapasowa</string> <string name="category_updates">Aktualizacje i kopia zapasowa</string>
<string name="settings_info">Informacje</string> <string name="settings_info">Informacje</string>
<string name="advanced_search">Zaawansowane wyszukiwanie</string> <string name="advanced_search">Zaawansowane wyszukiwanie</string>
<string name="advanced_search_des">Szukaj z podziałem na dostawców</string> <string name="advanced_search_des">Szukaj z podziałem na źródła</string>
<string name="bug_report_settings_off">Wysyłaj dane tylko przy awariach</string> <string name="bug_report_settings_off">Wysyłaj dane tylko przy awariach</string>
<string name="bug_report_settings_on">Nie wysyłaj żadnych danych</string> <string name="bug_report_settings_on">Nie wysyłaj żadnych danych</string>
<string name="show_fillers_settings">Pokaż odcinek wypełniający dla anime</string> <string name="show_fillers_settings">Pokaż fillery dla anime</string>
<string name="show_trailers_settings">Pokaż zwiastuny</string> <string name="show_trailers_settings">Pokaż zwiastuny</string>
<string name="kitsu_settings">Pokaż plakaty z Kitsu</string> <string name="kitsu_settings">Pokaż obrazki z Kitsu</string>
<string name="pref_filter_search_quality">Ukryj wybraną jakość wideo w wynikach wyszukiwania</string> <string name="pref_filter_search_quality">Ukryj wybraną jakość wideo w wynikach wyszukiwania</string>
<string name="automatic_plugin_updates">Automatyczne aktualizacje rozszerzeń</string> <string name="automatic_plugin_updates">Automatyczne aktualizacje rozszerzeń</string>
<string name="automatic_plugin_download">Automatyczne pobieranie rozszerzeń</string> <string name="automatic_plugin_download">Automatyczne pobieranie rozszerzeń</string>
<string name="updates_settings">Pokazuj aktualizacje</string> <string name="updates_settings">Pokazuj aktualizacje</string>
<string name="updates_settings_des">Automatycznie wyszukuj aktualizacji przy starcie</string> <string name="updates_settings_des">Automatycznie wyszukuj aktualizacje przy starcie</string>
<string name="uprereleases_settings">Aktualizuj do wersji beta</string> <string name="uprereleases_settings">Aktualizuj do wersji beta</string>
<string name="uprereleases_settings_des">Wyszukuj wersji beta, zamiast pełnych wydań</string> <string name="uprereleases_settings_des">Wyszukuj wersji beta, zamiast oficjalnych wydań</string>
<string name="github">Github</string> <string name="github">Github</string>
<string name="lightnovel">Aplikacja do noweli</string> <string name="lightnovel">Aplikacja do light novel od nas</string>
<string name="anim">Aplikacja do anime</string> <string name="anim">Aplikacja do anime od nas</string>
<string name="discord">Discord</string> <string name="discord">Serwer Discord</string>
<string name="benene">Daj banana programistom</string> <string name="benene">Daj banana programistom</string>
<string name="benene_des">Dano banana</string> <string name="benene_des">Dano banana</string>
<string name="app_language">Język aplikacji</string> <string name="app_language">Język aplikacji</string>
@ -167,7 +168,7 @@
<string name="copy_link_toast">Skopiowano do schowka</string> <string name="copy_link_toast">Skopiowano do schowka</string>
<string name="play_episode_toast">Odtwórz odcinek</string> <string name="play_episode_toast">Odtwórz odcinek</string>
<string name="subs_default_reset_toast">Zresetowano</string> <string name="subs_default_reset_toast">Zresetowano</string>
<string name="acra_report_toast">Awaria aplikacji. Anonimowe zgłoszenie błedu zostanie wysłane programistom</string> <string name="acra_report_toast">Awaria aplikacji. Anonimowe zgłoszenie błędu zostanie wysłane programistom</string>
<string name="season">Sezon</string> <string name="season">Sezon</string>
<string name="season_format">%s %d%s</string> <string name="season_format">%s %d%s</string>
<string name="no_season">Brak sezonu</string> <string name="no_season">Brak sezonu</string>
@ -184,9 +185,11 @@
<string name="resume">Odtwórz</string> <string name="resume">Odtwórz</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Spowoduje to trwałe usunięcie %s\nCzy jesteś pewien?</string> <string name="delete_message" formatted="true">Spowoduje to trwałe usunięcie %s
<string name="resume_time_left" formatted="true">%dm\npozostało</string> \nCzy jesteś pewien\?</string>
<string name="status_ongoing">Bierzący</string> <string name="resume_time_left" formatted="true">%dm
\npozostało</string>
<string name="status_ongoing">Bieżący</string>
<string name="status_completed">Zakończone</string> <string name="status_completed">Zakończone</string>
<string name="status">Status</string> <string name="status">Status</string>
<string name="year">Rok</string> <string name="year">Rok</string>
@ -202,13 +205,13 @@
<string name="app_storage">Aplikacja</string> <string name="app_storage">Aplikacja</string>
<!--plural--> <!--plural-->
<string name="movies">Filmy</string> <string name="movies">Filmy</string>
<string name="tv_series">Serial telewizyjny</string> <string name="tv_series">Seriale telewizyjne</string>
<string name="cartoons">Kreskówki</string> <string name="cartoons">Kreskówki</string>
<string name="anime">Anime</string> <string name="anime">Anime</string>
<string name="torrent">Torrenty</string> <string name="torrent">Torrenty</string>
<string name="documentaries">Filmy dokumentalne</string> <string name="documentaries">Filmy dokumentalne</string>
<string name="ova">OVA</string> <string name="ova">OVA</string>
<string name="asian_drama">Filmy azjatyckie</string> <string name="asian_drama">Dramy azjatyckie</string>
<string name="livestreams">Transmisje na żywo</string> <string name="livestreams">Transmisje na żywo</string>
<string name="nsfw">NSFW</string> <string name="nsfw">NSFW</string>
<string name="others">Inne</string> <string name="others">Inne</string>
@ -218,7 +221,7 @@
<string name="cartoons_singular">Kreskówka</string> <string name="cartoons_singular">Kreskówka</string>
<string name="torrent_singular">Torrent</string> <string name="torrent_singular">Torrent</string>
<string name="documentaries_singular">Film dokumentalny</string> <string name="documentaries_singular">Film dokumentalny</string>
<string name="asian_drama_singular">Film azjatycki</string> <string name="asian_drama_singular">Drama azjatycka</string>
<string name="live_singular">Transmisja na żywo</string> <string name="live_singular">Transmisja na żywo</string>
<string name="nsfw_singular">NSFW</string> <string name="nsfw_singular">NSFW</string>
<string name="other_singular">Inne</string> <string name="other_singular">Inne</string>
@ -226,48 +229,48 @@
<string name="remote_error">Zdalny błąd</string> <string name="remote_error">Zdalny błąd</string>
<string name="render_error">Błąd renderowania</string> <string name="render_error">Błąd renderowania</string>
<string name="unexpected_error">Nieoczekiwany błąd odtwarzacza</string> <string name="unexpected_error">Nieoczekiwany błąd odtwarzacza</string>
<string name="storage_error">Błąd pobierania, sprawdź uprawnienia</string> <string name="storage_error">Błąd pobierania, sprawdź uprawnienia aplikacji</string>
<string name="episode_action_chromecast_episode">Chromecast odcinka</string> <string name="episode_action_chromecast_episode">odcinek Chromecast</string>
<string name="episode_action_chromecast_mirror">Chromecast mirroru</string> <string name="episode_action_chromecast_mirror">mirror dla Chromecast</string>
<string name="episode_action_play_in_app">Odtwórz w aplikacji</string> <string name="episode_action_play_in_app">Odtwórz w aplikacji</string>
<string name="episode_action_play_in_format">Odtwórz w %s</string> <string name="episode_action_play_in_format">Odtwórz w %s</string>
<string name="episode_action_play_in_browser">Odtwórz w przeglądarce</string> <string name="episode_action_play_in_browser">Odtwórz w przeglądarce</string>
<string name="episode_action_copy_link">Kopiuj link</string> <string name="episode_action_copy_link">Kopiuj link</string>
<string name="episode_action_auto_download">Automatyczne pobieranie</string> <string name="episode_action_auto_download">Automatyczne pobieranie</string>
<string name="episode_action_download_mirror">Pobierz mirror</string> <string name="episode_action_download_mirror">Pobierz mirror</string>
<string name="episode_action_reload_links">Odświerz linki</string> <string name="episode_action_reload_links">Odśwież linki</string>
<string name="episode_action_download_subtitle">Pobierz napisy</string> <string name="episode_action_download_subtitle">Pobierz napisy</string>
<string name="show_hd">Etykieta jakości</string> <string name="show_hd">Etykieta jakości</string>
<string name="show_dub">Etykieta dubbingu</string> <string name="show_dub">Etykieta dubbingu</string>
<string name="show_sub">Etykieta napisów</string> <string name="show_sub">Etykieta napisów</string>
<string name="show_title">Tytuł</string> <string name="show_title">Tytuł</string>
<string name="poster_ui_settings">Włącz elementy interfejsu na plakatach</string> <string name="poster_ui_settings">Pokaż elementy interfejsu na obrazkach</string>
<string name="no_update_found">Nie znaleziono aktualizacji</string> <string name="no_update_found">Nie znaleziono aktualizacji</string>
<string name="check_for_update">Sprawdź czy jest aktualizacja</string> <string name="check_for_update">Sprawdź, czy jest aktualizacja</string>
<string name="video_lock">Zablokuj</string> <string name="video_lock">Zablokuj</string>
<string name="video_aspect_ratio_resize">Rozmiar</string> <string name="video_aspect_ratio_resize">Zmień rozmiar</string>
<string name="video_source">Źródlo</string> <string name="video_source">Źródło</string>
<string name="video_skip_op">Pomiń OP</string> <string name="video_skip_op">Pomiń OP</string>
<string name="dont_show_again">Nie pokazuj ponownie</string> <string name="dont_show_again">Nie pokazuj ponownie</string>
<string name="skip_update">Pomiń tę aktualizację</string> <string name="skip_update">Pomiń tę aktualizację</string>
<string name="update">Aktualizacja</string> <string name="update">Aktualizacja</string>
<string name="watch_quality_pref">Domyślna jakość</string> <string name="watch_quality_pref">Domyślna jakość</string>
<string name="limit_title">Maksymalna ilość znaków tytułu w odtwarzaczu</string> <string name="limit_title">Maksymalna ilość znaków w tytule odtwarzacza</string>
<string name="limit_title_rez">Zawartość tytułu w odtwarzaczu</string> <string name="limit_title_rez">Rozdzielczość odtwarzacza wideo</string>
<string name="video_buffer_size_settings">Rozmiar bufora wideo</string> <string name="video_buffer_size_settings">Rozmiar bufora wideo</string>
<string name="video_buffer_length_settings">Długość bufora wideo</string> <string name="video_buffer_length_settings">Długość bufora wideo</string>
<string name="video_buffer_disk_settings">Pamięć podręczna wideo na dysku</string> <string name="video_buffer_disk_settings">Pamięć podręczna wideo na dysku</string>
<string name="video_buffer_clear_settings">Wyczyść pamięć podręczną wideo i obrazów</string> <string name="video_buffer_clear_settings">Wyczyść pamięć podręczną wideo i obrazów</string>
<string name="video_ram_description">Ustawienie zbyt wysokiej wartości może powodować problemy w systemach z małą ilością pamięci RAM, takich jak urządzenia Android TV lub stare telefony.</string> <string name="video_ram_description">Ustawienie zbyt wysokiej wartości może powodować problemy na urządzeniach z małą ilością pamięci RAM, takich jak urządzenia Android TV lub stare telefony.</string>
<string name="video_disk_description">Zbyt wysokie ustawienie może powodować problemy w systemach z małą ilością miejsca w pamięci, takich jak urządzenia Android TV.</string> <string name="video_disk_description">Zbyt wysokie ustawienie może powodować problemy na urządzeniach z małą ilością dostęponej pamięci, takich jak urządzenia Android TV.</string>
<string name="dns_pref">DNS przez HTTPS</string> <string name="dns_pref">DNS over HTTPS</string>
<string name="dns_pref_summary">Przydatne w pomijaniu blokad dostawców internetu</string> <string name="dns_pref_summary">Przydatne w pomijaniu blokad dostawców internetu</string>
<string name="add_site_pref">Sklonuj stronę</string> <string name="add_site_pref">Sklonuj stronę</string>
<string name="remove_site_pref">Usuń stronę</string> <string name="remove_site_pref">Usuń stronę</string>
<string name="add_site_summary">Dodaj klona istniejącej strony z innym adresem URL</string> <string name="add_site_summary">Dodaj klona istniejącej strony z innym adresem URL</string>
<string name="download_path_pref">Ścieżka pobierania</string> <string name="download_path_pref">Ścieżka pobierania</string>
<string name="nginx_url_pref">URL serwera Nginx</string> <string name="nginx_url_pref">URL serwera Nginx</string>
<string name="display_subbed_dubbed_settings">Wyświetlanie Anime z dubbingiem/subbingiem</string> <string name="display_subbed_dubbed_settings">Wyświetlanie Anime z dubbingiem/napisami</string>
<string name="resize_fit">Dopasuj do ekranu</string> <string name="resize_fit">Dopasuj do ekranu</string>
<string name="resize_fill">Rozciągnij</string> <string name="resize_fill">Rozciągnij</string>
<string name="resize_zoom">Powiększ</string> <string name="resize_zoom">Powiększ</string>
@ -275,12 +278,12 @@
<string name="category_general">Ogólne</string> <string name="category_general">Ogólne</string>
<string name="random_button_settings">Przycisk do losowania</string> <string name="random_button_settings">Przycisk do losowania</string>
<string name="random_button_settings_desc">Pokaż przycisk do losowania na stronie głównej</string> <string name="random_button_settings_desc">Pokaż przycisk do losowania na stronie głównej</string>
<string name="provider_lang_settings">Języki dostawców</string> <string name="provider_lang_settings">Języki źródeł</string>
<string name="app_layout">Układ aplikacji</string> <string name="app_layout">Układ aplikacji</string>
<string name="preferred_media_settings">Preferowane media</string> <string name="preferred_media_settings">Preferowane media</string>
<string name="enable_nsfw_on_providers">Włącz NSFW u obsługiwanych dostawców</string> <string name="enable_nsfw_on_providers">Włącz NSFW w obsługiwanych źródłach</string>
<string name="subtitles_encoding">Kodowanie napisów</string> <string name="subtitles_encoding">Kodowanie napisów</string>
<string name="category_providers">Dostawcy</string> <string name="category_providers">Źródła</string>
<string name="category_ui">Układ interfejsu</string> <string name="category_ui">Układ interfejsu</string>
<string name="automatic">Automatyczny</string> <string name="automatic">Automatyczny</string>
<string name="tv_layout">Układ dla telewizorów</string> <string name="tv_layout">Układ dla telewizorów</string>
@ -288,8 +291,8 @@
<string name="emulator_layout">Układ dla emulatorów</string> <string name="emulator_layout">Układ dla emulatorów</string>
<string name="primary_color_settings">Kolor podstawowy</string> <string name="primary_color_settings">Kolor podstawowy</string>
<string name="app_theme_settings">Motyw aplikacji</string> <string name="app_theme_settings">Motyw aplikacji</string>
<string name="bottom_title_settings">Pozycja tytułu względem plakatu</string> <string name="bottom_title_settings">Pozycja tytułu względem obrazka</string>
<string name="bottom_title_settings_des">Ustaw tytuł pod plakatem</string> <string name="bottom_title_settings_des">Ustaw tytuł pod obrazkiem</string>
<string name="example_lang_name">Kod języka (pl)</string> <string name="example_lang_name">Kod języka (pl)</string>
<string name="login_format" formatted="true">%s %s</string> <string name="login_format" formatted="true">%s %s</string>
<string name="account">konto</string> <string name="account">konto</string>
@ -301,7 +304,7 @@
<string name="add_sync">Dodaj synchronizację</string> <string name="add_sync">Dodaj synchronizację</string>
<string name="added_sync_format" formatted="true">Dodano %s</string> <string name="added_sync_format" formatted="true">Dodano %s</string>
<string name="upload_sync">Synchronizacja</string> <string name="upload_sync">Synchronizacja</string>
<string name="sync_score">Ocenione</string> <string name="sync_score">Oceniono</string>
<string name="sync_score_format" formatted="true">%d na 10</string> <string name="sync_score_format" formatted="true">%d na 10</string>
<string name="authenticated_user" formatted="true">Uwierzytelniono %s</string> <string name="authenticated_user" formatted="true">Uwierzytelniono %s</string>
<string name="authenticated_user_fail" formatted="true">Nie udało się uwierzytelnić %s</string> <string name="authenticated_user_fail" formatted="true">Nie udało się uwierzytelnić %s</string>
@ -312,9 +315,9 @@
<string name="max">Maks</string> <string name="max">Maks</string>
<string name="min">Min</string> <string name="min">Min</string>
<string name="subtitles_outline">Kontur</string> <string name="subtitles_outline">Kontur</string>
<string name="subtitles_depressed">Wciśnięte</string> <string name="subtitles_depressed">Obniżone</string>
<string name="subtitles_shadow">Cień</string> <string name="subtitles_shadow">Cień</string>
<string name="subtitles_raised">Zniesione</string> <string name="subtitles_raised">Wzniesione</string>
<string name="subtitle_offset">Synchronizacja napisów</string> <string name="subtitle_offset">Synchronizacja napisów</string>
<string name="subtitle_offset_hint">1000 ms</string> <string name="subtitle_offset_hint">1000 ms</string>
<string name="subtitle_offset_title">Opóźnienie napisów</string> <string name="subtitle_offset_title">Opóźnienie napisów</string>
@ -327,7 +330,7 @@
<string name="player_load_subtitles">Wczytaj z pliku</string> <string name="player_load_subtitles">Wczytaj z pliku</string>
<string name="player_load_subtitles_online">Wczytaj z Internetu</string> <string name="player_load_subtitles_online">Wczytaj z Internetu</string>
<string name="downloaded_file">Pobrano plik</string> <string name="downloaded_file">Pobrano plik</string>
<string name="actor_main">Główna</string> <string name="actor_main">Główny</string>
<string name="actor_supporting">Drugoplanowy</string> <string name="actor_supporting">Drugoplanowy</string>
<string name="actor_background">Pomocniczy</string> <string name="actor_background">Pomocniczy</string>
<string name="home_source">Źródło</string> <string name="home_source">Źródło</string>
@ -349,7 +352,7 @@
<string name="quality_hdr">HDR</string> <string name="quality_hdr">HDR</string>
<string name="quality_sdr">SDR</string> <string name="quality_sdr">SDR</string>
<string name="quality_webrip">Web</string> <string name="quality_webrip">Web</string>
<string name="poster_image">Obraz plakatu</string> <string name="poster_image">Obrazek</string>
<string name="category_player">Odtwarzacz</string> <string name="category_player">Odtwarzacz</string>
<string name="resolution_and_title">Rozdzielczość i tytuł</string> <string name="resolution_and_title">Rozdzielczość i tytuł</string>
<string name="title">Tytuł</string> <string name="title">Tytuł</string>
@ -358,26 +361,26 @@
<string name="error_invalid_data">Niepoprawne dane</string> <string name="error_invalid_data">Niepoprawne dane</string>
<string name="error_invalid_url">Niepoprawny URL</string> <string name="error_invalid_url">Niepoprawny URL</string>
<string name="error">Błąd</string> <string name="error">Błąd</string>
<string name="subtitles_remove_captions">Usuń informacje dla niesłyszących z napisów</string> <string name="subtitles_remove_captions">Usuń CC z napisów</string>
<string name="subtitles_remove_bloat">Usuń nadmiarowe informacje z napisów</string> <string name="subtitles_remove_bloat">Usuń nadmiarowe informacje z napisów</string>
<string name="subtitles_filter_lang">Filtrowanie wg preferowanego języka mediów</string> <string name="subtitles_filter_lang">Filtrowanie wg preferowanego języka</string>
<string name="extras">Dodatki</string> <string name="extras">Dodatki</string>
<string name="trailer">Zwiastun</string> <string name="trailer">Zwiastun</string>
<string name="referer">Odsyłacz</string> <string name="referer">Odsyłacz</string>
<string name="next">Dalej</string> <string name="next">Następny</string>
<string name="provider_languages_tip">Wyświetlaj filmy w wybranych językach</string> <string name="provider_languages_tip">Wyświetlaj filmy w tych językach</string>
<string name="previous">Cofnij</string> <string name="previous">Poprzedni</string>
<string name="skip_setup">Pomiń</string> <string name="skip_setup">Pomiń setup</string>
<string name="app_layout_subtext">Dostosuj wygląd aplikacji do urządzenia</string> <string name="app_layout_subtext">Dostosuj wygląd aplikacji do urządzenia</string>
<string name="crash_reporting_title">Przekazywanie błędów</string> <string name="crash_reporting_title">Zgłaszanie błędów</string>
<string name="preferred_media_subtext">Preferowany rodzaj filmów</string> <string name="preferred_media_subtext">Co chciałbyś obejrzeć\?</string>
<string name="setup_done">Gotowe</string> <string name="setup_done">Gotowe</string>
<string name="extensions">Dodatki</string> <string name="extensions">Rozszerzenia</string>
<string name="add_repository">Dodaj repozytorium</string> <string name="add_repository">Dodaj repozytorium</string>
<string name="repository_name_hint">Nazwa repozytorium</string> <string name="repository_name_hint">Nazwa repozytorium</string>
<string name="repository_url_hint">Adres URL repozytorium</string> <string name="repository_url_hint">Adres URL repozytorium</string>
<string name="plugin_loaded">Rozszerzenie załadowane</string> <string name="plugin_loaded">Załadowano rozszerzenie</string>
<string name="plugin_deleted">Rozszerzenie usunięte</string> <string name="plugin_deleted">Usunięto rozszerzenie</string>
<string name="plugin_load_fail" formatted="true">Błąd ładowania %s</string> <string name="plugin_load_fail" formatted="true">Błąd ładowania %s</string>
<string name="is_adult">18+</string> <string name="is_adult">18+</string>
<string name="batch_download_start_format" formatted="true">Rozpoczęto pobieranie %d %s…</string> <string name="batch_download_start_format" formatted="true">Rozpoczęto pobieranie %d %s…</string>
@ -395,24 +398,24 @@
<string name="plugins_updated">Zaaktualizowano %d rozszerzeń</string> <string name="plugins_updated">Zaaktualizowano %d rozszerzeń</string>
<string name="blank_repo_message">CloudStream nie ma domyślnie zainstalowanych żadnych witryn. Musisz zainstalować witryny z repozytoriów. <string name="blank_repo_message">CloudStream nie ma domyślnie zainstalowanych żadnych witryn. Musisz zainstalować witryny z repozytoriów.
\n \n
\nZ powodu bezmyślnego usunięcia DMCA przez Sky UK Limited 🤮 nie możemy zamieścić linku dowitryny z repozytoriami. \nZ powodu bezmyślnego usunięcia DMCA przez Sky UK Limited 🤮 nie możemy zamieścić linku do witryny z repozytoriami.
\n \n
\nDołącz do naszego Discorda lub szukaj online.</string> \nDołącz do naszego Discorda lub poszukaj online.</string>
<string name="view_public_repositories_button">Zobacz repozytoria społeczności</string> <string name="view_public_repositories_button">Zobacz repozytoria społeczności</string>
<string name="view_public_repositories_button_short">Publiczna lista</string> <string name="view_public_repositories_button_short">Publiczna lista</string>
<string name="uppercase_all_subtitles">Wszystkie napisy wielką literą</string> <string name="uppercase_all_subtitles">Wszystkie napisy wielką literą</string>
<string name="download_all_plugins_from_repo">Pobrać wszystkie rozszerzenia z tego repozytorium?</string> <string name="download_all_plugins_from_repo">Pobrać wszystkie rozszerzenia z tego repozytorium\?</string>
<string name="single_plugin_disabled" formatted="true">%s (Wyłączone)</string> <string name="single_plugin_disabled" formatted="true">%s (Wyłączone)</string>
<string name="tracks">Ścieżki</string> <string name="tracks">Ścieżki</string>
<string name="audio_tracks">Ścieżki audio</string> <string name="audio_tracks">Ścieżki audio</string>
<string name="video_tracks">Ścieżki wideo</string> <string name="video_tracks">Ścieżki wideo</string>
<string name="apply_on_restart">Zastosuj po ponownym uruchomieniu</string> <string name="apply_on_restart">Zastosuj po ponownym uruchomieniu</string>
<string name="safe_mode_title">Tryb bezpieczny włączony</string> <string name="safe_mode_title">Tryb bezpieczny włączony</string>
<string name="safe_mode_description">Wszystkie rozszerzenia zostały wyłączone z powodu awarii, aby pomóc Ci znaleźć ten, który powoduje problemy.</string> <string name="safe_mode_description">Z powodu wystąpienia błędu wszystkie rozszerzenia zostały wyłączone, aby ułatwić wykrycie tego wadliwego.</string>
<string name="safe_mode_crash_info">Wyświetl informacje o awarii</string> <string name="safe_mode_crash_info">Wyświetl informacje o błędzie</string>
<string name="extension_rating" formatted="true">Ocena: %s</string> <string name="extension_rating" formatted="true">Ocena: %s</string>
<string name="extension_description">Opis</string> <string name="extension_description">Opis</string>
<string name="extension_version">Versja</string> <string name="extension_version">Wersja</string>
<string name="extension_status">Status</string> <string name="extension_status">Status</string>
<string name="extension_size">Rozmiar</string> <string name="extension_size">Rozmiar</string>
<string name="extension_authors">Autorzy</string> <string name="extension_authors">Autorzy</string>
@ -431,7 +434,7 @@
<string name="clear_history">Wyczyść historię</string> <string name="clear_history">Wyczyść historię</string>
<string name="history">Historia</string> <string name="history">Historia</string>
<string name="clipboard_too_large">Za dużo tekstu. Nie można skopiować do schowka.</string> <string name="clipboard_too_large">Za dużo tekstu. Nie można skopiować do schowka.</string>
<string name="network_adress_example">Link do transmisji</string> <string name="network_adress_example">Link do odtwarzania</string>
<string name="play_with_app_name">Odtwórz w CloudStream</string> <string name="play_with_app_name">Odtwórz w CloudStream</string>
<string name="skip_type_format" formatted="true">Pomiń %s</string> <string name="skip_type_format" formatted="true">Pomiń %s</string>
<string name="next_episode_time_hour_format" formatted="true">%dh %dm</string> <string name="next_episode_time_hour_format" formatted="true">%dh %dm</string>
@ -446,11 +449,11 @@
<string name="update_notification_downloading">Pobieranie aktualizacji aplikacji…</string> <string name="update_notification_downloading">Pobieranie aktualizacji aplikacji…</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="cast_format" formatted="true">Obsada: %s</string> <string name="cast_format" formatted="true">Obsada: %s</string>
<string name="automatic_plugin_download_summary">Automatycznie instaluj wszystkie jeszcze nie zainstalowane wtyczki z dodanych repozytoriów.</string> <string name="automatic_plugin_download_summary">Automatycznie instaluj wszystkie jeszcze niezainstalowane wtyczki z dodanych repozytoriów.</string>
<string name="search_poster_img_des">\@string/result_poster_img_des</string> <string name="search_poster_img_des">Poster</string>
<string name="skip_type_recap">Podsumowanie</string> <string name="skip_type_recap">Podsumowanie</string>
<string name="apk_installer_settings">Instalator APK</string> <string name="apk_installer_settings">Instalator APK</string>
<string name="apk_installer_settings_des">Niektóre telefony nie obsługują nowego instalatora pakietów. Wypróbuj tryb kompatybilności, jeśli aktualizacje nie zostaną zainstalowane.</string> <string name="apk_installer_settings_des">Niektóre telefony nie obsługują nowego instalatora pakietów. Wypróbuj tryb legacy, jeśli aktualizacje nie zostaną zainstalowane.</string>
<string name="example_password">password123</string> <string name="example_password">password123</string>
<string name="ova_singular">\@string/ova</string> <string name="ova_singular">\@string/ova</string>
<string name="example_site_name">MojaFajnaWitryna</string> <string name="example_site_name">MojaFajnaWitryna</string>
@ -470,12 +473,12 @@
<string name="skip_type_intro">Intro</string> <string name="skip_type_intro">Intro</string>
<string name="skip_type_mixed_ed">Mixed ending</string> <string name="skip_type_mixed_ed">Mixed ending</string>
<string name="enable_skip_op_from_database_des">Pokaż wyskakujące okienka pomijania dla niektórych segmentów</string> <string name="enable_skip_op_from_database_des">Pokaż wyskakujące okienka pomijania dla niektórych segmentów</string>
<string name="pref_category_extensions">Dodatki</string> <string name="pref_category_extensions">Rozszerzenia</string>
<string name="pref_category_actions">Działania</string> <string name="pref_category_actions">Działania</string>
<string name="pref_category_cache">Pamięć podręczna</string> <string name="pref_category_cache">Pamięć podręczna</string>
<string name="redo_setup_process">Powtórz proces konfiguracji</string> <string name="redo_setup_process">Powtórz proces konfiguracji</string>
<string name="pref_category_links">Linki</string> <string name="pref_category_links">Linki</string>
<string name="pref_category_app_updates">Aktualizacje aplikacji</string> <string name="pref_category_app_updates">Aktualizacje</string>
<string name="pref_category_backup">Kopia zapasowa</string> <string name="pref_category_backup">Kopia zapasowa</string>
<string name="pref_category_subtitles">Napisy</string> <string name="pref_category_subtitles">Napisy</string>
<string name="pref_category_gestures">Gesty</string> <string name="pref_category_gestures">Gesty</string>
@ -486,6 +489,24 @@
<string name="pref_category_looks">Wygląd</string> <string name="pref_category_looks">Wygląd</string>
<string name="play_trailer_button">Odtwórz zwiastun</string> <string name="play_trailer_button">Odtwórz zwiastun</string>
<string name="delayed_update_notice">Aplikacja zostanie zaktualizowana po wyjściu</string> <string name="delayed_update_notice">Aplikacja zostanie zaktualizowana po wyjściu</string>
<string name="update_started">Aktualizacja rozpoczęta</string> <string name="update_started">Rozpoczęto aktualizację</string>
<string name="plugin_downloaded">Wtyczka pobrana</string> <string name="plugin_downloaded">Pobrano rozszerzenie</string>
<string name="action_remove_from_watched">Usuń z obejrzanych</string>
<string name="browser">Przeglądarka</string>
<string name="sort_updated_new">Data aktualizacji (od nowego do starego)</string>
<string name="sort_by">Sortuj według</string>
<string name="sort">Sortuj</string>
<string name="open_with">Otwórz za pomocą</string>
<string name="sort_rating_desc">Ocena (od najwyższej do najniższej)</string>
<string name="sort_rating_asc">Ocena (od najniższej do najwyższej)</string>
<string name="sort_updated_old">Data aktualizacji (od starego do nowego)</string>
<string name="sort_alphabetical_a">Alfabetycznie (od A do Z)</string>
<string name="sort_alphabetical_z">Alfabetycznie (od Z do A)</string>
<string name="select_library">Wybierz bibliotekę</string>
<string name="library">Biblioteka</string>
<string name="empty_library_no_accounts_message">Wygląda na to, że twoja biblioteka jest pusta :(
\nZaloguj się na swoje konto lub dodaj programy do swojej lokalnej biblioteki</string>
<string name="empty_library_logged_in_message">Wygląda na to, że ta lista jest pusta, spróbuj przełączyć się na inną</string>
<string name="safe_mode_file">Znaleziono plik trybu bezpiecznego.
\nRozszerzenia nie zostaną wczytane, dopóki plik nie zostanie usunięty.</string>
</resources> </resources>

View file

@ -1,32 +1,34 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation"> <?xml version="1.0" encoding="utf-8"?>
<!--Created by The Translator <https://play.google.com/store/apps/details?id=com.sunilpaulmathew.translator>--> <resources>
<string name="app_dub_sub_episode_text_format" formatted="true">%s Ep %d</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <string name="next_episode_time_hour_format" formatted="true">%dh %dm</string>
<string name="next_episode_time_min_format" formatted="true">%dm</string>
<string name="next_episode_format" formatted="true">Episódio %d será lançado em</string>
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="episode_poster_img_des">Capa do Episódio</string>
<string name="episode_poster_img_des">Episode Poster</string> <string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="home_main_poster_img_des">Main Poster</string> <string name="home_main_poster_img_des">Capa Principal</string>
<string name="home_next_random_img_des">Next Random</string> <string name="home_next_random_img_des">Próximo Aleatório</string>
<string name="go_back_img_des">Go back</string> <string name="go_back_img_des">Voltar</string>
<string name="home_change_provider_img_des">Change Provider</string> <string name="home_change_provider_img_des">Trocar Provedor</string>
<string name="next_episode_time_day_format" formatted="true">%dd %dh %dm</string>
<string name="home_source">Fonte</string>
<string name="resolution">Resolução</string>
<string name="extras">Extras</string>
<string name="preview_background_img_des">Preview Background</string> <string name="preview_background_img_des">Preview Background</string>
<!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Velocidade (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Velocidade (%.2fx)</string>
<string name="rated_format" formatted="true">Classificado: %.1f</string> <string name="rated_format" formatted="true">Classificado: %.1f</string>
<string name="new_update_format" formatted="true">Nova atualização encontrada!\n%s -> %s</string> <string name="new_update_format" formatted="true">Nova atualização encontrada!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Enchimento</string> <string name="filler" formatted="true">Enchimento</string>
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="play_with_app_name">Reproduzir com CloudStream</string> <string name="play_with_app_name">Reproduzir com CloudStream</string>
<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">Opçõ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>
<string name="no_data">Sem Dados</string> <string name="no_data">Sem Dados</string>
<string name="episode_more_options_des">Mais Opções</string> <string name="episode_more_options_des">Mais Opções</string>
<string name="next_episode">Próximo episódio</string> <string name="next_episode">Próximo episódio</string>
@ -35,24 +37,21 @@
<string name="result_open_in_browser">Abrir no Navegador</string> <string name="result_open_in_browser">Abrir no Navegador</string>
<string name="skip_loading">Saltar Carga</string> <string name="skip_loading">Saltar Carga</string>
<string name="loading">Carregando…</string> <string name="loading">Carregando…</string>
<string name="type_watching">Assistindo</string> <string name="type_watching">Assistindo</string>
<string name="type_on_hold">Em Espera</string> <string name="type_on_hold">Em Espera</string>
<string name="type_completed">Concluído</string> <string name="type_completed">Concluído</string>
<string name="type_dropped">Abandonado</string> <string name="type_dropped">Abandonado</string>
<string name="type_plan_to_watch">Planeio Assistir</string> <string name="type_plan_to_watch">Planeio Assistir</string>
<string name="type_none">Nenhuma</string> <string name="type_none">Nenhuma</string>
<string name="type_re_watching">Assistindo de Novo</string> <string name="type_re_watching">Assistindo de Novo</string>
<string name="play_movie_button">Reproduzir Filme</string> <string name="play_movie_button">Reproduzir Filme</string>
<string name="play_livestream_button">Reproduzir Livestream</string> <string name="play_livestream_button">Reproduzir Livestream</string>
<string name="play_torrent_button">Transmitir Torrent</string> <string name="play_torrent_button">Transmitir Torrent</string>
<string name="pick_source">Fontes</string> <string name="pick_source">Fontes</string>
<string name="pick_subtitle">Legendas</string> <string name="pick_subtitle">Legendas</string>
<string name="reload_error">Voltar a tentar ligação…</string> <string name="reload_error">Voltar a tentar ligação…</string>
<string name="go_back">Voltar Atrás</string> <string name="go_back">Voltar Atrás</string>
<string name="play_episode">Reproduzir Episódio</string> <string name="play_episode">Reproduzir Episódio</string>
<string name="download">Transferir</string> <string name="download">Transferir</string>
<string name="downloaded">Transferido</string> <string name="downloaded">Transferido</string>
<string name="downloading">A Transferir</string> <string name="downloading">A Transferir</string>
@ -61,19 +60,15 @@
<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">Stream</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>
<string name="app_dubbed_text">Dob</string> <string name="app_dubbed_text">Dob</string>
<string name="app_subbed_text">Leg</string> <string name="app_subbed_text">Leg</string>
<string name="popup_delete_file">Eliminar Ficheiro</string> <string name="popup_delete_file">Eliminar Ficheiro</string>
<string name="popup_play_file">Reproduzir Ficheiro</string> <string name="popup_play_file">Reproduzir Ficheiro</string>
<string name="popup_resume_download">Retomar Transferência</string> <string name="popup_resume_download">Retomar Transferência</string>
<string name="popup_pause_download">Pausar Transferência</string> <string name="popup_pause_download">Pausar Transferência</string>
<string name="pref_disable_acra">Desativar relatório automático de erros</string> <string name="pref_disable_acra">Desativar relatório automático de erros</string>
<string name="home_more_info">Mais info</string> <string name="home_more_info">Mais info</string>
<string name="home_expanded_hide">Esconder</string> <string name="home_expanded_hide">Esconder</string>
@ -84,13 +79,11 @@
<string name="action_remove_from_bookmarks">Remover</string> <string name="action_remove_from_bookmarks">Remover</string>
<string name="sort_apply">Aplicar</string> <string name="sort_apply">Aplicar</string>
<string name="sort_cancel">Cancelar</string> <string name="sort_cancel">Cancelar</string>
<string name="sort_copy">Copiar</string> <string name="sort_copy">Copiar</string>
<string name="sort_close">Fechar</string> <string name="sort_close">Fechar</string>
<string name="sort_clear">Limpar</string> <string name="sort_clear">Limpar</string>
<string name="sort_save">Guardar</string> <string name="sort_save">Guardar</string>
<string name="player_speed">Velocidade de Reprodução</string> <string name="player_speed">Velocidade de Reprodução</string>
<string name="subtitles_settings">Configurações de Legendas</string> <string name="subtitles_settings">Configurações de Legendas</string>
<string name="subs_text_color">Cor do Texto</string> <string name="subs_text_color">Cor do Texto</string>
<string name="subs_outline_color">Cor do Delineado</string> <string name="subs_outline_color">Cor do Delineado</string>
@ -100,89 +93,70 @@
<string name="subs_subtitle_elevation">Elevação da Legenda</string> <string name="subs_subtitle_elevation">Elevação da Legenda</string>
<string name="subs_font">Fonte</string> <string name="subs_font">Fonte</string>
<string name="subs_font_size">Tamanho da Fonte</string> <string name="subs_font_size">Tamanho da Fonte</string>
<string name="search_provider_text_providers">Procurar usando fornecedores</string> <string name="search_provider_text_providers">Procurar usando fornecedores</string>
<string name="search_provider_text_types">Procurar usando tipos</string> <string name="search_provider_text_types">Procurar usando tipos</string>
<string name="benene_count_text">%d Benenes dadas aos devs</string> <string name="benene_count_text">%d Benenes dadas aos devs</string>
<string name="benene_count_text_none">Nenhum Benene dada</string> <string name="benene_count_text_none">Nenhum Benene dada</string>
<string name="subs_auto_select_language">Auto-seleção de Idioma</string> <string name="subs_auto_select_language">Auto-seleção de Idioma</string>
<string name="subs_download_languages">Transferir Idiomas</string> <string name="subs_download_languages">Transferir Idiomas</string>
<string name="subs_subtitle_languages">Idioma da Legenda</string> <string name="subs_subtitle_languages">Idioma da Legenda</string>
<string name="subs_hold_to_reset_to_default">Segure para retornar para o padrão</string> <string name="subs_hold_to_reset_to_default">Segure para retornar para o padrão</string>
<string name="subs_import_text" formatted="true">Importar fontes colocando em %s</string> <string name="subs_import_text" formatted="true">Importar fontes colocando em %s</string>
<string name="continue_watching">Continuar a Assistir</string> <string name="continue_watching">Continuar a Assistir</string>
<string name="action_remove_watching">Remover</string> <string name="action_remove_watching">Remover</string>
<string name="action_open_watching">Mais info</string> <string name="action_open_watching">Mais info</string>
<string name="vpn_might_be_needed">Uma VPN pode ser necessária para que este fornecedor funcione corretamente</string> <string name="vpn_might_be_needed">Uma VPN pode ser necessária para que este fornecedor funcione corretamente</string>
<string name="vpn_torrent">Este fornecedor é um torrent, uma VPN é recomendada</string> <string name="vpn_torrent">Este fornecedor é um torrent, uma VPN é recomendada</string>
<string name="provider_info_meta">Metadados não são oferecidos pelo site, o carregamento do vídeo irá falhar se ele não existir no site.</string>
<string name="provider_info_meta">Metadados não são oferecidos pelo site, o carregamento do vídeo irá falhar se ele não existir no site.</string> <string name="torrent_plot">Descrição</string>
<string name="torrent_plot">Descrição</string>
<string name="normal_no_plot">Nenhum Enredo Encontrado</string> <string name="normal_no_plot">Nenhum Enredo Encontrado</string>
<string name="torrent_no_plot">Nenhuma Descrição Encontrada</string> <string name="torrent_no_plot">Nenhuma Descrição Encontrada</string>
<string name="show_log_cat">Mostrar logcat 🐈</string>
<string name="show_log_cat">Mostrar logcat 🐈</string>
<string name="picture_in_picture">Picture-in-picture</string> <string name="picture_in_picture">Picture-in-picture</string>
<string name="picture_in_picture_des">Continua a reprodução num player em miniatura em cima de outras apps</string> <string name="picture_in_picture_des">Continua a reprodução num player em miniatura em cima de outras apps</string>
<string name="player_size_settings">Botão de redimensionamento do player</string> <string name="player_size_settings">Botão de redimensionamento do player</string>
<string name="player_size_settings_des">Remover as bordas negras</string> <string name="player_size_settings_des">Remover as bordas negras</string>
<string name="player_subtitles_settings">Legendas</string> <string name="player_subtitles_settings">Legendas</string>
<string name="player_subtitles_settings_des">Configurações de legendas do player</string> <string name="player_subtitles_settings_des">Configurações de legendas do player</string>
<string name="chromecast_subtitles_settings">Legendas do Chromecast</string> <string name="chromecast_subtitles_settings">Legendas do Chromecast</string>
<string name="chromecast_subtitles_settings_des">Configurações de legendas do Chromecast</string> <string name="chromecast_subtitles_settings_des">Configurações de legendas do Chromecast</string>
<string name="eigengraumode_settings">Modo Eigengravy</string> <string name="eigengraumode_settings">Modo Eigengravy</string>
<string name="eigengraumode_settings_des">Acrescenta uma opção de velocidade no player</string> <string name="eigengraumode_settings_des">Acrescenta uma opção de velocidade no player</string>
<string name="swipe_to_seek_settings">Deslize para andar</string> <string name="swipe_to_seek_settings">Deslize para andar</string>
<string name="swipe_to_seek_settings_des">Deslize para a esq. ou dir. para controlar o tempo no player</string> <string name="swipe_to_seek_settings_des">Deslize para a esq. ou dir. para controlar o tempo no player</string>
<string name="swipe_to_change_settings">Deslize para mudar as configurações</string> <string name="swipe_to_change_settings">Deslize para mudar as configurações</string>
<string name="swipe_to_change_settings_des">Deslize do lado esq. ou dir. para ajustar brilho ou volume</string> <string name="swipe_to_change_settings_des">Deslize do lado esq. ou dir. para ajustar brilho ou volume</string>
<string name="autoplay_next_settings">Reproduzir automaticamente próximo episódio</string>
<string name="autoplay_next_settings">Reproduzir automaticamente próximo episódio</string>
<string name="autoplay_next_settings_des">Começa o próximo episódio quando o atual termina</string> <string name="autoplay_next_settings_des">Começa o próximo episódio quando o atual termina</string>
<string name="double_tap_to_seek_settings">Toque duplo para avançar</string> <string name="double_tap_to_seek_settings">Toque duplo para avançar</string>
<string name="double_tap_to_pause_settings">Toque duplo para pôr em pausa</string> <string name="double_tap_to_pause_settings">Toque duplo para pôr em pausa</string>
<string name="double_tap_to_seek_amount_settings">Segundos avançados no player</string> <string name="double_tap_to_seek_amount_settings">Segundos avançados no player</string>
<string name="double_tap_to_seek_settings_des">Toque duplo no lado esq. ou dir. para andar para trás ou para a frente</string> <string name="double_tap_to_seek_settings_des">Toque duplo no lado esq. ou dir. para andar para trás ou para a frente</string>
<string name="double_tap_to_pause_settings_des">Toque no meio para pôr em pausa</string> <string name="double_tap_to_pause_settings_des">Toque no meio para pôr em pausa</string>
<string name="use_system_brightness_settings">Usar brilho da sistema</string> <string name="use_system_brightness_settings">Usar brilho da sistema</string>
<string name="use_system_brightness_settings_des">Usar brilho do sistema no player em vez de uma sobreposição escura</string> <string name="use_system_brightness_settings_des">Usar brilho do sistema no player em vez de uma sobreposição escura</string>
<string name="episode_sync_settings">Atualizar progresso</string>
<string name="episode_sync_settings">Atualizar progresso</string>
<string name="episode_sync_settings_des">Sincronizar automaticamente o progresso do seu episódio atual</string> <string name="episode_sync_settings_des">Sincronizar automaticamente o progresso do seu episódio atual</string>
<string name="restore_settings">Restaurar dados a partir de backup</string> <string name="restore_settings">Restaurar dados a partir de backup</string>
<string name="backup_settings">Fazer backup</string> <string name="backup_settings">Fazer backup</string>
<string name="restore_success">Arquivo de backup carregado</string> <string name="restore_success">Arquivo de backup carregado</string>
<string name="restore_failed_format" formatted="true">Falha ao restaurar dados do ficheiro %s</string> <string name="restore_failed_format" formatted="true">Falha ao restaurar dados do ficheiro %s</string>
<string name="backup_success">Dados guardados com sucesso</string> <string name="backup_success">Dados guardados com sucesso</string>
<string name="backup_failed">Permissões de armazenamento em falta, por favor tente de novo</string> <string name="backup_failed">Permissões de armazenamento em falta, por favor tente de novo</string>
<string name="backup_failed_error_format">Erro no backup de %s</string> <string name="backup_failed_error_format">Erro no backup de %s</string>
<string name="search">Procurar</string> <string name="search">Procurar</string>
<string name="category_account">Contas</string> <string name="category_account">Contas</string>
<string name="category_updates">Atualizações e backup</string> <string name="category_updates">Atualizações e backup</string>
<string name="settings_info">Info</string> <string name="settings_info">Info</string>
<string name="advanced_search">Procura Avançada</string> <string name="advanced_search">Procura Avançada</string>
<string name="advanced_search_des">Mostra resultados separados por fornecedor</string> <string name="advanced_search_des">Mostra resultados separados por fornecedor</string>
<string name="bug_report_settings_off">Só envia dados sobre falhas</string> <string name="bug_report_settings_off">Só envia dados sobre falhas</string>
<string name="bug_report_settings_on">Não envia nenhum dado</string> <string name="bug_report_settings_on">Não envia nenhum dado</string>
<string name="show_fillers_settings">Mostrar episódios de enchimento para anime</string> <string name="show_fillers_settings">Mostrar episódios de enchimento para anime</string>
<string name="show_trailers_settings">Mostrar trailers</string> <string name="show_trailers_settings">Mostrar trailers</string>
<string name="kitsu_settings">Mostrar posters do kitsu</string> <string name="kitsu_settings">Mostrar posters do kitsu</string>
<string name="pref_filter_search_quality">Esconder qualidades de vídeo selecionadas nos resultados da Pesquisa</string>
<string name="pref_filter_search_quality">Esconder qualidades de vídeo selecionadas nos resultados da Pesquisa</string> <string name="automatic_plugin_updates">Atualizações de plugin automáticas</string>
<string name="automatic_plugin_updates">Atualizações de plugin automáticas</string>
<string name="updates_settings">Mostrar atualizações da app</string> <string name="updates_settings">Mostrar atualizações da app</string>
<string name="updates_settings_des">Procurar novas atualizações automaticamente ao iniciar</string> <string name="updates_settings_des">Procurar novas atualizações automaticamente ao iniciar</string>
<string name="uprereleases_settings">Atualizar para pré-lançamentos</string> <string name="uprereleases_settings">Atualizar para pré-lançamentos</string>
@ -192,18 +166,13 @@
<string name="discord">Junte-se ao Discord</string> <string name="discord">Junte-se ao Discord</string>
<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">Idioma 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>
<string name="copy_link_toast">Link copiado para a área de transferência</string> <string name="copy_link_toast">Link copiado para a área de transferência</string>
<string name="play_episode_toast">Reproduzir episódio</string> <string name="play_episode_toast">Reproduzir episódio</string>
<string name="subs_default_reset_toast">Restaurar para o padrão</string> <string name="subs_default_reset_toast">Restaurar para o padrão</string>
<string name="acra_report_toast">Desculpe, a aplicação falhou. Um relatório de erro anónimo será enviado para os <string name="acra_report_toast">Desculpe, a aplicação falhou. Um relatório de erro anónimo será enviado para os desenvolvedores</string>
desenvolvedores
</string>
<string name="season">Temporada</string> <string name="season">Temporada</string>
<string name="no_season">Nenhuma Temporada</string> <string name="no_season">Nenhuma Temporada</string>
<string name="episode">Episódio</string> <string name="episode">Episódio</string>
@ -211,14 +180,14 @@
<string name="season_short">T</string> <string name="season_short">T</string>
<string name="episode_short">E</string> <string name="episode_short">E</string>
<string name="no_episodes_found">Nenhum Episódio encontrado</string> <string name="no_episodes_found">Nenhum Episódio encontrado</string>
<string name="delete_file">Eliminar Ficheiro</string> <string name="delete_file">Eliminar Ficheiro</string>
<string name="delete">Eliminar</string> <string name="delete">Eliminar</string>
<string name="pause">Pôr em Pausa</string> <string name="pause">Pôr em Pausa</string>
<string name="resume">Retomar</string> <string name="resume">Retomar</string>
<string name="delete_message">Isto apagará %s permanentemente\nTem a certeza?</string> <string name="delete_message" formatted="true">Isto apagará %s permanentemente
<string name="resume_time_left" formatted="true">%dm\nem falta</string> \nTem a certeza\?</string>
<string name="resume_time_left" formatted="true">%dm
\nem falta</string>
<string name="status_ongoing">Em Curso</string> <string name="status_ongoing">Em Curso</string>
<string name="status_completed">Concluído</string> <string name="status_completed">Concluído</string>
<string name="status">Estado</string> <string name="status">Estado</string>
@ -227,44 +196,36 @@
<string name="duration">Duração</string> <string name="duration">Duração</string>
<string name="site">Site</string> <string name="site">Site</string>
<string name="synopsis">Sinopse</string> <string name="synopsis">Sinopse</string>
<string name="queued">Na fila</string> <string name="queued">Na fila</string>
<string name="no_subtitles">Sem Legendas</string> <string name="no_subtitles">Sem Legendas</string>
<string name="default_subtitles">Padrão</string> <string name="default_subtitles">Padrão</string>
<string name="free_storage">Livre</string> <string name="free_storage">Livre</string>
<string name="used_storage">Usado</string> <string name="used_storage">Usado</string>
<string name="app_storage">App</string> <string name="app_storage">App</string>
<!--plural-->
<string name="movies">Filmes</string> <string name="movies">Filmes</string>
<string name="tv_series">Séries</string> <string name="tv_series">Séries</string>
<string name="cartoons">Desenhos Animados</string> <string name="cartoons">Desenhos Animados</string>
<string name="anime">Anime</string> <string name="anime">Anime</string>
<string name="torrent">Torrents</string> <string name="torrent">Torrents</string>
<string name="documentaries">Documentários</string> <string name="documentaries">Documentários</string>
<string name="ova">OVA</string> <string name="ova">OVA</string>
<string name="asian_drama">Dramas Asiáticos</string> <string name="asian_drama">Dramas Asiáticos</string>
<string name="livestreams">Transmissões em Direto</string> <string name="livestreams">Transmissões em Direto</string>
<string name="nsfw">NSFW</string> <string name="nsfw">NSFW</string>
<string name="others">Outros</string> <string name="others">Outros</string>
<string name="movies_singular">Filme</string>
<!--singular--> <string name="tv_series_singular">Série</string>
<string name="movies_singular">Filme</string> <string name="cartoons_singular">Desenho Animado</string>
<string name="tv_series_singular">Série</string> <string name="torrent_singular">Torrent</string>
<string name="cartoons_singular">Desenho Animado</string> <string name="documentaries_singular">Documentário</string>
<string name="torrent_singular">Torrent</string> <string name="asian_drama_singular">Drama Asiático</string>
<string name="documentaries_singular">Documentário</string> <string name="live_singular">Transmissão em Direto</string>
<string name="asian_drama_singular">Drama Asiático</string>
<string name="live_singular">Transmissão em Direto</string>
<string name="nsfw_singular">NSFW</string> <string name="nsfw_singular">NSFW</string>
<string name="source_error">Erro de fonte</string> <string name="source_error">Erro de fonte</string>
<string name="remote_error">Erro remoto</string> <string name="remote_error">Erro remoto</string>
<string name="render_error">Erro de renderização</string> <string name="render_error">Erro de renderização</string>
<string name="unexpected_error">Erro inesperado do player</string> <string name="unexpected_error">Erro inesperado do player</string>
<string name="storage_error">Erro de transferência, verifique permissões de armazenamento</string> <string name="storage_error">Erro de transferência, verifique permissões de armazenamento</string>
<string name="episode_action_chromecast_episode">Episódio pelo Chromecast</string> <string name="episode_action_chromecast_episode">Episódio pelo Chromecast</string>
<string name="episode_action_chromecast_mirror">Alternativa pelo Chromecast</string> <string name="episode_action_chromecast_mirror">Alternativa pelo Chromecast</string>
<string name="episode_action_play_in_app">Reproduzir na app</string> <string name="episode_action_play_in_app">Reproduzir na app</string>
@ -274,118 +235,82 @@
<string name="episode_action_auto_download">Transferência Automática</string> <string name="episode_action_auto_download">Transferência Automática</string>
<string name="episode_action_download_mirror">Transferir por servidor alternativo</string> <string name="episode_action_download_mirror">Transferir por servidor alternativo</string>
<string name="episode_action_reload_links">Recarregar links</string> <string name="episode_action_reload_links">Recarregar links</string>
<string name="episode_action_download_subtitle">Transferir legendas</string> <string name="episode_action_download_subtitle">Transferir legendas</string>
<string name="show_hd">Etiqueta de qualidade</string>
<string name="show_hd">Etiqueta de qualidade</string>
<string name="show_dub">Etiqueta Dub</string> <string name="show_dub">Etiqueta Dub</string>
<string name="show_sub">Etiqueta Sub</string> <string name="show_sub">Etiqueta Sub</string>
<string name="show_title">Título</string> <string name="show_title">Título</string>
<string name="poster_ui_settings">Alternar elementos da interface no póster</string> <string name="poster_ui_settings">Alternar elementos da interface no póster</string>
<string name="no_update_found">Nenhuma Atualização Encontrada</string> <string name="no_update_found">Nenhuma Atualização Encontrada</string>
<string name="check_for_update">Procurar Atualização</string> <string name="check_for_update">Procurar Atualização</string>
<string name="video_lock">Fixar</string> <string name="video_lock">Fixar</string>
<string name="video_aspect_ratio_resize">Mudar Tamanho</string> <string name="video_aspect_ratio_resize">Mudar Tamanho</string>
<string name="video_source">Fonte</string> <string name="video_source">Fonte</string>
<string name="video_skip_op">Saltar OP</string> <string name="video_skip_op">Saltar OP</string>
<string name="dont_show_again">Não mostrar de novo</string> <string name="dont_show_again">Não mostrar de novo</string>
<string name="skip_update">Saltar esta Atualização</string> <string name="skip_update">Saltar esta Atualização</string>
<string name="update">Atualizar</string> <string name="update">Atualizar</string>
<string name="watch_quality_pref">Qualidade Preferida</string> <string name="watch_quality_pref">Qualidade Preferida</string>
<string name="limit_title">Máximo de caracteres do título de vídeos</string> <string name="limit_title">Máximo de caracteres do título de vídeos</string>
<string name="limit_title_rez">Resolução do player de vídeo</string> <string name="limit_title_rez">Resolução do player de vídeo</string>
<string name="video_buffer_size_settings">Tamanho do buffer do vídeo</string>
<string name="video_buffer_size_settings">Tamanho do buffer do vídeo</string>
<string name="video_buffer_length_settings">Comprimento do buffer do vídeo</string> <string name="video_buffer_length_settings">Comprimento do buffer do vídeo</string>
<string name="video_buffer_disk_settings">Cache do vídeo em disco</string> <string name="video_buffer_disk_settings">Cache do vídeo em disco</string>
<string name="video_buffer_clear_settings">Limpar cache de vídeo e imagem</string> <string name="video_buffer_clear_settings">Limpar cache de vídeo e imagem</string>
<string name="video_ram_description">Causará travamentos aleatórios se definido muito alto. Não mude se tiver pouca memória RAM, como um Android TV ou um telefone antigo</string> <string name="video_ram_description">Causará travamentos aleatórios se definido muito alto. Não mude se tiver pouca memória RAM, como um Android TV ou um telefone antigo</string>
<string name="video_disk_description">Pode causar problemas em sistemas com pouco espaço de armazenamento se definido muito alto, como em dispositivos Android TV</string> <string name="video_disk_description">Pode causar problemas em sistemas com pouco espaço de armazenamento se definido muito alto, como em dispositivos Android TV</string>
<string name="dns_pref">DNS sobre HTTPS</string> <string name="dns_pref">DNS sobre HTTPS</string>
<string name="dns_pref_summary">Útil para contornar bloqueios do fornecedor de internet</string> <string name="dns_pref_summary">Útil para contornar bloqueios do fornecedor de internet</string>
<string name="add_site_pref">Clonar site</string>
<string name="add_site_pref">Clonar site</string>
<string name="remove_site_pref">Remover site</string> <string name="remove_site_pref">Remover site</string>
<string name="add_site_summary">Adiciona um clone de um site existente, com um url diferente</string> <string name="add_site_summary">Adiciona um clone de um site existente, com um url diferente</string>
<string name="download_path_pref">Caminho de transferência</string>
<string name="download_path_pref">Caminho de transferência</string>
<string name="nginx_url_pref">Url do servidor Nginx</string> <string name="nginx_url_pref">Url do servidor Nginx</string>
<string name="display_subbed_dubbed_settings">Mostrar Anime Dobrado/Legendado</string> <string name="display_subbed_dubbed_settings">Mostrar Anime Dobrado/Legendado</string>
<string name="resize_fit">Ajustar para a Tela</string> <string name="resize_fit">Ajustar para a Tela</string>
<string name="resize_fill">Esticar</string> <string name="resize_fill">Esticar</string>
<string name="resize_zoom">Aumentar</string> <string name="resize_zoom">Aumentar</string>
<string name="legal_notice">Aviso Legal</string>
<string name="legal_notice">Aviso Legal</string> <string name="category_general">Geral</string>
<string name="legal_notice_text" translatable="false">Quaisquer questões legais relativas ao conteúdo desta aplicação <string name="random_button_settings">Botão Aleatório</string>
devem ser levados em conta com os próprios anfitriões e fornecedores de arquivos, pois não somos afiliados a eles.
Em caso de violação de direitos autorais, favor contatar diretamente as partes responsáveis ou os sites de streaming.
O aplicativo é puramente para uso educacional e pessoal.
O CloudStream 3 não hospeda nenhum conteúdo no aplicativo, e não tem controle sobre qual mídia é colocada ou retirada.
O CloudStream 3 funciona como qualquer outro mecanismo de busca, como o Google. O CloudStream 3 não hospeda, não faz upload ou
gerenciar qualquer vídeo, filme ou conteúdo. Ele simplesmente rasteja, agrega e exibe links em um conveniente,
interface amigável para o usuário.
Ela apenas raspa sites de terceiros que podem ser acessados publicamente através de qualquer navegador web normal. É o
responsabilidade do usuário de evitar qualquer ação que possa violar as leis que regem sua localidade. Utilizar
CloudStream 3 por sua própria conta e risco.
</string>
<string name="category_general">Geral</string>
<string name="random_button_settings">Botão Aleatório</string>
<string name="random_button_settings_desc">Mostra o botão Aleatório na página inicial</string> <string name="random_button_settings_desc">Mostra o botão Aleatório na página inicial</string>
<string name="provider_lang_settings">Idioma dos fornecedores</string> <string name="provider_lang_settings">Idioma dos fornecedores</string>
<string name="app_layout">Layout da App</string> <string name="app_layout">Layout da App</string>
<string name="preferred_media_settings">Mídia preferida</string> <string name="preferred_media_settings">Mídia preferida</string>
<string name="enable_nsfw_on_providers">Ativar NSFW em fornecedores compatíveis</string> <string name="enable_nsfw_on_providers">Ativar NSFW em fornecedores compatíveis</string>
<string name="category_providers">Fornecedores</string> <string name="subtitles_encoding">Codificação das legendas</string>
<string name="subtitles_encoding">Codificação das legendas</string> <string name="category_providers">Fornecedores</string>
<string name="category_ui">Layout</string> <string name="category_ui">Layout</string>
<string name="automatic">Auto</string> <string name="automatic">Auto</string>
<string name="tv_layout">Layout de TV</string> <string name="tv_layout">Layout de TV</string>
<string name="phone_layout">Layout de telemóvel</string> <string name="phone_layout">Layout de telemóvel</string>
<string name="emulator_layout">Layout de emulador</string> <string name="emulator_layout">Layout de emulador</string>
<string name="primary_color_settings">Cor Primária</string> <string name="primary_color_settings">Cor Primária</string>
<string name="app_theme_settings">Tema do App</string> <string name="app_theme_settings">Tema do App</string>
<string name="bottom_title_settings">Local do título do poster</string> <string name="bottom_title_settings">Local do título do poster</string>
<string name="bottom_title_settings_des">Coloca o título debaixo do poster</string> <string name="bottom_title_settings_des">Coloca o título debaixo do poster</string>
<string name="example_password">senha123</string>
<!-- account stuff -->
<string name="example_password">senha123</string>
<string name="example_username">MeuNomeFixe</string> <string name="example_username">MeuNomeFixe</string>
<string name="example_email">ola@mundo.com</string> <string name="example_email">ola@mundo.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">MeuSiteFixe</string> <string name="example_site_name">MeuSiteFixe</string>
<string name="example_site_url">examplo.com</string> <string name="example_site_url">examplo.com</string>
<string name="example_lang_name">Codigo da Língua (pt)</string> <string name="example_lang_name">Codigo da Língua (pt)</string>
<string name="account">Conta</string> <string name="account">Conta</string>
<string name="logout">Sair</string> <string name="logout">Sair</string>
<string name="login">Entrar</string> <string name="login">Entrar</string>
<string name="switch_account">Mudar de conta</string> <string name="switch_account">Mudar de conta</string>
<string name="add_account">Adicionar conta</string> <string name="add_account">Adicionar conta</string>
<string name="create_account">Criar conta</string> <string name="create_account">Criar conta</string>
<string name="add_sync">Adicionar sincronização</string> <string name="add_sync">Adicionar sincronização</string>
<string name="added_sync_format" formatted="true">%s adicionado</string> <string name="added_sync_format" formatted="true">%s adicionado</string>
<string name="upload_sync">Sincronizar</string> <string name="upload_sync">Sincronizar</string>
<string name="sync_score">Nota</string> <string name="sync_score">Nota</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s autenticado</string> <string name="authenticated_user" formatted="true">%s autenticado</string>
<string name="authenticated_user_fail" formatted="true">Falha em autenticar para %s</string> <string name="authenticated_user_fail" formatted="true">Falha em autenticar para %s</string>
<!-- ============ -->
<string name="none">Nenhuma</string> <string name="none">Nenhuma</string>
<string name="normal">Normal</string> <string name="normal">Normal</string>
<string name="all">Tudo</string> <string name="all">Tudo</string>
@ -395,20 +320,13 @@
<string name="subtitles_depressed">Deprimido</string> <string name="subtitles_depressed">Deprimido</string>
<string name="subtitles_shadow">Sombreado</string> <string name="subtitles_shadow">Sombreado</string>
<string name="subtitles_raised">Em Relevo</string> <string name="subtitles_raised">Em Relevo</string>
<string name="subtitle_offset">Sincronizar legendas</string> <string name="subtitle_offset">Sincronizar legendas</string>
<string name="subtitle_offset_title">Atraso de legenda</string> <string name="subtitle_offset_title">Atraso de legenda</string>
<string name="subtitle_offset_extra_hint_later_format">Use isto se as legendas forem mostradas %dms adiantadas</string> <string name="subtitle_offset_extra_hint_later_format">Use isto se as legendas forem mostradas %dms adiantadas</string>
<string name="subtitle_offset_extra_hint_before_format">Use isto se as legendas forem mostradas %dms atrasadas</string> <string name="subtitle_offset_extra_hint_before_format">Use isto se as legendas forem mostradas %dms atrasadas</string>
<string name="subtitle_offset_extra_hint_none_format">Sem atraso de legenda</string> <string name="subtitle_offset_extra_hint_none_format">Sem atraso de legenda</string>
<!--
Example text (pangram) can optionally be translated; if you do, include all the letters in the alphabet,
see:
https://en.wikipedia.org/w/index.php?title=Pangram&oldid=225849300
https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog
-->
<string name="subtitles_example_text">Luís argüia à Júlia que «brações, fé, chá, óxido, pôr, zângão» eram palavras do português</string> <string name="subtitles_example_text">Luís argüia à Júlia que «brações, fé, chá, óxido, pôr, zângão» eram palavras do português</string>
<string name="recommended">Recomendada</string>
<string name="recommended">Recomendada</string>
<string name="player_loaded_subtitles" formatted="true">%s carregada</string> <string name="player_loaded_subtitles" formatted="true">%s carregada</string>
<string name="player_load_subtitles">Carregar de arquivo</string> <string name="player_load_subtitles">Carregar de arquivo</string>
<string name="player_load_subtitles_online">Carregar da Internet</string> <string name="player_load_subtitles_online">Carregar da Internet</string>
@ -416,34 +334,24 @@
<string name="actor_main">Protagonista</string> <string name="actor_main">Protagonista</string>
<string name="actor_supporting">Coadjuvante</string> <string name="actor_supporting">Coadjuvante</string>
<string name="actor_background">Figurante</string> <string name="actor_background">Figurante</string>
<string name="home_source">Fonte</string>
<string name="home_random">Aleatório</string> <string name="home_random">Aleatório</string>
<string name="coming_soon">Em breve…</string> <string name="coming_soon">Em breve…</string>
<string name="poster_image">Imagem de Poster</string>
<string name="poster_image">Imagem de Poster</string>
<string name="category_player">Player</string> <string name="category_player">Player</string>
<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="error_invalid_id">Id inválida</string> <string name="error_invalid_id">Id inválida</string>
<string name="error_invalid_data">Dado inválido</string> <string name="error_invalid_data">Dado inválido</string>
<string name="error_invalid_url">URL 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="subtitles_filter_lang">Filtrar por linguagem preferida</string>
<string name="extras">Extras</string>
<string name="trailer">Trailer</string> <string name="trailer">Trailer</string>
<string name="next">Próximo</string> <string name="next">Próximo</string>
<string name="provider_languages_tip">Ver vídeos nestas linguagens</string> <string name="provider_languages_tip">Ver vídeos nestas linguagens</string>
<string name="previous">Anterior</string> <string name="previous">Anterior</string>
<string name="skip_setup">Saltar setup</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="app_layout_subtext">Change the look of the app to suit your device</string>
<string name="crash_reporting_title">Crash reporting</string> <string name="crash_reporting_title">Crash reporting</string>
<string name="preferred_media_subtext">What do you want to see</string> <string name="preferred_media_subtext">What do you want to see</string>
@ -455,7 +363,6 @@
<string name="plugin_loaded">Plugin Carregado</string> <string name="plugin_loaded">Plugin Carregado</string>
<string name="plugin_deleted">Plugin Apagado</string> <string name="plugin_deleted">Plugin Apagado</string>
<string name="plugin_load_fail" formatted="true">Falha ao carregar %s</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_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_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_nothing_to_download_format" formatted="true">Tudo %s já transferido</string>
@ -472,7 +379,6 @@
<string name="view_public_repositories_button">Ver repositórios da comunidade</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="view_public_repositories_button_short">Lista pública</string>
<string name="uppercase_all_subtitles">Todas as legendas em maiúsculas</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="download_all_plugins_from_repo">Transferir todos os plugins deste repositório?</string>
<string name="single_plugin_disabled" formatted="true">%s (Desativado)</string> <string name="single_plugin_disabled" formatted="true">%s (Desativado)</string>
</resources> </resources>

View file

@ -4,12 +4,12 @@
<string name="app_name">aauugghhaauuh</string> <string name="app_name">aauugghhaauuh</string>
<string name="title_home">ooh</string> <string name="title_home">ooh</string>
<string name="title_search">oouuh</string> <string name="title_search">oouuh</string>
<string name="title_downloads">ouuhhhooh ooh</string> <string name="title_downloads">ouuhhuhooh ooh</string>
<string name="title_settings">aaaghhoh aauugghh</string> <string name="title_settings">aaaghhoh aauugghh</string>
<string name="search_hint">haaooh</string> <string name="search_hint">haaooh ooo</string>
<string name="search_poster_img_des">aaaaaah</string> <string name="search_poster_img_des">aaaaaah</string>
<string name="no_data">oooohhoouuh</string> <string name="no_data">oooohhoouuh</string>
<string name="episode_more_options_des">aaaaaoouuhahhh ahh</string> <string name="episode_more_options_des">aaaaoouuuhahhh ahh</string>
<string name="go_back_img_des">oooohh aauuh</string> <string name="go_back_img_des">oooohh aauuh</string>
<string name="next_episode">ahhhaaaghh aaaaa</string> <string name="next_episode">ahhhaaaghh aaaaa</string>
<string name="result_poster_img_des">ahaauugghh</string> <string name="result_poster_img_des">ahaauugghh</string>
@ -122,7 +122,7 @@
<string name="episode_short">A</string> <string name="episode_short">A</string>
<string name="delete_file">ooha ohahaaahoooa ahahooo</string> <string name="delete_file">ooha ohahaaahoooa ahahooo</string>
<string name="delete">oooooah</string> <string name="delete">oooooah</string>
<string name="delete_message">aahhaaaaaahooo aauuh aaahhuaooo-ahahoooohh aoouuhoohoohooo-ahah</string> <string name="delete_message">aahhaaaaaahooo aauuh aaahhuaooo-ahahoooohh aoouuhoohoohooo-ahah %s</string>
<string name="status_ongoing">aaaghhaaaaa</string> <string name="status_ongoing">aaaghhaaaaa</string>
<string name="status_completed">aauuhaauuh</string> <string name="status_completed">aauuhaauuh</string>
<string name="status">ahhhaaaaa</string> <string name="status">ahhhaaaaa</string>
@ -145,7 +145,7 @@
<string name="episode_action_chromecast_episode">aauugghhooo-ahah ohaaauugghh</string> <string name="episode_action_chromecast_episode">aauugghhooo-ahah ohaaauugghh</string>
<string name="episode_action_chromecast_mirror">aoohaaahhu ahouuhhh</string> <string name="episode_action_chromecast_mirror">aoohaaahhu ahouuhhh</string>
<string name="episode_action_play_in_app">ooo-ahahaauuh aaahhu</string> <string name="episode_action_play_in_app">ooo-ahahaauuh aaahhu</string>
<string name="episode_action_play_in_format">ooo-ahah ohaauuh</string> <string name="episode_action_play_in_format">ooo-ahah ohaauuh %s</string>
<string name="episode_action_play_in_browser">ahoha ooo-ahahohoohah oooohh</string> <string name="episode_action_play_in_browser">ahoha ooo-ahahohoohah oooohh</string>
<string name="episode_action_copy_link">aauugghhahhaauugghh</string> <string name="episode_action_copy_link">aauugghhahhaauugghh</string>
<string name="episode_action_auto_download">aaaghhoooohh aaahhu ahooo</string> <string name="episode_action_auto_download">aaaghhoooohh aaahhu ahooo</string>
@ -195,5 +195,27 @@
<string name="phone_layout">u ooah uo ahauao huhuu hauu h</string> <string name="phone_layout">u ooah uo ahauao huhuu hauu h</string>
<string name="primary_color_settings">a ou oh ouhuouhoaaha</string> <string name="primary_color_settings">a ou oh ouhuouhoaaha</string>
<string name="show_fillers_settings">aaooohhouhhha hauauuu</string> <string name="show_fillers_settings">aaooohhouhhha hauauuu</string>
<string name="new_update_format">aaaaaaa uuuuuu\n%s -> %s</string> <string name="new_update_format">aaaaaaa uuuuuu\n%s -&gt; %s</string>
<string name="app_dub_sub_episode_text_format" formatted="true">%s aaou %d</string>
<string name="cast_format" formatted="true">oouaaahh %s</string>
<string name="next_episode_format" formatted="true">aaaaaaugh ouh %d uuoogahaaah ooua-h-ha</string>
<string name="next_episode_time_day_format" formatted="true">%daaa %duuu %dhhhg</string>
<string name="next_episode_time_hour_format" formatted="true">%daaaaaaauuhh %doouuahaaha</string>
<string name="next_episode_time_min_format" formatted="true">%dmmmm...</string>
<string name="player_speed_text_format" formatted="true">aaaaaaaaaaaaahh (%.2foouo)</string>
<string name="rated_format" formatted="true">aghaaaooo-ough %.1f</string>
<string name="filler" formatted="true">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaooooohhuhuhuhuhuhhuhuhhhaaagaha-agagaoooo</string>
<string name="duration_format" formatted="true">%d ooaaaugha</string>
<string name="play_with_app_name">oooooh aaah aauuuggghauuh</string>
<string name="search_hint_site" formatted="true">aaoohhu %s aoouu</string>
<string name="browser">oooaaaauhgaaaa</string>
<string name="type_re_watching">aaaaaah-ooooooooouuagh</string>
<string name="action_add_to_bookmarks">auugggguuuuuuhhh uuuu hhhhhhhhuhggghggg</string>
<string name="play_trailer_button">ggaaaahhhhhhh gaauuuuuuuaaaau</string>
<string name="play_livestream_button">aaauuuuggggguu</string>
<string name="update_started">ooo aagg hhhh</string>
<string name="stream">ooo aagg hhhh</string>
<string name="sort_copy">uuuuhhhoouuooog ooaaahhhh</string>
<string name="sort_close">uuu ugggg</string>
<string name="sort_clear">ooo guggg ooh</string>
</resources> </resources>

View file

@ -9,7 +9,7 @@
<string name="next_episode_time_min_format" formatted="true">%dm</string> <string name="next_episode_time_min_format" formatted="true">%dm</string>
<!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS --> <!-- IS NOT NEEDED TO TRANSLATE AS THEY ARE ONLY USED FOR SCREEN READERS AND WONT SHOW UP TO NORMAL USERS -->
<string name="result_poster_img_des">Poster</string> <string name="result_poster_img_des">Poster</string>
<string name="search_poster_img_des">@string/result_poster_img_des</string> <string name="search_poster_img_des">\@string/result_poster_img_des</string>
<string name="episode_poster_img_des">Poster Episod</string> <string name="episode_poster_img_des">Poster Episod</string>
<string name="home_main_poster_img_des">Poster Principal</string> <string name="home_main_poster_img_des">Poster Principal</string>
<string name="home_next_random_img_des">Următorul la Întâmplare</string> <string name="home_next_random_img_des">Următorul la Întâmplare</string>
@ -19,7 +19,8 @@
<!-- TRANSLATE, BUT DON'T FORGET FORMAT --> <!-- TRANSLATE, BUT DON'T FORGET FORMAT -->
<string name="player_speed_text_format" formatted="true">Viteză (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Viteză (%.2fx)</string>
<string name="rated_format" formatted="true">Evaluare: %.1f</string> <string name="rated_format" formatted="true">Evaluare: %.1f</string>
<string name="new_update_format" formatted="true">Actualizare nouă găsită!\n%s -&gt; %s</string> <string name="new_update_format" formatted="true">Actualizare nouă găsită!
\n%s -&gt; %s</string>
<string name="filler" formatted="true">Filler</string> <string name="filler" formatted="true">Filler</string>
<string name="duration_format" formatted="true">%d min</string> <string name="duration_format" formatted="true">%d min</string>
<!-- <string name="app_name">CloudStream</string> --> <!-- <string name="app_name">CloudStream</string> -->
@ -105,7 +106,7 @@
<string name="continue_watching">Continuați să urmăriți</string> <string name="continue_watching">Continuați să urmăriți</string>
<string name="action_remove_watching">Eliminați</string> <string name="action_remove_watching">Eliminați</string>
<string name="action_open_watching">Mai multe informații</string> <string name="action_open_watching">Mai multe informații</string>
<string name="action_open_play">@string/home_play</string> <string name="action_open_play">\@string/home_play</string>
<string name="vpn_might_be_needed">Există probabilitatea necesitații unui VPN pentru ca acest furnizor să funcționeze corespunzător</string> <string name="vpn_might_be_needed">Există probabilitatea necesitații unui VPN pentru ca acest furnizor să funcționeze corespunzător</string>
<string name="vpn_torrent">Acest furnizor este un torrent, se recomandă un VPN</string> <string name="vpn_torrent">Acest furnizor este un torrent, se recomandă un VPN</string>
<string name="provider_info_meta">Metadatele nu sunt furnizate de către site, există posibilitatea ca încărcarea videoclipului să eșueze.</string> <string name="provider_info_meta">Metadatele nu sunt furnizate de către site, există posibilitatea ca încărcarea videoclipului să eșueze.</string>
@ -140,7 +141,7 @@
<string name="backup_settings">Copie de rezervă a datelor</string> <string name="backup_settings">Copie de rezervă a datelor</string>
<string name="restore_success">Fișier de rezervă încărcat</string> <string name="restore_success">Fișier de rezervă încărcat</string>
<string name="restore_failed_format" formatted="true">Imposibilitatea de a restaura datele din %s</string> <string name="restore_failed_format" formatted="true">Imposibilitatea de a restaura datele din %s</string>
<string name="backup_success">Datele au fost salvate cu succes</string> <string name="backup_success">Date stocate</string>
<string name="backup_failed">Permisiuni de arhivare lipsă, vă rugăm să încercați din nou</string> <string name="backup_failed">Permisiuni de arhivare lipsă, vă rugăm să încercați din nou</string>
<string name="backup_failed_error_format">Eroare de backup %s</string> <string name="backup_failed_error_format">Eroare de backup %s</string>
<string name="search">Căutare</string> <string name="search">Căutare</string>
@ -184,8 +185,10 @@
<string name="resume">Continuă</string> <string name="resume">Continuă</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Sunteți pe cale să ștergeți definitiv %s\nSunteți sigur?</string> <string name="delete_message" formatted="true">Sunteți pe cale să ștergeți definitiv %s
<string name="resume_time_left" formatted="true">%dm\nrămas</string> \nSunteți sigur\?</string>
<string name="resume_time_left" formatted="true">%dm
\nrămas</string>
<string name="status_ongoing">În curs de desfășurare</string> <string name="status_ongoing">În curs de desfășurare</string>
<string name="status_completed">Finalizat</string> <string name="status_completed">Finalizat</string>
<string name="status">Status</string> <string name="status">Status</string>
@ -268,22 +271,7 @@
<string name="resize_fill">Întindere</string> <string name="resize_fill">Întindere</string>
<string name="resize_zoom">Mărire</string> <string name="resize_zoom">Mărire</string>
<string name="legal_notice">Aviz juridic (declinarea responsabilității și drepturi de autor)</string> <string name="legal_notice">Aviz juridic (declinarea responsabilității și drepturi de autor)</string>
<string name="legal_notice_text">Orice probleme legale privind conținutul acestei aplicații ar trebui <string name="legal_notice_text">Orice probleme legale privind conținutul acestei aplicații ar trebui să fie rezolvate cu furnizorii și gazdele actuale de fișiere, întrucât noi nu suntem afiliați cu aceștia. În caz de încălcare a drepturilor de autor, vă rugăm să contactați direct părțile responsabile sau site-urile de streaming. Aplicația este destinată exclusiv utilizării educaționale și personale. CloudStream 3 nu găzduiește niciun fel de conținut în aplicație și nu are niciun control asupra conținutului media care este pus sau retras. CloudStream 3 funcționează ca orice alt motor de căutare, cum ar fi Google. CloudStream 3 nu găzduiește, nu încarcă și nu gestionează niciun videoclip, film sau conținut. Pur și simplu navighează, adună și afișează linkuri într-o interfață convenabilă și ușor de utilizat. Pur și simplu, acesta extrage paginile web ale unor terțe părți care sunt accesibile publicului prin intermediul oricărui browser web obișnuit. Este responsabilitatea utilizatorului de a evita orice acțiune care ar putea încălca legile care guvernează locația sa. Utilizați CloudStream 3 pe propria răspundere.</string>
să fie rezolvate cu furnizorii și gazdele actuale de fișiere, întrucât noi nu suntem afiliați cu aceștia.
În caz de încălcare a drepturilor de autor, vă rugăm să contactați direct părțile responsabile sau site-urile de streaming.
Aplicația este destinată exclusiv utilizării educaționale și personale.
CloudStream 3 nu găzduiește niciun fel de conținut în aplicație și nu are niciun control asupra conținutului media care este pus sau retras.
CloudStream 3 funcționează ca orice alt motor de căutare, cum ar fi Google. CloudStream 3 nu găzduiește, nu încarcă și
nu gestionează niciun videoclip, film sau conținut. Pur și simplu navighează, adună și afișează linkuri într-o interfață convenabilă
și ușor de utilizat.
Pur și simplu, acesta extrage paginile web ale unor terțe părți care sunt accesibile publicului prin intermediul oricărui browser web obișnuit. Este
responsabilitatea utilizatorului de a evita orice acțiune care ar putea încălca legile care guvernează locația sa. Utilizați
CloudStream 3 pe propria răspundere.
</string>
<string name="category_general">General</string> <string name="category_general">General</string>
<string name="random_button_settings">Aleatoriu</string> <string name="random_button_settings">Aleatoriu</string>
<string name="random_button_settings_desc">Afișați butonul Aleatoriu pe pagina de start</string> <string name="random_button_settings_desc">Afișați butonul Aleatoriu pe pagina de start</string>
@ -320,7 +308,7 @@
<string name="upload_sync">Sincronizare</string> <string name="upload_sync">Sincronizare</string>
<string name="sync_score">Recenzie</string> <string name="sync_score">Recenzie</string>
<string name="sync_score_format" formatted="true">%d / 10</string> <string name="sync_score_format" formatted="true">%d / 10</string>
<string name="sync_total_episodes_none">/??</string> <string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string> <string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="authenticated_user" formatted="true">%s autentificat</string> <string name="authenticated_user" formatted="true">%s autentificat</string>
<string name="authenticated_user_fail" formatted="true">Imposibil de autentificat la %s</string> <string name="authenticated_user_fail" formatted="true">Imposibil de autentificat la %s</string>
@ -388,4 +376,12 @@
<string name="trailer">Trailer</string> <string name="trailer">Trailer</string>
<string name="history">Istoric</string> <string name="history">Istoric</string>
<string name="action_mark_as_watched">Marcare ca vizionat</string> <string name="action_mark_as_watched">Marcare ca vizionat</string>
<string name="autoplay_next_settings">Redă automat următorul episod</string>
<string name="app_name">CloudStream</string>
<string name="play_trailer_button">Vizionează trailerul</string>
<string name="update_started">Actualizarea a început</string>
<string name="episode_sync_settings">Actualizați progresul ceasului</string>
<string name="autoplay_next_settings_des">Începe următorul episod când se termină episodul curent</string>
<string name="pref_filter_search_quality">Ascundeți calitatea video selectată în rezultatele căutării</string>
<string name="play_livestream_button">Redare Livestream</string>
</resources> </resources>

View file

@ -4,19 +4,19 @@
<string name="no">Нет</string> <string name="no">Нет</string>
<string name="yes">Да</string> <string name="yes">Да</string>
<string name="tracks">Треки</string> <string name="tracks">Треки</string>
<string name="queued">в очереди</string> <string name="queued">В очереди</string>
<string name="resize_zoom">Приблизить</string> <string name="resize_zoom">Приблизить</string>
<string name="download">Скачать</string> <string name="download">Загрузить</string>
<string name="search">Поиск</string> <string name="search">Поиск</string>
<string name="resize_fill">Заполнить</string> <string name="resize_fill">Заполнить</string>
<string name="download_failed">Скачать неудачный</string> <string name="download_failed">Скачать неудачный</string>
<string name="resize_fit">Подогнать</string> <string name="resize_fit">Подогнать</string>
<string name="delete">Удалить</string> <string name="delete">Удалить</string>
<string name="all">Всё</string> <string name="all">Все</string>
<string name="pause">Пауза</string> <string name="pause">Пауза</string>
<string name="cast_format" formatted="true">Актёрский состав: %s</string> <string name="cast_format" formatted="true">Актёрский состав: %s</string>
<string name="show_title">Название источника</string> <string name="show_title">Название источника</string>
<string name="login">Вход</string> <string name="login">Войти</string>
<string name="none">Нет</string> <string name="none">Нет</string>
<string name="title">Название</string> <string name="title">Название</string>
<string name="loading">Загрузка…</string> <string name="loading">Загрузка…</string>
@ -24,13 +24,13 @@
<string name="logout">Выйти</string> <string name="logout">Выйти</string>
<string name="next_episode_format" formatted="true">Серия %d будет выпущен в</string> <string name="next_episode_format" formatted="true">Серия %d будет выпущен в</string>
<string name="result_poster_img_des">Плакат</string> <string name="result_poster_img_des">Плакат</string>
<string name="search_poster_img_des">\@нить/результат_плокат_картинка_</string> <string name="search_poster_img_des">Плакат</string>
<string name="episode_poster_img_des">Серия плакат</string> <string name="episode_poster_img_des">Плакат эпизода</string>
<string name="home_main_poster_img_des">Главный плакат</string> <string name="home_main_poster_img_des">Главный плакат</string>
<string name="home_next_random_img_des">Следующий случайный</string> <string name="home_next_random_img_des">Следующий случайный</string>
<string name="go_back_img_des">Вернуться</string> <string name="go_back_img_des">Вернуться</string>
<string name="home_change_provider_img_des">Сменить поставщика</string> <string name="home_change_provider_img_des">Изменить поставщика</string>
<string name="preview_background_img_des">Фон предпросмотр</string> <string name="preview_background_img_des">Предпросмотр фона</string>
<string name="player_speed_text_format" formatted="true">Скорость (%.2fx)</string> <string name="player_speed_text_format" formatted="true">Скорость (%.2fx)</string>
<string name="rated_format" formatted="true">Оценили: %.1f</string> <string name="rated_format" formatted="true">Оценили: %.1f</string>
<string name="new_update_format" formatted="true">Новое обновление найдено! <string name="new_update_format" formatted="true">Новое обновление найдено!
@ -39,7 +39,7 @@
<string name="app_name">CloudStream</string> <string name="app_name">CloudStream</string>
<string name="action_remove_from_bookmarks">Убирать</string> <string name="action_remove_from_bookmarks">Убирать</string>
<string name="app_dub_sub_episode_text_format" formatted="true">%s Ep %d</string> <string name="app_dub_sub_episode_text_format" formatted="true">%s Ep %d</string>
<string name="play_with_app_name">Проиграть с CloudStream</string> <string name="play_with_app_name">Смотреть с CloudStream</string>
<string name="title_home">Главная</string> <string name="title_home">Главная</string>
<string name="title_search">Поиск</string> <string name="title_search">Поиск</string>
<string name="title_downloads">Загрузки</string> <string name="title_downloads">Загрузки</string>
@ -48,49 +48,49 @@
<string name="search_hint_site" formatted="true">Поиск %s…</string> <string name="search_hint_site" formatted="true">Поиск %s…</string>
<string name="no_data">Нет данных</string> <string name="no_data">Нет данных</string>
<string name="episode_more_options_des">Дополнительные опции</string> <string name="episode_more_options_des">Дополнительные опции</string>
<string name="next_episode">Следующий серия</string> <string name="next_episode">Следующий эпизод</string>
<string name="result_tags">Жанры</string> <string name="result_tags">Жанры</string>
<string name="result_share">Делиться</string> <string name="result_share">Поделиться</string>
<string name="result_open_in_browser">Открыть в браузер</string> <string name="result_open_in_browser">Открыть в браузере</string>
<string name="skip_loading">Скип загрузка</string> <string name="skip_loading">Пропустить загрузку</string>
<string name="type_watching">Смотрю</string> <string name="type_watching">Просмотр</string>
<string name="type_on_hold">Приостановленный</string> <string name="type_on_hold">Приостановленно</string>
<string name="type_completed">Завершено</string> <string name="type_completed">Завершено</string>
<string name="type_dropped">Брошенный</string> <string name="type_dropped">Брошенный</string>
<string name="type_plan_to_watch">План по смотреть</string> <string name="type_plan_to_watch">План посмотреть</string>
<string name="type_none">Никто</string> <string name="type_none">Нет</string>
<string name="type_re_watching">Пересмотрю</string> <string name="type_re_watching">Пересмотрю</string>
<string name="play_movie_button">Проиграть фильм</string> <string name="play_movie_button">Смотреть фильм</string>
<string name="play_trailer_button">Проиграть трейлер</string> <string name="play_trailer_button">Смотреть трейлер</string>
<string name="play_livestream_button">Проиграть Livestream</string> <string name="play_livestream_button">Смотреть Livestream</string>
<string name="pick_source">Источники</string> <string name="pick_source">Источники</string>
<string name="pick_subtitle">Субтитры</string> <string name="pick_subtitle">Субтитры</string>
<string name="play_episode">Проиграть серия</string> <string name="play_episode">Смотреть эпизод</string>
<string name="reload_error">Повторная попытка подключение…</string> <string name="reload_error">Повторная попытка подключение…</string>
<string name="go_back">Вернуться</string> <string name="go_back">Вернуться</string>
<string name="downloaded">Скачали</string> <string name="downloaded">Скачано</string>
<string name="downloading">Скачивание</string> <string name="downloading">Скачивание</string>
<string name="download_paused">Скачать приостановленный</string> <string name="download_paused">Скачать остановлена</string>
<string name="download_started">Скачать начатый</string> <string name="download_started">Скачать начатый</string>
<string name="download_canceled">Скачать отменено</string> <string name="download_canceled">Скачать отменённый</string>
<string name="download_done">Скачать выполнено</string> <string name="download_done">Скачать выполнено</string>
<string name="home_info">Инфо</string> <string name="home_info">Инфо</string>
<string name="update_started">Обновление началось</string> <string name="update_started">Обновление началось</string>
<string name="home_expanded_hide">Прятать</string> <string name="home_expanded_hide">Прятать</string>
<string name="home_play">Проиграть</string> <string name="home_play">Смотреть</string>
<string name="home_more_info">Подробнее инфо</string> <string name="home_more_info">Подробнее</string>
<string name="filter_bookmarks">Фильтр закладки</string> <string name="filter_bookmarks">Фильтр закладки</string>
<string name="error_bookmarks_text">Закладки</string> <string name="error_bookmarks_text">Закладки</string>
<string name="sort_apply">Наносить</string> <string name="sort_apply">Применить</string>
<string name="sort_cancel">Прервать</string> <string name="sort_cancel">Отмена</string>
<string name="sort_copy">Копия</string> <string name="sort_copy">Копия</string>
<string name="sort_close">Закрыть</string> <string name="sort_close">Закрыть</string>
<string name="sort_clear">Очистить</string> <string name="sort_clear">Очистить</string>
<string name="sort_save">Сохранить</string> <string name="sort_save">Сохранить</string>
<string name="player_speed">Скорость проигрыватель</string> <string name="player_speed">Скорость проигрыватель</string>
<string name="play_episode_toast">Проиграть Серия</string> <string name="play_episode_toast">Воспроизвести Эпизод</string>
<string name="next_episode_time_day_format" formatted="true">%dд %dч %dм</string> <string name="next_episode_time_day_format" formatted="true">%dд %dч %dм</string>
<string name="duration_format" formatted="true">%d мин</string> <string name="duration_format" formatted="true">%d мин.</string>
<string name="app_dubbed_text">Dub</string> <string name="app_dubbed_text">Dub</string>
<string name="app_subbed_text">Sub</string> <string name="app_subbed_text">Sub</string>
<string name="action_add_to_bookmarks">Установите смотреть состояние</string> <string name="action_add_to_bookmarks">Установите смотреть состояние</string>
@ -101,28 +101,28 @@
<string name="subs_window_color">Цвет окна</string> <string name="subs_window_color">Цвет окна</string>
<string name="subs_edge_type">Тип края</string> <string name="subs_edge_type">Тип края</string>
<string name="subs_subtitle_elevation">Субтитр подъём</string> <string name="subs_subtitle_elevation">Субтитр подъём</string>
<string name="search_provider_text_providers">Поиск с использованием поставщики</string> <string name="search_provider_text_providers">Поиск с использованием поставщиков</string>
<string name="search_provider_text_types">Поиск с использованием типов</string> <string name="search_provider_text_types">Поиск с использованием типов</string>
<string name="benene_count_text">%d Бенены данность на разрабы</string> <string name="benene_count_text">%d Бенены данность на разрабы</string>
<string name="benene_count_text_none">Бенены не дают</string> <string name="benene_count_text_none">Бенены не дают</string>
<string name="subs_auto_select_language">Автовыбор языка</string> <string name="subs_auto_select_language">Автовыбор языка</string>
<string name="subs_download_languages">Скачать языки</string> <string name="subs_download_languages">Скачать языки</string>
<string name="subs_subtitle_languages">Язык субтитров</string> <string name="subs_subtitle_languages">Язык субтитров</string>
<string name="subs_hold_to_reset_to_default">Удерживайте чтобы сбросить по умолчанию</string> <string name="subs_hold_to_reset_to_default">Удерживайте, чтобы сбросить по умолчанию</string>
<string name="error_loading_links_toast">Ошибка загрузки ссылок</string> <string name="error_loading_links_toast">Ошибка загрузки ссылок</string>
<string name="stream">Поток</string> <string name="stream">Поток</string>
<string name="subs_font">Шрифт</string> <string name="subs_font">Шрифт</string>
<string name="subs_font_size">Размер шрифта</string> <string name="subs_font_size">Размер шрифта</string>
<string name="popup_delete_file">Удалить файл</string> <string name="popup_delete_file">Удалить файл</string>
<string name="popup_play_file">Проиграть файл</string> <string name="popup_play_file">Воспроизвести файл</string>
<string name="download_storage_text">Внутренняя память</string> <string name="download_storage_text">Внутренняя память</string>
<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">Отключить автоматическое информирование об ошибках</string> <string name="pref_disable_acra">Отключить автоматическое информирование об ошибках</string>
<string name="subs_import_text" formatted="true">Импортируйте шрифты поместив их в %s</string> <string name="subs_import_text" formatted="true">Импортируйте шрифты поместив их в %s</string>
<string name="continue_watching">Продолжать смотрю</string> <string name="continue_watching">Продолжить смотреть</string>
<string name="action_remove_watching">Удалите</string> <string name="action_remove_watching">Удалите</string>
<string name="action_open_watching">Дополнительная инфо</string> <string name="action_open_watching">Подробнее</string>
<string name="vpn_might_be_needed">Для корректной работы этого поставщика может потребоваться VPN</string> <string name="vpn_might_be_needed">Для корректной работы этого поставщика может потребоваться VPN</string>
<string name="vpn_torrent">Этот поставщика - торрент, рекомендуется VPN</string> <string name="vpn_torrent">Этот поставщика - торрент, рекомендуется VPN</string>
<string name="provider_info_meta">Метаданные не предоставляются сайтом, загрузка видео будет неудачной, если они не существуют на сайте.</string> <string name="provider_info_meta">Метаданные не предоставляются сайтом, загрузка видео будет неудачной, если они не существуют на сайте.</string>
@ -151,7 +151,7 @@
<string name="restore_failed_format" formatted="true">Не удалось восстановить данные из %s</string> <string name="restore_failed_format" formatted="true">Не удалось восстановить данные из %s</string>
<string name="backup_failed">Отсутствует разрешение на хранение. Пожалуйста попробуйте снова.</string> <string name="backup_failed">Отсутствует разрешение на хранение. Пожалуйста попробуйте снова.</string>
<string name="category_account">Аккаунты</string> <string name="category_account">Аккаунты</string>
<string name="category_updates">Обновления и резервное копирование</string> <string name="category_updates">Обновления и резервное</string>
<string name="settings_info">Информация</string> <string name="settings_info">Информация</string>
<string name="advanced_search">Расширенный поиск</string> <string name="advanced_search">Расширенный поиск</string>
<string name="show_trailers_settings">Показывать трейлеры</string> <string name="show_trailers_settings">Показывать трейлеры</string>
@ -166,20 +166,20 @@
<string name="app_language">Язык приложения</string> <string name="app_language">Язык приложения</string>
<string name="no_links_found_toast">Ссылок не найдено</string> <string name="no_links_found_toast">Ссылок не найдено</string>
<string name="copy_link_toast">Ссылка скопирована в буфер обмена</string> <string name="copy_link_toast">Ссылка скопирована в буфер обмена</string>
<string name="subs_default_reset_toast">Восстановить к изначальному значению</string> <string name="subs_default_reset_toast">Восстановить по умолчанию</string>
<string name="acra_report_toast">Извините, приложение прекратило работу. Анонимный отчет об ошибке был отправлен разработчикам</string> <string name="acra_report_toast">Извините, приложение прекратило работу. Анонимный отчет об ошибке будет отправлен разработчикам</string>
<string name="episode">Эпизод</string> <string name="episode">Эпизод</string>
<string name="episodes">Эпизоды</string> <string name="episodes">Эпизодов</string>
<string name="season_short">С</string> <string name="season_short">С</string>
<string name="episode_short">Э</string> <string name="episode_short">Э</string>
<string name="no_episodes_found">Эпизоды не найдены</string> <string name="no_episodes_found">Эпизоды не найдены</string>
<string name="delete_file">Удалить файл</string> <string name="delete_file">Удалить файл</string>
<string name="resume">Возобновить</string> <string name="resume">Продолжить</string>
<string name="go_back_30">-30</string> <string name="go_back_30">-30</string>
<string name="go_forward_30">+30</string> <string name="go_forward_30">+30</string>
<string name="delete_message" formatted="true">Это будет удалено безвозвратно%s <string name="delete_message" formatted="true">Это будет удалено безвозвратно%s
\nВы уверены\?</string> \nВы уверены\?</string>
<string name="resume_time_left" formatted="true">%dм <string name="resume_time_left" formatted="true">%d мин.
\nосталось</string> \nосталось</string>
<string name="status_completed">Завершено</string> <string name="status_completed">Завершено</string>
<string name="year">Год</string> <string name="year">Год</string>
@ -193,11 +193,317 @@
<string name="others">Другое</string> <string name="others">Другое</string>
<string name="storage_error">Ошибка загрузки, проверьте разрешения хранилища</string> <string name="storage_error">Ошибка загрузки, проверьте разрешения хранилища</string>
<string name="episode_action_copy_link">Копировать ссылку</string> <string name="episode_action_copy_link">Копировать ссылку</string>
<string name="episode_action_auto_download">Автоматическая загрузка</string> <string name="episode_action_auto_download">Автоскачивание</string>
<string name="episode_action_download_mirror">Загрузка. Зеркало</string> <string name="episode_action_download_mirror">Загрузка. Зеркало</string>
<string name="season">Сезон</string> <string name="season">Сезон</string>
<string name="anim">Аниме приложение от тех же разработчиков</string> <string name="anim">Аниме приложение от тех же разработчиков</string>
<string name="automatic_plugin_download_summary">Автоматически загружать еще не установленные плагины из добавленных репозиториев.</string> <string name="automatic_plugin_download_summary">Автоматически загружать еще не установленные плагины из добавленных репозиториев.</string>
<string name="discord">Присоединится в Discord</string> <string name="discord">Присоединится в Discord</string>
<string name="free_storage">Бесплатно</string> <string name="free_storage">Бесплатно</string>
<string name="next_episode_time_min_format" formatted="true">%d мин.</string>
<string name="next_episode_time_hour_format" formatted="true">%d ч. %d мин.</string>
<string name="movies">Фильмы</string>
<string name="cartoons_singular">Мультфильм</string>
<string name="tv_series">Сериалы</string>
<string name="asian_drama">Азиатские драмы</string>
<string name="other_singular">Видео</string>
<string name="cartoons">Мультфильмы</string>
<string name="documentaries">Документальные фильмы</string>
<string name="ova">OVA</string>
<string name="nsfw">NSFW</string>
<string name="nsfw_singular">NSFW</string>
<string name="movies_singular">Фильм</string>
<string name="tv_series_singular">Сериал</string>
<string name="torrent_singular">Торрент</string>
<string name="documentaries_singular">Документальный</string>
<string name="asian_drama_singular">Азиатская драма</string>
<string name="category_general">Общие</string>
<string name="category_providers">Провайдеры</string>
<string name="category_ui">Макет</string>
<string name="pref_category_extensions">Расширения</string>
<string name="category_player">Плеер</string>
<string name="backup_settings">Резервное копирование данных</string>
<string name="bug_report_settings_off">Отправлять данные только при вылетах</string>
<string name="used_storage">Использовано</string>
<string name="double_tap_to_pause_settings">Двойное нажатие для паузы</string>
<string name="double_tap_to_seek_settings_des">Коснитесь дважды правой или левой стороны для поиска вперед или назад</string>
<string name="double_tap_to_pause_settings_des">Нажмите в центре для паузы</string>
<string name="use_system_brightness_settings">Использовать системную яркость</string>
<string name="episode_sync_settings_des">Автоматически синхронизировать текущий прогресс эпизода</string>
<string name="backup_failed_error_format">Ошибка резервного копирования %s</string>
<string name="restore_settings">Восстановить данные из резервной копии</string>
<string name="show_fillers_settings">Показывать Филлер эпизоды для аниме</string>
<string name="kitsu_settings">Показывать афиши из Kitsu</string>
<string name="apk_installer_settings_des">Некоторые телефоны не поддерживают новые установщики. Попробуйте использовать legacy (старый) вариант, если обновления не устанавливаются.</string>
<string name="status_ongoing">Выходит</string>
<string name="video_lock">Блокировка</string>
<string name="no_update_found">Обновление не найдено</string>
<string name="video_aspect_ratio_resize">Изменить размер</string>
<string name="video_source">Источник</string>
<string name="check_for_update">Проверить обновления</string>
<string name="add_site_pref">Клон сайта</string>
<string name="dns_pref">DNS через HTTPS</string>
<string name="remove_site_pref">Удалить сайт</string>
<string name="legal_notice">Оговорка</string>
<string name="subtitle_offset">Синхронизация субтитров</string>
<string name="add_site_summary">Добавить клон существующего сайта с другим URL-адресом</string>
<string name="dns_pref_summary">Используется для обхода блокировок интернет провайдера</string>
<string name="download_path_pref">Путь скачивания</string>
<string name="benene_des">Давал бенен</string>
<string name="update">Обновить</string>
<string name="primary_color_settings">Основной цвет</string>
<string name="provider_lang_settings">Языки поставщиков</string>
<string name="repository_name_hint">Название репозитория</string>
<string name="clear_history">Очистить историю</string>
<string name="referer">Referer</string>
<string name="benene">Дайте бенен разрабам</string>
<string name="pref_category_links">Ссылки</string>
<string name="pref_category_player_layout">Макет</string>
<string name="app_layout">Макет приложения</string>
<string name="app_theme_settings">Тема приложения</string>
<string name="add_repository">Добавить репозиторий</string>
<string name="action_remove_from_watched">Убрать отметку</string>
<string name="confirm_exit_dialog">Вы уверены, что хотите выйти\?</string>
<string name="plugin_downloaded">Плагин скачан</string>
<string name="plugin_deleted">Плагин удалён</string>
<string name="extension_description">Описание</string>
<string name="extension_version">Версия</string>
<string name="extension_status">Статус</string>
<string name="extension_size">Размер</string>
<string name="extension_authors">Авторы</string>
<string name="extension_types">Поддерживается</string>
<string name="player_settings_play_in_vlc">VLC</string>
<string name="player_settings_play_in_mpv">MPV</string>
<string name="skip_type_format" formatted="true">Пропустить %s</string>
<string name="skip_type_ed">Концовка</string>
<string name="use_system_brightness_settings_des">Используйте яркость системы в проигрывателе приложения вместо темного наложения</string>
<string name="episode_sync_settings">Обновить состояние хода просмотра</string>
<string name="backup_success">Данные сохранены</string>
<string name="advanced_search_des">Показывает результаты поиска, разделенные по провайдеру</string>
<string name="uprereleases_settings_des">Поиск предварительных обновлений вместо полных выпусков</string>
<string name="redo_setup_process">Повторить процесс настройки</string>
<string name="no_chromecast_support_toast">Этот провайдер не поддерживает Chromecast</string>
<string name="season_format">%s %d%s</string>
<string name="no_season">Нет сезона</string>
<string name="episodes_range">%d-%d</string>
<string name="episode_format" formatted="true">%d %s</string>
<string name="livestreams">Прямые трансляции</string>
<string name="live_singular">Прямая трансляция</string>
<string name="source_error">Ошибка источника</string>
<string name="remote_error">Ошибка пульта</string>
<string name="render_error">Ошибка рендера</string>
<string name="unexpected_error">Неожиданная ошибка плеера</string>
<string name="episode_action_chromecast_episode">Эпизод Chromecast</string>
<string name="episode_action_play_in_format">Воспроизведение на %s</string>
<string name="episode_action_play_in_browser">Воспроизвести в браузере</string>
<string name="episode_action_download_subtitle">Скачать субтитры</string>
<string name="show_hd">Знак качества</string>
<string name="poster_ui_settings">Переключение элементов интерфейса на плакате</string>
<string name="video_skip_op">Пропустить OP</string>
<string name="dont_show_again">Больше не показывать</string>
<string name="skip_update">Пропустить это обновление</string>
<string name="nginx_url_pref">URL сервера NGINX</string>
<string name="create_account">Создать учётную запись</string>
<string name="add_sync">Добавить слежение</string>
<string name="added_sync_format" formatted="true">Добавлено %s</string>
<string name="upload_sync">Синхронизировать</string>
<string name="sync_score">Оценено</string>
<string name="sync_score_format" formatted="true">%d из 10</string>
<string name="safe_mode_crash_info">Посмотреть информацию о сбое</string>
<string name="player_pref">Предпочитаемый видеоплеер</string>
<string name="player_settings_play_in_browser">Веб-браузер</string>
<string name="app_not_found_error">Приложение не найдено</string>
<string name="all_languages_preference">Все языки</string>
<string name="skip_type_op">Вступление</string>
<string name="skip_type_creddits">Титры</string>
<string name="action_mark_as_watched">Отметить как просмотренное</string>
<string name="limit_title_rez">Разрешение видеоплеера</string>
<string name="watch_quality_pref">Желаемое качество видео</string>
<string name="limit_title">Максимум символов</string>
<string name="video_buffer_length_settings">Длинна буфера</string>
<string name="video_buffer_disk_settings">Кеш видео на диске</string>
<string name="video_buffer_size_settings">Размер буфера</string>
<string name="video_buffer_clear_settings">Отчистить кеш видео и изображений</string>
<string name="video_ram_description">Вызывает сбои, если установлено слишком высокое значение на устройствах с небольшим объемом памяти, таких как Android TV.</string>
<string name="video_disk_description">Вызывает проблемы, если установлено слишком высокое значение на устройствах с небольшим объемом памяти, таких как Android TV.</string>
<string name="lightnovel">Легкая новелла от тех же разработчиков</string>
<string name="extension_language">Язык</string>
<string name="hls_playlist">Плейлист HLS</string>
<string name="extension_install_first">Сначала установить расширение</string>
<string name="player_settings_play_in_app">Внутренний проигрыватель</string>
<string name="synopsis">Синопсис</string>
<string name="skip_type_intro">Интро</string>
<string name="example_email">hello@world.com</string>
<string name="episode_action_chromecast_mirror">Зеркало Chromecast</string>
<string name="episode_action_play_in_app">Воспроизвести в приложении</string>
<string name="pref_category_defaults">По умолчанию</string>
<string name="pref_category_player_features">Возможности плеера</string>
<string name="pref_category_subtitles">Субтитры</string>
<string name="bottom_title_settings">Расположение названия плаката</string>
<string name="tv_layout">ТV (телевидение)</string>
<string name="phone_layout">Телефон</string>
<string name="emulator_layout">Эмулятор</string>
<string name="bottom_title_settings_des">Под плакатом</string>
<string name="example_password">parol123</string>
<string name="example_username">МоёИмяПользователя</string>
<string name="switch_account">Сменить учётную запись</string>
<string name="add_account">Добавить учётную запись</string>
<string name="example_site_name">МойКрутойСайт</string>
<string name="example_site_url">example.com</string>
<string name="example_lang_name">Код языка (ru)</string>
<string name="account">учётная запись</string>
<string name="automatic">Автоматически</string>
<string name="example_ip">127.0.0.1</string>
<string name="pref_category_app_updates">Обновления приложения</string>
<string name="pref_category_backup">Резервная копия</string>
<string name="pref_category_actions">Действия</string>
<string name="pref_category_cache">Кэш</string>
<string name="pref_category_gestures">Жесты</string>
<string name="setup_done">Готово</string>
<string name="extensions">Расширения</string>
<string name="repository_url_hint">URL репозитория</string>
<string name="plugin_loaded">Плагин загружен</string>
<string name="action_open_play">\@string/home_play</string>
<string name="double_tap_to_seek_settings">Перемотка двойным нажатием</string>
<string name="sync_total_episodes_none">/\?\?</string>
<string name="sync_total_episodes_some" formatted="true">/%d</string>
<string name="is_adult">18+</string>
<string name="plugin_load_fail" formatted="true">Не удалось загрузить %s</string>
<string name="plugin">плагины</string>
<string name="quality_sdr">SDR</string>
<string name="quality_ts">TS</string>
<string name="delete_repository">Удалить репозиторий</string>
<string name="quality_sd">SD</string>
<string name="quality_4k">4K</string>
<string name="quality_webrip">Web</string>
<string name="quality_uhd">UHD</string>
<string name="plugin_singular">плагин</string>
<string name="skip_setup">Пропустить настройку</string>
<string name="error">Ошибка</string>
<string name="quality_cam_hd">Cam</string>
<string name="quality_cam_rip">Cam</string>
<string name="quality_hdr">HDR</string>
<string name="quality_dvd">DVD</string>
<string name="quality_workprint">WP</string>
<string name="quality_tc">TC</string>
<string name="quality_hd">HD</string>
<string name="quality_blueray">Blu-ray</string>
<string name="quality_cam">Cam</string>
<string name="quality_hq">HQ</string>
<string name="plugins_disabled" formatted="true">Отключено: %d</string>
<string name="login_format" formatted="true">%s %s</string>
<string name="authenticated_user" formatted="true">%s аутентифицировано</string>
<string name="authenticated_user_fail" formatted="true">Не удается логин на %s</string>
<string name="max">Макс</string>
<string name="min">Мин</string>
<string name="subtitles_outline">Контурный</string>
<string name="subtitles_shadow">С тенью</string>
<string name="subtitle_offset_hint">1000 мс</string>
<string name="subtitle_offset_title">Задержка субтитров</string>
<string name="subtitle_offset_extra_hint_none_format">Без задержки субтитров</string>
<string name="subtitle_offset_extra_hint_later_format">Используйте, если субтитры отображаются на %d мс слишком рано</string>
<string name="subtitle_offset_extra_hint_before_format">Используйте, если субтитры отображаются %d мс слишком поздно</string>
<string name="normal">Нормально</string>
<string name="subtitles_raised">Поднятые</string>
<string name="subtitles_example_text">Съешь ещё этих мягких французских булок, да выпей же чаю</string>
<string name="recommended">Рекомендуется</string>
<string name="player_loaded_subtitles" formatted="true">Загружено %s</string>
<string name="anime_singular">\@нить/аниме</string>
<string name="ova_singular">\@нить/ova</string>
<string name="show_dub">Этикетка Dub</string>
<string name="site">Сайт</string>
<string name="pref_category_ui_features">Функции</string>
<string name="actor_main">Главное</string>
<string name="home_source">Источник</string>
<string name="home_random">Случайный</string>
<string name="coming_soon">Скоро…</string>
<string name="show_sub">Этикетка Sub</string>
<string name="actor_background">Фон</string>
<string name="pref_category_looks">Oтoбpaжeниe</string>
<string name="trailer">Трейлер</string>
<string name="single_plugin_disabled" formatted="true">%s (отключено)</string>
<string name="next">Следующий</string>
<string name="blank_repo_message">В CloudStream по умолчанию не установлены сайты. Вам необходимо установить сайты из репозиториев.
\n
\nИз-за безмозглой DMCA-атаки со стороны Sky UK Limited 🤮 мы не можем привязать сайт репозитория в приложении.
\n
\nПрисоединяйтесь к нашему Discord или ищите в интернете.</string>
<string name="error_invalid_data">Недопустимые данные</string>
<string name="resolution_and_title">Разрешение и название</string>
<string name="previous">Предыдущий</string>
<string name="resolution">Разрешение</string>
<string name="browser">Браузер</string>
<string name="library">Библиотека</string>
<string name="sort_updated_old">Обновленный (старый - новый)</string>
<string name="sort_alphabetical_a">Алфавитный (А до Я)</string>
<string name="sort_alphabetical_z">Алфавитный (Я до А)</string>
<string name="select_library">Выбрать библиотеку</string>
<string name="open_with">Открыть с</string>
<string name="empty_library_no_accounts_message">Похоже, ваша библиотека пуста :(
\nВойдите в аккаунт с библиотекой или добавьте сериалы в локальную библиотеку</string>
<string name="sort">Сортировка</string>
<string name="view_public_repositories_button_short">Открытый список</string>
<string name="sort_rating_desc">Рейтинг (высокий - низкий)</string>
<string name="sort_rating_asc">Рейтинг (низкий - высокий)</string>
<string name="sort_updated_new">Обновленный (новый - старый)</string>
<string name="sort_by">Сортировать по</string>
<string name="apk_installer_package_installer">PackageInstaller</string>
<string name="subtitles_encoding">Кодировка субтитров</string>
<string name="player_load_subtitles">Загрузить из файла</string>
<string name="extension_rating" formatted="true">Рейтинг: %s</string>
<string name="batch_download_finish_format" formatted="true">Скачано %d %s</string>
<string name="batch_download_nothing_to_download_format" formatted="true">Все %s уже скачаны</string>
<string name="batch_download_start_format" formatted="true">Начата загрузка %d %s…</string>
<string name="plugins_not_downloaded" formatted="true">Не скачано: %d</string>
<string name="download_all_plugins_from_repo">Скачать все плагины из этого репозитория\?</string>
<string name="safe_mode_title">Включен безопасный режим</string>
<string name="plugins_downloaded" formatted="true">Скачано: %d</string>
<string name="plugins_updated" formatted="true">Обновлено %d плагинов</string>
<string name="player_load_subtitles_online">Загрузить из интернета</string>
<string name="update_notification_downloading">Загрузка обновления приложения…</string>
<string name="error_invalid_url">Недопустимый URL</string>
<string name="apply_on_restart">Применить при перезапуске</string>
<string name="crash_reporting_title">Отчеты ошибках</string>
<string name="preferred_media_subtext">Что вы хотите увидеть</string>
<string name="provider_languages_tip">Смотрите видео на этих языках</string>
<string name="downloaded_file">Скачано файл</string>
<string name="poster_image">Изображение постера</string>
<string name="batch_download">Пакетная загрузка</string>
<string name="setup_extensions_subtext">Скачайте список сайтов, который вы хотите использовать</string>
<string name="display_subbed_dubbed_settings">Отображать Аниме с Дубляжом/Субтитрами</string>
<string name="enable_nsfw_on_providers">Включить NSFW на поддерживаемых провайдерах</string>
<string name="subtitles_remove_captions">Удалять скрытые субтитры из субтитров</string>
<string name="extras">Дополнительно</string>
<string name="app_layout_subtext">Изменить вид интерфейса, чтобы соответствовать устройству</string>
<string name="audio_tracks">Аудио дорожки</string>
<string name="delete_repository_plugins">Это также удалит все плагины репозитория</string>
<string name="view_public_repositories_button">Просмотреть репозитории сообщества</string>
<string name="video_tracks">Видео дорожки</string>
<string name="safe_mode_description">Все расширения были отключены из-за сбоя, чтобы помочь вам найти то, которое вызывает проблемы.</string>
<string name="skip_type_recap">Повтор</string>
<string name="clipboard_too_large">Слишком много текста. Не удалось сохранить в буфер обмена.</string>
<string name="update_notification_installing">Установка обновления приложения…</string>
<string name="update_notification_failed">Не удалось установить новую версию приложения</string>
<string name="safe_mode_file">Файл безопасного режима найден!
\nНе загружаются никакие расширения при запуске, пока файл не будет удален.</string>
<string name="delayed_update_notice">Приложение будет обновлено после выхода</string>
<string name="empty_library_logged_in_message">Похоже, этот список пуст, попробуйте переключиться на другой</string>
<string name="uppercase_all_subtitles">Все субтитры заглавными</string>
<string name="enable_skip_op_from_database_des">Показывать всплывающие окна для пропуска вступления/заключения</string>
<string name="subtitles_filter_lang">Фильтровать по предпочитаемому языку медиа</string>
<string name="error_invalid_id">Неверный ID</string>
<string name="network_adress_example">Ссылка на стрим</string>
<string name="random_button_settings_desc">Отображать рандомную кнопку на Главной странице</string>
<string name="random_button_settings">Рандомная кнопка</string>
<string name="apk_installer_legacy">Legacy (старый)</string>
<string name="player_settings_play_in_web">Веб видеокаст</string>
<string name="bug_report_settings_on">Не отправляет данные</string>
<string name="episode_action_reload_links">Перезагрузить ссылки</string>
<string name="preferred_media_settings">Предпочтительные медиа</string>
<string name="subtitles_depressed">Опущенные</string>
<string name="double_tap_to_seek_amount_settings">Объем перемотки плеера</string>
<string name="android_tv_interface_on_seek_settings_summary">Объем перемотка, используемый, когда плеер виден</string>
<string name="android_tv_interface_on_seek_settings">Плеер показан - Перемотки объем</string>
<string name="android_tv_interface_off_seek_settings">Плеер спрятан - Перемотки объем</string>
<string name="subtitles_remove_bloat">Удалять лишнее из субтитров</string>
</resources> </resources>

Some files were not shown because too many files have changed in this diff Show more