Custom download chapter popup now replaced with range select

Long pressing the badge also starts range select
pull/3117/head
Jay 5 years ago
parent dad12ce216
commit b3cda93f3c

@ -21,7 +21,6 @@ import android.view.WindowManager
import android.webkit.WebView import android.webkit.WebView
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.view.GestureDetectorCompat import androidx.core.view.GestureDetectorCompat
@ -392,7 +391,8 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
val duration = resources.getInteger(android.R.integer.config_mediumAnimTime) * scale val duration = resources.getInteger(android.R.integer.config_mediumAnimTime) * scale
delay(duration.toLong()) delay(duration.toLong())
delay(100) delay(100)
window?.statusBarColor = ColorUtils.setAlphaComponent(getResourceColor(android.R.attr if (Color.alpha(window?.statusBarColor ?: Color.BLACK) >= 255)
window?.statusBarColor = ColorUtils.setAlphaComponent(getResourceColor(android.R.attr
.colorBackground), 175) .colorBackground), 175)
} }
super.onSupportActionModeFinished(mode) super.onSupportActionModeFinished(mode)

@ -27,6 +27,9 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
@ -51,6 +54,7 @@ import com.bumptech.glide.signature.ObjectKey
import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.SelectableAdapter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
@ -68,6 +72,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.BaseController import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog
import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.library.LibraryController
@ -76,7 +81,6 @@ import eu.kanade.tachiyomi.ui.main.SearchActivity
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterMatHolder import eu.kanade.tachiyomi.ui.manga.chapter.ChapterMatHolder
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter
import eu.kanade.tachiyomi.ui.manga.chapter.DownloadCustomChaptersDialog
import eu.kanade.tachiyomi.ui.manga.info.EditMangaDialog import eu.kanade.tachiyomi.ui.manga.info.EditMangaDialog
import eu.kanade.tachiyomi.ui.manga.track.TrackItem import eu.kanade.tachiyomi.ui.manga.track.TrackItem
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
@ -101,12 +105,12 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
class MangaDetailsController : BaseController, open class MangaDetailsController : BaseController,
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener, FlexibleAdapter.OnItemLongClickListener,
ActionMode.Callback,
ChaptersAdapter.MangaHeaderInterface, ChaptersAdapter.MangaHeaderInterface,
ChangeMangaCategoriesDialog.Listener, ChangeMangaCategoriesDialog.Listener,
DownloadCustomChaptersDialog.Listener,
NoToolbarElevationController { NoToolbarElevationController {
constructor(manga: Manga?, constructor(manga: Manga?,
@ -145,11 +149,18 @@ class MangaDetailsController : BaseController,
val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false) val fromCatalogue = args.getBoolean(FROM_CATALOGUE_EXTRA, false)
var coverDrawable:Drawable? = null var coverDrawable:Drawable? = null
var trackingBottomSheet: TrackingBottomSheet? = null var trackingBottomSheet: TrackingBottomSheet? = null
var startingDLChapterPos:Int? = null
/** /**
* Adapter containing a list of chapters. * Adapter containing a list of chapters.
*/ */
private var adapter: ChaptersAdapter? = null private var adapter: ChaptersAdapter? = null
/**
* Action mode for selections.
*/
private var actionMode: ActionMode? = null
// Hold a reference to the current animator, // Hold a reference to the current animator,
// so that it can be canceled mid-way. // so that it can be canceled mid-way.
private var currentAnimator: Animator? = null private var currentAnimator: Animator? = null
@ -209,6 +220,13 @@ class MangaDetailsController : BaseController,
val atTop = !recycler.canScrollVertically(-1) val atTop = !recycler.canScrollVertically(-1)
if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) { if ((!atTop && !toolbarIsColored) || (atTop && toolbarIsColored)) {
toolbarIsColored = !atTop toolbarIsColored = !atTop
val isCurrentController =
router?.backstack?.lastOrNull()?.controller() == this@MangaDetailsController
if (isCurrentController) setTitle()
if (actionMode != null) {
(activity as MainActivity).toolbar.setBackgroundColor(Color.TRANSPARENT)
return
}
val color = val color =
coverColor ?: activity!!.getResourceColor(android.R.attr.colorPrimary) coverColor ?: activity!!.getResourceColor(android.R.attr.colorPrimary)
val colorFrom = val colorFrom =
@ -230,9 +248,6 @@ class MangaDetailsController : BaseController,
activity?.window?.statusBarColor = (animator.animatedValue as Int) activity?.window?.statusBarColor = (animator.animatedValue as Int)
} }
colorAnimator?.start() colorAnimator?.start()
val isCurrentController =
router?.backstack?.lastOrNull()?.controller() == this@MangaDetailsController
if (isCurrentController) setTitle()
} }
} }
}) })
@ -310,11 +325,10 @@ class MangaDetailsController : BaseController,
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type) super.onChangeStarted(handler, type)
if (type == ControllerChangeType.PUSH_ENTER || type == ControllerChangeType.POP_ENTER) { if (type == ControllerChangeType.PUSH_ENTER || type == ControllerChangeType.POP_ENTER) {
if (type == ControllerChangeType.POP_ENTER) setStatusBar()
return
(activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT) (activity as MainActivity).appbar.setBackgroundColor(Color.TRANSPARENT)
(activity as MainActivity).toolbar.setBackgroundColor(Color.TRANSPARENT) (activity as MainActivity).toolbar.setBackgroundColor(activity?.window?.statusBarColor
activity?.window?.statusBarColor = Color.TRANSPARENT ?: Color.TRANSPARENT)
} }
else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) { else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) {
if (router.backstack.lastOrNull()?.controller() is DialogController) if (router.backstack.lastOrNull()?.controller() is DialogController)
@ -349,7 +363,6 @@ class MangaDetailsController : BaseController,
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
} }
fun updateChapters(chapters: List<ChapterItem>) { fun updateChapters(chapters: List<ChapterItem>) {
swipe_refresh?.isRefreshing = presenter.isLoading swipe_refresh?.isRefreshing = presenter.isLoading
if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) { if (presenter.chapters.isEmpty() && fromCatalogue && !presenter.hasRequested) {
@ -365,6 +378,32 @@ class MangaDetailsController : BaseController,
override fun onItemClick(view: View?, position: Int): Boolean { override fun onItemClick(view: View?, position: Int): Boolean {
val chapter = adapter?.getItem(position)?.chapter ?: return false val chapter = adapter?.getItem(position)?.chapter ?: return false
if (chapter.isHeader) return false if (chapter.isHeader) return false
if (actionMode != null) {
if (startingDLChapterPos == null) {
adapter?.addSelection(position)
(recycler.findViewHolderForAdapterPosition(position) as? BaseFlexibleViewHolder)
?.toggleActivation()
startingDLChapterPos = position
actionMode?.invalidate()
}
else {
val startingPosition = startingDLChapterPos ?: return false
var chapterList = listOf<ChapterItem>()
when {
startingPosition > position ->
chapterList = presenter.chapters.subList(position - 1, startingPosition)
startingPosition <= position ->
chapterList = presenter.chapters.subList(startingPosition - 1, position)
}
downloadChapters(chapterList)
adapter?.removeSelection(startingPosition)
(recycler.findViewHolderForAdapterPosition(startingPosition) as? BaseFlexibleViewHolder)
?.toggleActivation()
startingDLChapterPos = null
destroyActionModeIfNeeded()
}
return false
}
openChapter(chapter) openChapter(chapter)
return false return false
} }
@ -551,7 +590,7 @@ class MangaDetailsController : BaseController,
R.id.download_next_5 -> presenter.getUnreadChaptersSorted().take(5) R.id.download_next_5 -> presenter.getUnreadChaptersSorted().take(5)
R.id.download_next_10 -> presenter.getUnreadChaptersSorted().take(10) R.id.download_next_10 -> presenter.getUnreadChaptersSorted().take(10)
R.id.download_custom -> { R.id.download_custom -> {
showCustomDownloadDialog() createActionModeIfNeeded()
return return
} }
R.id.download_unread -> presenter.chapters.filter { !it.read } R.id.download_unread -> presenter.chapters.filter { !it.read }
@ -669,15 +708,9 @@ class MangaDetailsController : BaseController,
} }
} }
private fun showCustomDownloadDialog() { override fun startDownloadRange(position: Int) {
DownloadCustomChaptersDialog(this, presenter.chapters.size).showDialog(router) createActionModeIfNeeded()
} onItemClick(null, position)
override fun downloadCustomChapters(amount: Int) {
val chaptersToDownload = presenter.getUnreadChaptersSorted().take(amount)
if (chaptersToDownload.isNotEmpty()) {
downloadChapters(chaptersToDownload)
}
} }
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -903,6 +936,61 @@ class MangaDetailsController : BaseController,
trackingBottomSheet?.onSearchResultsError(error) trackingBottomSheet?.onSearchResultsError(error)
} }
/**
* Creates the action mode if it's not created already.
*/
private fun createActionModeIfNeeded() {
if (actionMode == null) {
actionMode = (activity as AppCompatActivity).startSupportActionMode(this)
(activity as MainActivity).toolbar.setBackgroundColor(Color.TRANSPARENT)
val view = activity?.window?.currentFocus ?: return
val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
?: return
imm.hideSoftInputFromWindow(view.windowToken, 0)
if (adapter?.mode != SelectableAdapter.Mode.MULTI) {
adapter?.mode = SelectableAdapter.Mode.MULTI
}
}
}
/**
* Destroys the action mode.
*/
private fun destroyActionModeIfNeeded() {
actionMode?.finish()
}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
return true
}
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
return true
}
override fun onDestroyActionMode(mode: ActionMode?) {
actionMode = null
setStatusBar()
startingDLChapterPos = null
adapter?.mode = SelectableAdapter.Mode.IDLE
adapter?.clearSelection()
return
}
private fun setStatusBar() {
activity?.window?.statusBarColor = if (toolbarIsColored) {
val translucentColor = ColorUtils.setAlphaComponent(coverColor ?: Color.TRANSPARENT, 175)
(activity as MainActivity).toolbar.setBackgroundColor(translucentColor)
translucentColor
} else Color.TRANSPARENT
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
mode?.title = view?.context?.getString(if (startingDLChapterPos == null)
R.string.select_start_chapter else R.string.select_end_chapter)
return false
}
override fun zoomImageFromThumb(thumbView: View) { override fun zoomImageFromThumb(thumbView: View) {
// If there's an animation in progress, cancel it immediately and proceed with this one. // If there's an animation in progress, cancel it immediately and proceed with this one.
currentAnimator?.cancel() currentAnimator?.cancel()
@ -1040,9 +1128,5 @@ class MangaDetailsController : BaseController,
const val FROM_CATALOGUE_EXTRA = "from_catalogue" const val FROM_CATALOGUE_EXTRA = "from_catalogue"
const val MANGA_EXTRA = "manga" const val MANGA_EXTRA = "manga"
const val INFO_CONTROLLER = 0
const val CHAPTERS_CONTROLLER = 1
const val TRACK_CONTROLLER = 2
} }
} }

