mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Hold-to-seek acceleration for playback DPAD and seekbar (#900)
## Description - Adds hold-to-seek acceleration for left/right DPAD input during playback skip handling. - Reuses one shared, duration-aware acceleration profile for both playback DPAD and seekbar skipping. - Extracts acceleration logic into a shared helper to keep playback and seekbar behavior consistent. - Slows the acceleration ramp (about one-third) to improve control during longer holds. - Preserves tap-on-release behavior: single taps seek on key release, while holds seek on repeated key-down without an extra release step. - Normalizes unknown/unset duration values to use the shortest-content acceleration profile. - Added unit coverage for shared seek acceleration math to prevent accidental regression in ramp thresholds. ### Related issues Supersedes #846 Incorporates #784 Closes #522 ### Testing Tested on Nvidia Shield Pro 2019. - Quick left/right tap still performs normal skip behavior. - Holding left/right seeks repeatedly with progressive acceleration. - Seekbar hold uses the same acceleration profile as playback hold. - Releasing after a hold does not trigger an extra seek step. ## AI or LLM usage Codex 5.3 and Claude Opus 4.6 were used for implementation, debugging, and cross-review. Changes were manually validated on device. --------- Co-authored-by: Ray <154766448+damontecres@users.noreply.github.com>
This commit is contained in:
parent
55466f803c
commit
fd9063fbad
5 changed files with 279 additions and 27 deletions
|
|
@ -0,0 +1,53 @@
|
|||
package com.github.damontecres.wholphin.ui.playback
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class SeekAccelerationTest {
|
||||
@Test
|
||||
fun returnsOneWhenNotRepeating() {
|
||||
assertEquals(1, calculateSeekAccelerationMultiplier(repeatCount = 0, durationMs = 30_000L))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unknownDurationDoesNotAccelerate() {
|
||||
assertEquals(1, calculateSeekAccelerationMultiplier(repeatCount = 89, durationMs = 0L))
|
||||
assertEquals(1, calculateSeekAccelerationMultiplier(repeatCount = 300, durationMs = -1L))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shortContentHasTwoTiers() {
|
||||
val shortDurationMs = 20L * 60_000L
|
||||
|
||||
assertEquals(
|
||||
1,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 89, durationMs = shortDurationMs),
|
||||
)
|
||||
assertEquals(
|
||||
2,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 90, durationMs = shortDurationMs),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mediumContentEscalatesAcrossAllTiers() {
|
||||
val mediumDurationMs = 60L * 60_000L
|
||||
|
||||
assertEquals(
|
||||
1,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 38, durationMs = mediumDurationMs),
|
||||
)
|
||||
assertEquals(
|
||||
2,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 39, durationMs = mediumDurationMs),
|
||||
)
|
||||
assertEquals(
|
||||
3,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 150, durationMs = mediumDurationMs),
|
||||
)
|
||||
assertEquals(
|
||||
4,
|
||||
calculateSeekAccelerationMultiplier(repeatCount = 225, durationMs = mediumDurationMs),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue