Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ fun downloadItemAD(
}
}
val chaptersAdapter = BaseListAdapter<DownloadChapter>()
.addDelegate(ListItemType.CHAPTER_LIST, downloadChapterAD())
.addDelegate(
ListItemType.CHAPTER_LIST,
downloadChapterAD { chapter ->
listener.onDeleteChapterClick(item, chapter)
},
)

binding.recyclerViewChapters.adapter = chaptersAdapter
binding.buttonCancel.setOnClickListener(clickListener)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.landwarderer.futon.download.ui.list

import io.github.landwarderer.futon.core.ui.list.OnListItemClickListener
import io.github.landwarderer.futon.download.ui.list.chapters.DownloadChapter

interface DownloadItemListener : OnListItemClickListener<DownloadItemModel> {

Expand All @@ -15,4 +16,6 @@ interface DownloadItemListener : OnListItemClickListener<DownloadItemModel> {
fun onSkipAllClick(item: DownloadItemModel)

fun onExpandClick(item: DownloadItemModel)

fun onDeleteChapterClick(item: DownloadItemModel, chapter: DownloadChapter)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import io.github.landwarderer.futon.core.nav.router
import io.github.landwarderer.futon.core.ui.BaseActivity
import io.github.landwarderer.futon.core.ui.list.ListSelectionController
import io.github.landwarderer.futon.core.ui.list.RecyclerScrollKeeper
import io.github.landwarderer.futon.core.ui.dialog.buildAlertDialog
import io.github.landwarderer.futon.core.ui.dialog.setCheckbox
import io.github.landwarderer.futon.core.ui.util.MenuInvalidator
import io.github.landwarderer.futon.core.ui.util.ReversibleActionObserver
import io.github.landwarderer.futon.core.util.FileSize
import io.github.landwarderer.futon.download.ui.list.chapters.DownloadChapter
import io.github.landwarderer.futon.core.util.ext.observe
import io.github.landwarderer.futon.core.util.ext.observeEvent
import io.github.landwarderer.futon.databinding.ActivityDownloadsBinding
Expand Down Expand Up @@ -194,8 +197,18 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
}

R.id.action_remove -> {
viewModel.remove(controller.snapshot())
mode?.finish()
var deleteFiles = false
buildAlertDialog(this) {
setTitle(R.string.remove_downloads_confirm)
setCheckbox(R.string.delete_downloaded_files, false) { _, isChecked ->
deleteFiles = isChecked
}
setPositiveButton(R.string.delete) { _, _ ->
viewModel.remove(controller.snapshot(), deleteFiles)
mode?.finish()
}
setNegativeButton(android.R.string.cancel, null)
}.show()
true
}

Expand Down Expand Up @@ -226,4 +239,15 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>(),
menu.findItem(R.id.action_remove)?.isVisible = canRemove
return super.onPrepareActionMode(controller, mode, menu)
}

