mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Show notification to disable Incognito Mode when it's enabled (#4976)
* Show notification to disable Incognito Mode when it's enabled * Finish ReaderActivity and BrowseSourceController when incognito is disabled * CLeanup strings * Only register DisableIncognitoReceiver when needed
This commit is contained in:
		@@ -2,14 +2,20 @@ package eu.kanade.tachiyomi
 | 
			
		||||
 | 
			
		||||
import android.app.ActivityManager
 | 
			
		||||
import android.app.Application
 | 
			
		||||
import android.app.PendingIntent
 | 
			
		||||
import android.content.BroadcastReceiver
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.IntentFilter
 | 
			
		||||
import android.content.res.Configuration
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import androidx.core.app.NotificationManagerCompat
 | 
			
		||||
import androidx.core.content.getSystemService
 | 
			
		||||
import androidx.lifecycle.Lifecycle
 | 
			
		||||
import androidx.lifecycle.LifecycleObserver
 | 
			
		||||
import androidx.lifecycle.OnLifecycleEvent
 | 
			
		||||
import androidx.lifecycle.ProcessLifecycleOwner
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import androidx.multidex.MultiDex
 | 
			
		||||
import coil.ImageLoader
 | 
			
		||||
import coil.ImageLoaderFactory
 | 
			
		||||
@@ -22,6 +28,9 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notification
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import org.acra.ACRA
 | 
			
		||||
import org.acra.annotation.AcraCore
 | 
			
		||||
import org.acra.annotation.AcraHttpSender
 | 
			
		||||
