Skip to content

Commit

Permalink
Merge pull request #6897 from PatrykMis/a11y-fix-unlabeled-buttons-an…
Browse files Browse the repository at this point in the history
…droid

Fix unlabeled buttons in Android app
  • Loading branch information
Rawa committed Oct 3, 2024
2 parents 54f9af8 + fd11fe3 commit 0bdcf58
Show file tree
Hide file tree
Showing 36 changed files with 169 additions and 20 deletions.
1 change: 1 addition & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Line wrap the file at 100 chars. Th

### Fixed
- Fix VPN service being recreated multiple times when toggling certain options.
- Fix unlabeled icon buttons for basic accessibility with screen readers.


## [android/2024.4] - 2024-09-03
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
Expand Down Expand Up @@ -157,7 +158,7 @@ fun SwitchLocationButton(
) {
Icon(
painter = painterResource(R.drawable.icon_reconnect),
contentDescription = null,
contentDescription = stringResource(id = R.string.reconnect),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens

Expand Down Expand Up @@ -43,7 +45,7 @@ fun ThreeDotCell(
IconButton(onClick = onClickDots) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = null,
contentDescription = stringResource(id = R.string.custom_lists),
tint = textColor,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private fun ExpandableComposeCellBody(
) {
Icon(
imageVector = Icons.Default.Info,
contentDescription = null,
contentDescription = stringResource(id = R.string.more_information),
tint = MaterialTheme.colorScheme.onPrimary,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens
import net.mullvad.mullvadvpn.lib.theme.color.AlphaInactive
Expand Down Expand Up @@ -80,7 +82,7 @@ private fun InformationComposeCellBody(modifier: Modifier, onInfoClicked: (() ->
) {
Icon(
imageVector = Icons.Default.Info,
contentDescription = null,
contentDescription = stringResource(id = R.string.more_information),
tint = MaterialTheme.colorScheme.onPrimary,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
Expand Down Expand Up @@ -168,7 +169,11 @@ fun SwitchCellView(
.padding(horizontal = Dimens.miniPadding),
onClick = onInfoClicked,
) {
Icon(imageVector = Icons.Default.Info, contentDescription = null, tint = iconColor)
Icon(
imageVector = Icons.Default.Info,
contentDescription = stringResource(id = R.string.more_information),
tint = iconColor,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import net.mullvad.mullvadvpn.R

@Composable
@Preview
Expand All @@ -29,6 +31,12 @@ private fun PreviewChevron() {
fun ExpandChevron(modifier: Modifier = Modifier, color: Color, isExpanded: Boolean) {

val degree = remember(isExpanded) { if (isExpanded) UP_ROTATION else DOWN_ROTATION }
val stateLabel =
if (isExpanded) {
stringResource(id = R.string.collapse)
} else {
stringResource(id = R.string.expand)
}
val animatedRotation =
animateFloatAsState(
targetValue = degree,
Expand All @@ -38,7 +46,7 @@ fun ExpandChevron(modifier: Modifier = Modifier, color: Color, isExpanded: Boole

Icon(
imageVector = Icons.Default.KeyboardArrowDown,
contentDescription = null,
contentDescription = stateLabel,
tint = color,
modifier = modifier.rotate(animatedRotation.value),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,35 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import net.mullvad.mullvadvpn.R

@Composable
fun NavigateBackIconButton(modifier: Modifier = Modifier, onNavigateBack: () -> Unit) {
IconButton(onClick = onNavigateBack, modifier = modifier) {
Icon(imageVector = Icons.AutoMirrored.Default.ArrowBack, contentDescription = null)
Icon(
imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = stringResource(id = R.string.back),
)
}
}

@Composable
fun NavigateBackDownIconButton(onNavigateBack: () -> Unit) {
IconButton(onClick = onNavigateBack) {
Icon(imageVector = Icons.Default.ArrowDownward, contentDescription = null)
Icon(
imageVector = Icons.Default.ArrowDownward,
contentDescription = stringResource(id = R.string.back),
)
}
}

@Composable
fun NavigateCloseIconButton(onNavigateClose: () -> Unit) {
IconButton(onClick = onNavigateClose) {
Icon(imageVector = Icons.Default.Close, contentDescription = null)
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(id = R.string.close),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private fun Notification(notificationBannerData: NotificationData) {
Icon(
modifier = Modifier.padding(Dimens.notificationIconPadding),
imageVector = it.icon,
contentDescription = null,
contentDescription = it.contentDescription,
tint = MaterialTheme.colorScheme.onSurface,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ data class NotificationData(
) : this(title, message?.let { AnnotatedString(it) }, statusLevel, action)
}

data class NotificationAction(val icon: ImageVector, val onClick: (() -> Unit))
data class NotificationAction(
val icon: ImageVector,
val onClick: (() -> Unit),
val contentDescription: String,
)

@Composable
fun InAppNotification.toNotificationData(
Expand Down Expand Up @@ -64,7 +68,12 @@ fun InAppNotification.toNotificationData(
)
),
statusLevel = StatusLevel.Info,
action = NotificationAction(Icons.Default.Clear, onDismissNewDevice),
action =
NotificationAction(
Icons.Default.Clear,
onDismissNewDevice,
stringResource(id = R.string.dismiss),
),
)
is InAppNotification.AccountExpiry ->
NotificationData(
Expand All @@ -74,7 +83,11 @@ fun InAppNotification.toNotificationData(
action =
if (isPlayBuild) null
else
NotificationAction(Icons.AutoMirrored.Default.OpenInNew, onClickShowAccount),
NotificationAction(
Icons.AutoMirrored.Default.OpenInNew,
onClickShowAccount,
stringResource(id = R.string.open_url),
),
)
InAppNotification.TunnelStateBlocked ->
NotificationData(
Expand All @@ -93,6 +106,7 @@ fun InAppNotification.toNotificationData(
NotificationAction(
Icons.AutoMirrored.Default.OpenInNew,
onClickUpdateVersion,
stringResource(id = R.string.open_url),
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ private fun DeviceNameRow(deviceName: String, onInfoClick: () -> Unit) {
IconButton(onClick = onInfoClick) {
Icon(
imageVector = Icons.Default.Info,
contentDescription = null,
contentDescription = stringResource(id = R.string.more_information),
tint = MaterialTheme.colorScheme.onSurface,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private fun TopBar(onBackClick: () -> Unit) {
IconButton(onClick = onBackClick) {
Icon(
imageVector = Icons.AutoMirrored.Default.ArrowBack,
contentDescription = null,
contentDescription = stringResource(id = R.string.back),
tint = MaterialTheme.colorScheme.onSurface,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ fun ImportOverridesByTextScreen(onNavigateBack: () -> Unit, onImportClicked: (St
title = stringResource(R.string.import_overrides_text_title),
navigationIcon = {
IconButton(onClick = onNavigateBack) {
Icon(imageVector = Icons.Default.Close, contentDescription = null)
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(id = R.string.close),
)
}
},
actions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ private fun SelectLocationTopBar(onBackClick: () -> Unit, onFilterClick: () -> U
Icon(
imageVector = Icons.Default.Close,
tint = MaterialTheme.colorScheme.onSurface,
contentDescription = null,
contentDescription = stringResource(id = R.string.back),
)
}
Text(
Expand All @@ -504,7 +504,7 @@ private fun SelectLocationTopBar(onBackClick: () -> Unit, onFilterClick: () -> U
IconButton(onClick = onFilterClick) {
Icon(
imageVector = Icons.Default.FilterList,
contentDescription = null,
contentDescription = stringResource(id = R.string.filter),
tint = MaterialTheme.colorScheme.onSurface,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,19 @@ private fun TopBar(
onClick = { clipboardHandle(state.text(), clipboardToastMessage) },
modifier = Modifier.focusProperties { down = FocusRequester.Cancel },
) {
Icon(imageVector = Icons.Default.ContentCopy, contentDescription = null)
Icon(
imageVector = Icons.Default.ContentCopy,
contentDescription = stringResource(id = R.string.copy),
)
}
IconButton(
onClick = { scope.launch { shareText(context, state.text()) } },
modifier = Modifier.focusProperties { down = FocusRequester.Cancel },
) {
Icon(imageVector = Icons.Default.Share, contentDescription = null)
Icon(
imageVector = Icons.Default.Share,
contentDescription = stringResource(id = R.string.share),
)
}
},
)
Expand Down
4 changes: 4 additions & 0 deletions android/lib/resource/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<string name="cancel">Annuller</string>
<string name="changes_dialog_subtitle">Ændringer i denne version:</string>
<string name="cipher">Chiffer</string>
<string name="close">Luk</string>
<string name="confirm_local_dns">Den lokale DNS-server fungerer ikke, medmindre du aktiverer \"Lokal netværksdeling\" under Indstillinger.</string>
<string name="confirm_no_email">Du er ved at sende rapporten om problemet, men har ikke angivet hvordan vi kan kontakte dig. Hvis du ønsker et svar på din rapport, skal du indtaste en e-mail-adresse.</string>
<string name="confirm_removal">Ja, log enhed af</string>
Expand Down Expand Up @@ -193,6 +194,7 @@
<string name="max_devices_resolved_title">Super!</string>
<string name="max_devices_warning_description">Log ud af mindst én ved at fjerne den fra listen nedenfor. Du kan finde det tilsvarende enhedsnavn under enhedens kontoindstillinger.</string>
<string name="max_devices_warning_title">For mange enheder</string>
<string name="more_information">Mere information</string>
<string name="mullvad_account_number">Mullvad-kontonummer</string>
<string name="mullvad_owned_only">Kun ejet af Mullvad</string>
<string name="name">Navn</string>
Expand All @@ -213,6 +215,7 @@
<string name="obfuscation_title">WireGuard-tilsløring</string>
<string name="off">Fra</string>
<string name="on">Til</string>
<string name="open_url">Åbn URL</string>
<string name="out_address">Ud</string>
<string name="out_of_time">Tid udløbet</string>
<string name="overrides_cleared">Tilsidesættelser ryddet</string>
Expand Down Expand Up @@ -244,6 +247,7 @@
<string name="quantum_resistant_info_first_paragaph">Denne funktion gør WireGuard-tunnelen modstandsdygtig over for potentielle angreb fra kvantecomputere.</string>
<string name="quantum_resistant_info_second_paragaph">Det gør den ved at udføre en ekstra nøgleudveksling ved hjælp af en kvantesikker algoritme og blande resultatet med WireGuards almindelige kryptering. Dette ekstra trin bruger cirka 500 kB trafik, hver gang en ny tunnel etableres.</string>
<string name="quantum_resistant_title">Kvante-modstandsdygtig tunnel</string>
<string name="reconnect">Genopret forbindelse</string>
<string name="redeem">Indløs</string>
<string name="redeem_voucher">Indløs kupon</string>
<string name="remove_button">Fjern</string>
Expand Down
4 changes: 4 additions & 0 deletions android/lib/resource/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<string name="cancel">Abbrechen</string>
<string name="changes_dialog_subtitle">Änderungen in dieser Version:</string>
<string name="cipher">Chiffre</string>
<string name="close">Schließen</string>
<string name="confirm_local_dns">Der lokale DNS-Server wird nicht funktionieren, solange „Teilen im lokalen Netzwerk“ nicht in den Einstellungen aktiviert ist.</string>
<string name="confirm_no_email">Sie wollen einen Problembericht senden, ohne uns die Möglichkeit zu geben, Sie zu erreichen. Wenn Sie sich eine Antwort zu Ihrem Problem wünschen, müssen Sie eine E-Mail-Adresse eingeben.</string>
<string name="confirm_removal">Ja, von Gerät abmelden</string>
Expand Down Expand Up @@ -193,6 +194,7 @@
<string name="max_devices_resolved_title">Super!</string>
<string name="max_devices_warning_description">Bitte melden Sie sich von mindestens einem Gerät ab, indem Sie es aus der Liste unten entfernen. Sie finden den entsprechenden Gerätenamen unter den Kontoeinstellungen des Geräts.</string>
<string name="max_devices_warning_title">Zu viele Geräte</string>
<string name="more_information">Weitere Informationen</string>
<string name="mullvad_account_number">Mullvad-Kontonummer</string>
<string name="mullvad_owned_only">Nur im Besitz von Mullvad</string>
<string name="name">Name</string>
Expand All @@ -213,6 +215,7 @@
<string name="obfuscation_title">WireGuard-Verschleierung</string>
<string name="off">Aus</string>
<string name="on">Ein</string>
<string name="open_url">URL öffnen</string>
<string name="out_address">Ausgehend</string>
<string name="out_of_time">Zeit abgelaufen</string>
<string name="overrides_cleared">Überschreibungen entfernt</string>
Expand Down Expand Up @@ -244,6 +247,7 @@
<string name="quantum_resistant_info_first_paragaph">Diese Funktion macht den WireGuard-Tunnel resistent gegen mögliche Angriffe von Quantencomputern.</string>
<string name="quantum_resistant_info_second_paragaph">Dazu wird ein zusätzlicher Schlüsselaustausch mit einem quantensicheren Algorithmus durchgeführt und das Ergebnis mit der regulären Verschlüsselung von WireGuard vermischt. Dieser zusätzliche Schritt verbraucht jedes Mal, wenn ein neuer Tunnel aufgebaut wird, etwa 500 KiB an Datenverkehr.</string>
<string name="quantum_resistant_title">Quantenresistenter Tunnel</string>
<string name="reconnect">Erneut verbinden</string>
<string name="redeem">Einlösen</string>
<string name="redeem_voucher">Gutschein einlösen</string>
<string name="remove_button">Entfernen</string>
Expand Down
4 changes: 4 additions & 0 deletions android/lib/resource/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<string name="cancel">Cancelar</string>
<string name="changes_dialog_subtitle">Cambios en esta versión:</string>
<string name="cipher">Cifrado</string>
<string name="close">Cerrar</string>
<string name="confirm_local_dns">El servidor DNS local no funcionará a no ser que habilite la opción «Uso compartido de red local» en Preferencias.</string>
<string name="confirm_no_email">Va a enviar el informe de problemas sin indicar una forma de contacto. Para obtener una respuesta sobre el informe, necesita especificar su dirección de correo electrónico.</string>
<string name="confirm_removal">Sí, cerrar sesión</string>
Expand Down Expand Up @@ -193,6 +194,7 @@
<string name="max_devices_resolved_title">¡Genial!</string>
<string name="max_devices_warning_description">Cierre la sesión como mínimo en un dispositivo (para hacerlo, quítelo de la lista siguiente). Consulte el nombre del dispositivo en la configuración de la cuenta del dispositivo.</string>
<string name="max_devices_warning_title">Demasiados dispositivos</string>
<string name="more_information">Más información</string>
<string name="mullvad_account_number">Número de cuenta de Mullvad</string>
<string name="mullvad_owned_only">Solo propiedad de Mullvad</string>
<string name="name">Nombre</string>
Expand All @@ -213,6 +215,7 @@
<string name="obfuscation_title">Ofuscación de WireGuard</string>
<string name="off">Desactivado</string>
<string name="on">Activado</string>
<string name="open_url">Abrir URL</string>
<string name="out_address">Salida</string>
<string name="out_of_time">Tiempo agotado</string>
<string name="overrides_cleared">Anulaciones borradas</string>
Expand Down Expand Up @@ -244,6 +247,7 @@
<string name="quantum_resistant_info_first_paragaph">Esta característica permite que el túnel de WireGuard resista posibles ataques de ordenadores cuánticos.</string>
<string name="quantum_resistant_info_second_paragaph">Lo hace al realizar un intercambio de claves adicional usando un algoritmo cuántico seguro y combinando el resultado en el cifrado normal de WireGuard. Este paso extra utiliza aproximadamente 500 kiB de tráfico cada vez que se establece un nuevo túnel.</string>
<string name="quantum_resistant_title">Túnel con resistencia cuántica</string>
<string name="reconnect">Reconectar</string>
<string name="redeem">Canjear</string>
<string name="redeem_voucher">Canjear cupón</string>
<string name="remove_button">Quitar</string>
Expand Down
Loading

0 comments on commit 0bdcf58

Please sign in to comment.