Scroll timer improvements
This commit is contained in:
@@ -110,7 +110,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
|
||||
setSupportActionBar(viewBinding.searchBar)
|
||||
|
||||
viewBinding.fab?.setOnClickListener(this)
|
||||
viewBinding.navRail?.headerView?.setOnClickListener(this)
|
||||
viewBinding.navRail?.headerView?.findViewById<View>(R.id.railFab)?.setOnClickListener(this)
|
||||
fadingAppbarMediator =
|
||||
FadingAppbarMediator(viewBinding.appbar, viewBinding.layoutSearch ?: viewBinding.searchBar)
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ class ReaderActivity :
|
||||
ReaderControlDelegate.OnInteractionListener,
|
||||
ReaderNavigationCallback,
|
||||
IdlingDetector.Callback,
|
||||
ZoomControl.ZoomControlListener {
|
||||
ZoomControl.ZoomControlListener, View.OnClickListener, ScrollTimerControlView.OnVisibilityChangeListener {
|
||||
|
||||
@Inject
|
||||
lateinit var settings: AppSettings
|
||||
@@ -115,10 +115,15 @@ class ReaderActivity :
|
||||
controlDelegate = ReaderControlDelegate(resources, settings, tapGridSettings, this)
|
||||
viewBinding.zoomControl.listener = this
|
||||
viewBinding.actionsView.listener = this
|
||||
viewBinding.buttonTimer?.setOnClickListener(this)
|
||||
idlingDetector.bindToLifecycle(this)
|
||||
screenOrientationHelper.applySettings()
|
||||
viewModel.isBookmarkAdded.observe(this) { viewBinding.actionsView.isBookmarkAdded = it }
|
||||
scrollTimer.isActive.observe(this) { viewBinding.actionsView.setTimerActive(it) }
|
||||
scrollTimer.isActive.observe(this) {
|
||||
updateScrollTimerButton()
|
||||
viewBinding.actionsView.setTimerActive(it)
|
||||
}
|
||||
viewBinding.timerControl.onVisibilityChangeListener = this
|
||||
viewBinding.timerControl.attach(scrollTimer, this)
|
||||
if (resources.getBoolean(R.bool.is_tablet)) {
|
||||
viewBinding.timerControl.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||
@@ -198,6 +203,10 @@ class ReaderActivity :
|
||||
viewModel.saveCurrentState(readerManager.currentReader?.getCurrentState())
|
||||
}
|
||||
|
||||
override fun onVisibilityChanged(v: View, visibility: Int) {
|
||||
updateScrollTimerButton()
|
||||
}
|
||||
|
||||
override fun onZoomIn() {
|
||||
readerManager.currentReader?.onZoomIn()
|
||||
}
|
||||
@@ -206,6 +215,12 @@ class ReaderActivity :
|
||||
readerManager.currentReader?.onZoomOut()
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.button_timer -> onScrollTimerClick(isLongClick = false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onInitReader(mode: ReaderMode?) {
|
||||
if (mode == null) {
|
||||
return
|
||||
@@ -328,6 +343,7 @@ class ReaderActivity :
|
||||
viewBinding.toolbarDocked?.isVisible = isUiVisible
|
||||
viewBinding.infoBar.isGone = isUiVisible || (!viewModel.isInfoBarEnabled.value)
|
||||
viewBinding.infoBar.isTimeVisible = isFullscreen
|
||||
updateScrollTimerButton()
|
||||
systemUiController.setSystemUiVisible(isUiVisible || !isFullscreen)
|
||||
}
|
||||
}
|
||||
@@ -455,6 +471,18 @@ class ReaderActivity :
|
||||
viewBinding.actionsView.isPrevEnabled = uiState.hasPreviousChapter()
|
||||
}
|
||||
|
||||
private fun updateScrollTimerButton() {
|
||||
val button = viewBinding.buttonTimer ?: return
|
||||
val isButtonVisible = scrollTimer.isActive.value
|
||||
&& !viewBinding.appbarTop.isVisible
|
||||
&& !viewBinding.timerControl.isVisible
|
||||
if (button.isVisible != isButtonVisible) {
|
||||
val transition = Fade().addTarget(button)
|
||||
TransitionManager.beginDelayedTransition(viewBinding.root, transition)
|
||||
button.isVisible = isButtonVisible
|
||||
}
|
||||
}
|
||||
|
||||
private fun askForIncognitoMode() {
|
||||
buildAlertDialog(this, isCentered = true) {
|
||||
var dontAskAgain = false
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.koitharu.kotatsu.core.prefs.observeAsFlow
|
||||
import org.koitharu.kotatsu.core.util.ext.resolveDp
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
private const val MAX_DELAY = 8L
|
||||
private const val MAX_DELAY = 32L
|
||||
private const val MAX_SWITCH_DELAY = 10_000L
|
||||
private const val INTERACTION_SKIP_MS = 2_000L
|
||||
private const val SPEED_FACTOR_DELTA = 0.02f
|
||||
@@ -45,7 +45,7 @@ class ScrollTimer @AssistedInject constructor(
|
||||
private var resumeAt = 0L
|
||||
private var isTouchDown = MutableStateFlow(false)
|
||||
private val isRunning = MutableStateFlow(false)
|
||||
private val scrollDelta = resources.resolveDp(2)
|
||||
private val scrollDelta = resources.resolveDp(1)
|
||||
|
||||
val isActive: StateFlow<Boolean>
|
||||
get() = isRunning
|
||||
@@ -88,7 +88,7 @@ class ScrollTimer @AssistedInject constructor(
|
||||
delayMs = 0L
|
||||
pageSwitchDelay = 0L
|
||||
} else {
|
||||
val speedFactor = 1 - speed
|
||||
val speedFactor = 1f - speed
|
||||
delayMs = (MAX_DELAY * speedFactor).roundToLong()
|
||||
pageSwitchDelay = (MAX_SWITCH_DELAY * speedFactor).roundToLong()
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.koitharu.kotatsu.core.util.ext.parentView
|
||||
import org.koitharu.kotatsu.databinding.ViewScrollTimerBinding
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ScrollTimerControlView @JvmOverloads constructor(
|
||||
@@ -37,6 +38,8 @@ class ScrollTimerControlView @JvmOverloads constructor(
|
||||
@Inject
|
||||
lateinit var settings: AppSettings
|
||||
|
||||
var onVisibilityChangeListener: OnVisibilityChangeListener? = null
|
||||
|
||||
private val binding = ViewScrollTimerBinding.inflate(LayoutInflater.from(context), this)
|
||||
|
||||
private var scrollTimer: ScrollTimer? = null
|
||||
@@ -63,10 +66,12 @@ class ScrollTimerControlView @JvmOverloads constructor(
|
||||
key = AppSettings.KEY_READER_AUTOSCROLL_SPEED,
|
||||
valueProducer = { readerAutoscrollSpeed },
|
||||
).observe(lifecycleOwner) {
|
||||
binding.sliderTimer.value = it.coerceIn(
|
||||
binding.sliderTimer.valueFrom,
|
||||
binding.sliderTimer.valueTo,
|
||||
)
|
||||
if (abs(it - binding.sliderTimer.value) > 0.0001) {
|
||||
binding.sliderTimer.value = it.coerceIn(
|
||||
binding.sliderTimer.valueFrom,
|
||||
binding.sliderTimer.valueTo,
|
||||
)
|
||||
}
|
||||
}
|
||||
updateDescription()
|
||||
}
|
||||
@@ -83,9 +88,10 @@ class ScrollTimerControlView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun getFormattedValue(value: Float): String {
|
||||
// val minValue = binding.sliderTimer.valueFrom
|
||||
// val maxValue = binding.sliderTimer.valueTo
|
||||
return labelPattern.format(value * 10f)
|
||||
val valueFrom = binding.sliderTimer.valueFrom
|
||||
val valueTo = binding.sliderTimer.valueTo
|
||||
val percent = (value - valueFrom) / (valueTo - valueFrom)
|
||||
return labelPattern.format(0.1 + percent * 10) // just something to display
|
||||
}
|
||||
|
||||
override fun onValueChange(
|
||||
@@ -103,6 +109,11 @@ class ScrollTimerControlView @JvmOverloads constructor(
|
||||
scrollTimer?.setActive(isChecked)
|
||||
}
|
||||
|
||||
override fun setVisibility(visibility: Int) {
|
||||
super.setVisibility(visibility)
|
||||
onVisibilityChangeListener?.onVisibilityChanged(this, visibility)
|
||||
}
|
||||
|
||||
fun show() {
|
||||
setupVisibilityTransition()
|
||||
isVisible = true
|
||||
@@ -139,4 +150,9 @@ class ScrollTimerControlView @JvmOverloads constructor(
|
||||
binding.textViewDescription.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
fun interface OnVisibilityChangeListener {
|
||||
|
||||
fun onVisibilityChanged(v: View, visibility: Int)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,19 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:background="@color/grey" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_timer"
|
||||
style="?materialIconButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/page_switch_timer"
|
||||
android:tooltipText="@string/page_switch_timer"
|
||||
app:backgroundTint="@color/bg_floating_button"
|
||||
app:icon="@drawable/ic_timelapse"
|
||||
app:layout_insetEdge="bottom" />
|
||||
|
||||
<org.koitharu.kotatsu.core.ui.widgets.ZoomControl
|
||||
android:id="@+id/zoomControl"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
android:layout_marginEnd="@dimen/margin_normal"
|
||||
android:contentDescription="@string/speed"
|
||||
android:labelFor="@id/switch_scroll_timer"
|
||||
android:valueFrom="0.001"
|
||||
android:valueTo="0.9"
|
||||
android:valueFrom="0.000001"
|
||||
android:valueTo="0.95"
|
||||
app:labelBehavior="floating"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/label_timer"
|
||||
|
||||
Reference in New Issue
Block a user