mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-08 08:08:45 +01:00
VoiceBroadcast - Show error dialog if user is not able to record a voice broadcast
This commit is contained in:
parent
838e11c167
commit
362696cfc8
@ -3085,6 +3085,10 @@
|
|||||||
<string name="a11y_play_voice_broadcast">Play or resume voice broadcast</string>
|
<string name="a11y_play_voice_broadcast">Play or resume voice broadcast</string>
|
||||||
<string name="a11y_pause_voice_broadcast">Pause voice broadcast</string>
|
<string name="a11y_pause_voice_broadcast">Pause voice broadcast</string>
|
||||||
<string name="a11y_voice_broadcast_buffering">Buffering</string>
|
<string name="a11y_voice_broadcast_buffering">Buffering</string>
|
||||||
|
<string name="error_voice_broadcast_unauthorized_title">Can’t start a new voice broadcast</string>
|
||||||
|
<string name="error_voice_broadcast_permission_denied_message">You don’t have the required permissions to start a voice broadcast in this room. Contact a room administrator to upgrade your permissions.</string>
|
||||||
|
<string name="error_voice_broadcast_blocked_by_someone_else_message">Someone else is already recording a voice broadcast. Wait for their voice broadcast to end to start a new one.</string>
|
||||||
|
<string name="error_voice_broadcast_already_in_progress_message">You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.</string>
|
||||||
|
|
||||||
<string name="upgrade_room_for_restricted">Anyone in %s will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
|
<string name="upgrade_room_for_restricted">Anyone in %s will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
|
||||||
<string name="upgrade_room_for_restricted_no_param">Anyone in a parent space will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
|
<string name="upgrade_room_for_restricted_no_param">Anyone in a parent space will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string>
|
||||||
|
@ -21,6 +21,8 @@ import im.vector.app.R
|
|||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.call.dialpad.DialPadLookup
|
import im.vector.app.features.call.dialpad.DialPadLookup
|
||||||
import im.vector.app.features.voice.VoiceFailure
|
import im.vector.app.features.voice.VoiceFailure
|
||||||
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastFailure
|
||||||
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastFailure.RecordingError
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
import org.matrix.android.sdk.api.failure.MatrixIdFailure
|
import org.matrix.android.sdk.api.failure.MatrixIdFailure
|
||||||
@ -135,6 +137,7 @@ class DefaultErrorFormatter @Inject constructor(
|
|||||||
is MatrixIdFailure.InvalidMatrixId ->
|
is MatrixIdFailure.InvalidMatrixId ->
|
||||||
stringProvider.getString(R.string.login_signin_matrix_id_error_invalid_matrix_id)
|
stringProvider.getString(R.string.login_signin_matrix_id_error_invalid_matrix_id)
|
||||||
is VoiceFailure -> voiceMessageError(throwable)
|
is VoiceFailure -> voiceMessageError(throwable)
|
||||||
|
is VoiceBroadcastFailure -> voiceBroadcastMessageError(throwable)
|
||||||
is ActivityNotFoundException ->
|
is ActivityNotFoundException ->
|
||||||
stringProvider.getString(R.string.error_no_external_application_found)
|
stringProvider.getString(R.string.error_no_external_application_found)
|
||||||
else -> throwable.localizedMessage
|
else -> throwable.localizedMessage
|
||||||
@ -149,6 +152,14 @@ class DefaultErrorFormatter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun voiceBroadcastMessageError(throwable: VoiceBroadcastFailure): String {
|
||||||
|
return when (throwable) {
|
||||||
|
RecordingError.BlockedBySomeoneElse -> stringProvider.getString(R.string.error_voice_broadcast_blocked_by_someone_else_message)
|
||||||
|
RecordingError.NoPermission -> stringProvider.getString(R.string.error_voice_broadcast_permission_denied_message)
|
||||||
|
RecordingError.UserAlreadyBroadcasting -> stringProvider.getString(R.string.error_voice_broadcast_already_in_progress_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun limitExceededError(error: MatrixError): String {
|
private fun limitExceededError(error: MatrixError): String {
|
||||||
val delay = error.retryAfterMillis
|
val delay = error.retryAfterMillis
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ import android.widget.FrameLayout
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.addCallback
|
import androidx.activity.addCallback
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.view.menu.MenuBuilder
|
import androidx.appcompat.view.menu.MenuBuilder
|
||||||
import androidx.constraintlayout.widget.ConstraintSet
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
@ -1320,8 +1321,12 @@ class TimelineFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun displayRoomDetailActionFailure(result: RoomDetailViewEvents.ActionFailure) {
|
private fun displayRoomDetailActionFailure(result: RoomDetailViewEvents.ActionFailure) {
|
||||||
|
@StringRes val titleResId = when(result.action) {
|
||||||
|
RoomDetailAction.VoiceBroadcastAction.Recording.Start -> R.string.error_voice_broadcast_unauthorized_title
|
||||||
|
else -> R.string.dialog_title_error
|
||||||
|
}
|
||||||
MaterialAlertDialogBuilder(requireActivity())
|
MaterialAlertDialogBuilder(requireActivity())
|
||||||
.setTitle(R.string.dialog_title_error)
|
.setTitle(titleResId)
|
||||||
.setMessage(errorFormatter.toHumanReadable(result.throwable))
|
.setMessage(errorFormatter.toHumanReadable(result.throwable))
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show()
|
.show()
|
||||||
|
@ -604,7 +604,12 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
if (room == null) return
|
if (room == null) return
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
when (action) {
|
when (action) {
|
||||||
RoomDetailAction.VoiceBroadcastAction.Recording.Start -> voiceBroadcastHelper.startVoiceBroadcast(room.roomId)
|
RoomDetailAction.VoiceBroadcastAction.Recording.Start -> {
|
||||||
|
voiceBroadcastHelper.startVoiceBroadcast(room.roomId).fold(
|
||||||
|
{ _viewEvents.post(RoomDetailViewEvents.ActionSuccess(action)) },
|
||||||
|
{ _viewEvents.post(RoomDetailViewEvents.ActionFailure(action, it)) },
|
||||||
|
)
|
||||||
|
}
|
||||||
RoomDetailAction.VoiceBroadcastAction.Recording.Pause -> voiceBroadcastHelper.pauseVoiceBroadcast(room.roomId)
|
RoomDetailAction.VoiceBroadcastAction.Recording.Pause -> voiceBroadcastHelper.pauseVoiceBroadcast(room.roomId)
|
||||||
RoomDetailAction.VoiceBroadcastAction.Recording.Resume -> voiceBroadcastHelper.resumeVoiceBroadcast(room.roomId)
|
RoomDetailAction.VoiceBroadcastAction.Recording.Resume -> voiceBroadcastHelper.resumeVoiceBroadcast(room.roomId)
|
||||||
RoomDetailAction.VoiceBroadcastAction.Recording.Stop -> voiceBroadcastHelper.stopVoiceBroadcast(room.roomId)
|
RoomDetailAction.VoiceBroadcastAction.Recording.Stop -> voiceBroadcastHelper.stopVoiceBroadcast(room.roomId)
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.voicebroadcast
|
||||||
|
|
||||||
|
sealed class VoiceBroadcastFailure : Throwable() {
|
||||||
|
sealed class RecordingError : VoiceBroadcastFailure() {
|
||||||
|
object NoPermission : RecordingError()
|
||||||
|
object BlockedBySomeoneElse : RecordingError()
|
||||||
|
object UserAlreadyBroadcasting : RecordingError()
|
||||||
|
}
|
||||||
|
}
|
@ -24,15 +24,22 @@ import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
|
|||||||
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
|
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
|
||||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastChunk
|
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastChunk
|
||||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
|
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
|
||||||
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastFailure
|
||||||
import im.vector.app.features.voicebroadcast.recording.VoiceBroadcastRecorder
|
import im.vector.app.features.voicebroadcast.recording.VoiceBroadcastRecorder
|
||||||
import im.vector.app.features.voicebroadcast.usecase.GetOngoingVoiceBroadcastsUseCase
|
import im.vector.app.features.voicebroadcast.usecase.GetOngoingVoiceBroadcastsUseCase
|
||||||
import im.vector.lib.multipicker.utils.toMultiPickerAudioType
|
import im.vector.lib.multipicker.utils.toMultiPickerAudioType
|
||||||
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.getRoom
|
import org.matrix.android.sdk.api.session.getRoom
|
||||||
import org.matrix.android.sdk.api.session.room.Room
|
import org.matrix.android.sdk.api.session.room.Room
|
||||||
|
import org.matrix.android.sdk.api.session.room.getStateEvent
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
||||||
|
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -50,12 +57,27 @@ class StartVoiceBroadcastUseCase @Inject constructor(
|
|||||||
|
|
||||||
Timber.d("## StartVoiceBroadcastUseCase: Start voice broadcast requested")
|
Timber.d("## StartVoiceBroadcastUseCase: Start voice broadcast requested")
|
||||||
|
|
||||||
val onGoingVoiceBroadcastEvents = getOngoingVoiceBroadcastsUseCase.execute(roomId)
|
val powerLevelsHelper = room.getStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.IsEmpty)
|
||||||
|
?.content
|
||||||
|
?.toModel<PowerLevelsContent>()
|
||||||
|
?.let { PowerLevelsHelper(it) }
|
||||||
|
|
||||||
if (onGoingVoiceBroadcastEvents.isEmpty()) {
|
when {
|
||||||
startVoiceBroadcast(room)
|
powerLevelsHelper?.isUserAllowedToSend(session.myUserId, true, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO) != true -> {
|
||||||
} else {
|
Timber.d("## StartVoiceBroadcastUseCase: Cannot start voice broadcast: no permission")
|
||||||
Timber.d("## StartVoiceBroadcastUseCase: Cannot start voice broadcast: currentVoiceBroadcastEvents=$onGoingVoiceBroadcastEvents")
|
throw VoiceBroadcastFailure.RecordingError.NoPermission
|
||||||
|
}
|
||||||
|
voiceBroadcastRecorder?.state == VoiceBroadcastRecorder.State.Recording || voiceBroadcastRecorder?.state == VoiceBroadcastRecorder.State.Paused -> {
|
||||||
|
Timber.d("## StartVoiceBroadcastUseCase: Cannot start voice broadcast: another voice broadcast")
|
||||||
|
throw VoiceBroadcastFailure.RecordingError.UserAlreadyBroadcasting
|
||||||
|
}
|
||||||
|
getOngoingVoiceBroadcastsUseCase.execute(roomId).isNotEmpty() -> {
|
||||||
|
Timber.d("## StartVoiceBroadcastUseCase: Cannot start voice broadcast: user already broadcasting")
|
||||||
|
throw VoiceBroadcastFailure.RecordingError.BlockedBySomeoneElse
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
startVoiceBroadcast(room)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user