diff options
author | Hailey <me@haileyok.com> | 2024-05-31 13:02:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-31 21:02:18 +0100 |
commit | 708a80e7a7ca1199247a8c3ff4552d3957ea1c7b (patch) | |
tree | 2543d97769031c2e86ca08e12af7c2a92f4ea74d /src | |
parent | b51640fbc099a1e9df1430b5a05bf913495008b7 (diff) | |
download | voidsky-708a80e7a7ca1199247a8c3ff4552d3957ea1c7b.tar.zst |
fix accessibility label in notifications (#4305)
* fix accessibility label in notifications * add accessibility options to expand post * inherit from outside, but always include `activate` * include option to disable label/hint on previewable avatar * fix hidden elements still being read on voiceover * make it work for followers too * extract variable * fix hint * update wording elsewhere
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/notifications/FeedItem.tsx | 118 | ||||
-rw-r--r-- | src/view/com/util/Link.tsx | 15 | ||||
-rw-r--r-- | src/view/com/util/UserAvatar.tsx | 9 |
3 files changed, 93 insertions, 49 deletions
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 4b50946a4..22ebf8271 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -194,10 +194,36 @@ let FeedItem = ({ ]} href={itemHref} noFeedback - accessible={ - (item.type === 'post-like' && authors.length === 1) || - item.type === 'repost' + accessible={!isAuthorsExpanded} + accessibilityActions={ + authors.length > 1 + ? [ + { + name: 'toggleAuthorsExpanded', + label: isAuthorsExpanded + ? _(msg`Collapse list of users`) + : _(msg`Expand list of users`), + }, + ] + : [ + { + name: 'viewProfile', + label: _( + msg`View ${ + authors[0].profile.displayName || authors[0].profile.handle + }'s profile`, + ), + }, + ] } + onAccessibilityAction={e => { + if (e.nativeEvent.actionName === 'activate') { + onBeforePress() + } + if (e.nativeEvent.actionName === 'toggleAuthorsExpanded') { + onToggleAuthorsExpanded() + } + }} onBeforePress={onBeforePress}> <View style={[styles.layoutIcon, a.pr_sm]}> {/* TODO: Prevent conditional rendering and move toward composable @@ -332,16 +358,14 @@ function CondensedAuthorsList({ profile={authors[0].profile} moderation={authors[0].moderation.ui('avatar')} type={authors[0].profile.associated?.labeler ? 'labeler' : 'user'} + accessible={false} /> </View> ) } return ( <TouchableOpacity - accessibilityLabel={_(msg`Show users`)} - accessibilityHint={_( - msg`Opens an expanded list of users in this notification`, - )} + accessibilityRole="none" onPress={onToggleAuthorsExpanded}> <View style={styles.avis}> {authors.slice(0, MAX_AUTHORS).map(author => ( @@ -351,6 +375,7 @@ function CondensedAuthorsList({ profile={author.profile} moderation={author.moderation.ui('avatar')} type={author.profile.associated?.labeler ? 'labeler' : 'user'} + accessible={false} /> </View> ))} @@ -392,48 +417,45 @@ function ExpandedAuthorsList({ }, [heightInterp, visible]) return ( - <Animated.View - style={[ - heightStyle, - styles.overflowHidden, - visible ? s.mb10 : undefined, - ]}> - {authors.map(author => ( - <NewLink - key={author.profile.did} - label={_(msg`See profile`)} - to={makeProfileLink({ - did: author.profile.did, - handle: author.profile.handle, - })} - style={styles.expandedAuthor}> - <View style={styles.expandedAuthorAvi}> - <ProfileHoverCard did={author.profile.did}> - <UserAvatar - size={35} - avatar={author.profile.avatar} - moderation={author.moderation.ui('avatar')} - type={author.profile.associated?.labeler ? 'labeler' : 'user'} - /> - </ProfileHoverCard> - </View> - <View style={s.flex1}> - <Text - type="lg-bold" - numberOfLines={1} - style={pal.text} - lineHeight={1.2}> - {sanitizeDisplayName( - author.profile.displayName || author.profile.handle, - )} - - <Text style={[pal.textLight]} lineHeight={1.2}> - {sanitizeHandle(author.profile.handle)} + <Animated.View style={[heightStyle, styles.overflowHidden]}> + {visible && + authors.map(author => ( + <NewLink + key={author.profile.did} + label={author.profile.displayName || author.profile.handle} + accessibilityHint={_(msg`Opens this profile`)} + to={makeProfileLink({ + did: author.profile.did, + handle: author.profile.handle, + })} + style={styles.expandedAuthor}> + <View style={styles.expandedAuthorAvi}> + <ProfileHoverCard did={author.profile.did}> + <UserAvatar + size={35} + avatar={author.profile.avatar} + moderation={author.moderation.ui('avatar')} + type={author.profile.associated?.labeler ? 'labeler' : 'user'} + /> + </ProfileHoverCard> + </View> + <View style={s.flex1}> + <Text + type="lg-bold" + numberOfLines={1} + style={pal.text} + lineHeight={1.2}> + {sanitizeDisplayName( + author.profile.displayName || author.profile.handle, + )} + + <Text style={[pal.textLight]} lineHeight={1.2}> + {sanitizeHandle(author.profile.handle)} + </Text> </Text> - </Text> - </View> - </NewLink> - ))} + </View> + </NewLink> + ))} </Animated.View> ) } diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 865be4552..ab6fd200f 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -64,6 +64,8 @@ export const Link = memo(function Link({ anchorNoUnderline, navigationAction, onBeforePress, + accessibilityActions, + onAccessibilityAction, ...props }: Props) { const t = useTheme() @@ -89,6 +91,11 @@ export const Link = memo(function Link({ [closeModal, navigation, navigationAction, href, openLink, onBeforePress], ) + const accessibilityActionsWithActivate = [ + ...(accessibilityActions || []), + {name: 'activate', label: title}, + ] + if (noFeedback) { return ( <WebAuxClickWrapper> @@ -97,6 +104,14 @@ export const Link = memo(function Link({ onPress={onPress} accessible={accessible} accessibilityRole="link" + accessibilityActions={accessibilityActionsWithActivate} + onAccessibilityAction={e => { + if (e.nativeEvent.actionName === 'activate') { + onPress() + } else { + onAccessibilityAction?.(e) + } + }} {...props} android_ripple={{ color: t.atoms.bg_contrast_25.backgroundColor, diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index f23f4f7a5..587b466a3 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -53,6 +53,7 @@ interface PreviewableUserAvatarProps extends BaseUserAvatarProps { profile: AppBskyActorDefs.ProfileViewBasic disableHoverCard?: boolean onBeforePress?: () => void + accessible?: boolean } const BLUR_AMOUNT = isWeb ? 5 : 100 @@ -386,6 +387,7 @@ let PreviewableUserAvatar = ({ profile, disableHoverCard, onBeforePress, + accessible = true, ...rest }: PreviewableUserAvatarProps): React.ReactNode => { const {_} = useLingui() @@ -399,7 +401,12 @@ let PreviewableUserAvatar = ({ return ( <ProfileHoverCard did={profile.did} disable={disableHoverCard}> <Link - label={_(msg`See profile`)} + label={ + accessible + ? _(msg`${profile.displayName || profile.handle}'s avatar`) + : undefined + } + accessibilityHint={accessible ? _(msg`Opens this profile`) : undefined} to={makeProfileLink({ did: profile.did, handle: profile.handle, |