diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 0c98321047..e7762fe278 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -29,6 +29,7 @@ import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -42,6 +43,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageEvents import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageState import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageStateProvider +import io.element.android.libraries.androidutils.accessibility.isScreenReaderEnabled import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -86,6 +88,7 @@ fun TimelineItemVoiceView( overflow = TextOverflow.Ellipsis, ) Spacer(Modifier.width(8.dp)) + val context = LocalContext.current WaveformPlaybackView( showCursor = state.button == VoiceMessageState.Button.Pause, playbackProgress = state.progress, @@ -93,6 +96,7 @@ fun TimelineItemVoiceView( modifier = Modifier .height(34.dp) .weight(1f), + seekEnabled = !context.isScreenReaderEnabled(), onSeek = { state.eventSink(VoiceMessageEvents.Seek(it)) }, ) Spacer(Modifier.width(extraPadding.getDpSize())) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/accessibility/ContextExt.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/accessibility/ContextExt.kt new file mode 100644 index 0000000000..bb223e43fb --- /dev/null +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/accessibility/ContextExt.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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 io.element.android.libraries.androidutils.accessibility + +import android.content.Context +import android.view.accessibility.AccessibilityManager +import androidx.core.content.getSystemService + +/** + * Whether a screen reader is enabled. + * + * Avoid changing UI or app behavior based on the state of accessibility. + * See [AccessibilityManager.isTouchExplorationEnabled] for more details. + * + * @return true if the screen reader is enabled. + */ +fun Context.isScreenReaderEnabled(): Boolean { + val accessibilityManager = getSystemService() + ?: return false + + return accessibilityManager.let { + it.isEnabled && it.isTouchExplorationEnabled + } +} +