This commit is contained in:
Koitharu
2023-10-16 12:02:52 +03:00
parent f3e597275b
commit 8bfdf07a2f
13 changed files with 38 additions and 59 deletions

View File

@@ -1,9 +1,9 @@
package org.koitharu.kotatsu.details.domain
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.model.findChapter
import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.history.data.PROGRESS_NONE
import org.koitharu.kotatsu.local.data.LocalMangaRepository
import org.koitharu.kotatsu.parsers.model.Manga
@@ -11,12 +11,12 @@ import javax.inject.Inject
class ProgressUpdateUseCase @Inject constructor(
private val mangaRepositoryFactory: MangaRepository.Factory,
private val historyRepository: HistoryRepository,
private val database: MangaDatabase,
private val localMangaRepository: LocalMangaRepository,
) {
suspend operator fun invoke(manga: Manga): Float {
val history = historyRepository.getOne(manga) ?: return PROGRESS_NONE
val history = database.historyDao.find(manga.id) ?: return PROGRESS_NONE
val seed = if (manga.isLocal) {
localMangaRepository.getRemoteManga(manga) ?: manga
} else {
@@ -42,13 +42,14 @@ class ProgressUpdateUseCase @Inject constructor(
val pagePercent = (history.page + 1) / pagesCount.toFloat()
val ppc = 1f / chaptersCount
val result = ppc * chapterIndex + ppc * pagePercent
historyRepository.addOrUpdate(
manga = details,
chapterId = chapter.id,
page = history.page,
scroll = history.scroll,
percent = result,
)
if (result != history.percent) {
database.historyDao.update(
history.copy(
chapterId = chapter.id,
percent = result,
),
)
}
return result
}
}

View File

@@ -14,7 +14,7 @@ import kotlinx.coroutines.runInterruptible
import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.CompositeMutex
import org.koitharu.kotatsu.core.util.CompositeMutex2
import org.koitharu.kotatsu.core.util.ext.children
import org.koitharu.kotatsu.core.util.ext.deleteAwait
import org.koitharu.kotatsu.core.util.ext.filterWith
@@ -45,7 +45,7 @@ class LocalMangaRepository @Inject constructor(
) : MangaRepository {
override val source = MangaSource.LOCAL
private val locks = CompositeMutex<Long>()
private val locks = CompositeMutex2<Long>()
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.RATING, SortOrder.NEWEST)
@@ -122,7 +122,7 @@ class LocalMangaRepository @Inject constructor(
suspend fun getRemoteManga(localManga: Manga): Manga? {
return runCatchingCancellable {
LocalMangaInput.of(localManga).getMangaInfo()
LocalMangaInput.of(localManga).getMangaInfo()?.takeUnless { it.isLocal }
}.onFailure {
it.printStackTraceDebug()
}.getOrNull()

View File

@@ -4,6 +4,7 @@ import androidx.annotation.WorkerThread
import org.json.JSONArray
import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource
@@ -21,7 +22,8 @@ class MangaIndex(source: String?) {
private val json: JSONObject = source?.let(::JSONObject) ?: JSONObject()
fun setMangaInfo(manga: Manga, append: Boolean) {
fun setMangaInfo(manga: Manga) {
require(!manga.isLocal) { "Local manga information cannot be stored" }
json.put("id", manga.id)
json.put("title", manga.title)
json.put("title_alt", manga.altTitle)
@@ -46,7 +48,7 @@ class MangaIndex(source: String?) {
}
},
)
if (!append || !json.has("chapters")) {
if (!json.has("chapters")) {
json.put("chapters", JSONObject())
}
json.put("app_id", BuildConfig.APPLICATION_ID)

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.local.data.output
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible
import org.koitharu.kotatsu.core.model.findById
import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.core.util.ext.deleteAwait
import org.koitharu.kotatsu.core.util.ext.takeIfReadable
import org.koitharu.kotatsu.core.zip.ZipOutput
@@ -21,7 +22,9 @@ class LocalMangaDirOutput(
private val index = MangaIndex(File(rootFile, ENTRY_NAME_INDEX).takeIfReadable()?.readText())
init {
index.setMangaInfo(manga, append = true)
if (!manga.isLocal) {
index.setMangaInfo(manga)
}
}
override suspend fun mergeWithExisting() = Unit

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.local.data.output
import androidx.annotation.WorkerThread
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible
import org.koitharu.kotatsu.core.model.isLocal
import org.koitharu.kotatsu.core.util.ext.deleteAwait
import org.koitharu.kotatsu.core.util.ext.readText
import org.koitharu.kotatsu.core.zip.ZipOutput
@@ -21,7 +22,9 @@ class LocalMangaZipOutput(
private val index = MangaIndex(null)
init {
index.setMangaInfo(manga, false)
if (!manga.isLocal) {
index.setMangaInfo(manga)
}
}
override suspend fun mergeWithExisting() {

View File

@@ -47,7 +47,7 @@ class LocalChaptersRemoveService : CoroutineIntentService() {
startForeground()
val mangaWithChapters = localMangaRepository.getDetails(manga)
localMangaRepository.deleteChapters(mangaWithChapters, chaptersIds)
localStorageChanges.emit(LocalManga(manga))
localStorageChanges.emit(LocalManga(localMangaRepository.getDetails(manga)))
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
}

View File

@@ -24,7 +24,7 @@ class LocalListMenuProvider(
true
}
R.id.action_settings -> {
R.id.action_directories -> {
context.startActivity(MangaDirectoriesActivity.newIntent(context))
true
}

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.colorfilter
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.Bitmap
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
@@ -121,10 +122,10 @@ class ColorFilterConfigActivity :
.scale(Scale.FILL)
.decodeRegion()
.tag(page.source)
.bitmapConfig(if (viewModel.is32BitColorsEnabled) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565)
.indicator(listOf(viewBinding.progressBefore, viewBinding.progressAfter))
.error(R.drawable.ic_error_placeholder)
.size(ViewSizeResolver(viewBinding.imageViewBefore))
.allowRgb565(false)
.target(DoubleViewTarget(viewBinding.imageViewBefore, viewBinding.imageViewAfter))
.enqueueWith(coil)
}

View File

@@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaPage
import org.koitharu.kotatsu.core.parser.MangaDataRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call
@@ -18,6 +19,7 @@ import javax.inject.Inject
@HiltViewModel
class ColorFilterConfigViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
private val settings: AppSettings,
private val mangaDataRepository: MangaDataRepository,
) : BaseViewModel() {
@@ -31,6 +33,9 @@ class ColorFilterConfigViewModel @Inject constructor(
val isChanged: Boolean
get() = colorFilter.value != initialColorFilter
val is32BitColorsEnabled: Boolean
get() = settings.is32BitColorsEnabled
init {
launchLoadingJob {
initialColorFilter = mangaDataRepository.getColorFilter(manga.id)

View File

@@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.distinctById
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
@@ -67,7 +68,7 @@ open class RemoteListViewModel @Inject constructor(
private var randomJob: Job? = null
override val content = combine(
mangaList.map { it?.skipNsfwIfNeeded() },
mangaList.map { it?.distinctById()?.skipNsfwIfNeeded() },
listMode,
listError,
hasNextPage,
@@ -138,7 +139,7 @@ open class RemoteListViewModel @Inject constructor(
} else if (list.isNotEmpty()) {
mangaList.value = mangaList.value?.plus(list) ?: list
}
hasNextPage.value = list.isNotEmpty()
hasNextPage.value = list.isNotEmpty() // TODO check if new ids added
} catch (e: CancellationException) {
throw e
} catch (e: Throwable) {

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Fills the entire area with the divider's color first... -->
<item>
<shape
android:shape="rectangle">
<solid android:color="?attr/colorOutline"/>
</shape>
</item>
<!-- ..., then draws a rectangle with the container color to cover the area not for the divider. -->
<item
android:bottom="1dp">
<shape
android:shape="rectangle">
<solid android:color="?attr/m3ColorBackground"/>
</shape>
</item>
</layer-list>

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Fills the entire area with the divider's color first... -->
<item>
<shape
android:shape="rectangle">
<solid android:color="@color/kotatsu_primaryContainer"/>
</shape>
</item>
<!-- ..., then draws a rectangle with the container color to cover the area not for the divider. -->
<item
android:bottom="1dp">
<shape
android:shape="rectangle">
<solid android:color="@color/kotatsu_m3_background"/>
</shape>
</item>
</layer-list>

View File

@@ -21,7 +21,6 @@
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@drawable/toolbar_background"
android:theme="?attr/actionBarTheme"
app:layout_scrollFlags="noScroll"
tools:ignore="PrivateResource" />