From f97128e11c32e3d35328fa92f342df8cc3d71def Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 8 Feb 2024 17:16:54 -0500 Subject: [PATCH] Fixing accessibility issues raised on https://github.com/vitorpamplona/amethyst/issues/765 --- .../amethyst/ui/actions/NewPostView.kt | 32 +++---- .../amethyst/ui/buttons/ChannelFabColumn.kt | 2 +- .../ui/buttons/NewCommunityNoteButton.kt | 3 +- .../amethyst/ui/buttons/NewImageButton.kt | 8 +- .../amethyst/ui/buttons/NewNoteButton.kt | 3 +- .../ui/components/RobohashAsyncImage.kt | 2 +- .../amethyst/ui/navigation/AppBottomBar.kt | 10 +- .../amethyst/ui/navigation/AppTopBar.kt | 12 +-- .../amethyst/ui/navigation/Routes.kt | 10 ++ .../vitorpamplona/amethyst/ui/note/Icons.kt | 31 +++--- .../amethyst/ui/note/NoteCompose.kt | 2 +- .../amethyst/ui/note/ReactionsRow.kt | 4 +- .../amethyst/ui/note/RelayListBox.kt | 4 +- .../amethyst/ui/note/RelayListRow.kt | 10 +- .../amethyst/ui/note/UserProfilePicture.kt | 17 +++- .../amethyst/ui/note/UsernameDisplay.kt | 5 +- .../ui/screen/loggedIn/ProfileScreen.kt | 94 +++++++++++++++---- .../ui/screen/loggedOff/LoginScreen.kt | 5 +- app/src/main/res/values/strings.xml | 53 ++++++++++- 19 files changed, 228 insertions(+), 79 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index 7a9e7e45e..b2b9462ed 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -264,7 +264,7 @@ fun NewPostView( ) { Icon( painter = painterResource(R.drawable.relays), - contentDescription = null, + contentDescription = stringResource(id = R.string.relay_list_selector), modifier = Modifier.height(25.dp), tint = MaterialTheme.colorScheme.onBackground, ) @@ -1381,7 +1381,7 @@ private fun AddZapraiserButton( ) Icon( imageVector = Icons.Default.Bolt, - contentDescription = stringResource(R.string.zaps), + contentDescription = stringResource(R.string.add_zapraiser), modifier = Modifier .size(13.dp) @@ -1400,7 +1400,7 @@ private fun AddZapraiserButton( ) Icon( imageVector = Icons.Default.Bolt, - contentDescription = stringResource(R.string.zaps), + contentDescription = stringResource(R.string.cancel_zapraiser), modifier = Modifier .size(13.dp) @@ -1423,14 +1423,14 @@ fun AddGeoHash( if (!postViewModel.wantsToAddGeoHash) { Icon( imageVector = Icons.Default.LocationOff, - null, + contentDescription = stringResource(id = R.string.add_location), modifier = Modifier.size(20.dp), tint = MaterialTheme.colorScheme.onBackground, ) } else { Icon( imageVector = Icons.Default.LocationOn, - null, + contentDescription = stringResource(id = R.string.remove_location), modifier = Modifier.size(20.dp), tint = MaterialTheme.colorScheme.primary, ) @@ -1449,14 +1449,14 @@ private fun AddLnInvoiceButton( if (!isLnInvoiceActive) { Icon( imageVector = Icons.Default.CurrencyBitcoin, - null, + contentDescription = stringResource(id = R.string.add_bitcoin_invoice), modifier = Modifier.size(20.dp), tint = MaterialTheme.colorScheme.onBackground, ) } else { Icon( imageVector = Icons.Default.CurrencyBitcoin, - null, + contentDescription = stringResource(id = R.string.cancel_bitcoin_invoice), modifier = Modifier.size(20.dp), tint = BitcoinOrange, ) @@ -1480,7 +1480,7 @@ private fun ForwardZapTo( if (!postViewModel.wantsForwardZapTo) { Icon( imageVector = Icons.Default.Bolt, - contentDescription = stringResource(R.string.zaps), + contentDescription = stringResource(R.string.add_zap_split), modifier = Modifier .size(20.dp) @@ -1489,7 +1489,7 @@ private fun ForwardZapTo( ) Icon( imageVector = Icons.Default.ArrowForwardIos, - contentDescription = stringResource(R.string.zaps), + contentDescription = null, modifier = Modifier .size(13.dp) @@ -1499,7 +1499,7 @@ private fun ForwardZapTo( } else { Icon( imageVector = Icons.Outlined.Bolt, - contentDescription = stringResource(id = R.string.zaps), + contentDescription = stringResource(id = R.string.cancel_zap_split), modifier = Modifier .size(20.dp) @@ -1508,7 +1508,7 @@ private fun ForwardZapTo( ) Icon( imageVector = Icons.Outlined.ArrowForwardIos, - contentDescription = stringResource(id = R.string.zaps), + contentDescription = null, modifier = Modifier .size(13.dp) @@ -1538,7 +1538,7 @@ private fun AddClassifiedsButton( } else { Icon( imageVector = Icons.Default.Sell, - contentDescription = stringResource(id = R.string.classifieds), + contentDescription = stringResource(id = R.string.cancel_classifieds), modifier = Modifier.size(20.dp), tint = BitcoinOrange, ) @@ -1562,7 +1562,7 @@ private fun MarkAsSensitive( if (!postViewModel.wantsToMarkAsSensitive) { Icon( imageVector = Icons.Default.Visibility, - contentDescription = stringResource(R.string.content_warning), + contentDescription = stringResource(R.string.add_content_warning), modifier = Modifier .size(18.dp) @@ -1571,7 +1571,7 @@ private fun MarkAsSensitive( ) Icon( imageVector = Icons.Rounded.Warning, - contentDescription = stringResource(R.string.content_warning), + contentDescription = null, modifier = Modifier .size(10.dp) @@ -1581,7 +1581,7 @@ private fun MarkAsSensitive( } else { Icon( imageVector = Icons.Default.VisibilityOff, - contentDescription = stringResource(id = R.string.content_warning), + contentDescription = stringResource(id = R.string.remove_content_warning), modifier = Modifier .size(18.dp) @@ -1590,7 +1590,7 @@ private fun MarkAsSensitive( ) Icon( imageVector = Icons.Rounded.Warning, - contentDescription = stringResource(id = R.string.content_warning), + contentDescription = null, modifier = Modifier .size(10.dp) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/ChannelFabColumn.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/ChannelFabColumn.kt index a9a386ca2..38025fe1b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/ChannelFabColumn.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/ChannelFabColumn.kt @@ -123,7 +123,7 @@ fun ChannelFabColumn( ) { Icon( imageVector = Icons.Outlined.Add, - contentDescription = stringResource(R.string.messages_create_public_chat), + contentDescription = stringResource(R.string.messages_create_public_private_chat_desription), modifier = Modifier.size(26.dp), tint = Color.White, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewCommunityNoteButton.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewCommunityNoteButton.kt index 39d724aa4..13fd9bd13 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewCommunityNoteButton.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewCommunityNoteButton.kt @@ -33,6 +33,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note @@ -72,7 +73,7 @@ fun NewCommunityNoteButton( ) { Icon( painter = painterResource(R.drawable.ic_compose), - null, + contentDescription = stringResource(id = R.string.new_community_note), modifier = Modifier.size(26.dp), tint = Color.White, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewImageButton.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewImageButton.kt index 6ef527715..0c9c19fde 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewImageButton.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewImageButton.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -135,7 +136,7 @@ fun NewImageButton( ) { Icon( painter = painterResource(R.drawable.ic_compose), - null, + contentDescription = stringResource(id = R.string.new_short), modifier = Modifier.size(26.dp), tint = Color.White, ) @@ -153,7 +154,10 @@ private fun ShowProgress(postViewModel: NewMediaModel) { animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec, ) .value, - modifier = Size55Modifier.clip(CircleShape).background(MaterialTheme.colorScheme.background), + modifier = + Size55Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.background), strokeWidth = 5.dp, ) postViewModel.uploadingDescription.value?.let { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewNoteButton.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewNoteButton.kt index d128bed2e..0c0a17cc5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewNoteButton.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/buttons/NewNoteButton.kt @@ -33,6 +33,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.actions.NewPostView @@ -58,7 +59,7 @@ fun NewNoteButton( ) { Icon( painter = painterResource(R.drawable.ic_compose), - null, + contentDescription = stringResource(R.string.new_post), modifier = Modifier.size(26.dp), tint = Color.White, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt index d119568cc..cae0ea2aa 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt @@ -117,7 +117,7 @@ fun RobohashFallbackAsyncImage( Image( painter = base64Painter, - contentDescription = null, + contentDescription = contentDescription, modifier = modifier, alignment = alignment, contentScale = contentScale, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt index e2f173a71..8bae02284 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt @@ -49,6 +49,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavBackStackEntry @@ -180,7 +181,7 @@ private fun NotifiableIcon( Box(route.notifSize) { Icon( painter = painterResource(id = route.icon), - contentDescription = null, + contentDescription = stringResource(route.contentDescriptor), modifier = route.iconSize, tint = if (selected) MaterialTheme.colorScheme.primary else Color.Unspecified, ) @@ -216,7 +217,12 @@ private fun NotificationDotIcon(modifier: Modifier) { color = Color.White, textAlign = TextAlign.Center, fontSize = Font12SP, - modifier = remember { Modifier.wrapContentHeight().align(Alignment.TopEnd) }, + modifier = + remember { + Modifier + .wrapContentHeight() + .align(Alignment.TopEnd) + }, ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt index 825258813..f48443400 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt @@ -542,23 +542,17 @@ private fun LoggedInUserPictureDrawer( ) { val profilePicture by accountViewModel.account.userProfile().live().profilePictureChanges.observeAsState() - val pubkeyHex = remember { accountViewModel.userProfile().pubkeyHex } - - val automaticallyShowProfilePicture = - remember { - accountViewModel.settings.showProfilePictures.value - } IconButton( onClick = onClick, ) { RobohashFallbackAsyncImage( - robot = pubkeyHex, + robot = accountViewModel.userProfile().pubkeyHex, model = profilePicture, - contentDescription = stringResource(id = R.string.profile_image), + contentDescription = stringResource(id = R.string.your_profile_image), modifier = HeaderPictureModifier, contentScale = ContentScale.Crop, - loadProfilePicture = automaticallyShowProfilePicture, + loadProfilePicture = accountViewModel.settings.showProfilePictures.value, ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index 95a978070..03de452d3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -60,6 +60,7 @@ sealed class Route( val icon: Int, val notifSize: Modifier = Modifier.size(Size23dp), val iconSize: Modifier = Modifier.size(Size20dp), + val contentDescriptor: Int = R.string.route, val hasNewItems: (Account, Set) -> Boolean = { _, _ -> false }, @@ -80,6 +81,7 @@ sealed class Route( }, ) .toImmutableList(), + contentDescriptor = R.string.route_home, hasNewItems = { accountViewModel, newNotes -> HomeLatestItem.hasNewItems(accountViewModel, newNotes) }, @@ -89,18 +91,21 @@ sealed class Route( Route( route = "Global", icon = R.drawable.ic_globe, + contentDescriptor = R.string.route_global, ) object Search : Route( route = "Search", icon = R.drawable.ic_search, + contentDescriptor = R.string.route_search, ) object Video : Route( route = "Video", icon = R.drawable.ic_video, + contentDescriptor = R.string.route_video, ) object Discover : @@ -110,6 +115,7 @@ sealed class Route( // hasNewItems = { accountViewModel, newNotes -> // DiscoverLatestItem.hasNewItems(accountViewModel, newNotes) // }, + contentDescriptor = R.string.route_discover, ) object Notification : @@ -119,6 +125,7 @@ sealed class Route( hasNewItems = { accountViewModel, newNotes -> NotificationLatestItem.hasNewItems(accountViewModel, newNotes) }, + contentDescriptor = R.string.route_notifications, ) object Message : @@ -128,18 +135,21 @@ sealed class Route( hasNewItems = { accountViewModel, newNotes -> MessagesLatestItem.hasNewItems(accountViewModel, newNotes) }, + contentDescriptor = R.string.route_messages, ) object BlockedUsers : Route( route = "BlockedUsers", icon = R.drawable.ic_security, + contentDescriptor = R.string.route_security_filters, ) object Bookmarks : Route( route = "Bookmarks", icon = R.drawable.ic_bookmarks, + contentDescriptor = R.string.route_home, ) object Profile : diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt index 514e11796..465551a07 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/Icons.kt @@ -152,7 +152,7 @@ fun LikeIcon( ) { Icon( painter = painterResource(R.drawable.ic_like), - null, + contentDescription = stringResource(id = R.string.like_description), modifier = iconSizeModifier, tint = grayTint, ) @@ -165,7 +165,7 @@ fun RepostedIcon( ) { Icon( painter = painterResource(R.drawable.ic_retweeted), - null, + contentDescription = stringResource(id = R.string.boost_or_quote_description), modifier = modifier, tint = tint, ) @@ -198,10 +198,11 @@ fun ZappedIcon(modifier: Modifier) { fun ZapIcon( modifier: Modifier, tint: Color = Color.Unspecified, + contentDescriptor: Int = R.string.zap_description, ) { Icon( imageVector = Icons.Default.Bolt, - contentDescription = stringResource(R.string.zaps), + contentDescription = stringResource(contentDescriptor), tint = tint, modifier = modifier, ) @@ -244,20 +245,26 @@ fun OpenInNewIcon( } @Composable -fun ExpandLessIcon(modifier: Modifier) { +fun ExpandLessIcon( + modifier: Modifier, + contentDescriptor: Int, +) { Icon( imageVector = Icons.Default.ExpandLess, - null, + contentDescription = stringResource(id = contentDescriptor), modifier = modifier, tint = MaterialTheme.colorScheme.subtleButton, ) } @Composable -fun ExpandMoreIcon(modifier: Modifier) { +fun ExpandMoreIcon( + modifier: Modifier, + contentDescriptor: Int, +) { Icon( imageVector = Icons.Default.ExpandMore, - null, + contentDescription = stringResource(id = contentDescriptor), modifier = modifier, tint = MaterialTheme.colorScheme.subtleButton, ) @@ -270,7 +277,7 @@ fun CommentIcon( ) { Icon( painter = painterResource(R.drawable.ic_comment), - contentDescription = null, + contentDescription = stringResource(id = R.string.reply_description), modifier = iconSizeModifier, tint = tint, ) @@ -293,7 +300,7 @@ fun ViewCountIcon( fun PollIcon() { Icon( painter = painterResource(R.drawable.ic_poll), - null, + contentDescription = stringResource(id = R.string.poll), modifier = Size20Modifier, tint = MaterialTheme.colorScheme.onBackground, ) @@ -303,7 +310,7 @@ fun PollIcon() { fun RegularPostIcon() { Icon( painter = painterResource(R.drawable.ic_lists), - null, + contentDescription = stringResource(id = R.string.disable_poll), modifier = Size20Modifier, tint = MaterialTheme.colorScheme.onBackground, ) @@ -435,10 +442,10 @@ fun LinkIcon( } @Composable -fun VerticalDotsIcon() { +fun VerticalDotsIcon(contentDescriptor: Int? = null) { Icon( imageVector = Icons.Default.MoreVert, - null, + contentDescription = contentDescriptor?.let { stringResource(id = it) }, modifier = Size18Modifier, tint = MaterialTheme.colorScheme.placeholderText, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index cad8439b5..7abbabe58 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -2658,7 +2658,7 @@ fun MoreOptionsButton( modifier = Size24Modifier, onClick = enablePopup, ) { - VerticalDotsIcon() + VerticalDotsIcon(R.string.note_options) NoteDropDownMenu( baseNote, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index dfee68fc7..e95c26965 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -379,9 +379,9 @@ private fun RenderShowIndividualReactionsButton(wantsToSeeReactions: MutableStat label = "RenderShowIndividualReactionsButton", ) { if (it) { - ExpandLessIcon(modifier = Size22Modifier) + ExpandLessIcon(modifier = Size22Modifier, R.string.close_all_reactions_to_this_post) } else { - ExpandMoreIcon(modifier = Size22Modifier) + ExpandMoreIcon(modifier = Size22Modifier, R.string.open_all_reactions_to_this_post) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt index 3fdc8e644..184a44334 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt @@ -37,6 +37,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment +import androidx.compose.ui.res.stringResource +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer @@ -87,7 +89,7 @@ private fun ShowMoreRelaysButton(onClick: () -> Unit) { ) { Icon( imageVector = Icons.Default.ExpandMore, - null, + contentDescription = stringResource(id = R.string.expand_relay_list), modifier = ShowMoreRelaysButtonIconModifier, tint = MaterialTheme.colorScheme.placeholderText, ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt index 9891828db..3a5b95c8e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt @@ -119,7 +119,7 @@ fun ChatRelayExpandButton(onClick: () -> Unit) { ) { Icon( imageVector = Icons.Default.ChevronRight, - null, + contentDescription = stringResource(id = R.string.expand_relay_list), modifier = Size15Modifier, tint = MaterialTheme.colorScheme.placeholderText, ) @@ -156,7 +156,8 @@ fun RenderRelay( val clickableModifier = remember(relay) { - Modifier.padding(1.dp) + Modifier + .padding(1.dp) .size(Size15dp) .clickable( role = Role.Button, @@ -175,18 +176,21 @@ fun RenderRelay( url, exceptionMessage, ) + Nip11Retriever.ErrorCode.FAIL_TO_REACH_SERVER -> context.getString( R.string.relay_information_document_error_assemble_url, url, exceptionMessage, ) + Nip11Retriever.ErrorCode.FAIL_TO_PARSE_RESULT -> context.getString( R.string.relay_information_document_error_assemble_url, url, exceptionMessage, ) + Nip11Retriever.ErrorCode.FAIL_WITH_HTTP_STATUS -> context.getString( R.string.relay_information_document_error_assemble_url, @@ -223,7 +227,7 @@ fun RenderRelayIcon( RobohashFallbackAsyncImage( robot = displayUrl, model = iconUrl, - contentDescription = stringResource(id = R.string.relay_icon), + contentDescription = stringResource(id = R.string.relay_info, displayUrl), colorFilter = RelayIconFilter, modifier = iconModifier, loadProfilePicture = loadProfilePicture, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index ac9efe810..04a8f29d1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -340,10 +340,11 @@ fun BaseUserPicture( val myIconSize by remember(size) { derivedStateOf { size.div(3.5f) } } Box(outerModifier, contentAlignment = Alignment.TopEnd) { - LoadUserProfilePicture(baseUser) { userProfilePicture -> + LoadUserProfilePicture(baseUser) { userProfilePicture, userName -> InnerUserPicture( userHex = baseUser.pubkeyHex, userPicture = userProfilePicture, + userName = userName, size = size, modifier = innerModifier, accountViewModel = accountViewModel, @@ -357,17 +358,18 @@ fun BaseUserPicture( @Composable fun LoadUserProfilePicture( baseUser: User, - innerContent: @Composable (String?) -> Unit, + innerContent: @Composable (String?, String?) -> Unit, ) { - val userProfile by baseUser.live().profilePictureChanges.observeAsState(baseUser.profilePicture()) + val userProfile by baseUser.live().userMetadataInfo.observeAsState(baseUser.info) - innerContent(userProfile) + innerContent(userProfile?.profilePicture(), userProfile?.bestDisplayName() ?: userProfile?.bestDisplayName()) } @Composable fun InnerUserPicture( userHex: String, userPicture: String?, + userName: String?, size: Dp, modifier: Modifier, accountViewModel: AccountViewModel, @@ -386,7 +388,12 @@ fun InnerUserPicture( RobohashFallbackAsyncImage( robot = userHex, model = userPicture, - contentDescription = stringResource(id = R.string.profile_image), + contentDescription = + if (userName != null) { + stringResource(id = R.string.profile_image_of_user, userName) + } else { + stringResource(id = R.string.profile_image) + }, modifier = myImageModifier, contentScale = ContentScale.Crop, loadProfilePicture = automaticallyShowProfilePicture, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index 85ce58f12..48b7d5667 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -213,7 +213,10 @@ fun DrawPlayName(name: String) { @Composable fun DrawPlayNameIcon(onClick: () -> Unit) { IconButton(onClick = onClick, modifier = StdButtonSizeModifier) { - PlayIcon(modifier = StdButtonSizeModifier, tint = MaterialTheme.colorScheme.placeholderText) + PlayIcon( + modifier = StdButtonSizeModifier, + tint = MaterialTheme.colorScheme.placeholderText, + ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt index b1996662d..82ece50df 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt @@ -390,7 +390,10 @@ private fun RenderSurface( var tabsSize by remember { mutableStateOf(IntSize.Zero) } Column( - modifier = Modifier.fillMaxSize().onSizeChanged { columnSize = it }, + modifier = + Modifier + .fillMaxSize() + .onSizeChanged { columnSize = it }, ) { val coroutineScope = rememberCoroutineScope() val scrollState = rememberScrollState() @@ -403,7 +406,8 @@ private fun RenderSurface( Box( modifier = remember { - Modifier.verticalScroll(scrollState) + Modifier + .verticalScroll(scrollState) .nestedScroll( object : NestedScrollConnection { override fun onPreScroll( @@ -726,10 +730,17 @@ private fun ProfileHeader( DrawBanner(baseUser, accountViewModel) Box( - modifier = Modifier.padding(horizontal = 10.dp).size(40.dp).align(Alignment.TopEnd), + modifier = + Modifier + .padding(horizontal = 10.dp) + .size(40.dp) + .align(Alignment.TopEnd), ) { Button( - modifier = Modifier.size(30.dp).align(Alignment.Center), + modifier = + Modifier + .size(30.dp) + .align(Alignment.Center), onClick = { popupExpanded = true }, shape = ButtonBorder, colors = @@ -754,7 +765,11 @@ private fun ProfileHeader( } Column( - modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp).padding(top = 75.dp), + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 10.dp) + .padding(top = 75.dp), ) { Row( horizontalArrangement = Arrangement.SpaceBetween, @@ -789,7 +804,10 @@ private fun ProfileHeader( Spacer(Modifier.weight(1f)) Row( - modifier = Modifier.height(Size35dp).padding(bottom = 3.dp), + modifier = + Modifier + .height(Size35dp) + .padding(bottom = 3.dp), ) { MessageButton(baseUser, accountViewModel, nav) @@ -969,12 +987,15 @@ private fun DrawAdditionalInfo( ) IconButton( - modifier = Modifier.size(25.dp).padding(start = 5.dp), + modifier = + Modifier + .size(25.dp) + .padding(start = 5.dp), onClick = { clipboardManager.setText(AnnotatedString(user.pubkeyNpub())) }, ) { Icon( imageVector = Icons.Default.ContentCopy, - null, + contentDescription = stringResource(id = R.string.copy_npub_to_clipboard), modifier = Modifier.size(15.dp), tint = MaterialTheme.colorScheme.placeholderText, ) @@ -1000,7 +1021,7 @@ private fun DrawAdditionalInfo( ) { Icon( painter = painterResource(R.drawable.ic_qrcode), - null, + contentDescription = stringResource(id = R.string.show_npub_as_a_qr_code), modifier = Modifier.size(15.dp), tint = MaterialTheme.colorScheme.placeholderText, ) @@ -1059,7 +1080,10 @@ private fun DrawAdditionalInfo( text = AnnotatedString(identity.identity), onClick = { runCatching { uri.openUri(identity.toProofUrl()) } }, style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary), - modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp).weight(1f), + modifier = + Modifier + .padding(top = 1.dp, bottom = 1.dp, start = 5.dp) + .weight(1f), ) } } @@ -1131,7 +1155,10 @@ fun DisplayLNAddress( text = AnnotatedString(lud16), onClick = { zapExpanded = !zapExpanded }, style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary), - modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp).weight(1f), + modifier = + Modifier + .padding(top = 1.dp, bottom = 1.dp, start = 5.dp) + .weight(1f), ) } @@ -1223,12 +1250,21 @@ private fun WatchApp( appLogo?.let { Box( - remember { Modifier.size(Size35dp).clickable { nav("Note/${baseApp.idHex}") } }, + remember { + Modifier + .size(Size35dp) + .clickable { nav("Note/${baseApp.idHex}") } + }, ) { AsyncImage( model = appLogo, contentDescription = null, - modifier = remember { Modifier.size(Size35dp).clip(shape = CircleShape) }, + modifier = + remember { + Modifier + .size(Size35dp) + .clip(shape = CircleShape) + }, ) } } @@ -1343,7 +1379,11 @@ fun BadgeThumb( onClick: ((String) -> Unit)? = null, ) { Box( - remember { Modifier.width(size).height(size) }, + remember { + Modifier + .width(size) + .height(size) + }, ) { WatchAndRenderBadgeImage(baseNote, loadProfilePicture, size, pictureModifier, onClick) } @@ -1373,7 +1413,13 @@ private fun WatchAndRenderBadgeImage( RobohashAsyncImage( robot = "authornotfound", contentDescription = stringResource(R.string.unknown_author), - modifier = remember { pictureModifier.width(size).height(size).background(bgColor) }, + modifier = + remember { + pictureModifier + .width(size) + .height(size) + .background(bgColor) + }, ) } else { RobohashFallbackAsyncImage( @@ -1418,7 +1464,8 @@ fun DrawBanner( contentDescription = stringResource(id = R.string.profile_image), contentScale = ContentScale.FillWidth, modifier = - Modifier.fillMaxWidth() + Modifier + .fillMaxWidth() .height(125.dp) .combinedClickable( onClick = { zoomImageDialogOpen = true }, @@ -1438,7 +1485,10 @@ fun DrawBanner( painter = painterResource(R.drawable.profile_banner), contentDescription = stringResource(id = R.string.profile_banner), contentScale = ContentScale.FillWidth, - modifier = Modifier.fillMaxWidth().height(125.dp), + modifier = + Modifier + .fillMaxWidth() + .height(125.dp), ) } } @@ -1692,7 +1742,10 @@ private fun MessageButton( val scope = rememberCoroutineScope() Button( - modifier = Modifier.padding(horizontal = 3.dp).width(50.dp), + modifier = + Modifier + .padding(horizontal = 3.dp) + .width(50.dp), onClick = { scope.launch(Dispatchers.IO) { accountViewModel.createChatRoomFor(user) { nav("Room/$it") } } }, @@ -1727,7 +1780,10 @@ private fun InnerEditButtonPreview() { @Composable private fun InnerEditButton(onClick: () -> Unit) { Button( - modifier = Modifier.padding(horizontal = 3.dp).width(50.dp), + modifier = + Modifier + .padding(horizontal = 3.dp) + .width(50.dp), onClick = onClick, contentPadding = ZeroPadding, ) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt index 3fec84763..501347bf3 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt @@ -312,7 +312,10 @@ fun LoginPage( IconButton(onClick = { dialogOpen = true }) { Icon( painter = painterResource(R.drawable.ic_qrcode), - null, + contentDescription = + stringResource( + R.string.login_with_qr_code, + ), modifier = Modifier.size(24.dp), tint = MaterialTheme.colorScheme.primary, ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de1131a51..c8c0655a4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,7 +3,8 @@ Amethyst Debug Point to the QR Code Show QR - Profile Image + Profile Picture + Your Profile Picture Scan QR Show Anyway Post was muted or reported by @@ -523,6 +524,7 @@ Activate Public + New Public or Private Group Private To Subject @@ -543,6 +545,7 @@ When to load images Copy to clipboard + Copy npub to clipboard Copy URL to clipboard Copy Note ID to clipboard @@ -702,4 +705,52 @@ Server did not provide a URL after uploading Could not download uploaded media from the server Could not prepare local file to upload: %1$s + + Login with QR Code + Route + Home + Search + Discover + Messages + Notifications + Global + Shorts + Security Filters + + New Post + New Shorts: images or videos + New Community Note + + Open all reactions to this post + Close all reactions to this post + + Reply + Boost Or Quote + Like + Zap + + Profile Picture of %1$s + Relay %1$s + Expand relay list + Note options + Relay list selector + Poll + Disable Poll + + Bitcoin Invoice + Cancel Bitcoin Invoice + Cancel Sell an Item + + Zapraiser + Cancel Zapraiser + + Location + Remove Location + + Zap splits + Cancel Zap split + + Add content warning + Remove content warning + Show npub as a QR code