Add wrap around scrolling to settings pages (#1937)

## Description
Add scrolling from top to bottom and vice versa. This makes it quicker
to get to Advanced Settings for example.

### Related issues
N/A

### Testing
Emulator

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-09-05 12:11:30 -04:00 • committed by GitHub
parent 1f3a861c47
commit 39239dd444
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 112 additions and 39 deletions

View file

@ -1,5 +1,19 @@
package com.github.damontecres.wholphin.preferences
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.type
import com.github.damontecres.wholphin.ui.ifElse
import com.github.damontecres.wholphin.ui.playback.isDown
import com.github.damontecres.wholphin.ui.playback.isUp
import com.github.damontecres.wholphin.ui.tryRequestFocus
import kotlinx.coroutines.launch
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@ -10,3 +24,48 @@ val PlaybackPreferences.skipBackOnResume: Duration?
} else {
null
}
/**
* Adds modifiers so that pressing Up on the first element scrolls to the bottom and vice versa
*/
@Composable
fun Modifier.lazyListWrapScrolling(
state: LazyListState,
focused: Boolean,
isFirst: Boolean,
isLast: Boolean,
firstFocusRequester: FocusRequester,
lastFocusRequester: FocusRequester,
): Modifier {
val scope = rememberCoroutineScope()
return this
.ifElse(
isFirst,
Modifier
.focusRequester(firstFocusRequester)
.onKeyEvent {
if (focused && isUp(it) && it.type == KeyEventType.KeyDown) {
scope.launch {
state.animateScrollToItem(state.layoutInfo.totalItemsCount - 1)
lastFocusRequester.tryRequestFocus()
}
return@onKeyEvent true
}
false
},
).ifElse(
isLast,
Modifier
.focusRequester(lastFocusRequester)
.onKeyEvent {
if (focused && isDown(it) && it.type == KeyEventType.KeyDown) {
scope.launch {
state.animateScrollToItem(0)
firstFocusRequester.tryRequestFocus()
}
return@onKeyEvent true
}
false
},
)
}