@ -32,12 +32,10 @@ class MangaHeaderHolder(
startExpanded: Boolean startExpanded: Boolean
) : MangaChapterHolder(view, adapter) { ) : MangaChapterHolder(view, adapter) {
init { init {
start_reading_button.setOnClickListener { adapter.coverListener?.readNextChapter() } start_reading_button.setOnClickListener { adapter.coverListener.readNextChapter() }
top_view.updateLayoutParams<ConstraintLayout.LayoutParams> { top_view.updateLayoutParams<ConstraintLayout.LayoutParams> {
height = adapter.coverListener?.topCoverHeight() ?: 0 height = adapter.coverListener.topCoverHeight()
} }
more_button.setOnClickListener { expandDesc() } more_button.setOnClickListener { expandDesc() }
manga_summary.setOnClickListener { expandDesc() } manga_summary.setOnClickListener { expandDesc() }
@ -48,30 +46,30 @@ class MangaHeaderHolder(
more_button_group.visible() more_button_group.visible()
} }
manga_genres_tags.setOnTagClickListener { manga_genres_tags.setOnTagClickListener {
adapter.coverListener?.tagClicked(it) adapter.coverListener.tagClicked(it)
} }
filter_button.setOnClickListener { adapter.coverListener?.showChapterFilter() } filter_button.setOnClickListener { adapter.coverListener.showChapterFilter() }
filters_text.setOnClickListener { adapter.coverListener?.showChapterFilter() } filters_text.setOnClickListener { adapter.coverListener.showChapterFilter() }
chapters_title.setOnClickListener { adapter.coverListener?.showChapterFilter() } chapters_title.setOnClickListener { adapter.coverListener.showChapterFilter() }
webview_button.setOnClickListener { adapter.coverListener?.openInWebView() } webview_button.setOnClickListener { adapter.coverListener.openInWebView() }
share_button.setOnClickListener { adapter.coverListener?.prepareToShareManga() } share_button.setOnClickListener { adapter.coverListener.prepareToShareManga() }
favorite_button.setOnClickListener { favorite_button.setOnClickListener {
adapter.coverListener?.favoriteManga(false) adapter.coverListener.favoriteManga(false)
} }
favorite_button.setOnLongClickListener { favorite_button.setOnLongClickListener {
adapter.coverListener?.favoriteManga(true) adapter.coverListener.favoriteManga(true)
true true
} }
manga_full_title.setOnLongClickListener { manga_full_title.setOnLongClickListener {
adapter.coverListener?.copyToClipboard(manga_full_title.text.toString(), R.string.manga_info_full_title_label) adapter.coverListener.copyToClipboard(manga_full_title.text.toString(), R.string.manga_info_full_title_label)
true true
} }
manga_author.setOnLongClickListener { manga_author.setOnLongClickListener {
adapter.coverListener?.copyToClipboard(manga_author.text.toString(), R.string.manga_info_author_label) adapter.coverListener.copyToClipboard(manga_author.text.toString(), R.string.manga_info_author_label)
true true
} }
manga_cover.setOnClickListener { adapter.coverListener?.zoomImageFromThumb(cover_card) } manga_cover.setOnClickListener { adapter.coverListener.zoomImageFromThumb(cover_card) }
track_button.setOnClickListener { adapter.coverListener?.showTrackingSheet() } track_button.setOnClickListener { adapter.coverListener.showTrackingSheet() }
if (startExpanded) if (startExpanded)
expandDesc() expandDesc()
} }

