Incognito mode indicator in reader

(cherry picked from commit db1ddf539c)
This commit is contained in:
Koitharu
2024-01-21 10:10:20 +02:00
parent cdd76f723f
commit ec53eb9c70
13 changed files with 94 additions and 35 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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<Long>, 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)

View File

@@ -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)

View File

@@ -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<Boolean> {

View File

@@ -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(

View File

@@ -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(

View File

@@ -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()
}
}

View File

@@ -96,6 +96,12 @@ class ReaderViewModel @Inject constructor(
val onShowToast = MutableEventFlow<Int>()
val uiState = MutableStateFlow<ReaderUiState?>(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

View File

@@ -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)

View File

@@ -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)

View File

@@ -1,13 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/action_chapters"
android:icon="@drawable/ic_expand_more"
android:title="@string/chapters"
android:orderInCategory="0"
android:title="@string/chapters"
app:showAsAction="always" />
</menu>
<item
android:id="@+id/action_incognito"
android:icon="@drawable/ic_incognito"
android:title="@string/incognito_mode"
android:visible="false"
app:showAsAction="always" />
</menu>

View File

@@ -559,4 +559,5 @@
<string name="mark_as_completed">Mark as completed</string>
<string name="mark_as_completed_prompt">Mark selected manga as completely read?\n\nWarning: current reading progress will be lost.</string>
<string name="category_hidden_done">This category was hidden from the main screen and is accessible through Menu → Manage categories</string>
<string name="incognito_mode_hint">Your reading progress will not be saved</string>
</resources>