Merge branch 'recloudstream:master' into master
This commit is contained in:
commit
3b26d9826d
|
@ -28,6 +28,7 @@ import com.lagradost.cloudstream3.APIHolder.removePluginMapping
|
|||
import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent
|
||||
import com.lagradost.cloudstream3.mvvm.debugPrint
|
||||
import com.lagradost.cloudstream3.mvvm.logError
|
||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||
import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||
|
@ -123,6 +124,10 @@ object PluginManager {
|
|||
val plugins = getPluginsOnline().filter {
|
||||
!it.filePath.contains(repositoryPath)
|
||||
}
|
||||
val file = File(repositoryPath)
|
||||
normalSafeApiCall {
|
||||
if (file.exists()) file.deleteRecursively()
|
||||
}
|
||||
setKey(PLUGINS_KEY, plugins)
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +183,11 @@ object PluginManager {
|
|||
val isDisabled = onlineData.second.status == PROVIDER_STATUS_DOWN
|
||||
|
||||
fun validOnlineData(context: Context): Boolean {
|
||||
return getPluginPath(context, savedData.internalName, onlineData.first).absolutePath == savedData.filePath
|
||||
return getPluginPath(
|
||||
context,
|
||||
savedData.internalName,
|
||||
onlineData.first
|
||||
).absolutePath == savedData.filePath
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,18 +493,13 @@ object PluginManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isFilePath will treat the pluginUrl as as the filepath instead of url
|
||||
* */
|
||||
suspend fun deletePlugin(pluginIdentifier: String, isFilePath: Boolean): Boolean {
|
||||
val data =
|
||||
(if (isFilePath) (getPluginsLocal() + getPluginsOnline()).firstOrNull { it.filePath == pluginIdentifier }
|
||||
else getPluginsOnline().firstOrNull { it.url == pluginIdentifier }) ?: return false
|
||||
suspend fun deletePlugin(file: File): Boolean {
|
||||
val list = (getPluginsLocal() + getPluginsOnline()).filter { it.filePath == file.absolutePath }
|
||||
|
||||
return try {
|
||||
if (File(data.filePath).delete()) {
|
||||
unloadPlugin(data.filePath)
|
||||
deletePluginData(data)
|
||||
if (File(file.absolutePath).delete()) {
|
||||
unloadPlugin(file.absolutePath)
|
||||
list.forEach { deletePluginData(it) }
|
||||
return true
|
||||
}
|
||||
false
|
||||
|
|
|
@ -58,6 +58,7 @@ import kotlinx.android.synthetic.main.player_select_source_and_subs.*
|
|||
import kotlinx.android.synthetic.main.player_select_source_and_subs.subtitles_click_settings
|
||||
import kotlinx.android.synthetic.main.player_select_tracks.*
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
class GeneratorPlayer : FullScreenPlayer() {
|
||||
companion object {
|
||||
|
@ -115,10 +116,11 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
|
||||
override fun onTracksInfoChanged() {
|
||||
val tracks = player.getVideoTracks()
|
||||
player_tracks_btt?.isVisible = tracks.allVideoTracks.size > 1 || tracks.allAudioTracks.size > 1
|
||||
player_tracks_btt?.isVisible =
|
||||
tracks.allVideoTracks.size > 1 || tracks.allAudioTracks.size > 1
|
||||
// Only set the preferred language if it is available.
|
||||
// Otherwise it may give some users audio track init failed!
|
||||
if (tracks.allAudioTracks.any { it.language == preferredAudioTrackLanguage }){
|
||||
if (tracks.allAudioTracks.any { it.language == preferredAudioTrackLanguage }) {
|
||||
player.setPreferredAudioTrack(preferredAudioTrackLanguage)
|
||||
}
|
||||
}
|
||||
|
@ -602,8 +604,20 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
subtitleList.setItemChecked(subtitleIndex, true)
|
||||
|
||||
subtitleList.setOnItemClickListener { _, _, which, _ ->
|
||||
subtitleIndex = which
|
||||
subtitleList.setItemChecked(which, true)
|
||||
if (which > currentSubtitles.size) {
|
||||
// Since android TV is funky the setOnItemClickListener will be triggered
|
||||
// instead of setOnClickListener when selecting. To override this we programmatically
|
||||
// click the view when selecting an item outside the list.
|
||||
|
||||
// Cheeky way of getting the view at that position to click it
|
||||
// to avoid keeping track of the various footers.
|
||||
// getChildAt() gives null :(
|
||||
val child = subtitleList.adapter.getView(which, null, subtitleList)
|
||||
child?.performClick()
|
||||
} else {
|
||||
subtitleIndex = which
|
||||
subtitleList.setItemChecked(which, true)
|
||||
}
|
||||
}
|
||||
|
||||
sourceDialog.cancel_btt?.setOnClickListener {
|
||||
|
@ -762,7 +776,8 @@ class GeneratorPlayer : FullScreenPlayer() {
|
|||
ArrayAdapter<String>(ctx, R.layout.sort_bottom_single_choice)
|
||||
// audioArrayAdapter.add(ctx.getString(R.string.no_subtitles))
|
||||
audioArrayAdapter.addAll(currentAudioTracks.mapIndexed { index, format ->
|
||||
format.label ?: format.language?.let { fromTwoLettersToLanguage(it) } ?: index.toString()
|
||||
format.label ?: format.language?.let { fromTwoLettersToLanguage(it) }
|
||||
?: index.toString()
|
||||
})
|
||||
|
||||
audioList.adapter = audioArrayAdapter
|
||||
|
|
|
@ -133,11 +133,10 @@ class PluginsViewModel : ViewModel() {
|
|||
if (activity == null) return@ioSafe
|
||||
val (repo, metadata) = plugin
|
||||
|
||||
val (success, message) = if (isDownloaded(activity, plugin.second.internalName, plugin.first) || isLocal) {
|
||||
PluginManager.deletePlugin(
|
||||
metadata.url,
|
||||
isLocal
|
||||
) to R.string.plugin_deleted
|
||||
val file = getPluginPath(activity, plugin.second.internalName, plugin.first)
|
||||
|
||||
val (success, message) = if (file.exists() || isLocal) {
|
||||
PluginManager.deletePlugin(file) to R.string.plugin_deleted
|
||||
} else {
|
||||
PluginManager.downloadAndLoadPlugin(
|
||||
activity,
|
||||
|
|
Loading…
Reference in New Issue