mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Merge branch 'arabicLanguage' of https://github.com/SANCTI-afk/cloudstream into arabicLanguage
This commit is contained in:
commit
057e8d1206
16 changed files with 642 additions and 156 deletions
|
@ -17,13 +17,11 @@ import com.lagradost.cloudstream3.ui.player.SubtitleData
|
|||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.Qualities
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||
import okhttp3.Interceptor
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.collections.MutableList
|
||||
|
||||
const val USER_AGENT =
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||
|
@ -191,17 +189,26 @@ object APIHolder {
|
|||
return list.filter { names.contains(it) }.map { DubStatus.valueOf(it) }.toHashSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the activated provider languages
|
||||
* Used to obey the preference provider_lang_key
|
||||
* but it turned out too complicated and unnecessary with extensions.
|
||||
**/
|
||||
fun Context.getApiProviderLangSettings(): HashSet<String> {
|
||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val hashSet = HashSet<String>()
|
||||
hashSet.add("en") // def is only en
|
||||
val list = settingsManager.getStringSet(
|
||||
this.getString(R.string.provider_lang_key),
|
||||
hashSet.toMutableSet()
|
||||
)
|
||||
val langs = apis.map { it.lang }.toSet()
|
||||
.sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) }
|
||||
return langs.toHashSet()
|
||||
|
||||
if (list.isNullOrEmpty()) return hashSet
|
||||
return list.toHashSet()
|
||||
// val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
// val hashSet = HashSet<String>()
|
||||
// hashSet.add("en") // def is only en
|
||||
// val list = settingsManager.getStringSet(
|
||||
// this.getString(R.string.provider_lang_key),
|
||||
// hashSet.toMutableSet()
|
||||
// )
|
||||
//
|
||||
// if (list.isNullOrEmpty()) return hashSet
|
||||
// return list.toHashSet()
|
||||
}
|
||||
|
||||
fun Context.getApiTypeSettings(): HashSet<TvType> {
|
||||
|
@ -324,13 +331,24 @@ data class SettingsJson(
|
|||
data class MainPageData(
|
||||
val name: String,
|
||||
val data: String,
|
||||
val horizontalImages: Boolean = false
|
||||
)
|
||||
|
||||
data class MainPageRequest(
|
||||
val name: String,
|
||||
val data: String,
|
||||
val horizontalImages: Boolean,
|
||||
//TODO genre selection or smth
|
||||
)
|
||||
|
||||
fun mainPage(url: String, name: String, horizontalImages: Boolean = false): MainPageData {
|
||||
return MainPageData(name = name, data = url, horizontalImages = horizontalImages)
|
||||
}
|
||||
|
||||
fun mainPageOf(vararg elements: MainPageData): List<MainPageData> {
|
||||
return elements.toList()
|
||||
}
|
||||
|
||||
/** return list of MainPageData with url to name, make for more readable code */
|
||||
fun mainPageOf(vararg elements: Pair<String, String>): List<MainPageData> {
|
||||
return elements.map { (url, name) -> MainPageData(name = name, data = url) }
|
||||
|
@ -339,7 +357,7 @@ fun mainPageOf(vararg elements: Pair<String, String>): List<MainPageData> {
|
|||
fun newHomePageResponse(
|
||||
name: String,
|
||||
list: List<SearchResponse>,
|
||||
hasNext: Boolean? = null
|
||||
hasNext: Boolean? = null,
|
||||
): HomePageResponse {
|
||||
return HomePageResponse(
|
||||
listOf(HomePageList(name, list)),
|
||||
|
@ -347,6 +365,17 @@ fun newHomePageResponse(
|
|||
)
|
||||
}
|
||||
|
||||
fun newHomePageResponse(
|
||||
data: MainPageRequest,
|
||||
list: List<SearchResponse>,
|
||||
hasNext: Boolean? = null,
|
||||
): HomePageResponse {
|
||||
return HomePageResponse(
|
||||
listOf(HomePageList(data.name, list, data.horizontalImages)),
|
||||
hasNext = hasNext ?: list.isNotEmpty()
|
||||
)
|
||||
}
|
||||
|
||||
fun newHomePageResponse(list: HomePageList, hasNext: Boolean? = null): HomePageResponse {
|
||||
return HomePageResponse(listOf(list), hasNext = hasNext ?: list.list.isNotEmpty())
|
||||
}
|
||||
|
@ -384,11 +413,14 @@ abstract class MainAPI {
|
|||
/** if this is turned on then it will request the homepage one after the other,
|
||||
used to delay if they block many request at the same time*/
|
||||
open var sequentialMainPage: Boolean = false
|
||||
|
||||
/** in milliseconds, this can be used to add more delay between homepage requests
|
||||
* on first load if sequentialMainPage is turned on */
|
||||
open var sequentialMainPageDelay: Long = 0L
|
||||
|
||||
/** in milliseconds, this can be used to add more delay between homepage requests when scrolling */
|
||||
open var sequentialMainPageScrollDelay: Long = 0L
|
||||
|
||||
/** used to keep track when last homepage request was in unixtime ms */
|
||||
var lastHomepageRequest: Long = 0L
|
||||
|
||||
|
@ -423,7 +455,8 @@ abstract class MainAPI {
|
|||
open val vpnStatus = VPNStatus.None
|
||||
open val providerType = ProviderType.DirectProvider
|
||||
|
||||
open val mainPage = listOf(MainPageData("", ""))
|
||||
//emptyList<MainPageData>() //
|
||||
open val mainPage = listOf(MainPageData("", "", false))
|
||||
|
||||
@WorkerThread
|
||||
open suspend fun getMainPage(
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.*
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||
|
||||
class Vidmolyme : Vidmoly() {
|
||||
override val mainUrl = "https://vidmoly.me"
|
||||
}
|
||||
|
||||
open class Vidmoly : ExtractorApi() {
|
||||
override val name = "Vidmoly"
|
||||
override val mainUrl = "https://vidmoly.to"
|
||||
override val requiresReferer = true
|
||||
|
||||
private fun String.addMarks(str: String): String {
|
||||
return this.replace(Regex("\"?$str\"?"), "\"$str\"")
|
||||
}
|
||||
|
||||
override suspend fun getUrl(
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
|
||||
val script = app.get(
|
||||
url,
|
||||
referer = referer,
|
||||
).document.select("script")
|
||||
.find { it.data().contains("sources:") }?.data()
|
||||
val videoData = script?.substringAfter("sources: [")
|
||||
?.substringBefore("],")?.addMarks("file")
|
||||
val subData = script?.substringAfter("tracks: [")?.substringBefore("]")?.addMarks("file")
|
||||
?.addMarks("label")?.addMarks("kind")
|
||||
|
||||
tryParseJson<Source>(videoData)?.file?.let { m3uLink ->
|
||||
M3u8Helper.generateM3u8(
|
||||
name,
|
||||
m3uLink,
|
||||
"$mainUrl/"
|
||||
).forEach(callback)
|
||||
}
|
||||
|
||||
tryParseJson<List<SubSource>>("[${subData}]")
|
||||
?.filter { it.kind == "captions" }?.map {
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
it.label.toString(),
|
||||
fixUrl(it.file.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private data class Source(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
)
|
||||
|
||||
private data class SubSource(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
@JsonProperty("label") val label: String? = null,
|
||||
@JsonProperty("kind") val kind: String? = null,
|
||||
)
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.lagradost.cloudstream3.extractors
|
||||
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||
|
||||
open class Voe : ExtractorApi() {
|
||||
override val name = "Voe"
|
||||
override val mainUrl = "https://voe.sx"
|
||||
override val requiresReferer = true
|
||||
|
||||
override suspend fun getUrl(
|
||||
url: String,
|
||||
referer: String?,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val res = app.get(url, referer = referer).document
|
||||
val link = res.select("script").find { it.data().contains("const sources") }?.data()
|
||||
?.substringAfter("\"hls\": \"")?.substringBefore("\",")
|
||||
|
||||
M3u8Helper.generateM3u8(
|
||||
name,
|
||||
link ?: return,
|
||||
"$mainUrl/",
|
||||
headers = mapOf("Origin" to "$mainUrl/")
|
||||
).forEach(callback)
|
||||
|
||||
}
|
||||
}
|
|
@ -75,7 +75,7 @@ class APIRepository(val api: MainAPI) {
|
|||
api.lastHomepageRequest = unixTimeMS
|
||||
|
||||
nameIndex?.let { api.mainPage.getOrNull(it) }?.let { data ->
|
||||
listOf(api.getMainPage(page, MainPageRequest(data.name, data.data)))
|
||||
listOf(api.getMainPage(page, MainPageRequest(data.name, data.data, data.horizontalImages)))
|
||||
} ?: run {
|
||||
if (api.sequentialMainPage) {
|
||||
var first = true
|
||||
|
@ -84,11 +84,17 @@ class APIRepository(val api: MainAPI) {
|
|||
delay(api.sequentialMainPageDelay)
|
||||
first = false
|
||||
|
||||
api.getMainPage(page, MainPageRequest(data.name, data.data))
|
||||
api.getMainPage(
|
||||
page,
|
||||
MainPageRequest(data.name, data.data, data.horizontalImages)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
api.mainPage.apmap { data ->
|
||||
api.getMainPage(page, MainPageRequest(data.name, data.data))
|
||||
api.getMainPage(
|
||||
page,
|
||||
MainPageRequest(data.name, data.data, data.horizontalImages)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import androidx.core.view.isVisible
|
|||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
|
||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent
|
||||
import com.lagradost.cloudstream3.R
|
||||
|
@ -25,7 +24,6 @@ import com.lagradost.cloudstream3.mvvm.observe
|
|||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||
import com.lagradost.cloudstream3.ui.result.setText
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.downloadAllPluginsDialog
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
|
@ -34,7 +32,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
|||
import com.lagradost.cloudstream3.widget.LinearRecycleViewLayoutManager
|
||||
import kotlinx.android.synthetic.main.add_repo_input.*
|
||||
import kotlinx.android.synthetic.main.fragment_extensions.*
|
||||
import kotlinx.android.synthetic.main.fragment_extensions.list_repositories
|
||||
|
||||
const val PUBLIC_REPOSITORIES_LIST = "https://recloudstream.github.io/repos/"
|
||||
|
||||
|
@ -128,20 +125,20 @@ class ExtensionsFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
list_repositories?.setOnClickListener {
|
||||
// Open webview on tv if browser fails
|
||||
val isTv = isTvSettings()
|
||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
||||
|
||||
// Set clipboard on TV because the browser might not exist or work properly
|
||||
if (isTv) {
|
||||
val serviceClipboard =
|
||||
(activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?)
|
||||
?: return@setOnClickListener
|
||||
val clip = ClipData.newPlainText("Repository url", PUBLIC_REPOSITORIES_LIST)
|
||||
serviceClipboard.setPrimaryClip(clip)
|
||||
}
|
||||
}
|
||||
// list_repositories?.setOnClickListener {
|
||||
// // Open webview on tv if browser fails
|
||||
// val isTv = isTvSettings()
|
||||
// openBrowser(PUBLIC_REPOSITORIES_LIST, isTv, this)
|
||||
//
|
||||
// // Set clipboard on TV because the browser might not exist or work properly
|
||||
// if (isTv) {
|
||||
// val serviceClipboard =
|
||||
// (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?)
|
||||
// ?: return@setOnClickListener
|
||||
// val clip = ClipData.newPlainText("Repository url", PUBLIC_REPOSITORIES_LIST)
|
||||
// serviceClipboard.setPrimaryClip(clip)
|
||||
// }
|
||||
// }
|
||||
|
||||
observe(extensionViewModel.pluginStats) {
|
||||
when (it) {
|
||||
|
@ -200,11 +197,11 @@ class ExtensionsFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
dialog.list_repositories?.setOnClickListener {
|
||||
// Open webview on tv if browser fails
|
||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
dialog.dismissSafe()
|
||||
}
|
||||
// dialog.list_repositories?.setOnClickListener {
|
||||
// // Open webview on tv if browser fails
|
||||
// openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
// dialog.dismissSafe()
|
||||
// }
|
||||
|
||||
// dialog.text2?.text = provider.name
|
||||
dialog.apply_btt?.setOnClickListener secondListener@{
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.lagradost.cloudstream3.CommonActivity.showToast
|
|||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.apmap
|
||||
import com.lagradost.cloudstream3.mvvm.launchSafe
|
||||
import com.lagradost.cloudstream3.plugins.PluginData
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginPath
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||
|
@ -21,8 +20,8 @@ import com.lagradost.cloudstream3.ui.result.txt
|
|||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.runOnMainThread
|
||||
import kotlinx.coroutines.launch
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
import java.io.File
|
||||
|
||||
typealias Plugin = Pair<String, SitePlugin>
|
||||
/**
|
||||
|
@ -47,7 +46,11 @@ class PluginsViewModel : ViewModel() {
|
|||
private val repositoryCache: MutableMap<String, List<Plugin>> = mutableMapOf()
|
||||
const val TAG = "PLG"
|
||||
|
||||
private fun isDownloaded(context: Context, pluginName: String, repositoryUrl: String): Boolean {
|
||||
private fun isDownloaded(
|
||||
context: Context,
|
||||
pluginName: String,
|
||||
repositoryUrl: String
|
||||
): Boolean {
|
||||
return getPluginPath(context, pluginName, repositoryUrl).exists()
|
||||
}
|
||||
|
||||
|
@ -73,7 +76,13 @@ class PluginsViewModel : ViewModel() {
|
|||
if (activity == null) return@ioSafe
|
||||
val plugins = getPlugins(repositoryUrl)
|
||||
|
||||
plugins.filter { plugin -> !isDownloaded(activity, plugin.second.internalName, repositoryUrl) }.also { list ->
|
||||
plugins.filter { plugin ->
|
||||
!isDownloaded(
|
||||
activity,
|
||||
plugin.second.internalName,
|
||||
repositoryUrl
|
||||
)
|
||||
}.also { list ->
|
||||
main {
|
||||
showToast(
|
||||
activity,
|
||||
|
@ -133,9 +142,13 @@ class PluginsViewModel : ViewModel() {
|
|||
if (activity == null) return@ioSafe
|
||||
val (repo, metadata) = plugin
|
||||
|
||||
val file = getPluginPath(activity, plugin.second.internalName, plugin.first)
|
||||
val file = if (isLocal) File(plugin.second.url) else getPluginPath(
|
||||
activity,
|
||||
plugin.second.internalName,
|
||||
plugin.first
|
||||
)
|
||||
|
||||
val (success, message) = if (file.exists() || isLocal) {
|
||||
val (success, message) = if (file.exists()) {
|
||||
PluginManager.deletePlugin(file) to R.string.plugin_deleted
|
||||
} else {
|
||||
PluginManager.downloadAndLoadPlugin(
|
||||
|
@ -167,7 +180,9 @@ class PluginsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
this.plugins = list
|
||||
_filteredPlugins.postValue(false to list.filterTvTypes().filterLang().sortByQuery(currentQuery))
|
||||
_filteredPlugins.postValue(
|
||||
false to list.filterTvTypes().filterLang().sortByQuery(currentQuery)
|
||||
)
|
||||
}
|
||||
|
||||
// Perhaps can be optimized?
|
||||
|
@ -175,7 +190,8 @@ class PluginsViewModel : ViewModel() {
|
|||
if (tvTypes.isEmpty()) return this
|
||||
return this.filter {
|
||||
(it.plugin.second.tvTypes?.any { type -> tvTypes.contains(type) } == true) ||
|
||||
(tvTypes.contains("Others") && (it.plugin.second.tvTypes ?: emptyList()).isEmpty())
|
||||
(tvTypes.contains("Others") && (it.plugin.second.tvTypes
|
||||
?: emptyList()).isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +215,9 @@ class PluginsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
fun updateFilteredPlugins() {
|
||||
_filteredPlugins.postValue(false to plugins.filterTvTypes().filterLang().sortByQuery(currentQuery))
|
||||
_filteredPlugins.postValue(
|
||||
false to plugins.filterTvTypes().filterLang().sortByQuery(currentQuery)
|
||||
)
|
||||
}
|
||||
|
||||
fun updatePluginList(context: Context?, repositoryUrl: String) = viewModelScope.launchSafe {
|
||||
|
@ -210,7 +228,9 @@ class PluginsViewModel : ViewModel() {
|
|||
|
||||
fun search(query: String?) {
|
||||
currentQuery = query
|
||||
_filteredPlugins.postValue(true to (filteredPlugins.value?.second?.sortByQuery(query) ?: emptyList()))
|
||||
_filteredPlugins.postValue(
|
||||
true to (filteredPlugins.value?.second?.sortByQuery(query) ?: emptyList())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,6 +246,8 @@ class PluginsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
plugins = downloadedPlugins
|
||||
_filteredPlugins.postValue(false to downloadedPlugins.filterTvTypes().filterLang().sortByQuery(currentQuery))
|
||||
_filteredPlugins.postValue(
|
||||
false to downloadedPlugins.filterTvTypes().filterLang().sortByQuery(currentQuery)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -7,21 +7,16 @@ import android.view.ViewGroup
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.lagradost.cloudstream3.AcraApplication.Companion.openBrowser
|
||||
import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent
|
||||
import com.lagradost.cloudstream3.R
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.PUBLIC_REPOSITORIES_LIST
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.PluginsViewModel
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.RepoAdapter
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||
import kotlinx.android.synthetic.main.fragment_extensions.blank_repo_screen
|
||||
import kotlinx.android.synthetic.main.fragment_extensions.list_repositories
|
||||
import kotlinx.android.synthetic.main.fragment_extensions.repo_recycler_view
|
||||
import kotlinx.android.synthetic.main.fragment_setup_extensions.*
|
||||
import kotlinx.android.synthetic.main.fragment_setup_media.next_btt
|
||||
import kotlinx.android.synthetic.main.fragment_setup_media.prev_btt
|
||||
import kotlinx.android.synthetic.main.fragment_setup_media.setup_root
|
||||
|
@ -64,18 +59,19 @@ class SetupFragmentExtensions : Fragment() {
|
|||
val hasRepos = repositories.isNotEmpty()
|
||||
repo_recycler_view?.isVisible = hasRepos
|
||||
blank_repo_screen?.isVisible = !hasRepos
|
||||
view_public_repositories_button?.isVisible = hasRepos
|
||||
// view_public_repositories_button?.isVisible = hasRepos
|
||||
|
||||
if (hasRepos) {
|
||||
repo_recycler_view?.adapter = RepoAdapter(true, {}, {
|
||||
PluginsViewModel.downloadAll(activity, it.url, null)
|
||||
}).apply { updateList(repositories) }
|
||||
} else {
|
||||
list_repositories?.setOnClickListener {
|
||||
// Open webview on tv if browser fails
|
||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// list_repositories?.setOnClickListener {
|
||||
// // Open webview on tv if browser fails
|
||||
// openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +80,9 @@ class SetupFragmentExtensions : Fragment() {
|
|||
context?.fixPaddingStatusbar(setup_root)
|
||||
val isSetup = arguments?.getBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP) ?: false
|
||||
|
||||
view_public_repositories_button?.setOnClickListener {
|
||||
openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
}
|
||||
// view_public_repositories_button?.setOnClickListener {
|
||||
// openBrowser(PUBLIC_REPOSITORIES_LIST, isTvSettings(), this)
|
||||
// }
|
||||
|
||||
with(context) {
|
||||
if (this == null) return
|
||||
|
@ -100,7 +96,7 @@ class SetupFragmentExtensions : Fragment() {
|
|||
next_btt?.setOnClickListener {
|
||||
// Continue setup
|
||||
if (isSetup)
|
||||
findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_provider_languages)
|
||||
findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_media)
|
||||
else
|
||||
findNavController().navigate(R.id.navigation_home)
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ class SetupFragmentLanguage : Fragment() {
|
|||
&& PluginManager.getPluginsLocal().isEmpty()
|
||||
//&& PREBUILT_REPOSITORIES.isNotEmpty()
|
||||
) R.id.action_navigation_global_to_navigation_setup_extensions
|
||||
else R.id.action_navigation_setup_language_to_navigation_setup_provider_languages
|
||||
else R.id.action_navigation_setup_language_to_navigation_setup_media
|
||||
|
||||
findNavController().navigate(
|
||||
nextDestination,
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.lagradost.cloudstream3.utils
|
||||
|
||||
import android.net.Uri
|
||||
import com.lagradost.cloudstream3.SubtitleFile
|
||||
import com.lagradost.cloudstream3.TvType
|
||||
import com.lagradost.cloudstream3.USER_AGENT
|
||||
import com.lagradost.cloudstream3.app
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.extractors.*
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -323,6 +320,9 @@ val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
|||
Embedgram(),
|
||||
Mvidoo(),
|
||||
Streamplay(),
|
||||
Vidmoly(),
|
||||
Vidmolyme(),
|
||||
Voe(),
|
||||
|
||||
Gdriveplayerapi(),
|
||||
Gdriveplayerapp(),
|
||||
|
@ -399,6 +399,28 @@ suspend fun getPostForm(requestUrl: String, html: String): String? {
|
|||
).text
|
||||
}
|
||||
|
||||
fun ExtractorApi.fixUrl(url: String): String {
|
||||
if (url.startsWith("http") ||
|
||||
// Do not fix JSON objects when passed as urls.
|
||||
url.startsWith("{\"")
|
||||
) {
|
||||
return url
|
||||
}
|
||||
if (url.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
|
||||
val startsWithNoHttp = url.startsWith("//")
|
||||
if (startsWithNoHttp) {
|
||||
return "https:$url"
|
||||
} else {
|
||||
if (url.startsWith('/')) {
|
||||
return mainUrl + url
|
||||
}
|
||||
return "$mainUrl/$url"
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ExtractorApi {
|
||||
abstract val name: String
|
||||
abstract val mainUrl: String
|
||||
|
|
|
@ -28,15 +28,15 @@
|
|||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:nextFocusDown="@id/repo_name_input"
|
||||
android:id="@+id/list_repositories"
|
||||
android:nextFocusLeft="@id/apply_btt"
|
||||
android:nextFocusRight="@id/cancel_btt"
|
||||
style="@style/WhiteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/view_public_repositories_button_short" />
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:nextFocusDown="@id/repo_name_input"-->
|
||||
<!-- android:id="@+id/list_repositories"-->
|
||||
<!-- android:nextFocusLeft="@id/apply_btt"-->
|
||||
<!-- android:nextFocusRight="@id/cancel_btt"-->
|
||||
<!-- style="@style/WhiteButton"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_gravity="center_vertical"-->
|
||||
<!-- android:text="@string/view_public_repositories_button_short" />-->
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
|
@ -70,7 +70,6 @@
|
|||
android:autofillHints="username"
|
||||
android:hint="@string/repository_name_hint"
|
||||
android:inputType="text"
|
||||
android:nextFocusUp="@id/list_repositories"
|
||||
android:nextFocusLeft="@id/apply_btt"
|
||||
android:nextFocusRight="@id/cancel_btt"
|
||||
android:nextFocusDown="@id/site_url_input"
|
||||
|
|
|
@ -47,12 +47,12 @@
|
|||
android:text="@string/blank_repo_message"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/list_repositories"
|
||||
style="@style/WhiteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:nextFocusDown="@id/add_repo_button"
|
||||
android:text="@string/view_public_repositories_button" />
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:id="@+id/list_repositories"-->
|
||||
<!-- style="@style/WhiteButton"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:nextFocusDown="@id/add_repo_button"-->
|
||||
<!-- android:text="@string/view_public_repositories_button" />-->
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
android:text="@string/blank_repo_message"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/list_repositories"
|
||||
style="@style/WhiteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/view_public_repositories_button" />
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:id="@+id/list_repositories"-->
|
||||
<!-- style="@style/WhiteButton"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:text="@string/view_public_repositories_button" />-->
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
@ -68,12 +68,12 @@
|
|||
android:gravity="bottom|end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/view_public_repositories_button"
|
||||
style="@style/WhiteButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:text="@string/add_repository" />
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:id="@+id/view_public_repositories_button"-->
|
||||
<!-- style="@style/WhiteButton"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_gravity="center_vertical|end"-->
|
||||
<!-- android:text="@string/add_repository" />-->
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/next_btt"
|
||||
|
|
|
@ -522,6 +522,13 @@
|
|||
app:exitAnim="@anim/exit_anim"
|
||||
app:popEnterAnim="@anim/enter_anim"
|
||||
app:popExitAnim="@anim/exit_anim" />
|
||||
<action
|
||||
android:id="@+id/action_navigation_setup_language_to_navigation_setup_media"
|
||||
app:destination="@id/navigation_setup_media"
|
||||
app:enterAnim="@anim/enter_anim"
|
||||
app:exitAnim="@anim/exit_anim"
|
||||
app:popEnterAnim="@anim/enter_anim"
|
||||
app:popExitAnim="@anim/exit_anim" />
|
||||
</fragment>
|
||||
|
||||
<action
|
||||
|
@ -553,6 +560,13 @@
|
|||
app:exitAnim="@anim/exit_anim"
|
||||
app:popEnterAnim="@anim/enter_anim"
|
||||
app:popExitAnim="@anim/exit_anim" />
|
||||
<action
|
||||
android:id="@+id/action_navigation_setup_extensions_to_navigation_setup_media"
|
||||
app:destination="@id/navigation_setup_media"
|
||||
app:enterAnim="@anim/enter_anim"
|
||||
app:exitAnim="@anim/exit_anim"
|
||||
app:popEnterAnim="@anim/enter_anim"
|
||||
app:popExitAnim="@anim/exit_anim" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
|
|
@ -5,39 +5,39 @@
|
|||
<string name="title_search">Αναζήτηση</string>
|
||||
<string name="title_downloads">Λήψεις</string>
|
||||
<string name="title_settings">Ρυθμίσεις</string>
|
||||
<string name="search_hint">Ψάξε…</string>
|
||||
<string name="play_with_app_name">Άνοιγμα με CloudStream</string>
|
||||
<string name="search_hint">Αναζήτηση…</string>
|
||||
<string name="search_poster_img_des">Πόστερ</string>
|
||||
<string name="no_data">Χωρίς δεδομένα</string>
|
||||
<string name="episode_more_options_des">Περισσότερες Επιλογές</string>
|
||||
<string name="go_back_img_des">Πίσω</string>
|
||||
<string name="next_episode">Επόμενο Επισόδειο</string>
|
||||
<string name="next_episode">Επόμενο Επεισόδιο</string>
|
||||
<string name="result_poster_img_des">Πόστερ</string>
|
||||
<string name="synopsis">Πλοκή</string>
|
||||
<string name="result_tags">Genres</string>
|
||||
<string name="result_share">Μοίρασε</string>
|
||||
<string name="result_tags">Κατηγορίες</string>
|
||||
<string name="result_share">Κοινοποίηση</string>
|
||||
<string name="result_open_in_browser">Άνοιγμα στον περιηγητή</string>
|
||||
<string name="skip_loading">Προσπέραση φορτώματος</string>
|
||||
<string name="skip_loading">Παράλειψη φόρτωσης</string>
|
||||
<string name="loading">Φόρτωση…</string>
|
||||
|
||||
<string name="type_watching">Watching</string>
|
||||
<string name="type_on_hold">On-Hold</string>
|
||||
<string name="type_completed">Completed</string>
|
||||
<string name="type_dropped">Dropped</string>
|
||||
<string name="type_plan_to_watch">Plan to Watch</string>
|
||||
<string name="type_none">None</string>
|
||||
<string name="type_watching">Παρακολούθηση</string>
|
||||
<string name="type_on_hold">Σε αναμονή</string>
|
||||
<string name="type_completed">Ολοκληρώθηκε</string>
|
||||
<string name="type_dropped">Διακόπηκε</string>
|
||||
<string name="type_plan_to_watch">Για παρακολούθηση</string>
|
||||
<string name="type_none">Τίποτα</string>
|
||||
|
||||
<string name="play_movie_button">Αναπαραγωγή Ταινείας</string>
|
||||
<string name="play_movie_button">Αναπαραγωγή Ταινίας</string>
|
||||
<string name="play_torrent_button">Μετάδοση Torrent</string>
|
||||
<string name="pick_source">Πηγές</string>
|
||||
<string name="pick_subtitle">Υπότιτλοι</string>
|
||||
<string name="reload_error">Ξανά φόρτωσε…</string>
|
||||
<string name="reload_error">Προσπάθεια επανασύνδεσης…</string>
|
||||
<string name="go_back">Πίσω</string>
|
||||
<string name="episode_poster_img_des">Πόστερ</string>
|
||||
<string name="play_episode">Αναπαραγωγή Επισοδείου</string>
|
||||
<!--<string name="need_storage">Δώσε άδεια για την λήψη επισοδείου</string>-->
|
||||
<string name="download">Λήξη</string>
|
||||
<string name="error_loading_links_toast">Σφάλμα φόρτωσεις συνδέσμων</string>
|
||||
<string name="download_storage_text">Εσωτερικός χώρος</string>
|
||||
<string name="play_episode">Αναπαραγωγή Επεισοδίου</string>
|
||||
<!--<string name="need_storage">Απαιτείται άδεια για την λήψη επεισοδίου</string>-->
|
||||
<string name="download">Λήψη</string>
|
||||
<string name="error_loading_links_toast">Σφάλμα φόρτωσης συνδέσμων</string>
|
||||
<string name="download_storage_text">Εσωτερικός χώρος αποθήκευσης</string>
|
||||
<!--<string name="options">Επιλογές</string>-->
|
||||
|
||||
<string name="app_dubbed_text">Dub</string>
|
||||
|
@ -50,77 +50,372 @@
|
|||
|
||||
<string name="acra_report_toast">Λυπούμαστε, η εφαρμογή κατέρρευσε. Μια ανώνυμη αναφορά σφαλμάτων θα σταλεί στους προγραμματιστές</string>
|
||||
<string name="pref_disable_acra">Απενεργοποιήστε την αυτόματη αναφορά σφαλμάτων</string>
|
||||
<string name="show_log_cat">Εμφάνιση logcat 🐈</string>
|
||||
<string name="home_more_info">Παραπάνω πληροφορίες</string>
|
||||
<string name="home_expanded_hide">Κρύψιμο</string>
|
||||
<string name="home_expanded_hide">Απόκρυψη</string>
|
||||
<string name="home_main_poster_img_des">Κύριο Πόστερ</string>
|
||||
<string name="home_play">Αναπαραγωγή</string>
|
||||
<string name="home_info">Πληροφορίες</string>
|
||||
<string name="home_next_random_img_des">Next Random</string>
|
||||
<string name="home_change_provider_img_des">Change Provider</string>
|
||||
<string name="filter_bookmarks">Filter Bookmarks</string>
|
||||
<string name="error_bookmarks_text">Bookmarks</string>
|
||||
<string name="action_remove_from_bookmarks">Remove</string>
|
||||
<string name="play_episode_toast">Αναπαραγωγή Episode</string>
|
||||
<string name="home_change_provider_img_des">Αλλαγή Παρόχου</string>
|
||||
<string name="filter_bookmarks">Φιλτράρισμα Σελιδοδεικτών</string>
|
||||
<string name="error_bookmarks_text">Σελιδοδείκτες</string>
|
||||
<string name="action_remove_from_bookmarks">Αφαίρεση</string>
|
||||
<string name="play_episode_toast">Αναπαραγωγή Επεισοδίου</string>
|
||||
<string name="sort_apply">Υποβολή</string>
|
||||
<string name="sort_cancel">Ακύρωση</string>
|
||||
<string name="player_speed">Ταχύτητα αναπαραγωγής</string>
|
||||
<string name="subtitles_settings">Ρυθμίσεις υπότιτλων</string>
|
||||
<string name="subs_text_color">Χρώμα κείμενου</string>
|
||||
<string name="subs_text_color">Χρώμα κειμένου</string>
|
||||
<string name="subs_outline_color">Χρώμα περιγράμματος</string>
|
||||
<string name="subs_background_color">Χρώμα φόντου</string>
|
||||
<string name="subs_window_color">Χρώμα παραθύρου</string>
|
||||
<string name="subs_edge_type">Τύπος άκρων</string>
|
||||
<string name="subs_subtitle_elevation">Ύψωση υπότιτλων</string>
|
||||
<string name="subs_default_reset_toast">Επαναφορά στην προεπιλεγμένη τιμή</string>
|
||||
<string name="subs_default_reset_toast">Επαναφορά στις προεπιλεγμένες τιμές</string>
|
||||
<string name="preview_background_img_des">Προεπισκόπηση φόντου</string>
|
||||
<string name="subs_font">Γραμματοσειρά</string>
|
||||
<string name="search_provider_text_providers">Αναζήτηση με τους παρόχους</string>
|
||||
<string name="search_provider_text_types">Αναζήτηση με τύπους</string>
|
||||
<string name="benene_count_text">%d Benenes given to devs</string>
|
||||
<string name="benene_count_text_none">No Benenes given</string>
|
||||
<string name="search_provider_text_providers">Αναζήτηση βάσει παρόχων</string>
|
||||
<string name="search_provider_text_types">Αναζήτηση βάσει τύπων</string>
|
||||
<string name="benene_count_text">%d μπανάνες δόθηκαν στους προγραμματιστές</string>
|
||||
<string name="benene_count_text_none">Καμία μπανάνα δεν δόθηκε</string>
|
||||
|
||||
<string name="subs_auto_select_language">Αυτόματη επιλογή γλώσσας</string>
|
||||
<string name="subs_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="action_remove_watching">Αφαίρεση</string>
|
||||
<string name="action_open_watching">Παραπάνω Πληροφορίες</string>
|
||||
<string name="action_open_watching">Επιπλέον Πληροφορίες</string>
|
||||
|
||||
<string name="vpn_might_be_needed">A VPN might be needed for this provider to work correctly</string>
|
||||
<string name="vpn_torrent">This providers is a torrent, a VPN is recommended</string>
|
||||
<string name="vpn_might_be_needed">Η χρήση ενός VPN ίσως χρειαστεί για την ομαλή λειτουργία του τρέχοντος παρόχου</string>
|
||||
<string name="vpn_torrent">Πρόκειται για torrent, η χρήση ενός VPN συνιστάται</string>
|
||||
<string name="torrent_plot">Περιγραφή</string>
|
||||
<string name="normal_no_plot">Δεν βρέθηκε περιγραφή</string>
|
||||
<string name="torrent_no_plot">Δεν βρέθηκε περιγραφή</string>
|
||||
|
||||
<string name="picture_in_picture">Picture-in-picture</string>
|
||||
<string name="picture_in_picture_des">Συνεχίζει την αναπαραγωγή σε ένα μίνι παίκτη πάνω από άλλες εφαρμογές</string>
|
||||
<string name="player_size_settings">Αλλαγή μεγέθους παίκτη</string>
|
||||
<string name="picture_in_picture">Εικόνα-σε-Εικόνα</string>
|
||||
<string name="picture_in_picture_des">Συνεχίζει την αναπαραγωγή σε ένα μίνι παράθυρο πάνω από άλλες εφαρμογές</string>
|
||||
<string name="player_size_settings">Αλλαγή μεγέθους παραθύρου</string>
|
||||
<string name="player_size_settings_des">Αφαίρεση μαύρων περιγραμμάτων</string>
|
||||
<string name="player_subtitles_settings">Υπότιτλοι</string>
|
||||
<string name="player_subtitles_settings_des">Ρυθμίσεις υποτίτλων του παίκτη</string>
|
||||
<string name="player_subtitles_settings_des">Ρυθμίσεις υποτίτλων του προγράμματος αναπαραγωγής</string>
|
||||
<string name="chromecast_subtitles_settings">Chromecast Υπότιτλοι</string>
|
||||
<string name="chromecast_subtitles_settings_des">Ρυθμίσεις Chromecast υποτίτλων</string>
|
||||
<string name="eigengraumode_settings">Eigengrau Mode</string>
|
||||
<string name="eigengraumode_settings_des">Προσθέτει την επιλογή ταχύτητας στον παίκτη</string>
|
||||
<string name="swipe_to_seek_settings">Σύρετε για seek</string>
|
||||
<string name="swipe_to_seek_settings_des">Σύρετε αριστερά ή δεξιά για να ελέγξετε τον χρόνο στον παίκτη</string>
|
||||
<string name="eigengraumode_settings_des">Προσθέτει την επιλογή ταχύτητας στο πρόγραμμα αναπαραγωγής</string>
|
||||
<string name="swipe_to_seek_settings">Σύρετε για αναζήτηση</string>
|
||||
<string name="swipe_to_seek_settings_des">Σύρετε αριστερά ή δεξιά για να ελέγξετε τον χρόνο στην κάτω μπάρα</string>
|
||||
<string name="swipe_to_change_settings">Σύρετε για να αλλάξετε ρυθμίσεις</string>
|
||||
<string name="swipe_to_change_settings_des">Σύρετε αριστερά ή δεξιά για να αλλάξετε τη φωτεινότητα ή την ένταση</string>
|
||||
<string name="double_tap_to_seek_settings">Διπλό πάτημα για seek</string>
|
||||
<string name="double_tap_to_seek_settings_des">Διπλό πάτημα στα αριστερά ή δεξιά για seek μπροστά ή πίσω</string>
|
||||
<string name="double_tap_to_seek_settings">Διπλό πάτημα για αναζήτηση</string>
|
||||
<string name="double_tap_to_seek_settings_des">Διπλό πάτημα στα αριστερά ή δεξιά για αναζήτηση μπροστά ή πίσω</string>
|
||||
<string name="search">Αναζήτηση</string>
|
||||
<string name="settings_info">Πληροφορείες</string>
|
||||
<string name="settings_info">Πληροφορίες</string>
|
||||
<string name="advanced_search">Προχωρημένη Αναζήτηση</string>
|
||||
<string name="advanced_search_des">Δίνει τα αποτελέσματα αναζήτησης χωρισμένα ανά πάροχο</string>
|
||||
<string name="advanced_search_des">Δίνει τα αποτελέσματα αναζήτησης ταξινομημένα ανά πάροχο</string>
|
||||
<string name="bug_report_settings_off">Αποστέλλει δεδομένα μόνο για σφάλματα</string>
|
||||
<string name="bug_report_settings_on">Δεν στέλνει δεδομένα</string>
|
||||
<string name="updates_settings">Εμφάνιση ενημερώσεων</string>
|
||||
<string name="updates_settings_des">Αυτόματη αναζήτηση νέων ενημερώσεων</string>
|
||||
<string name="uprereleases_settings">Ενημέρωση σε προ-εκδόσεις</string>
|
||||
<string name="uprereleases_settings_des">Αναζητήστε ενημερώσεις προ-εκδόσεων αντί για κανονικές εκδόσεις</string>
|
||||
<string name="uprereleases_settings">Ενημέρωση σε προ-εκδόσεις (beta)</string>
|
||||
<string name="uprereleases_settings_des">Αναζητήστε ενημερώσεις προ-εκδόσεων (beta) αντί για σταθερές εκδόσεις</string>
|
||||
<string name="github">Github</string>
|
||||
<string name="lightnovel">Light novel app by the same devs</string>
|
||||
<string name="anim">Anime app by the same devs</string>
|
||||
<string name="discord">Join Discord</string>
|
||||
<string name="benene">Δώσε benene στους devs</string>
|
||||
<string name="benene_des">Βenene δώθηκε</string>
|
||||
<string name="lightnovel">Ελαφριά novel εφαρμογή από τους ίδιους προγραμματιστές</string>
|
||||
<string name="anim">Anime εφαρμογή από τους ίδιους προγραμματιστές</string>
|
||||
<string name="discord">Εγγραφείτε στο Discord</string>
|
||||
<string name="benene">Δώστε μπανάνα στους προγραμματιστές</string>
|
||||
<string name="benene_des">Μπανάνα δόθηκε δώθηκε</string>
|
||||
|
||||
<string name="player_speed_text_format" formatted="true">Ταχύτητα (%.2fx)</string>
|
||||
<string name="rated_format" formatted="true">Βαθμολογία: %.1f</string>
|
||||
<string name="new_update_format" formatted="true">Νέα ενημέρωση διαθέσιμη!\n%s -> %s</string>
|
||||
|
||||
<string name="double_tap_to_pause_settings_des">Πάτημα στη μέση για παύση</string>
|
||||
<string name="use_system_brightness_settings">Χρήση φωτεινότητας συστήματος</string>
|
||||
<string name="use_system_brightness_settings_des">Χρήση φωτεινότητας συστήματος στο ενσωματωμένο πρόγραμμα αναπαραγωγής αντί να εφαρμοστεί το προεπιλεγμένο σκούρο επικάλυμμα
|
||||
</string>
|
||||
|
||||
<string name="episode_sync_settings">Ενημέρωση προόδου παρακολούθησης</string>
|
||||
<string name="episode_sync_settings_des">Αυτόματος συγχρονισμός της προόδου του τρέχοντος επεισοδίου</string>
|
||||
|
||||
<string name="restore_settings">Επαναφορά δεδομένων από αντίγραφο ασφαλείας</string>
|
||||
|
||||
<string name="backup_settings">Αντίγραφα ασφαλείας</string>
|
||||
<string name="restore_success">Τα αντίγραφα ασφαλείας φορτώθηκαν</string>
|
||||
<string name="restore_failed_format" formatted="true">Η επαναφορά αντιγράφων ασφαλαείας απέτυχε από το αρχείο %s</string>
|
||||
<string name="backup_success">Επιτυχής αποθήκευση δεδομένων</string>
|
||||
<string name="backup_failed">Δεν έχει δοθεί άδεια για πρόσβαση στον αποθηκευτικό χώρο, προσπαθήστε ξανά</string>
|
||||
<string name="backup_failed_error_format">Σφάλμα δημιουργίας αντιγράφων ασφαλείας %s</string>
|
||||
|
||||
<string name="category_account">Λογαριασμοί</string>
|
||||
<string name="category_updates">Ενημερώσεις και αντίγραφα ασφαλείας</string>
|
||||
|
||||
<string name="show_fillers_settings">Εμφάνιση filler επεισοδίου για anime</string>
|
||||
<string name="show_trailers_settings">Εμφάνιση trailers</string>
|
||||
<string name="kitsu_settings">Εμφάνιση posters από kitsu</string>
|
||||
<string name="pref_filter_search_quality">Απόκρυψη επιλεγμένης ποιότητας βίντεο στα αποτελέσματα αναζήτησης</string>
|
||||
|
||||
<string name="app_language">App Language</string>
|
||||
|
||||
<string name="no_chromecast_support_toast">Αυτός ο πάροχος δεν έχει υποστήριξη Chromecast</string>
|
||||
<string name="no_links_found_toast">Δεν βρέθηκαν διαθέσιμοι σύνδεσμοι</string>
|
||||
<string name="copy_link_toast">Ο σύνδεσμος αντιγράφηκε στο πρόχειρο</string>
|
||||
|
||||
<string name="season">Season</string>
|
||||
<string name="season_format">%s %d%s</string>
|
||||
<string name="no_season">No Season</string>
|
||||
<string name="episode">Episode</string>
|
||||
<string name="episodes">Episodes</string>
|
||||
<string name="episodes_range">%d-%d</string>
|
||||
<string name="episode_format" formatted="true">%d %s</string>
|
||||
<string name="season_short">S</string>
|
||||
<string name="episode_short">E</string>
|
||||
<string name="no_episodes_found">No Episodes found</string>
|
||||
|
||||
<string name="delete_file">Διαγραφή αρχείου</string>
|
||||
<string name="delete">Διαγραφή</string>
|
||||
<string name="pause">Πάυση</string>
|
||||
<string name="resume">Συνέχιση</string>
|
||||
<string name="delete_message" formatted="true">Αυτό θα διαγράψει μόνιμα το %s\nΕπιβεβαίωση;</string>
|
||||
<string name="resume_time_left" formatted="true">%dm\nαπομένουν</string>
|
||||
|
||||
<string name="status_ongoing">Σε εξέλιξη</string>
|
||||
<string name="status">Κατάσταση</string>
|
||||
<string name="year">Έτος</string>
|
||||
<string name="duration">Διάρκεια</string>
|
||||
<string name="site">Ιστότοπος</string>
|
||||
<string name="synopsis">Περίληψη</string>
|
||||
|
||||
<string name="queued">προστέθηκε στην ουρά</string>
|
||||
<string name="no_subtitles">Δεν υπάρχουν διαθέσιμοι υπότιτλοι</string>
|
||||
<string name="default_subtitles">Προεπιλεγμένοι υπότιτλοι</string>
|
||||
|
||||
<string name="free_storage">Ελέυθερος</string>
|
||||
<string name="used_storage">Σε χρήση</string>
|
||||
<string name="app_storage">Εφαρμογή</string>
|
||||
|
||||
<string name="movies">Ταινίες</string>
|
||||
<string name="tv_series">Τηλεοπτικές Σειρές</string>
|
||||
<string name="cartoons">Κινούμενα σχέδια</string>
|
||||
<string name="torrent">Torrents</string>
|
||||
<string name="documentaries">Ντοκιμαντέρ</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">Cartoon</string>
|
||||
<string name="documentaries_singular">Ντοκιμαντέρ</string>
|
||||
<string name="asian_drama_singular">Ασιατικό Δράμα</string>
|
||||
<string name="live_singular">Ζωντανή ροή</string>
|
||||
<string name="other_singular">Άλλο</string>
|
||||
|
||||
<string name="source_error">Σφάλμα πηγής</string>
|
||||
<string name="remote_error">Απομακρυσμένο σφάλμα</string>
|
||||
<string name="render_error">Σφάλμα απόδοσης</string>
|
||||
<string name="unexpected_error">Μη αναμενόμενο σφάλμα αναπαραγωγής</string>
|
||||
<string name="storage_error">Σφάλμα λήψης, επιβεβαιώστε ότι η άδεια αποθήκευσης είναι ενεργοποιημένη</string>
|
||||
|
||||
<string name="episode_action_chromecast_episode">Chromecast επεισόδο</string>
|
||||
<string name="episode_action_play_in_app">Αναπαραγωγή εντός της εφαρμογής</string>
|
||||
<string name="episode_action_play_in_format">Αναπαραγωγή σε %s</string>
|
||||
<string name="episode_action_play_in_browser">Αναπαραγωγή στον περιηγητή</string>
|
||||
<string name="episode_action_copy_link">Αντιγραφή συνδέσμου</string>
|
||||
<string name="episode_action_auto_download">Αυτόματη λήψη</string>
|
||||
<string name="episode_action_download_mirror">Λήψη mirror</string>
|
||||
<string name="episode_action_reload_links">Επαναφόρτωση συνδέσμων</string>
|
||||
<string name="episode_action_download_subtitle">Λήψη υποτίτλων</string>
|
||||
|
||||
<string name="show_hd">Ποιότητα</string>
|
||||
<string name="show_dub">Dub</string>
|
||||
<string name="show_sub">Sub</string>
|
||||
<string name="show_title">Τίτλος</string>
|
||||
<string name="poster_ui_settings">Εναλλαγή των στοιχείων UI στο poster</string>
|
||||
|
||||
<string name="video_lock">Κλείδωμα</string>
|
||||
<string name="video_aspect_ratio_resize">Αλλαγή μεγέθους</string>
|
||||
<string name="video_source">Πηγή</string>
|
||||
<string name="video_skip_op">Παράλειψη 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="video_buffer_size_settings">Μέγεθος buffer βίντεο</string>
|
||||
<string name="video_buffer_length_settings">Μήκος buffer βίντεο</string>
|
||||
<string name="video_buffer_disk_settings">Προσωρινή μνήμη βίντεο στο δίσκο</string>
|
||||
<string name="video_buffer_clear_settings">Εκκαθάριση προσωρινής μνήμης βίντεο και εικόνων</string>
|
||||
|
||||
<string name="video_ram_description">Θα προκαλέσει τυχαία σφάλματα εάν οριστεί πολύ ψηλά. Μην το αλλάξετε εάν έχετε χαμηλή ποσότητα μνήμης ram, όπως σε Android TV ή παλιό τηλέφωνο</string>
|
||||
<string name="video_disk_description">Μπορεί να προκαλέσει προβλήματα σε συστήματα με χαμηλό αποθηκευτικό χώρο, όπως σε συσκευές Android TV, εάν τον ρυθμίσετε πολύ ψηλά</string>
|
||||
|
||||
<string name="dns_pref_summary">Χρήσιμο για παράκαμψη μπλοκ ISP</string>
|
||||
|
||||
<string name="add_site_pref">Αντίγραφο ιστοτόπου</string>
|
||||
<string name="remove_site_pref">Αφαίρεση ιστοτόπου</string>
|
||||
<string name="add_site_summary">Προσθήκη αντιγράφου ενός υπάρχοντος ιστοτόπου, με έναν διαφορετικό σύνδεσμο</string>
|
||||
|
||||
<string name="download_path_pref">Διαδρομή λήψης</string>
|
||||
|
||||
<string name="display_subbed_dubbed_settings">Εμφάνιση Dubbed/Subbed Anime</string>
|
||||
|
||||
<string name="resize_fit">Προσαρμογή στην οθόνη</string>
|
||||
<string name="resize_fill">Τέντωμα</string>
|
||||
<string name="resize_zoom">Μεγέθυνση</string>
|
||||
|
||||
<string name="legal_notice">Αποποίηση ευθυνών</string>
|
||||
|
||||
<string name="category_general">Γενικά</string>
|
||||
<string name="random_button_settings">Τυχαίο κουμπί</string>
|
||||
<string name="random_button_settings_desc">Εμφάνιση τυχαίου κουμπιού στην Αρχική οθόνη</string>
|
||||
<string name="provider_lang_settings">Γλώσσες παρόχων</string>
|
||||
<string name="app_layout">Διάταξη εφαρμογής</string>
|
||||
<string name="preferred_media_settings">Προτιμώμενα μέσα</string>
|
||||
<string name="enable_nsfw_on_providers">Ενεργοποίηση NSFW σε υποστηριζόμενους παρόχους</string>
|
||||
<string name="subtitles_encoding">Κωδικοποίηση υποτίτλων</string>
|
||||
<string name="category_providers">Πάροχοι</string>
|
||||
<string name="category_ui">Διάταξη</string>
|
||||
|
||||
<string name="automatic">Αυτόματο</string>
|
||||
<string name="tv_layout">Διάταξη TV</string>
|
||||
<string name="phone_layout">Διάταξη τηλεφώνου</string>
|
||||
<string name="emulator_layout">Διάταξη emulator</string>
|
||||
|
||||
<string name="primary_color_settings">Πρωτεύον χρώμα</string>
|
||||
<string name="app_theme_settings">Θέμα εφαρμογής</string>
|
||||
<string name="bottom_title_settings">Τοποθεσία τίτλου Poster</string>
|
||||
<string name="bottom_title_settings_des">Τοποθετήστε τον τίτλο κάτω από το poster</string>
|
||||
|
||||
<string name="example_lang_name">Κωδικός γλώσσας (el)</string>
|
||||
|
||||
<string name="account">Λογαριασμός</string>
|
||||
<string name="logout">Αποσύνδεση</string>
|
||||
<string name="login">Σύνδεση</string>
|
||||
<string name="switch_account">Εναλλαγή λογαριασμού</string>
|
||||
<string name="add_account">Προσθήκη λογαριασμού</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="authenticated_user" formatted="true">Πιστοποιήθηκε %s</string>
|
||||
<string name="authenticated_user_fail" formatted="true">Αποτυχία πιστοποίησης σε %s</string>
|
||||
|
||||
<string name="none">Τίποτα</string>
|
||||
<string name="normal">Κανονικά</string>
|
||||
<string name="all">Όλα</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">Συγχρονισμός υποτίτλων</string>
|
||||
<string name="subtitle_offset_hint">1000ms</string>
|
||||
<string name="subtitle_offset_title">Καθυστέρηση υποτίτλων</string>
|
||||
<string name="subtitle_offset_extra_hint_later_format">Χρησιμοποιήστε αυτό αν οι υπότιτλοι εμφανίζονται %dms πολύ νωρίς</string>
|
||||
<string name="subtitle_offset_extra_hint_before_format">Χρησιμοποιήστε αυτό αν οι υπότιτλοι εμφανίζονται %dms πολύ αργά</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="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="home_random">Τυχαίο</string>
|
||||
|
||||
<string name="coming_soon">Έρχεται σύντομα…</string>
|
||||
|
||||
|
||||
<string name="poster_image">Εικόνα Poster</string>
|
||||
<string name="category_player">Πρόγραμμα αναπαραγωγής</string>
|
||||
<string name="resolution_and_title">Ανάλυση και τίτλος</string>
|
||||
<string name="title">Τίτλος</string>
|
||||
<string name="resolution">Ανάλυση</string>
|
||||
<string name="error_invalid_id">Μη έγκυρο id</string>
|
||||
<string name="error_invalid_data">Μη έγκυρα δεδομένα</string>
|
||||
<string name="error_invalid_url">Μη έγκυρος σύνδεσμος</string>
|
||||
<string name="error">Σφάλμα</string>
|
||||
<string name="subtitles_remove_captions">Αφαίρεση closed captions (για άτομα με προβλήματα ακοής) από τους υπότιτλους</string>
|
||||
<string name="subtitles_remove_bloat">Αφαίρεση bloat από τους υπότιτλους</string>
|
||||
<string name="subtitles_filter_lang">Φιλτράρισμα ανά την προτεινόμενη γλώσσα του μέσου</string>
|
||||
<string name="extras">Έξτρα</string>
|
||||
<string name="trailer">Τρέιλερ</string>
|
||||
<string name="network_adress_example">Σύνδεσμος για stream</string>
|
||||
<string name="referer">Παραπομπή</string>
|
||||
<string name="next">Επόμενο</string>
|
||||
<string name="provider_languages_tip">Παρακολούθηση βίντεο σε αυτή την γλώσσα</string>
|
||||
<string name="previous">Προηγούμενο</string>
|
||||
<string name="skip_setup">Παράλειψη διαμόρφωσης</string>
|
||||
<string name="app_layout_subtext">Αλλαγή της εμφάνισης της συσκευής για να ταιριάζει με την συσκευή σας</string>
|
||||
<string name="crash_reporting_title">Αναφορά κατάρρευσης</string>
|
||||
<string name="preferred_media_subtext">Τι θα θέλατε να δείτε</string>
|
||||
<string name="setup_done">Έγινε</string>
|
||||
<string name="extensions">Πρόσθετα</string>
|
||||
<string name="add_repository">Προσθήκη αποθετηρίου</string>
|
||||
<string name="repository_name_hint">Όνομα αποθετηρίου</string>
|
||||
<string name="repository_url_hint">Σύνδεσμος αποθετηρίου</string>
|
||||
<string name="plugin_loaded">Το πρόσθετο φορτώθηκε</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="batch_download_nothing_to_download_format" formatted="true">Όλα τα %s έχουν ήδη κατέβει</string>
|
||||
<string name="batch_download">Μαζική λήψη</string>
|
||||
<string name="plugin_singular">Πρόσθετο</string>
|
||||
<string name="plugin">Πρόσθετα</string>
|
||||
<string name="delete_repository_plugins">Αυτό θα διαγράψει όλα τα πρόσθετα του αποθετηρίου</string>
|
||||
<string name="delete_repository">Διαγραφή αποθετηρίου</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="plugins_updated" formatted="true">Ενημερώθηκαν %d πρόσθετα</string>
|
||||
<string name="blank_repo_message">Προσθήκη ενός αποθετηρίου για να εγκαταστήσετε πρόσθετα ιστοσελίδας</string>
|
||||
<string name="view_public_repositories_button">Προβολή αποθετηρίων κοινότητας</string>
|
||||
<string name="view_public_repositories_button_short">Δημόσια λίστα</string>
|
||||
<string name="uppercase_all_subtitles">Κεφαλοποίηση υποτίτλων</string>
|
||||
|
||||
<string name="download_all_plugins_from_repo">Λήψη όλων των προσθέτων από αυτό το αποθετήριο;</string>
|
||||
<string name="single_plugin_disabled" formatted="true">%s (Απενεργοποιήθηκε)</string>
|
||||
<string name="tracks">Κομμάτια</string>
|
||||
<string name="audio_tracks">Ηχητικά κομμάτια</string>
|
||||
<string name="video_tracks">Κομμάτια βίντεο</string>
|
||||
<string name="apply_on_restart">Εφαρμογή στην επανεκκίνηση</string>
|
||||
|
||||
<string name="safe_mode_title">Η ασφαλής λειτουργία ενεργοποιήθηκε</string>
|
||||
<string name="safe_mode_description">Ένα μη αντιστρέψιμο σφάλμα συνέβη και απενεργοποιήσαμε όλα τα πρόσθετα, ώστε να μπορέσετε να διαπιστώσετε ποιο πρόσθετο προκάλεσε αυτή τη κατάρρευση.</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_authors">Συγγραφείς</string>
|
||||
<string name="extension_types">Υποστηρίζονται</string>
|
||||
<string name="extension_language">Γλώσσα</string>
|
||||
<string name="extension_install_first">Εγκατάσταση προσθέτου πρώτα</string>
|
||||
|
||||
<string name="hls_playlist">HLS Playlist</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="player_settings_play_in_mpv">MPV</string>
|
||||
<string name="player_settings_play_in_web">Web Video Cast</string>
|
||||
<string name="player_settings_play_in_browser">Περιηγητής</string>
|
||||
<string name="app_not_found_error">Η εφαρμογή δεν βρέθηκε</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -602,7 +602,7 @@
|
|||
<string name="plugins_disabled" formatted="true">Disabled: %d</string>
|
||||
<string name="plugins_not_downloaded" formatted="true">Not downloaded: %d</string>
|
||||
<string name="plugins_updated" formatted="true">Updated %d plugins</string>
|
||||
<string name="blank_repo_message">Add a repository to install site extensions</string>
|
||||
<string name="blank_repo_message">CloudStream has no sites installed by default. You need to install the sites from repositories.\n\nBecause of a brainless DMCA takedown by Sky Uk Limited 🤮 we cannot link the repository sites in app.\n\nJoin our discord for links or search online.</string>
|
||||
<string name="view_public_repositories_button">View community repositories</string>
|
||||
<string name="view_public_repositories_button_short">Public list</string>
|
||||
<string name="uppercase_all_subtitles">Uppercase all subtitles</string>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<Preference
|
||||
app:isPreferenceVisible="false"
|
||||
android:icon="@drawable/ic_baseline_language_24"
|
||||
android:key="@string/provider_lang_key"
|
||||
android:title="@string/provider_lang_settings" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue