Use CountUpTimer

This commit is contained in:
Benoit Marty 2021-07-13 11:59:37 +02:00 committed by Benoit Marty
parent c69bc12637
commit 78e9a4ffe7
4 changed files with 43 additions and 38 deletions

View file

@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
class CountUpTimer(private val intervalInMs: Long) { class CountUpTimer(private val intervalInMs: Long = 1_000) {
private val elapsedTime: AtomicLong = AtomicLong() private val elapsedTime: AtomicLong = AtomicLong()
private val resumed: AtomicBoolean = AtomicBoolean(false) private val resumed: AtomicBoolean = AtomicBoolean(false)

View file

@ -627,13 +627,13 @@ class RoomDetailViewModel @AssistedInject constructor(
private fun handleEndRecordingVoiceMessage(isCancelled: Boolean) { private fun handleEndRecordingVoiceMessage(isCancelled: Boolean) {
if (isCancelled) { if (isCancelled) {
voiceMessageHelper.deleteRecording() voiceMessageHelper.deleteRecording()
return } else {
} voiceMessageHelper.stopRecording()?.let { audioType ->
voiceMessageHelper.stopRecording()?.let { audioType -> if (audioType.duration > 1000) {
if (audioType.duration > 1000) { room.sendMedia(audioType.toContentAttachmentData(), false, emptySet())
room.sendMedia(audioType.toContentAttachmentData(), false, emptySet()) } else {
} else { voiceMessageHelper.deleteRecording()
voiceMessageHelper.deleteRecording() }
} }
} }
} }

View file

@ -31,8 +31,6 @@ import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.FileOutputStream import java.io.FileOutputStream
import java.lang.IllegalStateException
import java.lang.RuntimeException
import java.util.Timer import java.util.Timer
import java.util.TimerTask import java.util.TimerTask
import java.util.UUID import java.util.UUID

View file

@ -25,13 +25,12 @@ import androidx.core.view.isVisible
import im.vector.app.BuildConfig import im.vector.app.BuildConfig
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.hardware.vibrate import im.vector.app.core.hardware.vibrate
import im.vector.app.core.utils.CountUpTimer
import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.databinding.ViewVoiceMessageRecorderBinding import im.vector.app.databinding.ViewVoiceMessageRecorderBinding
import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
import timber.log.Timber import timber.log.Timber
import java.util.Timer
import java.util.TimerTask
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.floor import kotlin.math.floor
@ -68,10 +67,8 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
private var lastX: Float = 0f private var lastX: Float = 0f
private var lastY: Float = 0f private var lastY: Float = 0f
private var recordingTime: Int = -1
private var amplitudeList = emptyList<Int>() private var amplitudeList = emptyList<Int>()
private val recordingTimer = Timer() private var recordingTimer: CountUpTimer? = null
private var recordingTimerTask: TimerTask? = null
private val dimensionConverter = DimensionConverter(context.resources) private val dimensionConverter = DimensionConverter(context.resources)
@ -80,6 +77,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
views = ViewVoiceMessageRecorderBinding.bind(this) views = ViewVoiceMessageRecorderBinding.bind(this)
initVoiceRecordingViews() initVoiceRecordingViews()
initListeners()
} }
fun initVoiceRecordingViews() { fun initVoiceRecordingViews() {
@ -88,7 +86,9 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
views.voiceMessageMicButton.isVisible = true views.voiceMessageMicButton.isVisible = true
views.voiceMessageSendButton.isVisible = false views.voiceMessageSendButton.isVisible = false
}
private fun initListeners() {
views.voiceMessageSendButton.setOnClickListener { views.voiceMessageSendButton.setOnClickListener {
stopRecordingTimer() stopRecordingTimer()
hideRecordingViews(animationDuration = 0) hideRecordingViews(animationDuration = 0)
@ -232,27 +232,34 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
} }
private fun startRecordingTimer() { private fun startRecordingTimer() {
recordingTimerTask = object : TimerTask() { recordingTimer?.stop()
override fun run() { recordingTimer = CountUpTimer().apply {
recordingTime++ tickListener = object : CountUpTimer.TickListener {
showRecordingTimer() override fun onTick(milliseconds: Long) {
showRecordingWaveform() onRecordingTimerTick(milliseconds)
val timeDiffToRecordingLimit = BuildConfig.VOICE_MESSAGE_DURATION_LIMIT_MS - recordingTime * 1000
if (timeDiffToRecordingLimit <= 0) {
views.voiceMessageRecordingLayout.post {
recordingState = RecordingState.PLAYBACK
showPlaybackViews()
stopRecordingTimer()
}
} else if (timeDiffToRecordingLimit in 10000..10999) {
views.voiceMessageRecordingLayout.post {
renderToast(context.getString(R.string.voice_message_n_seconds_warning_toast, floor(timeDiffToRecordingLimit / 1000f).toInt()))
vibrate(context)
}
} }
} }
resume()
}
onRecordingTimerTick(0L)
}
private fun onRecordingTimerTick(milliseconds: Long) {
renderRecordingTimer(milliseconds / 1_000)
renderRecordingWaveform()
val timeDiffToRecordingLimit = BuildConfig.VOICE_MESSAGE_DURATION_LIMIT_MS - milliseconds
if (timeDiffToRecordingLimit <= 0) {
views.voiceMessageRecordingLayout.post {
recordingState = RecordingState.PLAYBACK
showPlaybackViews()
stopRecordingTimer()
}
} else if (timeDiffToRecordingLimit in 10_000..10_999) {
views.voiceMessageRecordingLayout.post {
renderToast(context.getString(R.string.voice_message_n_seconds_warning_toast, floor(timeDiffToRecordingLimit / 1000f).toInt()))
vibrate(context)
}
} }
recordingTimer.scheduleAtFixedRate(recordingTimerTask, 0, 1000)
} }
private fun renderToast(message: String) { private fun renderToast(message: String) {
@ -266,8 +273,8 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
views.voiceMessageToast.isVisible = false views.voiceMessageToast.isVisible = false
} }
private fun showRecordingTimer() { private fun renderRecordingTimer(recordingTimeMillis: Long) {
val formattedTimerText = DateUtils.formatElapsedTime(recordingTime.toLong()) val formattedTimerText = DateUtils.formatElapsedTime(recordingTimeMillis)
if (recordingState == RecordingState.LOCKED) { if (recordingState == RecordingState.LOCKED) {
views.voicePlaybackTime.apply { views.voicePlaybackTime.apply {
post { post {
@ -281,7 +288,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
} }
} }
private fun showRecordingWaveform() { private fun renderRecordingWaveform() {
val audioRecordView = views.voicePlaybackWaveform val audioRecordView = views.voicePlaybackWaveform
audioRecordView.apply { audioRecordView.apply {
post { post {
@ -294,8 +301,8 @@ class VoiceMessageRecorderView @JvmOverloads constructor(
} }
private fun stopRecordingTimer() { private fun stopRecordingTimer() {
recordingTimerTask?.cancel() recordingTimer?.stop()
recordingTime = -1 recordingTimer = null
} }
private fun showRecordingViews() { private fun showRecordingViews() {