Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03426694c8 | ||
|
|
385003bcc8 | ||
|
|
225aacff43 | ||
|
|
208c0a494b | ||
|
|
0045c7cf44 | ||
|
|
eed7f89518 | ||
|
|
80c8b9eac0 | ||
|
|
53a680d13c | ||
|
|
3e77df20a2 | ||
|
|
7c1c0a38fa |
@@ -16,8 +16,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 600
|
||||
versionName = '6.4'
|
||||
versionCode = 601
|
||||
versionName = '6.4.1'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner "org.koitharu.kotatsu.HiltTestRunner"
|
||||
ksp {
|
||||
@@ -82,7 +82,7 @@ afterEvaluate {
|
||||
}
|
||||
dependencies {
|
||||
//noinspection GradleDependency
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:46e863ef79') {
|
||||
implementation('com.github.KotatsuApp:kotatsu-parsers:3bb10ee948') {
|
||||
exclude group: 'org.json', module: 'json'
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ dependencies {
|
||||
|
||||
implementation 'io.coil-kt:coil-base:2.5.0'
|
||||
implementation 'io.coil-kt:coil-svg:2.5.0'
|
||||
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:c7dab3aefe'
|
||||
implementation 'com.github.KotatsuApp:subsampling-scale-image-view:771c8753ae'
|
||||
implementation 'com.github.solkin:disk-lru-cache:1.4'
|
||||
implementation 'io.noties.markwon:core:4.6.2'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.core.parser
|
||||
|
||||
import android.net.Uri
|
||||
import coil.request.CachePolicy
|
||||
import dagger.Reusable
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
import org.koitharu.kotatsu.core.util.ext.ifNullOrEmpty
|
||||
@@ -85,7 +86,7 @@ class MangaLinkResolver @Inject constructor(
|
||||
|
||||
private suspend fun MangaRepository.getDetailsNoCache(manga: Manga): Manga {
|
||||
return if (this is RemoteMangaRepository) {
|
||||
getDetails(manga, withCache = false)
|
||||
getDetails(manga, CachePolicy.READ_ONLY)
|
||||
} else {
|
||||
getDetails(manga)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.core.parser
|
||||
|
||||
import android.util.Log
|
||||
import coil.request.CachePolicy
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -82,7 +83,7 @@ class RemoteMangaRepository(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = getDetails(manga, withCache = true)
|
||||
override suspend fun getDetails(manga: Manga): Manga = getDetails(manga, CachePolicy.ENABLED)
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
cache.getPages(source, chapter.url)?.let { return it }
|
||||
@@ -116,17 +117,18 @@ class RemoteMangaRepository(
|
||||
return related.await()
|
||||
}
|
||||
|
||||
suspend fun getDetails(manga: Manga, withCache: Boolean): Manga {
|
||||
if (!withCache) {
|
||||
return parser.getDetails(manga)
|
||||
suspend fun getDetails(manga: Manga, cachePolicy: CachePolicy): Manga {
|
||||
if (cachePolicy.readEnabled) {
|
||||
cache.getDetails(source, manga.url)?.let { return it }
|
||||
}
|
||||
cache.getDetails(source, manga.url)?.let { return it }
|
||||
val details = asyncSafe {
|
||||
mirrorSwitchInterceptor.withMirrorSwitching {
|
||||
parser.getDetails(manga)
|
||||
}
|
||||
}
|
||||
cache.putDetails(source, manga.url, details)
|
||||
if (cachePolicy.writeEnabled) {
|
||||
cache.putDetails(source, manga.url, details)
|
||||
}
|
||||
return details.await()
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ fun filterTagDelegate(
|
||||
) {
|
||||
|
||||
itemView.setOnClickListener {
|
||||
listener.onTagItemClick(item)
|
||||
listener.onTagItemClick(item, isFromChip = false)
|
||||
}
|
||||
|
||||
bind { payloads ->
|
||||
@@ -69,7 +69,7 @@ fun filterTagMultipleDelegate(
|
||||
) {
|
||||
|
||||
itemView.setOnClickListener {
|
||||
listener.onTagItemClick(item)
|
||||
listener.onTagItemClick(item, isFromChip = false)
|
||||
}
|
||||
|
||||
bind { payloads ->
|
||||
|
||||
@@ -92,10 +92,14 @@ class FilterCoordinator @Inject constructor(
|
||||
repository.defaultSortOrder = item.order
|
||||
}
|
||||
|
||||
override fun onTagItemClick(item: FilterItem.Tag) {
|
||||
override fun onTagItemClick(item: FilterItem.Tag, isFromChip: Boolean) {
|
||||
currentState.update { oldValue ->
|
||||
val newTags = if (!item.isMultiple) {
|
||||
setOf(item.tag)
|
||||
if (isFromChip && item.isChecked) {
|
||||
emptySet()
|
||||
} else {
|
||||
setOf(item.tag)
|
||||
}
|
||||
} else if (item.isChecked) {
|
||||
oldValue.tags - item.tag
|
||||
} else {
|
||||
|
||||
@@ -39,7 +39,8 @@ class FilterHeaderFragment : BaseFragment<FragmentFilterHeaderBinding>(), ChipsV
|
||||
if (tag == null) {
|
||||
FilterSheetFragment.show(parentFragmentManager)
|
||||
} else {
|
||||
filter.onTagItemClick(FilterItem.Tag(tag, filter.header.value.allowMultipleTags, !chip.isChecked))
|
||||
val filterItem = FilterItem.Tag(tag, filter.header.value.allowMultipleTags, !chip.isChecked)
|
||||
filter.onTagItemClick(filterItem, isFromChip = true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ interface OnFilterChangedListener : ListHeaderClickListener {
|
||||
|
||||
fun onSortItemClick(item: FilterItem.Sort)
|
||||
|
||||
fun onTagItemClick(item: FilterItem.Tag)
|
||||
fun onTagItemClick(item: FilterItem.Tag, isFromChip: Boolean)
|
||||
|
||||
fun onStateItemClick(item: FilterItem.State)
|
||||
}
|
||||
|
||||
@@ -98,7 +98,8 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
|
||||
if (filter == null) {
|
||||
startActivity(MangaListActivity.newIntent(requireContext(), setOf(tag)))
|
||||
} else {
|
||||
filter.onTagItemClick(FilterItem.Tag(tag, filter.header.value.allowMultipleTags, false))
|
||||
val filterItem = FilterItem.Tag(tag, filter.header.value.allowMultipleTags, false)
|
||||
filter.onTagItemClick(filterItem, isFromChip = false)
|
||||
closeSelf()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
@@ -43,7 +42,7 @@ class WebtoonHolder(
|
||||
if (settings.applyBitmapConfig(binding.ssiv)) {
|
||||
delegate.reload()
|
||||
}
|
||||
binding.ssiv.downsampling = if (isResumed()) 1 else getBackgroundDownsampling()
|
||||
// FIXME binding.ssiv.downsampling = if (isResumed()) 1 else getBackgroundDownsampling()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -53,7 +52,7 @@ class WebtoonHolder(
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
binding.ssiv.downsampling = getBackgroundDownsampling()
|
||||
// FIXME binding.ssiv.downsampling = getBackgroundDownsampling()
|
||||
}
|
||||
|
||||
override fun onBind(data: ReaderPage) {
|
||||
@@ -97,9 +96,6 @@ class WebtoonHolder(
|
||||
override fun onImageShowing(settings: ReaderSettings) {
|
||||
binding.ssiv.colorFilter = settings.colorFilter?.toColorFilter()
|
||||
with(binding.ssiv) {
|
||||
minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM
|
||||
minScale = width / sWidth.toFloat()
|
||||
maxScale = minScale
|
||||
scrollTo(
|
||||
when {
|
||||
scrollToRestore != 0 -> scrollToRestore
|
||||
|
||||
@@ -100,6 +100,17 @@ class WebtoonImageView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReady() {
|
||||
super.onReady()
|
||||
adjustScale()
|
||||
}
|
||||
|
||||
override fun onDownsamplingChanged() {
|
||||
super.onDownsamplingChanged()
|
||||
adjustScale()
|
||||
computeScrollRange()
|
||||
}
|
||||
|
||||
private fun scrollToInternal(pos: Int) {
|
||||
scrollPos = pos
|
||||
ct.set(sWidth / 2f, (height / 2f + pos.toFloat()) / minScale)
|
||||
@@ -117,4 +128,10 @@ class WebtoonImageView @JvmOverloads constructor(
|
||||
private fun parentHeight(): Int {
|
||||
return ancestors.firstNotNullOfOrNull { it as? RecyclerView }?.height ?: 0
|
||||
}
|
||||
|
||||
private fun adjustScale() {
|
||||
minScale = width / sWidth.toFloat()
|
||||
maxScale = minScale
|
||||
minimumScaleType = SCALE_TYPE_CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.koitharu.kotatsu.tracker.domain
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import coil.request.CachePolicy
|
||||
import org.koitharu.kotatsu.core.model.getPreferredBranch
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.history.data.HistoryRepository
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
@@ -76,7 +78,9 @@ class Tracker @Inject constructor(
|
||||
}
|
||||
|
||||
suspend fun fetchUpdates(track: MangaTracking, commit: Boolean): MangaUpdates.Success {
|
||||
val manga = mangaRepositoryFactory.create(track.manga.source).getDetails(track.manga)
|
||||
val repo = mangaRepositoryFactory.create(track.manga.source)
|
||||
require(repo is RemoteMangaRepository) { "Repository ${repo.javaClass.simpleName} is not supported" }
|
||||
val manga = repo.getDetails(track.manga, CachePolicy.WRITE_ONLY)
|
||||
val updates = compare(track, manga, getBranch(manga))
|
||||
if (commit) {
|
||||
repository.saveUpdates(updates)
|
||||
@@ -120,7 +124,7 @@ class Tracker @Inject constructor(
|
||||
manga = manga,
|
||||
newChapters = emptyList(),
|
||||
isValid = chapters.lastOrNull()?.id == track.lastChapterId,
|
||||
channelId = null
|
||||
channelId = null,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -522,4 +522,10 @@
|
||||
<string name="available_d">Даступна: %1$d</string>
|
||||
<string name="content_type_other">Іншае</string>
|
||||
<string name="state_paused">Прыпынена</string>
|
||||
<string name="error_multiple_states_not_supported">Фільтраванне па некалькіх станам не падтрымліваецца гэтай крыніцай мангі</string>
|
||||
<string name="reader_optimize">Памяншэнне спажывання памяці (бэта)</string>
|
||||
<string name="error_multiple_genres_not_supported">Фільтраванне па некалькіх жанрах не падтрымліваецца гэтай крыніцай мангі</string>
|
||||
<string name="error_search_not_supported">Пошук не падтрымліваецца гэтай крыніцай мангі</string>
|
||||
<string name="reader_optimize_summary">Паменшыць якасць закадравых старонак, каб выкарыстоўваць менш памяці</string>
|
||||
<string name="state">Стан</string>
|
||||
</resources>
|
||||
@@ -522,4 +522,10 @@
|
||||
<string name="disable_nsfw_summary">Desactivar las fuentes NSFW y ocultar el manga para adultos de la lista si es posible</string>
|
||||
<string name="available_d">Disponible: %1$d</string>
|
||||
<string name="state_paused">Pausado</string>
|
||||
<string name="error_multiple_states_not_supported">El filtrado por múltiples estados no es compatible con esta fuente del manga</string>
|
||||
<string name="reader_optimize">Reducir el consumo de memoria (beta)</string>
|
||||
<string name="error_multiple_genres_not_supported">Esta fuente del manga no permite filtrar por varios géneros</string>
|
||||
<string name="error_search_not_supported">La búsqueda no es compatible con esta fuente del manga</string>
|
||||
<string name="reader_optimize_summary">Reduce la resolución de las páginas fuera de pantalla para usar menos memoria</string>
|
||||
<string name="state">Estado</string>
|
||||
</resources>
|
||||
@@ -483,4 +483,49 @@
|
||||
<string name="zoom_out">Réduire</string>
|
||||
<string name="manga_list">Liste des mangas</string>
|
||||
<string name="to_top">En haut</string>
|
||||
<string name="sources_catalog">Sources catalogue</string>
|
||||
<string name="frequency_every_day">Tous les jours</string>
|
||||
<string name="categories">Catégories</string>
|
||||
<string name="list_options">Options de liste</string>
|
||||
<string name="content_type_manga">Mangas</string>
|
||||
<string name="error_multiple_states_not_supported">Filtrer par plusieurs états n\'est pas pris en charge par cette source de mangas</string>
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
<string name="backup_frequency">Fréquence de création de sauvegarde</string>
|
||||
<string name="content_type_hentai">Hentais</string>
|
||||
<string name="suggest_new_sources">Suggérer de nouvelles sources après la mise à jour de l\'application</string>
|
||||
<string name="periodic_backups_enable">Activer les sauvegardes périodiques</string>
|
||||
<string name="content_type_comics">Comics</string>
|
||||
<string name="catalog">Catalogue</string>
|
||||
<string name="enhanced_colors_summary">Réduit le crénelage, mais peut avoir une incidence sur les performances</string>
|
||||
<string name="frequency_every_2_days">Tous les 2 jours</string>
|
||||
<string name="reader_optimize">Réduire la consommation de mémoire (bêta)</string>
|
||||
<string name="manage_sources">Gérer les sources</string>
|
||||
<string name="no_manga_sources_found">Aucune source de manga disponible trouvée par votre requête</string>
|
||||
<string name="frequency_once_per_week">Une fois par semaine</string>
|
||||
<string name="periodic_backups">Sauvegardes périodiques</string>
|
||||
<string name="frequency_twice_per_month">Deux fois par mois</string>
|
||||
<string name="online_variant">Variante en ligne</string>
|
||||
<string name="error_multiple_genres_not_supported">Filtrer par plusieurs genres n\'est pas pris en charge par cette source manga</string>
|
||||
<string name="lock_screen_rotation">Verrouiller la rotation de l\'écran</string>
|
||||
<string name="by_relevance">Pertinence</string>
|
||||
<string name="state_abandoned">Abandonné</string>
|
||||
<string name="keep_screen_on">Garder l\'écran allumé</string>
|
||||
<string name="error_search_not_supported">La recherche n\'est pas prise en charge par cette source de mangas</string>
|
||||
<string name="frequency_once_per_month">Une fois par mois</string>
|
||||
<string name="manual">Manuel</string>
|
||||
<string name="reader_optimize_summary">Réduire la qualité des pages hors écran pour utiliser moins de mémoire</string>
|
||||
<string name="source_enabled">Source activée</string>
|
||||
<string name="enhanced_colors">mode couleur 32-bit</string>
|
||||
<string name="disable_nsfw_summary">Désactiver les sources pornographiques et masquer les mangas pour adultes de la liste si possible</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="keep_screen_on_summary">Ne pas désactiver l\'écran pendant que vous lisez des mangas</string>
|
||||
<string name="no_manga_sources_catalog_text">Il n\'y a pas de sources disponibles dans cette section, ou tout cela aurait pu être ajouté.
|
||||
\nRestez à l\'écoute</string>
|
||||
<string name="available_d">Disponible : %1$d</string>
|
||||
<string name="state">État</string>
|
||||
<string name="last_successful_backup">Dernière sauvegarde réussie : %s</string>
|
||||
<string name="state_paused">En pause</string>
|
||||
<string name="backups_output_directory">Sauvegardes répertoire de sortie</string>
|
||||
<string name="suggest_new_sources_summary">Prompt pour permettre des sources nouvellement ajoutées après la mise à jour de l\'application</string>
|
||||
<string name="content_type_other">Autre</string>
|
||||
</resources>
|
||||
@@ -522,4 +522,10 @@
|
||||
<string name="content_type_other">Другое</string>
|
||||
<string name="source_summary_pattern">%1$s, %2$s</string>
|
||||
<string name="state_paused">Приостановлено</string>
|
||||
<string name="error_multiple_states_not_supported">Фильтрация по нескольким состояниям не поддерживается этим источником манги</string>
|
||||
<string name="reader_optimize">Уменьшение потребления памяти (бета)</string>
|
||||
<string name="error_multiple_genres_not_supported">Фильтрация по нескольким жанрам не поддерживается этим источником манги</string>
|
||||
<string name="error_search_not_supported">Поиск не поддерживается этим источником манги</string>
|
||||
<string name="reader_optimize_summary">Уменьшить качество закадровых страниц, чтобы использовать меньше памяти</string>
|
||||
<string name="state">Состояние</string>
|
||||
</resources>
|
||||
@@ -30,7 +30,7 @@
|
||||
<string name="download_complete">İndirildi</string>
|
||||
<string name="downloads">İndirilenler</string>
|
||||
<string name="by_name">Ad</string>
|
||||
<string name="updated">Güncellenme</string>
|
||||
<string name="updated">Güncellendi</string>
|
||||
<string name="newest">Yeniler</string>
|
||||
<string name="by_rating">Puanlama</string>
|
||||
<string name="filter">Litre</string>
|
||||
@@ -112,7 +112,7 @@
|
||||
<string name="restore_backup">Yedekten geri yükle</string>
|
||||
<string name="update">Güncelle</string>
|
||||
<string name="sign_in">Oturum aç</string>
|
||||
<string name="state_finished">Bitti</string>
|
||||
<string name="state_finished">Tamamlandı</string>
|
||||
<string name="about">Hakkında</string>
|
||||
<string name="auth_required">Bu içeriği görüntülemek için oturum açın</string>
|
||||
<string name="confirm">Onayla</string>
|
||||
@@ -505,4 +505,27 @@
|
||||
<string name="backups_output_directory">Yedekleme dizini</string>
|
||||
<string name="speed_value">x%.1f</string>
|
||||
<string name="last_successful_backup">Son başarılı yedekleme: %s</string>
|
||||
<string name="sources_catalog">Kaynak kataloğu</string>
|
||||
<string name="content_type_manga">Manga</string>
|
||||
<string name="content_type_hentai">Hentai</string>
|
||||
<string name="catalog">Katalog</string>
|
||||
<string name="reader_optimize">Bellek kullanımını düşür (beta)</string>
|
||||
<string name="manage_sources">Kaynakları yönet</string>
|
||||
<string name="reader_optimize_summary">Daha az bellek kullanımı için ekran dışı sayfaların çözünürlüğünü düşür</string>
|
||||
<string name="source_enabled">Kaynak etkinleştirildi</string>
|
||||
<string name="no_manga_sources_catalog_text">Bu bölüm için kullanılabilir kaynak yok ya da hepsi zaten eklenmiş olabilir.
|
||||
\nTakipte kalın</string>
|
||||
<string name="state_paused">Durduruldu</string>
|
||||
<string name="content_type_other">Diğer</string>
|
||||
<string name="error_multiple_states_not_supported">Birden fazla duruma göre filtreleme bu manga kaynağı tarafından desteklenmemektedir</string>
|
||||
<string name="source_summary_pattern">%1$s,%2$s</string>
|
||||
<string name="content_type_comics">Karikatür</string>
|
||||
<string name="no_manga_sources_found">Sorgunuza göre mevcut manga kaynağı bulunamadı</string>
|
||||
<string name="error_multiple_genres_not_supported">Birden fazla türe göre filtreleme bu manga kaynağı tarafından desteklenmemektedir</string>
|
||||
<string name="lock_screen_rotation">Ekran döndürmeyi kilitle</string>
|
||||
<string name="error_search_not_supported">Arama bu manga kaynağı tarafından desteklenmemektedir</string>
|
||||
<string name="manual">Manuel</string>
|
||||
<string name="disable_nsfw_summary">Eğer mümkünse yetişkin içerik ve NSFW kaynaklarını arama listesinden kaldır</string>
|
||||
<string name="available_d">Mevcut:%1$d</string>
|
||||
<string name="state">Durum</string>
|
||||
</resources>
|
||||
@@ -522,4 +522,10 @@
|
||||
<string name="available_d">Доступно: %1$d</string>
|
||||
<string name="content_type_other">Інший</string>
|
||||
<string name="state_paused">Призупинено</string>
|
||||
<string name="error_multiple_states_not_supported">Фільтрування за кількома станами не підтримується цим джерелом манґи</string>
|
||||
<string name="reader_optimize">Зменшення споживання пам\'яті (бета)</string>
|
||||
<string name="error_multiple_genres_not_supported">Фільтрація за кількома жанрами не підтримується цим джерелом манґи</string>
|
||||
<string name="error_search_not_supported">Пошук не підтримується цим джерелом манґи</string>
|
||||
<string name="reader_optimize_summary">Зменшити якість закадрових сторінок, щоб використовувати менше пам\'яті</string>
|
||||
<string name="state">Стан</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user