mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Initial support for multi deleting downloads
This is probably a horrible way to do this, I just am not sure of the best way to go about this to be honest
This commit is contained in:
parent
c1b5f5c128
commit
7b1f59fdb4
6 changed files with 125 additions and 43 deletions
|
@ -27,6 +27,7 @@ const val DOWNLOAD_ACTION_RESUME_DOWNLOAD = 2
|
||||||
const val DOWNLOAD_ACTION_PAUSE_DOWNLOAD = 3
|
const val DOWNLOAD_ACTION_PAUSE_DOWNLOAD = 3
|
||||||
const val DOWNLOAD_ACTION_DOWNLOAD = 4
|
const val DOWNLOAD_ACTION_DOWNLOAD = 4
|
||||||
const val DOWNLOAD_ACTION_LONG_CLICK = 5
|
const val DOWNLOAD_ACTION_LONG_CLICK = 5
|
||||||
|
const val DOWNLOAD_ACTION_DELETE_MULTIPLE_FILES = 6
|
||||||
|
|
||||||
const val DOWNLOAD_ACTION_GO_TO_CHILD = 0
|
const val DOWNLOAD_ACTION_GO_TO_CHILD = 0
|
||||||
const val DOWNLOAD_ACTION_LOAD_RESULT = 1
|
const val DOWNLOAD_ACTION_LOAD_RESULT = 1
|
||||||
|
@ -57,6 +58,11 @@ abstract class VisualDownloadCached(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class DownloadActionEventBase(
|
||||||
|
open val action: Int,
|
||||||
|
open val data: VideoDownloadHelper.DownloadEpisodeCached?
|
||||||
|
)
|
||||||
|
|
||||||
data class VisualDownloadChildCached(
|
data class VisualDownloadChildCached(
|
||||||
override val currentBytes: Long,
|
override val currentBytes: Long,
|
||||||
override val totalBytes: Long,
|
override val totalBytes: Long,
|
||||||
|
@ -73,9 +79,14 @@ data class VisualDownloadHeaderCached(
|
||||||
): VisualDownloadCached(currentBytes, totalBytes, data)
|
): VisualDownloadCached(currentBytes, totalBytes, data)
|
||||||
|
|
||||||
data class DownloadClickEvent(
|
data class DownloadClickEvent(
|
||||||
val action: Int,
|
override val action: Int,
|
||||||
val data: VideoDownloadHelper.DownloadEpisodeCached
|
override val data: VideoDownloadHelper.DownloadEpisodeCached
|
||||||
)
|
): DownloadActionEventBase(action, data)
|
||||||
|
|
||||||
|
data class DownloadDeleteEvent(
|
||||||
|
override val action: Int,
|
||||||
|
val items: List<VideoDownloadHelper.DownloadEpisodeCached?>
|
||||||
|
): DownloadActionEventBase(action, null)
|
||||||
|
|
||||||
data class DownloadHeaderClickEvent(
|
data class DownloadHeaderClickEvent(
|
||||||
val action: Int,
|
val action: Int,
|
||||||
|
@ -83,8 +94,8 @@ data class DownloadHeaderClickEvent(
|
||||||
)
|
)
|
||||||
|
|
||||||
class DownloadAdapter(
|
class DownloadAdapter(
|
||||||
|
private val actionCallback: (DownloadActionEventBase) -> Unit,
|
||||||
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
|
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
|
||||||
private val mediaClickCallback: (DownloadClickEvent) -> Unit,
|
|
||||||
) : ListAdapter<VisualDownloadCached, DownloadAdapter.DownloadViewHolder>(DiffCallback()) {
|
) : ListAdapter<VisualDownloadCached, DownloadAdapter.DownloadViewHolder>(DiffCallback()) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -94,8 +105,8 @@ class DownloadAdapter(
|
||||||
|
|
||||||
inner class DownloadViewHolder(
|
inner class DownloadViewHolder(
|
||||||
private val binding: ViewBinding,
|
private val binding: ViewBinding,
|
||||||
|
private val actionCallback: (DownloadActionEventBase) -> Unit,
|
||||||
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
|
private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
|
||||||
private val mediaClickCallback: (DownloadClickEvent) -> Unit,
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(card: VisualDownloadCached?) {
|
fun bind(card: VisualDownloadCached?) {
|
||||||
|
@ -145,11 +156,11 @@ class DownloadAdapter(
|
||||||
ContextCompat.getDrawable(downloadButton.context, downloadButton.progressDrawable)
|
ContextCompat.getDrawable(downloadButton.context, downloadButton.progressDrawable)
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadButton.setDefaultClickListener(card.child, downloadHeaderInfo, mediaClickCallback)
|
downloadButton.setDefaultClickListener(card.child, downloadHeaderInfo, actionCallback)
|
||||||
downloadButton.isVisible = true
|
downloadButton.isVisible = true
|
||||||
|
|
||||||
episodeHolder.setOnClickListener {
|
episodeHolder.setOnClickListener {
|
||||||
mediaClickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, card.child))
|
actionCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, card.child))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
downloadButton.isVisible = false
|
downloadButton.isVisible = false
|
||||||
|
@ -214,7 +225,7 @@ class DownloadAdapter(
|
||||||
ContextCompat.getDrawable(downloadButton.context, downloadButton.progressDrawable)
|
ContextCompat.getDrawable(downloadButton.context, downloadButton.progressDrawable)
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadButton.setDefaultClickListener(d, downloadChildEpisodeTextExtra, mediaClickCallback)
|
downloadButton.setDefaultClickListener(d, downloadChildEpisodeTextExtra, actionCallback)
|
||||||
downloadButton.isVisible = true
|
downloadButton.isVisible = true
|
||||||
|
|
||||||
downloadChildEpisodeText.apply {
|
downloadChildEpisodeText.apply {
|
||||||
|
@ -223,7 +234,7 @@ class DownloadAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadChildEpisodeHolder.setOnClickListener {
|
downloadChildEpisodeHolder.setOnClickListener {
|
||||||
mediaClickCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d))
|
actionCallback.invoke(DownloadClickEvent(DOWNLOAD_ACTION_PLAY_FILE, d))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +247,7 @@ class DownloadAdapter(
|
||||||
VIEW_TYPE_CHILD -> DownloadChildEpisodeBinding.inflate(inflater, parent, false)
|
VIEW_TYPE_CHILD -> DownloadChildEpisodeBinding.inflate(inflater, parent, false)
|
||||||
else -> throw IllegalArgumentException("Invalid view type")
|
else -> throw IllegalArgumentException("Invalid view type")
|
||||||
}
|
}
|
||||||
return DownloadViewHolder(binding, clickCallback, mediaClickCallback)
|
return DownloadViewHolder(binding, actionCallback, clickCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: DownloadViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: DownloadViewHolder, position: Int) {
|
||||||
|
|
|
@ -17,19 +17,21 @@ import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
||||||
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
|
||||||
import com.lagradost.cloudstream3.utils.VideoDownloadManager
|
import com.lagradost.cloudstream3.utils.VideoDownloadManager
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
|
||||||
object DownloadButtonSetup {
|
object DownloadButtonSetup {
|
||||||
fun handleDownloadClick(click: DownloadClickEvent) {
|
fun handleDownloadClick(click: DownloadActionEventBase) {
|
||||||
val id = click.data.id
|
|
||||||
when (click.action) {
|
when (click.action) {
|
||||||
DOWNLOAD_ACTION_DELETE_FILE -> {
|
DOWNLOAD_ACTION_DELETE_FILE -> {
|
||||||
|
if (click !is DownloadDeleteEvent) return
|
||||||
|
val id = click.items.firstOrNull()?.id ?: return
|
||||||
activity?.let { ctx ->
|
activity?.let { ctx ->
|
||||||
val builder: AlertDialog.Builder = AlertDialog.Builder(ctx)
|
val builder: AlertDialog.Builder = AlertDialog.Builder(ctx)
|
||||||
val dialogClickListener =
|
val dialogClickListener =
|
||||||
DialogInterface.OnClickListener { _, which ->
|
DialogInterface.OnClickListener { _, which ->
|
||||||
when (which) {
|
when (which) {
|
||||||
DialogInterface.BUTTON_POSITIVE -> {
|
DialogInterface.BUTTON_POSITIVE -> {
|
||||||
VideoDownloadManager.deleteFileAndUpdateSettings(ctx, id)
|
VideoDownloadManager.deleteFilesAndUpdateSettings(ctx, listOf(id), MainScope())
|
||||||
}
|
}
|
||||||
DialogInterface.BUTTON_NEGATIVE -> {
|
DialogInterface.BUTTON_NEGATIVE -> {
|
||||||
}
|
}
|
||||||
|
@ -41,9 +43,9 @@ object DownloadButtonSetup {
|
||||||
.setMessage(
|
.setMessage(
|
||||||
ctx.getString(R.string.delete_message).format(
|
ctx.getString(R.string.delete_message).format(
|
||||||
ctx.getNameFull(
|
ctx.getNameFull(
|
||||||
click.data.name,
|
click.items.firstOrNull()?.name,
|
||||||
click.data.episode,
|
click.items.firstOrNull()?.episode,
|
||||||
click.data.season
|
click.items.firstOrNull()?.season
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -57,15 +59,17 @@ object DownloadButtonSetup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> {
|
DOWNLOAD_ACTION_PAUSE_DOWNLOAD -> {
|
||||||
|
val id = click.data?.id ?: return
|
||||||
VideoDownloadManager.downloadEvent.invoke(
|
VideoDownloadManager.downloadEvent.invoke(
|
||||||
Pair(click.data.id, VideoDownloadManager.DownloadActionType.Pause)
|
Pair(id, VideoDownloadManager.DownloadActionType.Pause)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
DOWNLOAD_ACTION_RESUME_DOWNLOAD -> {
|
DOWNLOAD_ACTION_RESUME_DOWNLOAD -> {
|
||||||
|
val id = click.data?.id ?: return
|
||||||
activity?.let { ctx ->
|
activity?.let { ctx ->
|
||||||
if (VideoDownloadManager.downloadStatus.containsKey(id) && VideoDownloadManager.downloadStatus[id] == VideoDownloadManager.DownloadType.IsPaused) {
|
if (VideoDownloadManager.downloadStatus.containsKey(id) && VideoDownloadManager.downloadStatus[id] == VideoDownloadManager.DownloadType.IsPaused) {
|
||||||
VideoDownloadManager.downloadEvent.invoke(
|
VideoDownloadManager.downloadEvent.invoke(
|
||||||
Pair(click.data.id, VideoDownloadManager.DownloadActionType.Resume)
|
Pair(id, VideoDownloadManager.DownloadActionType.Resume)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val pkg = VideoDownloadManager.getDownloadResumePackage(ctx, id)
|
val pkg = VideoDownloadManager.getDownloadResumePackage(ctx, id)
|
||||||
|
@ -73,18 +77,19 @@ object DownloadButtonSetup {
|
||||||
VideoDownloadManager.downloadFromResumeUsingWorker(ctx, pkg)
|
VideoDownloadManager.downloadFromResumeUsingWorker(ctx, pkg)
|
||||||
} else {
|
} else {
|
||||||
VideoDownloadManager.downloadEvent.invoke(
|
VideoDownloadManager.downloadEvent.invoke(
|
||||||
Pair(click.data.id, VideoDownloadManager.DownloadActionType.Resume)
|
Pair(id, VideoDownloadManager.DownloadActionType.Resume)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DOWNLOAD_ACTION_LONG_CLICK -> {
|
DOWNLOAD_ACTION_LONG_CLICK -> {
|
||||||
|
val id = click.data?.id ?: return
|
||||||
activity?.let { act ->
|
activity?.let { act ->
|
||||||
val length =
|
val length =
|
||||||
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
||||||
act,
|
act,
|
||||||
click.data.id
|
id
|
||||||
)?.fileLength
|
)?.fileLength
|
||||||
?: 0
|
?: 0
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
@ -95,19 +100,20 @@ object DownloadButtonSetup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DOWNLOAD_ACTION_PLAY_FILE -> {
|
DOWNLOAD_ACTION_PLAY_FILE -> {
|
||||||
|
val id = click.data?.id ?: return
|
||||||
activity?.let { act ->
|
activity?.let { act ->
|
||||||
val info =
|
val info =
|
||||||
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
|
||||||
act,
|
act,
|
||||||
click.data.id
|
id
|
||||||
) ?: return
|
) ?: return
|
||||||
val keyInfo = getKey<VideoDownloadManager.DownloadedFileInfo>(
|
val keyInfo = getKey<VideoDownloadManager.DownloadedFileInfo>(
|
||||||
VideoDownloadManager.KEY_DOWNLOAD_INFO,
|
VideoDownloadManager.KEY_DOWNLOAD_INFO,
|
||||||
click.data.id.toString()
|
id.toString()
|
||||||
) ?: return
|
) ?: return
|
||||||
val parent = getKey<VideoDownloadHelper.DownloadHeaderCached>(
|
val parent = getKey<VideoDownloadHelper.DownloadHeaderCached>(
|
||||||
DOWNLOAD_HEADER_CACHE,
|
DOWNLOAD_HEADER_CACHE,
|
||||||
click.data.parentId.toString()
|
click.data?.parentId.toString()
|
||||||
) ?: return
|
) ?: return
|
||||||
|
|
||||||
act.navigate(
|
act.navigate(
|
||||||
|
@ -117,11 +123,11 @@ object DownloadButtonSetup {
|
||||||
ExtractorUri(
|
ExtractorUri(
|
||||||
uri = info.path,
|
uri = info.path,
|
||||||
|
|
||||||
id = click.data.id,
|
id = id,
|
||||||
parentId = click.data.parentId,
|
parentId = click.data?.parentId,
|
||||||
name = act.getString(R.string.downloaded_file), //click.data.name ?: keyInfo.displayName
|
name = act.getString(R.string.downloaded_file), //click.data.name ?: keyInfo.displayName
|
||||||
season = click.data.season,
|
season = click.data?.season,
|
||||||
episode = click.data.episode,
|
episode = click.data?.episode,
|
||||||
headerName = parent.name,
|
headerName = parent.name,
|
||||||
tvType = parent.type,
|
tvType = parent.type,
|
||||||
|
|
||||||
|
@ -138,17 +144,47 @@ object DownloadButtonSetup {
|
||||||
// keyInfo.basePath,
|
// keyInfo.basePath,
|
||||||
// keyInfo.relativePath,
|
// keyInfo.relativePath,
|
||||||
// keyInfo.displayName,
|
// keyInfo.displayName,
|
||||||
// click.data.parentId,
|
// click.data?.parentId,
|
||||||
// click.data.id,
|
// click.data?.id,
|
||||||
// headerName ?: "null",
|
// headerName ?: "null",
|
||||||
// if (click.data.episode <= 0) null else click.data.episode,
|
// if (click.data.episode <= 0) null else click.data.episode,
|
||||||
// click.data.season
|
// click.data.season
|
||||||
// ),
|
// ),
|
||||||
// getViewPos(click.data.id)?.position ?: 0
|
// getViewPos(click.data?.id)?.position ?: 0
|
||||||
//)
|
//)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DOWNLOAD_ACTION_DELETE_MULTIPLE_FILES -> {
|
||||||
|
activity?.let { ctx ->
|
||||||
|
if (click !is DownloadDeleteEvent) return
|
||||||
|
val ids: List<Int> = click.items.mapNotNull { it?.id }
|
||||||
|
.takeIf { it.isNotEmpty() } ?: return@let
|
||||||
|
val builder: AlertDialog.Builder = AlertDialog.Builder(ctx)
|
||||||
|
val dialogClickListener =
|
||||||
|
DialogInterface.OnClickListener { _, which ->
|
||||||
|
when (which) {
|
||||||
|
DialogInterface.BUTTON_POSITIVE -> {
|
||||||
|
VideoDownloadManager.deleteFilesAndUpdateSettings(ctx, ids, MainScope())
|
||||||
|
}
|
||||||
|
DialogInterface.BUTTON_NEGATIVE -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
builder.setTitle(R.string.delete_files)
|
||||||
|
.setMessage(
|
||||||
|
ctx.getString(R.string.delete_multiple_message)
|
||||||
|
)
|
||||||
|
.setPositiveButton(R.string.delete, dialogClickListener)
|
||||||
|
.setNegativeButton(R.string.cancel, dialogClickListener)
|
||||||
|
.show().setDefaultFocus()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -102,13 +102,17 @@ class DownloadChildFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val adapter = DownloadAdapter(
|
val adapter = DownloadAdapter(
|
||||||
{},
|
{ actionEvent ->
|
||||||
{ downloadClickEvent ->
|
if (actionEvent.action == DOWNLOAD_ACTION_DELETE_FILE) {
|
||||||
handleDownloadClick(downloadClickEvent)
|
val downloadDeleteEvent = DownloadDeleteEvent(
|
||||||
if (downloadClickEvent.action == DOWNLOAD_ACTION_DELETE_FILE) {
|
action = DOWNLOAD_ACTION_DELETE_FILE,
|
||||||
|
items = listOf(actionEvent.data)
|
||||||
|
)
|
||||||
|
handleDownloadClick(downloadDeleteEvent)
|
||||||
setUpDownloadDeleteListener(folder)
|
setUpDownloadDeleteListener(folder)
|
||||||
}
|
} else handleDownloadClick(actionEvent)
|
||||||
}
|
},
|
||||||
|
{}
|
||||||
)
|
)
|
||||||
|
|
||||||
binding?.downloadChildList?.apply {
|
binding?.downloadChildList?.apply {
|
||||||
|
|
|
@ -108,14 +108,18 @@ class DownloadFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val adapter = DownloadAdapter(
|
val adapter = DownloadAdapter(
|
||||||
|
{ actionEvent ->
|
||||||
|
if (actionEvent.action == DOWNLOAD_ACTION_DELETE_FILE) {
|
||||||
|
val downloadDeleteEvent = DownloadDeleteEvent(
|
||||||
|
action = DOWNLOAD_ACTION_DELETE_FILE,
|
||||||
|
items = listOf(actionEvent.data)
|
||||||
|
)
|
||||||
|
handleDownloadClick(downloadDeleteEvent)
|
||||||
|
setUpDownloadDeleteListener()
|
||||||
|
} else handleDownloadClick(actionEvent)
|
||||||
|
},
|
||||||
{ click ->
|
{ click ->
|
||||||
handleItemClick(click)
|
handleItemClick(click)
|
||||||
},
|
|
||||||
{ downloadClickEvent ->
|
|
||||||
handleDownloadClick(downloadClickEvent)
|
|
||||||
if (downloadClickEvent.action == DOWNLOAD_ACTION_DELETE_FILE) {
|
|
||||||
setUpDownloadDeleteListener()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import androidx.work.WorkManager
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.model.GlideUrl
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.lagradost.api.Log
|
||||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.removeKey
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
|
@ -29,6 +30,7 @@ import com.lagradost.cloudstream3.MainActivity
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.TvType
|
import com.lagradost.cloudstream3.TvType
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
|
import com.lagradost.cloudstream3.mvvm.launchSafe
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.services.VideoDownloadService
|
import com.lagradost.cloudstream3.services.VideoDownloadService
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
|
@ -42,6 +44,8 @@ import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
|
@ -1705,7 +1709,28 @@ object VideoDownloadManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteFileAndUpdateSettings(context: Context, id: Int): Boolean {
|
fun deleteFilesAndUpdateSettings(context: Context, ids: List<Int>, scope: CoroutineScope) {
|
||||||
|
scope.launchSafe(Dispatchers.IO) {
|
||||||
|
val deleteJobs = ids.map { id ->
|
||||||
|
async {
|
||||||
|
id to deleteFileAndUpdateSettings(context, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val results = deleteJobs.awaitAll()
|
||||||
|
|
||||||
|
val failedDeletes = results.filterNot { it.second }
|
||||||
|
if (failedDeletes.isNotEmpty()) {
|
||||||
|
failedDeletes.forEach { (id, _) ->
|
||||||
|
// TODO show a toast if some failed?
|
||||||
|
Log.e("FileDeletion", "Failed to delete file with ID: $id")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.i("FileDeletion", "All files deleted successfully")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteFileAndUpdateSettings(context: Context, id: Int): Boolean {
|
||||||
val success = deleteFile(context, id)
|
val success = deleteFile(context, id)
|
||||||
if (success) context.removeKey(KEY_DOWNLOAD_INFO, id.toString())
|
if (success) context.removeKey(KEY_DOWNLOAD_INFO, id.toString())
|
||||||
return success
|
return success
|
||||||
|
|
|
@ -300,6 +300,7 @@
|
||||||
<string name="episode_short">E</string>
|
<string name="episode_short">E</string>
|
||||||
<string name="no_episodes_found">No Episodes found</string>
|
<string name="no_episodes_found">No Episodes found</string>
|
||||||
<string name="delete_file">Delete File</string>
|
<string name="delete_file">Delete File</string>
|
||||||
|
<string name="delete_files">Delete Files</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="pause">Pause</string>
|
<string name="pause">Pause</string>
|
||||||
|
@ -311,6 +312,7 @@
|
||||||
<string name="go_back_30">-30</string>
|
<string name="go_back_30">-30</string>
|
||||||
<string name="go_forward_30">+30</string>
|
<string name="go_forward_30">+30</string>
|
||||||
<string name="delete_message" formatted="true">This will permanently delete %s\nAre you sure?</string>
|
<string name="delete_message" formatted="true">This will permanently delete %s\nAre you sure?</string>
|
||||||
|
<string name="delete_multiple_message" formatted="true">This will permanently delete all of: %s\nAre you sure?</string>
|
||||||
<string name="resume_time_left" formatted="true">%dm\nremaining</string>
|
<string name="resume_time_left" formatted="true">%dm\nremaining</string>
|
||||||
<string name="resume_remaining" formatted="true">%s\nremaining</string>
|
<string name="resume_remaining" formatted="true">%s\nremaining</string>
|
||||||
<string name="status_ongoing">Ongoing</string>
|
<string name="status_ongoing">Ongoing</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue