Part 1 of incognito mode

Split this up into multiple commits since it's more readable but here goes:

Adding the preference for incognito mode (currently not togglable in this commit)

This is the logic from upstream, however as per ushe, there's difference in presentation. This one adds an incognito icon to toolbar. How it's displayed in upstream can work here to with (not too much) effort, but boy this was is easier and lazier

Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
Jays2Kings 2021-04-18 00:39:31 -04:00
parent 2661cd6e2e
commit 60f43e4457
8 changed files with 133 additions and 38 deletions

View File

@ -201,6 +201,8 @@ object PreferenceKeys {
const val showNsfwExtension = "show_nsfw_extension" const val showNsfwExtension = "show_nsfw_extension"
const val labelNsfwExtension = "label_nsfw_extension" const val labelNsfwExtension = "label_nsfw_extension"
const val incognitoMode = "incognito_mode"
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId" fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId" fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"

View File

@ -376,4 +376,6 @@ class PreferencesHelper(val context: Context) {
fun createLegacyBackup() = flowPrefs.getBoolean(Keys.createLegacyBackup, true) fun createLegacyBackup() = flowPrefs.getBoolean(Keys.createLegacyBackup, true)
fun dohProvider() = prefs.getInt(Keys.dohProvider, -1) fun dohProvider() = prefs.getInt(Keys.dohProvider, -1)
fun incognitoMode() = flowPrefs.getBoolean(Keys.incognitoMode, false)
} }

View File

@ -1,58 +1,110 @@
package eu.kanade.tachiyomi.ui.base package eu.kanade.tachiyomi.ui.base
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity
import android.widget.TextView import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable 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.appbar.MaterialToolbar
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import eu.kanade.tachiyomi.R 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) : class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
MaterialToolbar(context, attrs) { MaterialToolbar(context, attrs) {
private lateinit var toolbarTitle: TextView 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() { override fun onFinishInflate() {
super.onFinishInflate() super.onFinishInflate()
toolbarTitle = findViewById<MaterialTextView>(R.id.toolbar_title) toolbarTitle = findViewById<MaterialTextView>(R.id.toolbar_title)
toolbarTitle.setTextAppearance(titleTextAppeance)
toolbarTitle.setTextColor(context.getResourceColor(R.attr.actionBarTintColor))
} }
override fun setTitle(resId: Int) { override fun setTitle(resId: Int) {
if (navigationIcon is DrawerArrowDrawable) { setCustomTitle(context.getString(resId))
super.setTitle(resId)
toolbarTitle.text = null
hideDropdown()
} else {
toolbarTitle.text = context.getString(resId)
super.setTitle(null)
}
} }
override fun setTitle(title: CharSequence?) { override fun setTitle(title: CharSequence?) {
if (navigationIcon is DrawerArrowDrawable) { setCustomTitle(title)
super.setTitle(title) }
toolbarTitle.text = ""
hideDropdown() private fun setCustomTitle(title: CharSequence?) {
} else { toolbarTitle.isVisible = true
toolbarTitle.text = title toolbarTitle.text = title
super.setTitle(null) super.setTitle(null)
toolbarTitle.updateLayoutParams<LayoutParams> {
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) { fun showDropdown(down: Boolean = true) {
hasDropdown = down
setIcons()
}
fun setIncognitoMode(enabled: Boolean) {
incognito = enabled
setIcons()
}
private fun setIcons() {
toolbarTitle.setCompoundDrawablesRelativeWithIntrinsicBounds( toolbarTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_blank_24dp, getIncogRes(),
0, 0,
if (down) { getDropdownRes(),
R.drawable.ic_arrow_drop_down_24dp
} else {
R.drawable.ic_arrow_drop_up_24dp
},
0 0
) )
} }
fun hideDropdown() { @DrawableRes
toolbarTitle.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0) 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
}
} }
} }

View File

@ -43,6 +43,7 @@ import eu.kanade.tachiyomi.data.download.DownloadServiceListener
import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.notification.NotificationReceiver import eu.kanade.tachiyomi.data.notification.NotificationReceiver
import eu.kanade.tachiyomi.data.notification.Notifications 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.preference.getOrDefault
import eu.kanade.tachiyomi.data.updater.UpdateChecker import eu.kanade.tachiyomi.data.updater.UpdateChecker
import eu.kanade.tachiyomi.data.updater.UpdateResult import eu.kanade.tachiyomi.data.updater.UpdateResult
@ -79,6 +80,7 @@ import eu.kanade.tachiyomi.widget.EndAnimatorListener
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
@ -321,6 +323,10 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
preferences.extensionUpdatesCount().asObservable().subscribe { preferences.extensionUpdatesCount().asObservable().subscribe {
setExtensionsBadge() setExtensionsBadge()
} }
preferences.incognitoMode()
.asImmediateFlow { binding.toolbar.setIncognitoMode(it) }
.launchIn(lifecycleScope)
setExtensionsBadge() setExtensionsBadge()
} }

View File

