From 066234a30a1e3c72a5bd47334c21126f37d6de6d Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Mon, 12 Oct 2020 17:36:58 +1100 Subject: [PATCH] Waveform seek bar loading animation. --- .../securesms/loki/views/MessageAudioView.kt | 32 ++++++++++++++++++- .../securesms/loki/views/WaveformSeekBar.kt | 2 ++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt b/src/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt index 4a750842cf..c1b00da652 100644 --- a/src/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt +++ b/src/org/thoughtcrime/securesms/loki/views/MessageAudioView.kt @@ -7,6 +7,7 @@ import android.graphics.PorterDuff import android.graphics.drawable.AnimatedVectorDrawable import android.media.MediaDataSource import android.os.Build +import android.os.Handler import android.util.AttributeSet import android.view.View import android.view.View.OnTouchListener @@ -57,11 +58,12 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener { private var downloadListener: SlideClickListener? = null private var audioSlidePlayer: AudioSlidePlayer? = null -// private var backwardsCounter = 0 /** Background coroutine scope that is available when the view is attached to a window. */ private var asyncCoroutineScope: CoroutineScope? = null + private val loadingAnimation: SeekBarLoadingAnimation + constructor(context: Context): this(context, null) constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) @@ -121,6 +123,9 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener { container.setBackgroundColor(typedArray.getColor(R.styleable.MessageAudioView_widgetBackground, Color.TRANSPARENT)) typedArray.recycle() } + + loadingAnimation = SeekBarLoadingAnimation(this, seekBar) + loadingAnimation.start() } override fun onAttachedToWindow() { @@ -312,6 +317,7 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener { android.util.Log.d(TAG, "RMS: ${rmsValues.joinToString()}") post { + loadingAnimation.stop() seekBar.sampleData = rmsValues if (totalDurationMs > 0) { @@ -332,6 +338,30 @@ class MessageAudioView: FrameLayout, AudioSlidePlayer.Listener { } } +private class SeekBarLoadingAnimation( + private val hostView: View, + private val seekBar: WaveformSeekBar): Runnable { + + companion object { + private const val UPDATE_PERIOD = 500L // In milliseconds. + private val random = Random() + } + + fun start() { + stop() + run() + } + + fun stop() { + hostView.removeCallbacks(this) + } + + override fun run() { + seekBar.sampleData = (0 until 64).map { random.nextFloat() * 0.5f }.toFloatArray() + hostView.postDelayed(this, UPDATE_PERIOD) + } +} + @RequiresApi(Build.VERSION_CODES.M) private class InputStreamMediaDataSource: MediaDataSource { diff --git a/src/org/thoughtcrime/securesms/loki/views/WaveformSeekBar.kt b/src/org/thoughtcrime/securesms/loki/views/WaveformSeekBar.kt index 470224bb68..411e1793b0 100644 --- a/src/org/thoughtcrime/securesms/loki/views/WaveformSeekBar.kt +++ b/src/org/thoughtcrime/securesms/loki/views/WaveformSeekBar.kt @@ -33,6 +33,7 @@ class WaveformSeekBar : View { } private val sampleDataHolder = SampleDataHolder(::invalidate) + /** An array if normalized to [0..1] values representing the audio signal. */ var sampleData: FloatArray? get() { return sampleDataHolder.getSamples() @@ -282,6 +283,7 @@ class WaveformSeekBar : View { fun setSamples(sampleData: FloatArray?) { sampleDataFrom = sampleDataTo sampleDataTo = sampleData + progress = 0f animation?.cancel() animation = ValueAnimator.ofFloat(0f, 1f).apply {