mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
WIP lyric selection
This commit is contained in:
parent
6fa3f550b0
commit
d37c7604d2
3 changed files with 49 additions and 24 deletions
|
|
@ -22,7 +22,6 @@ import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.tv.material3.Text
|
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.model.CollectionFolderFilter
|
import com.github.damontecres.wholphin.data.model.CollectionFolderFilter
|
||||||
import com.github.damontecres.wholphin.data.model.GetItemsFilter
|
import com.github.damontecres.wholphin.data.model.GetItemsFilter
|
||||||
|
|
@ -55,7 +54,6 @@ fun CollectionFolderMusic(
|
||||||
stringResource(R.string.recommended),
|
stringResource(R.string.recommended),
|
||||||
stringResource(R.string.albums),
|
stringResource(R.string.albums),
|
||||||
stringResource(R.string.artists),
|
stringResource(R.string.artists),
|
||||||
stringResource(R.string.playlists),
|
|
||||||
stringResource(R.string.genres),
|
stringResource(R.string.genres),
|
||||||
stringResource(R.string.songs),
|
stringResource(R.string.songs),
|
||||||
)
|
)
|
||||||
|
|
@ -173,14 +171,8 @@ fun CollectionFolderMusic(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Playlists
|
|
||||||
3 -> {
|
|
||||||
// TODO
|
|
||||||
Text("TODO")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Genres
|
// Genres
|
||||||
4 -> {
|
3 -> {
|
||||||
GenreCardGrid(
|
GenreCardGrid(
|
||||||
itemId = destination.itemId,
|
itemId = destination.itemId,
|
||||||
includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM, BaseItemKind.AUDIO),
|
includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM, BaseItemKind.AUDIO),
|
||||||
|
|
@ -192,7 +184,7 @@ fun CollectionFolderMusic(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Songs
|
// Songs
|
||||||
5 -> {
|
4 -> {
|
||||||
CollectionFolderGrid(
|
CollectionFolderGrid(
|
||||||
preferences = preferences,
|
preferences = preferences,
|
||||||
onClickItem = { _, item ->
|
onClickItem = { _, item ->
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,28 @@ package com.github.damontecres.wholphin.ui.detail.music
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.LinearEasing
|
import androidx.compose.animation.core.LinearEasing
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
|
|
@ -26,6 +34,7 @@ import org.jellyfin.sdk.model.api.LyricLine
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LyricsContent(
|
fun LyricsContent(
|
||||||
|
synced: Boolean,
|
||||||
lyrics: LyricDto?,
|
lyrics: LyricDto?,
|
||||||
currentLyricPosition: Int?,
|
currentLyricPosition: Int?,
|
||||||
onClick: (LyricLine) -> Unit,
|
onClick: (LyricLine) -> Unit,
|
||||||
|
|
@ -33,16 +42,23 @@ fun LyricsContent(
|
||||||
) {
|
) {
|
||||||
val listState = rememberLazyListState(currentLyricPosition ?: 0)
|
val listState = rememberLazyListState(currentLyricPosition ?: 0)
|
||||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
LaunchedEffect(currentLyricPosition) {
|
if (synced) {
|
||||||
if (currentLyricPosition != null) {
|
LaunchedEffect(currentLyricPosition) {
|
||||||
bringIntoViewRequester.bringIntoView()
|
if (currentLyricPosition != null) {
|
||||||
|
listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index?.let {
|
||||||
|
if (currentLyricPosition !in 0..it) {
|
||||||
|
listState.animateScrollToItem(currentLyricPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bringIntoViewRequester.bringIntoView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
contentPadding = PaddingValues(),
|
contentPadding = PaddingValues(),
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
if (lyrics?.lyrics?.isNotEmpty() == true) {
|
if (lyrics?.lyrics?.isNotEmpty() == true) {
|
||||||
|
|
@ -55,17 +71,33 @@ fun LyricsContent(
|
||||||
},
|
},
|
||||||
animationSpec = tween(durationMillis = 500, easing = LinearEasing),
|
animationSpec = tween(durationMillis = 500, easing = LinearEasing),
|
||||||
)
|
)
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
Text(
|
val focused by interactionSource.collectIsFocusedAsState()
|
||||||
text = lyric.text,
|
Box(
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
|
||||||
color = color,
|
|
||||||
modifier =
|
modifier =
|
||||||
Modifier.ifElse(
|
Modifier
|
||||||
index == currentLyricPosition,
|
.background(
|
||||||
Modifier.bringIntoViewRequester(bringIntoViewRequester),
|
color = if (focused) MaterialTheme.colorScheme.border.copy(alpha = .66f) else Color.Unspecified,
|
||||||
),
|
shape = RoundedCornerShape(8.dp),
|
||||||
)
|
),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = lyric.text,
|
||||||
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
color = color,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(4.dp)
|
||||||
|
.clickable(
|
||||||
|
enabled = !synced,
|
||||||
|
onClick = { onClick.invoke(lyric) },
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
).ifElse(
|
||||||
|
index == currentLyricPosition,
|
||||||
|
Modifier.bringIntoViewRequester(bringIntoViewRequester),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ fun NowPlayingPage(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
LyricsContent(
|
LyricsContent(
|
||||||
|
synced = true,
|
||||||
lyrics = state.lyrics,
|
lyrics = state.lyrics,
|
||||||
currentLyricPosition = state.currentLyricIndex,
|
currentLyricPosition = state.currentLyricIndex,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue