mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 13:51:48 +01:00
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:
parent
2661cd6e2e
commit
60f43e4457
@ -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"
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
// For double pages, check if the second to last page is doubled up
|
val shouldTrack = !preferences.incognitoMode().get() || hasTrackers
|
||||||
if (selectedChapter.pages?.lastIndex == page.index ||
|
if (shouldTrack &&
|
||||||
(hasExtraPage && selectedChapter.pages?.lastIndex?.minus(1) == page.index)
|
// 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
|
selectedChapter.chapter.read = true
|
||||||
updateTrackChapterRead(selectedChapter)
|
updateTrackChapterRead(selectedChapter)
|
||||||
@ -521,20 +534,25 @@ 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
|
||||||
}
|
}
|
||||||
db.updateChapterProgress(chapter.chapter).executeAsBlocking()
|
if (!preferences.incognitoMode().get() || hasTrackers) {
|
||||||
|
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) {
|
||||||
val history = History.create(chapter.chapter).apply { last_read = Date().time }
|
if (!preferences.incognitoMode().get()) {
|
||||||
db.updateHistoryLastRead(history).executeAsBlocking()
|
val history = History.create(chapter.chapter).apply { last_read = Date().time }
|
||||||
|
db.updateHistoryLastRead(history).executeAsBlocking()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,15 +440,17 @@ 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) {
|
||||||
preferences.lastUsedCatalogueSource().set(source.id)
|
if (!preferences.incognitoMode().get()) {
|
||||||
if (source !is LocalSource) {
|
preferences.lastUsedCatalogueSource().set(source.id)
|
||||||
val list = preferences.lastUsedSources().get().toMutableSet()
|
if (source !is LocalSource) {
|
||||||
list.removeAll { it.startsWith("${source.id}:") }
|
val list = preferences.lastUsedSources().get().toMutableSet()
|
||||||
list.add("${source.id}:${Date().time}")
|
list.removeAll { it.startsWith("${source.id}:") }
|
||||||
val sortedList = list.filter { it.split(":").size == 2 }
|
list.add("${source.id}:${Date().time}")
|
||||||
.sortedByDescending { it.split(":").last().toLong() }
|
val sortedList = list.filter { it.split(":").size == 2 }
|
||||||
preferences.lastUsedSources()
|
.sortedByDescending { it.split(":").last().toLong() }
|
||||||
.set(sortedList.take(2).toSet())
|
preferences.lastUsedSources()
|
||||||
|
.set(sortedList.take(2).toSet())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
router.pushController(controller.withFadeTransaction())
|
router.pushController(controller.withFadeTransaction())
|
||||||
}
|
}
|
||||||
|
8
app/src/main/res/drawable/ic_incognito_circle_24dp.xml
Normal file
8
app/src/main/res/drawable/ic_incognito_circle_24dp.xml
Normal 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>
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user