@ -41,7 +41,7 @@ class ChapterItem(val chapter: Chapter, val manga: Manga) :
} }
override fun isSelectable(): Boolean { override fun isSelectable(): Boolean {
return chapter.isHeader return !chapter.isHeader
} }
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaChapterHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): MangaChapterHolder {

@ -20,17 +20,17 @@ class ChapterMatHolder(
) : MangaChapterHolder(view, adapter) { ) : MangaChapterHolder(view, adapter) {
init { init {
// We need to post a Runnable to show the popup to make sure that the PopupMenu is
// correctly positioned. The reason being that the view may change position before the
// PopupMenu is shown.
//chapter_menu.setOnClickListener { it.post { showPopupMenu(it) } }
download_button.setOnClickListener { downloadOrRemoveMenu() } download_button.setOnClickListener { downloadOrRemoveMenu() }
download_button.setOnLongClickListener {
adapter.coverListener.startDownloadRange(adapterPosition)
true
}
} }
private fun downloadOrRemoveMenu() { private fun downloadOrRemoveMenu() {
val chapter = adapter.getItem(adapterPosition) ?: return val chapter = adapter.getItem(adapterPosition) ?: return
if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) { if (chapter.status == Download.NOT_DOWNLOADED || chapter.status == Download.ERROR) {
adapter.coverListener?.downloadChapter(adapterPosition) adapter.coverListener.downloadChapter(adapterPosition)
} else { } else {
download_button.post { download_button.post {
// Create a PopupMenu, giving it the clicked view for an anchor // Create a PopupMenu, giving it the clicked view for an anchor
@ -46,7 +46,7 @@ class ChapterMatHolder(
// Set a listener so we are notified if a menu item is clicked // Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { _ -> popup.setOnMenuItemClickListener { _ ->
adapter.coverListener?.downloadChapter(adapterPosition) adapter.coverListener.downloadChapter(adapterPosition)
true true
} }

@ -1,14 +1,13 @@
package eu.kanade.tachiyomi.ui.manga.chapter package eu.kanade.tachiyomi.ui.manga.chapter
import android.content.Context import android.content.Context
import android.view.MenuItem
import android.view.View import android.view.View
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
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.ui.base.controller.BaseController import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
import eu.kanade.tachiyomi.ui.manga.MangaDetailsPresenter import eu.kanade.tachiyomi.ui.manga.MangaDetailsPresenter
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
@ -18,7 +17,7 @@ import java.text.DecimalFormat
import java.text.DecimalFormatSymbols import java.text.DecimalFormatSymbols
class ChaptersAdapter( class ChaptersAdapter(
val controller: BaseController, val controller: MangaDetailsController,
context: Context context: Context
) : FlexibleAdapter<ChapterItem>(null, controller, true) { ) : FlexibleAdapter<ChapterItem>(null, controller, true) {
@ -26,8 +25,7 @@ class ChaptersAdapter(
var items: List<ChapterItem> = emptyList() var items: List<ChapterItem> = emptyList()
val menuItemListener: OnMenuItemClickListener? = controller as? OnMenuItemClickListener val coverListener: MangaHeaderInterface = controller
val coverListener: MangaHeaderInterface? = controller as? MangaHeaderInterface
val readColor = context.getResourceColor(android.R.attr.textColorHint) val readColor = context.getResourceColor(android.R.attr.textColorHint)
@ -54,10 +52,6 @@ class ChaptersAdapter(
SecureActivityDelegate.promptLockIfNeeded(activity) SecureActivityDelegate.promptLockIfNeeded(activity)
} }
interface OnMenuItemClickListener {
fun onMenuItemClick(position: Int, item: MenuItem)
}
interface MangaHeaderInterface { interface MangaHeaderInterface {
fun coverColor(): Int? fun coverColor(): Int?
fun mangaPresenter(): MangaDetailsPresenter fun mangaPresenter(): MangaDetailsPresenter
@ -72,5 +66,6 @@ class ChaptersAdapter(
fun copyToClipboard(content: String, label: Int) fun copyToClipboard(content: String, label: Int)
fun zoomImageFromThumb(thumbView: View) fun zoomImageFromThumb(thumbView: View)
fun showTrackingSheet() fun showTrackingSheet()
fun startDownloadRange(position: Int)
} }
} }

@ -1,76 +0,0 @@
package eu.kanade.tachiyomi.ui.manga.chapter
import android.app.Dialog
import android.os.Bundle
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.bluelinelabs.conductor.Controller
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.widget.DialogCustomDownloadView
/**
* Dialog used to let user select amount of chapters to download.
*/
class DownloadCustomChaptersDialog<T> : DialogController
where T : Controller, T : DownloadCustomChaptersDialog.Listener {
/**
* Maximum number of chapters to download in download chooser.
*/
private val maxChapters: Int
/**
* Initialize dialog.
* @param maxChapters maximal number of chapters that user can download.
*/
constructor(target: T, maxChapters: Int) : super(Bundle().apply {
// Add maximum number of chapters to download value to bundle.
putInt(KEY_ITEM_MAX, maxChapters)
}) {
targetController = target
this.maxChapters = maxChapters
}
/**
* Restore dialog.
* @param bundle bundle containing data from state restore.
*/
@Suppress("unused")
constructor(bundle: Bundle) : super(bundle) {
// Get maximum chapters to download from bundle
val maxChapters = bundle.getInt(KEY_ITEM_MAX, 0)
this.maxChapters = maxChapters
}
/**
* Called when dialog is being created.
*/
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val activity = activity!!
// Initialize view that lets user select number of chapters to download.
val view = DialogCustomDownloadView(activity).apply {
setMinMax(0, maxChapters)
}
// Build dialog.
// when positive dialog is pressed call custom listener.
return MaterialDialog(activity)
.title(R.string.custom_download)
.customView(view = view, scrollable = true)
.positiveButton(android.R.string.ok) {
(targetController as? Listener)?.downloadCustomChapters(view.amount)
}
.negativeButton(android.R.string.cancel)
}
interface Listener {
fun downloadCustomChapters(amount: Int)
}
private companion object {
// Key to retrieve max chapters from bundle on process death.
const val KEY_ITEM_MAX = "DownloadCustomChaptersDialog.int.maxChapters"
}
}

@ -2,13 +2,14 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/chapter_layout"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectable_list_drawable"> android:background="?attr/selectable_list_drawable">
<TextView <TextView
android:id="@+id/chapter_title" android:id="@+id/chapter_title"
style="@style/TextAppearance.Regular.Body1" style="@style/TextAppearance.MaterialComponents.Body2"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@ -23,7 +24,7 @@
<TextView <TextView
android:id="@+id/chapter_scanlator" android:id="@+id/chapter_scanlator"
style="@style/TextAppearance.Regular.Caption.Hint" style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"

@ -16,13 +16,7 @@
<menu> <menu>
<item <item
android:id="@+id/download_next" android:id="@+id/download_next"
android:title="@string/download_1" /> android:title="@string/download_first" />
<item
android:id="@+id/download_next_5"
android:title="@string/download_5" />
<item
android:id="@+id/download_next_10"
android:title="@string/download_10" />
<item <item
android:id="@+id/download_custom" android:id="@+id/download_custom"
android:title="@string/download_custom" /> android:title="@string/download_custom" />

@ -524,6 +524,8 @@
<string name="mark_all_as_read_message">Mark all chapters as read?</string> <string name="mark_all_as_read_message">Mark all chapters as read?</string>
<string name="remove_from_library">Remove from library</string> <string name="remove_from_library">Remove from library</string>
<string name="all_caught_up">All caught up</string> <string name="all_caught_up">All caught up</string>
<string name="select_start_chapter">Select starting chapter</string>
<string name="select_end_chapter">Select ending chapter</string>
<!-- Manga chapters fragment --> <!-- Manga chapters fragment -->
<string name="start_reading">Start reading</string> <string name="start_reading">Start reading</string>
@ -549,11 +551,12 @@
<string name="manga_download">Download</string> <string name="manga_download">Download</string>
<string name="custom_download">Download custom amount</string> <string name="custom_download">Download custom amount</string>
<string name="download_1">Next chapter</string> <string name="download_1">Next chapter</string>
<string name="download_first">First unread chapter</string>
<string name="download_5">Next 5 chapters</string> <string name="download_5">Next 5 chapters</string>
<string name="download_10">Next 10 chapters</string> <string name="download_10">Next 10 chapters</string>
<string name="download_custom">Custom</string> <string name="download_custom">Custom range</string>
<string name="download_all">All</string> <string name="download_all">All chapters</string>
<string name="download_unread">Unread</string> <string name="download_unread">All unread chapters</string>
<string name="confirm_delete_chapters">Are you sure you want to delete selected chapters?</string> <string name="confirm_delete_chapters">Are you sure you want to delete selected chapters?</string>
<plurals name="confirm_migration"> <plurals name="confirm_migration">
<item quantity="one">Migrate %1$d%2$s manga?</item> <item quantity="one">Migrate %1$d%2$s manga?</item>
@ -743,5 +746,4 @@
<string name="sort_by_chapter_number">Sort by chapter number</string> <string name="sort_by_chapter_number">Sort by chapter number</string>
<string name="newest_first">Newest to oldest</string> <string name="newest_first">Newest to oldest</string>
<string name="oldest_first">Oldest to newest</string> <string name="oldest_first">Oldest to newest</string>
</resources> </resources>

Loading…
Cancel
Save