mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-09 19:55:11 +01:00
New fast scroller used on chapter list
Scrolls by volume now Updated to jsoup 1.13.1 since there was some errors with 1.12.2
This commit is contained in:
parent
21953424c0
commit
4d8340a0c3
@ -148,7 +148,7 @@ dependencies {
|
||||
implementation("com.github.inorichi:unifile:e9ee588")
|
||||
|
||||
// HTML parser
|
||||
implementation("org.jsoup:jsoup:1.12.2")
|
||||
implementation("org.jsoup:jsoup:1.13.1")
|
||||
|
||||
// Job scheduling
|
||||
implementation("com.evernote:android-job:1.4.2")
|
||||
|
@ -49,6 +49,7 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.fetchMangaDetailsAsync
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.system.sendLocalBroadcast
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -286,7 +287,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
|
||||
*/
|
||||
suspend fun restoreMangaFetch(source: Source, manga: Manga): Manga {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val networkManga = source.fetchMangaDetails(manga).toBlocking().single()
|
||||
val networkManga = source.fetchMangaDetailsAsync(manga)!!
|
||||
manga.copyFrom(networkManga)
|
||||
manga.favorite = true
|
||||
manga.initialized = true
|
||||
|
@ -48,11 +48,17 @@ interface Source {
|
||||
fun fetchPageList(chapter: SChapter): Observable<List<Page>>
|
||||
}
|
||||
|
||||
suspend fun Source.fetchMangaDetails(manga: SManga): SManga? {
|
||||
suspend fun Source.fetchMangaDetailsAsync(manga: SManga): SManga? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
fetchMangaDetails(manga).toBlocking().single()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Source.fetchChapterListAsync(manga: SManga): List<SChapter>? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
fetchChapterList(manga).toBlocking().single()
|
||||
}
|
||||
}
|
||||
|
||||
fun Source.icon(): Drawable? =
|
||||
Injekt.get<ExtensionManager>().getAppIconForSource(this)
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.library
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
@ -67,11 +68,8 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||
import kotlinx.android.synthetic.main.filter_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.library_grid_recycler.*
|
||||
import kotlinx.android.synthetic.main.library_grid_recycler.recycler
|
||||
import kotlinx.android.synthetic.main.library_list_controller.*
|
||||
import kotlinx.android.synthetic.main.library_list_controller.swipe_refresh
|
||||
import kotlinx.android.synthetic.main.main_activity.*
|
||||
import kotlinx.android.synthetic.main.recents_controller.*
|
||||
import kotlinx.coroutines.delay
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@ -199,9 +197,8 @@ class LibraryController(
|
||||
context, R.drawable.fast_scroll_background
|
||||
) else null
|
||||
fast_scroller.textColor = ColorStateList.valueOf(
|
||||
context.getResourceColor(
|
||||
if (!alwaysShowScroller) android.R.attr.textColorPrimaryInverse else android.R.attr.textColorPrimary
|
||||
)
|
||||
if (!alwaysShowScroller) Color.WHITE
|
||||
else context.getResourceColor(android.R.attr.textColorPrimary)
|
||||
)
|
||||
fast_scroller.iconColor = fast_scroller.textColor
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class MangaDetailsAdapter(
|
||||
|
||||
private var isAnimating = false
|
||||
val delegate: MangaDetailsInterface = controller
|
||||
val presenter = controller.presenter
|
||||
|
||||
val readColor = context.getResourceColor(android.R.attr.textColorHint)
|
||||
|
||||
@ -67,6 +68,104 @@ class MangaDetailsAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
fun getSectionText(position: Int): String? {
|
||||
val chapter = getItem(position) as? ChapterItem ?: return null
|
||||
if (position == itemCount - 1) return "-"
|
||||
return when (presenter.scrollType) {
|
||||
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS ->
|
||||
presenter.getGroupNumber(chapter)?.toString() ?: "*"
|
||||
MangaDetailsPresenter.HUNDREDS_OF_CHAPTERS ->
|
||||
if (chapter.chapter_number < 0) "*"
|
||||
else (chapter.chapter_number / 100).toInt().toString()
|
||||
MangaDetailsPresenter.TENS_OF_CHAPTERS ->
|
||||
if (chapter.chapter_number < 0) "*"
|
||||
else (chapter.chapter_number / 10).toInt().toString()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun getFullText(position: Int): String {
|
||||
val chapter =
|
||||
getItem(position) as? ChapterItem ?: return recyclerView.context.getString(R.string.top)
|
||||
if (position == itemCount - 1) return recyclerView.context.getString(R.string.bottom)
|
||||
return when (val scrollType = presenter.scrollType) {
|
||||
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS -> {
|
||||
val volume = presenter.getGroupNumber(chapter)
|
||||
if (volume != null) recyclerView.context.getString(
|
||||
if (scrollType == MangaDetailsPresenter.MULTIPLE_SEASONS) R.string.season_x
|
||||
else R.string.volume_x, volume)
|
||||
else recyclerView.context.getString(R.string.unknown)
|
||||
}
|
||||
MangaDetailsPresenter.HUNDREDS_OF_CHAPTERS -> recyclerView.context.getString(
|
||||
R.string.chapters_x, get100sRange(
|
||||
chapter.chapter_number
|
||||
)
|
||||
)
|
||||
MangaDetailsPresenter.TENS_OF_CHAPTERS -> recyclerView.context.getString(
|
||||
R.string.chapters_x, get10sRange(
|
||||
chapter.chapter_number
|
||||
)
|
||||
)
|
||||
else -> recyclerView.context.getString(R.string.unknown)
|
||||
}
|
||||
}
|
||||
|
||||
private fun get100sRange(value: Float): String {
|
||||
return when (value.toInt()) {
|
||||
in 0..99 -> "0-99"
|
||||
in 100..199 -> "100-199"
|
||||
in 200..299 -> "200-299"
|
||||
in 300..399 -> "300-399"
|
||||
in 400..499 -> "400-499"
|
||||
in 500..599 -> "500-599"
|
||||
in 600..699 -> "600-699"
|
||||
in 700..799 -> "700-799"
|
||||
in 800..899 -> "800-899"
|
||||
in 900..Int.MAX_VALUE -> "900+"
|
||||
else -> "None"
|
||||
}
|
||||
}
|
||||
|
||||
private fun get10sRange(value: Float): String {
|
||||
return when (value.toInt()) {
|
||||
in 0..9 -> "0-9"
|
||||
in 10..19 -> "10-19"
|
||||
in 20..29 -> "20-29"
|
||||
in 30..39 -> "30-39"
|
||||
in 40..49 -> "40-49"
|
||||
in 50..59 -> "50-59"
|
||||
in 60..69 -> "60-69"
|
||||
in 70..79 -> "70-79"
|
||||
in 80..89 -> "80-89"
|
||||
in 80..89 -> "80-89"
|
||||
in 90..99 -> "90-99"
|
||||
in 100..109 -> "100-109"
|
||||
in 110..119 -> "110-119"
|
||||
in 120..129 -> "120-129"
|
||||
in 130..139 -> "130-139"
|
||||
in 140..149 -> "140-149"
|
||||
in 150..159 -> "150-159"
|
||||
in 160..169 -> "160-169"
|
||||
in 170..179 -> "170-179"
|
||||
in 180..189 -> "180-189"
|
||||
in 190..199 -> "190-199"
|
||||
in 190..199 -> "190-199"
|
||||
in 200..209 -> "200-209"
|
||||
in 210..219 -> "210-219"
|
||||
in 220..229 -> "220-229"
|
||||
in 230..239 -> "230-239"
|
||||
in 240..249 -> "240-249"
|
||||
in 250..259 -> "250-259"
|
||||
in 260..269 -> "260-269"
|
||||
in 270..279 -> "270-279"
|
||||
in 280..289 -> "280-289"
|
||||
in 290..299 -> "290-299"
|
||||
in 290..299 -> "290-299"
|
||||
in 300..Int.MAX_VALUE -> "300+"
|
||||
else -> recyclerView.context.getString(R.string.unknown)
|
||||
}
|
||||
}
|
||||
|
||||
interface MangaDetailsInterface : MangaHeaderInterface, DownloadInterface
|
||||
|
||||
interface MangaHeaderInterface {
|
||||
|
@ -25,6 +25,7 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -56,6 +57,8 @@ import com.bumptech.glide.request.transition.Transition
|
||||
import com.bumptech.glide.signature.ObjectKey
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.reddit.indicatorfastscroll.FastScrollItemIndicator
|
||||
import com.reddit.indicatorfastscroll.FastScrollerView
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -165,6 +168,8 @@ class MangaDetailsController : BaseController,
|
||||
private var startingDLChapterPos: Int? = null
|
||||
private var editMangaDialog: EditMangaDialog? = null
|
||||
var refreshTracker: Int? = null
|
||||
private var textAnim: ViewPropertyAnimator? = null
|
||||
private var scrollAnim: ViewPropertyAnimator? = null
|
||||
|
||||
/**
|
||||
* Library search query.
|
||||
@ -184,6 +189,7 @@ class MangaDetailsController : BaseController,
|
||||
// Hold a reference to the current animator, so that it can be canceled mid-way.
|
||||
private var currentAnimator: Animator? = null
|
||||
|
||||
var showScroll = false
|
||||
var headerHeight = 0
|
||||
|
||||
init {
|
||||
@ -212,7 +218,6 @@ class MangaDetailsController : BaseController,
|
||||
)
|
||||
)
|
||||
recycler.setHasFixedSize(true)
|
||||
adapter?.fastScroller = fast_scroller
|
||||
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
|
||||
val array = view.context.obtainStyledAttributes(attrsArray)
|
||||
val appbarHeight = array.getDimensionPixelSize(0, 0)
|
||||
@ -228,15 +233,15 @@ class MangaDetailsController : BaseController,
|
||||
swipe_refresh.setProgressViewOffset(false, (-40).dpToPx, headerHeight + offset)
|
||||
(recycler.findViewHolderForAdapterPosition(0) as? MangaHeaderHolder)
|
||||
?.setTopHeight(headerHeight)
|
||||
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = statusBarHeight
|
||||
fast_scroll_layout.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = headerHeight
|
||||
bottomMargin = insets.systemWindowInsetBottom
|
||||
}
|
||||
v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)
|
||||
}
|
||||
|
||||
presenter.onCreate()
|
||||
|
||||
fast_scroller.translationX = if (showScroll) 0f else 22f.dpToPx
|
||||
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
@ -259,6 +264,19 @@ class MangaDetailsController : BaseController,
|
||||
getHeader()?.backdrop?.translationY = 0f
|
||||
activity!!.appbar.y = 0f
|
||||
}
|
||||
val fPosition =
|
||||
(recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
if (fPosition > 0 && !showScroll) {
|
||||
showScroll = true
|
||||
scrollAnim?.cancel()
|
||||
scrollAnim = fast_scroller.animate().setDuration(100).translationX(0f)
|
||||
scrollAnim?.start()
|
||||
} else if (fPosition <= 0 && showScroll) {
|
||||
showScroll = false
|
||||
scrollAnim?.cancel()
|
||||
scrollAnim = fast_scroller.animate().setDuration(100).translationX(22f.dpToPx)
|
||||
scrollAnim?.start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
@ -291,6 +309,38 @@ class MangaDetailsController : BaseController,
|
||||
})
|
||||
setPaletteColor()
|
||||
|
||||
fast_scroller.setupWithRecyclerView(recycler, { position ->
|
||||
val letter = adapter?.getSectionText(position)
|
||||
when {
|
||||
presenter.scrollType == 0 -> null
|
||||
letter != null -> FastScrollItemIndicator.Text(letter)
|
||||
else -> FastScrollItemIndicator.Icon(R.drawable.star)
|
||||
}
|
||||
})
|
||||
fast_scroller.useDefaultScroller = false
|
||||
fast_scroller.itemIndicatorSelectedCallbacks += object :
|
||||
FastScrollerView.ItemIndicatorSelectedCallback {
|
||||
override fun onItemIndicatorSelected(
|
||||
indicator: FastScrollItemIndicator,
|
||||
indicatorCenterY: Int,
|
||||
itemPosition: Int
|
||||
) {
|
||||
textAnim?.cancel()
|
||||
textAnim = text_view_m.animate().alpha(0f).setDuration(250L).setStartDelay(1000)
|
||||
textAnim?.start()
|
||||
|
||||
text_view_m.translationY = indicatorCenterY.toFloat() - text_view_m.height / 2
|
||||
text_view_m.alpha = 1f
|
||||
text_view_m.text = adapter?.getFullText(itemPosition)
|
||||
val appbar = activity?.appbar
|
||||
appbar?.y = 0f
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
itemPosition, headerHeight
|
||||
)
|
||||
colorToolbar(itemPosition > 0, false)
|
||||
}
|
||||
}
|
||||
|
||||
swipe_refresh.isRefreshing = presenter.isLoading
|
||||
if (manga?.initialized != true)
|
||||
swipe_refresh.post { swipe_refresh.isRefreshing = true }
|
||||
@ -298,7 +348,8 @@ class MangaDetailsController : BaseController,
|
||||
swipe_refresh.setOnRefreshListener { presenter.refreshAll() }
|
||||
}
|
||||
|
||||
fun colorToolbar(isColor: Boolean) {
|
||||
fun colorToolbar(isColor: Boolean, animate: Boolean = true) {
|
||||
if (isColor == toolbarIsColored) return
|
||||
toolbarIsColored = isColor
|
||||
val isCurrentController =
|
||||
router?.backstack?.lastOrNull()?.controller() == this@MangaDetailsController
|
||||
@ -319,6 +370,7 @@ class MangaDetailsController : BaseController,
|
||||
color, if (toolbarIsColored) 175 else 0
|
||||
)
|
||||
colorAnimator?.cancel()
|
||||
if (animate) {
|
||||
colorAnimator = ValueAnimator.ofObject(
|
||||
android.animation.ArgbEvaluator(), colorFrom, colorTo
|
||||
)
|
||||
@ -328,6 +380,10 @@ class MangaDetailsController : BaseController,
|
||||
activity?.window?.statusBarColor = (animator.animatedValue as Int)
|
||||
}
|
||||
colorAnimator?.start()
|
||||
} else {
|
||||
(activity as MainActivity).toolbar.setBackgroundColor(colorTo)
|
||||
activity?.window?.statusBarColor = colorTo
|
||||
}
|
||||
}
|
||||
|
||||
fun setPaletteColor() {
|
||||
|
@ -24,6 +24,8 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.fetchChapterListAsync
|
||||
import eu.kanade.tachiyomi.source.fetchMangaDetailsAsync
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||
@ -60,6 +62,9 @@ class MangaDetailsPresenter(
|
||||
var isLockedFromSearch = false
|
||||
var hasRequested = false
|
||||
var isLoading = false
|
||||
var scrollType = 0
|
||||
private val volumeRegex = Regex("""(vol|volume)\.? *([0-9]+)?""", RegexOption.IGNORE_CASE)
|
||||
private val seasonRegex = Regex("""(Season |S)([0-9]+)?""")
|
||||
|
||||
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } }
|
||||
var tracks = emptyList<Track>()
|
||||
@ -242,9 +247,71 @@ class MangaDetailsPresenter(
|
||||
else -> { c1, c2 -> c1.source_order.compareTo(c2.source_order) }
|
||||
}
|
||||
chapters = chapters.sortedWith(Comparator(sortFunction))
|
||||
getScrollType(chapters)
|
||||
return chapters
|
||||
}
|
||||
|
||||
private fun getScrollType(chapters: List<ChapterItem>) {
|
||||
scrollType = when {
|
||||
hasMultipleVolumes(chapters) -> MULTIPLE_VOLUMES
|
||||
hasMultipleSeasons(chapters) -> MULTIPLE_SEASONS
|
||||
hasHundredsOfChapters(chapters) -> HUNDREDS_OF_CHAPTERS
|
||||
hasTensOfChapters(chapters) -> TENS_OF_CHAPTERS
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
fun getGroupNumber(chapter: ChapterItem): Int? {
|
||||
val groups = volumeRegex.find(chapter.name)?.groups
|
||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||
val seasonGroups = seasonRegex.find(chapter.name)?.groups
|
||||
if (seasonGroups != null) return seasonGroups[2]?.value?.toIntOrNull()
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getVolumeNumber(chapter: ChapterItem): Int? {
|
||||
val groups = volumeRegex.find(chapter.name)?.groups
|
||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getSeasonNumber(chapter: ChapterItem): Int? {
|
||||
val groups = seasonRegex.find(chapter.name)?.groups
|
||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||
return null
|
||||
}
|
||||
|
||||
private fun hasMultipleVolumes(chapters: List<ChapterItem>): Boolean {
|
||||
val volumeSet = mutableSetOf<Int>()
|
||||
chapters.forEach {
|
||||
val volNum = getVolumeNumber(it)
|
||||
if (volNum != null) {
|
||||
volumeSet.add(volNum)
|
||||
if (volumeSet.size >= 3) return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun hasMultipleSeasons(chapters: List<ChapterItem>): Boolean {
|
||||
val volumeSet = mutableSetOf<Int>()
|
||||
chapters.forEach {
|
||||
val volNum = getSeasonNumber(it)
|
||||
if (volNum != null) {
|
||||
volumeSet.add(volNum)
|
||||
if (volumeSet.size >= 3) return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun hasHundredsOfChapters(chapters: List<ChapterItem>): Boolean {
|
||||
return chapters.size > 300
|
||||
}
|
||||
|
||||
private fun hasTensOfChapters(chapters: List<ChapterItem>): Boolean {
|
||||
return chapters.size in 21..300
|
||||
}
|
||||
/**
|
||||
* Returns the next unread chapter or null if everything is read.
|
||||
*/
|
||||
@ -309,7 +376,7 @@ class MangaDetailsPresenter(
|
||||
var chapterError: java.lang.Exception? = null
|
||||
val chapters = async(Dispatchers.IO) {
|
||||
try {
|
||||
source.fetchChapterList(manga).toBlocking().single()
|
||||
source.fetchChapterListAsync(manga)
|
||||
} catch (e: Exception) {
|
||||
chapterError = e
|
||||
emptyList<SChapter>()
|
||||
@ -318,7 +385,7 @@ class MangaDetailsPresenter(
|
||||
val thumbnailUrl = manga.thumbnail_url
|
||||
val nManga = async(Dispatchers.IO) {
|
||||
try {
|
||||
source.fetchMangaDetails(manga).toBlocking().single()
|
||||
source.fetchMangaDetailsAsync(manga)
|
||||
} catch (e: java.lang.Exception) {
|
||||
mangaError = e
|
||||
null
|
||||
@ -342,6 +409,14 @@ class MangaDetailsPresenter(
|
||||
}
|
||||
isLoading = false
|
||||
if (chapterError == null) withContext(Dispatchers.Main) { controller.updateChapters(this@MangaDetailsPresenter.chapters) }
|
||||
else {
|
||||
withContext(Dispatchers.Main) {
|
||||
controller.showError(
|
||||
trimException(mangaError!!)
|
||||
)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
if (mangaError != null) withContext(Dispatchers.Main) {
|
||||
controller.showError(
|
||||
trimException(mangaError!!)
|
||||
@ -359,7 +434,7 @@ class MangaDetailsPresenter(
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val chapters = try {
|
||||
source.fetchChapterList(manga).toBlocking().single()
|
||||
source.fetchChapterListAsync(manga)
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) { controller.showError(trimException(e)) }
|
||||
return@launch
|
||||
@ -760,4 +835,11 @@ class MangaDetailsPresenter(
|
||||
track.last_chapter_read = chapterNumber
|
||||
updateRemote(track, item.service)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MULTIPLE_VOLUMES = 1
|
||||
const val TENS_OF_CHAPTERS = 2
|
||||
const val HUNDREDS_OF_CHAPTERS = 3
|
||||
const val MULTIPLE_SEASONS = 4
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
@ -16,7 +14,6 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
@ -152,13 +149,6 @@ class SettingsAdvancedController : SettingsController() {
|
||||
}
|
||||
|
||||
private fun clearDatabase() {
|
||||
// Avoid weird behavior by going back to the library.
|
||||
val newBackstack = listOf(RouterTransaction.with(
|
||||
LibraryController())) +
|
||||
router.backstack.drop(1)
|
||||
|
||||
router.setBackstack(newBackstack, FadeChangeHandler())
|
||||
|
||||
db.deleteMangasNotInLibrary().executeAsBlocking()
|
||||
db.deleteHistoryNoLastRead().executeAsBlocking()
|
||||
activity?.toast(R.string.clear_database_completed)
|
||||
|
@ -94,7 +94,7 @@
|
||||
layout="@layout/download_button"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
@ -32,6 +32,7 @@
|
||||
android:elevation="10dp"
|
||||
android:layout_gravity="end"
|
||||
android:background="@drawable/fast_scroll_background"
|
||||
android:backgroundTint="@color/md_grey_800"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingStart="3dp"
|
||||
|
@ -25,14 +25,45 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/chapters_title"
|
||||
tools:listitem="@layout/chapters_item"/>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
<eu.davidea.fastscroller.FastScroller
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/fast_scroll_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.reddit.indicatorfastscroll.FastScrollerView
|
||||
android:id="@+id/fast_scroller"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
app:iconColor="?android:attr/textColorPrimary"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="0dp"
|
||||
android:elevation="10dp"
|
||||
android:layout_gravity="end"
|
||||
app:fastScrollerBubbleEnabled="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingStart="1dp"
|
||||
android:paddingEnd="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text_view_m"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0"
|
||||
tools:alpha="1"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:background="@drawable/round_textview_background"
|
||||
android:backgroundTint="@color/md_grey_800_50"
|
||||
android:padding="8dp"
|
||||
android:textColor="@android:color/white"
|
||||
app:layout_constraintEnd_toStartOf="@id/fast_scroller"
|
||||
app:layout_constraintTop_toTopOf="@id/fast_scroller"
|
||||
tools:text="sdfsdf" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/full_backdrop"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -372,7 +372,7 @@
|
||||
android:tint="?colorAccent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="9dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@null"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/ic_filter_list_white_24dp"
|
||||
|
@ -211,6 +211,10 @@
|
||||
<item quantity="other">%d categories</item>
|
||||
</plurals>
|
||||
<string name="top">Top</string>
|
||||
<string name="bottom">Bottom</string>
|
||||
<string name="volume_x">Volume %1$d</string>
|
||||
<string name="season_x">Season %1$d</string>
|
||||
<string name="chapters_x">Chapters %1$s</string>
|
||||
|
||||
<string name="pref_category_library_update">Updates</string>
|
||||
<string name="pref_library_update_interval">Library update frequency</string>
|
||||
|
Loading…
Reference in New Issue
Block a user