mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 15:29:15 +01:00
custom seek bar, don't play on seek, trim CJK line height, fix icon aspect
This commit is contained in:
@@ -376,10 +376,7 @@ class PlaybackController(
|
|||||||
fun previous() = skip(-1)
|
fun previous() = skip(-1)
|
||||||
|
|
||||||
fun seekTo(positionMs: Long) {
|
fun seekTo(positionMs: Long) {
|
||||||
val player = player ?: return
|
player?.seekTo(positionMs)
|
||||||
player.ensurePrepared()
|
|
||||||
player.seekTo(positionMs)
|
|
||||||
player.play()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun coverArt(
|
fun coverArt(
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.subtracks.ui.playback
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.basicMarquee
|
import androidx.compose.foundation.basicMarquee
|
||||||
|
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -30,8 +32,6 @@ import androidx.compose.material3.IconButton
|
|||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Slider
|
|
||||||
import androidx.compose.material3.SliderDefaults
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
@@ -40,6 +40,7 @@ import androidx.compose.runtime.CompositionLocalProvider
|
|||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
import androidx.compose.runtime.mutableFloatStateOf
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -47,8 +48,11 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.PlatformTextStyle
|
import androidx.compose.ui.text.PlatformTextStyle
|
||||||
|
import androidx.compose.ui.text.style.LineHeightStyle
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@@ -131,10 +135,12 @@ fun NowPlayingScreen(
|
|||||||
val titleStyle =
|
val titleStyle =
|
||||||
MaterialTheme.typography.headlineSmall.copy(
|
MaterialTheme.typography.headlineSmall.copy(
|
||||||
platformStyle = PlatformTextStyle(includeFontPadding = false),
|
platformStyle = PlatformTextStyle(includeFontPadding = false),
|
||||||
|
lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.Both),
|
||||||
)
|
)
|
||||||
val subtitleStyle =
|
val subtitleStyle =
|
||||||
MaterialTheme.typography.bodyMedium.copy(
|
MaterialTheme.typography.bodyMedium.copy(
|
||||||
platformStyle = PlatformTextStyle(includeFontPadding = false),
|
platformStyle = PlatformTextStyle(includeFontPadding = false),
|
||||||
|
lineHeightStyle = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.Both),
|
||||||
)
|
)
|
||||||
|
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||||
@@ -218,26 +224,9 @@ fun NowPlayingScreen(
|
|||||||
modifier = Modifier.padding(top = 6.dp).basicMarquee(),
|
modifier = Modifier.padding(top = 6.dp).basicMarquee(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
var dragging by remember { mutableStateOf(false) }
|
SeekBar(
|
||||||
var dragPosition by remember { mutableFloatStateOf(0f) }
|
progress = if (state.durationMs > 0) (state.positionMs.toFloat() / state.durationMs).coerceIn(0f, 1f) else 0f,
|
||||||
Slider(
|
onSeek = { fraction -> onSeek((fraction * state.durationMs).toLong()) },
|
||||||
value = if (dragging) dragPosition else state.positionMs.toFloat(),
|
|
||||||
onValueChange = {
|
|
||||||
dragging = true
|
|
||||||
dragPosition = it
|
|
||||||
},
|
|
||||||
onValueChangeFinished = {
|
|
||||||
onSeek(dragPosition.toLong())
|
|
||||||
dragging = false
|
|
||||||
},
|
|
||||||
valueRange = 0f..state.durationMs.toFloat().coerceAtLeast(1f),
|
|
||||||
track = { sliderState ->
|
|
||||||
SliderDefaults.Track(
|
|
||||||
sliderState = sliderState,
|
|
||||||
thumbTrackGapSize = 0.dp,
|
|
||||||
drawStopIndicator = {},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
modifier = Modifier.padding(top = 28.dp),
|
modifier = Modifier.padding(top = 28.dp),
|
||||||
)
|
)
|
||||||
Row(
|
Row(
|
||||||
@@ -317,6 +306,50 @@ fun NowPlayingScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun SeekBar(
|
||||||
|
progress: Float,
|
||||||
|
onSeek: (Float) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
var widthPx by remember { mutableIntStateOf(0) }
|
||||||
|
var dragging by remember { mutableStateOf(false) }
|
||||||
|
var dragFraction by remember { mutableFloatStateOf(0f) }
|
||||||
|
val active = MaterialTheme.colorScheme.primary
|
||||||
|
val track = active.copy(alpha = 0.24f)
|
||||||
|
val shown = if (dragging) dragFraction else progress
|
||||||
|
Box(
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(32.dp)
|
||||||
|
.onSizeChanged { widthPx = it.width }
|
||||||
|
.pointerInput(widthPx) {
|
||||||
|
detectHorizontalDragGestures(
|
||||||
|
onDragStart = { offset ->
|
||||||
|
dragging = true
|
||||||
|
dragFraction = if (widthPx > 0) (offset.x / widthPx).coerceIn(0f, 1f) else 0f
|
||||||
|
},
|
||||||
|
onDragEnd = {
|
||||||
|
dragging = false
|
||||||
|
onSeek(dragFraction)
|
||||||
|
},
|
||||||
|
onDragCancel = { dragging = false },
|
||||||
|
) { change, _ ->
|
||||||
|
dragFraction = if (widthPx > 0) (change.position.x / widthPx).coerceIn(0f, 1f) else 0f
|
||||||
|
}
|
||||||
|
}.pointerInput(widthPx) {
|
||||||
|
detectTapGestures { offset ->
|
||||||
|
if (widthPx > 0) onSeek((offset.x / widthPx).coerceIn(0f, 1f))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
) {
|
||||||
|
Box(Modifier.fillMaxWidth().height(4.dp).background(track))
|
||||||
|
Box(Modifier.fillMaxWidth(shown).height(4.dp).background(active))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun formatTime(milliseconds: Long): String {
|
private fun formatTime(milliseconds: Long): String {
|
||||||
val totalSeconds = (milliseconds / 1000).coerceAtLeast(0)
|
val totalSeconds = (milliseconds / 1000).coerceAtLeast(0)
|
||||||
val minutes = totalSeconds / 60
|
val minutes = totalSeconds / 60
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="299.84"
|
android:viewportWidth="300"
|
||||||
android:viewportHeight="219.51">
|
android:viewportHeight="300">
|
||||||
|
<group android:translateY="40.25">
|
||||||
<path
|
<path
|
||||||
android:pathData="m23.84,-0c-12.76,0 -23.44,13 -23.65,25.12 -0.42,79.03 0,160.73 0,170.4 0,12.59 9.8,23.99 23.41,23.99l253.58,0c11.4,0 22.66,-12.38 22.66,-22.79L299.84,24.12c0,-10.8 -10.24,-23.81 -21.84,-23.81 -11.6,0 -254.16,-0.31 -254.16,-0.31zM39.05,25.28c0,0 217.71,0.71 223.67,0.71 6.07,0 12.17,6.83 12.17,12.06l0,142.25c0,8.97 -6.97,14.63 -12.48,14.64l-33.42,0.07c-5.32,0.01 -9.93,-7.19 -11.35,-10.61 -1.89,-4.55 -11.08,-25.75 -12.1,-28.1 -0.6,-1.38 -2.9,-2.83 -5.89,-2.83L98.33,153.45c-2.68,0 -4.89,2.87 -5.67,4.71 -1.12,2.66 -9.02,21.39 -11.63,27.57 -2.73,6.46 -4.37,9.06 -11.47,9.06l-30.97,0c-7.44,0 -13.69,-7.17 -13.67,-15.18l0.28,-139.51c0,-6.88 5.54,-14.83 13.85,-14.83z"
|
android:pathData="m23.84,-0c-12.76,0 -23.44,13 -23.65,25.12 -0.42,79.03 0,160.73 0,170.4 0,12.59 9.8,23.99 23.41,23.99l253.58,0c11.4,0 22.66,-12.38 22.66,-22.79L299.84,24.12c0,-10.8 -10.24,-23.81 -21.84,-23.81 -11.6,0 -254.16,-0.31 -254.16,-0.31zM39.05,25.28c0,0 217.71,0.71 223.67,0.71 6.07,0 12.17,6.83 12.17,12.06l0,142.25c0,8.97 -6.97,14.63 -12.48,14.64l-33.42,0.07c-5.32,0.01 -9.93,-7.19 -11.35,-10.61 -1.89,-4.55 -11.08,-25.75 -12.1,-28.1 -0.6,-1.38 -2.9,-2.83 -5.89,-2.83L98.33,153.45c-2.68,0 -4.89,2.87 -5.67,4.71 -1.12,2.66 -9.02,21.39 -11.63,27.57 -2.73,6.46 -4.37,9.06 -11.47,9.06l-30.97,0c-7.44,0 -13.69,-7.17 -13.67,-15.18l0.28,-139.51c0,-6.88 5.54,-14.83 13.85,-14.83z"
|
||||||
android:strokeWidth="0.9"
|
android:strokeWidth="0.9"
|
||||||
@@ -21,4 +22,5 @@
|
|||||||
android:fillColor="#FFFFFFFF"
|
android:fillColor="#FFFFFFFF"
|
||||||
android:fillType="nonZero"
|
android:fillType="nonZero"
|
||||||
android:strokeColor="#00000000"/>
|
android:strokeColor="#00000000"/>
|
||||||
|
</group>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
Reference in New Issue
Block a user