Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/7895.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Send voice message should not be allowed during a voice broadcast recording
2 changes: 2 additions & 0 deletions library/ui-strings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3097,6 +3097,8 @@
<string name="error_voice_message_unable_to_play">Cannot play this voice message</string>
<string name="error_voice_message_unable_to_record">Cannot record a voice message</string>
<string name="error_voice_message_cannot_reply_or_edit">Cannot reply or edit while voice message is active</string>
<string name="error_voice_message_broadcast_in_progress">Cannot start voice message</string>
<string name="error_voice_message_broadcast_in_progress_message">You can’t start a voice message as you are currently recording a live broadcast. Please end your live broadcast in order to start recording a voice message</string>
<string name="voice_message_reply_content">Voice Message (%1$s)</string>

<string name="a11y_audio_message_item">%1$s, %2$s, %3$s</string> <!-- filename, duration, file size -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class DefaultErrorFormatter @Inject constructor(
return when (throwable) {
is VoiceFailure.UnableToPlay -> stringProvider.getString(R.string.error_voice_message_unable_to_play)
is VoiceFailure.UnableToRecord -> stringProvider.getString(R.string.error_voice_message_unable_to_record)
is VoiceFailure.VoiceBroadcastInProgress -> stringProvider.getString(R.string.error_voice_message_broadcast_in_progress)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
is MessageComposerViewEvents.VoicePlaybackOrRecordingFailure -> {
if (it.throwable is VoiceFailure.UnableToRecord) {
onCannotRecord()
} else if (it.throwable is VoiceFailure.VoiceBroadcastInProgress) {
displayErrorVoiceBroadcastInProgress()
}
showErrorInSnackbar(it.throwable)
}
Expand Down Expand Up @@ -526,6 +528,14 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
messageComposerViewModel.handle(MessageComposerAction.OnVoiceRecordingUiStateChanged(VoiceMessageRecorderView.RecordingUiState.Idle))
}

private fun displayErrorVoiceBroadcastInProgress() {
MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.error_voice_message_broadcast_in_progress)
.setMessage(getString(R.string.error_voice_message_broadcast_in_progress_message))
.setPositiveButton(android.R.string.ok, null)
.show()
}

private fun handleJoinedToAnotherRoom(action: MessageComposerViewEvents.JoinRoomCommandSuccess) {
composer.setTextIfDifferent("")
lockSendButton = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package im.vector.app.features.home.room.detail.composer
import android.text.SpannableString
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.withState
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
Expand All @@ -28,6 +29,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.getVectorLastMessageContent
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.time.Clock
import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.extensions.toAnalyticsComposer
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
Expand All @@ -42,12 +44,19 @@ import im.vector.app.features.home.room.detail.toMessageType
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.voice.VoiceFailure
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
import im.vector.app.features.voicebroadcast.VoiceBroadcastHelper
import im.vector.app.features.voicebroadcast.model.VoiceBroadcast
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
import im.vector.app.features.voicebroadcast.usecase.GetVoiceBroadcastStateEventLiveUseCase
import im.vector.app.features.voicebroadcast.voiceBroadcastId
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session
Expand All @@ -74,6 +83,7 @@ import org.matrix.android.sdk.api.session.room.send.UserDraft
import org.matrix.android.sdk.api.session.room.timeline.getRelationContent
import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
import org.matrix.android.sdk.api.session.space.CreateSpaceParams
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.flow.unwrap
import timber.log.Timber
Expand All @@ -88,6 +98,8 @@ class MessageComposerViewModel @AssistedInject constructor(
private val audioMessageHelper: AudioMessageHelper,
private val analyticsTracker: AnalyticsTracker,
private val voiceBroadcastHelper: VoiceBroadcastHelper,
private val clock: Clock,
private val getVoiceBroadcastStateEventLiveUseCase: GetVoiceBroadcastStateEventLiveUseCase,
) : VectorViewModel<MessageComposerViewState, MessageComposerAction, MessageComposerViewEvents>(initialState) {

private val room = session.getRoom(initialState.roomId)
Expand Down Expand Up @@ -203,8 +215,11 @@ class MessageComposerViewModel @AssistedInject constructor(
private fun observeVoiceBroadcast(room: Room) {
room.stateService().getStateEventLive(VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO, QueryStringValue.Equals(session.myUserId))
.asFlow()
.unwrap()
.mapNotNull { it.asVoiceBroadcastEvent()?.content?.voiceBroadcastState }
.map { it.getOrNull()?.asVoiceBroadcastEvent()?.voiceBroadcastId }
.flatMapLatest { voiceBroadcastId ->
voiceBroadcastId?.let { getVoiceBroadcastStateEventLiveUseCase.execute(VoiceBroadcast(it, room.roomId)) } ?: flowOf(Optional.empty())
}
.map { it.getOrNull()?.content?.voiceBroadcastState }
.setOnEach {
copy(voiceBroadcastState = it)
}
Expand Down Expand Up @@ -916,10 +931,16 @@ class MessageComposerViewModel @AssistedInject constructor(
}

private fun handleStartRecordingVoiceMessage(room: Room) {
try {
audioMessageHelper.startRecording(room.roomId)
} catch (failure: Throwable) {
_viewEvents.post(MessageComposerViewEvents.VoicePlaybackOrRecordingFailure(failure))
val voiceBroadcastState = withState(this) { it.voiceBroadcastState }
if (voiceBroadcastState != null && voiceBroadcastState != VoiceBroadcastState.STOPPED) {
_viewEvents.post(MessageComposerViewEvents.VoicePlaybackOrRecordingFailure(VoiceFailure.VoiceBroadcastInProgress))
} else {
try {
audioMessageHelper.startRecording(room.roomId)
setState { copy(voiceRecordingUiState = VoiceMessageRecorderView.RecordingUiState.Recording(clock.epochMillis())) }
} catch (failure: Throwable) {
_viewEvents.post(MessageComposerViewEvents.VoicePlaybackOrRecordingFailure(failure))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ class VoiceRecorderFragment : VectorBaseFragment<FragmentVoiceRecorderBinding>()
if (checkPermissions(PERMISSIONS_FOR_VOICE_MESSAGE, requireActivity(), permissionVoiceMessageLauncher)) {
messageComposerViewModel.handle(MessageComposerAction.StartRecordingVoiceMessage)
vibrate(requireContext())
updateRecordingUiState(VoiceMessageRecorderView.RecordingUiState.Recording(clock.epochMillis()))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ package im.vector.app.features.voice
sealed class VoiceFailure(cause: Throwable? = null) : Throwable(cause = cause) {
data class UnableToPlay(val throwable: Throwable) : VoiceFailure(throwable)
data class UnableToRecord(val throwable: Throwable) : VoiceFailure(throwable)
object VoiceBroadcastInProgress : VoiceFailure()
}