diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
index 35cfbb1594..977308178d 100644
--- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
+++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt
@@ -609,6 +609,7 @@ private fun JoinRoomTopBar(
val roundedCornerShape = RoundedCornerShape(8.dp)
val titleModifier = Modifier
.clip(roundedCornerShape)
+ .semantics { heading() }
if (contentState.name != null) {
Row(
modifier = titleModifier,
@@ -621,10 +622,7 @@ private fun JoinRoomTopBar(
)
Text(
modifier = Modifier
- .padding(horizontal = 8.dp)
- .semantics {
- heading()
- },
+ .padding(horizontal = 8.dp),
text = contentState.name,
style = ElementTheme.typography.fontBodyLgMedium,
maxLines = 1,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
index 1beabcd3fa..5e26d849a5 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/list/ThreadsListView.kt
@@ -31,6 +31,9 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.heading
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
@@ -79,7 +82,18 @@ fun ThreadsListView(
topBar = {
TopAppBar(
title = {
- Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
+ val description = stringResource(
+ CommonStrings.a11y_threads_in_room,
+ state.roomName,
+ )
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.clearAndSetSemantics {
+ heading()
+ contentDescription = description
+ },
+ ) {
Avatar(
avatarData = AvatarData(
id = state.roomId.value,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt
index 639092fc6c..4f023ad2bd 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt
@@ -80,7 +80,8 @@ internal fun MessagesViewTopBar(
Row(
modifier = Modifier
.clip(roundedCornerShape)
- .clickable { onRoomDetailsClick() },
+ .clickable { onRoomDetailsClick() }
+ .semantics { heading() },
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
@@ -158,10 +159,7 @@ private fun RoomAvatarAndNameRow(
)
Text(
modifier = Modifier
- .padding(start = 8.dp)
- .semantics {
- heading()
- },
+ .padding(start = 8.dp),
text = roomName ?: stringResource(CommonStrings.common_no_room_name),
style = ElementTheme.typography.fontBodyLgMedium,
fontStyle = FontStyle.Italic.takeIf { roomName == null },
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/ThreadTopBar.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/ThreadTopBar.kt
index e73b6b19b7..5ef4541f06 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/ThreadTopBar.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/ThreadTopBar.kt
@@ -17,8 +17,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
-import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -58,7 +59,18 @@ internal fun ThreadTopBar(
BackButton(onClick = onBackClick)
},
title = {
- Row(verticalAlignment = Alignment.CenterVertically) {
+ val name = roomName ?: stringResource(CommonStrings.common_no_room_name)
+ val description = stringResource(
+ CommonStrings.a11y_thread_in_room,
+ name,
+ )
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.clearAndSetSemantics {
+ heading()
+ contentDescription = description
+ },
+ ) {
Avatar(
avatarData = roomAvatarData,
avatarType = AvatarType.Room(
@@ -69,17 +81,14 @@ internal fun ThreadTopBar(
Column(
modifier = Modifier
.fillMaxWidth()
- .padding(horizontal = 8.dp)
- .semantics {
- heading()
- },
+ .padding(horizontal = 8.dp),
) {
Text(
text = stringResource(CommonStrings.common_thread),
style = ElementTheme.typography.fontBodyLgMedium,
)
Text(
- text = roomName ?: stringResource(CommonStrings.common_no_room_name),
+ text = name,
style = ElementTheme.typography.fontBodySmRegular,
fontStyle = FontStyle.Italic.takeIf { roomName == null },
color = ElementTheme.colors.textSecondary,
diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt
index 05fb75ee5e..29898a1f63 100644
--- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt
+++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/root/SpaceView.kt
@@ -354,7 +354,8 @@ private fun EmptySpaceView(
title = stringResource(R.string.screen_space_empty_state_title),
subTitle = null,
iconStyle = BigIcon.Style.Default(vectorIcon = CompoundIcons.Room(), usePrimaryTint = true),
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier
+ .fillMaxWidth()
.padding(top = 40.dp, start = 24.dp, end = 24.dp, bottom = 24.dp),
)
ButtonColumnMolecule(
@@ -425,6 +426,7 @@ private fun SpaceViewTopBar(
modifier = Modifier
.clip(roundedCornerShape)
.clickable(enabled = canAccessSpaceSettings, onClick = onSettingsClick)
+ .semantics { heading() }
)
},
actions = {
@@ -532,6 +534,7 @@ private fun ManageModeTopBar(
Text(
text = pluralStringResource(CommonPlurals.common_selected_count, selectedCount, selectedCount),
style = ElementTheme.typography.fontBodyLgMedium,
+ modifier = Modifier.semantics { heading() },
)
},
actions = {
@@ -585,10 +588,7 @@ private fun SpaceAvatarAndNameRow(
)
Text(
modifier = Modifier
- .padding(horizontal = 8.dp)
- .semantics {
- heading()
- },
+ .padding(horizontal = 8.dp),
text = name ?: stringResource(CommonStrings.common_no_space_name),
style = ElementTheme.typography.fontBodyLgMedium,
fontStyle = FontStyle.Italic.takeIf { name == null },
diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt
index d52db124ea..3a7c006593 100644
--- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt
+++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/viewer/MediaViewerView.kt
@@ -55,6 +55,8 @@ import androidx.compose.ui.layout.onVisibilityChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
@@ -495,14 +497,20 @@ private fun MediaViewerTopBar(
TopAppBar(
title = {
if (senderName != null && dateSent != null) {
+ val description = stringResource(
+ CommonStrings.a11y_sent_by_sender_at_date,
+ senderName,
+ dateSent,
+ )
Column(
modifier = Modifier
.fillMaxWidth()
+ .clearAndSetSemantics {
+ heading()
+ contentDescription = description
+ },
) {
Text(
- modifier = Modifier.semantics {
- heading()
- },
text = senderName,
style = ElementTheme.typography.fontBodyMdMedium,
color = ElementTheme.colors.textPrimary,
diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml
index fd3679a140..e89d45b228 100644
--- a/libraries/ui-strings/src/main/res/values/localazy.xml
+++ b/libraries/ui-strings/src/main/res/values/localazy.xml
@@ -50,12 +50,15 @@
"Room avatar"
"Send files"
"Sender location"
+ "Sent by %1$s at %2$s"
"Time limited action required, you have one minute to verify"
"Settings, action required"
"Show password"
"Start a call"
"Start a video call"
"Start a voice call"
+ "Thread in %1$s"
+ "Threads in %1$s"
"Tombstoned room"
"User avatar"
"User menu"