mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Snackbar when mark read/unread from library (#1175)
* Normalize manga titles to avoid different apostrophe * Remove logs normalized * Add snackbar when mark as read/unread from library * Improve snackbar when mark as read/unread from library * Add language in pinned sources and migration * Fix oldChapters being readded * Remove tracking library * Change reader webview url to chapter instead of manga * add chapterUrl to ReaderActivity.onProvideAssistContent * remove normalized db titles * remove setTitleNormalized * add toNormalized for manualSearch in migration and globalSearch from manga_details * add confirmation for mark read/unread from library * add helper method getChapterUrl to presenter
This commit is contained in:
parent
e2351b0a18
commit
94fcad3ef5
14 changed files with 189 additions and 52 deletions
|
@ -29,5 +29,25 @@ interface Chapter : SChapter, Serializable {
|
||||||
fun create(): Chapter = ChapterImpl().apply {
|
fun create(): Chapter = ChapterImpl().apply {
|
||||||
chapter_number = -1f
|
chapter_number = -1f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun List<Chapter>.copy(): List<Chapter> {
|
||||||
|
return map {
|
||||||
|
ChapterImpl().apply {
|
||||||
|
copyFrom(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyFrom(other: Chapter) {
|
||||||
|
id = other.id
|
||||||
|
manga_id = other.manga_id
|
||||||
|
read = other.read
|
||||||
|
bookmark = other.bookmark
|
||||||
|
last_page_read = other.last_page_read
|
||||||
|
pages_left = other.pages_left
|
||||||
|
date_fetch = other.date_fetch
|
||||||
|
source_order = other.source_order
|
||||||
|
copyFrom(other as SChapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.util.lang.toNormalized
|
||||||
import eu.kanade.tachiyomi.util.system.await
|
import eu.kanade.tachiyomi.util.system.await
|
||||||
import info.debatty.java.stringsimilarity.NormalizedLevenshtein
|
import info.debatty.java.stringsimilarity.NormalizedLevenshtein
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -54,18 +55,21 @@ class SmartSearchEngine(
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
suspend fun normalSearch(source: CatalogueSource, title: String): SManga? {
|
suspend fun normalSearch(source: CatalogueSource, title: String): SManga? {
|
||||||
|
val titleNormalized = title.toNormalized()
|
||||||
val eligibleManga = supervisorScope {
|
val eligibleManga = supervisorScope {
|
||||||
val searchQuery = if (extraSearchParams != null) {
|
val searchQuery = if (extraSearchParams != null) {
|
||||||
"$title ${extraSearchParams.trim()}"
|
"$titleNormalized ${extraSearchParams.trim()}"
|
||||||
} else title
|
} else titleNormalized
|
||||||
val searchResults = source.fetchSearchManga(1, searchQuery, source.getFilterList()).toSingle().await(Schedulers.io())
|
val searchResults =
|
||||||
|
source.fetchSearchManga(1, searchQuery, source.getFilterList()).toSingle()
|
||||||
|
.await(Schedulers.io())
|
||||||
|
|
||||||
if (searchResults.mangas.size == 1) {
|
if (searchResults.mangas.size == 1) {
|
||||||
return@supervisorScope listOf(SearchEntry(searchResults.mangas.first(), 0.0))
|
return@supervisorScope listOf(SearchEntry(searchResults.mangas.first(), 0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
searchResults.mangas.map {
|
searchResults.mangas.map {
|
||||||
val normalizedDistance = normalizedLevenshtein.similarity(title, it.title)
|
val normalizedDistance = normalizedLevenshtein.similarity(titleNormalized, it.title.toNormalized())
|
||||||
SearchEntry(it, normalizedDistance)
|
SearchEntry(it, normalizedDistance)
|
||||||
}.filter { (_, normalizedDistance) ->
|
}.filter { (_, normalizedDistance) ->
|
||||||
normalizedDistance >= MIN_NORMAL_ELIGIBLE_THRESHOLD
|
normalizedDistance >= MIN_NORMAL_ELIGIBLE_THRESHOLD
|
||||||
|
|
|
@ -112,7 +112,6 @@ import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
@ -1751,12 +1750,22 @@ class LibraryController(
|
||||||
presenter.downloadUnread(selectedMangas.toList())
|
presenter.downloadUnread(selectedMangas.toList())
|
||||||
}
|
}
|
||||||
R.id.action_mark_as_read -> {
|
R.id.action_mark_as_read -> {
|
||||||
presenter.markReadStatus(selectedMangas.toList(), true)
|
activity!!.materialAlertDialog()
|
||||||
destroyActionModeIfNeeded()
|
.setMessage(R.string.mark_all_chapters_as_read)
|
||||||
|
.setPositiveButton(R.string.mark_as_read) { _, _ ->
|
||||||
|
markReadStatus(R.string.marked_as_read, true)
|
||||||
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
R.id.action_mark_as_unread -> {
|
R.id.action_mark_as_unread -> {
|
||||||
presenter.markReadStatus(selectedMangas.toList(), false)
|
activity!!.materialAlertDialog()
|
||||||
destroyActionModeIfNeeded()
|
.setMessage(R.string.mark_all_chapters_as_unread)
|
||||||
|
.setPositiveButton(R.string.mark_as_unread) { _, _ ->
|
||||||
|
markReadStatus(R.string.marked_as_unread, false)
|
||||||
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show()
|
||||||
}
|
}
|
||||||
R.id.action_migrate -> {
|
R.id.action_migrate -> {
|
||||||
val skipPre = preferences.skipPreMigration().get()
|
val skipPre = preferences.skipPreMigration().get()
|
||||||
|
@ -1772,6 +1781,35 @@ class LibraryController(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun markReadStatus(resource: Int, markRead: Boolean) {
|
||||||
|
val mapMangaChapters = presenter.markReadStatus(selectedMangas.toList(), markRead)
|
||||||
|
destroyActionModeIfNeeded()
|
||||||
|
snack?.dismiss()
|
||||||
|
snack = view?.snack(resource, Snackbar.LENGTH_INDEFINITE) {
|
||||||
|
anchorView = anchorView()
|
||||||
|
view.elevation = 15f.dpToPx
|
||||||
|
var undoing = false
|
||||||
|
setAction(R.string.undo) {
|
||||||
|
presenter.undoMarkReadStatus(mapMangaChapters)
|
||||||
|
undoing = true
|
||||||
|
}
|
||||||
|
addCallback(
|
||||||
|
object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
|
||||||
|
override fun onDismissed(
|
||||||
|
transientBottomBar: Snackbar?,
|
||||||
|
event: Int
|
||||||
|
) {
|
||||||
|
super.onDismissed(transientBottomBar, event)
|
||||||
|
if (!undoing) presenter.confirmMarkReadStatus(
|
||||||
|
mapMangaChapters, markRead
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(activity as? MainActivity)?.setUndoSnackBar(snack)
|
||||||
|
}
|
||||||
|
|
||||||
private fun shareManga() {
|
private fun shareManga() {
|
||||||
val context = view?.context ?: return
|
val context = view?.context ?: return
|
||||||
val mangas = selectedMangas.toList()
|
val mangas = selectedMangas.toList()
|
||||||
|
|
|
@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
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
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Chapter.Companion.copy
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
|
@ -1064,23 +1065,49 @@ class LibraryPresenter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markReadStatus(mangaList: List<Manga>, markRead: Boolean) {
|
fun markReadStatus(
|
||||||
presenterScope.launch {
|
mangaList: List<Manga>,
|
||||||
withContext(Dispatchers.IO) {
|
markRead: Boolean
|
||||||
mangaList.forEach {
|
): HashMap<Manga, List<Chapter>> {
|
||||||
withContext(Dispatchers.IO) {
|
val mapMangaChapters = HashMap<Manga, List<Chapter>>()
|
||||||
val chapters = db.getChapters(it).executeAsBlocking()
|
presenterScope.launchIO {
|
||||||
chapters.forEach {
|
mangaList.forEach { manga ->
|
||||||
it.read = markRead
|
val oldChapters = db.getChapters(manga).executeAsBlocking()
|
||||||
it.last_page_read = 0
|
val chapters = oldChapters.copy()
|
||||||
}
|
chapters.forEach {
|
||||||
db.updateChaptersProgress(chapters).executeAsBlocking()
|
it.read = markRead
|
||||||
if (markRead && preferences.removeAfterMarkedAsRead()) {
|
it.last_page_read = 0
|
||||||
deleteChapters(it, chapters)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
getLibrary()
|
db.updateChaptersProgress(chapters).executeAsBlocking()
|
||||||
|
|
||||||
|
mapMangaChapters[manga] = oldChapters
|
||||||
|
}
|
||||||
|
getLibrary()
|
||||||
|
}
|
||||||
|
return mapMangaChapters
|
||||||
|
}
|
||||||
|
|
||||||
|
fun undoMarkReadStatus(
|
||||||
|
mangaList: HashMap<Manga, List<Chapter>>,
|
||||||
|
) {
|
||||||
|
launchIO {
|
||||||
|
mangaList.forEach { (_, chapters) ->
|
||||||
|
db.updateChaptersProgress(chapters).executeAsBlocking()
|
||||||
|
}
|
||||||
|
getLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun confirmMarkReadStatus(
|
||||||
|
mangaList: HashMap<Manga, List<Chapter>>,
|
||||||
|
markRead: Boolean
|
||||||
|
) {
|
||||||
|
if (preferences.removeAfterMarkedAsRead() && markRead) {
|
||||||
|
mangaList.forEach { (manga, oldChapters) ->
|
||||||
|
deleteChapters(manga, oldChapters)
|
||||||
|
}
|
||||||
|
if (preferences.downloadBadge().get()) {
|
||||||
|
requestDownloadBadgesUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
|
import eu.kanade.tachiyomi.util.lang.toNormalized
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
import eu.kanade.tachiyomi.util.system.isInNightMode
|
||||||
import eu.kanade.tachiyomi.util.system.isLTR
|
import eu.kanade.tachiyomi.util.system.isLTR
|
||||||
|
@ -126,7 +127,7 @@ class MangaHeaderHolder(
|
||||||
adapter.delegate.favoriteManga(false)
|
adapter.delegate.favoriteManga(false)
|
||||||
}
|
}
|
||||||
title.setOnClickListener {
|
title.setOnClickListener {
|
||||||
title.text?.let { adapter.delegate.globalSearch(it.toString()) }
|
title.text?.let { adapter.delegate.globalSearch(it.toString().toNormalized()) }
|
||||||
}
|
}
|
||||||
title.setOnLongClickListener {
|
title.setOnLongClickListener {
|
||||||
adapter.delegate.copyToClipboard(title.text.toString(), R.string.title)
|
adapter.delegate.copyToClipboard(title.text.toString(), R.string.title)
|
||||||
|
|
|
@ -2,6 +2,9 @@ package eu.kanade.tachiyomi.ui.migration
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that holds the catalogue cards.
|
* Adapter that holds the catalogue cards.
|
||||||
|
@ -13,6 +16,9 @@ class SourceAdapter(val allClickListener: OnAllClickListener) :
|
||||||
|
|
||||||
private var items: List<IFlexible<*>>? = null
|
private var items: List<IFlexible<*>>? = null
|
||||||
|
|
||||||
|
val isMultiLanguage =
|
||||||
|
Injekt.get<PreferencesHelper>().enabledLanguages().get().filterNot { it == "all" }.size > 1
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDisplayHeadersAtStartUp(true)
|
setDisplayHeadersAtStartUp(true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ class SourceHolder(view: View, val adapter: SourceAdapter) :
|
||||||
val source = item.source
|
val source = item.source
|
||||||
|
|
||||||
// Set source name
|
// Set source name
|
||||||
binding.title.text = source.name
|
val sourceName =
|
||||||
|
if (adapter.isMultiLanguage) source.toString() else source.name.capitalize()
|
||||||
|
binding.title.text = sourceName
|
||||||
|
|
||||||
// Set circle letter image.
|
// Set circle letter image.
|
||||||
itemView.post {
|
itemView.post {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import eu.kanade.tachiyomi.ui.migration.MigrationMangaDialog
|
||||||
import eu.kanade.tachiyomi.ui.migration.SearchController
|
import eu.kanade.tachiyomi.ui.migration.SearchController
|
||||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
|
import eu.kanade.tachiyomi.util.lang.toNormalized
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
|
@ -330,6 +331,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
||||||
} else {
|
} else {
|
||||||
sources.filter { it.id != manga.source }
|
sources.filter { it.id != manga.source }
|
||||||
}
|
}
|
||||||
|
manga.title = manga.title.toNormalized()
|
||||||
val searchController = SearchController(manga, validSources)
|
val searchController = SearchController(manga, validSources)
|
||||||
searchController.targetController = this@MigrationListController
|
searchController.targetController = this@MigrationListController
|
||||||
router.pushController(searchController.withFadeTransaction())
|
router.pushController(searchController.withFadeTransaction())
|
||||||
|
|
|
@ -51,7 +51,6 @@ import eu.kanade.tachiyomi.data.preference.asImmediateFlowIn
|
||||||
import eu.kanade.tachiyomi.data.preference.toggle
|
import eu.kanade.tachiyomi.data.preference.toggle
|
||||||
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
|
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
|
||||||
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
||||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||||
|
@ -1379,14 +1378,8 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
||||||
|
|
||||||
override fun onProvideAssistContent(outContent: AssistContent) {
|
override fun onProvideAssistContent(outContent: AssistContent) {
|
||||||
super.onProvideAssistContent(outContent)
|
super.onProvideAssistContent(outContent)
|
||||||
val manga = presenter.manga ?: return
|
val chapterUrl = presenter.getChapterUrl() ?: return
|
||||||
val source = presenter.source as? HttpSource ?: return
|
outContent.webUri = Uri.parse(chapterUrl)
|
||||||
val url = try {
|
|
||||||
source.mangaDetailsRequest(manga).url.toString()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
outContent.webUri = Uri.parse(url)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1526,16 +1519,12 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
||||||
|
|
||||||
private fun openMangaInBrowser() {
|
private fun openMangaInBrowser() {
|
||||||
val source = presenter.getSource() ?: return
|
val source = presenter.getSource() ?: return
|
||||||
val url = try {
|
val chapterUrl = presenter.getChapterUrl() ?: return
|
||||||
source.mangaDetailsRequest(presenter.manga!!).url.toString()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val intent = WebViewActivity.newIntent(
|
val intent = WebViewActivity.newIntent(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
source.id,
|
source.id,
|
||||||
url,
|
chapterUrl,
|
||||||
presenter.manga!!.title
|
presenter.manga!!.title
|
||||||
)
|
)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
|
|
|
@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.ui.reader.settings.ReadingModeType
|
||||||
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
||||||
import eu.kanade.tachiyomi.util.chapter.ChapterSort
|
import eu.kanade.tachiyomi.util.chapter.ChapterSort
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
|
import eu.kanade.tachiyomi.util.lang.getUrlWithoutDomain
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
|
@ -565,6 +566,18 @@ class ReaderPresenter(
|
||||||
return viewerChaptersRelay.value?.currChapter
|
return viewerChaptersRelay.value?.currChapter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getChapterUrl(): String? {
|
||||||
|
val source = getSource() ?: return null
|
||||||
|
val chapterUrl = getCurrentChapter()?.chapter?.url?.getUrlWithoutDomain()
|
||||||
|
|
||||||
|
return if (chapterUrl.isNullOrBlank()) try {
|
||||||
|
val manga = manga ?: return null
|
||||||
|
source.mangaDetailsRequest(manga).url.toString()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
} else source.baseUrl + chapterUrl
|
||||||
|
}
|
||||||
|
|
||||||
fun getSource() = sourceManager.getOrStub(manga!!.source) as? HttpSource
|
fun getSource() = sourceManager.getOrStub(manga!!.source) as? HttpSource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,9 @@ package eu.kanade.tachiyomi.ui.source
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that holds the catalogue cards.
|
* Adapter that holds the catalogue cards.
|
||||||
|
@ -17,6 +20,9 @@ class SourceAdapter(val controller: BrowseController) :
|
||||||
|
|
||||||
val sourceListener: SourceListener = controller
|
val sourceListener: SourceListener = controller
|
||||||
|
|
||||||
|
val isMultiLanguage =
|
||||||
|
Injekt.get<PreferencesHelper>().enabledLanguages().get().filterNot { it == "all" }.size > 1
|
||||||
|
|
||||||
override fun onItemSwiped(position: Int, direction: Int) {
|
override fun onItemSwiped(position: Int, direction: Int) {
|
||||||
super.onItemSwiped(position, direction)
|
super.onItemSwiped(position, direction)
|
||||||
controller.hideCatalogue(position)
|
controller.hideCatalogue(position)
|
||||||
|
|
|
@ -29,10 +29,13 @@ class SourceHolder(view: View, val adapter: SourceAdapter) :
|
||||||
val source = item.source
|
val source = item.source
|
||||||
// setCardEdges(item)
|
// setCardEdges(item)
|
||||||
|
|
||||||
|
val underPinnedSection = item.header?.code?.equals(SourcePresenter.PINNED_KEY) ?: false
|
||||||
|
val isPinned = item.isPinned ?: underPinnedSection
|
||||||
// Set source name
|
// Set source name
|
||||||
binding.title.text = source.name
|
val sourceName =
|
||||||
|
if (adapter.isMultiLanguage && underPinnedSection) source.toString() else source.name
|
||||||
|
binding.title.text = sourceName
|
||||||
|
|
||||||
val isPinned = item.isPinned ?: item.header?.code?.equals(SourcePresenter.PINNED_KEY) ?: false
|
|
||||||
binding.sourcePin.apply {
|
binding.sourcePin.apply {
|
||||||
imageTintList = ColorStateList.valueOf(
|
imageTintList = ColorStateList.valueOf(
|
||||||
context.getResourceColor(
|
context.getResourceColor(
|
||||||
|
|
|
@ -128,14 +128,20 @@ fun syncChaptersWithSource(
|
||||||
var now = Date().time
|
var now = Date().time
|
||||||
|
|
||||||
for (i in toAdd.indices.reversed()) {
|
for (i in toAdd.indices.reversed()) {
|
||||||
val c = toAdd[i]
|
val chapter = toAdd[i]
|
||||||
c.date_fetch = now++
|
chapter.date_fetch = now++
|
||||||
// Try to mark already read chapters as read when the source deletes them
|
if (chapter.isRecognizedNumber && chapter.chapter_number in deletedChapterNumbers) {
|
||||||
if (c.isRecognizedNumber && c.chapter_number in deletedReadChapterNumbers) {
|
// Try to mark already read chapters as read when the source deletes them
|
||||||
c.read = true
|
if (chapter.chapter_number in deletedReadChapterNumbers) {
|
||||||
}
|
chapter.read = true
|
||||||
if (c.isRecognizedNumber && c.chapter_number in deletedChapterNumbers) {
|
}
|
||||||
readded.add(c)
|
// Try to to use the fetch date it originally had to not pollute 'Updates' tab
|
||||||
|
toDelete.filter { it.chapter_number == chapter.chapter_number }
|
||||||
|
.minByOrNull { it.date_fetch }?.let {
|
||||||
|
chapter.date_fetch = it.date_fetch
|
||||||
|
}
|
||||||
|
|
||||||
|
readded.add(chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val chapters = db.insertChapters(toAdd).executeAsBlocking()
|
val chapters = db.insertChapters(toAdd).executeAsBlocking()
|
||||||
|
|
|
@ -16,6 +16,8 @@ import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
|
||||||
|
import java.net.URI
|
||||||
|
import java.net.URISyntaxException
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,3 +148,21 @@ fun String.addBetaTag(context: Context): Spanned {
|
||||||
betaSpan.setSpan(ForegroundColorSpan(context.getResourceColor(R.attr.colorSecondary)), length, length + betaText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
betaSpan.setSpan(ForegroundColorSpan(context.getResourceColor(R.attr.colorSecondary)), length, length + betaText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
return betaSpan
|
return betaSpan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.toNormalized(): String = replace("’", "'")
|
||||||
|
|
||||||
|
fun String.getUrlWithoutDomain(): String {
|
||||||
|
return try {
|
||||||
|
val uri = URI(this.replace(" ", "%20"))
|
||||||
|
var out = uri.path
|
||||||
|
if (uri.query != null) {
|
||||||
|
out += "?" + uri.query
|
||||||
|
}
|
||||||
|
if (uri.fragment != null) {
|
||||||
|
out += "#" + uri.fragment
|
||||||
|
}
|
||||||
|
out
|
||||||
|
} catch (e: URISyntaxException) {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue