mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 19:31:49 +01:00
The Downloads Update
Pending downloads can be move to the top or bottom of the queue with a menu button on the right side, they can also be cancelled Mass Migration now shows progress and total manga in the title Fixed the issue where deleted downloads using the old folder format said they weren't (they were) Fixed cancelled downloads not deleting the temp folder Changed the format of downloads yet again, now it's just chapter id and the name Added option to reorder pending downloads by newest or oldest chapter
This commit is contained in:
parent
b6e4869d30
commit
68c3d28b4b
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -203,13 +204,15 @@ class DownloadCache(
|
|||||||
* @param manga the manga of the chapter.
|
* @param manga the manga of the chapter.
|
||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun removeChapters(chapters: List<Chapter>, manga: Manga) {
|
fun removeChapters(chapters: List<Chapter>, manga: Manga, source: Source) {
|
||||||
val sourceDir = rootDir.files[manga.source] ?: return
|
val sourceDir = rootDir.files[manga.source] ?: return
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
||||||
for (chapter in chapters) {
|
for (chapter in chapters) {
|
||||||
val chapterDirName = provider.getChapterDirName(chapter)
|
val list = provider.getValidChapterDirNames(chapter)
|
||||||
if (chapterDirName in mangaDir.files) {
|
list.forEach {
|
||||||
mangaDir.files -= chapterDirName
|
if (it in mangaDir.files) {
|
||||||
|
mangaDir.files -= it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
*
|
*
|
||||||
* @param context the application context.
|
* @param context the application context.
|
||||||
*/
|
*/
|
||||||
class DownloadManager(context: Context) {
|
class DownloadManager(val context: Context) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sources manager.
|
* The sources manager.
|
||||||
@ -99,7 +99,12 @@ class DownloadManager(context: Context) {
|
|||||||
* @param downloads value to set the download queue to
|
* @param downloads value to set the download queue to
|
||||||
*/
|
*/
|
||||||
fun reorderQueue(downloads: List<Download>) {
|
fun reorderQueue(downloads: List<Download>) {
|
||||||
val wasPaused = downloader.isPaused()
|
val wasPaused = isPaused()
|
||||||
|
if (downloads.isEmpty()) {
|
||||||
|
DownloadService.stop(context)
|
||||||
|
downloader.queue.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
downloader.pause()
|
downloader.pause()
|
||||||
downloader.queue.clear()
|
downloader.queue.clear()
|
||||||
downloader.queue.addAll(downloads)
|
downloader.queue.addAll(downloads)
|
||||||
@ -108,6 +113,8 @@ class DownloadManager(context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isPaused() = downloader.isPaused()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells the downloader to enqueue the given list of chapters.
|
* Tells the downloader to enqueue the given list of chapters.
|
||||||
@ -175,7 +182,7 @@ class DownloadManager(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the directories of a list of downloaded chapters.
|
* Deletes the directories of a list of partially downloaded chapters.
|
||||||
*
|
*
|
||||||
* @param chapters the list of chapters to delete.
|
* @param chapters the list of chapters to delete.
|
||||||
* @param manga the manga of the chapters.
|
* @param manga the manga of the chapters.
|
||||||
@ -183,9 +190,9 @@ class DownloadManager(context: Context) {
|
|||||||
*/
|
*/
|
||||||
fun deleteChapters(chapters: List<Chapter>, manga: Manga, source: Source) {
|
fun deleteChapters(chapters: List<Chapter>, manga: Manga, source: Source) {
|
||||||
queue.remove(chapters)
|
queue.remove(chapters)
|
||||||
val chapterDirs = provider.findChapterDirs(chapters, manga, source)
|
val chapterDirs = provider.findChapterDirs(chapters, manga, source) + provider.findTempChapterDirs(chapters, manga, source)
|
||||||
chapterDirs.forEach { it.delete() }
|
chapterDirs.forEach { it.delete() }
|
||||||
cache.removeChapters(chapters, manga)
|
cache.removeChapters(chapters, manga, source)
|
||||||
if (cache.getDownloadCount(manga) == 0) { // Delete manga directory if empty
|
if (cache.getDownloadCount(manga) == 0) { // Delete manga directory if empty
|
||||||
chapterDirs.firstOrNull()?.parentFile?.delete()
|
chapterDirs.firstOrNull()?.parentFile?.delete()
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,19 @@ class DownloadProvider(private val context: Context) {
|
|||||||
return chapters.flatMap { getValidChapterDirNames(it) }.mapNotNull { mangaDir.findFile(it) }
|
return chapters.flatMap { getValidChapterDirNames(it) }.mapNotNull { mangaDir.findFile(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of downloaded directories for the chapters that exist.
|
||||||
|
*
|
||||||
|
* @param chapters the chapters to query.
|
||||||
|
* @param manga the manga of the chapter.
|
||||||
|
* @param source the source of the chapter.
|
||||||
|
*/
|
||||||
|
fun findTempChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): List<UniFile> {
|
||||||
|
val mangaDir = findMangaDir(manga, source) ?: return emptyList()
|
||||||
|
return chapters.mapNotNull { mangaDir.findFile("${getChapterDirName(it)}_tmp") }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the download directory name for a source.
|
* Returns the download directory name for a source.
|
||||||
*
|
*
|
||||||
@ -119,6 +132,16 @@ class DownloadProvider(private val context: Context) {
|
|||||||
* @param chapter the chapter to query.
|
* @param chapter the chapter to query.
|
||||||
*/
|
*/
|
||||||
fun getChapterDirName(chapter: Chapter): String {
|
fun getChapterDirName(chapter: Chapter): String {
|
||||||
|
return DiskUtil.buildValidFilename("${chapter.id} - ${chapter.name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the chapter directory name for a chapter (that used the scanlator
|
||||||
|
*
|
||||||
|
* @param chapter the chapter to query.
|
||||||
|
*/
|
||||||
|
//TODO: Delete this in due time. N2Self, merging that pr was a mistake
|
||||||
|
private fun getChapterDirNameWithScanlator(chapter: Chapter): String {
|
||||||
return DiskUtil.buildValidFilename("${chapter.id}_${chapter.scanlator}_${chapter.name}")
|
return DiskUtil.buildValidFilename("${chapter.id}_${chapter.scanlator}_${chapter.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,8 +153,8 @@ class DownloadProvider(private val context: Context) {
|
|||||||
fun getValidChapterDirNames(chapter: Chapter): List<String> {
|
fun getValidChapterDirNames(chapter: Chapter): List<String> {
|
||||||
return listOf(
|
return listOf(
|
||||||
getChapterDirName(chapter),
|
getChapterDirName(chapter),
|
||||||
|
|
||||||
// Legacy chapter directory name used in v0.8.4 and before
|
// Legacy chapter directory name used in v0.8.4 and before
|
||||||
|
getChapterDirNameWithScanlator(chapter),
|
||||||
DiskUtil.buildValidFilename(chapter.name)
|
DiskUtil.buildValidFilename(chapter.name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.download
|
package eu.kanade.tachiyomi.ui.download
|
||||||
|
|
||||||
|
import android.view.MenuItem
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,12 +14,13 @@ class DownloadAdapter(controller: DownloadController) : FlexibleAdapter<Download
|
|||||||
/**
|
/**
|
||||||
* Listener called when an item of the list is released.
|
* Listener called when an item of the list is released.
|
||||||
*/
|
*/
|
||||||
val onItemReleaseListener: OnItemReleaseListener = controller
|
val downloadItemListener: DownloadItemListener = controller
|
||||||
|
|
||||||
interface OnItemReleaseListener {
|
interface DownloadItemListener {
|
||||||
/**
|
/**
|
||||||
* Called when an item of the list is released.
|
* Called when an item of the list is released.
|
||||||
*/
|
*/
|
||||||
fun onItemReleased(position: Int)
|
fun onItemReleased(position: Int)
|
||||||
|
fun onMenuItemClick(position: Int, menuItem: MenuItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
@ -17,6 +18,8 @@ import kotlinx.android.synthetic.main.download_controller.*
|
|||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -25,7 +28,7 @@ import java.util.concurrent.TimeUnit
|
|||||||
* Uses R.layout.fragment_download_queue.
|
* Uses R.layout.fragment_download_queue.
|
||||||
*/
|
*/
|
||||||
class DownloadController : NucleusController<DownloadPresenter>(),
|
class DownloadController : NucleusController<DownloadPresenter>(),
|
||||||
DownloadAdapter.OnItemReleaseListener {
|
DownloadAdapter.DownloadItemListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter containing the active downloads.
|
* Adapter containing the active downloads.
|
||||||
@ -110,6 +113,9 @@ class DownloadController : NucleusController<DownloadPresenter>(),
|
|||||||
|
|
||||||
// Set clear button visibility.
|
// Set clear button visibility.
|
||||||
menu.findItem(R.id.clear_queue).isVisible = !presenter.downloadQueue.isEmpty()
|
menu.findItem(R.id.clear_queue).isVisible = !presenter.downloadQueue.isEmpty()
|
||||||
|
|
||||||
|
// Set reorder button visibility.
|
||||||
|
menu.findItem(R.id.reorder).isVisible = !presenter.downloadQueue.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
@ -124,6 +130,16 @@ class DownloadController : NucleusController<DownloadPresenter>(),
|
|||||||
DownloadService.stop(context)
|
DownloadService.stop(context)
|
||||||
presenter.clearQueue()
|
presenter.clearQueue()
|
||||||
}
|
}
|
||||||
|
R.id.newest, R.id.oldest -> {
|
||||||
|
val adapter = adapter ?: return false
|
||||||
|
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
|
||||||
|
.toMutableList()
|
||||||
|
if (item.itemId == R.id.newest)
|
||||||
|
items.reverse()
|
||||||
|
adapter.updateDataSet(items)
|
||||||
|
val downloads = items.mapNotNull { it.download }
|
||||||
|
presenter.reorder(downloads)
|
||||||
|
}
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -264,4 +280,36 @@ class DownloadController : NucleusController<DownloadPresenter>(),
|
|||||||
presenter.reorder(downloads)
|
presenter.reorder(downloads)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the menu item of a download is pressed
|
||||||
|
*
|
||||||
|
* @param position The position of the item
|
||||||
|
* @param menuItem The menu Item pressed
|
||||||
|
*/
|
||||||
|
override fun onMenuItemClick(position: Int, menuItem: MenuItem) {
|
||||||
|
when (menuItem.itemId) {
|
||||||
|
R.id.move_to_top, R.id.move_to_bottom -> {
|
||||||
|
val items = adapter?.currentItems?.toMutableList() ?: return
|
||||||
|
val item = items[position]
|
||||||
|
items.remove(item)
|
||||||
|
if (menuItem.itemId == R.id.move_to_top)
|
||||||
|
items.add(0, item)
|
||||||
|
else
|
||||||
|
items.add(item)
|
||||||
|
adapter?.updateDataSet(items)
|
||||||
|
val downloads = items.mapNotNull { it.download }
|
||||||
|
presenter.reorder(downloads)
|
||||||
|
}
|
||||||
|
R.id.cancel_download -> {
|
||||||
|
val download = adapter?.getItem(position)?.download ?: return
|
||||||
|
presenter.cancelDownload(download)
|
||||||
|
|
||||||
|
adapter?.removeItem(position)
|
||||||
|
val adapter = adapter ?: return
|
||||||
|
val downloads = (0 until adapter.itemCount).mapNotNull { adapter.getItem(it)?.download }
|
||||||
|
presenter.reorder(downloads)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package eu.kanade.tachiyomi.ui.download
|
package eu.kanade.tachiyomi.ui.download
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.PopupMenu
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
|
import eu.kanade.tachiyomi.util.getResourceColor
|
||||||
|
import eu.kanade.tachiyomi.util.setVectorCompat
|
||||||
import kotlinx.android.synthetic.main.download_item.*
|
import kotlinx.android.synthetic.main.download_item.*
|
||||||
|
import kotlinx.android.synthetic.main.download_item.migration_menu
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to hold the data of a download.
|
* Class used to hold the data of a download.
|
||||||
@ -12,10 +17,12 @@ import kotlinx.android.synthetic.main.download_item.*
|
|||||||
* @param view the inflated view for this holder.
|
* @param view the inflated view for this holder.
|
||||||
* @constructor creates a new download holder.
|
* @constructor creates a new download holder.
|
||||||
*/
|
*/
|
||||||
class DownloadHolder(view: View, val adapter: DownloadAdapter) : BaseFlexibleViewHolder(view, adapter) {
|
class DownloadHolder(private val view: View, val adapter: DownloadAdapter) :
|
||||||
|
BaseFlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDragHandleView(reorder)
|
setDragHandleView(reorder)
|
||||||
|
migration_menu.setOnClickListener { it.post { showPopupMenu(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var download: Download
|
private lateinit var download: Download
|
||||||
@ -44,6 +51,10 @@ class DownloadHolder(view: View, val adapter: DownloadAdapter) : BaseFlexibleVie
|
|||||||
notifyProgress()
|
notifyProgress()
|
||||||
notifyDownloadedPages()
|
notifyDownloadedPages()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
migration_menu.setVectorCompat(
|
||||||
|
R.drawable.ic_more_vert_black_24dp, view.context
|
||||||
|
.getResourceColor(R.attr.icon_color))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +79,34 @@ class DownloadHolder(view: View, val adapter: DownloadAdapter) : BaseFlexibleVie
|
|||||||
|
|
||||||
override fun onItemReleased(position: Int) {
|
override fun onItemReleased(position: Int) {
|
||||||
super.onItemReleased(position)
|
super.onItemReleased(position)
|
||||||
adapter.onItemReleaseListener.onItemReleased(position)
|
adapter.downloadItemListener.onItemReleased(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun showPopupMenu(view: View) {
|
||||||
|
val item = adapter.getItem(adapterPosition) ?: return
|
||||||
|
|
||||||
|
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||||
|
val popup = PopupMenu(view.context, view)
|
||||||
|
|
||||||
|
// Inflate our menu resource into the PopupMenu's Menu
|
||||||
|
popup.menuInflater.inflate(R.menu.download_single, popup.menu)
|
||||||
|
|
||||||
|
val download = item.download
|
||||||
|
|
||||||
|
popup.menu.findItem(R.id.move_to_top).isVisible = adapterPosition != 0
|
||||||
|
popup.menu.findItem(R.id.move_to_bottom).isVisible = adapterPosition != adapter
|
||||||
|
.itemCount - 1
|
||||||
|
|
||||||
|
|
||||||
|
// Set a listener so we are notified if a menu item is clicked
|
||||||
|
popup.setOnMenuItemClickListener { menuItem ->
|
||||||
|
adapter.downloadItemListener.onMenuItemClick(adapterPosition, menuItem)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally show the PopupMenu
|
||||||
|
popup.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,4 +65,9 @@ class DownloadPresenter : BasePresenter<DownloadController>() {
|
|||||||
downloadManager.reorderQueue(downloads)
|
downloadManager.reorderQueue(downloads)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun cancelDownload(download: Download) {
|
||||||
|
downloadManager.deleteChapters(listOf(download.chapter), download.manga,
|
||||||
|
download.source)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -26,7 +26,6 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.jakewharton.rxbinding.support.v4.view.pageSelections
|
import com.jakewharton.rxbinding.support.v4.view.pageSelections
|
||||||
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges
|
||||||
import com.jakewharton.rxbinding.view.visible
|
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
@ -469,7 +468,7 @@ class LibraryController(
|
|||||||
val showAll =
|
val showAll =
|
||||||
(selectedMangas.filter { (it as? LibraryManga)?.hide_title == true }).size == selectedMangas.size
|
(selectedMangas.filter { (it as? LibraryManga)?.hide_title == true }).size == selectedMangas.size
|
||||||
menu.findItem(R.id.action_hide_title)?.title = activity?.getString(
|
menu.findItem(R.id.action_hide_title)?.title = activity?.getString(
|
||||||
if (showAll) R.string.label_show_title else R.string.label_hide_title
|
if (showAll) R.string.action_show_title else R.string.action_hide_title
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,8 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
return resources?.getString(R.string.migration)
|
return resources?.getString(R.string.migration) + " (${adapter?.items?.count { it.manga
|
||||||
|
.migrationStatus != MigrationStatus.RUNNUNG }}/${adapter?.itemCount ?: 0})"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View) {
|
override fun onViewCreated(view: View) {
|
||||||
@ -240,6 +241,12 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updateCount() {
|
||||||
|
launchUI {
|
||||||
|
setTitle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|
||||||
|
@ -38,9 +38,11 @@ class MigrationProcessAdapter(
|
|||||||
fun enableButtons()
|
fun enableButtons()
|
||||||
fun removeManga(item: MigrationProcessItem)
|
fun removeManga(item: MigrationProcessItem)
|
||||||
fun noMigration()
|
fun noMigration()
|
||||||
|
fun updateCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sourceFinished() {
|
fun sourceFinished() {
|
||||||
|
menuItemListener.updateCount()
|
||||||
if (itemCount == 0) menuItemListener.noMigration()
|
if (itemCount == 0) menuItemListener.noMigration()
|
||||||
if (allMangasDone()) menuItemListener.enableButtons()
|
if (allMangasDone()) menuItemListener.enableButtons()
|
||||||
}
|
}
|
||||||
|
@ -1,60 +1,89 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/relativeLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingRight="@dimen/material_layout_keylines_screen_edge_margin"
|
android:paddingStart="0dp"
|
||||||
android:paddingTop="@dimen/material_component_lists_padding_above_list">
|
android:paddingTop="@dimen/material_component_lists_padding_above_list">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/reorder"
|
||||||
|
android:layout_width="@dimen/material_component_lists_single_line_with_avatar_height"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_gravity="start"
|
||||||
|
android:contentDescription="@string/action_reorganize_by"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:tint="?android:attr/textColorPrimary"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_reorder_grey_24dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/manga_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_toEndOf="@id/reorder"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.Body1"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/download_progress_text"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/reorder"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Manga title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chapter_title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_toEndOf="@id/reorder"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textAppearance="@style/TextAppearance.Regular.Caption"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/migration_menu"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/manga_title"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/manga_title"
|
||||||
|
tools:text="Chapter Title" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/download_progress"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/migration_menu"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/reorder"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/chapter_title" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/download_progress_text"
|
android:id="@+id/download_progress_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_toEndOf="@id/manga_title"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textAppearance="@style/TextAppearance.Regular.Caption.Hint"
|
android:textAppearance="@style/TextAppearance.Regular.Caption.Hint"
|
||||||
tools:text="(0/10)"/>
|
app:layout_constraintBottom_toBottomOf="@+id/manga_title"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/migration_menu"
|
||||||
<TextView
|
app:layout_constraintTop_toTopOf="@+id/manga_title"
|
||||||
android:id="@+id/manga_title"
|
tools:text="(0/10)" />
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toLeftOf="@id/download_progress_text"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:layout_marginStart="@dimen/material_component_lists_single_line_with_avatar_height"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.Body1"
|
|
||||||
tools:text="Manga title"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/chapter_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/manga_title"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
tools:text="Chapter Title"
|
|
||||||
android:layout_marginStart="@dimen/material_component_lists_single_line_with_avatar_height"
|
|
||||||
android:textAppearance="@style/TextAppearance.Regular.Caption"/>
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/download_progress"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/chapter_title"
|
|
||||||
android:layout_marginStart="@dimen/material_component_lists_single_line_with_avatar_height"
|
|
||||||
style="?android:attr/progressBarStyleHorizontal"/>
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/reorder"
|
android:id="@+id/migration_menu"
|
||||||
android:layout_width="@dimen/material_component_lists_single_line_with_avatar_height"
|
android:layout_width="44dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
android:layout_height="@dimen/material_component_lists_single_line_with_avatar_height"
|
android:layout_height="@dimen/material_component_lists_single_line_with_avatar_height"
|
||||||
android:layout_gravity="start"
|
android:layout_toEndOf="@id/download_progress_text"
|
||||||
android:scaleType="center"
|
android:contentDescription="@string/description_cover"
|
||||||
android:tint="?android:attr/textColorPrimary"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:srcCompat="@drawable/ic_reorder_grey_24dp" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_more_vert_black_24dp" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -19,4 +19,19 @@
|
|||||||
android:visible="false"
|
android:visible="false"
|
||||||
app:showAsAction="never"/>
|
app:showAsAction="never"/>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/reorder"
|
||||||
|
android:title="@string/action_reorganize_by"
|
||||||
|
android:visible="false"
|
||||||
|
app:showAsAction="never">
|
||||||
|
<menu>
|
||||||
|
<item
|
||||||
|
android:id="@+id/newest"
|
||||||
|
android:title="@string/action_newest"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/oldest"
|
||||||
|
android:title="@string/action_oldest"/>
|
||||||
|
</menu>
|
||||||
|
</item>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
11
app/src/main/res/menu/download_single.xml
Normal file
11
app/src/main/res/menu/download_single.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@+id/move_to_top"
|
||||||
|
android:title="@string/action_move_to_top" />
|
||||||
|
|
||||||
|
<item android:id="@+id/move_to_bottom"
|
||||||
|
android:title="@string/action_move_to_bottom" />
|
||||||
|
|
||||||
|
<item android:id="@+id/cancel_download"
|
||||||
|
android:title="@string/action_cancel" />
|
||||||
|
</menu>
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_reorganize"
|
android:id="@+id/action_reorganize"
|
||||||
android:title="@string/label_reorganize_by"
|
android:title="@string/action_reorganize_by"
|
||||||
app:showAsAction="never">
|
app:showAsAction="never">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
<item
|
||||||
@ -42,7 +42,7 @@
|
|||||||
android:title="@string/action_sort_alpha"/>
|
android:title="@string/action_sort_alpha"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_alpha_dsc"
|
android:id="@+id/action_alpha_dsc"
|
||||||
android:title="@string/label_alpha_reverse"/>
|
android:title="@string/action_alpha_reverse"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_update_asc"
|
android:id="@+id/action_update_asc"
|
||||||
android:title="@string/action_sort_last_updated"/>
|
android:title="@string/action_sort_last_updated"/>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/action_hide_title"
|
android:id="@+id/action_hide_title"
|
||||||
android:icon="@drawable/ic_swap_calls_white_24dp"
|
android:icon="@drawable/ic_swap_calls_white_24dp"
|
||||||
android:title="@string/label_hide_title"
|
android:title="@string/action_hide_title"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
@ -22,10 +22,6 @@
|
|||||||
<string name="label_selected">Selected: %1$d</string>
|
<string name="label_selected">Selected: %1$d</string>
|
||||||
<string name="label_backup">Backup</string>
|
<string name="label_backup">Backup</string>
|
||||||
<string name="label_migration">Source migration</string>
|
<string name="label_migration">Source migration</string>
|
||||||
<string name="label_reorganize_by">Reorder</string>
|
|
||||||
<string name="label_alpha_reverse">Alpha. (descending)</string>
|
|
||||||
<string name="label_hide_title">Hide title</string>
|
|
||||||
<string name="label_show_title">Show title</string>
|
|
||||||
<string name="label_extensions">Extensions</string>
|
<string name="label_extensions">Extensions</string>
|
||||||
<string name="label_extension_info">Extension info</string>
|
<string name="label_extension_info">Extension info</string>
|
||||||
<string name="label_help">Help</string>
|
<string name="label_help">Help</string>
|
||||||
@ -44,8 +40,6 @@
|
|||||||
<string name="action_sort_enabled">Enabled</string>
|
<string name="action_sort_enabled">Enabled</string>
|
||||||
<string name="action_sort_total">Total chapters</string>
|
<string name="action_sort_total">Total chapters</string>
|
||||||
<string name="action_sort_last_read">Last read</string>
|
<string name="action_sort_last_read">Last read</string>
|
||||||
<string name="action_sort_last_updated">Last updated</string>
|
|
||||||
<string name="action_sort_first_updated">First updated</string>
|
|
||||||
<string name="action_sort_drag_and_drop">Drag & Drop</string>
|
<string name="action_sort_drag_and_drop">Drag & Drop</string>
|
||||||
<string name="action_search">Search</string>
|
<string name="action_search">Search</string>
|
||||||
<string name="action_skip_manga">Don\'t migrate</string>
|
<string name="action_skip_manga">Don\'t migrate</string>
|
||||||
@ -75,7 +69,7 @@
|
|||||||
<string name="action_start">Start</string>
|
<string name="action_start">Start</string>
|
||||||
<string name="action_stop">Stop</string>
|
<string name="action_stop">Stop</string>
|
||||||
<string name="action_pause">Pause</string>
|
<string name="action_pause">Pause</string>
|
||||||
<string name="action_clear">Clear</string>
|
<string name="action_clear">Cancel all</string>
|
||||||
<string name="action_close">Close</string>
|
<string name="action_close">Close</string>
|
||||||
<string name="action_previous_chapter">Previous chapter</string>
|
<string name="action_previous_chapter">Previous chapter</string>
|
||||||
<string name="action_next_chapter">Next chapter</string>
|
<string name="action_next_chapter">Next chapter</string>
|
||||||
@ -111,6 +105,16 @@
|
|||||||
<string name="action_search_manually">Search manually</string>
|
<string name="action_search_manually">Search manually</string>
|
||||||
<string name="action_migrate_now">Migrate now</string>
|
<string name="action_migrate_now">Migrate now</string>
|
||||||
<string name="action_copy_now">Copy now</string>
|
<string name="action_copy_now">Copy now</string>
|
||||||
|
<string name="action_reorganize_by">Reorder</string>
|
||||||
|
<string name="action_alpha_reverse">Alpha. (descending)</string>
|
||||||
|
<string name="action_sort_last_updated">Last updated</string>
|
||||||
|
<string name="action_sort_first_updated">Last updated (desc.)</string>
|
||||||
|
<string name="action_hide_title">Hide title</string>
|
||||||
|
<string name="action_show_title">Show title</string>
|
||||||
|
<string name="action_newest">Newest</string>
|
||||||
|
<string name="action_oldest">Oldest</string>
|
||||||
|
<string name="action_move_to_top">Move to top</string>
|
||||||
|
<string name="action_move_to_bottom">Move to bottom</string>
|
||||||
|
|
||||||
<!-- Operations -->
|
<!-- Operations -->
|
||||||
<string name="deleting">Deleting…</string>
|
<string name="deleting">Deleting…</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user