From 96d6f8d8e6ffc749ab3a2eb078516d7e230641e3 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 11 May 2023 18:48:51 +0300 Subject: [PATCH] Option to read in incognito mode instantly --- app/build.gradle | 4 +- .../base/ui/util/ReversibleActionObserver.kt | 5 -- .../kotatsu/details/ui/DetailsActivity.kt | 67 ++++++++++++------- .../kotatsu/reader/ui/ReaderActivity.kt | 3 +- .../kotatsu/shelf/domain/ShelfRepository.kt | 5 +- .../kotatsu/shelf/ui/ShelfViewModel.kt | 2 +- app/src/main/res/layout/activity_main.xml | 1 - app/src/main/res/menu/popup_read.xml | 9 +++ 8 files changed, 59 insertions(+), 37 deletions(-) create mode 100644 app/src/main/res/menu/popup_read.xml diff --git a/app/build.gradle b/app/build.gradle index 08870f3c0..3e24d9a35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 33 - versionCode 541 - versionName '5.1-a1' + versionCode 542 + versionName '5.1-b1' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ReversibleActionObserver.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ReversibleActionObserver.kt index 04a332cd2..ba685c4f4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ReversibleActionObserver.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/util/ReversibleActionObserver.kt @@ -5,8 +5,6 @@ import androidx.lifecycle.Observer import com.google.android.material.snackbar.Snackbar import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.reverseAsync -import org.koitharu.kotatsu.main.ui.owners.BottomNavOwner -import org.koitharu.kotatsu.utils.ext.findActivity class ReversibleActionObserver( private val snackbarHost: View, @@ -22,9 +20,6 @@ class ReversibleActionObserver( if (handle != null) { snackbar.setAction(R.string.undo) { handle.reverseAsync() } } - (snackbarHost.context.findActivity() as? BottomNavOwner)?.let { - snackbar.anchorView = it.bottomNav - } snackbar.show() } } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 4752e52f4..f3d357c7b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -7,6 +7,7 @@ import android.transition.Slide import android.transition.TransitionManager import android.view.Gravity import android.view.Menu +import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.view.animation.AccelerateDecelerateInterpolator @@ -42,6 +43,7 @@ import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.utils.ViewBadge import org.koitharu.kotatsu.utils.ext.getDisplayMessage +import org.koitharu.kotatsu.utils.ext.scaleUpActivityOptionsOf import org.koitharu.kotatsu.utils.ext.setNavigationBarTransparentCompat import org.koitharu.kotatsu.utils.ext.textAndVisible import javax.inject.Inject @@ -51,7 +53,7 @@ class DetailsActivity : BaseActivity(), View.OnClickListener, BottomSheetHeaderBar.OnExpansionChangeListener, - NoModalBottomSheetOwner { + NoModalBottomSheetOwner, View.OnLongClickListener, PopupMenu.OnMenuItemClickListener { override val bsHeader: BottomSheetHeaderBar? get() = binding.headerChapters @@ -72,6 +74,7 @@ class DetailsActivity : setDisplayShowTitleEnabled(false) } binding.buttonRead.setOnClickListener(this) + binding.buttonRead.setOnLongClickListener(this) binding.buttonDropdown.setOnClickListener(this) viewBadge = ViewBadge(binding.buttonRead, this) @@ -134,27 +137,34 @@ class DetailsActivity : } override fun onClick(v: View) { - val manga = viewModel.manga.value ?: return when (v.id) { - R.id.button_read -> { - val chapterId = viewModel.historyInfo.value?.history?.chapterId - if (chapterId != null && manga.chapters?.none { x -> x.id == chapterId } == true) { - showChapterMissingDialog(chapterId) - } else { - startActivity( - ReaderActivity.newIntent( - context = this, - manga = manga, - branch = viewModel.selectedBranchValue, - ), - ) - } - } - + R.id.button_read -> openReader(isIncognitoMode = false) R.id.button_dropdown -> showBranchPopupMenu() } } + override fun onLongClick(v: View): Boolean = when (v.id) { + R.id.button_read -> { + val menu = PopupMenu(v.context, v) + menu.inflate(R.menu.popup_read) + menu.setOnMenuItemClickListener(this) + menu.setForceShowIcon(true) + menu.show() + true + } + + else -> false + } + + override fun onMenuItemClick(item: MenuItem): Boolean = when (item.itemId) { + R.id.action_incognito -> { + openReader(isIncognitoMode = true) + true + } + + else -> false + } + override fun onExpansionStateChanged(headerBar: BottomSheetHeaderBar, isExpanded: Boolean) { if (isExpanded) { headerBar.addMenuProvider(chaptersMenuProvider) @@ -258,13 +268,22 @@ class DetailsActivity : menu.show() } - private fun resolveError(e: Throwable) { - lifecycleScope.launch { - if (exceptionResolver.resolve(e)) { - viewModel.reload() - } else if (viewModel.manga.value == null) { - Toast.makeText(this@DetailsActivity, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show() - finishAfterTransition() + private fun openReader(isIncognitoMode: Boolean) { + val manga = viewModel.manga.value ?: return + val chapterId = viewModel.historyInfo.value?.history?.chapterId + if (chapterId != null && manga.chapters?.none { x -> x.id == chapterId } == true) { + showChapterMissingDialog(chapterId) + } else { + startActivity( + ReaderActivity.newIntent( + context = this, + manga = manga, + branch = viewModel.selectedBranchValue, + isIncognitoMode = isIncognitoMode, + ), + ) + if (isIncognitoMode) { + Toast.makeText(this, R.string.incognito_mode, Toast.LENGTH_SHORT).show() } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 1138ad144..270c0684b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -407,10 +407,11 @@ class ReaderActivity : .putExtra(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = true)) } - fun newIntent(context: Context, manga: Manga, branch: String?): Intent { + fun newIntent(context: Context, manga: Manga, branch: String?, isIncognitoMode: Boolean): Intent { return Intent(context, ReaderActivity::class.java) .putExtra(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = true)) .putExtra(EXTRA_BRANCH, branch) + .putExtra(EXTRA_INCOGNITO, isIncognitoMode) } fun newIntent(context: Context, manga: Manga, state: ReaderState?): Intent { diff --git a/app/src/main/java/org/koitharu/kotatsu/shelf/domain/ShelfRepository.kt b/app/src/main/java/org/koitharu/kotatsu/shelf/domain/ShelfRepository.kt index 1cbb66dd0..d6e9a7fac 100644 --- a/app/src/main/java/org/koitharu/kotatsu/shelf/domain/ShelfRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/shelf/domain/ShelfRepository.kt @@ -14,11 +14,10 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.onStart import org.koitharu.kotatsu.core.db.MangaDatabase -import org.koitharu.kotatsu.core.db.entity.toManga -import org.koitharu.kotatsu.core.db.entity.toMangaTags import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity import org.koitharu.kotatsu.favourites.data.toFavouriteCategory +import org.koitharu.kotatsu.favourites.data.toMangaList import org.koitharu.kotatsu.history.domain.HistoryRepository import org.koitharu.kotatsu.local.data.LocalManga import org.koitharu.kotatsu.local.data.LocalStorageChanges @@ -93,7 +92,7 @@ class ShelfRepository @Inject constructor( categories.map { cat -> val category = cat.toFavouriteCategory() db.favouritesDao.observeAll(category.id, category.order) - .map { category to it.map { x -> x.manga.toManga(x.tags.toMangaTags()) } } + .map { category to it.toMangaList() } }, ) { array -> array.toMap() } } diff --git a/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt index 27e06aa49..2103b208f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt @@ -162,7 +162,7 @@ class ShelfViewModel @Inject constructor( sections: List, isNetworkAvailable: Boolean, ): List { - val result = ArrayList(content.favourites.keys.size + 3) + val result = ArrayList(content.favourites.keys.size + sections.size) if (isNetworkAvailable) { for (section in sections) { when (section) { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index ebf06ab36..4f870d43a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -91,7 +91,6 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:clickable="true" - app:layout_insetEdge="bottom" app:menu="@menu/nav_bottom" tools:ignore="KeyboardInaccessibleWidget" /> diff --git a/app/src/main/res/menu/popup_read.xml b/app/src/main/res/menu/popup_read.xml new file mode 100644 index 000000000..7feb8133b --- /dev/null +++ b/app/src/main/res/menu/popup_read.xml @@ -0,0 +1,9 @@ + + + + +