diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 4b50946a..22ebf827 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}> {/* 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} /> ) } return ( {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} /> ))} @@ -392,48 +417,45 @@ function ExpandedAuthorsList({ }, [heightInterp, visible]) return ( - - {authors.map(author => ( - - - - - - - - - {sanitizeDisplayName( - author.profile.displayName || author.profile.handle, - )} -   - - {sanitizeHandle(author.profile.handle)} + + {visible && + authors.map(author => ( + + + + + + + + + {sanitizeDisplayName( + author.profile.displayName || author.profile.handle, + )} +   + + {sanitizeHandle(author.profile.handle)} + - - - - ))} + + + ))} ) } diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 865be455..ab6fd200 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 ( @@ -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 f23f4f7a..587b466a 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 (