Ability to start download paused
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.annotation.UiContext
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
|
||||||
|
object CommonAlertDialogs {
|
||||||
|
|
||||||
|
fun showDownloadConfirmation(
|
||||||
|
@UiContext context: Context,
|
||||||
|
onConfirmed: (startPaused: Boolean) -> Unit,
|
||||||
|
) = buildAlertDialog(context, isCentered = true) {
|
||||||
|
var startPaused = false
|
||||||
|
setTitle(R.string.save_manga)
|
||||||
|
setIcon(R.drawable.ic_download)
|
||||||
|
setMessage(R.string.save_manga_confirm)
|
||||||
|
setCheckbox(R.string.start_download, true) { _, isChecked ->
|
||||||
|
startPaused = !isChecked
|
||||||
|
}
|
||||||
|
setPositiveButton(R.string.save) { _, _ ->
|
||||||
|
onConfirmed(startPaused)
|
||||||
|
}
|
||||||
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
@@ -168,6 +168,7 @@ abstract class ChaptersPagesViewModel(
|
|||||||
downloadScheduler.schedule(
|
downloadScheduler.schedule(
|
||||||
manga = requireManga(),
|
manga = requireManga(),
|
||||||
chaptersIds = chaptersIds,
|
chaptersIds = chaptersIds,
|
||||||
|
isPaused = false,
|
||||||
isSilent = false,
|
isSilent = false,
|
||||||
)
|
)
|
||||||
onDownloadStarted.call(Unit)
|
onDownloadStarted.call(Unit)
|
||||||
|
|||||||
@@ -128,7 +128,11 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
val chaptersIds = inputData.getLongArray(CHAPTERS_IDS)?.takeUnless { it.isEmpty() }
|
val chaptersIds = inputData.getLongArray(CHAPTERS_IDS)?.takeUnless { it.isEmpty() }
|
||||||
val downloadedIds = getDoneChapters(manga)
|
val downloadedIds = getDoneChapters(manga)
|
||||||
return try {
|
return try {
|
||||||
withContext(PausingHandle()) {
|
val pausingHandle = PausingHandle()
|
||||||
|
if (inputData.getBoolean(START_PAUSED, false)) {
|
||||||
|
pausingHandle.pause()
|
||||||
|
}
|
||||||
|
withContext(pausingHandle) {
|
||||||
downloadMangaImpl(manga, chaptersIds, downloadedIds)
|
downloadMangaImpl(manga, chaptersIds, downloadedIds)
|
||||||
}
|
}
|
||||||
Result.success(currentState.toWorkData())
|
Result.success(currentState.toWorkData())
|
||||||
@@ -431,10 +435,16 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
private val settings: AppSettings,
|
private val settings: AppSettings,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun schedule(manga: Manga, chaptersIds: Collection<Long>?, isSilent: Boolean) {
|
suspend fun schedule(
|
||||||
|
manga: Manga,
|
||||||
|
chaptersIds: Collection<Long>?,
|
||||||
|
isPaused: Boolean,
|
||||||
|
isSilent: Boolean,
|
||||||
|
) {
|
||||||
dataRepository.storeManga(manga)
|
dataRepository.storeManga(manga)
|
||||||
val data = Data.Builder()
|
val data = Data.Builder()
|
||||||
.putLong(MANGA_ID, manga.id)
|
.putLong(MANGA_ID, manga.id)
|
||||||
|
.putBoolean(START_PAUSED, isPaused)
|
||||||
.putBoolean(IS_SILENT, isSilent)
|
.putBoolean(IS_SILENT, isSilent)
|
||||||
if (!chaptersIds.isNullOrEmpty()) {
|
if (!chaptersIds.isNullOrEmpty()) {
|
||||||
data.putLongArray(CHAPTERS_IDS, chaptersIds.toLongArray())
|
data.putLongArray(CHAPTERS_IDS, chaptersIds.toLongArray())
|
||||||
@@ -442,11 +452,15 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
scheduleImpl(listOf(data.build()))
|
scheduleImpl(listOf(data.build()))
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun schedule(manga: Collection<Manga>) {
|
suspend fun schedule(
|
||||||
|
manga: Collection<Manga>,
|
||||||
|
isPaused: Boolean,
|
||||||
|
) {
|
||||||
val data = manga.map {
|
val data = manga.map {
|
||||||
dataRepository.storeManga(it)
|
dataRepository.storeManga(it)
|
||||||
Data.Builder()
|
Data.Builder()
|
||||||
.putLong(MANGA_ID, it.id)
|
.putLong(MANGA_ID, it.id)
|
||||||
|
.putBoolean(START_PAUSED, isPaused)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
scheduleImpl(data)
|
scheduleImpl(data)
|
||||||
@@ -556,6 +570,7 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
const val MANGA_ID = "manga_id"
|
const val MANGA_ID = "manga_id"
|
||||||
const val CHAPTERS_IDS = "chapters"
|
const val CHAPTERS_IDS = "chapters"
|
||||||
const val IS_SILENT = "silent"
|
const val IS_SILENT = "silent"
|
||||||
|
const val START_PAUSED = "paused"
|
||||||
const val TAG = "download"
|
const val TAG = "download"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.koitharu.kotatsu.core.model.isLocal
|
|||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.prefs.ListMode
|
import org.koitharu.kotatsu.core.prefs.ListMode
|
||||||
import org.koitharu.kotatsu.core.ui.BaseFragment
|
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.CommonAlertDialogs
|
||||||
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.core.ui.list.FitHeightGridLayoutManager
|
import org.koitharu.kotatsu.core.ui.list.FitHeightGridLayoutManager
|
||||||
import org.koitharu.kotatsu.core.ui.list.FitHeightLinearLayoutManager
|
import org.koitharu.kotatsu.core.ui.list.FitHeightLinearLayoutManager
|
||||||
@@ -238,6 +239,7 @@ abstract class MangaListFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onFilterOptionClick(option: ListFilterOption) {
|
override fun onFilterOptionClick(option: ListFilterOption) {
|
||||||
|
selectionController?.clear()
|
||||||
(viewModel as? QuickFilterListener)?.toggleFilterOption(option)
|
(viewModel as? QuickFilterListener)?.toggleFilterOption(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,8 +324,11 @@ abstract class MangaListFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_save -> {
|
R.id.action_save -> {
|
||||||
viewModel.download(selectedItems)
|
val itemsSnapshot = selectedItems
|
||||||
|
CommonAlertDialogs.showDownloadConfirmation(context ?: return false) { startPaused ->
|
||||||
mode?.finish()
|
mode?.finish()
|
||||||
|
viewModel.download(itemsSnapshot, isPaused = startPaused)
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ abstract class MangaListViewModel(
|
|||||||
|
|
||||||
abstract fun onRetry()
|
abstract fun onRetry()
|
||||||
|
|
||||||
fun download(items: Set<Manga>) {
|
fun download(items: Set<Manga>, isPaused: Boolean) {
|
||||||
launchJob(Dispatchers.Default) {
|
launchJob(Dispatchers.Default) {
|
||||||
downloadScheduler.schedule(items)
|
downloadScheduler.schedule(items, isPaused)
|
||||||
onDownloadStarted.call(Unit)
|
onDownloadStarted.call(Unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.CommonAlertDialogs
|
||||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.core.ui.widgets.TipView
|
import org.koitharu.kotatsu.core.ui.widgets.TipView
|
||||||
@@ -184,8 +185,11 @@ class SearchActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_save -> {
|
R.id.action_save -> {
|
||||||
viewModel.download(collectSelectedItems())
|
val itemsSnapshot = collectSelectedItems()
|
||||||
|
CommonAlertDialogs.showDownloadConfirmation(this) { startPaused ->
|
||||||
mode?.finish()
|
mode?.finish()
|
||||||
|
viewModel.download(itemsSnapshot, isPaused = startPaused)
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,9 +109,9 @@ class SearchViewModel @Inject constructor(
|
|||||||
retryCounter.value += 1
|
retryCounter.value += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun download(items: Set<Manga>) {
|
fun download(items: Set<Manga>, isPaused: Boolean) {
|
||||||
launchJob(Dispatchers.Default) {
|
launchJob(Dispatchers.Default) {
|
||||||
downloadScheduler.schedule(items)
|
downloadScheduler.schedule(items, isPaused)
|
||||||
onDownloadStarted.call(Unit)
|
onDownloadStarted.call(Unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ class TrackWorker @AssistedInject constructor(
|
|||||||
downloadSchedulerLazy.get().schedule(
|
downloadSchedulerLazy.get().schedule(
|
||||||
manga = mangaUpdates.manga,
|
manga = mangaUpdates.manga,
|
||||||
chaptersIds = mangaUpdates.newChapters.mapToSet { it.id },
|
chaptersIds = mangaUpdates.newChapters.mapToSet { it.id },
|
||||||
|
isPaused = false,
|
||||||
isSilent = true,
|
isSilent = true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -738,4 +738,7 @@
|
|||||||
<string name="user_manual">User manual</string>
|
<string name="user_manual">User manual</string>
|
||||||
<string name="telegram_group">Telegram group</string>
|
<string name="telegram_group">Telegram group</string>
|
||||||
<string name="error_image_format">Unsupported image format: %s</string>
|
<string name="error_image_format">Unsupported image format: %s</string>
|
||||||
|
<string name="start_download">Start download</string>
|
||||||
|
<string name="save_manga_confirm">Save selected manga? This may consume traffic and disk space</string>
|
||||||
|
<string name="save_manga">Save manga</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user