From b62f1ebb0578031ef93e49ddce54d54bc1454fdc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 14:30:38 +0100 Subject: [PATCH 01/10] Add contentDescription for sending states. --- .../impl/timeline/components/TimelineEventTimestampView.kt | 4 ++-- .../components/receipt/TimelineItemReadReceiptView.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt index 5bc7efc852..ff4fe92e57 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt @@ -36,8 +36,8 @@ import androidx.compose.ui.unit.dp import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent import io.element.android.libraries.core.bool.orFalse -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.utils.CommonDrawables @@ -91,7 +91,7 @@ fun TimelineEventTimestampView( Spacer(modifier = Modifier.width(2.dp)) Icon( resourceId = CommonDrawables.ic_compound_error, - contentDescription = "Error sending message", + contentDescription = stringResource(id = CommonStrings.common_sending_failed), tint = tint, modifier = Modifier.size(15.dp, 18.dp), ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 8725b365d0..7e7f1f74a2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -80,7 +80,7 @@ fun TimelineItemReadReceiptView( Icon( modifier = Modifier.padding(2.dp), resourceId = CommonDrawables.ic_sending, - contentDescription = null, + contentDescription = stringResource(id = CommonStrings.common_sending), tint = ElementTheme.colors.iconSecondary ) } @@ -96,7 +96,7 @@ fun TimelineItemReadReceiptView( Icon( modifier = Modifier.padding(2.dp), resourceId = CommonDrawables.ic_sent, - contentDescription = null, + contentDescription = stringResource(id = CommonStrings.common_sent), tint = ElementTheme.colors.iconSecondary ) } From 88a7cc9740000cc89768bb798e1cb6ad574e826e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 14:44:38 +0100 Subject: [PATCH 02/10] Fix some contentDescription. --- .../impl/timeline/components/event/TimelineItemFileView.kt | 2 +- .../timeline/components/event/TimelineItemVideoView.kt | 4 +++- .../virtual/TimelineEncryptedHistoryBannerView.kt | 3 ++- .../libraries/designsystem/components/button/BackButton.kt | 4 ++-- .../designsystem/theme/components/IconToggleButton.kt | 4 ++-- .../designsystem/theme/components/previews/MenuPreview.kt | 7 +++++-- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt index a8fb3e1fcc..8d7ffa4ca7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt @@ -60,7 +60,7 @@ fun TimelineItemFileView( ) { Icon( resourceId = CommonDrawables.ic_attachment, - contentDescription = "OpenFile", + contentDescription = null, tint = ElementTheme.materialColors.primary, modifier = Modifier .size(16.dp) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index f666a29ac9..87685e432c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContentProvider @@ -34,6 +35,7 @@ import io.element.android.libraries.designsystem.modifiers.roundedBackground import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.matrix.ui.media.MediaRequestData +import io.element.android.libraries.ui.strings.CommonStrings @Composable fun TimelineItemVideoView( @@ -56,7 +58,7 @@ fun TimelineItemVideoView( ) { Image( Icons.Default.PlayArrow, - contentDescription = "Play", + contentDescription = stringResource(id = CommonStrings.a11y_play), colorFilter = ColorFilter.tint(Color.White), ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt index 241f98c141..b70514a8e0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt @@ -39,6 +39,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings @Composable fun TimelineEncryptedHistoryBannerView( @@ -57,7 +58,7 @@ fun TimelineEncryptedHistoryBannerView( Icon( modifier = Modifier.size(20.dp), resourceId = CommonDrawables.ic_compound_info_solid, - contentDescription = "Info", + contentDescription = null, tint = ElementTheme.colors.iconInfoPrimary ) Text( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/BackButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/BackButton.kt index 30c8b95d74..44388ec812 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/BackButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/BackButton.kt @@ -51,7 +51,7 @@ fun BackButton( @Composable internal fun BackButtonPreview() = ElementThemedPreview { Column { - BackButton(onClick = { }, enabled = true, contentDescription = "Back") - BackButton(onClick = { }, enabled = false, contentDescription = "Back") + BackButton(onClick = { }, enabled = true) + BackButton(onClick = { }, enabled = false) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconToggleButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconToggleButton.kt index fd355d3860..92bc5c7605 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconToggleButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconToggleButton.kt @@ -69,7 +69,7 @@ private fun ContentToPreview() { val icon: @Composable () -> Unit = { Icon( imageVector = if (checked) Icons.Default.CheckCircle else Icons.Default.RadioButtonUnchecked, - contentDescription = "IconToggleButton" + contentDescription = null ) } IconToggleButton(checked = checked, enabled = true, onCheckedChange = { checked = !checked }, content = icon) @@ -79,7 +79,7 @@ private fun ContentToPreview() { val icon: @Composable () -> Unit = { Icon( imageVector = if (!checked) Icons.Default.CheckCircle else Icons.Default.RadioButtonUnchecked, - contentDescription = "IconToggleButton" + contentDescription = null ) } IconToggleButton(checked = !checked, enabled = true, onCheckedChange = { checked = !checked }, content = icon) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt index 4bbb20b6a2..67da422d5b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt @@ -43,7 +43,10 @@ internal fun MenuPreview() { for (i in 0..5) { val leadingIcon: @Composable (() -> Unit)? = if (i in 2..3) { @Composable { - Icon(Icons.Filled.Favorite, contentDescription = "Favorite") + Icon( + imageVector = Icons.Filled.Favorite, + contentDescription = null + ) } } else { null @@ -53,7 +56,7 @@ internal fun MenuPreview() { @Composable { Icon( resourceId = CommonDrawables.ic_compound_chevron_right, - contentDescription = "Favorite", + contentDescription = null, ) } } else { From 311835962f9cb5d35275b7d410d02eda5cb5e36d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 14:58:36 +0100 Subject: [PATCH 03/10] Fix some contentDescription. --- .../messages/impl/actionlist/ActionListView.kt | 15 ++++++++++++--- .../messages/impl/media/local/LocalMediaView.kt | 4 +++- .../messages/impl/media/local/pdf/PdfViewer.kt | 4 +++- .../ui-strings/src/main/res/values/localazy.xml | 7 ++++++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index 1e57de2466..92cfa91308 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -48,6 +48,8 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter @@ -371,7 +373,7 @@ private fun EmojiReactionsRow( ) { Icon( resourceId = CommonDrawables.ic_add_reaction, - contentDescription = "Emojis", + contentDescription = stringResource(id = CommonStrings.a11y_react_with_other_emojis), tint = MaterialTheme.colorScheme.secondary, modifier = Modifier .size(24.dp) @@ -398,11 +400,18 @@ private fun EmojiButton( } else { Color.Transparent } + val description = if (isHighlighted) { + stringResource(id = CommonStrings.a11y_remove_reaction_with, emoji) + } else { + stringResource(id = CommonStrings.a11y_react_with, emoji) + } Box( modifier = modifier .size(48.dp) - .background(backgroundColor, CircleShape), - + .background(backgroundColor, CircleShape) + .clearAndSetSemantics { + contentDescription = description + }, contentAlignment = Alignment.Center ) { Text( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt index 96e721e815..145b8ac56e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/LocalMediaView.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -69,6 +70,7 @@ import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.KeepScreenOn import io.element.android.libraries.designsystem.utils.OnLifecycleEvent import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings import me.saket.telephoto.zoomable.ZoomSpec import me.saket.telephoto.zoomable.ZoomableState import me.saket.telephoto.zoomable.coil.ZoomableAsyncImage @@ -135,7 +137,7 @@ private fun MediaImageView( modifier = modifier.fillMaxSize(), state = zoomableImageState, model = localMedia?.uri, - contentDescription = "Image", + contentDescription = stringResource(id = CommonStrings.common_image), contentScale = ContentScale.Fit, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/pdf/PdfViewer.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/pdf/PdfViewer.kt index 41a111d97d..9940d22542 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/pdf/PdfViewer.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/media/local/pdf/PdfViewer.kt @@ -35,9 +35,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import io.element.android.libraries.designsystem.text.roundToPx import io.element.android.libraries.designsystem.text.toDp +import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import me.saket.telephoto.zoomable.zoomable @@ -98,7 +100,7 @@ private fun PdfPageView( is PdfPage.State.Loaded -> { Image( bitmap = state.bitmap.asImageBitmap(), - contentDescription = "Page ${pdfPage.pageIndex}", + contentDescription = stringResource(id = CommonStrings.a11y_page_n, pdfPage.pageIndex), contentScale = ContentScale.FillWidth, modifier = modifier.fillMaxWidth() ) diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index c2f969551c..4f18ef9c4a 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -4,19 +4,24 @@ "Hide password" "Mentions only" "Muted" + "Page %1$d" "Pause" "PIN field" "Play" "Poll" "Ended poll" + "React with %1$s" + "React with other emojis" + "Read by %1$s and %2$s" "Read by %1$s" + "Tap to show all" + "Remove reaction with %1$s" "Send files" "Show password" "Start a call" "User menu" "Record voice message." "Stop recording" - "Read by %1$s and %2$s" "Accept" "Add to timeline" "Back" From 3a21ee7a50533c6c5c030880bf5b4aec6dcf6eba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 15:35:36 +0100 Subject: [PATCH 04/10] Fix contentDescription for Read Receipt. --- .../components/receipt/TimelineItemReadReceiptView.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 7e7f1f74a2..65bc185c14 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.stateDescription +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex @@ -69,7 +69,9 @@ fun TimelineItemReadReceiptView( receipts = state.receipts, modifier = Modifier .clip(RoundedCornerShape(4.dp)) - .clickable { onReadReceiptsClicked() } + .clickable { + onReadReceiptsClicked() + } .padding(2.dp) ) } @@ -139,7 +141,7 @@ private fun ReadReceiptsAvatars( Row( modifier = modifier .clearAndSetSemantics { - stateDescription = receiptDescription + contentDescription = receiptDescription }, horizontalArrangement = Arrangement.spacedBy(4.dp - avatarStrokeSize), verticalAlignment = Alignment.CenterVertically, From 2e6803ac411cd918d0033e99c20d10078f7f1de2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 15:21:20 +0100 Subject: [PATCH 05/10] Fix contentDescription for jump to bottom FAB. --- .../android/features/messages/impl/timeline/TimelineView.kt | 4 +++- libraries/ui-strings/src/main/res/values/localazy.xml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 1d831e5e21..2b9433dd5b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -52,6 +52,7 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.rotate import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.pluralStringResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.features.messages.impl.R @@ -78,6 +79,7 @@ import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.coroutines.launch @Composable @@ -350,7 +352,7 @@ private fun JumpToBottomButton( .size(24.dp) .rotate(90f), resourceId = CommonDrawables.ic_compound_arrow_right, - contentDescription = "", + contentDescription = stringResource(id = CommonStrings.a11y_jump_to_bottom) ) } } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 4f18ef9c4a..054a6281e6 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -2,6 +2,7 @@ "Delete" "Hide password" + "Jump to bottom" "Mentions only" "Muted" "Page %1$d" From 67ed385e4540acd4dd390f26c89f16a01c95bf47 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 15:36:20 +0100 Subject: [PATCH 06/10] Prevent usage of hard-coded string for contentDescription, and fix existing issues. --- .../createroom/impl/components/RoomPrivacyOption.kt | 2 +- .../features/lockscreen/impl/unlock/PinUnlockView.kt | 2 +- .../designsystem/atomic/atoms/RoundedIconAtom.kt | 2 +- .../components/preferences/components/PreferenceIcon.kt | 2 +- .../designsystem/theme/components/FloatingActionButton.kt | 2 +- .../libraries/designsystem/theme/components/Icon.kt | 2 +- .../libraries/designsystem/theme/components/IconButton.kt | 8 ++++---- .../libraries/matrix/ui/components/EditableAvatarView.kt | 2 +- .../libraries/matrix/ui/components/UnresolvedUserRow.kt | 2 +- .../libraries/matrix/ui/components/UnsavedAvatar.kt | 2 +- .../libraries/textcomposer/components/FormattingOption.kt | 6 +++--- tools/check/forbidden_strings_in_code.txt | 4 ++++ 12 files changed, 20 insertions(+), 16 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt index 00b4206a73..3a570e9e0f 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/RoomPrivacyOption.kt @@ -58,7 +58,7 @@ fun RoomPrivacyOption( Icon( modifier = Modifier.padding(horizontal = 8.dp), resourceId = roomPrivacyItem.icon, - contentDescription = "", + contentDescription = null, tint = MaterialTheme.colorScheme.secondary, ) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt index fcca4985f5..a40ec08910 100644 --- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt @@ -300,7 +300,7 @@ private fun PinUnlockHeader( .size(32.dp), tint = ElementTheme.colors.iconPrimary, imageVector = Icons.Filled.Lock, - contentDescription = "", + contentDescription = null, ) } Spacer(modifier = Modifier.height(16.dp)) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoundedIconAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoundedIconAtom.kt index 8c8f009618..990e113d75 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoundedIconAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoundedIconAtom.kt @@ -70,7 +70,7 @@ fun RoundedIconAtom( tint = tint, resourceId = resourceId, imageVector = imageVector, - contentDescription = "", + contentDescription = null, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt index c29b46f3c3..61e8aabdd7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt @@ -51,7 +51,7 @@ fun PreferenceIcon( Icon( imageVector = icon, resourceId = iconResourceId, - contentDescription = "", + contentDescription = null, tint = tintColor ?: enabled.toSecondaryEnabledColor(), modifier = Modifier .padding(end = 16.dp) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt index ed32018f84..fd6620e356 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/FloatingActionButton.kt @@ -66,7 +66,7 @@ internal fun FloatingActionButtonPreview() = private fun ContentToPreview() { Box(modifier = Modifier.padding(8.dp)) { FloatingActionButton(onClick = {}) { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Icon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Icon.kt index 1813db36f2..299c9991ad 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Icon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Icon.kt @@ -145,5 +145,5 @@ internal fun IconImageVectorPreview() = @Composable private fun ContentToPreview() { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconButton.kt index fd6d2ed471..5f989d2fb2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/IconButton.kt @@ -67,20 +67,20 @@ private fun ContentToPreview() { CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.iconPrimary) { Row { IconButton(onClick = {}) { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } IconButton(enabled = false, onClick = {}) { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } } } CompositionLocalProvider(LocalContentColor provides ElementTheme.colors.iconSecondary) { Row { IconButton(onClick = {}) { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } IconButton(enabled = false, onClick = {}) { - Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = "") + Icon(resourceId = CommonDrawables.ic_compound_close, contentDescription = null) } } } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt index 289c37530a..e28435a243 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt @@ -87,7 +87,7 @@ fun EditableAvatarView( Icon( modifier = Modifier.size(16.dp), resourceId = CommonDrawables.ic_edit, - contentDescription = "", + contentDescription = null, tint = MaterialTheme.colorScheme.onPrimary, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt index 2916fa7f06..a61378a982 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnresolvedUserRow.kt @@ -79,7 +79,7 @@ fun UnresolvedUserRow( ) { Icon( resourceId = CommonDrawables.ic_compound_error, - contentDescription = "", + contentDescription = null, modifier = Modifier .size(18.dp) .align(Alignment.Top) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt index f7852d690e..62481d33c1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt @@ -72,7 +72,7 @@ fun UnsavedAvatar( Box(modifier = commonModifier.background(ElementTheme.colors.temporaryColorBgSpecial)) { Icon( imageVector = Icons.Outlined.AddAPhoto, - contentDescription = "", + contentDescription = null, modifier = Modifier .align(Alignment.Center) .size(40.dp), diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt index 791bf7cc75..525fdeab43 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt @@ -98,19 +98,19 @@ internal fun FormattingButtonPreview() = ElementPreview { state = FormattingOptionState.Default, onClick = { }, imageVector = ImageVector.vectorResource(CommonDrawables.ic_bold), - contentDescription = "", + contentDescription = null, ) FormattingOption( state = FormattingOptionState.Selected, onClick = { }, imageVector = ImageVector.vectorResource(CommonDrawables.ic_italic), - contentDescription = "", + contentDescription = null, ) FormattingOption( state = FormattingOptionState.Disabled, onClick = { }, imageVector = ImageVector.vectorResource(CommonDrawables.ic_underline), - contentDescription = "", + contentDescription = null, ) } } diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 17f352fca4..37234ac670 100755 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -132,3 +132,7 @@ System\.currentTimeMillis\(\)===1 ### Use `import io.element.android.libraries.ui.strings.CommonStrings` then `CommonStrings.` instead import io\.element\.android\.libraries\.ui\.strings\.R + +# Accessibility +### Use string resource for `contentDescription`, or null instead of empty string +contentDescription = " From 3e751e42bacd1929be4bc584a40869e63ff69f90 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 16:48:38 +0100 Subject: [PATCH 07/10] Fix some contentDescription. --- .../components/customreaction/EmojiItem.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt index 3de0734b61..ca66cbb298 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/customreaction/EmojiItem.kt @@ -30,12 +30,16 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.unit.dp import io.element.android.emojibasebindings.Emoji import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings @Composable fun EmojiItem( @@ -49,7 +53,11 @@ fun EmojiItem( } else { Color.Transparent } - + val description = if (isSelected) { + stringResource(id = CommonStrings.a11y_remove_reaction_with, item.unicode) + } else { + stringResource(id = CommonStrings.a11y_react_with, item.unicode) + } Box( modifier = modifier .size(40.dp) @@ -59,7 +67,10 @@ fun EmojiItem( onClick = { onEmojiSelected(item) }, indication = rememberRipple(bounded = false, radius = 20.dp), interactionSource = remember { MutableInteractionSource() } - ), + ) + .clearAndSetSemantics { + contentDescription = description + }, contentAlignment = Alignment.Center ) { Text( From a8e0d1e66dd2f2d5b946e6a043a4fdf3771cc1d1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 16:51:50 +0100 Subject: [PATCH 08/10] Fix compilation issue --- .../libraries/textcomposer/components/FormattingOption.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt index 525fdeab43..e7b1ccadac 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt @@ -32,8 +32,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.iconSuccessPrimaryBackground import io.element.android.libraries.designsystem.utils.CommonDrawables @@ -45,7 +45,7 @@ internal fun FormattingOption( state: FormattingOptionState, onClick: () -> Unit, imageVector: ImageVector, - contentDescription: String, + contentDescription: String?, modifier: Modifier = Modifier, colors: SemanticColors = ElementTheme.colors, ) { From 164269ef7649137ad71ab16ea7154a77ab25bfa1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 16:53:03 +0100 Subject: [PATCH 09/10] No need to have a SemanticColors parameter. --- .../textcomposer/components/FormattingOption.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt index e7b1ccadac..8c1b099930 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/FormattingOption.kt @@ -38,7 +38,6 @@ import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.iconSuccessPrimaryBackground import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.theme.ElementTheme -import io.element.android.libraries.theme.compound.generated.SemanticColors @Composable internal fun FormattingOption( @@ -47,18 +46,17 @@ internal fun FormattingOption( imageVector: ImageVector, contentDescription: String?, modifier: Modifier = Modifier, - colors: SemanticColors = ElementTheme.colors, ) { val backgroundColor = when (state) { - FormattingOptionState.Selected -> colors.iconSuccessPrimaryBackground + FormattingOptionState.Selected -> ElementTheme.colors.iconSuccessPrimaryBackground FormattingOptionState.Default, FormattingOptionState.Disabled -> Color.Transparent } val foregroundColor = when (state) { - FormattingOptionState.Selected -> colors.iconSuccessPrimary - FormattingOptionState.Default -> colors.iconSecondary - FormattingOptionState.Disabled -> colors.iconDisabled + FormattingOptionState.Selected -> ElementTheme.colors.iconSuccessPrimary + FormattingOptionState.Default -> ElementTheme.colors.iconSecondary + FormattingOptionState.Disabled -> ElementTheme.colors.iconDisabled } Box( modifier = modifier From 0114d97acf943451b858e667fce2960770d5abe0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 21 Nov 2023 17:18:29 +0100 Subject: [PATCH 10/10] Remove unused import --- .../components/virtual/TimelineEncryptedHistoryBannerView.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt index b70514a8e0..a26ba71beb 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/virtual/TimelineEncryptedHistoryBannerView.kt @@ -39,7 +39,6 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.theme.ElementTheme -import io.element.android.libraries.ui.strings.CommonStrings @Composable fun TimelineEncryptedHistoryBannerView(