Read button tip in DetailsActivity
This commit is contained in:
@@ -45,7 +45,7 @@ abstract class BaseActivity<B : ViewBinding> :
|
|||||||
protected val exceptionResolver = ExceptionResolver(this)
|
protected val exceptionResolver = ExceptionResolver(this)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
protected val insetsDelegate = WindowInsetsDelegate(this)
|
protected val insetsDelegate = WindowInsetsDelegate()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val actionModeDelegate = ActionModeDelegate()
|
val actionModeDelegate = ActionModeDelegate()
|
||||||
@@ -62,6 +62,7 @@ abstract class BaseActivity<B : ViewBinding> :
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
insetsDelegate.handleImeInsets = true
|
insetsDelegate.handleImeInsets = true
|
||||||
|
insetsDelegate.addInsetsListener(this)
|
||||||
putDataToExtras(intent)
|
putDataToExtras(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ abstract class BaseFragment<B : ViewBinding> :
|
|||||||
protected val exceptionResolver = ExceptionResolver(this)
|
protected val exceptionResolver = ExceptionResolver(this)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
protected val insetsDelegate = WindowInsetsDelegate(this)
|
protected val insetsDelegate = WindowInsetsDelegate()
|
||||||
|
|
||||||
protected val actionModeDelegate: ActionModeDelegate
|
protected val actionModeDelegate: ActionModeDelegate
|
||||||
get() = (requireActivity() as BaseActivity<*>).actionModeDelegate
|
get() = (requireActivity() as BaseActivity<*>).actionModeDelegate
|
||||||
@@ -44,11 +44,13 @@ abstract class BaseFragment<B : ViewBinding> :
|
|||||||
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
insetsDelegate.onViewCreated(view)
|
insetsDelegate.onViewCreated(view)
|
||||||
|
insetsDelegate.addInsetsListener(this)
|
||||||
onViewBindingCreated(requireViewBinding(), savedInstanceState)
|
onViewBindingCreated(requireViewBinding(), savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
viewBinding = null
|
viewBinding = null
|
||||||
|
insetsDelegate.removeInsetsListener(this)
|
||||||
insetsDelegate.onDestroyView()
|
insetsDelegate.onDestroyView()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
|||||||
lateinit var settings: AppSettings
|
lateinit var settings: AppSettings
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
protected val insetsDelegate = WindowInsetsDelegate(this)
|
protected val insetsDelegate = WindowInsetsDelegate()
|
||||||
|
|
||||||
override val recyclerView: RecyclerView
|
override val recyclerView: RecyclerView
|
||||||
get() = listView
|
get() = listView
|
||||||
@@ -35,9 +35,11 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
listView.clipToPadding = false
|
listView.clipToPadding = false
|
||||||
insetsDelegate.onViewCreated(view)
|
insetsDelegate.onViewCreated(view)
|
||||||
|
insetsDelegate.addInsetsListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
insetsDelegate.removeInsetsListener(this)
|
||||||
insetsDelegate.onDestroyView()
|
insetsDelegate.onDestroyView()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ActionModeDelegate : OnBackPressedCallback(false) {
|
|||||||
get() = activeActionMode != null
|
get() = activeActionMode != null
|
||||||
|
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
activeActionMode?.finish()
|
finishActionMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSupportActionModeStarted(mode: ActionMode) {
|
fun onSupportActionModeStarted(mode: ActionMode) {
|
||||||
@@ -45,6 +45,10 @@ class ActionModeDelegate : OnBackPressedCallback(false) {
|
|||||||
owner.lifecycle.addObserver(ListenerLifecycleObserver(listener))
|
owner.lifecycle.addObserver(ListenerLifecycleObserver(listener))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun finishActionMode() {
|
||||||
|
activeActionMode?.finish()
|
||||||
|
}
|
||||||
|
|
||||||
private inner class ListenerLifecycleObserver(
|
private inner class ListenerLifecycleObserver(
|
||||||
private val listener: ActionModeListener,
|
private val listener: ActionModeListener,
|
||||||
) : DefaultLifecycleObserver {
|
) : DefaultLifecycleObserver {
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import androidx.core.graphics.Insets
|
|||||||
import androidx.core.view.OnApplyWindowInsetsListener
|
import androidx.core.view.OnApplyWindowInsetsListener
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import java.util.LinkedList
|
||||||
|
|
||||||
class WindowInsetsDelegate(
|
class WindowInsetsDelegate : OnApplyWindowInsetsListener, View.OnLayoutChangeListener {
|
||||||
private val listener: WindowInsetsListener,
|
|
||||||
) : OnApplyWindowInsetsListener, View.OnLayoutChangeListener {
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
var handleImeInsets: Boolean = false
|
var handleImeInsets: Boolean = false
|
||||||
@@ -16,6 +15,7 @@ class WindowInsetsDelegate(
|
|||||||
@JvmField
|
@JvmField
|
||||||
var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null
|
var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null
|
||||||
|
|
||||||
|
private val listeners = LinkedList<WindowInsetsListener>()
|
||||||
private var lastInsets: Insets? = null
|
private var lastInsets: Insets? = null
|
||||||
|
|
||||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||||
@@ -29,7 +29,7 @@ class WindowInsetsDelegate(
|
|||||||
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
}
|
}
|
||||||
if (newInsets != lastInsets) {
|
if (newInsets != lastInsets) {
|
||||||
listener.onWindowInsetsChanged(newInsets)
|
listeners.forEach { it.onWindowInsetsChanged(newInsets) }
|
||||||
lastInsets = newInsets
|
lastInsets = newInsets
|
||||||
}
|
}
|
||||||
return handledInsets
|
return handledInsets
|
||||||
@@ -52,6 +52,15 @@ class WindowInsetsDelegate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addInsetsListener(listener: WindowInsetsListener) {
|
||||||
|
listeners.add(listener)
|
||||||
|
lastInsets?.let { listener.onWindowInsetsChanged(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeInsetsListener(listener: WindowInsetsListener) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
fun onViewCreated(view: View) {
|
fun onViewCreated(view: View) {
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||||
view.addOnLayoutChangeListener(this)
|
view.addOnLayoutChangeListener(this)
|
||||||
|
|||||||
@@ -92,6 +92,14 @@ class SlidingBottomNavigationView @JvmOverloads constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showOrHide(show: Boolean) {
|
||||||
|
if (show) {
|
||||||
|
show()
|
||||||
|
} else {
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun animateTranslation(targetY: Float, duration: Long, interpolator: TimeInterpolator) {
|
private fun animateTranslation(targetY: Float, duration: Long, interpolator: TimeInterpolator) {
|
||||||
currentAnimator = animate()
|
currentAnimator = animate()
|
||||||
.translationY(targetY)
|
.translationY(targetY)
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package org.koitharu.kotatsu.details.ui
|
||||||
|
|
||||||
|
import android.transition.TransitionManager
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
import androidx.core.graphics.Insets
|
||||||
|
import androidx.core.view.setMargins
|
||||||
|
import androidx.core.view.updateLayoutParams
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.getThemeDimensionPixelSize
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled
|
||||||
|
import org.koitharu.kotatsu.databinding.ItemTipBinding
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
|
class ButtonTip(
|
||||||
|
private val root: ViewGroup,
|
||||||
|
private val insetsDelegate: WindowInsetsDelegate,
|
||||||
|
private val viewModel: DetailsViewModel,
|
||||||
|
) : View.OnClickListener, WindowInsetsDelegate.WindowInsetsListener {
|
||||||
|
|
||||||
|
private var selfBinding = ItemTipBinding.inflate(LayoutInflater.from(root.context), root, false)
|
||||||
|
private val actionBarSize = root.context.getThemeDimensionPixelSize(materialR.attr.actionBarSize)
|
||||||
|
|
||||||
|
init {
|
||||||
|
selfBinding.textView.setText(R.string.details_button_tip)
|
||||||
|
selfBinding.imageViewIcon.setImageResource(R.drawable.ic_tap)
|
||||||
|
selfBinding.root.id = R.id.layout_tip
|
||||||
|
selfBinding.buttonClose.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onWindowInsetsChanged(insets: Insets) {
|
||||||
|
if (root is CoordinatorLayout) {
|
||||||
|
selfBinding.root.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||||
|
bottomMargin = topMargin + insets.bottom + insets.top + actionBarSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addToRoot() {
|
||||||
|
val lp: ViewGroup.LayoutParams = when (root) {
|
||||||
|
is CoordinatorLayout -> CoordinatorLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
).apply {
|
||||||
|
// anchorId = R.id.layout_bottom
|
||||||
|
// anchorGravity = Gravity.TOP
|
||||||
|
gravity = Gravity.BOTTOM
|
||||||
|
setMargins(root.resources.getDimensionPixelOffset(R.dimen.margin_normal))
|
||||||
|
bottomMargin += actionBarSize
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConstraintLayout -> ConstraintLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
).apply {
|
||||||
|
width = root.resources.getDimensionPixelSize(R.dimen.m3_side_sheet_width)
|
||||||
|
setMargins(root.resources.getDimensionPixelOffset(R.dimen.margin_normal))
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
root.addView(selfBinding.root, lp)
|
||||||
|
if (root is ConstraintLayout) {
|
||||||
|
val cs = ConstraintSet()
|
||||||
|
cs.clone(root)
|
||||||
|
cs.connect(R.id.layout_tip, ConstraintSet.TOP, R.id.appbar, ConstraintSet.BOTTOM)
|
||||||
|
cs.connect(R.id.layout_tip, ConstraintSet.START, R.id.card_chapters, ConstraintSet.START)
|
||||||
|
cs.connect(R.id.layout_tip, ConstraintSet.END, R.id.card_chapters, ConstraintSet.END)
|
||||||
|
cs.applyTo(root)
|
||||||
|
}
|
||||||
|
insetsDelegate.addInsetsListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove() {
|
||||||
|
if (root.context.isAnimationsEnabled) {
|
||||||
|
TransitionManager.beginDelayedTransition(root)
|
||||||
|
}
|
||||||
|
insetsDelegate.removeInsetsListener(this)
|
||||||
|
root.removeView(selfBinding.root)
|
||||||
|
viewModel.onButtonTipClosed()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@ import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner
|
|||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
||||||
import org.koitharu.kotatsu.reader.ui.thumbnails.PagesThumbnailsSheet
|
import org.koitharu.kotatsu.reader.ui.thumbnails.PagesThumbnailsSheet
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
@@ -70,6 +71,7 @@ class DetailsActivity :
|
|||||||
lateinit var shortcutsUpdater: ShortcutsUpdater
|
lateinit var shortcutsUpdater: ShortcutsUpdater
|
||||||
|
|
||||||
private lateinit var viewBadge: ViewBadge
|
private lateinit var viewBadge: ViewBadge
|
||||||
|
private var buttonTip: WeakReference<ButtonTip>? = null
|
||||||
|
|
||||||
private val viewModel: DetailsViewModel by viewModels()
|
private val viewModel: DetailsViewModel by viewModels()
|
||||||
private lateinit var chaptersMenuProvider: ChaptersMenuProvider
|
private lateinit var chaptersMenuProvider: ChaptersMenuProvider
|
||||||
@@ -122,6 +124,7 @@ class DetailsActivity :
|
|||||||
viewModel.onShowToast.observeEvent(this) {
|
viewModel.onShowToast.observeEvent(this) {
|
||||||
makeSnackbar(getString(it), Snackbar.LENGTH_SHORT).show()
|
makeSnackbar(getString(it), Snackbar.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
viewModel.onShowTip.observeEvent(this) { showTip() }
|
||||||
viewModel.historyInfo.observe(this, ::onHistoryChanged)
|
viewModel.historyInfo.observe(this, ::onHistoryChanged)
|
||||||
viewModel.selectedBranch.observe(this) {
|
viewModel.selectedBranch.observe(this) {
|
||||||
viewBinding.toolbarChapters?.subtitle = it
|
viewBinding.toolbarChapters?.subtitle = it
|
||||||
@@ -162,6 +165,8 @@ class DetailsActivity :
|
|||||||
|
|
||||||
override fun onLongClick(v: View): Boolean = when (v.id) {
|
override fun onLongClick(v: View): Boolean = when (v.id) {
|
||||||
R.id.button_read -> {
|
R.id.button_read -> {
|
||||||
|
buttonTip?.get()?.remove()
|
||||||
|
buttonTip = null
|
||||||
val menu = PopupMenu(v.context, v)
|
val menu = PopupMenu(v.context, v)
|
||||||
menu.inflate(R.menu.popup_read)
|
menu.inflate(R.menu.popup_read)
|
||||||
menu.setOnMenuItemClickListener(this)
|
menu.setOnMenuItemClickListener(this)
|
||||||
@@ -345,8 +350,16 @@ class DetailsActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showTip() {
|
||||||
|
val tip = ButtonTip(viewBinding.root as ViewGroup, insetsDelegate, viewModel)
|
||||||
|
tip.addToRoot()
|
||||||
|
buttonTip = WeakReference(tip)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
const val TIP_BUTTON = "btn_read"
|
||||||
|
|
||||||
fun newIntent(context: Context, manga: Manga): Intent {
|
fun newIntent(context: Context, manga: Manga): Intent {
|
||||||
return Intent(context, DetailsActivity::class.java)
|
return Intent(context, DetailsActivity::class.java)
|
||||||
.putExtra(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = true))
|
.putExtra(MangaIntent.KEY_MANGA, ParcelableManga(manga, withChapters = true))
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import kotlinx.coroutines.flow.SharingStarted
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||||
|
import kotlinx.coroutines.flow.filterNot
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
@@ -78,6 +80,7 @@ class DetailsViewModel @Inject constructor(
|
|||||||
private var loadingJob: Job
|
private var loadingJob: Job
|
||||||
|
|
||||||
val onShowToast = MutableEventFlow<Int>()
|
val onShowToast = MutableEventFlow<Int>()
|
||||||
|
val onShowTip = MutableEventFlow<Unit>()
|
||||||
val onDownloadStarted = MutableEventFlow<Unit>()
|
val onDownloadStarted = MutableEventFlow<Unit>()
|
||||||
|
|
||||||
val manga = doubleManga.map { it?.any }
|
val manga = doubleManga.map { it?.any }
|
||||||
@@ -191,6 +194,12 @@ class DetailsViewModel @Inject constructor(
|
|||||||
localStorageChanges
|
localStorageChanges
|
||||||
.collect { onDownloadComplete(it) }
|
.collect { onDownloadComplete(it) }
|
||||||
}
|
}
|
||||||
|
launchJob(Dispatchers.Default) {
|
||||||
|
if (settings.isTipEnabled(DetailsActivity.TIP_BUTTON)) {
|
||||||
|
manga.filterNot { it?.chapters.isNullOrEmpty() }.first()
|
||||||
|
onShowTip.call(Unit)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reload() {
|
fun reload() {
|
||||||
@@ -277,6 +286,10 @@ class DetailsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onButtonTipClosed() {
|
||||||
|
settings.closeTip(DetailsActivity.TIP_BUTTON)
|
||||||
|
}
|
||||||
|
|
||||||
private fun doLoad() = launchLoadingJob(Dispatchers.Default) {
|
private fun doLoad() = launchLoadingJob(Dispatchers.Default) {
|
||||||
val result = doubleMangaLoadUseCase(intent)
|
val result = doubleMangaLoadUseCase(intent)
|
||||||
val manga = result.requireAny()
|
val manga = result.requireAny()
|
||||||
|
|||||||
@@ -126,8 +126,10 @@ class MainActivity :
|
|||||||
viewBinding.navRail?.headerView?.setOnClickListener(this)
|
viewBinding.navRail?.headerView?.setOnClickListener(this)
|
||||||
viewBinding.searchView.isVoiceSearchEnabled = voiceInputLauncher.resolve(this, null) != null
|
viewBinding.searchView.isVoiceSearchEnabled = voiceInputLauncher.resolve(this, null) != null
|
||||||
|
|
||||||
navigationDelegate =
|
navigationDelegate = MainNavigationDelegate(
|
||||||
MainNavigationDelegate(checkNotNull(bottomNav ?: viewBinding.navRail), supportFragmentManager)
|
navBar = checkNotNull(bottomNav ?: viewBinding.navRail),
|
||||||
|
fragmentManager = supportFragmentManager,
|
||||||
|
)
|
||||||
navigationDelegate.addOnFragmentChangedListener(this)
|
navigationDelegate.addOnFragmentChangedListener(this)
|
||||||
navigationDelegate.onCreate()
|
navigationDelegate.onCreate()
|
||||||
|
|
||||||
@@ -156,6 +158,8 @@ class MainActivity :
|
|||||||
override fun onFragmentChanged(fragment: Fragment, fromUser: Boolean) {
|
override fun onFragmentChanged(fragment: Fragment, fromUser: Boolean) {
|
||||||
adjustFabVisibility(topFragment = fragment)
|
adjustFabVisibility(topFragment = fragment)
|
||||||
if (fromUser) {
|
if (fromUser) {
|
||||||
|
actionModeDelegate.finishActionMode()
|
||||||
|
closeSearchCallback.handleOnBackPressed()
|
||||||
viewBinding.appbar.setExpanded(true)
|
viewBinding.appbar.setExpanded(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,13 +247,13 @@ class MainActivity :
|
|||||||
override fun onSupportActionModeStarted(mode: ActionMode) {
|
override fun onSupportActionModeStarted(mode: ActionMode) {
|
||||||
super.onSupportActionModeStarted(mode)
|
super.onSupportActionModeStarted(mode)
|
||||||
adjustFabVisibility()
|
adjustFabVisibility()
|
||||||
showNav(false)
|
bottomNav?.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSupportActionModeFinished(mode: ActionMode) {
|
override fun onSupportActionModeFinished(mode: ActionMode) {
|
||||||
super.onSupportActionModeFinished(mode)
|
super.onSupportActionModeFinished(mode)
|
||||||
adjustFabVisibility()
|
adjustFabVisibility()
|
||||||
showNav(true)
|
bottomNav?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onOpenReader(manga: Manga) {
|
private fun onOpenReader(manga: Manga) {
|
||||||
@@ -301,17 +305,6 @@ class MainActivity :
|
|||||||
closeSearchCallback.isEnabled = false
|
closeSearchCallback.isEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showNav(visible: Boolean) {
|
|
||||||
bottomNav?.run {
|
|
||||||
if (visible) {
|
|
||||||
show()
|
|
||||||
} else {
|
|
||||||
hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewBinding.navRail?.isVisible = visible
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isSearchOpened(): Boolean {
|
private fun isSearchOpened(): Boolean {
|
||||||
return supportFragmentManager.findFragmentByTag(TAG_SEARCH) != null
|
return supportFragmentManager.findFragmentByTag(TAG_SEARCH) != null
|
||||||
}
|
}
|
||||||
@@ -340,7 +333,7 @@ class MainActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun adjustFabVisibility(
|
private fun adjustFabVisibility(
|
||||||
isResumeEnabled: Boolean = viewModel.isResumeEnabled.value == true,
|
isResumeEnabled: Boolean = viewModel.isResumeEnabled.value,
|
||||||
topFragment: Fragment? = navigationDelegate.primaryFragment,
|
topFragment: Fragment? = navigationDelegate.primaryFragment,
|
||||||
isSearchOpened: Boolean = isSearchOpened(),
|
isSearchOpened: Boolean = isSearchOpened(),
|
||||||
) {
|
) {
|
||||||
@@ -383,7 +376,7 @@ class MainActivity :
|
|||||||
supportActionBar?.setHomeAsUpIndicator(
|
supportActionBar?.setHomeAsUpIndicator(
|
||||||
if (isOpened) materialR.drawable.abc_ic_ab_back_material else materialR.drawable.abc_ic_search_api_material,
|
if (isOpened) materialR.drawable.abc_ic_ab_back_material else materialR.drawable.abc_ic_search_api_material,
|
||||||
)
|
)
|
||||||
showNav(!isOpened)
|
bottomNav?.showOrHide(!isOpened)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestNotificationsPermission() {
|
private fun requestNotificationsPermission() {
|
||||||
|
|||||||
12
app/src/main/res/drawable/ic_tap.xml
Normal file
12
app/src/main/res/drawable/ic_tap.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M10,9A1,1 0 0,1 11,8A1,1 0 0,1 12,9V13.47L13.21,13.6L18.15,15.79C18.68,16.03 19,16.56 19,17.14V21.5C18.97,22.32 18.32,22.97 17.5,23H11C10.62,23 10.26,22.85 10,22.57L5.1,18.37L5.84,17.6C6.03,17.39 6.3,17.28 6.58,17.28H6.8L10,19V9M11,5A4,4 0 0,1 15,9C15,10.5 14.2,11.77 13,12.46V11.24C13.61,10.69 14,9.89 14,9A3,3 0 0,0 11,6A3,3 0 0,0 8,9C8,9.89 8.39,10.69 9,11.24V12.46C7.8,11.77 7,10.5 7,9A4,4 0 0,1 11,5Z" />
|
||||||
|
</vector>
|
||||||
@@ -5,4 +5,5 @@
|
|||||||
<item name="action_leaks" type="id" />
|
<item name="action_leaks" type="id" />
|
||||||
<item name="fast_scroller" type="id" />
|
<item name="fast_scroller" type="id" />
|
||||||
<item name="group_branches" type="id" />
|
<item name="group_branches" type="id" />
|
||||||
|
<item name="layout_tip" type="id" />
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -436,4 +436,5 @@
|
|||||||
<string name="reader_info_bar_summary">Show the current time and reading progress at the top of the screen</string>
|
<string name="reader_info_bar_summary">Show the current time and reading progress at the top of the screen</string>
|
||||||
<string name="show_pages_numbers_summary">Show page numbers in bottom corner</string>
|
<string name="show_pages_numbers_summary">Show page numbers in bottom corner</string>
|
||||||
<string name="pages_animation_summary">Animate page switching</string>
|
<string name="pages_animation_summary">Animate page switching</string>
|
||||||
|
<string name="details_button_tip">Press and hold the Read button to see more options</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user