Revert "replace the play arrow with an animated bar indicator"

This reverts commit c67569a15a7c7150de3601b57a59e2ed2ba302ef.
This commit is contained in:
austinried
2026-10-04 00:30:02 +00:00
parent a23d9a3c31
commit 94c514cdd9
@@ -1,10 +1,5 @@
package com.subtracks.ui.library package com.subtracks.ui.library
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -18,6 +13,7 @@ import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.text.TextAutoSize import androidx.compose.foundation.text.TextAutoSize
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.DownloadDone import androidx.compose.material.icons.rounded.DownloadDone
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
@@ -25,7 +21,6 @@ import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment 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
@@ -41,8 +36,13 @@ import androidx.compose.ui.graphics.asAndroidPath
import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.clipPath import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.PathParser
import androidx.compose.ui.graphics.vector.VectorGroup
import androidx.compose.ui.graphics.vector.VectorPath
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
@@ -56,8 +56,6 @@ import com.subtracks.data.model.DownloadStatus
import com.subtracks.data.model.Song import com.subtracks.data.model.Song
import com.subtracks.data.model.SongDownload import com.subtracks.data.model.SongDownload
import com.subtracks.ui.components.CoverArt import com.subtracks.ui.components.CoverArt
import kotlin.math.PI
import kotlin.math.sin
private val TRACK_COLUMN_WIDTH = 24.dp private val TRACK_COLUMN_WIDTH = 24.dp
private val TIME_COLUMN_WIDTH = 36.dp private val TIME_COLUMN_WIDTH = 36.dp
@@ -68,9 +66,23 @@ private val PLAY_SHADOW_RADIUS = 3.dp
private val PLAY_SHADOW = Color.Black.copy(alpha = 0.6f) private val PLAY_SHADOW = Color.Black.copy(alpha = 0.6f)
private val INNER_SHADOW_RADIUS = 8.dp private val INNER_SHADOW_RADIUS = 8.dp
private val INNER_SHADOW = Color.Black.copy(alpha = 0.85f) private val INNER_SHADOW = Color.Black.copy(alpha = 0.85f)
private const val BAR_COUNT = 3 private val PLAY_ARROW = Icons.Rounded.PlayArrow
private const val PLAY_BAR_PERIOD_MS = 900 private val PLAY_ARROW_PATH: Path by lazy { buildVectorPath(PLAY_ARROW) }
private const val PLAY_BAR_PHASE = 0.18f
private fun buildVectorPath(vector: ImageVector): Path {
val parser = PathParser()
fun collect(group: VectorGroup) {
for (node in group) {
when (node) {
is VectorPath -> parser.addPathNodes(node.pathData)
is VectorGroup -> collect(node)
}
}
}
collect(vector.root)
return parser.toPath()
}
@Composable @Composable
fun SongRow( fun SongRow(
@@ -204,44 +216,30 @@ private fun PlayIndicator(
shadow: Boolean, shadow: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val phase by
rememberInfiniteTransition(label = "playing")
.animateFloat(
initialValue = 0f,
targetValue = 1f,
animationSpec = infiniteRepeatable(tween(PLAY_BAR_PERIOD_MS, easing = LinearEasing)),
label = "phase",
)
val tint = MaterialTheme.colorScheme.primary val tint = MaterialTheme.colorScheme.primary
val shadowRadius = with(LocalDensity.current) { PLAY_SHADOW_RADIUS.toPx() } if (shadow) {
Canvas(modifier.semantics { contentDescription = "Playing" }) { val radius = with(LocalDensity.current) { PLAY_SHADOW_RADIUS.toPx() }
val barWidth = size.width * 0.22f Canvas(modifier.semantics { contentDescription = "Playing" }) {
val gap = size.width * 0.11f val scale = minOf(size.width / PLAY_ARROW.viewportWidth, size.height / PLAY_ARROW.viewportHeight)
val radius = CornerRadius(barWidth / 2f) withTransform({ scale(scale, scale, pivot = Offset.Zero) }) {
val total = barWidth * BAR_COUNT + gap * (BAR_COUNT - 1) drawIntoCanvas { canvas ->
val startX = (size.width - total) / 2f val paint =
val minHeight = size.height * 0.3f android.graphics.Paint().apply {
val bars = isAntiAlias = true
(0 until BAR_COUNT).map { index -> color = tint.toArgb()
val wave = ((sin((phase + index * PLAY_BAR_PHASE) * 2.0 * PI) + 1.0) / 2.0).toFloat() setShadowLayer(radius, 0f, 0f, PLAY_SHADOW.toArgb())
val height = minHeight + (size.height - minHeight) * wave }
val x = startX + index * (barWidth + gap) canvas.nativeCanvas.drawPath(PLAY_ARROW_PATH.asAndroidPath(), paint)
Rect(x, (size.height - height) / 2f, x + barWidth, (size.height + height) / 2f) }
} }
if (shadow) {
val path = Path().apply { bars.forEach { addRoundRect(RoundRect(it, radius)) } }
drawIntoCanvas { canvas ->
val paint =
android.graphics.Paint().apply {
isAntiAlias = true
color = tint.toArgb()
setShadowLayer(shadowRadius, 0f, 0f, PLAY_SHADOW.toArgb())
}
canvas.nativeCanvas.drawPath(path.asAndroidPath(), paint)
}
} else {
bars.forEach { drawRoundRect(color = tint, topLeft = it.topLeft, size = it.size, cornerRadius = radius) }
} }
} else {
Icon(
imageVector = PLAY_ARROW,
contentDescription = "Playing",
tint = tint,
modifier = modifier,
)
} }
} }