diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index f72c89d640..d985a29b11 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -1,9 +1,15 @@ package eu.kanade.tachiyomi +import android.annotation.SuppressLint 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.os.Build import androidx.appcompat.app.AppCompatDelegate +import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent @@ -15,7 +21,9 @@ import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate +import eu.kanade.tachiyomi.util.system.notification import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.acra.ACRA import org.acra.config.httpSender import org.acra.data.StringFormat @@ -39,6 +47,9 @@ open class App : Application(), LifecycleObserver { val preferences: PreferencesHelper by injectLazy() + private val disableIncognitoReceiver = DisableIncognitoReceiver() + + @SuppressLint("LaunchActivityFromNotification") override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) @@ -61,8 +72,34 @@ open class App : Application(), LifecycleObserver { .asImmediateFlow { AppCompatDelegate.setDefaultNightMode(it) } .launchIn(ProcessLifecycleOwner.get().lifecycleScope) - // 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) { + val incogText = getString(R.string.incognito_mode) + setContentTitle(incogText) + setContentText(getString(R.string.turn_off_, incogText)) + setSmallIcon(R.drawable.ic_glasses_24dp) + setOngoing(true) + + val pendingIntent = PendingIntent.getBroadcast( + this@App, + 0, + Intent(ACTION_DISABLE_INCOGNITO_MODE), + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE + ) + setContentIntent(pendingIntent) + } + notificationManager.notify(Notifications.ID_INCOGNITO_MODE, notification) + } else { + disableIncognitoReceiver.unregister() + notificationManager.cancel(Notifications.ID_INCOGNITO_MODE) + } + } + .launchIn(ProcessLifecycleOwner.get().lifecycleScope) } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) @@ -95,4 +132,28 @@ open class App : Application(), LifecycleObserver { 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 + } + } + } } + +private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt index 621329ed7c..4026c7396a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -74,6 +74,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( "backup_restore_channel", "library_channel" @@ -160,6 +166,11 @@ object Notifications { CHANNEL_CRASH_LOGS, context.getString(R.string.crash_logs), NotificationManager.IMPORTANCE_HIGH + ), + NotificationChannel( + CHANNEL_INCOGNITO_MODE, + context.getString(R.string.incognito_mode), + NotificationManager.IMPORTANCE_LOW ) ) context.notificationManager.createNotificationChannels(channels) 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 b956acadc2..3e6d81b047 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 @@ -374,6 +374,9 @@ open class MainActivity : BaseActivity(), DownloadServiceLi (router.backstack.lastOrNull()?.controller as? SettingsController)?.setTitle() if (savedInstanceState == null) { + // Reset Incognito Mode on relaunch + preferences.incognitoMode().set(false) + // Show changelog if needed if (Migrations.upgrade(preferences)) { if (!BuildConfig.DEBUG) {