@@ -21,17 +21,16 @@ import androidx.compose.foundation.background
2121import androidx.compose.foundation.border
2222import androidx.compose.foundation.layout.Box
2323import androidx.compose.foundation.layout.BoxScope
24+ import androidx.compose.foundation.layout.BoxWithConstraints
2425import androidx.compose.foundation.layout.fillMaxSize
2526import androidx.compose.foundation.layout.fillMaxWidth
2627import androidx.compose.foundation.layout.height
2728import androidx.compose.foundation.layout.offset
2829import androidx.compose.foundation.layout.size
29- import androidx.compose.foundation.layout.width
3030import androidx.compose.foundation.progressSemantics
3131import androidx.compose.foundation.shape.CircleShape
3232import androidx.compose.runtime.Composable
3333import androidx.compose.runtime.getValue
34- import androidx.compose.runtime.mutableFloatStateOf
3534import androidx.compose.runtime.mutableStateOf
3635import androidx.compose.runtime.remember
3736import androidx.compose.runtime.rememberUpdatedState
@@ -41,9 +40,7 @@ import androidx.compose.ui.Modifier
4140import androidx.compose.ui.geometry.CornerRadius
4241import androidx.compose.ui.geometry.Offset
4342import androidx.compose.ui.geometry.Size
44- import androidx.compose.ui.graphics.Color
4543import androidx.compose.ui.graphics.graphicsLayer
46- import androidx.compose.ui.layout.onSizeChanged
4744import androidx.compose.ui.platform.LocalDensity
4845import androidx.compose.ui.platform.LocalLayoutDirection
4946import androidx.compose.ui.tooling.preview.Preview
@@ -60,7 +57,6 @@ import kotlin.random.Random
6057 *
6158 * @param modifier Modifier for styling.
6259 * @param waveformData The waveform data to display.
63- * @param style The style for the waveform slider.
6460 * @param visibleBarLimit The number of bars to display at once.
6561 * @param adjustBarWidthToLimit Whether to adjust the bar width to fit the visible bar limit.
6662 * @param progress The current progress of the waveform.
@@ -84,43 +80,45 @@ public fun StaticWaveformSlider(
8480) {
8581 val isRtl = LocalLayoutDirection .current == LayoutDirection .Rtl
8682 val currentProgress by rememberUpdatedState(progress)
87- var widthPx by remember { mutableFloatStateOf(0f ) }
88- Box (
83+ BoxWithConstraints (
8984 modifier = modifier
9085 .fillMaxSize()
91- .progressSemantics(value = progress)
92- .onSizeChanged { size ->
93- widthPx = size.width.toFloat()
94- }
95- .dragPointerInput(
96- enabled = isThumbVisible,
97- onDragStart = {
98- onDragStart(it.toHorizontalProgress(widthPx, isRtl))
99- },
100- onDrag = {
101- onDrag(it.toHorizontalProgress(widthPx, isRtl))
102- },
103- onDragStop = {
104- onDragStop(it?.toHorizontalProgress(widthPx, isRtl) ? : currentProgress)
105- },
106- ),
86+ .progressSemantics(value = progress),
10787 ) {
108- // Draw the waveform
109- WaveformTrack (
110- modifier = Modifier .fillMaxSize(),
111- waveformData = waveformData,
112- visibleBarLimit = visibleBarLimit,
113- adjustBarWidthToLimit = adjustBarWidthToLimit,
114- progress = progress,
115- )
116-
117- // Draw the thumb
118- if (isThumbVisible) {
119- WaveformHandle (
120- isPlaying = isPlaying,
88+ val widthPx = constraints.maxWidth.toFloat()
89+ Box (
90+ modifier = Modifier
91+ .fillMaxSize()
92+ .dragPointerInput(
93+ enabled = isThumbVisible,
94+ onDragStart = {
95+ onDragStart(it.toHorizontalProgress(widthPx, isRtl))
96+ },
97+ onDrag = {
98+ onDrag(it.toHorizontalProgress(widthPx, isRtl))
99+ },
100+ onDragStop = {
101+ onDragStop(it?.toHorizontalProgress(widthPx, isRtl) ? : currentProgress)
102+ },
103+ ),
104+ ) {
105+ // Draw the waveform
106+ WaveformTrack (
107+ modifier = Modifier .fillMaxSize(),
108+ waveformData = waveformData,
109+ visibleBarLimit = visibleBarLimit,
110+ adjustBarWidthToLimit = adjustBarWidthToLimit,
121111 progress = progress,
122- parentWidthPx = widthPx,
123112 )
113+
114+ // Draw the thumb
115+ if (isThumbVisible) {
116+ WaveformHandle (
117+ isPlaying = isPlaying,
118+ progress = progress,
119+ parentWidthPx = widthPx,
120+ )
121+ }
124122 }
125123 }
126124}
@@ -175,10 +173,7 @@ internal fun WaveformTrack(
175173
176174 val totalBars = when (adjustBarWidthToLimit) {
177175 true -> visibleBarLimit
178- else -> when (waveformData.size > visibleBarLimit) {
179- true -> visibleBarLimit
180- else -> waveformData.size
181- }
176+ else -> minOf(waveformData.size, visibleBarLimit)
182177 }
183178 val visibleBars = minOf(visibleBarLimit, waveformData.size)
184179 var barCornerRadius by remember(totalBars) { mutableStateOf(CornerRadius .Zero ) }
@@ -193,7 +188,7 @@ internal fun WaveformTrack(
193188 val barWidth = barsWidth / totalBars
194189 val barSpacing = spaceWidth / totalSpaces
195190
196- val thresholdX = canvasW * finalProgress * visibleBars / visibleBarLimit
191+ val thresholdX = if (totalBars > 0 ) canvasW * finalProgress * visibleBars / totalBars else 0f
197192 val halfHeight = canvasH / 2
198193 if (barCornerRadius.x != barWidth || barCornerRadius.y != barWidth) {
199194 barCornerRadius = CornerRadius (barWidth, barWidth)
@@ -227,60 +222,62 @@ internal fun WaveformTrack(
227222 }
228223}
229224
230- @Preview(showBackground = true )
225+ @Preview(showBackground = true , widthDp = 250 )
231226@Composable
232- internal fun WaveformSeekBarPreview () {
233- val rand = Random ( 50 )
234- val waveform = List ( 50 ) { rand.nextFloat() }
227+ private fun StaticWaveformSliderAtStartPreview () {
228+ ChatPreviewTheme { StaticWaveformSliderSample (progress = 0f , isPlaying = true ) }
229+ }
235230
236- ChatPreviewTheme {
237- Box (
238- modifier = Modifier
239- .width(250 .dp)
240- .height(60 .dp)
241- .background(Color .Cyan ),
242- contentAlignment = Alignment .Center ,
243- ) {
244- StaticWaveformSlider (
245- modifier = Modifier
246- .fillMaxWidth()
247- .height(36 .dp),
248- waveformData = waveform,
249- progress = 0.0f ,
250- isPlaying = true ,
251- )
252- }
253- }
231+ @Preview(showBackground = true , widthDp = 250 )
232+ @Composable
233+ private fun StaticWaveformSliderMidwayPreview () {
234+ ChatPreviewTheme { StaticWaveformSliderSample (progress = 0.5f , isPlaying = true ) }
235+ }
236+
237+ @Preview(showBackground = true , widthDp = 250 )
238+ @Composable
239+ private fun StaticWaveformSliderPausedPreview () {
240+ ChatPreviewTheme { StaticWaveformSliderSample (progress = 0.3f , isPlaying = false ) }
241+ }
242+
243+ @Preview(showBackground = true , widthDp = 250 )
244+ @Composable
245+ private fun StaticWaveformSliderWithoutThumbPreview () {
246+ ChatPreviewTheme { StaticWaveformSliderSample (progress = 0.7f , isPlaying = true , isThumbVisible = false ) }
254247}
255248
256- @Preview(showBackground = true )
257249@Composable
258- internal fun WaveformTrackPreview () {
259- val waveform = mutableListOf<Float >()
260- val barCount = 100
261- for (i in 0 until barCount) {
262- waveform.add((i + 1 ) / barCount.toFloat())
250+ private fun StaticWaveformSliderSample (progress : Float , isPlaying : Boolean , isThumbVisible : Boolean = true) {
251+ val previewWaveform = remember {
252+ val rand = Random (50 )
253+ List (50 ) { rand.nextFloat() }
263254 }
264255
256+ StaticWaveformSlider (
257+ modifier = Modifier
258+ .fillMaxWidth()
259+ .height(36 .dp),
260+ waveformData = previewWaveform,
261+ progress = progress,
262+ isPlaying = isPlaying,
263+ isThumbVisible = isThumbVisible,
264+ )
265+ }
266+
267+ @Preview(showBackground = true , widthDp = 250 )
268+ @Composable
269+ private fun FullWaveformTrackPreview () {
265270 ChatPreviewTheme {
266- Box (
271+ val waveform = List (100 ) { (it + 1 ) / 100f }
272+ WaveformTrack (
267273 modifier = Modifier
268- .width(250 .dp)
269- .height(80 .dp)
270- .background(Color .Black ),
271- contentAlignment = Alignment .Center ,
272- ) {
273- WaveformTrack (
274- modifier = Modifier
275- .background(Color .Red )
276- .fillMaxWidth()
277- .height(60 .dp),
278- waveformData = waveform,
279- progress = 0f ,
280- adjustBarWidthToLimit = true ,
281- visibleBarLimit = 100 ,
282- )
283- }
274+ .fillMaxWidth()
275+ .height(60 .dp),
276+ waveformData = waveform,
277+ progress = 1f ,
278+ adjustBarWidthToLimit = true ,
279+ visibleBarLimit = 100 ,
280+ )
284281 }
285282}
286283
0 commit comments