From 08fb2fe467a786e1273bf22531361d33ae898a38 Mon Sep 17 00:00:00 2001
From: FourTOne5 <59261191+FourTOne5@users.noreply.github.com>
Date: Thu, 12 May 2022 19:00:57 +0600
Subject: [PATCH] Add option to reset viewer flags (#7062)

* Add option to reset viewer flags

* Review Changes

* Run `resetViewerFlags()` content with `launchIO`
---
 .../kanade/data/manga/MangaRepositoryImpl.kt  | 12 +++++
 .../java/eu/kanade/domain/DomainModule.kt     |  2 +
 .../manga/interactor/ResetViewerFlags.kt      | 11 +++++
 .../manga/repository/MangaRepository.kt       |  2 +
 .../ui/setting/SettingsAdvancedController.kt  | 49 ++++++++++++++-----
 app/src/main/res/values/strings.xml           |  4 ++
 app/src/main/sqldelight/data/mangas.sq        |  6 ++-
 7 files changed, 74 insertions(+), 12 deletions(-)
 create mode 100644 app/src/main/java/eu/kanade/domain/manga/interactor/ResetViewerFlags.kt

diff --git a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt
index 11c67db775..70ff72e294 100644
--- a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt
+++ b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt
@@ -3,7 +3,9 @@ package eu.kanade.data.manga
 import eu.kanade.data.DatabaseHandler
 import eu.kanade.domain.manga.model.Manga
 import eu.kanade.domain.manga.repository.MangaRepository
+import eu.kanade.tachiyomi.util.system.logcat
 import kotlinx.coroutines.flow.Flow
+import logcat.LogPriority
 
 class MangaRepositoryImpl(
     private val databaseHandler: DatabaseHandler,
@@ -12,4 +14,14 @@ class MangaRepositoryImpl(
     override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> {
         return databaseHandler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
     }
+
+    override suspend fun resetViewerFlags(): Boolean {
+        return try {
+            databaseHandler.await { mangasQueries.resetViewerFlags() }
+            true
+        } catch (e: Exception) {
+            logcat(LogPriority.ERROR, e)
+            false
+        }
+    }
 }
diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt
index ee5668767d..7e9cd3de1a 100644
--- a/app/src/main/java/eu/kanade/domain/DomainModule.kt
+++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt
@@ -10,6 +10,7 @@ import eu.kanade.domain.history.interactor.RemoveHistoryById
 import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
 import eu.kanade.domain.history.repository.HistoryRepository
 import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
+import eu.kanade.domain.manga.interactor.ResetViewerFlags
 import eu.kanade.domain.manga.repository.MangaRepository
 import eu.kanade.domain.source.interactor.GetEnabledSources
 import eu.kanade.domain.source.interactor.GetLanguagesWithSources
@@ -31,6 +32,7 @@ class DomainModule : InjektModule {
         addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
         addFactory { GetFavoritesBySourceId(get()) }
         addFactory { GetNextChapterForManga(get()) }
+        addFactory { ResetViewerFlags(get()) }
 
         addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
         addFactory { DeleteHistoryTable(get()) }
diff --git a/app/src/main/java/eu/kanade/domain/manga/interactor/ResetViewerFlags.kt b/app/src/main/java/eu/kanade/domain/manga/interactor/ResetViewerFlags.kt
new file mode 100644
index 0000000000..cc07264e34
--- /dev/null
+++ b/app/src/main/java/eu/kanade/domain/manga/interactor/ResetViewerFlags.kt
@@ -0,0 +1,11 @@
+package eu.kanade.domain.manga.interactor
+
+import eu.kanade.domain.manga.repository.MangaRepository
+
+class ResetViewerFlags(
+    private val mangaRepository: MangaRepository
+) {
+    suspend fun await(): Boolean {
+        return mangaRepository.resetViewerFlags()
+    }
+}
diff --git a/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt
index 8fb60a78a1..0dcf680822 100644
--- a/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt
+++ b/app/src/main/java/eu/kanade/domain/manga/repository/MangaRepository.kt
@@ -6,4 +6,6 @@ import kotlinx.coroutines.flow.Flow
 interface MangaRepository {
 
     fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
+
+    suspend fun resetViewerFlags(): Boolean
 }
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
index e0557e2d38..3e35c5c413 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt
@@ -9,9 +9,9 @@ import android.webkit.WebView
 import androidx.core.net.toUri
 import androidx.preference.PreferenceScreen
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import eu.kanade.domain.manga.repository.MangaRepository
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.cache.ChapterCache
-import eu.kanade.tachiyomi.data.database.DatabaseHelper
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
 import eu.kanade.tachiyomi.data.preference.PreferenceValues
@@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.ui.base.controller.pushController
 import eu.kanade.tachiyomi.ui.setting.database.ClearDatabaseController
 import eu.kanade.tachiyomi.util.CrashLogUtil
 import eu.kanade.tachiyomi.util.lang.launchIO
+import eu.kanade.tachiyomi.util.lang.withIOContext
 import eu.kanade.tachiyomi.util.lang.withUIContext
 import eu.kanade.tachiyomi.util.preference.bindTo
 import eu.kanade.tachiyomi.util.preference.defaultValue
@@ -45,17 +46,21 @@ import eu.kanade.tachiyomi.util.system.logcat
 import eu.kanade.tachiyomi.util.system.powerManager
 import eu.kanade.tachiyomi.util.system.setDefaultSettings
 import eu.kanade.tachiyomi.util.system.toast
+import kotlinx.coroutines.runBlocking
 import logcat.LogPriority
 import rikka.sui.Sui
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
 import uy.kohesive.injekt.injectLazy
 import java.io.File
 import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
 
-class SettingsAdvancedController : SettingsController() {
+class SettingsAdvancedController(
+    private val mangaRepository: MangaRepository = Injekt.get()
+) : SettingsController() {
 
     private val network: NetworkHelper by injectLazy()
     private val chapterCache: ChapterCache by injectLazy()
-    private val db: DatabaseHelper by injectLazy()
 
     @SuppressLint("BatteryLife")
     override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
@@ -216,6 +221,13 @@ class SettingsAdvancedController : SettingsController() {
 
                 onClick { LibraryUpdateService.start(context, target = Target.TRACKING) }
             }
+            preference {
+                key = "pref_reset_viewer_flags"
+                titleRes = R.string.pref_reset_viewer_flags
+                summaryRes = R.string.pref_reset_viewer_flags_summary
+
+                onClick { resetViewerFlags() }
+            }
         }
 
         preferenceCategory {
@@ -276,37 +288,52 @@ class SettingsAdvancedController : SettingsController() {
     }
 
     private fun clearChapterCache() {
-        if (activity == null) return
+        val activity = activity ?: return
         launchIO {
             try {
                 val deletedFiles = chapterCache.clear()
                 withUIContext {
-                    activity?.toast(resources?.getString(R.string.cache_deleted, deletedFiles))
+                    activity.toast(resources?.getString(R.string.cache_deleted, deletedFiles))
                     findPreference(CLEAR_CACHE_KEY)?.summary =
                         resources?.getString(R.string.used_cache, chapterCache.readableSize)
                 }
             } catch (e: Throwable) {
                 logcat(LogPriority.ERROR, e)
-                withUIContext { activity?.toast(R.string.cache_delete_error) }
+                withUIContext { activity.toast(R.string.cache_delete_error) }
             }
         }
     }
 
     private fun clearWebViewData() {
-        if (activity == null) return
+        val activity = activity ?: return
         try {
-            val webview = WebView(activity!!)
+            val webview = WebView(activity)
             webview.setDefaultSettings()
             webview.clearCache(true)
             webview.clearFormData()
             webview.clearHistory()
             webview.clearSslPreferences()
             WebStorage.getInstance().deleteAllData()
-            activity?.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() }
-            activity?.toast(R.string.webview_data_deleted)
+            activity.applicationInfo?.dataDir?.let { File("$it/app_webview/").deleteRecursively() }
+            activity.toast(R.string.webview_data_deleted)
         } catch (e: Throwable) {
             logcat(LogPriority.ERROR, e)
-            activity?.toast(R.string.cache_delete_error)
+            activity.toast(R.string.cache_delete_error)
+        }
+    }
+
+    private fun resetViewerFlags() {
+        val activity = activity ?: return
+        launchIO {
+            val isSuccesful = mangaRepository.resetViewerFlags()
+            withUIContext {
+                val resouurceString = if (isSuccesful) {
+                    R.string.pref_reset_viewer_flags_succesful
+                } else {
+                    R.string.pref_reset_viewer_flags_unsuccesful
+                }
+                activity.toast(resouurceString)
+            }
         }
     }
 }
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5a1d4b42db..cb3e79ed55 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -486,6 +486,10 @@
     <string name="pref_refresh_library_covers">Refresh library manga covers</string>
     <string name="pref_refresh_library_tracking">Refresh tracking</string>
     <string name="pref_refresh_library_tracking_summary">Updates status, score and last chapter read from the tracking services</string>
+    <string name="pref_reset_viewer_flags">Reset Viewer Flags</string>
+    <string name="pref_reset_viewer_flags_summary">Resets reading mode and orientation of all series</string>
+    <string name="pref_reset_viewer_flags_succesful">Viewer flags reset was succesful</string>
+    <string name="pref_reset_viewer_flags_unsuccesful">Couldn\'t reset viewer flags</string>
     <string name="pref_dump_crash_logs">Dump crash logs</string>
     <string name="pref_dump_crash_logs_summary">Saves error logs to a file for sharing with the developers</string>
     <string name="crash_log_saved">Crash logs saved</string>
diff --git a/app/src/main/sqldelight/data/mangas.sq b/app/src/main/sqldelight/data/mangas.sq
index e46bb4c5e0..a1b61f4228 100644
--- a/app/src/main/sqldelight/data/mangas.sq
+++ b/app/src/main/sqldelight/data/mangas.sq
@@ -42,4 +42,8 @@ getFavoriteBySourceId:
 SELECT *
 FROM mangas
 WHERE favorite = 1
-AND source = :sourceId;
\ No newline at end of file
+AND source = :sourceId;
+
+resetViewerFlags:
+UPDATE mangas
+SET viewer = 0;
\ No newline at end of file