diff --git a/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt b/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt
index 5d49d78d5d3..372e2ee474f 100644
--- a/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt
+++ b/app/src/main/kotlin/com/wire/android/model/UserAvatarData.kt
@@ -19,6 +19,7 @@
package com.wire.android.model
import androidx.compose.runtime.Stable
+import com.wire.android.R
import com.wire.android.ui.home.conversationslist.model.Membership
import com.wire.android.util.EMPTY
import com.wire.kalium.logic.data.user.ConnectionState
@@ -37,6 +38,13 @@ data class UserAvatarData(
return asset == null && nameBasedAvatar != null &&
nameBasedAvatar.initials.isEmpty().not() && membership != Membership.Service
}
+
+ fun getAvailabilityStatusDescriptionId(): Int? = when (availabilityStatus) {
+ UserAvailabilityStatus.NONE -> null
+ UserAvailabilityStatus.AVAILABLE -> R.string.user_profile_status_available
+ UserAvailabilityStatus.AWAY -> R.string.user_profile_status_away
+ UserAvailabilityStatus.BUSY -> R.string.user_profile_status_busy
+ }
}
/**
diff --git a/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreateAccountOverviewParams.kt b/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreateAccountOverviewParams.kt
index 51d3d2336e0..d59243c3c77 100644
--- a/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreateAccountOverviewParams.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreateAccountOverviewParams.kt
@@ -26,5 +26,6 @@ data class CreateAccountOverviewParams(
val contentText: String = "",
@DrawableRes val contentIconResId: Int = 0,
val learnMoreText: String = "",
- val learnMoreUrl: String = ""
+ val learnMoreUrl: String = "",
+ val isContentTextSemanticAccessible: Boolean = false
)
diff --git a/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreatePersonalAccountOverviewScreen.kt b/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreatePersonalAccountOverviewScreen.kt
index ba76da0c892..7e2237c1ed3 100644
--- a/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreatePersonalAccountOverviewScreen.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/authentication/create/overview/CreatePersonalAccountOverviewScreen.kt
@@ -109,7 +109,8 @@ fun CreateTeamAccountOverviewScreen(
contentText = stringResource(id = overviewResources.overviewContentTextResId),
contentIconResId = overviewResources.overviewContentIconResId,
learnMoreText = stringResource(id = overviewResources.overviewLearnMoreTextResId),
- learnMoreUrl = viewModel.learnMoreUrl()
+ learnMoreUrl = viewModel.learnMoreUrl(),
+ isContentTextSemanticAccessible = true
)
)
}
@@ -193,7 +194,15 @@ private fun OverviewTexts(
text = overviewParams.contentText,
style = MaterialTheme.wireTypography.body02,
textAlign = TextAlign.Center,
- modifier = Modifier.fillMaxWidth().clearAndSetSemantics {}
+ modifier = Modifier
+ .fillMaxWidth()
+ .run {
+ if (overviewParams.isContentTextSemanticAccessible) {
+ this
+ } else {
+ clearAndSetSemantics {}
+ }
+ }
)
Text(
text = overviewParams.learnMoreText,
diff --git a/app/src/main/kotlin/com/wire/android/ui/authentication/devices/DeviceItem.kt b/app/src/main/kotlin/com/wire/android/ui/authentication/devices/DeviceItem.kt
index a3a940da9e5..b0a7d95a2b4 100644
--- a/app/src/main/kotlin/com/wire/android/ui/authentication/devices/DeviceItem.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/authentication/devices/DeviceItem.kt
@@ -42,6 +42,8 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.wire.android.BuildConfig
@@ -189,13 +191,22 @@ private fun ColumnScope.DeviceItemTexts(
.fillMaxWidth()
.shimmerPlaceholder(visible = placeholder)
) {
+ val deviceName = device.name.asString()
+ val shouldAddNotVerifiedLabel = shouldShowVerifyLabel && !shouldShowE2EIInfo && !(device.isVerifiedProteus && !isCurrentClient)
+ val semantic = if (shouldAddNotVerifiedLabel) {
+ val notVerifiedLabel = stringResource(R.string.label_client_unverified)
+ Modifier.clearAndSetSemantics { contentDescription = "$deviceName, $notVerifiedLabel" }
+ } else {
+ Modifier
+ }
Text(
style = MaterialTheme.wireTypography.body02,
color = MaterialTheme.wireColorScheme.onBackground,
- text = device.name.asString(),
+ text = deviceName,
modifier = Modifier
.wrapContentWidth()
.shimmerPlaceholder(visible = placeholder)
+ .then(semantic)
)
if (shouldShowVerifyLabel) {
if (shouldShowE2EIInfo) {
@@ -223,6 +234,16 @@ private fun ColumnScope.DeviceItemTexts(
Spacer(modifier = Modifier.height(MaterialTheme.wireDimensions.removeDeviceItemTitleVerticalPadding))
+ MLSDetails(device, placeholder)
+
+ ProteusDetails(device, placeholder)
+}
+
+@Composable
+private fun MLSDetails(
+ device: Device,
+ placeholder: Boolean
+) {
device.mlsClientIdentity?.let { identity ->
Text(
style = MaterialTheme.wireTypography.subline01,
@@ -238,7 +259,13 @@ private fun ColumnScope.DeviceItemTexts(
.shimmerPlaceholder(visible = placeholder)
)
}
+}
+@Composable
+private fun ProteusDetails(
+ device: Device,
+ placeholder: Boolean
+) {
val proteusDetails: String = if (!device.registrationTime.isNullOrBlank()) {
if (device.lastActiveInWholeWeeks != null) {
stringResource(
diff --git a/app/src/main/kotlin/com/wire/android/ui/common/WireDropDown.kt b/app/src/main/kotlin/com/wire/android/ui/common/WireDropDown.kt
index b2da6fc4d46..0ea54cc114c 100644
--- a/app/src/main/kotlin/com/wire/android/ui/common/WireDropDown.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/common/WireDropDown.kt
@@ -56,6 +56,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.onClick
+import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
@@ -168,6 +169,8 @@ private fun MenuPopUp(
hidePopUp: () -> Unit,
onChange: (selectedIndex: Int) -> Unit
) {
+ val dropdownDescription = stringResource(R.string.content_description_drop_down)
+
MaterialTheme(shapes = MaterialTheme.shapes.copy(extraSmall = shape)) {
// we want PopUp to cover the selection field, so we set this offset.
// "- 8.dp" is because DropdownMenu has inner top padding, which can't be changed,
@@ -182,6 +185,7 @@ private fun MenuPopUp(
.width(with(LocalDensity.current) { textFieldWidth.width.toDp() })
.background(color = MaterialTheme.wireColorScheme.secondaryButtonEnabled)
.border(width = 1.dp, color = borderColor, shape)
+ .semantics { paneTitle = dropdownDescription }
) {
SelectionField(
@@ -191,7 +195,7 @@ private fun MenuPopUp(
arrowRotation = arrowRotation,
modifier = Modifier.clickable(onClickLabel = stringResource(R.string.content_description_close_dropdown)) {
hidePopUp()
- },
+ }
)
List(items.size) { index ->
@@ -268,6 +272,7 @@ private fun DropdownItem(
onClick: () -> Unit
) {
val selectLabel = stringResource(R.string.content_description_select_label)
+ val closeDropdownLabel = stringResource(R.string.content_description_close_dropdown)
return DropdownMenuItem(
text = {
Text(
@@ -287,8 +292,12 @@ private fun DropdownItem(
onClick = onClick,
modifier = Modifier
.semantics {
- onClick(selectLabel) { false }
- if (isSelected) selected = true
+ if (isSelected) {
+ selected = true
+ onClick(closeDropdownLabel) { false }
+ } else {
+ onClick(selectLabel) { false }
+ }
}
.background(
color = if (isSelected) MaterialTheme.wireColorScheme.secondaryButtonSelected
diff --git a/app/src/main/kotlin/com/wire/android/ui/common/avatar/UserProfileAvatar.kt b/app/src/main/kotlin/com/wire/android/ui/common/avatar/UserProfileAvatar.kt
index e26a223f4dd..86581480232 100644
--- a/app/src/main/kotlin/com/wire/android/ui/common/avatar/UserProfileAvatar.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/common/avatar/UserProfileAvatar.kt
@@ -57,7 +57,10 @@ import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -291,12 +294,19 @@ private fun DefaultInitialsAvatar(
type: UserProfileAvatarType,
size: Dp,
modifier: Modifier = Modifier,
- contentDescription: String? = stringResource(R.string.content_description_user_avatar),
+ contentDescription: String? = null,
) {
+ val semantics = if (contentDescription != null) {
+ Modifier.semantics {
+ this.contentDescription = contentDescription
+ this.role = Role.Image
+ }
+ } else {
+ Modifier.clearAndSetSemantics { }
+ }
Box(
contentAlignment = Alignment.Center,
modifier = modifier
- .semantics { this.contentDescription = contentDescription ?: "" }
.size(size)
.clip(CircleShape)
.background(
@@ -312,6 +322,7 @@ private fun DefaultInitialsAvatar(
)
}
)
+ .then(semantics)
) {
Text(
text = nameBasedAvatar.initials,
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/ConversationParticipantItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/ConversationParticipantItem.kt
index 6f865c57870..317f56dbe2a 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/ConversationParticipantItem.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/details/participants/ConversationParticipantItem.kt
@@ -28,6 +28,8 @@ 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.contentDescription
+import androidx.compose.ui.semantics.semantics
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.model.Clickable
@@ -124,10 +126,18 @@ fun ConversationParticipantItem(
}
},
subtitle = {
+ val userName = processUsername(uiParticipant)
+ // Availability status should be called after username by TalkBack
+ val subtitleModifier = uiParticipant.avatarData.getAvailabilityStatusDescriptionId()?.let {
+ val contentDescription = stringResource(it)
+ Modifier.semantics { this.contentDescription = "$userName, $contentDescription" }
+ } ?: Modifier
+
HighlightSubtitle(
- subTitle = processUsername(uiParticipant),
+ subTitle = userName,
searchQuery = searchQuery,
- prefix = processUsernamePrefix(uiParticipant)
+ prefix = processUsernamePrefix(uiParticipant),
+ modifier = subtitleModifier
)
},
actions = {
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/HighLightSubtTitle.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/HighLightSubtTitle.kt
index 1ace87650f4..35c8a79c809 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/HighLightSubtTitle.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/HighLightSubtTitle.kt
@@ -51,7 +51,7 @@ fun HighlightSubtitle(
if (searchQuery != String.EMPTY && highlightIndexes.isNotEmpty()) {
Text(
- buildAnnotatedString {
+ text = buildAnnotatedString {
withStyle(
style = SpanStyle(
color = MaterialTheme.wireColorScheme.secondaryText,
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/SearchUsersAndServicesScreen.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/SearchUsersAndServicesScreen.kt
index ff3801d6bf9..743832d4877 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/SearchUsersAndServicesScreen.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/search/SearchUsersAndServicesScreen.kt
@@ -117,8 +117,11 @@ fun SearchUsersAndServicesScreen(
SearchPeopleScreenType.CONVERSATION_DETAILS ->
NavigationIconType.Close(R.string.content_description_add_participants_close)
- SearchPeopleScreenType.NEW_CONVERSATION -> NavigationIconType.Close()
- SearchPeopleScreenType.NEW_GROUP_CONVERSATION -> NavigationIconType.Back()
+ SearchPeopleScreenType.NEW_CONVERSATION ->
+ NavigationIconType.Close(R.string.content_description_new_conversation_close_btn)
+
+ SearchPeopleScreenType.NEW_GROUP_CONVERSATION ->
+ NavigationIconType.Back(R.string.content_description_new_group_conversation_back_btn)
},
onNavigationPressed = onClose
)
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/common/ConversationItemFactory.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/common/ConversationItemFactory.kt
index e7311dbe4ed..45db07413b1 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/common/ConversationItemFactory.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/conversationslist/common/ConversationItemFactory.kt
@@ -32,6 +32,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.semantics
import com.wire.android.R
import com.wire.android.model.Clickable
import com.wire.android.model.UserAvatarData
@@ -75,16 +76,24 @@ fun ConversationItemFactory(
) {
val openConversationOptionDescription = stringResource(R.string.content_description_conversation_details_more_btn)
val openUserProfileDescription = stringResource(R.string.content_description_open_user_profile_label)
+ val acceptOrIgnoreDescription = stringResource(R.string.content_description_accept_or_ignore_connection_label)
val openConversationDescription = stringResource(R.string.content_description_open_conversation_label)
val onConversationItemClick = remember(conversation) {
when (val lastEvent = conversation.lastMessageContent) {
- is UILastMessageContent.Connection -> Clickable(
- enabled = true,
- onClick = { openUserProfile(lastEvent.userId) },
- onLongClick = null,
- onClickDescription = openUserProfileDescription,
- onLongClickDescription = null
- )
+ is UILastMessageContent.Connection -> {
+ val onClickDescription = if (conversation.badgeEventType == BadgeEventType.ReceivedConnectionRequest) {
+ acceptOrIgnoreDescription
+ } else {
+ openUserProfileDescription
+ }
+ Clickable(
+ enabled = true,
+ onClick = { openUserProfile(lastEvent.userId) },
+ onLongClick = null,
+ onClickDescription = onClickDescription,
+ onLongClickDescription = null
+ )
+ }
else -> Clickable(
enabled = true,
@@ -97,7 +106,7 @@ fun ConversationItemFactory(
}
GeneralConversationItem(
- modifier = modifier,
+ modifier = modifier.semantics(mergeDescendants = true) { },
conversation = conversation,
isSelectable = isSelectableItem,
isChecked = isChecked,
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/MessageActions.kt b/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/MessageActions.kt
index 17f9ad78bbc..30f5621a889 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/MessageActions.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/MessageActions.kt
@@ -108,7 +108,7 @@ fun MessageEditActions(
WireTertiaryIconButton(
onButtonClicked = onEditCancelButtonClicked,
iconResource = R.drawable.ic_close,
- contentDescription = R.string.content_description_close_button,
+ contentDescription = R.string.label_close,
shape = CircleShape,
minSize = MaterialTheme.wireDimensions.buttonCircleMinSize,
minClickableSize = MaterialTheme.wireDimensions.buttonMinClickableSize,
diff --git a/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioButtons.kt b/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioButtons.kt
index 33e010dc9b1..487e0cc5171 100644
--- a/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioButtons.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/home/messagecomposer/recordaudio/RecordAudioButtons.kt
@@ -74,7 +74,7 @@ fun RecordAudioButtonClose(
WireTertiaryIconButton(
onButtonClicked = onClick,
iconResource = R.drawable.ic_close,
- contentDescription = R.string.content_description_close_button,
+ contentDescription = R.string.label_close,
shape = CircleShape,
minSize = MaterialTheme.wireDimensions.buttonCircleMinSize,
minClickableSize = MaterialTheme.wireDimensions.buttonMinClickableSize,
diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/dialog/LogoutOptionsDialog.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/dialog/LogoutOptionsDialog.kt
index 3992ff11ece..19e2fd9b6cc 100644
--- a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/dialog/LogoutOptionsDialog.kt
+++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/dialog/LogoutOptionsDialog.kt
@@ -54,7 +54,8 @@ fun LogoutOptionsDialog(
dismissButtonProperties = WireDialogButtonProperties(
onClick = dialogState::dismiss,
text = stringResource(id = R.string.label_cancel),
- state = WireButtonState.Default
+ state = WireButtonState.Default,
+ description = stringResource(R.string.dialog_logout_wipe_data_cancel_description)
),
optionButton1Properties = WireDialogButtonProperties(
onClick = remember(state) { { logout(state.shouldWipeData).also { dialogState.dismiss() } } },
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 826347c0d64..36c6d043c92 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -211,14 +211,18 @@
toggle setting
Go back to conversation details
Go back to conversation details
+ accept or ignore the request
open profile
open conversation
open service
change it
open link
Alert
+ Dropdown
close dropdown
open notification settings
+ Close new conversation view
+ Go back to new conversation view
Go back to new conversation view
Type group name
Conversation options
@@ -624,6 +628,7 @@
Clear Data?
Delete all your personal information and conversations on this device
+ Cancel logout
Set yourself to Available
You will appear as Available to other people. You will receive notifications for incoming calls and for messages according to the Notifications setting in each conversation.
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt
index b4e0ab63aa6..c16829ab2df 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/WireDialog.kt
@@ -41,6 +41,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
@@ -230,7 +231,7 @@ fun WireDialogContent(
@Composable
private fun TitleDialogSection(title: String, titleLoading: Boolean) {
Row(verticalAlignment = Alignment.CenterVertically) {
- Text(text = title, style = MaterialTheme.wireTypography.title02)
+ Text(text = title, style = MaterialTheme.wireTypography.title02, modifier = Modifier.semantics { heading() })
if (titleLoading) {
WireCircularProgressIndicator(progressColor = MaterialTheme.wireColorScheme.onBackground)
}
@@ -281,13 +282,13 @@ private fun WireDialogButtonProperties?.getButton(modifier: Modifier = Modifier)
Box(modifier = modifier) {
when (type) {
WireDialogButtonType.Primary ->
- WirePrimaryButton(onClick = onClick, text = text, state = state, loading = loading)
+ WirePrimaryButton(onClick = onClick, text = text, state = state, loading = loading, description = description)
WireDialogButtonType.Secondary ->
- WireSecondaryButton(onClick = onClick, text = text, state = state, loading = loading)
+ WireSecondaryButton(onClick = onClick, text = text, state = state, loading = loading, description = description)
WireDialogButtonType.Tertiary ->
- WireTertiaryButton(onClick = onClick, text = text, state = state, loading = loading)
+ WireTertiaryButton(onClick = onClick, text = text, state = state, loading = loading, description = description)
}
}
}
@@ -300,7 +301,8 @@ data class WireDialogButtonProperties(
val onClick: () -> Unit,
val state: WireButtonState = WireButtonState.Default,
val type: WireDialogButtonType = WireDialogButtonType.Secondary,
- val loading: Boolean = false
+ val loading: Boolean = false,
+ val description: String? = null
)
data class DialogTextSuffixLink(val linkText: String, val linkUrl: String)
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/ModalSheetHeaderItem.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/ModalSheetHeaderItem.kt
index 1f00db1864c..f43ac73b191 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/ModalSheetHeaderItem.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/bottomsheet/ModalSheetHeaderItem.kt
@@ -30,7 +30,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import com.wire.android.ui.common.dimensions
@@ -60,7 +60,7 @@ fun ModalSheetHeaderItem(header: MenuModalSheetHeader = MenuModalSheetHeader.Gon
Text(
text = header.title,
style = MaterialTheme.wireTypography.title02,
- modifier = Modifier.semantics { contentDescription = header.title }
+ modifier = Modifier.semantics { heading() }
)
}
WireDivider()
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt
index abda14ccdc2..0e441d40c33 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt
@@ -48,6 +48,8 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
@@ -89,7 +91,8 @@ fun WireButton(
vertical = MaterialTheme.wireDimensions.buttonVerticalContentPadding
),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- onClickDescription: String? = null
+ onClickDescription: String? = null,
+ description: String? = null
) {
val border = when {
borderWidth > 0.dp -> BorderStroke(width = borderWidth, color = colors.outlineColor(state).value)
@@ -122,7 +125,10 @@ fun WireButton(
placeable.place(centerX, centerY)
}
}
- .semantics { onClickDescription?.let { onClick(it) { false } } },
+ .semantics {
+ onClickDescription?.let { onClick(it) { false } }
+ description?.let { contentDescription = description }
+ },
enabled = state != WireButtonState.Disabled,
interactionSource = interactionSource,
elevation = elevation,
@@ -142,6 +148,7 @@ fun WireButton(
textStyle = textStyle,
state = state,
colors = colors,
+ semanticIgnoreText = !description.isNullOrEmpty()
)
}
}
@@ -159,6 +166,7 @@ private fun InnerButtonBox(
textStyle: TextStyle = MaterialTheme.wireTypography.button03,
state: WireButtonState = WireButtonState.Default,
colors: WireButtonColors = wirePrimaryButtonColors(),
+ semanticIgnoreText: Boolean = false
) {
val contentColor = colors.contentColor(state).value
val leadingItem: (@Composable () -> Unit) = { leadingIcon?.let { Tint(contentColor = contentColor, content = it) } }
@@ -196,7 +204,9 @@ private fun InnerButtonBox(
) {
if (leadingIconAlignment == IconAlignment.Center) leadingItem()
if (!text.isNullOrEmpty()) {
+ val modifier = if (semanticIgnoreText) Modifier.clearAndSetSemantics { } else Modifier
Text(
+ modifier = modifier,
text = text,
style = textStyle,
color = contentColor
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireItemLabel.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireItemLabel.kt
index 8a5ae5ec23b..51bf9059129 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireItemLabel.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireItemLabel.kt
@@ -33,6 +33,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
@@ -53,13 +54,14 @@ fun WireItemLabel(
contentDescription: String = text
) = Box(
modifier = modifier
- .border(width = 1.dp, color = MaterialTheme.wireColorScheme.divider, shape = shape)
+ .border(width = 1.dp, color = MaterialTheme.wireColorScheme.secondaryButtonDisabledOutline, shape = shape)
.padding(contentPadding)
- .semantics(mergeDescendants = true) { this.contentDescription = contentDescription }
+ .semantics { this.contentDescription = contentDescription }
.wrapContentWidth()
.wrapContentHeight(),
) {
Text(
+ modifier = Modifier.clearAndSetSemantics { },
text = text,
style = MaterialTheme.wireTypography.label02,
)
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryButton.kt
index 48b08791764..7b1dc2af159 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryButton.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryButton.kt
@@ -71,7 +71,8 @@ fun WirePrimaryButton(
vertical = MaterialTheme.wireDimensions.buttonVerticalContentPadding
),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- onClickDescription: String? = null
+ onClickDescription: String? = null,
+ description: String? = null
) = WireButton(
onClick = onClick,
loading = loading,
@@ -93,7 +94,8 @@ fun WirePrimaryButton(
contentPadding = contentPadding,
interactionSource = interactionSource,
modifier = modifier,
- onClickDescription = onClickDescription
+ onClickDescription = onClickDescription,
+ description = description
)
@Preview(name = "Default WirePrimaryButton")
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireSecondaryButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireSecondaryButton.kt
index 4045fa2d517..9fdf93fdb77 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireSecondaryButton.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireSecondaryButton.kt
@@ -70,7 +70,8 @@ fun WireSecondaryButton(
vertical = MaterialTheme.wireDimensions.buttonVerticalContentPadding
),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- onClickDescription: String? = null
+ onClickDescription: String? = null,
+ description: String? = null
) = WireButton(
onClick = onClick,
loading = loading,
@@ -92,7 +93,8 @@ fun WireSecondaryButton(
contentPadding = contentPadding,
interactionSource = interactionSource,
modifier = modifier,
- onClickDescription = onClickDescription
+ onClickDescription = onClickDescription,
+ description = description
)
@Preview(name = "Default WireSecondaryButton")
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryButton.kt
index bcd77ea67bb..80696e05ecf 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryButton.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryButton.kt
@@ -66,7 +66,8 @@ fun WireTertiaryButton(
vertical = MaterialTheme.wireDimensions.buttonVerticalContentPadding
),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- onClickDescription: String? = null
+ onClickDescription: String? = null,
+ description: String? = null
) = WireButton(
onClick = onClick,
loading = loading,
@@ -88,7 +89,8 @@ fun WireTertiaryButton(
contentPadding = contentPadding,
interactionSource = interactionSource,
modifier = modifier,
- onClickDescription = onClickDescription
+ onClickDescription = onClickDescription,
+ description = description
)
@Preview(name = "Default WireSecondaryButton")
diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/topappbar/NavigationIconButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/topappbar/NavigationIconButton.kt
index f0618adca53..dd0bb92a1b4 100644
--- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/topappbar/NavigationIconButton.kt
+++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/topappbar/NavigationIconButton.kt
@@ -45,10 +45,10 @@ fun BackNavigationIconButton(onBackButtonClick: () -> Unit) {
}
sealed class NavigationIconType(val icon: ImageVector, @StringRes open val contentDescription: Int) {
- data class Back(@StringRes override val contentDescription: Int = R.string.content_description_back_button) :
+ data class Back(@StringRes override val contentDescription: Int = R.string.content_description_left_arrow) :
NavigationIconType(Icons.AutoMirrored.Filled.ArrowBack, contentDescription)
- data class Close(@StringRes override val contentDescription: Int = R.string.content_description_close_button) :
+ data class Close(@StringRes override val contentDescription: Int = R.string.content_description_close) :
NavigationIconType(Icons.Filled.Close, contentDescription)
data object Menu : NavigationIconType(Icons.Filled.Menu, R.string.content_description_menu_button)
diff --git a/core/ui-common/src/main/res/values/strings.xml b/core/ui-common/src/main/res/values/strings.xml
index 88bc5693363..ae450d738d4 100644
--- a/core/ui-common/src/main/res/values/strings.xml
+++ b/core/ui-common/src/main/res/values/strings.xml
@@ -20,7 +20,9 @@
Please wait until the app is synchronized
Please wait until the Internet connection is restored
Back button
+ Go Back
Close button
+ Close
Main navigation
Drop down arrow
pending approval of connection request