88package com.nextcloud.talk.ui.chat
99
1010import android.text.format.DateUtils
11- import android.widget.SeekBar
1211import androidx.compose.foundation.layout.Column
1312import androidx.compose.foundation.layout.Row
1413import androidx.compose.foundation.layout.fillMaxWidth
@@ -19,26 +18,32 @@ import androidx.compose.material.icons.Icons
1918import androidx.compose.material.icons.filled.Pause
2019import androidx.compose.material.icons.filled.PlayArrow
2120import androidx.compose.material3.CircularProgressIndicator
21+ import androidx.compose.material3.ExperimentalMaterial3Api
2222import androidx.compose.material3.Icon
2323import androidx.compose.material3.IconButton
2424import androidx.compose.material3.MaterialTheme.colorScheme
2525import androidx.compose.material3.Text
2626import androidx.compose.material3.TextButton
2727import androidx.compose.runtime.Composable
28+ import androidx.compose.runtime.getValue
29+ import androidx.compose.runtime.mutableFloatStateOf
2830import androidx.compose.runtime.remember
31+ import androidx.compose.runtime.setValue
2932import androidx.compose.ui.Alignment
3033import androidx.compose.ui.Modifier
3134import androidx.compose.ui.graphics.toArgb
3235import androidx.compose.ui.res.stringResource
3336import androidx.compose.ui.unit.dp
34- import androidx.compose.ui.viewinterop.AndroidView
3537import com.nextcloud.talk.R
3638import com.nextcloud.talk.chat.ui.model.ChatMessageUi
3739import com.nextcloud.talk.chat.ui.model.MessageTypeContent
38- import com.nextcloud.talk.ui.WaveformSeekBar
40+ import com.nextcloud.talk.ui.ComposeWaveformSeekBar
41+ import com.nextcloud.talk.ui.WAVEFORM_SIZE
42+ import com.nextcloud.talk.utils.AudioUtils
3943
4044private const val SEEKBAR_MAX = 100
4145
46+ @OptIn(ExperimentalMaterial3Api ::class )
4247@Suppress(" Detekt.LongMethod" , " LongParameterList" )
4348@Composable
4449fun VoiceMessage (
@@ -57,12 +62,14 @@ fun VoiceMessage(
5762 forceTimeBelow = true ,
5863 content = {
5964 val inversePrimaryColor = colorScheme.inversePrimary
60- val inversePrimary = remember(inversePrimaryColor) { inversePrimaryColor.toArgb() }
65+ remember(inversePrimaryColor) { inversePrimaryColor.toArgb() }
6166 val onPrimaryContainerColor = colorScheme.onPrimaryContainer
62- val onPrimaryContainer = remember(onPrimaryContainerColor) { onPrimaryContainerColor.toArgb() }
67+ remember(onPrimaryContainerColor) { onPrimaryContainerColor.toArgb() }
6368 val remainingSeconds = (typeContent.durationSeconds - typeContent.playedSeconds).coerceAtLeast(0 )
64- val waveformData = remember(typeContent.waveform) { typeContent.waveform.toFloatArray() }
65- val lastWaveformData = remember { mutableListOf<Float >() }
69+ val waveformData = remember(typeContent.waveform) {
70+ val floatArr = typeContent.waveform.toFloatArray()
71+ AudioUtils .shrinkFloatArray(floatArr, WAVEFORM_SIZE )
72+ }
6673
6774 Column {
6875 Row (
@@ -84,49 +91,21 @@ fun VoiceMessage(
8491 }
8592 }
8693
87- AndroidView (
88- factory = { ctx ->
89- WaveformSeekBar (ctx).apply {
90- max = SEEKBAR_MAX
91- setWaveData(waveformData)
92- setColors(
93- inversePrimary,
94- onPrimaryContainer
95- )
96- setOnSeekBarChangeListener(object : SeekBar .OnSeekBarChangeListener {
97- override fun onProgressChanged (
98- seekBar : SeekBar ? ,
99- progress : Int ,
100- fromUser : Boolean
101- ) {
102- if (fromUser) {
103- onSeek(message.id, progress)
104- }
105- }
106-
107- override fun onStartTrackingTouch (seekBar : SeekBar ? ) = Unit
94+ var sliderValue by remember { mutableFloatStateOf(0f ) }
95+ sliderValue = typeContent.seekbarProgress * 1f / SEEKBAR_MAX
10896
109- override fun onStopTrackingTouch (seekBar : SeekBar ? ) = Unit
110- })
111- }
112- },
113- update = { seekBar ->
114- seekBar.max = SEEKBAR_MAX
115- val waveformChanged = typeContent.waveform != lastWaveformData
116- if (waveformChanged) {
117- lastWaveformData.clear()
118- lastWaveformData.addAll(typeContent.waveform)
119- seekBar.setWaveData(waveformData)
120- seekBar.requestLayout()
121- }
122- seekBar.setColors(inversePrimary, onPrimaryContainer)
123- seekBar.progress = typeContent.seekbarProgress
124- seekBar.isEnabled = ! typeContent.isDownloading
125- seekBar.invalidate()
97+ ComposeWaveformSeekBar (
98+ sliderValue,
99+ {
100+ val progressI = (it * SEEKBAR_MAX ).toInt()
101+ onSeek(message.id, progressI)
102+ sliderValue = it
126103 },
127104 modifier = Modifier
128- .weight(1f )
129105 .height(56 .dp)
106+ .fillMaxWidth()
107+ .padding(8 .dp), // or weight(1f),
108+ waveformData
130109 )
131110
132111 TextButton (
0 commit comments