diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index b91ce7e426..a2f2bd3541 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -201,6 +201,8 @@ object PreferenceKeys { const val showNsfwExtension = "show_nsfw_extension" const val labelNsfwExtension = "label_nsfw_extension" + const val incognitoMode = "incognito_mode" + fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId" fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 8105ea5fdf..522d58d972 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -376,4 +376,6 @@ class PreferencesHelper(val context: Context) { fun createLegacyBackup() = flowPrefs.getBoolean(Keys.createLegacyBackup, true) fun dohProvider() = prefs.getInt(Keys.dohProvider, -1) + + fun incognitoMode() = flowPrefs.getBoolean(Keys.incognitoMode, false) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt index 42e708ce73..7c2a28d96c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt @@ -1,58 +1,110 @@ package eu.kanade.tachiyomi.ui.base +import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet +import android.view.Gravity import android.widget.TextView +import androidx.annotation.DrawableRes import androidx.appcompat.graphics.drawable.DrawerArrowDrawable +import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.textview.MaterialTextView import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.system.getResourceColor +@SuppressLint("CustomViewStyleable") class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : MaterialToolbar(context, attrs) { private lateinit var toolbarTitle: TextView + private val defStyleRes = com.google.android.material.R.style.Widget_MaterialComponents_Toolbar + + private val titleTextAppeance: Int + + var incognito = false + var hasDropdown: Boolean? = null + init { + val a = context.obtainStyledAttributes( + attrs, + R.styleable.Toolbar, + 0, + defStyleRes + ) + titleTextAppeance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0) + a.recycle() + } override fun onFinishInflate() { super.onFinishInflate() toolbarTitle = findViewById(R.id.toolbar_title) + toolbarTitle.setTextAppearance(titleTextAppeance) + toolbarTitle.setTextColor(context.getResourceColor(R.attr.actionBarTintColor)) } override fun setTitle(resId: Int) { - if (navigationIcon is DrawerArrowDrawable) { - super.setTitle(resId) - toolbarTitle.text = null - hideDropdown() - } else { - toolbarTitle.text = context.getString(resId) - super.setTitle(null) - } + setCustomTitle(context.getString(resId)) } override fun setTitle(title: CharSequence?) { - if (navigationIcon is DrawerArrowDrawable) { - super.setTitle(title) - toolbarTitle.text = "" - hideDropdown() - } else { - toolbarTitle.text = title - super.setTitle(null) + setCustomTitle(title) + } + + private fun setCustomTitle(title: CharSequence?) { + toolbarTitle.isVisible = true + toolbarTitle.text = title + super.setTitle(null) + toolbarTitle.updateLayoutParams { + gravity = if (navigationIcon is DrawerArrowDrawable) Gravity.START else Gravity.CENTER } + toolbarTitle.compoundDrawablePadding = if (navigationIcon is DrawerArrowDrawable) 6.dpToPx else 0 + if (navigationIcon is DrawerArrowDrawable) { + hideDropdown() + } + setIncognitoMode(incognito) + } + + fun hideDropdown() { + hasDropdown = null + setIcons() } fun showDropdown(down: Boolean = true) { + hasDropdown = down + setIcons() + } + + fun setIncognitoMode(enabled: Boolean) { + incognito = enabled + setIcons() + } + + private fun setIcons() { toolbarTitle.setCompoundDrawablesRelativeWithIntrinsicBounds( - R.drawable.ic_blank_24dp, + getIncogRes(), 0, - if (down) { - R.drawable.ic_arrow_drop_down_24dp - } else { - R.drawable.ic_arrow_drop_up_24dp - }, + getDropdownRes(), 0 ) } - fun hideDropdown() { - toolbarTitle.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) + @DrawableRes + private fun getIncogRes(): Int { + return when { + incognito -> R.drawable.ic_incognito_circle_24dp + hasDropdown != null -> R.drawable.ic_blank_24dp + else -> 0 + } + } + + @DrawableRes + private fun getDropdownRes(): Int { + return when { + hasDropdown == true -> R.drawable.ic_arrow_drop_down_24dp + hasDropdown == false -> R.drawable.ic_arrow_drop_up_24dp + incognito && navigationIcon !is DrawerArrowDrawable -> R.drawable.ic_blank_28dp + else -> 0 + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 8dbde18227..9d66db9ca8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -43,6 +43,7 @@ import eu.kanade.tachiyomi.data.download.DownloadServiceListener import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.Notifications +import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.updater.UpdateChecker import eu.kanade.tachiyomi.data.updater.UpdateResult @@ -79,6 +80,7 @@ import eu.kanade.tachiyomi.widget.EndAnimatorListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber @@ -321,6 +323,10 @@ open class MainActivity : BaseActivity(), DownloadServiceLi preferences.extensionUpdatesCount().asObservable().subscribe { setExtensionsBadge() } + + preferences.incognitoMode() + .asImmediateFlow { binding.toolbar.setIncognitoMode(it) } + .launchIn(lifecycleScope) setExtensionsBadge() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 40c0a8ae0b..acfe18a014 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -124,6 +124,13 @@ class ReaderPresenter( private var scope = CoroutineScope(Job() + Dispatchers.Default) + private var hasTrackers: Boolean = false + private val checkTrackers: (Manga) -> Unit = { manga -> + val tracks = db.getTracks(manga).executeAsBlocking() + + hasTrackers = tracks.size > 0 + } + /** * Called when the presenter is created. It retrieves the saved active chapter if the process * was restored. @@ -250,6 +257,8 @@ class ReaderPresenter( this.manga = manga if (chapterId == -1L) chapterId = initialChapterId + checkTrackers(manga) + NotificationReceiver.dismissNotification( preferences.context, manga.id!!.hashCode(), @@ -476,9 +485,13 @@ class ReaderPresenter( selectedChapter.chapter.last_page_read = page.index selectedChapter.chapter.pages_left = (selectedChapter.pages?.size ?: page.index) - page.index - // For double pages, check if the second to last page is doubled up - if (selectedChapter.pages?.lastIndex == page.index || - (hasExtraPage && selectedChapter.pages?.lastIndex?.minus(1) == page.index) + val shouldTrack = !preferences.incognitoMode().get() || hasTrackers + if (shouldTrack && + // For double pages, check if the second to last page is doubled up + ( + selectedChapter.pages?.lastIndex == page.index || + (hasExtraPage && selectedChapter.pages?.lastIndex?.minus(1) == page.index) + ) ) { selectedChapter.chapter.read = true updateTrackChapterRead(selectedChapter) @@ -521,20 +534,25 @@ class ReaderPresenter( /** * Saves this [chapter] progress (last read page and whether it's read). + * If incognito mode isn't on or has at least 1 tracker */ private fun saveChapterProgress(chapter: ReaderChapter) { db.getChapter(chapter.chapter.id!!).executeAsBlocking()?.let { dbChapter -> chapter.chapter.bookmark = dbChapter.bookmark } - db.updateChapterProgress(chapter.chapter).executeAsBlocking() + if (!preferences.incognitoMode().get() || hasTrackers) { + db.updateChapterProgress(chapter.chapter).executeAsBlocking() + } } /** * Saves this [chapter] last read history. */ private fun saveChapterHistory(chapter: ReaderChapter) { - val history = History.create(chapter.chapter).apply { last_read = Date().time } - db.updateHistoryLastRead(history).executeAsBlocking() + if (!preferences.incognitoMode().get()) { + val history = History.create(chapter.chapter).apply { last_read = Date().time } + db.updateHistoryLastRead(history).executeAsBlocking() + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/source/BrowseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/source/BrowseController.kt index 78d3a6acab..4fb36febfd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/source/BrowseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/source/BrowseController.kt @@ -440,15 +440,17 @@ class BrowseController : * Opens a catalogue with the given controller. */ private fun openCatalogue(source: CatalogueSource, controller: BrowseSourceController) { - preferences.lastUsedCatalogueSource().set(source.id) - if (source !is LocalSource) { - val list = preferences.lastUsedSources().get().toMutableSet() - list.removeAll { it.startsWith("${source.id}:") } - list.add("${source.id}:${Date().time}") - val sortedList = list.filter { it.split(":").size == 2 } - .sortedByDescending { it.split(":").last().toLong() } - preferences.lastUsedSources() - .set(sortedList.take(2).toSet()) + if (!preferences.incognitoMode().get()) { + preferences.lastUsedCatalogueSource().set(source.id) + if (source !is LocalSource) { + val list = preferences.lastUsedSources().get().toMutableSet() + list.removeAll { it.startsWith("${source.id}:") } + list.add("${source.id}:${Date().time}") + val sortedList = list.filter { it.split(":").size == 2 } + .sortedByDescending { it.split(":").last().toLong() } + preferences.lastUsedSources() + .set(sortedList.take(2).toSet()) + } } router.pushController(controller.withFadeTransaction()) } diff --git a/app/src/main/res/drawable/ic_incognito_circle_24dp.xml b/app/src/main/res/drawable/ic_incognito_circle_24dp.xml new file mode 100644 index 0000000000..fe7a9861c3 --- /dev/null +++ b/app/src/main/res/drawable/ic_incognito_circle_24dp.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ee2c302747..8a4b722fb3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -564,6 +564,11 @@ Help Search settings + Turn on %s + Turn off %s + Incognito mode + Pauses reading history + App theme Light Blue