forked from recloudstream/cloudstream
Added loading repositories from url
This commit is contained in:
parent
8c0e07decb
commit
34660bcd48
8 changed files with 68 additions and 23 deletions
|
@ -178,6 +178,7 @@
|
|||
<data android:scheme="https" android:host="aniflix.pro" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="kimcartoon.li" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="xcine.me" android:pathPrefix="/"/>
|
||||
<data android:scheme="https" android:host="cs.repo" android:pathPrefix="/"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.view.KeyEvent
|
|||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -79,6 +80,9 @@ import java.io.File
|
|||
import kotlin.concurrent.thread
|
||||
import kotlin.reflect.KClass
|
||||
import com.lagradost.cloudstream3.plugins.PluginManager
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager
|
||||
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
|
||||
|
||||
const val VLC_PACKAGE = "org.videolan.vlc"
|
||||
|
@ -320,7 +324,26 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
|||
val str = intent.dataString
|
||||
loadCache()
|
||||
if (str != null) {
|
||||
if (str.contains(appString)) {
|
||||
if (str.startsWith("https://cs.repo")) {
|
||||
val realUrl = "https://" + str.substringAfter("?")
|
||||
println("Repository url: $realUrl")
|
||||
ioSafe {
|
||||
val repo = RepositoryManager.parseRepository(realUrl) ?: return@ioSafe
|
||||
RepositoryManager.addRepository(
|
||||
RepositoryData(
|
||||
repo.name,
|
||||
realUrl
|
||||
)
|
||||
)
|
||||
main {
|
||||
showToast(
|
||||
this,
|
||||
this.getString(R.string.player_loaded_subtitles, repo.name),
|
||||
Toast.LENGTH_LONG
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (str.contains(appString)) {
|
||||
for (api in OAuth2Apis) {
|
||||
if (str.contains("/${api.redirectUrl}")) {
|
||||
ioSafe {
|
||||
|
|
|
@ -85,7 +85,7 @@ object PluginManager {
|
|||
var loadedLocalPlugins = false
|
||||
private val gson = Gson()
|
||||
|
||||
fun maybeLoadPlugin(context: Context, file: File) {
|
||||
private fun maybeLoadPlugin(context: Context, file: File) {
|
||||
val name = file.name
|
||||
if (file.extension == "zip" || file.extension == "cs3") {
|
||||
loadPlugin(context, file, PluginData(name, null, false, file.absolutePath))
|
||||
|
|
|
@ -44,19 +44,19 @@ data class SitePlugin(
|
|||
object RepositoryManager {
|
||||
const val ONLINE_PLUGINS_FOLDER = "Extensions"
|
||||
|
||||
private suspend fun parseRepository(url: String): Repository? {
|
||||
suspend fun parseRepository(url: String): Repository? {
|
||||
return suspendSafeApiCall {
|
||||
// Take manifestVersion and such into account later
|
||||
app.get(url).parsedSafe()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parsePlugins(pluginUrls: String): ArrayList<SitePlugin>? {
|
||||
private suspend fun parsePlugins(pluginUrls: String): List<SitePlugin> {
|
||||
// Take manifestVersion and such into account later
|
||||
val response = app.get(pluginUrls)
|
||||
// Normal parsed function not working?
|
||||
// return response.parsedSafe()
|
||||
return tryParseJson<ArrayList<SitePlugin>>(response.text)
|
||||
return tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
|
||||
}
|
||||
|
||||
suspend fun getRepoPlugins(repositoryUrl: String): List<SitePlugin>? {
|
||||
|
@ -85,10 +85,21 @@ object RepositoryManager {
|
|||
// Don't want to read before we write in another thread
|
||||
private val repoLock = Mutex()
|
||||
suspend fun addRepository(repository: RepositoryData) {
|
||||
repoLock.withLock {
|
||||
val currentRepos = getKey<List<RepositoryData>>(REPOSITORIES_KEY) ?: emptyList()
|
||||
setKey(REPOSITORIES_KEY, currentRepos + repository)
|
||||
}
|
||||
repoLock.withLock {
|
||||
val currentRepos = getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()
|
||||
// No duplicates
|
||||
if (currentRepos.any { it.url == repository.url }) return
|
||||
setKey(REPOSITORIES_KEY, currentRepos + repository)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun removeRepository(repository: RepositoryData) {
|
||||
repoLock.withLock {
|
||||
val currentRepos = getKey<Array<RepositoryData>>(REPOSITORIES_KEY) ?: emptyArray()
|
||||
// No duplicates
|
||||
val newRepos = currentRepos.filter { it.url != repository.url }
|
||||
setKey(REPOSITORIES_KEY, newRepos)
|
||||
}
|
||||
}
|
||||
|
||||
private fun write(stream: InputStream, output: OutputStream) {
|
||||
|
|
|
@ -39,16 +39,23 @@ class ExtensionsFragment : Fragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
context?.fixPaddingStatusbar(extensions_root)
|
||||
|
||||
observe(extensionViewModel.repositories) {
|
||||
// Kinda cheap to do this instead of updates
|
||||
repo_recycler_view?.adapter = RepoAdapter(it) {
|
||||
findNavController().navigate(
|
||||
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
||||
Bundle().apply {
|
||||
putString(PLUGINS_BUNDLE_NAME, it.name)
|
||||
putString(PLUGINS_BUNDLE_URL, it.url)
|
||||
})
|
||||
repo_recycler_view?.adapter = RepoAdapter(emptyArray(), {
|
||||
findNavController().navigate(
|
||||
R.id.navigation_settings_extensions_to_navigation_settings_plugins,
|
||||
Bundle().apply {
|
||||
putString(PLUGINS_BUNDLE_NAME, it.name)
|
||||
putString(PLUGINS_BUNDLE_URL, it.url)
|
||||
})
|
||||
}, { repo ->
|
||||
ioSafe {
|
||||
RepositoryManager.removeRepository(repo)
|
||||
extensionViewModel.loadRepositories()
|
||||
}
|
||||
})
|
||||
|
||||
observe(extensionViewModel.repositories) {
|
||||
(repo_recycler_view?.adapter as? RepoAdapter)?.repositories = it
|
||||
(repo_recycler_view?.adapter as? RepoAdapter)?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
add_repo_button?.setOnClickListener {
|
||||
|
|
|
@ -46,8 +46,6 @@ class PluginAdapter(
|
|||
plugin: SitePlugin
|
||||
) {
|
||||
val isDownloaded = storedPlugins.any { it.url == plugin.url }
|
||||
println("ISOWNLOADED $isDownloaded ${storedPlugins.map { it.url }} ||||| ${plugin.url}")
|
||||
|
||||
|
||||
val drawableInt = if (isDownloaded)
|
||||
R.drawable.ic_baseline_delete_outline_24
|
||||
|
|
|
@ -43,7 +43,6 @@ class PluginsFragment : Fragment() {
|
|||
|
||||
ioSafe {
|
||||
val plugins = extensionViewModel.getPlugins(url)
|
||||
println("GET PLUGINS $plugins")
|
||||
main {
|
||||
repo_recycler_view?.adapter = PluginAdapter(plugins) { plugin, isDownloaded ->
|
||||
ioSafe {
|
||||
|
|
|
@ -9,8 +9,9 @@ import com.lagradost.cloudstream3.ui.settings.AccountClickCallback
|
|||
import kotlinx.android.synthetic.main.repository_item.view.*
|
||||
|
||||
class RepoAdapter(
|
||||
private val repositories: Array<RepositoryData>,
|
||||
val clickCallback: (RepositoryData) -> Unit
|
||||
var repositories: Array<RepositoryData>,
|
||||
val clickCallback: RepoAdapter.(RepositoryData) -> Unit,
|
||||
val imageClickCallback: RepoAdapter.(RepositoryData) -> Unit
|
||||
) :
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
|
@ -36,6 +37,11 @@ class RepoAdapter(
|
|||
fun bind(
|
||||
repositoryData: RepositoryData
|
||||
) {
|
||||
itemView.action_button?.setImageResource(R.drawable.ic_baseline_delete_outline_24)
|
||||
itemView.action_button?.setOnClickListener {
|
||||
imageClickCallback(repositoryData)
|
||||
}
|
||||
|
||||
itemView.setOnClickListener {
|
||||
clickCallback(repositoryData)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue