diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt index b55f9d132..5b65235bb 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt @@ -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 } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/LocalMangaRepository.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/LocalMangaRepository.kt index 97029d856..822d0a52d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/LocalMangaRepository.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/LocalMangaRepository.kt @@ -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() + private val locks = CompositeMutex2() override val sortOrders: Set = 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() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt index a6a1c4bdc..36368fddf 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt @@ -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) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt index ce04320ea..339bcfcba 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaDirOutput.kt @@ -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 diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaZipOutput.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaZipOutput.kt index 23caca4fa..0596a7324 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaZipOutput.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/output/LocalMangaZipOutput.kt @@ -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() { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalChaptersRemoveService.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalChaptersRemoveService.kt index b09d7180f..b19b955da 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalChaptersRemoveService.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalChaptersRemoveService.kt @@ -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) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt index bdceb0328..882ea4646 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/ui/LocalListMenuProvider.kt @@ -24,7 +24,7 @@ class LocalListMenuProvider( true } - R.id.action_settings -> { + R.id.action_directories -> { context.startActivity(MangaDirectoriesActivity.newIntent(context)) true } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt index 629d781d5..20c12d7d9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt @@ -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) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigViewModel.kt index fc7c5e25d..c9ff9bc5f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigViewModel.kt @@ -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) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt index 84b58dfb3..41f27351a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt @@ -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) { diff --git a/app/src/main/res/drawable-v23/toolbar_background.xml b/app/src/main/res/drawable-v23/toolbar_background.xml deleted file mode 100644 index e70169f07..000000000 --- a/app/src/main/res/drawable-v23/toolbar_background.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/toolbar_background.xml b/app/src/main/res/drawable/toolbar_background.xml deleted file mode 100644 index 6da93cfb9..000000000 --- a/app/src/main/res/drawable/toolbar_background.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index 219cbaece..bebcbb8f7 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -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" />