-
-
Notifications
You must be signed in to change notification settings - Fork 247
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
playback speed control button for voice messages
Signed-off-by: Christian Reiner <[email protected]>
- Loading branch information
Showing
13 changed files
with
212 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
* Nextcloud Talk - Android Client | ||
* | ||
* SPDX-FileCopyrightText: 2024 Christian Reiner <[email protected]> | ||
* SPDX-FileCopyrightText: 2021 Andy Scherzinger <[email protected]> | ||
* SPDX-FileCopyrightText: 2021 Tim Krüger <[email protected]> | ||
* SPDX-FileCopyrightText: 2021 Marcel Hibbe <[email protected]> | ||
|
@@ -27,9 +28,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA | |
import com.nextcloud.talk.chat.ChatActivity | ||
import com.nextcloud.talk.chat.data.model.ChatMessage | ||
import com.nextcloud.talk.databinding.ItemCustomIncomingVoiceMessageBinding | ||
import com.nextcloud.talk.extensions.loadBotsAvatar | ||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar | ||
import com.nextcloud.talk.extensions.loadFederatedUserAvatar | ||
import com.nextcloud.talk.ui.theme.ViewThemeUtils | ||
import com.nextcloud.talk.utils.ApiUtils | ||
import com.nextcloud.talk.utils.ChatMessageUtils | ||
|
@@ -162,6 +160,10 @@ class IncomingVoiceMessageViewHolder(incomingView: View, payload: Any) : | |
} | ||
}) | ||
|
||
voiceMessageInterface.registerMessageToObservePlaybackSpeedPreferences(message.user.id) { speed -> | ||
binding.playbackSpeedControlBtn.setSpeed(speed) | ||
} | ||
|
||
Reaction().showReactions( | ||
message, | ||
::clickOnReaction, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
app/src/main/java/com/nextcloud/talk/adapters/messages/VoiceMessageInterface.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
/* | ||
* Nextcloud Talk - Android Client | ||
* | ||
* SPDX-FileCopyrightText: 2024 Christian Reiner <[email protected]> | ||
* SPDX-FileCopyrightText: 2021 Marcel Hibbe <[email protected]> | ||
* SPDX-License-Identifier: GPL-3.0-or-later | ||
*/ | ||
package com.nextcloud.talk.adapters.messages | ||
|
||
import com.nextcloud.talk.chat.data.model.ChatMessage | ||
import com.nextcloud.talk.ui.PlaybackSpeed | ||
|
||
interface VoiceMessageInterface { | ||
fun updateMediaPlayerProgressBySlider(message: ChatMessage, progress: Int) | ||
fun registerMessageToObservePlaybackSpeedPreferences(userId: String, listener: (speed: PlaybackSpeed) -> Unit) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
* Nextcloud Talk - Android Client | ||
* | ||
* SPDX-FileCopyrightText: 2024 Christian Reiner <[email protected]> | ||
* SPDX-FileCopyrightText: 2024 Parneet Singh <[email protected]> | ||
* SPDX-FileCopyrightText: 2024 Giacomo Pacini <[email protected]> | ||
* SPDX-FileCopyrightText: 2023 Ezhil Shanmugham <[email protected]> | ||
|
@@ -136,6 +137,8 @@ import com.nextcloud.talk.shareditems.activities.SharedItemsActivity | |
import com.nextcloud.talk.signaling.SignalingMessageReceiver | ||
import com.nextcloud.talk.signaling.SignalingMessageSender | ||
import com.nextcloud.talk.translate.ui.TranslateActivity | ||
import com.nextcloud.talk.ui.PlaybackSpeed | ||
import com.nextcloud.talk.ui.PlaybackSpeedControl | ||
import com.nextcloud.talk.ui.StatusDrawable | ||
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet | ||
import com.nextcloud.talk.ui.dialog.DateTimePickerFragment | ||
|
@@ -205,6 +208,7 @@ import java.util.Date | |
import java.util.Locale | ||
import java.util.concurrent.ExecutionException | ||
import javax.inject.Inject | ||
import kotlin.String | ||
import kotlin.collections.set | ||
import kotlin.math.roundToInt | ||
|
||
|
@@ -357,6 +361,19 @@ class ChatActivity : | |
private var voiceMessageToRestoreAudioPosition = 0 | ||
private var voiceMessageToRestoreWasPlaying = false | ||
|
||
private val playbackSpeedPreferencesObserver: (Map<String, PlaybackSpeed>) -> Unit = { speedPreferenceLiveData -> | ||
mediaPlayer?.let { mediaPlayer -> | ||
(mediaPlayer.isPlaying == true).also { | ||
currentlyPlayedVoiceMessage?.let { message -> | ||
mediaPlayer.playbackParams.let { params -> | ||
params.setSpeed(chatViewModel.getPlaybackSpeedPreference(message).value) | ||
mediaPlayer.playbackParams = params | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private val localParticipantMessageListener = object : SignalingMessageReceiver.LocalParticipantMessageListener { | ||
override fun onSwitchTo(token: String?) { | ||
if (token != null) { | ||
|
@@ -434,6 +451,10 @@ class ChatActivity : | |
|
||
onBackPressedDispatcher.addCallback(this, onBackPressedCallback) | ||
|
||
appPreferences.readVoiceMessagePlaybackSpeedPreferences().let { playbackSpeedPreferences -> | ||
chatViewModel.applyPlaybackSpeedPreferences(playbackSpeedPreferences) | ||
} | ||
|
||
initObservers() | ||
|
||
if (savedInstanceState != null) { | ||
|
@@ -1045,6 +1066,8 @@ class ChatActivity : | |
|
||
setupSwipeToReply() | ||
|
||
chatViewModel.voiceMessagePlaybackSpeedPreferences.observe(this, playbackSpeedPreferencesObserver) | ||
|
||
binding.unreadMessagesPopup.setOnClickListener { | ||
binding.messagesListView.smoothScrollToPosition(0) | ||
binding.unreadMessagesPopup.visibility = View.GONE | ||
|
@@ -1131,6 +1154,7 @@ class ChatActivity : | |
adapter?.setLoadMoreListener(this) | ||
adapter?.setDateHeadersFormatter { format(it) } | ||
adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } | ||
|
||
adapter?.registerViewClickListener( | ||
R.id.playPauseBtn | ||
) { _, message -> | ||
|
@@ -1154,6 +1178,15 @@ class ChatActivity : | |
} | ||
} | ||
} | ||
|
||
adapter?.registerViewClickListener(R.id.playbackSpeedControlBtn) { button, message -> | ||
val nextSpeed = (button as PlaybackSpeedControl).getSpeed().next() | ||
HashMap(appPreferences.readVoiceMessagePlaybackSpeedPreferences()).let { playbackSpeedPreferences -> | ||
playbackSpeedPreferences[message.user.id] = nextSpeed | ||
chatViewModel.applyPlaybackSpeedPreferences(playbackSpeedPreferences) | ||
appPreferences.saveVoiceMessagePlaybackSpeedPreferences(playbackSpeedPreferences) | ||
} | ||
} | ||
} | ||
|
||
private fun setUpWaveform(message: ChatMessage, thenPlay: Boolean = true) { | ||
|
@@ -1579,6 +1612,9 @@ class ChatActivity : | |
mediaPlayer?.let { | ||
if (!it.isPlaying && doPlay) { | ||
chatViewModel.audioRequest(true) { | ||
it.playbackParams = it.playbackParams.apply { | ||
setSpeed(chatViewModel.getPlaybackSpeedPreference(message).value) | ||
} | ||
it.start() | ||
} | ||
} | ||
|
@@ -1703,6 +1739,20 @@ class ChatActivity : | |
} | ||
} | ||
|
||
override fun registerMessageToObservePlaybackSpeedPreferences( | ||
userId: String, | ||
listener: (speed: PlaybackSpeed) -> Unit | ||
) { | ||
chatViewModel.voiceMessagePlaybackSpeedPreferences.let { liveData -> | ||
liveData.observe(this) { playbackSpeedPreferences -> | ||
listener(playbackSpeedPreferences[userId] ?: PlaybackSpeed.NORMAL) | ||
} | ||
liveData.value?.let { playbackSpeedPreferences -> | ||
listener(playbackSpeedPreferences[userId] ?: PlaybackSpeed.NORMAL) | ||
} | ||
} | ||
} | ||
|
||
@SuppressLint("NotifyDataSetChanged") | ||
override fun collapseSystemMessages() { | ||
adapter?.items?.forEach { | ||
|
@@ -2372,6 +2422,8 @@ class ChatActivity : | |
if (mentionAutocomplete != null && mentionAutocomplete!!.isPopupShowing) { | ||
mentionAutocomplete?.dismissPopup() | ||
} | ||
|
||
chatViewModel.voiceMessagePlaybackSpeedPreferences.removeObserver(playbackSpeedPreferencesObserver) | ||
} | ||
|
||
private fun isActivityNotChangingConfigurations(): Boolean = !isChangingConfigurations | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
* Nextcloud Talk - Android Client | ||
* | ||
* SPDX-FileCopyrightText: 2024 Christian Reiner <[email protected]> | ||
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <[email protected]> | ||
* SPDX-License-Identifier: GPL-3.0-or-later | ||
*/ | ||
|
@@ -33,6 +34,7 @@ import com.nextcloud.talk.models.json.conversations.RoomsOverall | |
import com.nextcloud.talk.models.json.generic.GenericOverall | ||
import com.nextcloud.talk.models.json.reminder.Reminder | ||
import com.nextcloud.talk.repositories.reactions.ReactionsRepository | ||
import com.nextcloud.talk.ui.PlaybackSpeed | ||
import com.nextcloud.talk.utils.ConversationUtils | ||
import com.nextcloud.talk.utils.bundle.BundleKeys | ||
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew | ||
|
@@ -107,6 +109,10 @@ class ChatViewModel @Inject constructor( | |
val getVoiceRecordingLocked: LiveData<Boolean> | ||
get() = _getVoiceRecordingLocked | ||
|
||
private val _voiceMessagePlaybackSpeeds: MutableLiveData<Map<String, PlaybackSpeed>> = MutableLiveData() | ||
val voiceMessagePlaybackSpeedPreferences: LiveData<Map<String, PlaybackSpeed>> | ||
get() = _voiceMessagePlaybackSpeeds | ||
|
||
val getMessageFlow = chatRepository.messageFlow | ||
.onEach { | ||
_chatMessageViewState.value = if (_chatMessageViewState.value == ChatMessageInitialState) { | ||
|
@@ -644,6 +650,13 @@ class ChatViewModel @Inject constructor( | |
emit(message.first()) | ||
} | ||
|
||
fun applyPlaybackSpeedPreferences(speeds: Map<String, PlaybackSpeed>) { | ||
_voiceMessagePlaybackSpeeds.postValue(speeds) | ||
} | ||
|
||
fun getPlaybackSpeedPreference(message: ChatMessage) = | ||
_voiceMessagePlaybackSpeeds.value?.get(message.user.id) ?: PlaybackSpeed.NORMAL | ||
|
||
// inner class GetRoomObserver : Observer<ConversationModel> { | ||
// override fun onSubscribe(d: Disposable) { | ||
// // unused atm | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
app/src/main/java/com/nextcloud/talk/ui/PlaybackSpeedControl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Nextcloud Talk - Android Client | ||
* | ||
* SPDX-FileCopyrightText: 2024 Christian Reiner <[email protected]> | ||
* SPDX-License-Identifier: GPL-3.0-or-later | ||
*/ | ||
|
||
package com.nextcloud.talk.ui | ||
|
||
import android.content.Context | ||
import android.util.AttributeSet | ||
import androidx.appcompat.app.AppCompatDelegate | ||
import com.google.android.material.button.MaterialButton | ||
import java.util.Locale | ||
|
||
internal const val SPEED_FACTOR_SLOW = 0.8f | ||
internal const val SPEED_FACTOR_NORMAL = 1.0f | ||
internal const val SPEED_FACTOR_FASTER = 1.5f | ||
internal const val SPEED_FACTOR_FASTEST = 2.0f | ||
|
||
class PlaybackSpeedControl @JvmOverloads constructor( | ||
context: Context, | ||
attrs: AttributeSet? = null, | ||
defStyleAttr: Int = 0 | ||
) : MaterialButton(context, attrs, defStyleAttr) { | ||
|
||
private var currentSpeed = PlaybackSpeed.NORMAL | ||
|
||
init { | ||
text = currentSpeed.label | ||
} | ||
|
||
fun setSpeed(newSpeed: PlaybackSpeed) { | ||
currentSpeed = newSpeed | ||
text = currentSpeed.label | ||
} | ||
|
||
fun getSpeed(): PlaybackSpeed { | ||
return currentSpeed | ||
} | ||
} | ||
|
||
enum class PlaybackSpeed(val value: Float) { | ||
SLOW(SPEED_FACTOR_SLOW), | ||
NORMAL(SPEED_FACTOR_NORMAL), | ||
FASTER(SPEED_FACTOR_FASTER), | ||
FASTEST(SPEED_FACTOR_FASTEST); | ||
|
||
// no fixed, literal labels, since we want to obey numeric interpunctuation for different locales | ||
val label: String = String.format(Locale.getDefault(), "%01.1fx", value) | ||
|
||
fun next(): PlaybackSpeed { | ||
return entries[(ordinal + 1) % entries.size] | ||
} | ||
|
||
companion object { | ||
fun byName(name: String): PlaybackSpeed { | ||
for (speed in entries) { | ||
if (speed.name.equals(name, ignoreCase = true)) { | ||
return speed | ||
} | ||
} | ||
return NORMAL | ||
} | ||
} | ||
} |
Oops, something went wrong.