diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index 4268a034f5..9f1497a40a 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -34,6 +34,7 @@ import im.vector.app.core.platform.VectorBaseActivity // Permissions sets val PERMISSIONS_FOR_AUDIO_IP_CALL = listOf(Manifest.permission.RECORD_AUDIO) val PERMISSIONS_FOR_VIDEO_IP_CALL = listOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA) +val PERMISSIONS_FOR_VOICE_MESSAGE = listOf(Manifest.permission.RECORD_AUDIO) val PERMISSIONS_FOR_TAKING_PHOTO = listOf(Manifest.permission.CAMERA) val PERMISSIONS_FOR_MEMBERS_SEARCH = listOf(Manifest.permission.READ_CONTACTS) val PERMISSIONS_FOR_ROOM_AVATAR = listOf(Manifest.permission.CAMERA) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index ce3346f8a6..25428bbfbf 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -51,6 +51,8 @@ class RoomDetailActivity : return ActivityRoomDetailBinding.inflate(layoutInflater) } + override fun getCoordinatorLayout() = views.coordinatorLayout + private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 8307c7bbed..fe8b40ca2e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -95,7 +95,7 @@ import im.vector.app.core.ui.views.NotificationAreaView import im.vector.app.core.utils.Debouncer import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.KeyboardStateUtils -import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL +import im.vector.app.core.utils.PERMISSIONS_FOR_VOICE_MESSAGE import im.vector.app.core.utils.PERMISSIONS_FOR_WRITING_FILES import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.colorizeMatchingText @@ -104,6 +104,7 @@ import im.vector.app.core.utils.createJSonViewerStyleProvider import im.vector.app.core.utils.createUIHandler import im.vector.app.core.utils.isValidUrl import im.vector.app.core.utils.onPermissionDeniedDialog +import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.openUrlInExternalBrowser import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.saveMedia @@ -613,17 +614,26 @@ class RoomDetailFragment @Inject constructor( } } + private val permissionVoiceMessageLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> + if (allGranted) { + // In this case, let the user start again the gesture + } else if (deniedPermanently) { + vectorBaseActivity.onPermissionDeniedSnackbar(R.string.denied_permission_voice_message) + } + } + private fun setupVoiceMessageView() { views.voiceMessageRecorderView.voiceMessagePlaybackTracker = voiceMessagePlaybackTracker views.voiceMessageRecorderView.callback = object : VoiceMessageRecorderView.Callback { override fun onVoiceRecordingStarted(): Boolean { - return if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL, requireActivity(), 0)) { + return if (checkPermissions(PERMISSIONS_FOR_VOICE_MESSAGE, requireActivity(), permissionVoiceMessageLauncher)) { views.composerLayout.isInvisible = true roomDetailViewModel.handle(RoomDetailAction.StartRecordingVoiceMessage) vibrate(requireContext()) true } else { + // Permission dialog is displayed false } } @@ -1272,13 +1282,6 @@ class RoomDetailFragment @Inject constructor( override fun onTextBlankStateChanged(isBlank: Boolean) { views.voiceMessageRecorderView.isVisible = !views.composerLayout.views.sendButton.isVisible && vectorPreferences.labsUseVoiceMessage() } - - override fun onTouchVoiceRecording() { - if (checkPermissions(PERMISSIONS_FOR_AUDIO_IP_CALL, requireActivity(), 0)) { - views.composerLayout.isInvisible = true - views.voiceMessageRecorderView.isVisible = true - } - } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt index 1ed54a1e8a..eb935f9e75 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt @@ -48,7 +48,6 @@ class TextComposerView @JvmOverloads constructor( fun onCloseRelatedMessage() fun onSendMessage(text: CharSequence) fun onAddAttachment() - fun onTouchVoiceRecording() } val views: ComposerLayoutBinding diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt index 4370ff43a7..924ec3ed98 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecorderView.kt @@ -119,18 +119,18 @@ class VoiceMessageRecorderView @JvmOverloads constructor( views.voiceMessageMicButton.setOnTouchListener { _, event -> return@setOnTouchListener when (event.action) { MotionEvent.ACTION_DOWN -> { - startRecordingTimer() val recordingStarted = callback?.onVoiceRecordingStarted().orFalse() if (recordingStarted) { + startRecordingTimer() renderToast(context.getString(R.string.voice_message_release_to_send_toast)) - } - recordingState = RecordingState.STARTED - showRecordingViews() + recordingState = RecordingState.STARTED + showRecordingViews() - firstX = event.rawX - firstY = event.rawY - lastX = firstX - lastY = firstY + firstX = event.rawX + firstY = event.rawY + lastX = firstX + lastY = firstY + } true } MotionEvent.ACTION_UP -> { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 37874b189b..1fb7c3cb09 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -389,6 +389,7 @@ Some permissions are missing to perform this action, please grant the permissions from the system settings. To perform this action, please grant the Camera permission from the system settings. + To send voice messages, please grant the Microphone permission. Ongoing conference call.\nJoin as %1$s or %2$s