mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-09 15:42:10 +00:00
Follow up fixes
- Larger Bar gap - Centered time below play/pause button - Time is the same color as the play/pause button Signed-off-by: Julius Linus <julius.linus@nextcloud.com>
This commit is contained in:
parent
a3650d9888
commit
1af04d2bd3
@ -894,12 +894,7 @@ class ChatActivity :
|
|||||||
message.isDownloadingVoiceMessage = true
|
message.isDownloadingVoiceMessage = true
|
||||||
adapter?.update(message)
|
adapter?.update(message)
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
val bars = if (message.actorDisplayName == conversationUser?.displayName) {
|
val r = AudioUtils.audioFileToFloatArray(file)
|
||||||
NUM_BARS_OUTCOMING
|
|
||||||
} else {
|
|
||||||
NUM_BARS_INCOMING
|
|
||||||
}
|
|
||||||
val r = AudioUtils.audioFileToFloatArray(file, bars)
|
|
||||||
message.voiceMessageFloatArray = r
|
message.voiceMessageFloatArray = r
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
startPlayback(message)
|
startPlayback(message)
|
||||||
@ -4275,7 +4270,5 @@ class ChatActivity :
|
|||||||
private const val TYPING_INTERVAL_TO_SEND_NEXT_TYPING_MESSAGE = 1000L
|
private const val TYPING_INTERVAL_TO_SEND_NEXT_TYPING_MESSAGE = 1000L
|
||||||
private const val TYPING_STARTED_SIGNALING_MESSAGE_TYPE = "startedTyping"
|
private const val TYPING_STARTED_SIGNALING_MESSAGE_TYPE = "startedTyping"
|
||||||
private const val TYPING_STOPPED_SIGNALING_MESSAGE_TYPE = "stoppedTyping"
|
private const val TYPING_STOPPED_SIGNALING_MESSAGE_TYPE = "stoppedTyping"
|
||||||
private const val NUM_BARS_OUTCOMING: Int = 38
|
|
||||||
private const val NUM_BARS_INCOMING: Int = 50
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import android.graphics.Paint
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.widget.AppCompatSeekBar
|
import androidx.appcompat.widget.AppCompatSeekBar
|
||||||
|
import com.nextcloud.talk.utils.AudioUtils
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class WaveformSeekBar : AppCompatSeekBar {
|
class WaveformSeekBar : AppCompatSeekBar {
|
||||||
@ -58,9 +59,20 @@ class WaveformSeekBar : AppCompatSeekBar {
|
|||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the wave data of the seekbar. Shrinks the data to a calculated number of bars based off the width of the
|
||||||
|
* seekBar. The greater the width, the more bars displayed.
|
||||||
|
*
|
||||||
|
* Note: bar gap = (usableWidth - waveData.size * DEFAULT_BAR_WIDTH) / (waveData.size - 1).toFloat()
|
||||||
|
* therefore, the gap is determined by the width of the seekBar by extension.
|
||||||
|
*/
|
||||||
fun setWaveData(data: FloatArray) {
|
fun setWaveData(data: FloatArray) {
|
||||||
waveData = data
|
val usableWidth = width - paddingLeft - paddingRight
|
||||||
invalidate()
|
if (usableWidth > 0) {
|
||||||
|
val numBars = if (usableWidth > VALUE_100) (usableWidth / WIDTH_DIVISOR) else usableWidth / 2f
|
||||||
|
waveData = AudioUtils.shrinkFloatArray(data, numBars.roundToInt())
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun init() {
|
private fun init() {
|
||||||
@ -109,6 +121,8 @@ class WaveformSeekBar : AppCompatSeekBar {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val DEFAULT_BAR_WIDTH: Int = 2
|
private const val DEFAULT_BAR_WIDTH: Int = 2
|
||||||
private const val MAX_HEIGHT_DIVISOR: Float = 4.0f
|
private const val MAX_HEIGHT_DIVISOR: Float = 4.0f
|
||||||
|
private const val WIDTH_DIVISOR = 20f
|
||||||
|
private const val VALUE_100 = 100
|
||||||
private val Int.dp: Int
|
private val Int.dp: Int
|
||||||
get() = (this * Resources.getSystem().displayMetrics.density).roundToInt()
|
get() = (this * Resources.getSystem().displayMetrics.density).roundToInt()
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,14 @@ object AudioUtils {
|
|||||||
private val TAG = AudioUtils::class.java.simpleName
|
private val TAG = AudioUtils::class.java.simpleName
|
||||||
private const val VALUE_10 = 10
|
private const val VALUE_10 = 10
|
||||||
private const val TIME_LIMIT = 5000
|
private const val TIME_LIMIT = 5000
|
||||||
|
private const val DEFAULT_SIZE = 500
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspension function, returns a FloatArray containing the values of an audio file squeezed between [0,1)
|
* Suspension function, returns a FloatArray of size 500, containing the values of an audio file squeezed between
|
||||||
|
* [0,1)
|
||||||
*/
|
*/
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
suspend fun audioFileToFloatArray(file: File, size: Int): FloatArray {
|
suspend fun audioFileToFloatArray(file: File): FloatArray {
|
||||||
return suspendCoroutine {
|
return suspendCoroutine {
|
||||||
val startTime = SystemClock.elapsedRealtime()
|
val startTime = SystemClock.elapsedRealtime()
|
||||||
var result = mutableListOf<Float>()
|
var result = mutableListOf<Float>()
|
||||||
@ -142,22 +144,18 @@ object AudioUtils {
|
|||||||
while (result.size <= 0) {
|
while (result.size <= 0) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
it.resume(shrinkFloatArray(result.toFloatArray(), size))
|
it.resume(shrinkFloatArray(result.toFloatArray(), DEFAULT_SIZE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shrinkFloatArray(data: FloatArray, size: Int): FloatArray {
|
fun shrinkFloatArray(data: FloatArray, size: Int): FloatArray {
|
||||||
val result = FloatArray(size)
|
val result = FloatArray(size)
|
||||||
val scale = data.size / size
|
val scale = data.size / size
|
||||||
var begin = 0
|
var begin = 0
|
||||||
var end = scale
|
var end = scale
|
||||||
for (i in 0 until size) {
|
for (i in 0 until size) {
|
||||||
val arr = data.copyOfRange(begin, end)
|
val arr = data.copyOfRange(begin, end)
|
||||||
var sum = 0f
|
result[i] = arr.average().toFloat()
|
||||||
for (j in arr.indices) {
|
|
||||||
sum += arr[j]
|
|
||||||
}
|
|
||||||
result[i] = (sum / arr.size)
|
|
||||||
begin += scale
|
begin += scale
|
||||||
end += scale
|
end += scale
|
||||||
}
|
}
|
||||||
|
@ -113,10 +113,11 @@
|
|||||||
android:id="@+id/voiceMessageDuration"
|
android:id="@+id/voiceMessageDuration"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/standard_margin"
|
android:layout_marginStart="@dimen/standard_half_margin"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
|
android:textColor="@color/high_emphasis_text"
|
||||||
tools:text="02:30"
|
tools:text="02:30"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
@ -97,10 +97,11 @@
|
|||||||
android:id="@+id/voiceMessageDuration"
|
android:id="@+id/voiceMessageDuration"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/standard_margin"
|
android:layout_marginStart="@dimen/standard_half_margin"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
|
android:textColor="@color/high_emphasis_text"
|
||||||
tools:text="02:30"
|
tools:text="02:30"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user