From b7a8389bf679332832d965d7b24441f60ccfafc7 Mon Sep 17 00:00:00 2001 From: gavine99 Date: Mon, 27 Jan 2025 19:31:45 +1100 Subject: [PATCH 1/2] removed audio state maintenance from audiobinder on the compose screen into messagesadapter class. fixed other ui issues also related to state loss in audiobinder and re-use of viewholders --- .../com/moez/QKSMS/common/QkMediaPlayer.kt | 1 + .../common/util/extensions/ViewExtensions.kt | 23 +- .../QKSMS/feature/compose/MessagesAdapter.kt | 13 +- .../QKSMS/feature/compose/part/AudioBinder.kt | 262 +++++++++++------- .../feature/compose/part/PartsAdapter.kt | 23 +- .../res/drawable/audio_preview_foreground.png | Bin 54307 -> 53429 bytes .../layout/mms_audio_preview_list_item.xml | 2 +- 7 files changed, 211 insertions(+), 113 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/common/QkMediaPlayer.kt b/presentation/src/main/java/com/moez/QKSMS/common/QkMediaPlayer.kt index a28d98e6..623bd519 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/QkMediaPlayer.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/QkMediaPlayer.kt @@ -9,6 +9,7 @@ object QkMediaPlayer : MediaPlayer() { private var onCompletionListener: OnCompletionListener? = null enum class PlayingState { + None, Stopped, Playing, Paused diff --git a/presentation/src/main/java/com/moez/QKSMS/common/util/extensions/ViewExtensions.kt b/presentation/src/main/java/com/moez/QKSMS/common/util/extensions/ViewExtensions.kt index dbb98d11..526126a8 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/util/extensions/ViewExtensions.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/util/extensions/ViewExtensions.kt @@ -53,20 +53,29 @@ fun EditText.hideKeyboard() { imm.hideSoftInputFromWindow(windowToken, 0) } -fun ImageView.setTint(color: Int) { - imageTintList = ColorStateList.valueOf(color) +fun ImageView.setTint(color: Int?) { + imageTintList = + if (color == null) null + else ColorStateList.valueOf(color) } -fun ProgressBar.setTint(color: Int) { - indeterminateTintList = ColorStateList.valueOf(color) - progressTintList = ColorStateList.valueOf(color) +fun ProgressBar.setTint(color: Int?) { + indeterminateTintList = + if (color == null) null + else ColorStateList.valueOf(color) + progressTintList = + if (color == null) null + else ColorStateList.valueOf(color) + } -fun View.setBackgroundTint(color: Int) { +fun View.setBackgroundTint(color: Int?) { // API 21 doesn't support this - backgroundTintList = ColorStateList.valueOf(color) + backgroundTintList = + if (color == null) null + else ColorStateList.valueOf(color) } fun View.setPadding(left: Int? = null, top: Int? = null, right: Int? = null, bottom: Int? = null) { diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt index d8dd5061..7c9db537 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt @@ -32,6 +32,7 @@ import android.widget.ImageView import android.widget.ProgressBar import androidx.recyclerview.widget.RecyclerView import com.jakewharton.rxbinding2.view.clicks +import com.moez.QKSMS.common.QkMediaPlayer import dev.octoshrimpy.quik.R import dev.octoshrimpy.quik.common.base.QkRealmAdapter import dev.octoshrimpy.quik.common.base.QkViewHolder @@ -55,6 +56,7 @@ import dev.octoshrimpy.quik.model.Message import dev.octoshrimpy.quik.model.Recipient import dev.octoshrimpy.quik.util.PhoneNumberUtils import dev.octoshrimpy.quik.util.Preferences +import io.reactivex.disposables.Disposable import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.Subject import io.realm.RealmResults @@ -83,6 +85,13 @@ class MessagesAdapter @Inject constructor( private val textViewStyler: TextViewStyler ) : QkRealmAdapter() { + class AudioState( + var partId: Long = -1, + var state: QkMediaPlayer.PlayingState = QkMediaPlayer.PlayingState.Stopped, + var seekBarUpdater: Disposable? = null, + var viewHolder: QkViewHolder? = null + ) + companion object { private const val VIEW_TYPE_MESSAGE_IN = 0 private const val VIEW_TYPE_MESSAGE_OUT = 1 @@ -132,6 +141,8 @@ class MessagesAdapter @Inject constructor( var theme: Colors.Theme = colors.theme() + private val audioState = AudioState() + /** * If the viewType is negative, then the viewHolder has an attachment. We'll consider * this a unique viewType even though it uses the same view, so that regular messages @@ -283,7 +294,7 @@ class MessagesAdapter @Inject constructor( // Bind the attachments val partsAdapter = holder.attachments.adapter as PartsAdapter partsAdapter.theme = theme - partsAdapter.setData(message, previous, next, holder) + partsAdapter.setData(message, previous, next, holder, audioState) } private fun bindStatus(holder: QkViewHolder, message: Message, next: Message?) { diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt index c956deeb..0ab8ad63 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt @@ -33,16 +33,14 @@ import dev.octoshrimpy.quik.common.util.extensions.setBackgroundTint import dev.octoshrimpy.quik.common.util.extensions.setTint import dev.octoshrimpy.quik.common.widget.BubbleImageView import dev.octoshrimpy.quik.extensions.isAudio +import dev.octoshrimpy.quik.feature.compose.MessagesAdapter import dev.octoshrimpy.quik.model.Message import dev.octoshrimpy.quik.model.MmsPart import dev.octoshrimpy.quik.util.GlideApp import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import kotlinx.android.synthetic.main.mms_audio_preview_list_item.* -import kotlinx.android.synthetic.main.mms_audio_preview_list_item.view.playPause -import kotlinx.android.synthetic.main.mms_audio_preview_list_item.view.seekBar import kotlinx.android.synthetic.main.mms_image_preview_list_item.thumbnail import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -53,91 +51,130 @@ class AudioBinder @Inject constructor(colors: Colors, private val context: Conte override val partLayout = R.layout.mms_audio_preview_list_item override var theme = colors.theme() - private var thisPlayingState = QkMediaPlayer.PlayingState.Stopped override fun canBindPart(part: MmsPart) = part.isAudio() + var audioState = MessagesAdapter.AudioState(-1, QkMediaPlayer.PlayingState.Stopped) + + private fun startSeekBarUpdateTimer() { + audioState.apply { + seekBarUpdater?.dispose() + seekBarUpdater = Observable.interval(500, TimeUnit.MILLISECONDS) + .subscribeOn(Schedulers.single()) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext { + viewHolder?.seekBar?.progress = QkMediaPlayer.currentPosition + } + .subscribe() + } + } + + private fun uiToPlaying(viewHolder: QkViewHolder) { + viewHolder.seekBar.max = QkMediaPlayer.duration + viewHolder.seekBar.isEnabled = true + viewHolder.seekBar.progress = QkMediaPlayer.currentPosition + viewHolder.playPause.setImageResource(R.drawable.exo_icon_pause) + viewHolder.playPause.tag = QkMediaPlayer.PlayingState.Playing + viewHolder.metadataTitle.isSelected = true // start marquee + } + + private fun uiToPaused(viewHolder: QkViewHolder) { + viewHolder.playPause.setImageResource(R.drawable.exo_icon_play) + viewHolder.playPause.tag = QkMediaPlayer.PlayingState.Paused + } + + private fun uiToStopped(viewHolder: QkViewHolder) { + viewHolder.seekBar.progress = 0 + viewHolder.seekBar.max = 0 + viewHolder.seekBar.isEnabled = false + viewHolder.playPause.setImageResource(R.drawable.exo_icon_play) + viewHolder.playPause.tag = QkMediaPlayer.PlayingState.Stopped + viewHolder.metadataTitle.isSelected = false // stop marquee + } + override fun bindPart( holder: QkViewHolder, part: MmsPart, message: Message, canGroupWithPrevious: Boolean, - canGroupWithNext: Boolean + canGroupWithNext: Boolean, ) { // play/pause button click handling - holder.playPause.setOnClickListener { view -> - var seekBarUpdater: Disposable? = null + holder.playPause.setOnClickListener { + when (holder.playPause.tag) { + QkMediaPlayer.PlayingState.Playing -> { + if (audioState.partId == part.id) { + QkMediaPlayer.pause() + uiToPaused(holder) + audioState.state = QkMediaPlayer.PlayingState.Paused - when (thisPlayingState) { - QkMediaPlayer.PlayingState.Stopped -> { - QkMediaPlayer.apply { - reset() // make sure reset before trying to (re-)use - - setAudioAttributes( - AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) // music, maybe?? could be voice. don't want to use CONTENT_TYPE_UNKNOWN though - .setUsage(AudioAttributes.USAGE_MEDIA) - .build() - ) - - setDataSource(context, part.getUri()) - - setOnPreparedListener { - // start timer to update seek bar - seekBarUpdater = Observable.interval(500, TimeUnit.MILLISECONDS) - .subscribeOn(Schedulers.single()) - .observeOn(AndroidSchedulers.mainThread()) - .map { System.nanoTime() } - .doOnNext { holder.seekBar.progress = QkMediaPlayer.currentPosition } - .subscribe() - - // set seek bar max value - holder.seekBar.max = QkMediaPlayer.duration - - start() - - thisPlayingState = QkMediaPlayer.PlayingState.Playing - view.playPause.setImageResource(R.drawable.exo_icon_pause) - holder.containerView.seekBar.isEnabled = true - holder.metadataTitle.isSelected = true - } - - setOnCompletionListener { // also called on error because we don't have an onerrorlistener - seekBarUpdater?.dispose() // stop timer - - thisPlayingState = QkMediaPlayer.PlayingState.Stopped - holder.containerView.seekBar.seekBar.isEnabled = false - holder.containerView.seekBar.seekBar.progress = 0 - view.playPause.setImageResource(R.drawable.exo_icon_play) - holder.metadataTitle.isSelected = false - } - - // prepare to play - prepareAsync() + // stop progress bar update timer + audioState.seekBarUpdater?.dispose() } } - QkMediaPlayer.PlayingState.Playing -> { - QkMediaPlayer.pause() - view.playPause.setImageResource(R.drawable.exo_icon_play) - thisPlayingState = QkMediaPlayer.PlayingState.Paused - } QkMediaPlayer.PlayingState.Paused -> { - QkMediaPlayer.start() - view.playPause.setImageResource(R.drawable.exo_icon_pause) - thisPlayingState = QkMediaPlayer.PlayingState.Playing + if (audioState.partId == part.id) { + QkMediaPlayer.start() + uiToPlaying(holder) + audioState.state = QkMediaPlayer.PlayingState.Playing + + // start progress bar update timer + startSeekBarUpdateTimer() + } + } + else -> { + QkMediaPlayer.reset() // make sure reset before trying to (re-)use + + QkMediaPlayer.setOnPreparedListener { + // start media playing + QkMediaPlayer.start() + + uiToPlaying(holder) + + // set current view holder and part as active + audioState.apply { + audioState.state = QkMediaPlayer.PlayingState.Playing + partId = part.id + viewHolder = holder + } + + // start progress bar update timer + startSeekBarUpdateTimer() + } + + QkMediaPlayer.setOnCompletionListener { // also called on error because we don't have an onerrorlistener + audioState.apply { + // if this part is currently active, set it to stopped and inactive + if ((partId == part.id) && (viewHolder != null)) + uiToStopped(viewHolder!!) + + state = QkMediaPlayer.PlayingState.Stopped + partId = -1 + viewHolder = null + } + } + + // start the media player play sequence + QkMediaPlayer.setAudioAttributes( + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) // music, maybe?? could be voice. don't want to use CONTENT_TYPE_UNKNOWN though + .setUsage(AudioAttributes.USAGE_MEDIA) + .build() + ) + + QkMediaPlayer.setDataSource(context, part.getUri()) + + QkMediaPlayer.prepareAsync() } } } - holder.thumbnail.bubbleStyle = when { - !canGroupWithPrevious && canGroupWithNext -> - if (message.isMe()) BubbleImageView.Style.OUT_FIRST else BubbleImageView.Style.IN_FIRST - canGroupWithPrevious && canGroupWithNext -> - if (message.isMe()) BubbleImageView.Style.OUT_MIDDLE else BubbleImageView.Style.IN_MIDDLE - canGroupWithPrevious && !canGroupWithNext -> - if (message.isMe()) BubbleImageView.Style.OUT_LAST else BubbleImageView.Style.IN_LAST - else -> BubbleImageView.Style.ONLY - } + // if this item is the active active audio item update the active view holder + if (audioState.partId == part.id) + audioState.viewHolder = holder + // else, this is not the active item so ensure the stored view holder is not this one + else if (audioState.viewHolder == holder) + audioState.viewHolder = null // tint colours val secondaryColor = @@ -151,9 +188,6 @@ class AudioBinder @Inject constructor(colors: Colors, private val context: Conte else holder.containerView.context.resolveThemeColor(android.R.attr.textColorPrimary) - val metaDataRetriever = MediaMetadataRetriever() - metaDataRetriever.setDataSource(context, part.getUri()) - // sound wave holder.soundWave.setTint(primaryColor) @@ -161,11 +195,11 @@ class AudioBinder @Inject constructor(colors: Colors, private val context: Conte holder.seekBar.apply { setTint(secondaryColor) thumbTintList = ColorStateList.valueOf(secondaryColor) - max = 0 - isEnabled = false + setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(p0: SeekBar?, progress: Int, fromUser: Boolean) { - if ((thisPlayingState != QkMediaPlayer.PlayingState.Stopped) && fromUser) + // if seek was initiated by the user and this part is currently playing + if (fromUser) QkMediaPlayer.seekTo(progress) } override fun onStartTrackingTouch(p0: SeekBar?) { /* nothing */ } @@ -175,35 +209,65 @@ class AudioBinder @Inject constructor(colors: Colors, private val context: Conte // playPause button holder.playPause. apply { + if ((audioState.partId == part.id) && + (audioState.state == QkMediaPlayer.PlayingState.Playing)) + uiToPlaying(holder) + else if ((audioState.partId == part.id) && + (audioState.state == QkMediaPlayer.PlayingState.Paused)) + uiToPaused(holder) + else + uiToStopped(holder) + setTint(secondaryColor) setBackgroundTint(primaryColor) } - holder.metadataTitle.apply { - // metadata title - text = metaDataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) ?: "" + MediaMetadataRetriever().use { + it.setDataSource(context, part.getUri()) - if (text == "") - visibility = View.GONE - else { - setTextColor(primaryColor) - setBackgroundTint(0xccffffff.toInt() and secondaryColor) // hex value is alpha + // metadata title + holder.metadataTitle.apply { + text = it.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) + + if (text.isEmpty()) + visibility = View.GONE + else { + visibility = View.VISIBLE + setTextColor(primaryColor) + setBackgroundTint(0xccffffff.toInt() and secondaryColor) // hex value is alpha + } + } + + // bubble / embedded image + holder.thumbnail.apply { + bubbleStyle = when { + !canGroupWithPrevious && canGroupWithNext -> + if (message.isMe()) BubbleImageView.Style.OUT_FIRST else BubbleImageView.Style.IN_FIRST + canGroupWithPrevious && canGroupWithNext -> + if (message.isMe()) BubbleImageView.Style.OUT_MIDDLE else BubbleImageView.Style.IN_MIDDLE + canGroupWithPrevious && !canGroupWithNext -> + if (message.isMe()) BubbleImageView.Style.OUT_LAST else BubbleImageView.Style.IN_LAST + else -> BubbleImageView.Style.ONLY + } + + val embeddedPicture = it.embeddedPicture + if (embeddedPicture == null) { + holder.frame.layoutParams.height = (holder.frame.layoutParams.width / 2) + setTint(secondaryColor) + setImageResource(R.drawable.rectangle) + } else { + holder.frame.layoutParams.height = holder.frame.layoutParams.width + setTint(null) + GlideApp.with(context) + .asBitmap() + .load(embeddedPicture) + .override( + holder.frame.layoutParams.width, + holder.frame.layoutParams.height + ) + .into(this) + } } } - - // embedded image - val embeddedPicture = metaDataRetriever.embeddedPicture - if (embeddedPicture == null) { - holder.thumbnail.setTint(secondaryColor) - holder.frame.layoutParams.height /= 2 - holder.thumbnail.requestLayout() - } else { - GlideApp.with(context) - .asBitmap() - .load(embeddedPicture) - .into(holder.thumbnail) - } - - metaDataRetriever.close() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/PartsAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/PartsAdapter.kt index 68d26a1c..7449616c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/PartsAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/PartsAdapter.kt @@ -28,6 +28,7 @@ import dev.octoshrimpy.quik.common.util.extensions.forwardTouches import dev.octoshrimpy.quik.extensions.isSmil import dev.octoshrimpy.quik.extensions.isText import dev.octoshrimpy.quik.feature.compose.BubbleUtils.canGroup +import dev.octoshrimpy.quik.feature.compose.MessagesAdapter import dev.octoshrimpy.quik.model.Message import dev.octoshrimpy.quik.model.MmsPart import io.reactivex.Observable @@ -39,7 +40,7 @@ class PartsAdapter @Inject constructor( fileBinder: FileBinder, imageBinder: ImageBinder, audioBinder: AudioBinder, - vCardBinder: VCardBinder + vCardBinder: VCardBinder, ) : QkAdapter() { private val partBinders = listOf(audioBinder, imageBinder, vCardBinder, fileBinder) @@ -57,14 +58,22 @@ class PartsAdapter @Inject constructor( private var next: Message? = null private var holder: QkViewHolder? = null private var bodyVisible: Boolean = true + private var audioState: MessagesAdapter.AudioState? = null - fun setData(message: Message, previous: Message?, next: Message?, holder: QkViewHolder) { + fun setData( + message: Message, + previous: Message?, + next: Message?, + holder: QkViewHolder, + audioState: MessagesAdapter.AudioState? + ) { this.message = message this.previous = previous this.next = next this.holder = holder this.bodyVisible = holder.body.visibility == View.VISIBLE this.data = message.parts.filter { !it.isSmil() && !it.isText() } + this.audioState = audioState } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QkViewHolder { @@ -80,9 +89,13 @@ class PartsAdapter @Inject constructor( val canGroupWithPrevious = canGroup(message, previous) || position > 0 val canGroupWithNext = canGroup(message, next) || position < itemCount - 1 || bodyVisible - partBinders - .firstOrNull { it.canBindPart(part) } - ?.bindPart(holder, part, message, canGroupWithPrevious, canGroupWithNext) + val binder = partBinders.firstOrNull { it.canBindPart(part) } + + // if audioState is set and binder is audio type, set audioState into it + if ((audioState != null) && (binder is AudioBinder)) + binder.audioState = audioState!! + + binder?.bindPart(holder, part, message, canGroupWithPrevious, canGroupWithNext) } override fun getItemViewType(position: Int): Int { diff --git a/presentation/src/main/res/drawable/audio_preview_foreground.png b/presentation/src/main/res/drawable/audio_preview_foreground.png index bf87f59e47c86776bd99261e2ed3870398f0c361..21a7354815936d47c2d56d3b4334f2eedcdfd881 100644 GIT binary patch delta 24302 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%0ANfkTW` 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 From 580ad9d02da02acedd04568763eb61afc553048e Mon Sep 17 00:00:00 2001 From: gavine99 Date: Mon, 27 Jan 2025 20:35:33 +1100 Subject: [PATCH 2/2] added onclick listener to audiobinder. removed recycledviewpool from parts adapter because it was recycling too fast and messing with attachment/part selection --- .../main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt | 2 -- .../java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt index 7c9db537..9e92bb2d 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/MessagesAdapter.kt @@ -136,7 +136,6 @@ class MessagesAdapter @Inject constructor( private val contactCache = ContactCache() private val expanded = HashMap() - private val partsViewPool = RecyclerView.RecycledViewPool() private val subs = subscriptionManager.activeSubscriptionInfoList var theme: Colors.Theme = colors.theme() @@ -167,7 +166,6 @@ class MessagesAdapter @Inject constructor( val partsAdapter = partsAdapterProvider.get() partsAdapter.clicks.subscribe(partClicks) view.attachments.adapter = partsAdapter - view.attachments.setRecycledViewPool(partsViewPool) view.body.forwardTouches(view) return QkViewHolder(view).apply { diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt index 0ab8ad63..b253185c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/part/AudioBinder.kt @@ -169,6 +169,8 @@ class AudioBinder @Inject constructor(colors: Colors, private val context: Conte } } + holder.containerView.setOnClickListener { clicks.onNext(part.id) } + // if this item is the active active audio item update the active view holder if (audioState.partId == part.id) audioState.viewHolder = holder