@ -124,6 +124,13 @@ class ReaderPresenter(
private var scope = CoroutineScope(Job() + Dispatchers.Default) 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 * Called when the presenter is created. It retrieves the saved active chapter if the process
* was restored. * was restored.
@ -250,6 +257,8 @@ class ReaderPresenter(
this.manga = manga this.manga = manga
if (chapterId == -1L) chapterId = initialChapterId if (chapterId == -1L) chapterId = initialChapterId
checkTrackers(manga)
NotificationReceiver.dismissNotification( NotificationReceiver.dismissNotification(
preferences.context, preferences.context,
manga.id!!.hashCode(), manga.id!!.hashCode(),
@ -476,9 +485,13 @@ class ReaderPresenter(
selectedChapter.chapter.last_page_read = page.index selectedChapter.chapter.last_page_read = page.index
selectedChapter.chapter.pages_left = selectedChapter.chapter.pages_left =
(selectedChapter.pages?.size ?: page.index) - page.index (selectedChapter.pages?.size ?: page.index) - page.index
val shouldTrack = !preferences.incognitoMode().get() || hasTrackers
if (shouldTrack &&
// For double pages, check if the second to last page is doubled up // For double pages, check if the second to last page is doubled up
if (selectedChapter.pages?.lastIndex == page.index || (
selectedChapter.pages?.lastIndex == page.index ||
(hasExtraPage && selectedChapter.pages?.lastIndex?.minus(1) == page.index) (hasExtraPage && selectedChapter.pages?.lastIndex?.minus(1) == page.index)
)
) { ) {
selectedChapter.chapter.read = true selectedChapter.chapter.read = true
updateTrackChapterRead(selectedChapter) updateTrackChapterRead(selectedChapter)
@ -521,21 +534,26 @@ class ReaderPresenter(
/** /**
* Saves this [chapter] progress (last read page and whether it's read). * 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) { private fun saveChapterProgress(chapter: ReaderChapter) {
db.getChapter(chapter.chapter.id!!).executeAsBlocking()?.let { dbChapter -> db.getChapter(chapter.chapter.id!!).executeAsBlocking()?.let { dbChapter ->
chapter.chapter.bookmark = dbChapter.bookmark chapter.chapter.bookmark = dbChapter.bookmark
} }
if (!preferences.incognitoMode().get() || hasTrackers) {
db.updateChapterProgress(chapter.chapter).executeAsBlocking() db.updateChapterProgress(chapter.chapter).executeAsBlocking()
} }
}
/** /**
* Saves this [chapter] last read history. * Saves this [chapter] last read history.
*/ */
private fun saveChapterHistory(chapter: ReaderChapter) { private fun saveChapterHistory(chapter: ReaderChapter) {
if (!preferences.incognitoMode().get()) {
val history = History.create(chapter.chapter).apply { last_read = Date().time } val history = History.create(chapter.chapter).apply { last_read = Date().time }
db.updateHistoryLastRead(history).executeAsBlocking() db.updateHistoryLastRead(history).executeAsBlocking()
} }
}
/** /**
* Called from the activity to preload the given [chapter]. * Called from the activity to preload the given [chapter].

View File

@ -440,6 +440,7 @@ class BrowseController :
* Opens a catalogue with the given controller. * Opens a catalogue with the given controller.
*/ */
private fun openCatalogue(source: CatalogueSource, controller: BrowseSourceController) { private fun openCatalogue(source: CatalogueSource, controller: BrowseSourceController) {
if (!preferences.incognitoMode().get()) {
preferences.lastUsedCatalogueSource().set(source.id) preferences.lastUsedCatalogueSource().set(source.id)
if (source !is LocalSource) { if (source !is LocalSource) {
val list = preferences.lastUsedSources().get().toMutableSet() val list = preferences.lastUsedSources().get().toMutableSet()
@ -450,6 +451,7 @@ class BrowseController :
preferences.lastUsedSources() preferences.lastUsedSources()
.set(sortedList.take(2).toSet()) .set(sortedList.take(2).toSet())
} }
}
router.pushController(controller.withFadeTransaction()) router.pushController(controller.withFadeTransaction())
} }

View File

@ -0,0 +1,8 @@
<!-- drawable/incognito_circle.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="28dp"
android:width="28dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12 2C17.5 2 22 6.5 22 12S17.5 22 12 22 2 17.5 2 12 6.5 2 12 2M14.92 12.81C13.84 12.81 12.95 13.56 12.71 14.56C12.17 14.33 11.66 14.39 11.29 14.55C11.05 13.55 10.15 12.81 9.08 12.81C7.83 12.81 6.82 13.82 6.82 15.07C6.82 16.32 7.83 17.33 9.08 17.33C10.28 17.33 11.24 16.42 11.33 15.25C11.53 15.12 12.04 14.86 12.67 15.26C12.77 16.42 13.73 17.33 14.92 17.33C16.17 17.33 17.18 16.32 17.18 15.07C17.18 13.82 16.17 12.81 14.92 12.81M9.08 13.45C10 13.45 10.7 14.18 10.7 15.07C10.7 15.96 10 16.69 9.08 16.69C8.19 16.69 7.46 15.96 7.46 15.07C7.46 14.18 8.19 13.45 9.08 13.45M14.92 13.45C15.81 13.45 16.54 14.18 16.54 15.07C16.54 15.96 15.81 16.69 14.92 16.69C14 16.69 13.3 15.96 13.3 15.07C13.3 14.18 14 13.45 14.92 13.45M17.83 11.5H6.17V12.17H17.83V11.5M14.15 6.89C14 6.59 13.67 6.43 13.35 6.53L12 7L10.65 6.53L10.61 6.5C10.29 6.43 9.95 6.61 9.84 6.92L8.36 10.83H15.64L14.16 6.92L14.15 6.89Z" />
</vector>

View File

@ -564,6 +564,11 @@
<string name="help">Help</string> <string name="help">Help</string>
<string name="search_settings">Search settings</string> <string name="search_settings">Search settings</string>
<string name="turn_on_">Turn on %s</string>
<string name="turn_off_">Turn off %s</string>
<string name="incognito_mode">Incognito mode</string>
<string name="pauses_reading_history">Pauses reading history</string>
<!-- General settings --> <!-- General settings -->
<string name="app_theme">App theme</string> <string name="app_theme">App theme</string>
<string name="light_blue">Light Blue</string> <string name="light_blue">Light Blue</string>