diff --git a/.github/workflows/build_to_archive.yml b/.github/workflows/build_to_archive.yml new file mode 100644 index 00000000..83430766 --- /dev/null +++ b/.github/workflows/build_to_archive.yml @@ -0,0 +1,76 @@ +name: Archive build + +on: + push: + branches: [ master ] + paths-ignore: + - '*.md' + - '*.json' + - '**/wcokey.txt' + workflow_dispatch: + +concurrency: + group: "Archive-build" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Generate access token + id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_KEY }} + repository: "recloudstream/secrets" + - name: Generate access token (archive) + id: generate_archive_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_KEY }} + repository: "recloudstream/cloudstream-archive" + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Fetch keystore + id: fetch_keystore + run: | + TMP_KEYSTORE_FILE_PATH="${RUNNER_TEMP}"/keystore + mkdir -p "${TMP_KEYSTORE_FILE_PATH}" + curl -H "Authorization: token ${{ steps.generate_token.outputs.token }}" -o "${TMP_KEYSTORE_FILE_PATH}/prerelease_keystore.keystore" "https://raw.githubusercontent.com/recloudstream/secrets/master/keystore.jks" + curl -H "Authorization: token ${{ steps.generate_token.outputs.token }}" -o "keystore_password.txt" "https://raw.githubusercontent.com/recloudstream/secrets/master/keystore_password.txt" + KEY_PWD="$(cat keystore_password.txt)" + echo "::add-mask::${KEY_PWD}" + echo "key_pwd=$KEY_PWD" >> $GITHUB_OUTPUT + - name: Run Gradle + run: | + ./gradlew assemblePrerelease + env: + SIGNING_KEY_ALIAS: "key0" + SIGNING_KEY_PASSWORD: ${{ steps.fetch_keystore.outputs.key_pwd }} + SIGNING_STORE_PASSWORD: ${{ steps.fetch_keystore.outputs.key_pwd }} + - uses: actions/checkout@v3 + with: + repository: "recloudstream/cloudstream-archive" + token: ${{ steps.generate_archive_token.outputs.token }} + path: "archive" + + - name: Move build + run: | + cp app/build/outputs/apk/prerelease/release/*.apk "archive/$(git rev-parse --short HEAD).apk" + + - name: Push archive + run: | + cd $GITHUB_WORKSPACE/archive + git config --local user.email "actions@github.com" + git config --local user.name "GitHub Actions" + git add . + git commit --amend -m "Build $GITHUB_SHA" || exit 0 # do not error if nothing to commit + git push --force \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index da257d69..190c0cf5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -18,7 +18,6 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSet import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.Coroutines.threadSafeListOf import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.SubtitleHelper import okhttp3.Interceptor import java.text.SimpleDateFormat import java.util.* @@ -31,6 +30,12 @@ const val USER_AGENT = val mapper = JsonMapper.builder().addModule(KotlinModule()) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! +/** + * Defines the constant for the all languages preference, if this is set then it is + * the equivalent of all languages being set + **/ +const val AllLanguagesName = "universal" + object APIHolder { val unixTime: Long get() = System.currentTimeMillis() / 1000L @@ -159,7 +164,8 @@ object APIHolder { val hashSet = HashSet() val activeLangs = getApiProviderLangSettings() - hashSet.addAll(apis.filter { activeLangs.contains(it.lang) }.map { it.name }) + val hasUniversal = activeLangs.contains(AllLanguagesName) + hashSet.addAll(apis.filter { hasUniversal || activeLangs.contains(it.lang) }.map { it.name }) /*val set = settingsManager.getStringSet( this.getString(R.string.search_providers_list_key), @@ -193,26 +199,17 @@ 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 { - val langs = apis.map { it.lang }.toSet() - .sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } - return langs.toHashSet() - -// val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) -// val hashSet = HashSet() + val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) + val hashSet = hashSetOf(AllLanguagesName) // def is all languages // 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() + val list = settingsManager.getStringSet( + this.getString(R.string.provider_lang_key), + hashSet + ) + + if (list.isNullOrEmpty()) return hashSet + return list.toHashSet() } fun Context.getApiTypeSettings(): HashSet { @@ -254,7 +251,8 @@ object APIHolder { null } ?: default val langs = this.getApiProviderLangSettings() - val allApis = apis.filter { langs.contains(it.lang) } + val hasUniversal = langs.contains(AllLanguagesName) + val allApis = apis.filter { hasUniversal || langs.contains(it.lang) } .filter { api -> api.hasMainPage || !hasHomePageIsRequired } return if (currentPrefMedia.isEmpty()) { allApis diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Jeniusplay.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Jeniusplay.kt new file mode 100644 index 00000000..11b66d99 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Jeniusplay.kt @@ -0,0 +1,72 @@ +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 + +open class Jeniusplay : ExtractorApi() { + override val name = "Jeniusplay" + override val mainUrl = "https://jeniusplay.com" + override val requiresReferer = true + + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val document = app.get(url, referer = "$mainUrl/").document + val hash = url.split("/").last().substringAfter("data=") + + val m3uLink = app.post( + url = "$mainUrl/player/index.php?data=$hash&do=getVideo", + data = mapOf("hash" to hash, "r" to "$referer"), + referer = url, + headers = mapOf("X-Requested-With" to "XMLHttpRequest") + ).parsed().videoSource + + M3u8Helper.generateM3u8( + this.name, + m3uLink, + url, + ).forEach(callback) + + + document.select("script").map { script -> + if (script.data().contains("eval(function(p,a,c,k,e,d)")) { + val subData = + getAndUnpack(script.data()).substringAfter("\"tracks\":[").substringBefore("],") + tryParseJson>("[$subData]")?.map { subtitle -> + subtitleCallback.invoke( + SubtitleFile( + getLanguage(subtitle.label ?: ""), + subtitle.file + ) + ) + } + } + } + } + + private fun getLanguage(str: String): String { + return when { + str.contains("indonesia", true) || str + .contains("bahasa", true) -> "Indonesian" + else -> str + } + } + + data class ResponseSource( + @JsonProperty("hls") val hls: Boolean, + @JsonProperty("videoSource") val videoSource: String, + @JsonProperty("securedLink") val securedLink: String?, + ) + + data class Tracks( + @JsonProperty("kind") val kind: String?, + @JsonProperty("file") val file: String, + @JsonProperty("label") val label: String?, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Moviehab.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Moviehab.kt index e2eb7bf0..aaa33ca1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Moviehab.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Moviehab.kt @@ -6,7 +6,11 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper -class Moviehab : ExtractorApi() { +class MoviehabNet : Moviehab() { + override var mainUrl = "https://play.moviehab.net" +} + +open class Moviehab : ExtractorApi() { override var name = "Moviehab" override var mainUrl = "https://play.moviehab.com" override val requiresReferer = false diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt index 2564abd0..0f23782d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -70,6 +70,28 @@ object RepositoryManager { getKey("PREBUILT_REPOSITORIES") ?: emptyArray() } + suspend fun parseRepoUrl(url: String): String? { + val fixedUrl = url.trim() + return if (fixedUrl.contains("^https?://".toRegex())) { + fixedUrl + } else if (fixedUrl.contains("^(cloudstreamrepo://)|(https://cs\\.repo/\\??)".toRegex())) { + fixedUrl.replace("^(cloudstreamrepo://)|(https://cs\\.repo/\\??)".toRegex(), "").let { + return@let if (!it.contains("^https?://".toRegex())) + "https://${it}" + else fixedUrl + } + } else if (fixedUrl.matches("^[a-zA-Z0-9!_-]+$".toRegex())) { + suspendSafeApiCall { + app.get("https://l.cloudstream.cf/${fixedUrl}").let { + return@let if (it.isSuccessful && !it.url.startsWith("https://cutt.ly/branded-domains")) it.url + else app.get("https://cutt.ly/${fixedUrl}").let let2@{ it2 -> + return@let2 if (it2.isSuccessful) it2.url else null + } + } + } + } else null + } + suspend fun parseRepository(url: String): Repository? { return suspendSafeApiCall { // Take manifestVersion and such into account later @@ -191,4 +213,4 @@ object RepositoryManager { output.write(dataBuffer, 0, readBytes) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index 9792fa43..a2dd469c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.ui.home +import android.animation.LayoutTransition import android.annotation.SuppressLint import android.app.Activity import android.content.Context @@ -23,12 +24,15 @@ import androidx.fragment.app.activityViewModels import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.transition.ChangeBounds +import androidx.transition.TransitionManager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.button.MaterialButton import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.APIHolder.allProviders import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.filterProviderByPreferredMedia import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull @@ -346,7 +350,9 @@ class HomeFragment : Fragment() { builder.setContentView(R.layout.home_select_mainpage) builder.show() builder.let { dialog -> - val isMultiLang = getApiProviderLangSettings().size > 1 + val isMultiLang = getApiProviderLangSettings().let { set -> + set.size > 1 || set.contains(AllLanguagesName) + } //dialog.window?.setGravity(Gravity.BOTTOM) var currentApiName = selectedApiName @@ -549,7 +555,7 @@ class HomeFragment : Fragment() { home_preview?.isVisible = true (home_preview_viewpager?.adapter as? HomeScrollAdapter)?.apply { setItems(preview.value) - // home_preview_viewpager?.setCurrentItem(1000, false) + // home_preview_viewpager?.setCurrentItem(1000, false) } //.also { @@ -574,10 +580,15 @@ class HomeFragment : Fragment() { setPageTransformer(false, HomeScrollTransformer()) adapter = HomeScrollAdapter { load -> load.apply { + home_preview_title_holder?.let { parent -> + TransitionManager.beginDelayedTransition(parent, ChangeBounds()) + } + home_preview_tags?.text = tags?.joinToString(" • ") ?: "" home_preview_tags?.isGone = tags.isNullOrEmpty() home_preview_image?.setImage(posterUrl, posterHeaders) home_preview_title?.text = name + home_preview_play?.setOnClickListener { activity?.loadResult(url, apiName, START_ACTION_RESUME_LATEST) //activity.loadSearchResult(url, START_ACTION_RESUME_LATEST) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt index a4b2be8f..bcb36f7e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt @@ -221,7 +221,9 @@ class SearchFragment : Fragment() { builder.setContentView(R.layout.home_select_mainpage) builder.show() builder.let { dialog -> - val isMultiLang = ctx.getApiProviderLangSettings().size > 1 + val isMultiLang = ctx.getApiProviderLangSettings().let { set -> + set.size > 1 || set.contains(AllLanguagesName) + } val cancelBtt = dialog.findViewById(R.id.cancel_btt) val applyBtt = dialog.findViewById(R.id.apply_btt) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsProviders.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsProviders.kt index 7bba9d88..4371fc39 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsProviders.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsProviders.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.ui.settings -import android.content.Context import android.os.Bundle import android.view.View import androidx.preference.PreferenceFragmentCompat @@ -9,17 +8,15 @@ import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey -import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setPaddingBottom import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar import com.lagradost.cloudstream3.utils.USER_SELECTED_HOMEPAGE_API -import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog import com.lagradost.cloudstream3.utils.SubtitleHelper import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard - +import kotlin.reflect.jvm.internal.impl.descriptors.deserialization.PlatformDependentDeclarationFilter.All class SettingsProviders : PreferenceFragmentCompat() { @@ -63,13 +60,17 @@ class SettingsProviders : PreferenceFragmentCompat() { getPref(R.string.prefer_media_type_key)?.setOnPreferenceClickListener { val names = enumValues().sorted().map { it.name } - val default = enumValues().sorted().filter { it != TvType.NSFW }.map { it.ordinal } + val default = + enumValues().sorted().filter { it != TvType.NSFW }.map { it.ordinal } val defaultSet = default.map { it.toString() }.toSet() val currentList = try { - settingsManager.getStringSet(getString(R.string.prefer_media_type_key), defaultSet)?.map { - it.toInt() - } - } catch (e: Throwable) { null } ?: default + settingsManager.getStringSet(getString(R.string.prefer_media_type_key), defaultSet) + ?.map { + it.toInt() + } + } catch (e: Throwable) { + null + } ?: default activity?.showMultiDialog( names, @@ -89,19 +90,22 @@ class SettingsProviders : PreferenceFragmentCompat() { getPref(R.string.provider_lang_key)?.setOnPreferenceClickListener { activity?.getApiProviderLangSettings()?.let { current -> - val langs = APIHolder.apis.map { it.lang }.toSet() - .sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } + val languages = APIHolder.apis.map { it.lang }.toSet() + .sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } + AllLanguagesName - val currentList = ArrayList() - for (i in current) { - currentList.add(langs.indexOf(i)) + val currentList = current.map { + languages.indexOf(it) } - val names = langs.map { - val emoji = SubtitleHelper.getFlagFromIso(it) - val name = SubtitleHelper.fromTwoLettersToLanguage(it) - val fullName = "$emoji $name" - Pair(it, fullName) + val names = languages.map { + if (it == AllLanguagesName) { + Pair(it, getString(R.string.all_languages_preference)) + } else { + val emoji = SubtitleHelper.getFlagFromIso(it) + val name = SubtitleHelper.fromTwoLettersToLanguage(it) + val fullName = "$emoji $name" + Pair(it, fullName) + } } activity?.showMultiDialog( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt index 418519e2..49f40879 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt @@ -33,8 +33,6 @@ import com.lagradost.cloudstream3.widget.LinearRecycleViewLayoutManager import kotlinx.android.synthetic.main.add_repo_input.* import kotlinx.android.synthetic.main.fragment_extensions.* -const val PUBLIC_REPOSITORIES_LIST = "https://recloudstream.github.io/repos/" - class ExtensionsFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, @@ -186,15 +184,7 @@ class ExtensionsFragment : Fragment() { (activity?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager?)?.primaryClip?.getItemAt( 0 )?.text?.toString()?.let { copy -> - // Fix our own repo links and only paste the text if it's a link. - if (copy.startsWith("http")) { - val fixedUrl = if (copy.startsWith("https://cs.repo")) { - "https://" + copy.substringAfter("?") - } else { - copy - } - dialog.repo_url_input?.setText(fixedUrl) - } + dialog.repo_url_input?.setText(copy) } // dialog.list_repositories?.setOnClickListener { @@ -206,21 +196,21 @@ class ExtensionsFragment : Fragment() { // dialog.text2?.text = provider.name dialog.apply_btt?.setOnClickListener secondListener@{ val name = dialog.repo_name_input?.text?.toString() - val url = dialog.repo_url_input?.text?.toString() - if (url.isNullOrBlank()) { - showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT) - return@secondListener - } - ioSafe { - val fixedName = if (!name.isNullOrBlank()) name - else RepositoryManager.parseRepository(url)?.name ?: "No name" + val url = dialog.repo_url_input?.text?.toString() + ?.let { it1 -> RepositoryManager.parseRepoUrl(it1) } + if (url.isNullOrBlank()) { + showToast(activity, R.string.error_invalid_data, Toast.LENGTH_SHORT) + } else { + val fixedName = if (!name.isNullOrBlank()) name + else RepositoryManager.parseRepository(url)?.name ?: "No name" - val newRepo = RepositoryData(fixedName, url) - RepositoryManager.addRepository(newRepo) - extensionViewModel.loadStats() - extensionViewModel.loadRepositories() - this@ExtensionsFragment.activity?.downloadAllPluginsDialog(url, fixedName) + val newRepo = RepositoryData(fixedName, url) + RepositoryManager.addRepository(newRepo) + extensionViewModel.loadStats() + extensionViewModel.loadRepositories() + this@ExtensionsFragment.activity?.downloadAllPluginsDialog(url, fixedName) + } } dialog.dismissSafe(activity) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentExtensions.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentExtensions.kt index c4bf7580..b7d2fff6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentExtensions.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentExtensions.kt @@ -7,6 +7,9 @@ import android.view.ViewGroup import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController +import com.lagradost.cloudstream3.APIHolder.apis +import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings +import com.lagradost.cloudstream3.AllLanguagesName import com.lagradost.cloudstream3.MainActivity.Companion.afterRepositoryLoadedEvent import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.plugins.RepositoryManager @@ -96,7 +99,14 @@ class SetupFragmentExtensions : Fragment() { next_btt?.setOnClickListener { // Continue setup if (isSetup) - findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_media) + if ( + // If any available languages + apis.distinctBy { it.lang }.size > 1 + ) { + findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_provider_languages) + } else { + findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_media) + } else findNavController().navigate(R.id.navigation_home) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentLanguage.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentLanguage.kt index f9268d77..80db59ee 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentLanguage.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentLanguage.kt @@ -15,7 +15,6 @@ import com.lagradost.cloudstream3.CommonActivity import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.normalSafeApiCall import com.lagradost.cloudstream3.plugins.PluginManager -import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES import com.lagradost.cloudstream3.ui.settings.appLanguages import com.lagradost.cloudstream3.ui.settings.getCurrentLocale import com.lagradost.cloudstream3.utils.SubtitleHelper @@ -85,7 +84,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_media + else R.id.action_navigation_setup_language_to_navigation_setup_provider_languages findNavController().navigate( nextDestination, diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentProviderLanguage.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentProviderLanguage.kt index 3e24cc4d..51abee90 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentProviderLanguage.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/setup/SetupFragmentProviderLanguage.kt @@ -12,6 +12,7 @@ import androidx.navigation.fragment.findNavController import androidx.preference.PreferenceManager import com.lagradost.cloudstream3.APIHolder import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings +import com.lagradost.cloudstream3.AllLanguagesName import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.utils.SubtitleHelper import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar @@ -39,14 +40,21 @@ class SetupFragmentProviderLanguage : Fragment() { val current = this.getApiProviderLangSettings() val langs = APIHolder.apis.map { it.lang }.toSet() - .sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } + .sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } + AllLanguagesName + + val currentList = + current.map { langs.indexOf(it) }.filter { it != -1 } // TODO LOOK INTO - val currentList = current.map { langs.indexOf(it) }.filter { it != -1 } // TODO LOOK INTO val languageNames = langs.map { - val emoji = SubtitleHelper.getFlagFromIso(it) - val name = SubtitleHelper.fromTwoLettersToLanguage(it) - "$emoji $name" + if (it == AllLanguagesName) { + getString(R.string.all_languages_preference) + } else { + val emoji = SubtitleHelper.getFlagFromIso(it) + val name = SubtitleHelper.fromTwoLettersToLanguage(it) + "$emoji $name" + } } + arrayAdapter.addAll(languageNames) listview1?.adapter = arrayAdapter diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index ca612385..1a1afb68 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -329,6 +329,8 @@ val extractorApis: MutableList = arrayListOf( Vidmolyme(), Voe(), Moviehab(), + MoviehabNet(), + Jeniusplay(), Gdriveplayerapi(), Gdriveplayerapp(), diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 3d7e3ba5..99fee606 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -363,19 +363,20 @@ --> --> - Web Video Cast Browser App not found + All Languages diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 70ac7516..f0bb2214 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -81,6 +81,7 @@ @color/transparent @color/chip_color_text @color/chip_color_text + @color/chip_color_text