mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Plugin setup screen and hopefully fix critical error
This commit is contained in:
parent
2c399e6916
commit
6e819e3b96
12 changed files with 333 additions and 128 deletions
|
@ -10,6 +10,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
import com.lagradost.cloudstream3.mvvm.debugWarning
|
||||||
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
|
||||||
|
@ -69,7 +70,11 @@ object APIHolder {
|
||||||
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
fun getApiFromNameNull(apiName: String?): MainAPI? {
|
||||||
if (apiName == null) return null
|
if (apiName == null) return null
|
||||||
initMap()
|
initMap()
|
||||||
return apiMap?.get(apiName)?.let { apis.getOrNull(it) }
|
// Fuck it load from allProviders since they're dynamically loaded
|
||||||
|
// This is required right now because apiMap might be outdated
|
||||||
|
// TODO FIX when we switch to LoadPlugin()
|
||||||
|
debugWarning { "FIX LoadPlugin! getApiFromNameNull sucks right now 💀" }
|
||||||
|
return apiMap?.get(apiName)?.let { apis.getOrNull(it) } ?: allProviders.firstOrNull { it.name == apiName }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApiFromUrlNull(url: String?): MainAPI? {
|
fun getApiFromUrlNull(url: String?): MainAPI? {
|
||||||
|
|
|
@ -670,6 +670,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
try {
|
try {
|
||||||
if (getKey(HAS_DONE_SETUP_KEY, false) != true) {
|
if (getKey(HAS_DONE_SETUP_KEY, false) != true) {
|
||||||
navController.navigate(R.id.navigation_setup_language)
|
navController.navigate(R.id.navigation_setup_language)
|
||||||
|
// If no plugins bring up extensions screen
|
||||||
|
} else if (PluginManager.getPluginsOnline().isEmpty()
|
||||||
|
&& PluginManager.getPluginsLocal().isEmpty()
|
||||||
|
) {
|
||||||
|
navController.navigate(R.id.navigation_setup_extensions)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
|
|
|
@ -18,6 +18,16 @@ import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comes with the app, always available in the app, non removable.
|
||||||
|
* */
|
||||||
|
val PREBUILT_REPOSITORIES = arrayOf(
|
||||||
|
// TODO FIX
|
||||||
|
RepositoryData(
|
||||||
|
"Testing repository",
|
||||||
|
"https://raw.githubusercontent.com/recloudstream/cs-repos/master/test.json"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
data class Repository(
|
data class Repository(
|
||||||
@JsonProperty("name") val name: String,
|
@JsonProperty("name") val name: String,
|
||||||
|
|
|
@ -42,7 +42,7 @@ class ExtensionsFragment : Fragment() {
|
||||||
|
|
||||||
setUpToolbar(R.string.extensions)
|
setUpToolbar(R.string.extensions)
|
||||||
|
|
||||||
repo_recycler_view?.adapter = RepoAdapter(emptyArray(), {
|
repo_recycler_view?.adapter = RepoAdapter(emptyArray(), false, {
|
||||||
findNavController().navigate(
|
findNavController().navigate(
|
||||||
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
||||||
Bundle().apply {
|
Bundle().apply {
|
||||||
|
|
|
@ -40,7 +40,7 @@ class PluginsFragment : Fragment() {
|
||||||
settings_toolbar?.setOnMenuItemClickListener { menuItem ->
|
settings_toolbar?.setOnMenuItemClickListener { menuItem ->
|
||||||
when (menuItem?.itemId) {
|
when (menuItem?.itemId) {
|
||||||
R.id.download_all -> {
|
R.id.download_all -> {
|
||||||
pluginViewModel.downloadAll(activity, url)
|
PluginsViewModel.downloadAll(activity, url, pluginViewModel)
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,75 +29,82 @@ class PluginsViewModel : ViewModel() {
|
||||||
companion object {
|
companion object {
|
||||||
private val repositoryCache: MutableMap<String, List<Plugin>> = mutableMapOf()
|
private val repositoryCache: MutableMap<String, List<Plugin>> = mutableMapOf()
|
||||||
const val TAG = "PLG"
|
const val TAG = "PLG"
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getPlugins(
|
private fun isDownloaded(plugin: Plugin, data: Set<String>? = null): Boolean {
|
||||||
repositoryUrl: String,
|
return (data ?: getDownloads()).contains(plugin.second.internalName)
|
||||||
canUseCache: Boolean = true
|
|
||||||
): List<Plugin> {
|
|
||||||
Log.i(TAG, "getPlugins = $repositoryUrl")
|
|
||||||
if (canUseCache && repositoryCache.containsKey(repositoryUrl)) {
|
|
||||||
repositoryCache[repositoryUrl]?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return RepositoryManager.getRepoPlugins(repositoryUrl)
|
|
||||||
?.also { repositoryCache[repositoryUrl] = it } ?: emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getStoredPlugins(): Array<PluginData> {
|
private suspend fun getPlugins(
|
||||||
return PluginManager.getPluginsOnline()
|
repositoryUrl: String,
|
||||||
}
|
canUseCache: Boolean = true
|
||||||
|
): List<Plugin> {
|
||||||
private fun getDownloads(): Set<String> {
|
Log.i(TAG, "getPlugins = $repositoryUrl")
|
||||||
return getStoredPlugins().map { it.internalName }.toSet()
|
if (canUseCache && repositoryCache.containsKey(repositoryUrl)) {
|
||||||
}
|
repositoryCache[repositoryUrl]?.let {
|
||||||
|
return it
|
||||||
private fun isDownloaded(plugin: Plugin, data: Set<String>? = null): Boolean {
|
}
|
||||||
return (data ?: getDownloads()).contains(plugin.second.internalName)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun downloadAll(activity: Activity?, repositoryUrl: String) = ioSafe {
|
|
||||||
if (activity == null) return@ioSafe
|
|
||||||
val stored = getDownloads()
|
|
||||||
val plugins = getPlugins(repositoryUrl)
|
|
||||||
|
|
||||||
plugins.filter { plugin -> !isDownloaded(plugin, stored) }.also { list ->
|
|
||||||
main {
|
|
||||||
showToast(
|
|
||||||
activity,
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
txt(
|
|
||||||
R.string.batch_download_nothing_to_download_format,
|
|
||||||
txt(R.string.plugin)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
txt(R.string.batch_download_start_format, list.size, txt(if(list.size == 1) R.string.plugin_singular else R.string.plugin))
|
|
||||||
},
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}.apmap { (repo, metadata) ->
|
return RepositoryManager.getRepoPlugins(repositoryUrl)
|
||||||
PluginManager.downloadAndLoadPlugin(
|
?.also { repositoryCache[repositoryUrl] = it } ?: emptyList()
|
||||||
activity,
|
}
|
||||||
metadata.url,
|
|
||||||
metadata.name,
|
private fun getStoredPlugins(): Array<PluginData> {
|
||||||
repo
|
return PluginManager.getPluginsOnline()
|
||||||
)
|
}
|
||||||
}.main { list ->
|
|
||||||
if (list.any { it }) {
|
private fun getDownloads(): Set<String> {
|
||||||
showToast(
|
return getStoredPlugins().map { it.internalName }.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param viewModel optional, updates the plugins livedata for that viewModel if included
|
||||||
|
* */
|
||||||
|
fun downloadAll(activity: Activity?, repositoryUrl: String, viewModel: PluginsViewModel?) = ioSafe {
|
||||||
|
if (activity == null) return@ioSafe
|
||||||
|
val stored = getDownloads()
|
||||||
|
val plugins = getPlugins(repositoryUrl)
|
||||||
|
|
||||||
|
plugins.filter { plugin -> !isDownloaded(plugin, stored) }.also { list ->
|
||||||
|
main {
|
||||||
|
showToast(
|
||||||
|
activity,
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
txt(
|
||||||
|
R.string.batch_download_nothing_to_download_format,
|
||||||
|
txt(R.string.plugin)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
txt(
|
||||||
|
R.string.batch_download_start_format,
|
||||||
|
list.size,
|
||||||
|
txt(if (list.size == 1) R.string.plugin_singular else R.string.plugin)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.apmap { (repo, metadata) ->
|
||||||
|
PluginManager.downloadAndLoadPlugin(
|
||||||
activity,
|
activity,
|
||||||
txt(
|
metadata.url,
|
||||||
R.string.batch_download_finish_format,
|
metadata.name,
|
||||||
list.count { it },
|
repo
|
||||||
txt(if(list.size == 1) R.string.plugin_singular else R.string.plugin)
|
|
||||||
),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
)
|
)
|
||||||
updatePluginListPrivate(repositoryUrl)
|
}.main { list ->
|
||||||
} else if (list.isNotEmpty()) {
|
if (list.any { it }) {
|
||||||
showToast(activity, R.string.download_failed, Toast.LENGTH_SHORT)
|
showToast(
|
||||||
|
activity,
|
||||||
|
txt(
|
||||||
|
R.string.batch_download_finish_format,
|
||||||
|
list.count { it },
|
||||||
|
txt(if (list.size == 1) R.string.plugin_singular else R.string.plugin)
|
||||||
|
),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
viewModel?.updatePluginListPrivate(repositoryUrl)
|
||||||
|
} else if (list.isNotEmpty()) {
|
||||||
|
showToast(activity, R.string.download_failed, Toast.LENGTH_SHORT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,16 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
||||||
import com.lagradost.cloudstream3.ui.settings.AccountClickCallback
|
import com.lagradost.cloudstream3.ui.settings.AccountClickCallback
|
||||||
import kotlinx.android.synthetic.main.repository_item.view.*
|
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||||
|
|
||||||
class RepoAdapter(
|
class RepoAdapter(
|
||||||
var repositories: Array<RepositoryData>,
|
var repositories: Array<RepositoryData>,
|
||||||
|
val isSetup: Boolean,
|
||||||
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||||
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit
|
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||||
|
/** In setup mode the trash icons will be replaced with download icons */
|
||||||
) :
|
) :
|
||||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
@ -37,7 +40,16 @@ class RepoAdapter(
|
||||||
fun bind(
|
fun bind(
|
||||||
repositoryData: RepositoryData
|
repositoryData: RepositoryData
|
||||||
) {
|
) {
|
||||||
itemView.action_button?.setImageResource(R.drawable.ic_baseline_delete_outline_24)
|
val isPrebuilt = PREBUILT_REPOSITORIES.contains(repositoryData)
|
||||||
|
val drawable =
|
||||||
|
if (isSetup) R.drawable.netflix_download else R.drawable.ic_baseline_delete_outline_24
|
||||||
|
|
||||||
|
// Only shows icon if on setup or if it isn't a prebuilt repo.
|
||||||
|
// No delete buttons on prebuilt repos.
|
||||||
|
if (!isPrebuilt || isSetup) {
|
||||||
|
itemView.action_button?.setImageResource(drawable)
|
||||||
|
}
|
||||||
|
|
||||||
itemView.action_button?.setOnClickListener {
|
itemView.action_button?.setOnClickListener {
|
||||||
imageClickCallback(repositoryData)
|
imageClickCallback(repositoryData)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.lagradost.cloudstream3.ui.setup
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.plugins.PREBUILT_REPOSITORIES
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.extensions.PluginsViewModel
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.extensions.RepoAdapter
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||||
|
import kotlinx.android.synthetic.main.fragment_extensions.*
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_media.*
|
||||||
|
|
||||||
|
|
||||||
|
class SetupFragmentExtensions : Fragment() {
|
||||||
|
companion object {
|
||||||
|
const val SETUP_EXTENSION_BUNDLE_IS_SETUP = "isSetup"
|
||||||
|
fun newInstance(isSetup: Boolean): Bundle {
|
||||||
|
return Bundle().apply {
|
||||||
|
putBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP, isSetup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_setup_extensions, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
context?.fixPaddingStatusbar(setup_root)
|
||||||
|
val isSetup = arguments?.getBoolean(SETUP_EXTENSION_BUNDLE_IS_SETUP) ?: false
|
||||||
|
|
||||||
|
with(context) {
|
||||||
|
if (this == null) return
|
||||||
|
|
||||||
|
repo_recycler_view?.adapter = RepoAdapter(PREBUILT_REPOSITORIES, true, {}, {
|
||||||
|
PluginsViewModel.downloadAll(activity, it.url, null)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!isSetup) {
|
||||||
|
next_btt.setText(R.string.setup_done)
|
||||||
|
}
|
||||||
|
prev_btt?.isVisible = isSetup
|
||||||
|
|
||||||
|
next_btt?.setOnClickListener {
|
||||||
|
// Continue setup
|
||||||
|
if (isSetup)
|
||||||
|
findNavController().navigate(R.id.action_navigation_setup_extensions_to_navigation_setup_provider_languages)
|
||||||
|
else
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_btt?.setOnClickListener {
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import com.lagradost.cloudstream3.BuildConfig
|
||||||
import com.lagradost.cloudstream3.CommonActivity
|
import com.lagradost.cloudstream3.CommonActivity
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
|
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||||
import com.lagradost.cloudstream3.ui.settings.appLanguages
|
import com.lagradost.cloudstream3.ui.settings.appLanguages
|
||||||
import com.lagradost.cloudstream3.ui.settings.getCurrentLocale
|
import com.lagradost.cloudstream3.ui.settings.getCurrentLocale
|
||||||
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
|
@ -23,6 +24,7 @@ import kotlinx.android.synthetic.main.fragment_setup_media.listview1
|
||||||
import kotlinx.android.synthetic.main.fragment_setup_media.next_btt
|
import kotlinx.android.synthetic.main.fragment_setup_media.next_btt
|
||||||
|
|
||||||
const val HAS_DONE_SETUP_KEY = "HAS_DONE_SETUP"
|
const val HAS_DONE_SETUP_KEY = "HAS_DONE_SETUP"
|
||||||
|
|
||||||
class SetupFragmentLanguage : Fragment() {
|
class SetupFragmentLanguage : Fragment() {
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
@ -76,7 +78,13 @@ class SetupFragmentLanguage : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
next_btt?.setOnClickListener {
|
next_btt?.setOnClickListener {
|
||||||
findNavController().navigate(R.id.action_navigation_setup_language_to_navigation_setup_provider_languages)
|
// If no plugins go to plugins page
|
||||||
|
val nextDestination = if (PluginManager.getPluginsOnline()
|
||||||
|
.isEmpty()
|
||||||
|
) R.id.action_navigation_global_to_navigation_setup_extensions
|
||||||
|
else R.id.action_navigation_setup_language_to_navigation_setup_provider_languages
|
||||||
|
|
||||||
|
findNavController().navigate(nextDestination, SetupFragmentExtensions.newInstance(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_btt?.setOnClickListener {
|
skip_btt?.setOnClickListener {
|
||||||
|
|
56
app/src/main/res/layout/fragment_setup_extensions.xml
Normal file
56
app/src/main/res/layout/fragment_setup_extensions.xml
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/setup_root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/extensions"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/setup_extensions_subtext" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/repo_recycler_view"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:listitem="@layout/repository_item" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/apply_btt_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_marginTop="-60dp"
|
||||||
|
android:gravity="bottom|end"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/next_btt"
|
||||||
|
style="@style/WhiteButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:text="@string/next" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/prev_btt"
|
||||||
|
style="@style/BlackButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:text="@string/previous" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -5,30 +5,30 @@
|
||||||
android:id="@+id/mobile_navigation"
|
android:id="@+id/mobile_navigation"
|
||||||
app:startDestination="@+id/navigation_home">
|
app:startDestination="@+id/navigation_home">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/global_to_navigation_results_tv"
|
android:id="@+id/global_to_navigation_results_tv"
|
||||||
app:destination="@id/navigation_results_tv"
|
app:destination="@id/navigation_results_tv"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim">
|
app:popExitAnim="@anim/exit_anim">
|
||||||
<argument
|
<argument
|
||||||
android:name="url"
|
android:name="url"
|
||||||
app:argType="string" />
|
app:argType="string" />
|
||||||
<argument
|
<argument
|
||||||
android:name="apiName"
|
android:name="apiName"
|
||||||
app:argType="string" />
|
app:argType="string" />
|
||||||
<argument
|
<argument
|
||||||
android:name="startAction"
|
android:name="startAction"
|
||||||
android:defaultValue="0"
|
android:defaultValue="0"
|
||||||
app:argType="integer" />
|
app:argType="integer" />
|
||||||
<argument
|
<argument
|
||||||
android:name="startValue"
|
android:name="startValue"
|
||||||
android:defaultValue="0"
|
android:defaultValue="0"
|
||||||
app:argType="integer" />
|
app:argType="integer" />
|
||||||
<argument
|
<argument
|
||||||
android:name="restart"
|
android:name="restart"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
app:argType="boolean" />
|
app:argType="boolean" />
|
||||||
</action>
|
</action>
|
||||||
<action
|
<action
|
||||||
android:id="@+id/global_to_navigation_results_phone"
|
android:id="@+id/global_to_navigation_results_phone"
|
||||||
|
@ -160,7 +160,8 @@
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim">
|
app:popExitAnim="@anim/exit_anim"
|
||||||
|
tools:layout="@layout/fragment_extensions">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/navigation_settings_extensions_to_navigation_settings_plugins"
|
android:id="@+id/navigation_settings_extensions_to_navigation_settings_plugins"
|
||||||
app:destination="@id/navigation_settings_plugins"
|
app:destination="@id/navigation_settings_plugins"
|
||||||
|
@ -186,7 +187,8 @@
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
app:popExitAnim="@anim/exit_anim"
|
||||||
|
tools:layout="@layout/fragment_plugins" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_settings_lang"
|
android:id="@+id/navigation_settings_lang"
|
||||||
|
@ -258,8 +260,7 @@
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim"
|
app:popExitAnim="@anim/exit_anim"
|
||||||
tools:layout="@layout/fragment_search">
|
tools:layout="@layout/fragment_search" />
|
||||||
</fragment>
|
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_downloads"
|
android:id="@+id/navigation_downloads"
|
||||||
|
@ -406,53 +407,53 @@
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_results_phone"
|
android:id="@+id/navigation_results_phone"
|
||||||
android:name="com.lagradost.cloudstream3.ui.result.ResultFragmentPhone"
|
android:name="com.lagradost.cloudstream3.ui.result.ResultFragmentPhone"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim"
|
||||||
|
tools:layout="@layout/fragment_result_swipe">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_navigation_results_phone_to_navigation_quick_search"
|
||||||
|
app:destination="@id/navigation_quick_search"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim"
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
tools:layout="@layout/fragment_result_swipe">
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_navigation_results_phone_to_navigation_quick_search"
|
android:id="@+id/action_navigation_results_phone_to_navigation_player"
|
||||||
app:destination="@id/navigation_quick_search"
|
app:destination="@id/navigation_player"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
<action
|
|
||||||
android:id="@+id/action_navigation_results_phone_to_navigation_player"
|
|
||||||
app:destination="@id/navigation_player"
|
|
||||||
app:enterAnim="@anim/enter_anim"
|
|
||||||
app:exitAnim="@anim/exit_anim"
|
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_results_tv"
|
android:id="@+id/navigation_results_tv"
|
||||||
android:name="com.lagradost.cloudstream3.ui.result.ResultFragmentTv"
|
android:name="com.lagradost.cloudstream3.ui.result.ResultFragmentTv"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim"
|
||||||
|
tools:layout="@layout/fragment_result_swipe">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_navigation_results_tv_to_navigation_quick_search"
|
||||||
|
app:destination="@id/navigation_quick_search"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim"
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
tools:layout="@layout/fragment_result_swipe">
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_navigation_results_tv_to_navigation_quick_search"
|
android:id="@+id/action_navigation_results_tv_to_navigation_player"
|
||||||
app:destination="@id/navigation_quick_search"
|
app:destination="@id/navigation_player"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
app:exitAnim="@anim/exit_anim"
|
app:exitAnim="@anim/exit_anim"
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
<action
|
|
||||||
android:id="@+id/action_navigation_results_tv_to_navigation_player"
|
|
||||||
app:destination="@id/navigation_player"
|
|
||||||
app:enterAnim="@anim/enter_anim"
|
|
||||||
app:exitAnim="@anim/exit_anim"
|
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<!--<fragment
|
<!--<fragment
|
||||||
|
@ -508,6 +509,38 @@
|
||||||
app:popEnterAnim="@anim/enter_anim"
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
app:popExitAnim="@anim/exit_anim" />
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_navigation_global_to_navigation_setup_extensions"
|
||||||
|
app:destination="@id/navigation_setup_extensions"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim">
|
||||||
|
<argument
|
||||||
|
android:name="isSetup"
|
||||||
|
android:defaultValue="false"
|
||||||
|
app:argType="boolean" />
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/navigation_setup_extensions"
|
||||||
|
android:name="com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim"
|
||||||
|
tools:layout="@layout/fragment_setup_extensions">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_navigation_setup_extensions_to_navigation_setup_provider_languages"
|
||||||
|
app:destination="@id/navigation_setup_provider_languages"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim" />
|
||||||
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_setup_provider_languages"
|
android:id="@+id/navigation_setup_provider_languages"
|
||||||
android:name="com.lagradost.cloudstream3.ui.setup.SetupFragmentProviderLanguage"
|
android:name="com.lagradost.cloudstream3.ui.setup.SetupFragmentProviderLanguage"
|
||||||
|
|
|
@ -585,4 +585,5 @@
|
||||||
<string name="plugin">plugins</string>
|
<string name="plugin">plugins</string>
|
||||||
<string name="delete_repository_plugins">This will also delete all repository plugins</string>
|
<string name="delete_repository_plugins">This will also delete all repository plugins</string>
|
||||||
<string name="delete_repository">Delete repository</string>
|
<string name="delete_repository">Delete repository</string>
|
||||||
|
<string name="setup_extensions_subtext">Download the list of sites you want to use</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue