Option to clear manga database
This commit is contained in:
@@ -58,6 +58,19 @@ abstract class MangaDao {
|
||||
@Delete
|
||||
abstract suspend fun delete(subjects: Collection<MangaEntity>)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
DELETE FROM manga WHERE NOT EXISTS(SELECT * FROM history WHERE history.manga_id == manga.manga_id)
|
||||
AND NOT EXISTS(SELECT * FROM favourites WHERE favourites.manga_id == manga.manga_id)
|
||||
AND NOT EXISTS(SELECT * FROM bookmarks WHERE bookmarks.manga_id == manga.manga_id)
|
||||
AND NOT EXISTS(SELECT * FROM suggestions WHERE suggestions.manga_id == manga.manga_id)
|
||||
AND NOT EXISTS(SELECT * FROM scrobblings WHERE scrobblings.manga_id == manga.manga_id)
|
||||
AND NOT EXISTS(SELECT * FROM local_index WHERE local_index.manga_id == manga.manga_id)
|
||||
AND manga.manga_id NOT IN (:idsToKeep)
|
||||
""",
|
||||
)
|
||||
abstract suspend fun cleanup(idsToKeep: Set<Long>)
|
||||
|
||||
@Transaction
|
||||
open suspend fun upsert(manga: MangaEntity, tags: Iterable<TagEntity>? = null) {
|
||||
upsert(manga)
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
||||
import org.koitharu.kotatsu.core.model.LocalMangaSource
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.core.nav.MangaIntent
|
||||
import org.koitharu.kotatsu.core.os.AppShortcutManager
|
||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||
import org.koitharu.kotatsu.core.util.ext.toFileOrNull
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
@@ -28,6 +29,7 @@ import javax.inject.Provider
|
||||
class MangaDataRepository @Inject constructor(
|
||||
private val db: MangaDatabase,
|
||||
private val resolverProvider: Provider<MangaLinkResolver>,
|
||||
private val appShortcutManagerProvider: Provider<AppShortcutManager>,
|
||||
) {
|
||||
|
||||
suspend fun saveReaderMode(manga: Manga, mode: ReaderMode) {
|
||||
@@ -119,7 +121,7 @@ class MangaDataRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun gcChapters() {
|
||||
suspend fun gcChaptersCache() {
|
||||
db.getChaptersDao().gc()
|
||||
}
|
||||
|
||||
@@ -136,6 +138,14 @@ class MangaDataRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun cleanupDatabase() {
|
||||
db.withTransaction {
|
||||
gcChaptersCache()
|
||||
val idsFromShortcuts = appShortcutManagerProvider.get().getMangaShortcuts()
|
||||
db.getMangaDao().cleanup(idsFromShortcuts)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MangaPrefsEntity.getColorFilterOrNull(): ReaderColorFilter? {
|
||||
return if (cfBrightness != 0f || cfContrast != 0f || cfInvert || cfGrayscale) {
|
||||
ReaderColorFilter(cfBrightness, cfContrast, cfInvert, cfGrayscale)
|
||||
|
||||
@@ -740,6 +740,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
|
||||
const val KEY_HANDLE_LINKS = "handle_links"
|
||||
const val KEY_BACKUP_TG_OPEN = "backup_periodic_tg_open"
|
||||
const val KEY_BACKUP_TG_TEST = "backup_periodic_tg_test"
|
||||
const val KEY_CLEAR_MANGA_DATA = "manga_data_clear"
|
||||
|
||||
// old keys are for migration only
|
||||
private const val KEY_IMAGES_PROXY_OLD = "images_proxy"
|
||||
|
||||
@@ -158,17 +158,17 @@ class HistoryRepository @Inject constructor(
|
||||
|
||||
suspend fun delete(manga: Manga) = db.withTransaction {
|
||||
db.getHistoryDao().delete(manga.id)
|
||||
mangaRepository.gcChapters()
|
||||
mangaRepository.gcChaptersCache()
|
||||
}
|
||||
|
||||
suspend fun deleteAfter(minDate: Long) = db.withTransaction {
|
||||
db.getHistoryDao().deleteAfter(minDate)
|
||||
mangaRepository.gcChapters()
|
||||
mangaRepository.gcChaptersCache()
|
||||
}
|
||||
|
||||
suspend fun deleteNotFavorite() = db.withTransaction {
|
||||
db.getHistoryDao().deleteNotFavorite()
|
||||
mangaRepository.gcChapters()
|
||||
mangaRepository.gcChaptersCache()
|
||||
}
|
||||
|
||||
suspend fun delete(ids: Collection<Long>): ReversibleHandle {
|
||||
@@ -176,7 +176,7 @@ class HistoryRepository @Inject constructor(
|
||||
for (id in ids) {
|
||||
db.getHistoryDao().delete(id)
|
||||
}
|
||||
mangaRepository.gcChapters()
|
||||
mangaRepository.gcChaptersCache()
|
||||
}
|
||||
return ReversibleHandle {
|
||||
recover(ids)
|
||||
|
||||
@@ -107,7 +107,7 @@ class UserDataSettingsFragment : BasePreferenceFragment(R.string.data_and_privac
|
||||
viewModel.loadingKeys.observe(viewLifecycleOwner) { keys ->
|
||||
loadingPrefs.addAll(keys)
|
||||
loadingPrefs.forEach { prefKey ->
|
||||
findPreference<Preference>(prefKey)!!.isEnabled = prefKey !in keys
|
||||
findPreference<Preference>(prefKey)?.isEnabled = prefKey !in keys
|
||||
}
|
||||
}
|
||||
viewModel.onError.observeEvent(viewLifecycleOwner, SnackbarErrorObserver(listView, this))
|
||||
@@ -153,6 +153,11 @@ class UserDataSettingsFragment : BasePreferenceFragment(R.string.data_and_privac
|
||||
true
|
||||
}
|
||||
|
||||
AppSettings.KEY_CLEAR_MANGA_DATA -> {
|
||||
viewModel.clearMangaData()
|
||||
true
|
||||
}
|
||||
|
||||
AppSettings.KEY_UPDATES_FEED_CLEAR -> {
|
||||
viewModel.clearUpdatesFeed()
|
||||
true
|
||||
|
||||
@@ -4,7 +4,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
@@ -13,6 +12,7 @@ import kotlinx.coroutines.runInterruptible
|
||||
import okhttp3.Cache
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||
import org.koitharu.kotatsu.core.parser.MangaDataRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
||||
import org.koitharu.kotatsu.core.ui.BaseViewModel
|
||||
@@ -27,6 +27,7 @@ import org.koitharu.kotatsu.search.domain.MangaSearchRepository
|
||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||
import java.util.EnumMap
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
@HiltViewModel
|
||||
class UserDataSettingsViewModel @Inject constructor(
|
||||
@@ -37,6 +38,7 @@ class UserDataSettingsViewModel @Inject constructor(
|
||||
private val cookieJar: MutableCookieJar,
|
||||
private val settings: AppSettings,
|
||||
private val deleteReadChaptersUseCase: DeleteReadChaptersUseCase,
|
||||
private val mangaDataRepositoryProvider: Provider<MangaDataRepository>,
|
||||
) : BaseViewModel() {
|
||||
|
||||
val onActionDone = MutableEventFlow<ReversibleAction>()
|
||||
@@ -139,6 +141,21 @@ class UserDataSettingsViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun clearMangaData() {
|
||||
launchJob(Dispatchers.Default) {
|
||||
try {
|
||||
loadingKeys.update { it + AppSettings.KEY_CLEAR_MANGA_DATA }
|
||||
trackingRepository.gc()
|
||||
val repository = mangaDataRepositoryProvider.get()
|
||||
repository.cleanupLocalManga()
|
||||
repository.cleanupDatabase()
|
||||
onActionDone.call(ReversibleAction(R.string.updates_feed_cleared, null))
|
||||
} finally {
|
||||
loadingKeys.update { it - AppSettings.KEY_CLEAR_MANGA_DATA }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun cleanupChapters() {
|
||||
launchJob(Dispatchers.Default) {
|
||||
try {
|
||||
|
||||
@@ -787,4 +787,6 @@
|
||||
<string name="test_connection">Test connection</string>
|
||||
<string name="telegram_chat_id_summary">Enter the chat ID where backups should be sent</string>
|
||||
<string name="open_telegram_bot_summary">Press to open chat with Kotatsu Backup Bot</string>
|
||||
<string name="clear_database">Clear database</string>
|
||||
<string name="clear_database_summary">Delete information about manga that is not used</string>
|
||||
</resources>
|
||||
|
||||
@@ -89,6 +89,12 @@
|
||||
android:summary="@string/loading_"
|
||||
android:title="@string/clear_network_cache" />
|
||||
|
||||
<Preference
|
||||
android:key="manga_data_clear"
|
||||
android:persistent="false"
|
||||
android:summary="@string/clear_database_summary"
|
||||
android:title="@string/clear_database" />
|
||||
|
||||
<Preference
|
||||
android:key="cookies_clear"
|
||||
android:persistent="false"
|
||||
|
||||
Reference in New Issue
Block a user