mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-28 09:15:12 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
4e114d30a6
20 changed files with 132 additions and 111 deletions
3
.github/workflows/build_pull_request.yml
vendored
3
.github/workflows/build_pull_request.yml
vendored
|
@ -1,6 +1,9 @@
|
|||
name: PR build check
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'app/src/main/res/**/strings.xml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
@ -29,7 +29,7 @@ android {
|
|||
minSdk = AndroidConfig.minSdk
|
||||
targetSdk = AndroidConfig.targetSdk
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
versionCode = 69
|
||||
versionCode = 70
|
||||
versionName = "0.12.3.2"
|
||||
|
||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||
|
|
|
@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
|
|||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
||||
import eu.kanade.tachiyomi.extension.AnimeExtensionUpdateJob
|
||||
|
@ -248,9 +249,9 @@ object Migrations {
|
|||
putString(PreferenceKeys.librarySortingDirection, newSortingDirection.name)
|
||||
}
|
||||
}
|
||||
if (oldVersion < 65) {
|
||||
if (preferences.lang().get() in listOf("en-US", "en-GB")) {
|
||||
preferences.lang().set("en")
|
||||
if (oldVersion < 70) {
|
||||
if (preferences.enabledLanguages().isSet()) {
|
||||
preferences.enabledLanguages() += "all"
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -574,4 +574,4 @@ class AnimelibUpdateService(
|
|||
}
|
||||
}
|
||||
|
||||
const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 50
|
||||
const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60
|
||||
|
|
|
@ -574,4 +574,4 @@ class LibraryUpdateService(
|
|||
}
|
||||
}
|
||||
|
||||
const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 50
|
||||
const val PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60
|
||||
|
|
|
@ -97,7 +97,6 @@ import eu.kanade.tachiyomi.util.episode.NoEpisodesException
|
|||
import eu.kanade.tachiyomi.util.hasCustomCover
|
||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||
|
@ -272,13 +271,21 @@ class AnimeController :
|
|||
if (anime == null || source == null) return
|
||||
|
||||
// Init RecyclerView and adapter
|
||||
animeInfoAdapter = AnimeInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null)
|
||||
episodesHeaderAdapter = AnimeEpisodesHeaderAdapter(this)
|
||||
animeInfoAdapter = AnimeInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null).apply {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
episodesHeaderAdapter = AnimeEpisodesHeaderAdapter(this).apply {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
episodesAdapter = EpisodesAdapter(this, view.context)
|
||||
|
||||
// Phone layout
|
||||
binding.fullRecycler?.let {
|
||||
it.adapter = ConcatAdapter(animeInfoAdapter, episodesHeaderAdapter, episodesAdapter)
|
||||
val config = ConcatAdapter.Config.Builder()
|
||||
.setIsolateViewTypes(true)
|
||||
.setStableIdMode(ConcatAdapter.Config.StableIdMode.SHARED_STABLE_IDS)
|
||||
.build()
|
||||
it.adapter = ConcatAdapter(config, animeInfoAdapter, episodesHeaderAdapter, episodesAdapter)
|
||||
|
||||
// Skips directly to chapters list if navigated to from the library
|
||||
it.post {
|
||||
|
@ -303,7 +310,7 @@ class AnimeController :
|
|||
|
||||
binding.fastScroller.doOnLayout { scroller ->
|
||||
scroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = getMainAppBarHeight()
|
||||
topMargin += getMainAppBarHeight()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,7 +348,6 @@ class AnimeController :
|
|||
settingsSheet = EpisodesSettingsSheet(router, presenter) { group ->
|
||||
if (group is EpisodesSettingsSheet.Filter.FilterGroup) {
|
||||
updateFilterIconState()
|
||||
episodesAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,7 +647,7 @@ class AnimeController :
|
|||
}
|
||||
}
|
||||
}
|
||||
animeInfoAdapter?.notifyDataSetChanged()
|
||||
animeInfoAdapter?.update()
|
||||
}
|
||||
|
||||
fun onCategoriesClick() {
|
||||
|
@ -842,7 +848,7 @@ class AnimeController :
|
|||
|
||||
override fun deleteAnimeCover(anime: Anime) {
|
||||
presenter.deleteCustomCover(anime)
|
||||
animeInfoAdapter?.notifyDataSetChanged()
|
||||
animeInfoAdapter?.notifyItemChanged(0, anime)
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
|
||||
|
@ -948,7 +954,7 @@ class AnimeController :
|
|||
}
|
||||
|
||||
fun onSetCoverSuccess() {
|
||||
animeInfoAdapter?.notifyDataSetChanged()
|
||||
animeInfoAdapter?.notifyItemChanged(0, this)
|
||||
(dialog as? AnimeFullCoverDialog)?.setImage(anime)
|
||||
activity?.toast(R.string.cover_updated)
|
||||
}
|
||||
|
@ -1120,19 +1126,20 @@ class AnimeController :
|
|||
val lastClickPosition = lastClickPositionStack.peek()!!
|
||||
when {
|
||||
lastClickPosition == -1 -> setSelection(position)
|
||||
lastClickPosition > position ->
|
||||
for (i in position until lastClickPosition)
|
||||
setSelection(i)
|
||||
lastClickPosition < position ->
|
||||
for (i in lastClickPosition + 1..position)
|
||||
setSelection(i)
|
||||
lastClickPosition > position -> {
|
||||
for (i in position until lastClickPosition) setSelection(i)
|
||||
episodesAdapter?.notifyItemRangeChanged(position, lastClickPosition, position)
|
||||
}
|
||||
lastClickPosition < position -> {
|
||||
for (i in lastClickPosition + 1..position) setSelection(i)
|
||||
episodesAdapter?.notifyItemRangeChanged(lastClickPosition + 1, position, position)
|
||||
}
|
||||
else -> setSelection(position)
|
||||
}
|
||||
if (lastClickPosition != position) {
|
||||
lastClickPositionStack.remove(position) // move to top if already exists
|
||||
lastClickPositionStack.push(position)
|
||||
}
|
||||
episodesAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun showSettingsSheet() {
|
||||
|
@ -1145,7 +1152,6 @@ class AnimeController :
|
|||
val adapter = episodesAdapter ?: return
|
||||
val item = adapter.getItem(position) ?: return
|
||||
adapter.toggleSelection(position)
|
||||
adapter.notifyDataSetChanged()
|
||||
if (adapter.isSelected(position)) {
|
||||
selectedEpisodes.add(item)
|
||||
} else {
|
||||
|
@ -1292,11 +1298,11 @@ class AnimeController :
|
|||
selectedEpisodes.clear()
|
||||
for (i in 0..adapter.itemCount) {
|
||||
adapter.toggleSelection(i)
|
||||
adapter.notifyItemChanged(i, i)
|
||||
}
|
||||
selectedEpisodes.addAll(adapter.selectedPositions.mapNotNull { adapter.getItem(it) })
|
||||
|
||||
actionMode?.invalidate()
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun markAsRead(episodes: List<EpisodeItem>) {
|
||||
|
@ -1384,10 +1390,7 @@ class AnimeController :
|
|||
fun onEpisodesDeleted(episodes: List<EpisodeItem>) {
|
||||
// this is needed so the downloaded text gets removed from the item
|
||||
episodes.forEach {
|
||||
episodesAdapter?.updateItem(it)
|
||||
}
|
||||
launchUI {
|
||||
episodesAdapter?.notifyDataSetChanged()
|
||||
episodesAdapter?.updateItem(it, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -763,6 +763,7 @@ class AnimePresenter(
|
|||
fun setDisplayMode(mode: Int) {
|
||||
anime.displayMode = mode
|
||||
db.updateEpisodeFlags(anime).executeAsBlocking()
|
||||
refreshEpisodes()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,8 @@ class AnimeEpisodesHeaderAdapter(
|
|||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||
|
||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
@ -37,13 +39,13 @@ class AnimeEpisodesHeaderAdapter(
|
|||
fun setNumEpisodes(numEpisodes: Int) {
|
||||
this.numEpisodes = numEpisodes
|
||||
|
||||
notifyDataSetChanged()
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
fun setHasActiveFilters(hasActiveFilters: Boolean) {
|
||||
this.hasActiveFilters = hasActiveFilters
|
||||
|
||||
notifyDataSetChanged()
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
|
|
@ -116,7 +116,7 @@ class EpisodesSettingsSheet(
|
|||
}
|
||||
|
||||
initModels()
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
adapter.notifyItemChanged(items.indexOf(item), item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,18 +158,18 @@ class EpisodesSettingsSheet(
|
|||
}
|
||||
|
||||
override fun onItemClicked(item: Item) {
|
||||
item as Item.MultiStateGroup
|
||||
val prevState = item.state
|
||||
|
||||
item.group.items.forEach {
|
||||
(it as Item.MultiStateGroup).state =
|
||||
items.forEachIndexed { i, multiSort ->
|
||||
multiSort.state = if (multiSort == item) {
|
||||
when (item.state) {
|
||||
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
||||
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
||||
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
||||
else -> throw Exception("Unknown state")
|
||||
}
|
||||
} else {
|
||||
Item.MultiSort.SORT_NONE
|
||||
}
|
||||
item.state = when (prevState) {
|
||||
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
||||
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
||||
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
||||
else -> throw Exception("Unknown state")
|
||||
}
|
||||
adapter.notifyItemChanged(i, multiSort)
|
||||
}
|
||||
|
||||
when (item) {
|
||||
|
@ -180,8 +180,6 @@ class EpisodesSettingsSheet(
|
|||
}
|
||||
|
||||
presenter.reverseSortOrder()
|
||||
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,16 +213,16 @@ class EpisodesSettingsSheet(
|
|||
item as Item.Radio
|
||||
if (item.checked) return
|
||||
|
||||
item.group.items.forEach { (it as Item.Radio).checked = false }
|
||||
item.checked = true
|
||||
items.forEachIndexed { index, radio ->
|
||||
radio.checked = item == radio
|
||||
adapter.notifyItemChanged(index, radio)
|
||||
}
|
||||
|
||||
when (item) {
|
||||
displayTitle -> presenter.setDisplayMode(Anime.EPISODE_DISPLAY_NAME)
|
||||
displayEpisodeNum -> presenter.setDisplayMode(Anime.EPISODE_DISPLAY_NUMBER)
|
||||
else -> throw NotImplementedError("Unknown display mode")
|
||||
}
|
||||
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ class AnimeInfoHeaderAdapter(
|
|||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||
|
||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
@ -69,14 +71,16 @@ class AnimeInfoHeaderAdapter(
|
|||
fun update(anime: Anime, source: AnimeSource) {
|
||||
this.anime = anime
|
||||
this.source = source
|
||||
update()
|
||||
}
|
||||
|
||||
notifyDataSetChanged()
|
||||
fun update() {
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
fun setTrackingCount(trackCount: Int) {
|
||||
this.trackCount = trackCount
|
||||
|
||||
notifyDataSetChanged()
|
||||
update()
|
||||
}
|
||||
|
||||
private fun updateCoverPosition() {
|
||||
|
|
|
@ -87,7 +87,6 @@ import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
|||
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
||||
import eu.kanade.tachiyomi.util.hasCustomCover
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||
|
@ -251,13 +250,21 @@ class MangaController :
|
|||
if (manga == null || source == null) return
|
||||
|
||||
// Init RecyclerView and adapter
|
||||
mangaInfoAdapter = MangaInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null)
|
||||
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this)
|
||||
mangaInfoAdapter = MangaInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null).apply {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this).apply {
|
||||
setHasStableIds(true)
|
||||
}
|
||||
chaptersAdapter = ChaptersAdapter(this, view.context)
|
||||
|
||||
// Phone layout
|
||||
binding.fullRecycler?.let {
|
||||
it.adapter = ConcatAdapter(mangaInfoAdapter, chaptersHeaderAdapter, chaptersAdapter)
|
||||
val config = ConcatAdapter.Config.Builder()
|
||||
.setIsolateViewTypes(true)
|
||||
.setStableIdMode(ConcatAdapter.Config.StableIdMode.SHARED_STABLE_IDS)
|
||||
.build()
|
||||
it.adapter = ConcatAdapter(config, mangaInfoAdapter, chaptersHeaderAdapter, chaptersAdapter)
|
||||
|
||||
// Skips directly to chapters list if navigated to from the library
|
||||
it.post {
|
||||
|
@ -282,7 +289,7 @@ class MangaController :
|
|||
|
||||
binding.fastScroller.doOnLayout { scroller ->
|
||||
scroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = getMainAppBarHeight()
|
||||
topMargin += getMainAppBarHeight()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,7 +327,6 @@ class MangaController :
|
|||
settingsSheet = ChaptersSettingsSheet(router, presenter) { group ->
|
||||
if (group is ChaptersSettingsSheet.Filter.FilterGroup) {
|
||||
updateFilterIconState()
|
||||
chaptersAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -622,7 +628,7 @@ class MangaController :
|
|||
}
|
||||
}
|
||||
}
|
||||
mangaInfoAdapter?.notifyDataSetChanged()
|
||||
mangaInfoAdapter?.update()
|
||||
}
|
||||
|
||||
fun onCategoriesClick() {
|
||||
|
@ -822,7 +828,7 @@ class MangaController :
|
|||
|
||||
override fun deleteMangaCover(manga: Manga) {
|
||||
presenter.deleteCustomCover(manga)
|
||||
mangaInfoAdapter?.notifyDataSetChanged()
|
||||
mangaInfoAdapter?.notifyItemChanged(0, manga)
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
|
||||
|
@ -836,7 +842,7 @@ class MangaController :
|
|||
}
|
||||
|
||||
fun onSetCoverSuccess() {
|
||||
mangaInfoAdapter?.notifyDataSetChanged()
|
||||
mangaInfoAdapter?.notifyItemChanged(0, this)
|
||||
(dialog as? MangaFullCoverDialog)?.setImage(manga)
|
||||
activity?.toast(R.string.cover_updated)
|
||||
}
|
||||
|
@ -947,19 +953,20 @@ class MangaController :
|
|||
val lastClickPosition = lastClickPositionStack.peek()!!
|
||||
when {
|
||||
lastClickPosition == -1 -> setSelection(position)
|
||||
lastClickPosition > position ->
|
||||
for (i in position until lastClickPosition)
|
||||
setSelection(i)
|
||||
lastClickPosition < position ->
|
||||
for (i in lastClickPosition + 1..position)
|
||||
setSelection(i)
|
||||
lastClickPosition > position -> {
|
||||
for (i in position until lastClickPosition) setSelection(i)
|
||||
chaptersAdapter?.notifyItemRangeChanged(position, lastClickPosition, position)
|
||||
}
|
||||
lastClickPosition < position -> {
|
||||
for (i in lastClickPosition + 1..position) setSelection(i)
|
||||
chaptersAdapter?.notifyItemRangeChanged(lastClickPosition + 1, position, position)
|
||||
}
|
||||
else -> setSelection(position)
|
||||
}
|
||||
if (lastClickPosition != position) {
|
||||
lastClickPositionStack.remove(position) // move to top if already exists
|
||||
lastClickPositionStack.push(position)
|
||||
}
|
||||
chaptersAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun showSettingsSheet() {
|
||||
|
@ -972,7 +979,6 @@ class MangaController :
|
|||
val adapter = chaptersAdapter ?: return
|
||||
val item = adapter.getItem(position) ?: return
|
||||
adapter.toggleSelection(position)
|
||||
adapter.notifyDataSetChanged()
|
||||
if (adapter.isSelected(position)) {
|
||||
selectedChapters.add(item)
|
||||
} else {
|
||||
|
@ -1105,11 +1111,11 @@ class MangaController :
|
|||
selectedChapters.clear()
|
||||
for (i in 0..adapter.itemCount) {
|
||||
adapter.toggleSelection(i)
|
||||
adapter.notifyItemChanged(i, i)
|
||||
}
|
||||
selectedChapters.addAll(adapter.selectedPositions.mapNotNull { adapter.getItem(it) })
|
||||
|
||||
actionMode?.invalidate()
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun markAsRead(chapters: List<ChapterItem>) {
|
||||
|
@ -1176,10 +1182,7 @@ class MangaController :
|
|||
fun onChaptersDeleted(chapters: List<ChapterItem>) {
|
||||
// this is needed so the downloaded text gets removed from the item
|
||||
chapters.forEach {
|
||||
chaptersAdapter?.updateItem(it)
|
||||
}
|
||||
launchUI {
|
||||
chaptersAdapter?.notifyDataSetChanged()
|
||||
chaptersAdapter?.updateItem(it, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,7 @@ class MangaPresenter(
|
|||
fun setDisplayMode(mode: Int) {
|
||||
manga.displayMode = mode
|
||||
db.updateChapterFlags(manga).executeAsBlocking()
|
||||
refreshChapters()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,7 +116,7 @@ class ChaptersSettingsSheet(
|
|||
}
|
||||
|
||||
initModels()
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
adapter.notifyItemChanged(items.indexOf(item), item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,18 +158,18 @@ class ChaptersSettingsSheet(
|
|||
}
|
||||
|
||||
override fun onItemClicked(item: Item) {
|
||||
item as Item.MultiStateGroup
|
||||
val prevState = item.state
|
||||
|
||||
item.group.items.forEach {
|
||||
(it as Item.MultiStateGroup).state =
|
||||
items.forEachIndexed { i, multiSort ->
|
||||
multiSort.state = if (multiSort == item) {
|
||||
when (item.state) {
|
||||
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
||||
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
||||
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
||||
else -> throw Exception("Unknown state")
|
||||
}
|
||||
} else {
|
||||
Item.MultiSort.SORT_NONE
|
||||
}
|
||||
item.state = when (prevState) {
|
||||
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
||||
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
||||
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
||||
else -> throw Exception("Unknown state")
|
||||
}
|
||||
adapter.notifyItemChanged(i, multiSort)
|
||||
}
|
||||
|
||||
when (item) {
|
||||
|
@ -180,8 +180,6 @@ class ChaptersSettingsSheet(
|
|||
}
|
||||
|
||||
presenter.reverseSortOrder()
|
||||
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,16 +213,16 @@ class ChaptersSettingsSheet(
|
|||
item as Item.Radio
|
||||
if (item.checked) return
|
||||
|
||||
item.group.items.forEach { (it as Item.Radio).checked = false }
|
||||
item.checked = true
|
||||
items.forEachIndexed { index, radio ->
|
||||
radio.checked = item == radio
|
||||
adapter.notifyItemChanged(index, radio)
|
||||
}
|
||||
|
||||
when (item) {
|
||||
displayTitle -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NAME)
|
||||
displayChapterNum -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NUMBER)
|
||||
else -> throw NotImplementedError("Unknown display mode")
|
||||
}
|
||||
|
||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,20 +30,20 @@ class MangaChaptersHeaderAdapter(
|
|||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||
|
||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
||||
fun setNumChapters(numChapters: Int) {
|
||||
this.numChapters = numChapters
|
||||
|
||||
notifyDataSetChanged()
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
fun setHasActiveFilters(hasActiveFilters: Boolean) {
|
||||
this.hasActiveFilters = hasActiveFilters
|
||||
|
||||
notifyDataSetChanged()
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
|
|
@ -56,6 +56,8 @@ class MangaInfoHeaderAdapter(
|
|||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||
|
||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||
holder.bind()
|
||||
}
|
||||
|
@ -69,14 +71,16 @@ class MangaInfoHeaderAdapter(
|
|||
fun update(manga: Manga, source: Source) {
|
||||
this.manga = manga
|
||||
this.source = source
|
||||
update()
|
||||
}
|
||||
|
||||
notifyDataSetChanged()
|
||||
fun update() {
|
||||
notifyItemChanged(0, this)
|
||||
}
|
||||
|
||||
fun setTrackingCount(trackCount: Int) {
|
||||
this.trackCount = trackCount
|
||||
|
||||
notifyDataSetChanged()
|
||||
update()
|
||||
}
|
||||
|
||||
private fun updateCoverPosition() {
|
||||
|
|
|
@ -105,7 +105,7 @@ class ReaderPresenter(
|
|||
|
||||
val chaptersForReader = when {
|
||||
(preferences.skipRead() || preferences.skipFiltered()) -> {
|
||||
val list = dbChapters.filterNot {
|
||||
val filteredChapters = dbChapters.filterNot {
|
||||
when {
|
||||
preferences.skipRead() && it.read -> true
|
||||
preferences.skipFiltered() -> {
|
||||
|
@ -119,13 +119,12 @@ class ReaderPresenter(
|
|||
else -> false
|
||||
}
|
||||
}
|
||||
.toMutableList()
|
||||
|
||||
val find = list.find { it.id == chapterId }
|
||||
if (find == null) {
|
||||
list.add(selectedChapter)
|
||||
if (filteredChapters.any { it.id == chapterId }) {
|
||||
filteredChapters
|
||||
} else {
|
||||
filteredChapters + listOf(selectedChapter)
|
||||
}
|
||||
list
|
||||
}
|
||||
else -> dbChapters
|
||||
}
|
||||
|
|
|
@ -167,17 +167,20 @@ inline fun ExtendedFloatingActionButton.shrinkOnScroll(recycler: RecyclerView):
|
|||
*
|
||||
* @param items List of strings that are shown as individual chips.
|
||||
* @param onClick Optional on click listener for each chip.
|
||||
* @param onLongClick Optional on long click listener for each chip.
|
||||
*/
|
||||
inline fun ChipGroup.setChips(
|
||||
items: List<String>?,
|
||||
noinline onClick: (item: String) -> Unit = {}
|
||||
noinline onClick: ((item: String) -> Unit)? = null,
|
||||
noinline onLongClick: ((item: String) -> Unit)? = null
|
||||
) {
|
||||
removeAllViews()
|
||||
|
||||
items?.forEach { item ->
|
||||
val chip = Chip(context).apply {
|
||||
text = item
|
||||
setOnClickListener { onClick(item) }
|
||||
if (onClick != null) { setOnClickListener { onClick(item) } }
|
||||
if (onLongClick != null) { setOnLongClickListener { onLongClick(item); true } }
|
||||
}
|
||||
|
||||
addView(chip)
|
||||
|
|
|
@ -64,8 +64,9 @@ class MangaSummaryView @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
fun setTags(items: List<String>?, onClick: (item: String) -> Unit) {
|
||||
binding.tagChipsShrunk.setChips(items, onClick)
|
||||
binding.tagChipsExpanded.setChips(items, onClick)
|
||||
listOfNotNull(binding.tagChipsShrunk, binding.tagChipsExpanded).forEach { chips ->
|
||||
chips.setChips(items, onClick) { tag -> context.copyToClipboard(tag, tag) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateExpandState() = binding.apply {
|
||||
|
|
|
@ -774,8 +774,8 @@
|
|||
<string name="page_list_empty_error">No pages found</string>
|
||||
<string name="loader_not_implemented_error">Source not found</string>
|
||||
<plurals name="missing_chapters_warning">
|
||||
<item quantity="one">Skipping %d chapter, this could be because the source does not have them, or you are filtering them out</item>
|
||||
<item quantity="other">Skipping %d chapters, this could be because the source does not have them, or you are filtering them out</item>
|
||||
<item quantity="one">Skipping 1 chapter, either the source is missing it or it has been filtered out</item>
|
||||
<item quantity="other">Skipping %d chapters, either the source is missing them or they have been filtered out</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Updates fragment -->
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
object BuildPluginsVersion {
|
||||
const val AGP = "7.0.2"
|
||||
const val AGP = "7.0.3"
|
||||
const val KOTLIN = "1.5.31"
|
||||
const val KOTLINTER = "3.6.0"
|
||||
const val VERSIONS_PLUGIN = "0.39.0"
|
||||
|
|
Loading…
Reference in a new issue