Bring back reader slider
This commit is contained in:
@@ -45,9 +45,11 @@ import org.koitharu.kotatsu.core.util.IdlingDetector
|
||||
import org.koitharu.kotatsu.core.util.ShareHelper
|
||||
import org.koitharu.kotatsu.core.util.ext.hasGlobalPoint
|
||||
import org.koitharu.kotatsu.core.util.ext.isAnimationsEnabled
|
||||
import org.koitharu.kotatsu.core.util.ext.isRtl
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||
import org.koitharu.kotatsu.core.util.ext.postDelayed
|
||||
import org.koitharu.kotatsu.core.util.ext.setValueRounded
|
||||
import org.koitharu.kotatsu.core.util.ext.zipWithPrevious
|
||||
import org.koitharu.kotatsu.databinding.ActivityReaderBinding
|
||||
import org.koitharu.kotatsu.details.ui.DetailsActivity
|
||||
@@ -103,7 +105,6 @@ class ReaderActivity :
|
||||
private var gestureInsets: Insets = Insets.NONE
|
||||
private lateinit var readerManager: ReaderManager
|
||||
private val hideUiRunnable = Runnable { setUiIsVisible(false) }
|
||||
private lateinit var bottomMenuProvider: ReaderBottomMenuProvider
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -113,8 +114,9 @@ class ReaderActivity :
|
||||
touchHelper = TapGridDispatcher(this, this)
|
||||
scrollTimer = scrollTimerFactory.create(this, this)
|
||||
controlDelegate = ReaderControlDelegate(resources, settings, tapGridSettings, this)
|
||||
bottomMenuProvider = ReaderBottomMenuProvider(this, readerManager, viewModel, this)
|
||||
viewBinding.slider.setLabelFormatter(PageLabelFormatter())
|
||||
viewBinding.zoomControl.listener = this
|
||||
ReaderSliderListener(viewModel, this).attachToSlider(viewBinding.slider)
|
||||
insetsDelegate.interceptingWindowInsetsListener = this
|
||||
idlingDetector.bindToLifecycle(this)
|
||||
|
||||
@@ -153,8 +155,7 @@ class ReaderActivity :
|
||||
viewBinding.zoomControl.isVisible = it
|
||||
}
|
||||
addMenuProvider(ReaderTopMenuProvider(this, viewModel))
|
||||
viewBinding.toolbarBottom.addMenuProvider(bottomMenuProvider)
|
||||
onBackPressedDispatcher.addCallback(bottomMenuProvider)
|
||||
viewBinding.toolbarBottom.addMenuProvider(ReaderBottomMenuProvider(this, readerManager, viewModel))
|
||||
}
|
||||
|
||||
override fun onActivityResult(result: Uri?) {
|
||||
@@ -196,9 +197,10 @@ class ReaderActivity :
|
||||
if (readerManager.currentMode != mode) {
|
||||
readerManager.replace(mode)
|
||||
}
|
||||
if (viewBinding.appbarTop.isVisible && !bottomMenuProvider.isSliderExpanded()) {
|
||||
if (viewBinding.appbarTop.isVisible) {
|
||||
lifecycle.postDelayed(TimeUnit.SECONDS.toMillis(1), hideUiRunnable)
|
||||
}
|
||||
viewBinding.slider.isRtl = mode == ReaderMode.REVERSED
|
||||
}
|
||||
|
||||
private fun onLoadingStateChanged(isLoading: Boolean) {
|
||||
@@ -210,7 +212,6 @@ class ReaderActivity :
|
||||
viewBinding.toastView.hide()
|
||||
}
|
||||
viewBinding.toolbarBottom.invalidateMenu()
|
||||
invalidateMenu()
|
||||
}
|
||||
|
||||
override fun onGridTouch(area: TapGridArea): Boolean {
|
||||
@@ -328,9 +329,6 @@ class ReaderActivity :
|
||||
viewBinding.infoBar.isGone = isUiVisible || (!viewModel.isInfoBarEnabled.value)
|
||||
viewBinding.infoBar.isTimeVisible = isFullscreen
|
||||
systemUiController.setSystemUiVisible(isUiVisible || !isFullscreen)
|
||||
if (!isUiVisible) {
|
||||
bottomMenuProvider.collapseSlider()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,20 +394,28 @@ class ReaderActivity :
|
||||
private fun onUiStateChanged(pair: Pair<ReaderUiState?, ReaderUiState?>) {
|
||||
val (previous: ReaderUiState?, uiState: ReaderUiState?) = pair
|
||||
title = uiState?.mangaName ?: getString(R.string.loading_)
|
||||
supportActionBar?.subtitle = uiState?.chapterName
|
||||
with(viewBinding.toolbarBottom) {
|
||||
title = uiState?.resolveSummary(context)
|
||||
subtitle = uiState?.resolveSubtitle(context)
|
||||
}
|
||||
viewBinding.infoBar.update(uiState)
|
||||
if (!bottomMenuProvider.updateState(uiState)) {
|
||||
viewBinding.toolbarBottom.invalidateMenu()
|
||||
if (uiState == null) {
|
||||
supportActionBar?.subtitle = null
|
||||
viewBinding.slider.isVisible = false
|
||||
return
|
||||
}
|
||||
if (uiState != null && previous?.chapterName != null && uiState.chapterName != previous.chapterName) {
|
||||
supportActionBar?.subtitle = when {
|
||||
uiState.incognito -> getString(R.string.incognito_mode)
|
||||
else -> uiState.chapterName
|
||||
}
|
||||
if (previous?.chapterName != null && uiState.chapterName != previous.chapterName) {
|
||||
if (!uiState.chapterName.isNullOrEmpty()) {
|
||||
viewBinding.toastView.showTemporary(uiState.chapterName, TOAST_DURATION)
|
||||
}
|
||||
}
|
||||
if (uiState.isSliderAvailable()) {
|
||||
viewBinding.slider.valueTo = uiState.totalPages.toFloat() - 1
|
||||
viewBinding.slider.setValueRounded(uiState.currentPage.toFloat())
|
||||
viewBinding.slider.isVisible = true
|
||||
} else {
|
||||
viewBinding.slider.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
class IntentBuilder(context: Context) {
|
||||
|
||||
@@ -3,29 +3,17 @@ package org.koitharu.kotatsu.reader.ui
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.android.material.slider.LabelFormatter
|
||||
import com.google.android.material.slider.Slider
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||
import org.koitharu.kotatsu.core.util.ext.isRtl
|
||||
import org.koitharu.kotatsu.core.util.ext.setValueRounded
|
||||
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet
|
||||
import org.koitharu.kotatsu.reader.ui.config.ReaderConfigSheet
|
||||
import org.koitharu.kotatsu.reader.ui.pager.ReaderUiState
|
||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
class ReaderBottomMenuProvider(
|
||||
private val activity: FragmentActivity,
|
||||
private val readerManager: ReaderManager,
|
||||
private val viewModel: ReaderViewModel,
|
||||
private val callback: ReaderNavigationCallback,
|
||||
) : OnBackPressedCallback(false), MenuProvider, MenuItem.OnActionExpandListener {
|
||||
|
||||
private var expandedItemRef: WeakReference<MenuItem>? = null
|
||||
) : MenuProvider {
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.opt_reader_bottom, menu)
|
||||
@@ -33,31 +21,12 @@ class ReaderBottomMenuProvider(
|
||||
}
|
||||
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
val shouldExpandSlider = expandedItemRef != null
|
||||
|
||||
val hasPages = viewModel.content.value.pages.isNotEmpty()
|
||||
menu.findItem(R.id.action_pages_thumbs).isVisible = hasPages
|
||||
|
||||
menu.findItem(R.id.action_slider)?.run {
|
||||
val state = viewModel.uiState.value?.takeIf { it.isSliderAvailable() }
|
||||
isVisible = state != null
|
||||
setOnActionExpandListener(this@ReaderBottomMenuProvider)
|
||||
if (state != null) {
|
||||
(actionView as? Slider)?.setupPagesSlider(state)
|
||||
}
|
||||
if (shouldExpandSlider) {
|
||||
expandActionView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
return when (menuItem.itemId) {
|
||||
R.id.action_settings -> {
|
||||
activity.startActivity(SettingsActivity.newReaderSettingsIntent(activity))
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_pages_thumbs -> {
|
||||
ChaptersPagesSheet.show(activity.supportFragmentManager, ChaptersPagesSheet.TAB_PAGES)
|
||||
true
|
||||
@@ -73,48 +42,4 @@ class ReaderBottomMenuProvider(
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
expandedItemRef?.get()?.collapseActionView()
|
||||
}
|
||||
|
||||
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
|
||||
expandedItemRef = WeakReference(item)
|
||||
isEnabled = true
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
|
||||
expandedItemRef = null
|
||||
isEnabled = false
|
||||
return true
|
||||
}
|
||||
|
||||
fun collapseSlider() {
|
||||
expandedItemRef?.get()?.collapseActionView()
|
||||
}
|
||||
|
||||
fun isSliderExpanded(): Boolean {
|
||||
return expandedItemRef?.get()?.isActionViewExpanded == true
|
||||
}
|
||||
|
||||
fun updateState(state: ReaderUiState?): Boolean {
|
||||
if (state == null || !state.isSliderAvailable()) {
|
||||
return false
|
||||
}
|
||||
val slider = (expandedItemRef?.get()?.actionView as? Slider) ?: return false
|
||||
slider.valueTo = state.totalPages.toFloat() - 1
|
||||
slider.setValueRounded(state.currentPage.toFloat())
|
||||
return true
|
||||
}
|
||||
|
||||
private fun Slider.setupPagesSlider(state: ReaderUiState) {
|
||||
isRtl = viewModel.readerMode.value == ReaderMode.REVERSED
|
||||
valueTo = state.totalPages.toFloat() - 1
|
||||
setValueRounded(state.currentPage.toFloat())
|
||||
labelBehavior = LabelFormatter.LABEL_FLOATING
|
||||
isTickVisible = true
|
||||
setLabelFormatter(PageLabelFormatter())
|
||||
ReaderSliderListener(viewModel, callback).attachToSlider(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,13 @@ class ReaderInfoBarView @JvmOverloads constructor(
|
||||
|
||||
fun update(state: ReaderUiState?) {
|
||||
text = if (state != null) {
|
||||
state.resolveSummary(context) + if (state.percent in 0f..1f) {
|
||||
context.getString(
|
||||
R.string.reader_info_pattern,
|
||||
state.chapterNumber,
|
||||
state.chaptersTotal,
|
||||
state.currentPage + 1,
|
||||
state.totalPages,
|
||||
) + if (state.percent in 0f..1f) {
|
||||
" " + context.getString(R.string.percent_string_pattern, (state.percent * 100).format())
|
||||
} else {
|
||||
""
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package org.koitharu.kotatsu.reader.ui.pager
|
||||
|
||||
import android.content.Context
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.parsers.util.format
|
||||
|
||||
data class ReaderUiState(
|
||||
val mangaName: String?,
|
||||
val branch: String?,
|
||||
@@ -20,28 +16,4 @@ data class ReaderUiState(
|
||||
fun isSliderAvailable(): Boolean {
|
||||
return isSliderEnabled && totalPages > 1 && currentPage < totalPages
|
||||
}
|
||||
|
||||
fun resolveSubtitle(context: Context): String? {
|
||||
val firstPart = branch
|
||||
val secondPart = if (incognito) {
|
||||
context.getString(R.string.incognito_mode)
|
||||
} else if (percent in 0f..1f) {
|
||||
context.getString(R.string.percent_string_pattern, (percent * 100).format())
|
||||
} else {
|
||||
null
|
||||
}
|
||||
return if (firstPart != null && secondPart != null) {
|
||||
context.getString(R.string.download_summary_pattern, firstPart, secondPart)
|
||||
} else {
|
||||
firstPart ?: secondPart
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveSummary(context: Context) = context.getString(
|
||||
R.string.reader_info_pattern,
|
||||
chapterNumber,
|
||||
chaptersTotal,
|
||||
currentPage + 1,
|
||||
totalPages,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M21,9L17,5V8H10V10H17V13M7,11L3,15L7,19V16H14V14H7V11Z" />
|
||||
</vector>
|
||||
@@ -60,6 +60,15 @@
|
||||
android:layout_weight="1"
|
||||
tools:menu="@menu/opt_reader_bottom">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stepSize="1"
|
||||
android:valueFrom="0"
|
||||
app:labelBehavior="floating"
|
||||
app:tickVisible="false" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -65,7 +65,20 @@
|
||||
android:id="@+id/toolbar_bottom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:menu="@menu/opt_reader_bottom" />
|
||||
tools:menu="@menu/opt_reader_bottom">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/slider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stepSize="1.0"
|
||||
android:valueFrom="0"
|
||||
app:labelBehavior="floating"
|
||||
app:tickVisible="true"
|
||||
tools:value="6"
|
||||
tools:valueTo="20" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -88,8 +101,12 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/bg_card"
|
||||
android:backgroundTint="?colorBackgroundFloating"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:outlineProvider="background"
|
||||
android:padding="@dimen/screen_padding">
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/progressBar"
|
||||
@@ -101,9 +118,9 @@
|
||||
android:id="@+id/textView_loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/loading_"
|
||||
android:textAppearance="?attr/textAppearanceBody2" />
|
||||
android:textAppearance="?attr/textAppearanceTitleMedium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -5,15 +5,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:ignore="AlwaysShowAction">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_slider"
|
||||
android:icon="@drawable/ic_slider"
|
||||
android:title="@string/reader_slider"
|
||||
android:visible="false"
|
||||
app:actionViewClass="com.google.android.material.slider.Slider"
|
||||
app:showAsAction="always|collapseActionView"
|
||||
tools:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_pages_thumbs"
|
||||
android:icon="@drawable/ic_grid"
|
||||
@@ -26,6 +17,7 @@
|
||||
android:id="@+id/action_options"
|
||||
android:icon="@drawable/abc_ic_menu_overflow_material"
|
||||
android:title="@string/options"
|
||||
app:showAsAction="always" />
|
||||
app:showAsAction="always"
|
||||
tools:visible="true" />
|
||||
|
||||
</menu>
|
||||
|
||||
Reference in New Issue
Block a user