Fix long press on voice message with screen reader (#1704)

As a workaround, disable seeking within the waveform so that it does
not interfere with the long press menu.

Seeking behaviour is already suboptimal given that there is no spoken
feedback about the current seek position. No core functionality is
lost as voice messages can be played using a screen reader.
This commit is contained in:
jonnyandrew 2023-10-31 13:00:08 +00:00 committed by GitHub
parent 5757789d29
commit 95a2152714
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 0 deletions

View file

@ -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()))

View file

@ -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<AccessibilityManager>()
?: return false
return accessibilityManager.let {
it.isEnabled && it.isTouchExplorationEnabled
}
}