From f5835e1b547693a2406cec05cd205ad0284f819e Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 8 Jul 2021 09:25:43 +1000 Subject: [PATCH 1/2] WIP: auto play next voice message --- .../conversation/v2/ConversationActivityV2.kt | 23 ++++++++++++++++--- .../v2/messages/VisibleMessageContentView.kt | 1 + .../v2/messages/VoiceMessageView.kt | 8 +++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index cf36023b17..b9899c8a32 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -23,6 +23,8 @@ import android.widget.RelativeLayout import android.widget.Toast import androidx.annotation.DimenRes import androidx.appcompat.app.AlertDialog +import androidx.core.view.children +import androidx.core.view.get import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider @@ -40,6 +42,7 @@ import kotlinx.android.synthetic.main.view_conversation.view.* import kotlinx.android.synthetic.main.view_input_bar.view.* import kotlinx.android.synthetic.main.view_input_bar_recording.* import kotlinx.android.synthetic.main.view_input_bar_recording.view.* +import kotlinx.android.synthetic.main.view_visible_message.view.* import network.loki.messenger.R import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi @@ -84,8 +87,7 @@ import org.thoughtcrime.securesms.conversation.v2.input_bar.mentions.MentionCand import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCallback import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCallbackDelegate import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper -import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentViewDelegate -import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView +import org.thoughtcrime.securesms.conversation.v2.messages.* import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager @@ -124,7 +126,7 @@ import kotlin.math.* class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate, InputBarRecordingViewDelegate, AttachmentManager.AttachmentListener, ActivityDispatcher, ConversationActionModeCallbackDelegate, VisibleMessageContentViewDelegate, RecipientModifiedListener, - SearchBottomBar.EventListener { + SearchBottomBar.EventListener, VoiceMessageViewDelegate { private val screenWidth = Resources.getSystem().displayMetrics.widthPixels private var linkPreviewViewModel: LinkPreviewViewModel? = null private var threadID: Long = -1 @@ -844,6 +846,21 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe conversationRecyclerView.scrollToPosition(lastSeenItemPosition) } + override fun playNextAudioIfPossible(current: Int) { + if (current < conversationRecyclerView.childCount) { + val nextVisibleMessageView = conversationRecyclerView[current + 1] as? VisibleMessageView + nextVisibleMessageView?.let { visibleMessageView -> + visibleMessageView.messageContentView.mainContainer.children.forEach { child -> + val nextVoiceMessageView = child as? VoiceMessageView + nextVoiceMessageView?.let { voiceMessageView -> + voiceMessageView.togglePlayback() + return@forEach + } + } + } + } + } + override fun sendMessage() { if (thread.isContactRecipient && thread.isBlocked) { BlockedDialog(thread).show(supportFragmentManager, "Blocked Dialog") diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index 16721b1625..5c02cb45a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -103,6 +103,7 @@ class VisibleMessageContentView : LinearLayout { val voiceMessageView = VoiceMessageView(context) voiceMessageView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster) mainContainer.addView(voiceMessageView) + voiceMessageView.delegate = delegate // We have to use onContentClick (rather than a click listener directly on the voice // message view) so as to not interfere with all the other gestures. onContentClick = { voiceMessageView.togglePlayback() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt index b957b0a166..8cbd904c29 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt @@ -25,6 +25,8 @@ class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { private var duration = 0L private var player: AudioSlidePlayer? = null private var isPreparing = false + var delegate: VisibleMessageContentViewDelegate? = null + var index = 0 // region Lifecycle constructor(context: Context) : super(context) { initialize() } @@ -70,6 +72,7 @@ class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { if (progress == 1.0) { togglePlayback() handleProgressChanged(0.0) + delegate?.playNextAudioIfPossible(index) } else { handleProgressChanged(progress) } @@ -112,3 +115,8 @@ class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { } // endregion } + +interface VoiceMessageViewDelegate { + + fun playNextAudioIfPossible(current: Int) +} From a1e63c5f8ecec22b9c1e3a84fa431e3b82f4ce8a Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 8 Jul 2021 10:24:10 +1000 Subject: [PATCH 2/2] auto play next audio --- .../securesms/conversation/v2/ConversationActivityV2.kt | 4 ++-- .../securesms/conversation/v2/ConversationAdapter.kt | 1 + .../conversation/v2/messages/VisibleMessageContentView.kt | 5 ++++- .../securesms/conversation/v2/messages/VisibleMessageView.kt | 2 ++ .../securesms/conversation/v2/messages/VoiceMessageView.kt | 4 ++-- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 480c74d33e..7ca866cd76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -847,8 +847,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } override fun playNextAudioIfPossible(current: Int) { - if (current < conversationRecyclerView.childCount) { - val nextVisibleMessageView = conversationRecyclerView[current + 1] as? VisibleMessageView + if (current > 0) { + val nextVisibleMessageView = conversationRecyclerView[current - 1] as? VisibleMessageView nextVisibleMessageView?.let { visibleMessageView -> visibleMessageView.messageContentView.mainContainer.children.forEach { child -> val nextVoiceMessageView = child as? VoiceMessageView diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 4b413ef89f..a4a5f1ba28 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -72,6 +72,7 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr view.snIsSelected = isSelected view.messageTimestampTextView.isVisible = isSelected val position = viewHolder.adapterPosition + view.viewHolderIndex = position view.bind(message, getMessageBefore(position, cursor), getMessageAfter(position, cursor), glide, searchQuery) view.onPress = { event -> onItemPress(message, viewHolder.adapterPosition, view, event) } view.onSwipeToReply = { onItemSwipeToReply(message, viewHolder.adapterPosition) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index 3f98ba5f87..b8b3b9812e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -32,6 +32,7 @@ import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView import org.thoughtcrime.securesms.components.emoji.EmojiTextView +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.dialogs.OpenURLDialog import org.thoughtcrime.securesms.conversation.v2.utilities.ModalURLSpan import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans @@ -48,6 +49,7 @@ class VisibleMessageContentView : LinearLayout { var onContentClick: ((event: MotionEvent) -> Unit)? = null var onContentDoubleTap: (() -> Unit)? = null var delegate: VisibleMessageContentViewDelegate? = null + var viewHolderIndex: Int = -1 // region Lifecycle constructor(context: Context) : super(context) { initialize() } @@ -107,9 +109,10 @@ class VisibleMessageContentView : LinearLayout { } } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { val voiceMessageView = VoiceMessageView(context) + voiceMessageView.index = viewHolderIndex + voiceMessageView.delegate = context as? ConversationActivityV2 voiceMessageView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster) mainContainer.addView(voiceMessageView) - voiceMessageView.delegate = delegate // We have to use onContentClick (rather than a click listener directly on the voice // message view) so as to not interfere with all the other gestures. onContentClick = { voiceMessageView.togglePlayback() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index ad90bd5328..f938007ada 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -47,6 +47,7 @@ class VisibleMessageView : LinearLayout { private var longPressCallback: Runnable? = null private var onDownTimestamp = 0L private var onDoubleTap: (() -> Unit)? = null + var viewHolderIndex: Int = -1 var snIsSelected = false set(value) { field = value; handleIsSelectedChanged()} var onPress: ((event: MotionEvent) -> Unit)? = null @@ -151,6 +152,7 @@ class VisibleMessageView : LinearLayout { var maxWidth = screenWidth - startPadding - endPadding if (profilePictureContainer.visibility != View.GONE) { maxWidth -= profilePictureContainer.width } // Populate content view + messageContentView.viewHolderIndex = viewHolderIndex messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide, maxWidth, thread, searchQuery) messageContentView.delegate = contentViewDelegate onDoubleTap = { messageContentView.onContentDoubleTap?.invoke() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt index d48d0b4d64..7823cc59d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VoiceMessageView.kt @@ -32,8 +32,8 @@ class VoiceMessageView : LinearLayout, AudioSlidePlayer.Listener { private var duration = 0L private var player: AudioSlidePlayer? = null private var isPreparing = false - var delegate: VisibleMessageContentViewDelegate? = null - var index = 0 + var delegate: VoiceMessageViewDelegate? = null + var index = -1 // region Lifecycle constructor(context: Context) : super(context) { initialize() }