Fixes
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class LocalListMenuProvider(
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_settings -> {
|
||||
R.id.action_directories -> {
|
||||
context.startActivity(MangaDirectoriesActivity.newIntent(context))
|
||||
true
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user