override fun onDeleteChapterClick(item: DownloadItemModel, chapter: DownloadChapter) {
buildAlertDialog(this) {
setTitle(R.string.delete_chapter)
setMessage(getString(R.string.delete_chapter_confirm, chapter.name))
setPositiveButton(R.string.delete) { _, _ ->
viewModel.deleteChapter(item, chapter)
}
setNegativeButton(android.R.string.cancel, null)
}.show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.fragment.app.FragmentActivity
import io.github.landwarderer.futon.R
import io.github.landwarderer.futon.core.nav.router
import io.github.landwarderer.futon.core.ui.dialog.buildAlertDialog
import io.github.landwarderer.futon.core.ui.dialog.setCheckbox

class DownloadsMenuProvider(
private val activity: FragmentActivity,
Expand Down Expand Up @@ -49,12 +50,16 @@ class DownloadsMenuProvider(
}

private fun confirmRemoveCompleted() {
var deleteFiles = false
buildAlertDialog(activity, isCentered = true) {
setTitle(R.string.remove_completed)
setMessage(R.string.remove_completed_downloads_confirm)
setIcon(R.drawable.ic_clear_all)
setCheckbox(R.string.delete_downloaded_files, false) { _, isChecked ->
deleteFiles = isChecked
}
setNegativeButton(android.R.string.cancel, null)
setPositiveButton(R.string.clear) { _, _ -> viewModel.removeCompleted() }
setPositiveButton(R.string.clear) { _, _ -> viewModel.removeCompleted(deleteFiles) }
}.show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import io.github.landwarderer.futon.core.util.ext.MutableEventFlow
import io.github.landwarderer.futon.core.util.ext.calculateTimeAgo
import io.github.landwarderer.futon.core.util.ext.call
import io.github.landwarderer.futon.core.util.ext.isEmpty
import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug
import io.github.landwarderer.futon.download.domain.DownloadState
import io.github.landwarderer.futon.download.ui.list.chapters.DownloadChapter
import io.github.landwarderer.futon.download.ui.worker.DownloadWorker
Expand All @@ -27,6 +28,7 @@ import io.github.landwarderer.futon.list.ui.model.ListModel
import io.github.landwarderer.futon.list.ui.model.LoadingState
import io.github.landwarderer.futon.local.data.LocalMangaRepository
import io.github.landwarderer.futon.local.data.LocalStorageChanges
import io.github.landwarderer.futon.local.domain.DeleteLocalMangaUseCase
import io.github.landwarderer.futon.local.domain.EnforceStorageQuotaUseCase
import io.github.landwarderer.futon.local.domain.model.LocalManga
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -57,6 +59,7 @@ class DownloadsViewModel @Inject constructor(
@LocalStorageChanges private val localStorageChanges: MutableSharedFlow<LocalManga?>,
private val localMangaRepository: LocalMangaRepository,
private val enforceStorageQuotaUseCase: EnforceStorageQuotaUseCase,
private val deleteLocalMangaUseCase: DeleteLocalMangaUseCase,
) : BaseViewModel() {

val storageUsage = MutableStateFlow<EnforceStorageQuotaUseCase.StorageUsage?>(null)
Expand Down Expand Up @@ -165,24 +168,55 @@ class DownloadsViewModel @Inject constructor(
onActionDone.call(ReversibleAction(R.string.downloads_resumed, null))
}

fun remove(ids: Set<Long>) {
fun remove(ids: Set<Long>, deleteFiles: Boolean) {
launchJob(Dispatchers.IO) {
val snapshot = works.value ?: return@launchJob
val uuids = HashSet<UUID>(ids.size)
for (work in snapshot) {
if (work.id.mostSignificantBits in ids) {
uuids.add(work.id)
if (deleteFiles) {
val manga = work.manga ?: continue
runCatchingCancellable {
deleteLocalMangaUseCase(manga)
}.onFailure {
it.printStackTraceDebug("DownloadsViewModel::remove")
}
}
}
}
workScheduler.delete(uuids)
onActionDone.call(ReversibleAction(R.string.downloads_removed, null))
refreshStorageUsage()
}
}

fun removeCompleted() {
fun removeCompleted(deleteFiles: Boolean) {
launchJob(Dispatchers.IO) {
if (deleteFiles) {
val snapshot = works.value ?: return@launchJob
for (work in snapshot) {
if (work.workState.isFinished) {
val manga = work.manga ?: continue
runCatchingCancellable {
deleteLocalMangaUseCase(manga)
}.onFailure {
it.printStackTraceDebug("DownloadsViewModel::removeCompleted")
}
}
}
}
workScheduler.removeCompleted()
onActionDone.call(ReversibleAction(R.string.downloads_removed, null))
refreshStorageUsage()
}
}

fun deleteChapter(item: DownloadItemModel, chapter: DownloadChapter) {
val manga = item.manga ?: return
launchJob(Dispatchers.IO) {
localMangaRepository.deleteChapters(manga, setOf(chapter.id))
refreshStorageUsage()
}
}

Expand Down Expand Up @@ -322,6 +356,7 @@ class DownloadsViewModel @Inject constructor(
return chapters.mapNotNullTo(ArrayList(size)) {
if (chapterIds == null || it.id in chapterIds) {
DownloadChapter(
id = it.id,
number = it.numberString(),
name = it.name,
isDownloaded = it.id in localChapters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import io.github.landwarderer.futon.list.ui.ListModelDiffCallback
import io.github.landwarderer.futon.list.ui.model.ListModel

data class DownloadChapter(
val id: Long,
val number: String?,
val name: String,
val isDownloaded: Boolean,
) : ListModel {

override fun areItemsTheSame(other: ListModel): Boolean {
return other is DownloadChapter && other.name == name
return other is DownloadChapter && other.id == id
}

override fun getChangePayload(previousState: ListModel): Any? {
return if (previousState is DownloadChapter && previousState.name == name && previousState.number == number) {
return if (previousState is DownloadChapter && previousState.id == id && previousState.number == number) {
ListModelDiffCallback.PAYLOAD_PROGRESS_CHANGED
} else {
super.getChangePayload(previousState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ package io.github.landwarderer.futon.download.ui.list.chapters

import androidx.core.content.ContextCompat
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import androidx.core.view.isVisible
import io.github.landwarderer.futon.R
import io.github.landwarderer.futon.core.util.ext.drawableEnd
import io.github.landwarderer.futon.databinding.ItemChapterDownloadBinding

fun downloadChapterAD() = adapterDelegateViewBinding<DownloadChapter, DownloadChapter, ItemChapterDownloadBinding>(
fun downloadChapterAD(
onDeleteClick: (DownloadChapter) -> Unit,
) = adapterDelegateViewBinding<DownloadChapter, DownloadChapter, ItemChapterDownloadBinding>(
{ layoutInflater, parent -> ItemChapterDownloadBinding.inflate(layoutInflater, parent, false) },
) {

val iconDone = ContextCompat.getDrawable(context, R.drawable.ic_check)

binding.buttonDelete.setOnClickListener {
onDeleteClick(item)
}

bind {
binding.textViewNumber.text = item.number
binding.textViewTitle.text = item.name
binding.textViewTitle.drawableEnd = if (item.isDownloaded) iconDone else null
binding.buttonDelete.isVisible = item.isDownloaded
}
}
17 changes: 15 additions & 2 deletions app/src/main/res/layout/item_chapter_download.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@

<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="?android:listPreferredItemPaddingStart"
android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:drawablePadding="4dp"
android:ellipsize="end"
android:gravity="center_vertical"
Expand All @@ -39,4 +40,16 @@
tools:drawableEnd="@drawable/ic_check"
tools:text="@tools:sample/lorem[15]" />

<ImageButton
android:id="@+id/button_delete"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/delete"
android:visibility="gone"
app:srcCompat="@drawable/ic_delete"
app:tint="?colorControlNormal"
tools:visibility="visible" />

</LinearLayout>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@
<string name="no_thanks">No thanks</string>
<string name="cancel_all_downloads_confirm">All active downloads will be cancelled, partially downloaded data will be lost</string>
<string name="remove_completed_downloads_confirm">Your downloads history will be permanently deleted. No downloaded files will be affected</string>
<string name="remove_downloads_confirm">Remove selected downloads?</string>
<string name="delete_downloaded_files">Also delete downloaded files from storage</string>
<string name="delete_chapter">Delete chapter</string>
<string name="delete_chapter_confirm">Delete chapter \"%1$s\" from local storage?</string>
<string name="text_downloads_list_holder">You don\'t have any downloads</string>
<string name="downloads_resumed">Downloads have been resumed</string>
<string name="downloads_paused">Downloads have been paused</string>
Expand Down
Loading