From db1ddf539ce483092c62d2aad1f8a74a3b4a8cc4 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 21 Jan 2024 10:10:20 +0200 Subject: [PATCH] Incognito mode indicator in reader --- .../koitharu/kotatsu/core/util/ext/Theme.kt | 6 +++ .../download/ui/list/DownloadsMenuProvider.kt | 13 ++--- .../categories/CategoriesSelectionCallback.kt | 4 +- .../FavouriteTabPopupMenuProvider.kt | 7 ++- .../kotatsu/history/data/HistoryRepository.kt | 3 +- .../history/ui/HistoryListMenuProvider.kt | 3 +- .../kotatsu/reader/ui/ReaderActivity.kt | 13 ++--- .../reader/ui/ReaderTopMenuProvider.kt | 48 +++++++++++++++++++ .../kotatsu/reader/ui/ReaderViewModel.kt | 6 +++ .../SearchSuggestionMenuProvider.kt | 3 +- .../kotatsu/settings/about/AppUpdateDialog.kt | 7 +-- app/src/main/res/menu/opt_reader_top.xml | 15 ++++-- app/src/main/res/values/strings.xml | 1 + 13 files changed, 94 insertions(+), 35 deletions(-) create mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderTopMenuProvider.kt diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Theme.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Theme.kt index e5b713d8f..0d3a8d738 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Theme.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Theme.kt @@ -8,9 +8,11 @@ import androidx.annotation.AttrRes import androidx.annotation.ColorInt import androidx.annotation.FloatRange import androidx.annotation.Px +import androidx.annotation.StyleRes import androidx.core.content.ContextCompat import androidx.core.content.res.use import androidx.core.graphics.ColorUtils +import com.google.android.material.R as materialR fun Context.getThemeDrawable( @AttrRes resId: Int, @@ -75,3 +77,7 @@ fun TypedArray.getDrawableCompat(context: Context, index: Int): Drawable? { val resId = getResourceId(index, 0) return if (resId != 0) ContextCompat.getDrawable(context, resId) else null } + +@get:StyleRes +val DIALOG_THEME_CENTERED: Int + inline get() = materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsMenuProvider.kt index 3429ee2c9..1c6b6e92b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsMenuProvider.kt @@ -7,6 +7,7 @@ import android.view.MenuItem import androidx.core.view.MenuProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED import org.koitharu.kotatsu.settings.SettingsActivity class DownloadsMenuProvider( @@ -41,10 +42,8 @@ class DownloadsMenuProvider( } private fun confirmCancelAll() { - MaterialAlertDialogBuilder( - context, - com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered, - ).setTitle(R.string.cancel_all) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) + .setTitle(R.string.cancel_all) .setMessage(R.string.cancel_all_downloads_confirm) .setIcon(R.drawable.ic_cancel_multiple) .setNegativeButton(android.R.string.cancel, null) @@ -54,10 +53,8 @@ class DownloadsMenuProvider( } private fun confirmRemoveCompleted() { - MaterialAlertDialogBuilder( - context, - com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered, - ).setTitle(R.string.remove_completed) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) + .setTitle(R.string.remove_completed) .setMessage(R.string.remove_completed_downloads_confirm) .setIcon(R.drawable.ic_clear_all) .setNegativeButton(android.R.string.cancel, null) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/CategoriesSelectionCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/CategoriesSelectionCallback.kt index d629424f7..fc529b643 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/CategoriesSelectionCallback.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/CategoriesSelectionCallback.kt @@ -7,7 +7,7 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.list.ListSelectionController -import com.google.android.material.R as materialR +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED class CategoriesSelectionCallback( private val recyclerView: RecyclerView, @@ -75,7 +75,7 @@ class CategoriesSelectionCallback( private fun confirmDeleteCategories(ids: Set, mode: ActionMode) { val context = recyclerView.context - MaterialAlertDialogBuilder(context, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) .setMessage(R.string.categories_delete_confirm) .setTitle(R.string.remove_category) .setIcon(R.drawable.ic_delete) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouriteTabPopupMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouriteTabPopupMenuProvider.kt index 995d5c616..64a26395a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouriteTabPopupMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouriteTabPopupMenuProvider.kt @@ -7,6 +7,7 @@ import android.view.MenuItem import androidx.core.view.MenuProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID @@ -40,10 +41,8 @@ class FavouriteTabPopupMenuProvider( } private fun confirmDelete() { - MaterialAlertDialogBuilder( - context, - com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered, - ).setMessage(R.string.categories_delete_confirm) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) + .setMessage(R.string.categories_delete_confirm) .setTitle(R.string.remove_category) .setIcon(R.drawable.ic_delete) .setNegativeButton(android.R.string.cancel, null) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/history/data/HistoryRepository.kt b/app/src/main/kotlin/org/koitharu/kotatsu/history/data/HistoryRepository.kt index 5aae882ae..7a9e5cf5e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/history/data/HistoryRepository.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/history/data/HistoryRepository.kt @@ -15,6 +15,7 @@ import org.koitharu.kotatsu.core.db.entity.toMangaTags import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.findById import org.koitharu.kotatsu.core.model.isLocal +import org.koitharu.kotatsu.core.model.isNsfw import org.koitharu.kotatsu.core.parser.MangaDataRepository import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.util.ReversibleHandle @@ -161,7 +162,7 @@ class HistoryRepository @Inject constructor( } fun shouldSkip(manga: Manga): Boolean { - return manga.isNsfw && settings.isHistoryExcludeNsfw || settings.isIncognitoModeEnabled + return ((manga.source.isNsfw() || manga.isNsfw) && settings.isHistoryExcludeNsfw) || settings.isIncognitoModeEnabled } fun observeShouldSkip(manga: Manga): Flow { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt index 08b1f82f4..d2a5758f3 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/history/ui/HistoryListMenuProvider.kt @@ -8,6 +8,7 @@ import androidx.core.view.MenuProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.ui.dialog.RememberSelectionDialogListener +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED import java.time.Instant import java.time.LocalDate import java.time.ZoneId @@ -36,7 +37,7 @@ class HistoryListMenuProvider( private fun showClearHistoryDialog() { val selectionListener = RememberSelectionDialogListener(2) - MaterialAlertDialogBuilder(context, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) .setTitle(R.string.clear_history) .setSingleChoiceItems( arrayOf( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index bee4837b6..535fe7f29 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -10,7 +10,6 @@ import android.transition.TransitionManager import android.transition.TransitionSet import android.view.Gravity import android.view.KeyEvent -import android.view.Menu import android.view.MenuItem import android.view.MotionEvent import android.view.View @@ -40,6 +39,7 @@ import org.koitharu.kotatsu.core.parser.MangaIntent import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode import org.koitharu.kotatsu.core.ui.BaseFullscreenActivity +import org.koitharu.kotatsu.core.ui.util.MenuInvalidator import org.koitharu.kotatsu.core.ui.widgets.ZoomControl import org.koitharu.kotatsu.core.util.GridTouchHelper import org.koitharu.kotatsu.core.util.IdlingDetector @@ -140,6 +140,7 @@ class ReaderActivity : viewModel.content.observe(this) { onLoadingStateChanged(viewModel.isLoading.value) } + viewModel.incognitoMode.observe(this, MenuInvalidator(this)) viewModel.isScreenshotsBlockEnabled.observe(this, this::setWindowSecure) viewModel.isKeepScreenOnEnabled.observe(this, this::setKeepScreenOn) viewModel.isInfoBarEnabled.observe(this, ::onReaderBarChanged) @@ -152,6 +153,7 @@ class ReaderActivity : viewModel.isZoomControlsEnabled.observe(this) { viewBinding.zoomControl.isVisible = it } + addMenuProvider(ReaderTopMenuProvider(this, viewModel)) } override fun getParentActivityIntent(): Intent? { @@ -190,21 +192,12 @@ class ReaderActivity : viewBinding.slider.isRtl = mode == ReaderMode.REVERSED } - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.opt_reader_top, menu) - return super.onCreateOptionsMenu(menu) - } - override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_settings -> { startActivity(SettingsActivity.newReaderSettingsIntent(this)) } - R.id.action_chapters -> { - ChaptersSheet.show(supportFragmentManager) - } - R.id.action_pages_thumbs -> { val state = viewModel.getCurrentState() ?: return false PagesThumbnailsSheet.show( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderTopMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderTopMenuProvider.kt new file mode 100644 index 000000000..867ecfc7f --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderTopMenuProvider.kt @@ -0,0 +1,48 @@ +package org.koitharu.kotatsu.reader.ui + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED + +class ReaderTopMenuProvider( + private val activity: ReaderActivity, + private val viewModel: ReaderViewModel, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_reader_top, menu) + } + + override fun onPrepareMenu(menu: Menu) { + menu.findItem(R.id.action_incognito)?.isVisible = viewModel.incognitoMode.value + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean { + return when (menuItem.itemId) { + R.id.action_chapters -> { + ChaptersSheet.show(activity.supportFragmentManager) + true + } + + R.id.action_incognito -> { + showIncognitoModeDialog() + true + } + + else -> false + } + } + + private fun showIncognitoModeDialog() { + MaterialAlertDialogBuilder(activity, DIALOG_THEME_CENTERED) + .setIcon(R.drawable.ic_incognito) + .setTitle(R.string.incognito_mode) + .setMessage(R.string.incognito_mode_hint) + .setPositiveButton(R.string.got_it, null) + .show() + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt index 5ce6a348d..03473f94f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -96,6 +96,12 @@ class ReaderViewModel @Inject constructor( val onShowToast = MutableEventFlow() val uiState = MutableStateFlow(null) + val incognitoMode = if (isIncognito) { + MutableStateFlow(true) + } else mangaFlow.map { + it != null && historyRepository.shouldSkip(it) + }.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, false) + val content = MutableStateFlow(ReaderContent(emptyList(), null)) val manga: MangaDetails? get() = mangaData.value diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt index 12d58adf9..8483287c1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/SearchSuggestionMenuProvider.kt @@ -8,6 +8,7 @@ import androidx.activity.result.ActivityResultLauncher import androidx.core.view.MenuProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED import org.koitharu.kotatsu.core.util.ext.resolve import org.koitharu.kotatsu.core.util.ext.tryLaunch import com.google.android.material.R as materialR @@ -43,7 +44,7 @@ class SearchSuggestionMenuProvider( } private fun clearSearchHistory() { - MaterialAlertDialogBuilder(context, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered) + MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED) .setTitle(R.string.clear_search_history) .setIcon(R.drawable.ic_clear_all) .setMessage(R.string.text_clear_search_history_prompt) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateDialog.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateDialog.kt index 74bcff08a..a93bc1925 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateDialog.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AppUpdateDialog.kt @@ -16,8 +16,8 @@ import io.noties.markwon.Markwon import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.github.AppVersion import org.koitharu.kotatsu.core.util.FileSize +import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED import org.koitharu.kotatsu.core.util.ext.getDisplayMessage -import com.google.android.material.R as materialR class AppUpdateDialog(private val activity: AppCompatActivity) { @@ -43,10 +43,7 @@ class AppUpdateDialog(private val activity: AppCompatActivity) { appendLine() append(Markwon.create(activity).toMarkdown(version.description)) } - MaterialAlertDialogBuilder( - activity, - materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered, - ) + MaterialAlertDialogBuilder(activity, DIALOG_THEME_CENTERED) .setTitle(R.string.app_update_available) .setMessage(message) .setIcon(R.drawable.ic_app_update) diff --git a/app/src/main/res/menu/opt_reader_top.xml b/app/src/main/res/menu/opt_reader_top.xml index c2f02a4d3..fa5c3be7d 100644 --- a/app/src/main/res/menu/opt_reader_top.xml +++ b/app/src/main/res/menu/opt_reader_top.xml @@ -1,13 +1,22 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="AlwaysShowAction"> - \ 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 ce3d9b64a..4de83d5ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -564,4 +564,5 @@ %1$s %2$s Volume %d Unknown volume + Your reading progress will not be saved