mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
Revert "replace the play arrow with an animated bar indicator"
This reverts commit c67569a15a7c7150de3601b57a59e2ed2ba302ef.
This commit is contained in:
@@ -1,10 +1,5 @@
|
||||
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.border
|
||||
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.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.DownloadDone
|
||||
import androidx.compose.material.icons.rounded.PlayArrow
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
@@ -25,7 +21,6 @@ import androidx.compose.material3.ListItemDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
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.clipPath
|
||||
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.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.semantics.contentDescription
|
||||
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.SongDownload
|
||||
import com.subtracks.ui.components.CoverArt
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.sin
|
||||
|
||||
private val TRACK_COLUMN_WIDTH = 24.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 INNER_SHADOW_RADIUS = 8.dp
|
||||
private val INNER_SHADOW = Color.Black.copy(alpha = 0.85f)
|
||||
private const val BAR_COUNT = 3
|
||||
private const val PLAY_BAR_PERIOD_MS = 900
|
||||
private const val PLAY_BAR_PHASE = 0.18f
|
||||
private val PLAY_ARROW = Icons.Rounded.PlayArrow
|
||||
private val PLAY_ARROW_PATH: Path by lazy { buildVectorPath(PLAY_ARROW) }
|
||||
|
||||
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
|
||||
fun SongRow(
|
||||
@@ -204,44 +216,30 @@ private fun PlayIndicator(
|
||||
shadow: Boolean,
|
||||
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 shadowRadius = with(LocalDensity.current) { PLAY_SHADOW_RADIUS.toPx() }
|
||||
Canvas(modifier.semantics { contentDescription = "Playing" }) {
|
||||
val barWidth = size.width * 0.22f
|
||||
val gap = size.width * 0.11f
|
||||
val radius = CornerRadius(barWidth / 2f)
|
||||
val total = barWidth * BAR_COUNT + gap * (BAR_COUNT - 1)
|
||||
val startX = (size.width - total) / 2f
|
||||
val minHeight = size.height * 0.3f
|
||||
val bars =
|
||||
(0 until BAR_COUNT).map { index ->
|
||||
val wave = ((sin((phase + index * PLAY_BAR_PHASE) * 2.0 * PI) + 1.0) / 2.0).toFloat()
|
||||
val height = minHeight + (size.height - minHeight) * wave
|
||||
val x = startX + index * (barWidth + gap)
|
||||
Rect(x, (size.height - height) / 2f, x + barWidth, (size.height + height) / 2f)
|
||||
if (shadow) {
|
||||
val radius = with(LocalDensity.current) { PLAY_SHADOW_RADIUS.toPx() }
|
||||
Canvas(modifier.semantics { contentDescription = "Playing" }) {
|
||||
val scale = minOf(size.width / PLAY_ARROW.viewportWidth, size.height / PLAY_ARROW.viewportHeight)
|
||||
withTransform({ scale(scale, scale, pivot = Offset.Zero) }) {
|
||||
drawIntoCanvas { canvas ->
|
||||
val paint =
|
||||
android.graphics.Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = tint.toArgb()
|
||||
setShadowLayer(radius, 0f, 0f, PLAY_SHADOW.toArgb())
|
||||
}
|
||||
canvas.nativeCanvas.drawPath(PLAY_ARROW_PATH.asAndroidPath(), paint)
|
||||
}
|
||||
}
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user