@@ -45,6 +54,8 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
 | 
			
		||||
 | 
			
		||||
    private val preferences: PreferencesHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private val disableIncognitoReceiver = DisableIncognitoReceiver()
 | 
			
		||||
 | 
			
		||||
    override fun onCreate() {
 | 
			
		||||
        super.onCreate()
 | 
			
		||||
        if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
 | 
			
		||||
@@ -65,6 +76,34 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
 | 
			
		||||
 | 
			
		||||
        // Reset Incognito Mode on relaunch
 | 
			
		||||
        preferences.incognitoMode().set(false)
 | 
			
		||||
 | 
			
		||||
        // Show notification to disable Incognito Mode when it's enabled
 | 
			
		||||
        preferences.incognitoMode().asFlow()
 | 
			
		||||
            .onEach { enabled ->
 | 
			
		||||
                val notificationManager = NotificationManagerCompat.from(this)
 | 
			
		||||
                if (enabled) {
 | 
			
		||||
                    disableIncognitoReceiver.register()
 | 
			
		||||
                    val notification = notification(Notifications.CHANNEL_INCOGNITO_MODE) {
 | 
			
		||||
                        setContentTitle(getString(R.string.pref_incognito_mode))
 | 
			
		||||
                        setContentText(getString(R.string.notification_incognito_text))
 | 
			
		||||
                        setSmallIcon(R.drawable.ic_glasses_black_24dp)
 | 
			
		||||
                        setOngoing(true)
 | 
			
		||||
 | 
			
		||||
                        val pendingIntent = PendingIntent.getBroadcast(
 | 
			
		||||
                            this@App,
 | 
			
		||||
                            0,
 | 
			
		||||
                            Intent(ACTION_DISABLE_INCOGNITO_MODE),
 | 
			
		||||
                            PendingIntent.FLAG_ONE_SHOT
 | 
			
		||||
                        )
 | 
			
		||||
                        setContentIntent(pendingIntent)
 | 
			
		||||
                    }
 | 
			
		||||
                    notificationManager.notify(Notifications.ID_INCOGNITO_MODE, notification)
 | 
			
		||||
                } else {
 | 
			
		||||
                    disableIncognitoReceiver.unregister()
 | 
			
		||||
                    notificationManager.cancel(Notifications.ID_INCOGNITO_MODE)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .launchIn(ProcessLifecycleOwner.get().lifecycleScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun attachBaseContext(base: Context) {
 | 
			
		||||
@@ -111,4 +150,30 @@ open class App : Application(), LifecycleObserver, ImageLoaderFactory {
 | 
			
		||||
    protected open fun setupNotificationChannels() {
 | 
			
		||||
        Notifications.createChannels(this)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private inner class DisableIncognitoReceiver : BroadcastReceiver() {
 | 
			
		||||
        private var registered = false
 | 
			
		||||
 | 
			
		||||
        override fun onReceive(context: Context, intent: Intent) {
 | 
			
		||||
            preferences.incognitoMode().set(false)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun register() {
 | 
			
		||||
            if (!registered) {
 | 
			
		||||
                registerReceiver(this, IntentFilter(ACTION_DISABLE_INCOGNITO_MODE))
 | 
			
		||||
                registered = true
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun unregister() {
 | 
			
		||||
            if (registered) {
 | 
			
		||||
                unregisterReceiver(this)
 | 
			
		||||
                registered = false
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,12 @@ object Notifications {
 | 
			
		||||
    const val CHANNEL_CRASH_LOGS = "crash_logs_channel"
 | 
			
		||||
    const val ID_CRASH_LOGS = -601
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Notification channel used for Incognito Mode
 | 
			
		||||
     */
 | 
			
		||||
    const val CHANNEL_INCOGNITO_MODE = "incognito_mode_channel"
 | 
			
		||||
    const val ID_INCOGNITO_MODE = -701
 | 
			
		||||
 | 
			
		||||
    private val deprecatedChannels = listOf(
 | 
			
		||||
        "downloader_channel",
 | 
			
		||||
        "backup_restore_complete_channel"
 | 
			
		||||
@@ -154,6 +160,11 @@ object Notifications {
 | 
			
		||||
                CHANNEL_CRASH_LOGS,
 | 
			
		||||
                context.getString(R.string.channel_crash_logs),
 | 
			
		||||
                NotificationManager.IMPORTANCE_HIGH
 | 
			
		||||
            ),
 | 
			
		||||
            NotificationChannel(
 | 
			
		||||
                CHANNEL_INCOGNITO_MODE,
 | 
			
		||||
                context.getString(R.string.pref_incognito_mode),
 | 
			
		||||
                NotificationManager.IMPORTANCE_LOW
 | 
			
		||||
            )
 | 
			
		||||
        ).forEach(context.notificationManager::createNotificationChannel)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.ToolbarLiftOnScrollController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.BrowseController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.download.DownloadController
 | 
			
		||||
import eu.kanade.tachiyomi.ui.library.LibraryController
 | 
			
		||||
@@ -224,7 +225,17 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
 | 
			
		||||
        preferences.incognitoMode()
 | 
			
		||||
            .asImmediateFlow { binding.incognitoMode.isVisible = it }
 | 
			
		||||
            .asImmediateFlow {
 | 
			
		||||
                binding.incognitoMode.isVisible = it
 | 
			
		||||
 | 
			
		||||
                // Close BrowseSourceController and its MangaController child when incognito mode is disabled
 | 
			
		||||
                if (!it) {
 | 
			
		||||
                    val fg = router.backstack.last().controller()
 | 
			
		||||
                    if (fg is BrowseSourceController || fg is MangaController && fg.fromSource) {
 | 
			
		||||
                        router.popToRoot()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,7 @@ class MangaController :
 | 
			
		||||
    var source: Source? = null
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
    private val fromSource = args.getBoolean(FROM_SOURCE_EXTRA, false)
 | 
			
		||||
    val fromSource = args.getBoolean(FROM_SOURCE_EXTRA, false)
 | 
			
		||||
 | 
			
		||||
    private val preferences: PreferencesHelper by injectLazy()
 | 
			
		||||
    private val coverCache: CoverCache by injectLazy()
 | 
			
		||||
 
 | 
			
		||||
@@ -167,6 +167,12 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
 | 
			
		||||
        window.decorView.setOnSystemUiVisibilityChangeListener {
 | 
			
		||||
            setMenuVisibility(menuVisible, animate = false)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Finish when incognito mode is disabled
 | 
			
		||||
        preferences.incognitoMode().asFlow()
 | 
			
		||||
            .drop(1)
 | 
			
		||||
            .onEach { if (!it) finish() }
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,8 @@ class ReaderPresenter(
 | 
			
		||||
        hasTrackers = tracks.size > 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val incognitoMode = preferences.incognitoMode().get()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when the presenter is created. It retrieves the saved active chapter if the process
 | 
			
		||||
     * was restored.
 | 
			
		||||
@@ -375,7 +377,7 @@ class ReaderPresenter(
 | 
			
		||||
 | 
			
		||||
        // Save last page read and mark as read if needed
 | 
			
		||||
        selectedChapter.chapter.last_page_read = page.index
 | 
			
		||||
        val shouldTrack = !preferences.incognitoMode().get() || hasTrackers
 | 
			
		||||
        val shouldTrack = !incognitoMode || hasTrackers
 | 
			
		||||
        if (selectedChapter.pages?.lastIndex == page.index && shouldTrack) {
 | 
			
		||||
            selectedChapter.chapter.read = true
 | 
			
		||||
            updateTrackChapterRead(selectedChapter)
 | 
			
		||||
@@ -430,7 +432,7 @@ class ReaderPresenter(
 | 
			
		||||
     * If incognito mode isn't on or has at least 1 tracker
 | 
			
		||||
     */
 | 
			
		||||
    private fun saveChapterProgress(chapter: ReaderChapter) {
 | 
			
		||||
        if (!preferences.incognitoMode().get() || hasTrackers) {
 | 
			
		||||
        if (!incognitoMode || hasTrackers) {
 | 
			
		||||
            db.updateChapterProgress(chapter.chapter).asRxCompletable()
 | 
			
		||||
                .onErrorComplete()
 | 
			
		||||
                .subscribeOn(Schedulers.io())
 | 
			
		||||
@@ -442,7 +444,7 @@ class ReaderPresenter(
 | 
			
		||||
     * Saves this [chapter] last read history if incognito mode isn't on.
 | 
			
		||||
     */
 | 
			
		||||
    private fun saveChapterHistory(chapter: ReaderChapter) {
 | 
			
		||||
        if (!preferences.incognitoMode().get()) {
 | 
			
		||||
        if (!incognitoMode) {
 | 
			
		||||
            val history = History.create(chapter.chapter).apply { last_read = Date().time }
 | 
			
		||||
            db.updateHistoryLastRead(history).asRxCompletable()
 | 
			
		||||
                .onErrorComplete()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user