Full voice message UI

pull/619/head
Niels Andriesse 3 years ago
parent ac718a425d
commit 6d9eb0a932

@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewOutlineProvider
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
@ -62,7 +63,7 @@ class VisibleMessageContentView : LinearLayout {
mainContainer.addView(bodyTextView) mainContainer.addView(bodyTextView)
} else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) {
val voiceMessageView = VoiceMessageView(context) val voiceMessageView = VoiceMessageView(context)
voiceMessageView.bind(message) voiceMessageView.bind(message, background)
mainContainer.addView(voiceMessageView) mainContainer.addView(voiceMessageView)
} else if (message is MmsMessageRecord && message.slideDeck.documentSlide != null) { } else if (message is MmsMessageRecord && message.slideDeck.documentSlide != null) {
val documentView = DocumentView(context) val documentView = DocumentView(context)

@ -1,14 +1,28 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewOutlineProvider
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.view_voice_message.view.* import kotlinx.android.synthetic.main.view_voice_message.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
class VoiceMessageView : LinearLayout { class VoiceMessageView : LinearLayout {
private val snHandler = Handler(Looper.getMainLooper())
private var runnable: Runnable? = null
private var mockIsPlaying = false
private var mockProgress = 0L
set(value) { field = value; handleProgressChanged() }
private var mockDuration = 12000L
// region Lifecycle // region Lifecycle
constructor(context: Context) : super(context) { initialize() } constructor(context: Context) : super(context) { initialize() }
@ -17,16 +31,54 @@ class VoiceMessageView : LinearLayout {
private fun initialize() { private fun initialize() {
LayoutInflater.from(context).inflate(R.layout.view_voice_message, this) LayoutInflater.from(context).inflate(R.layout.view_voice_message, this)
setOnClickListener { togglePlayBack() }
voiceMessageViewDurationTextView.text = String.format("%01d:%02d",
TimeUnit.MILLISECONDS.toMinutes(mockDuration),
TimeUnit.MILLISECONDS.toSeconds(mockDuration))
} }
// endregion // endregion
// region Updating // region Updating
fun bind(message: MessageRecord) { fun bind(message: MmsMessageRecord, background: Drawable) {
val audio = message.slideDeck.audioSlide!!
voiceMessageViewLoader.isVisible = audio.isPendingDownload
mainVoiceMessageViewContainer.background = background
mainVoiceMessageViewContainer.outlineProvider = ViewOutlineProvider.BACKGROUND
mainVoiceMessageViewContainer.clipToOutline = true
}
private fun handleProgressChanged() {
voiceMessageViewDurationTextView.text = String.format("%01d:%02d",
TimeUnit.MILLISECONDS.toMinutes(mockDuration - mockProgress),
TimeUnit.MILLISECONDS.toSeconds(mockDuration - mockProgress))
val layoutParams = progressView.layoutParams as RelativeLayout.LayoutParams
val fraction = mockProgress.toFloat() / mockDuration.toFloat()
layoutParams.width = (width.toFloat() * fraction).roundToInt()
progressView.layoutParams = layoutParams
} }
fun recycle() { fun recycle() {
// TODO: Implement // TODO: Implement
} }
// endregion // endregion
// region Interaction
private fun togglePlayBack() {
mockIsPlaying = !mockIsPlaying
val iconID = if (mockIsPlaying) R.drawable.exo_icon_pause else R.drawable.exo_icon_play
voiceMessagePlaybackImageView.setImageResource(iconID)
if (mockIsPlaying) {
updateProgress()
} else {
runnable?.let { snHandler.removeCallbacks(it) }
}
}
private fun updateProgress() {
mockProgress += 20L
val runnable = Runnable { updateProgress() }
this.runnable = runnable
snHandler.postDelayed(runnable, 20L)
}
// endregion
} }

@ -1,41 +1,70 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/mainVoiceMessageViewContainer"
android:layout_width="160dp" android:layout_width="160dp"
android:layout_height="36dp" android:layout_height="36dp">
android:orientation="horizontal"
android:padding="@dimen/small_spacing"
android:gravity="center">
<RelativeLayout <View
android:layout_width="20dp" android:id="@+id/progressView"
android:layout_height="20dp" android:layout_width="0dp"
android:background="@drawable/circle_tintable" android:layout_height="match_parent"
android:backgroundTint="@color/white"> android:layout_alignParentStart="true"
android:background="@color/black"
<ImageView android:alpha="0.2" />
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/exo_icon_play"
android:layout_centerInParent="true"
app:tint="@color/black" />
</RelativeLayout>
<View <View
android:layout_width="84dp" android:layout_width="84dp"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginStart="28dp"
android:layout_centerVertical="true"
android:background="@color/white" /> android:background="@color/white" />
<RelativeLayout
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentStart="true">
<RelativeLayout
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerInParent="true"
android:background="@drawable/circle_tintable"
android:backgroundTint="@color/white">
<ImageView
android:id="@+id/voiceMessagePlaybackImageView"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/exo_icon_play"
android:layout_centerInParent="true"
app:tint="@color/black" />
</RelativeLayout>
<ProgressBar
android:id="@+id/voiceMessageViewLoader"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:indeterminate="true"
android:indeterminateTint="@color/white" />
</RelativeLayout>
<TextView <TextView
android:id="@+id/voiceMessageViewDurationTextView"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="20dp" android:layout_height="20dp"
android:text="0:08" android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/small_spacing"
android:gravity="center" android:gravity="center"
android:text="0:08"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="@dimen/small_font_size" android:textSize="@dimen/small_font_size"
android:background="@drawable/view_voice_message_duration_text_view_background" android:background="@drawable/view_voice_message_duration_text_view_background"
android:backgroundTint="@color/white" /> android:backgroundTint="@color/white" />
</LinearLayout> </RelativeLayout>

@ -8,7 +8,7 @@
<item name="home_gradient_start">#00FFFFFF</item> <item name="home_gradient_start">#00FFFFFF</item>
<item name="home_gradient_end">#FFFFFFFF</item> <item name="home_gradient_end">#FFFFFFFF</item>
<item name="message_received_background_color">#F5F5F5</item> <item name="message_received_background_color">#F2F2F2</item>
<item name="message_sent_background_color">#00E076</item> <item name="message_sent_background_color">#00E076</item>
<item name="android:statusBarColor">@android:color/black</item> <item name="android:statusBarColor">@android:color/black</item>

Loading…
Cancel
Save