about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-07-03 15:57:53 -0500
committerGitHub <noreply@github.com>2023-07-03 15:57:53 -0500
commitbc55241c9ae731f633f8b93a9b7eac7635070148 (patch)
tree2f75cf5fc31bb8214f848a4326c1af731000b842 /src
parent0163ba0af8cd42e2a76b3ae66efc0777afdc2544 (diff)
downloadvoidsky-bc55241c9ae731f633f8b93a9b7eac7635070148.tar.zst
[APP-724] Collection of accessibility fixes (#949)
* Fix: include alt text on the web lightbox image

* a11y: Dont read the 'ALT' label

* a11y: remove a wrapper behavior from posts

This appears to have been introduced with the goal of creating meta
actions on posts, but the behavior seems counter-productive. The
accessibility inspector was unable to access individual items within
the post and therefore most content was simply skipped.

There may be a way to support the post actions without losing the
ability to access the inner elements but I couldnt find it. -prf

* a11y: apply alt tags to image wrappers so they get read

* a11y: set Link accessibilityLabel to the title if none set

* a11y: skip the SANDBOX watermark

* a11y: improve post meta to not read UI and give a useful date

* ally: improve post controls

* a11y: add labels to lightbox images on mobile

* fix types
Diffstat (limited to 'src')
-rw-r--r--src/view/com/composer/photos/Gallery.tsx4
-rw-r--r--src/view/com/lightbox/ImageViewing/@types/index.ts4
-rw-r--r--src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx2
-rw-r--r--src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx4
-rw-r--r--src/view/com/lightbox/Lightbox.tsx4
-rw-r--r--src/view/com/lightbox/Lightbox.web.tsx2
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx46
-rw-r--r--src/view/com/post/Post.tsx41
-rw-r--r--src/view/com/posts/FeedItem.tsx42
-rw-r--r--src/view/com/util/Link.tsx12
-rw-r--r--src/view/com/util/PostMeta.tsx14
-rw-r--r--src/view/com/util/PostSandboxWarning.tsx5
-rw-r--r--src/view/com/util/forms/DropdownButton.tsx12
-rw-r--r--src/view/com/util/images/AutoSizedImage.tsx9
-rw-r--r--src/view/com/util/images/Gallery.tsx6
-rw-r--r--src/view/com/util/moderation/PostHider.tsx3
-rw-r--r--src/view/com/util/post-ctrls/PostCtrls.tsx9
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.tsx5
-rw-r--r--src/view/com/util/post-embeds/index.tsx4
19 files changed, 80 insertions, 148 deletions
diff --git a/src/view/com/composer/photos/Gallery.tsx b/src/view/com/composer/photos/Gallery.tsx
index c226d25cc..6dba2f011 100644
--- a/src/view/com/composer/photos/Gallery.tsx
+++ b/src/view/com/composer/photos/Gallery.tsx
@@ -89,7 +89,9 @@ export const Gallery = observer(function ({gallery}: Props) {
                 openAltTextModal(store, image)
               }}
               style={[styles.altTextControl, altTextControlStyle]}>
-              <Text style={styles.altTextControlLabel}>ALT</Text>
+              <Text style={styles.altTextControlLabel} accessible={false}>
+                ALT
+              </Text>
               {image.altText.length > 0 ? (
                 <FontAwesomeIcon
                   icon="check"
diff --git a/src/view/com/lightbox/ImageViewing/@types/index.ts b/src/view/com/lightbox/ImageViewing/@types/index.ts
index 4a08e2394..8400e12e4 100644
--- a/src/view/com/lightbox/ImageViewing/@types/index.ts
+++ b/src/view/com/lightbox/ImageViewing/@types/index.ts
@@ -6,8 +6,6 @@
  *
  */
 
-import {ImageURISource, ImageRequireSource} from 'react-native'
-
 export type Dimensions = {
   width: number
   height: number
@@ -18,4 +16,4 @@ export type Position = {
   y: number
 }
 
-export type ImageSource = ImageURISource | ImageRequireSource
+export type ImageSource = {uri: string; alt?: string}
diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx
index 01a53ff6f..b900f9afe 100644
--- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx
+++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.android.tsx
@@ -133,6 +133,8 @@ const ImageItem = ({
         source={imageSrc}
         style={imageStylesWithOpacity}
         onLoad={onLoaded}
+        accessibilityLabel={imageSrc.alt}
+        accessibilityHint=""
       />
       {(!isLoaded || !imageDimensions) && <ImageLoading />}
     </ScrollView>
diff --git a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx
index 658735724..ebf0b1d28 100644
--- a/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx
+++ b/src/view/com/lightbox/ImageViewing/components/ImageItem/ImageItem.ios.tsx
@@ -128,7 +128,9 @@ const ImageItem = ({
           onPress={doubleTapToZoomEnabled ? handleDoubleTap : undefined}
           onLongPress={onLongPressHandler}
           delayLongPress={delayLongPress}
-          accessibilityRole="image">
+          accessibilityRole="image"
+          accessibilityLabel={imageSrc.alt}
+          accessibilityHint="">
           <Animated.Image
             source={imageSrc}
             style={imageStylesWithOpacity}
diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx
index b496e0d95..072bfebfa 100644
--- a/src/view/com/lightbox/Lightbox.tsx
+++ b/src/view/com/lightbox/Lightbox.tsx
@@ -109,7 +109,7 @@ export const Lightbox = observer(function Lightbox() {
     const opts = store.shell.activeLightbox as models.ProfileImageLightbox
     return (
       <ImageView
-        images={[{uri: opts.profileView.avatar}]}
+        images={[{uri: opts.profileView.avatar || ''}]}
         imageIndex={0}
         visible
         onRequestClose={onClose}
@@ -120,7 +120,7 @@ export const Lightbox = observer(function Lightbox() {
     const opts = store.shell.activeLightbox as models.ImagesLightbox
     return (
       <ImageView
-        images={opts.images.map(({uri}) => ({uri}))}
+        images={opts.images.map(img => ({...img}))}
         imageIndex={opts.index}
         visible
         onRequestClose={onClose}
diff --git a/src/view/com/lightbox/Lightbox.web.tsx b/src/view/com/lightbox/Lightbox.web.tsx
index f6aa26a3b..6d79dad36 100644
--- a/src/view/com/lightbox/Lightbox.web.tsx
+++ b/src/view/com/lightbox/Lightbox.web.tsx
@@ -109,6 +109,8 @@ function LightboxInner({
             accessibilityIgnoresInvertColors
             source={imgs[index]}
             style={styles.image}
+            accessibilityLabel={imgs[index].alt}
+            accessibilityHint=""
           />
           {canGoLeft && (
             <TouchableOpacity
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 83a51f7aa..e1c73c0d5 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -1,6 +1,6 @@
-import React, {useCallback, useMemo} from 'react'
+import React, {useMemo} from 'react'
 import {observer} from 'mobx-react-lite'
-import {AccessibilityActionEvent, Linking, StyleSheet, View} from 'react-native'
+import {Linking, StyleSheet, View} from 'react-native'
 import Clipboard from '@react-native-clipboard/clipboard'
 import {AtUri, AppBskyFeedDefs} from '@atproto/api'
 import {
@@ -138,40 +138,6 @@ export const PostThreadItem = observer(function PostThreadItem({
     )
   }, [item, store])
 
-  const accessibilityActions = useMemo(
-    () => [
-      {
-        name: 'reply',
-        label: 'Reply',
-      },
-      {
-        name: 'repost',
-        label: item.post.viewer?.repost ? 'Undo repost' : 'Repost',
-      },
-      {name: 'like', label: item.post.viewer?.like ? 'Unlike' : 'Like'},
-    ],
-    [item.post.viewer?.like, item.post.viewer?.repost],
-  )
-
-  const onAccessibilityAction = useCallback(
-    (event: AccessibilityActionEvent) => {
-      switch (event.nativeEvent.actionName) {
-        case 'like':
-          onPressToggleLike()
-          break
-        case 'reply':
-          onPressReply()
-          break
-        case 'repost':
-          onPressToggleRepost()
-          break
-        default:
-          break
-      }
-    },
-    [onPressReply, onPressToggleLike, onPressToggleRepost],
-  )
-
   if (!record) {
     return <ErrorMessage message="Invalid or unsupported post record" />
   }
@@ -193,9 +159,7 @@ export const PostThreadItem = observer(function PostThreadItem({
       <PostHider
         testID={`postThreadItem-by-${item.post.author.handle}`}
         style={[styles.outer, styles.outerHighlighted, pal.border, pal.view]}
-        moderation={item.moderation.thread}
-        accessibilityActions={accessibilityActions}
-        onAccessibilityAction={onAccessibilityAction}>
+        moderation={item.moderation.thread}>
         <PostSandboxWarning />
         <View style={styles.layout}>
           <View style={styles.layoutAvi}>
@@ -369,9 +333,7 @@ export const PostThreadItem = observer(function PostThreadItem({
             pal.view,
             item._showParentReplyLine && styles.noTopBorder,
           ]}
-          moderation={item.moderation.thread}
-          accessibilityActions={accessibilityActions}
-          onAccessibilityAction={onAccessibilityAction}>
+          moderation={item.moderation.thread}>
           {item._showParentReplyLine && (
             <View
               style={[
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index c74abb894..12ab0e901 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -1,6 +1,5 @@
-import React, {useCallback, useEffect, useMemo, useState} from 'react'
+import React, {useEffect, useState} from 'react'
 import {
-  AccessibilityActionEvent,
   ActivityIndicator,
   Linking,
   StyleProp,
@@ -200,47 +199,11 @@ const PostLoaded = observer(
       )
     }, [item, setDeleted, store])
 
-    const accessibilityActions = useMemo(
-      () => [
-        {
-          name: 'reply',
-          label: 'Reply',
-        },
-        {
-          name: 'repost',
-          label: item.post.viewer?.repost ? 'Undo repost' : 'Repost',
-        },
-        {name: 'like', label: item.post.viewer?.like ? 'Unlike' : 'Like'},
-      ],
-      [item.post.viewer?.like, item.post.viewer?.repost],
-    )
-
-    const onAccessibilityAction = useCallback(
-      (event: AccessibilityActionEvent) => {
-        switch (event.nativeEvent.actionName) {
-          case 'like':
-            onPressToggleLike()
-            break
-          case 'reply':
-            onPressReply()
-            break
-          case 'repost':
-            onPressToggleRepost()
-            break
-          default:
-            break
-        }
-      },
-      [onPressReply, onPressToggleLike, onPressToggleRepost],
-    )
-
     return (
       <PostHider
         href={itemHref}
         style={[styles.outer, pal.view, pal.border, style]}
-        moderation={item.moderation.list}
-        accessibilityActions={accessibilityActions}
-        onAccessibilityAction={onAccessibilityAction}>
+        moderation={item.moderation.list}>
         {showReplyLine && <View style={styles.replyLine} />}
         <View style={styles.layout}>
           <View style={styles.layoutAvi}>
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 7a292378e..6ec2c80f4 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -1,6 +1,6 @@
-import React, {useCallback, useMemo, useState} from 'react'
+import React, {useMemo, useState} from 'react'
 import {observer} from 'mobx-react-lite'
-import {AccessibilityActionEvent, Linking, StyleSheet, View} from 'react-native'
+import {Linking, StyleSheet, View} from 'react-native'
 import Clipboard from '@react-native-clipboard/clipboard'
 import {AtUri} from '@atproto/api'
 import {
@@ -158,40 +158,6 @@ export const FeedItem = observer(function ({
     moderation = {behavior: ModerationBehaviorCode.Show}
   }
 
-  const accessibilityActions = useMemo(
-    () => [
-      {
-        name: 'reply',
-        label: 'Reply',
-      },
-      {
-        name: 'repost',
-        label: item.post.viewer?.repost ? 'Undo repost' : 'Repost',
-      },
-      {name: 'like', label: item.post.viewer?.like ? 'Unlike' : 'Like'},
-    ],
-    [item.post.viewer?.like, item.post.viewer?.repost],
-  )
-
-  const onAccessibilityAction = useCallback(
-    (event: AccessibilityActionEvent) => {
-      switch (event.nativeEvent.actionName) {
-        case 'like':
-          onPressToggleLike()
-          break
-        case 'reply':
-          onPressReply()
-          break
-        case 'repost':
-          onPressToggleRepost()
-          break
-        default:
-          break
-      }
-    },
-    [onPressReply, onPressToggleLike, onPressToggleRepost],
-  )
-
   if (!record || deleted) {
     return <View />
   }
@@ -201,9 +167,7 @@ export const FeedItem = observer(function ({
       testID={`feedItem-by-${item.post.author.handle}`}
       style={outerStyles}
       href={itemHref}
-      moderation={moderation}
-      accessibilityActions={accessibilityActions}
-      onAccessibilityAction={onAccessibilityAction}>
+      moderation={moderation}>
       {isThreadChild && (
         <View
           style={[styles.topReplyLine, {borderColor: pal.colors.replyLine}]}
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx
index f753f01cc..7ff896344 100644
--- a/src/view/com/util/Link.tsx
+++ b/src/view/com/util/Link.tsx
@@ -88,6 +88,10 @@ export const Link = observer(function Link({
     props.dataSet.noUnderline = 1
   }
 
+  if (title && !props.accessibilityLabel) {
+    props.accessibilityLabel = title
+  }
+
   return (
     <TouchableOpacity
       testID={testID}
@@ -171,6 +175,7 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
   text,
   numberOfLines,
   lineHeight,
+  ...props
 }: {
   testID?: string
   type?: TypographyVariant
@@ -179,6 +184,9 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
   text: string | JSX.Element
   numberOfLines?: number
   lineHeight?: number
+  accessible?: boolean
+  accessibilityLabel?: string
+  accessibilityHint?: string
 }) {
   if (isDesktopWeb) {
     return (
@@ -190,6 +198,7 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
         text={text}
         numberOfLines={numberOfLines}
         lineHeight={lineHeight}
+        {...props}
       />
     )
   }
@@ -199,7 +208,8 @@ export const DesktopWebTextLink = observer(function DesktopWebTextLink({
       type={type}
       style={style}
       numberOfLines={numberOfLines}
-      lineHeight={lineHeight}>
+      lineHeight={lineHeight}
+      {...props}>
       {text}
     </Text>
   )
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index 45651e4e5..628c88722 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -2,7 +2,7 @@ import React from 'react'
 import {StyleSheet, View} from 'react-native'
 import {Text} from './text/Text'
 import {DesktopWebTextLink} from './Link'
-import {ago} from 'lib/strings/time'
+import {ago, niceDate} from 'lib/strings/time'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useStores} from 'state/index'
 import {UserAvatar} from './UserAvatar'
@@ -57,7 +57,11 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
               text={sanitizeDisplayName(displayName)}
               href={`/profile/${opts.authorHandle}`}
             />
-            <Text type="md" style={pal.textLight} lineHeight={1.2}>
+            <Text
+              type="md"
+              style={pal.textLight}
+              lineHeight={1.2}
+              accessible={false}>
               &nbsp;&middot;&nbsp;
             </Text>
             <DesktopWebTextLink
@@ -65,6 +69,8 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
               style={[styles.metaItem, pal.textLight]}
               lineHeight={1.2}
               text={ago(opts.timestamp)}
+              accessibilityLabel={niceDate(opts.timestamp)}
+              accessibilityHint=""
               href={opts.postHref}
             />
           </View>
@@ -122,7 +128,7 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
           href={`/profile/${opts.authorHandle}`}
         />
       </View>
-      <Text type="md" style={pal.textLight} lineHeight={1.2}>
+      <Text type="md" style={pal.textLight} lineHeight={1.2} accessible={false}>
         &middot;&nbsp;
       </Text>
       <DesktopWebTextLink
@@ -130,6 +136,8 @@ export const PostMeta = observer(function (opts: PostMetaOpts) {
         style={[styles.metaItem, pal.textLight]}
         lineHeight={1.2}
         text={ago(opts.timestamp)}
+        accessibilityLabel={niceDate(opts.timestamp)}
+        accessibilityHint=""
         href={opts.postHref}
       />
     </View>
diff --git a/src/view/com/util/PostSandboxWarning.tsx b/src/view/com/util/PostSandboxWarning.tsx
index 54495aa9b..21f5f7b90 100644
--- a/src/view/com/util/PostSandboxWarning.tsx
+++ b/src/view/com/util/PostSandboxWarning.tsx
@@ -10,7 +10,10 @@ export function PostSandboxWarning() {
   if (store.session.isSandbox) {
     return (
       <View style={styles.container}>
-        <Text type="title-2xl" style={[pal.text, styles.text]}>
+        <Text
+          type="title-2xl"
+          style={[pal.text, styles.text]}
+          accessible={false}>
           SANDBOX
         </Text>
       </View>
diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx
index c6e650077..ad216d97e 100644
--- a/src/view/com/util/forms/DropdownButton.tsx
+++ b/src/view/com/util/forms/DropdownButton.tsx
@@ -50,6 +50,8 @@ interface DropdownButtonProps {
   openToRight?: boolean
   rightOffset?: number
   bottomOffset?: number
+  accessibilityLabel?: string
+  accessibilityHint?: string
 }
 
 export function DropdownButton({
@@ -63,6 +65,7 @@ export function DropdownButton({
   openToRight = false,
   rightOffset = 0,
   bottomOffset = 0,
+  accessibilityLabel,
 }: PropsWithChildren<DropdownButtonProps>) {
   const ref1 = useRef<TouchableOpacity>(null)
   const ref2 = useRef<View>(null)
@@ -128,8 +131,8 @@ export function DropdownButton({
         hitSlop={HITSLOP}
         ref={ref1}
         accessibilityRole="button"
-        accessibilityLabel={`Opens ${numItems} options`}
-        accessibilityHint={`Opens ${numItems} options`}>
+        accessibilityLabel={accessibilityLabel || `Opens ${numItems} options`}
+        accessibilityHint="">
         {children}
       </TouchableOpacity>
     )
@@ -246,7 +249,9 @@ export function PostDropdownBtn({
       testID={testID}
       style={style}
       items={dropdownItems}
-      menuWidth={isWeb ? 220 : 200}>
+      menuWidth={isWeb ? 220 : 200}
+      accessibilityLabel="Additional post actions"
+      accessibilityHint="">
       {children}
     </DropdownButton>
   )
@@ -335,6 +340,7 @@ const DropdownItems = ({
                 key={index}
                 style={[styles.menuItem]}
                 onPress={() => onPressItem(index)}
+                accessibilityRole="button"
                 accessibilityLabel={item.label}
                 accessibilityHint={`Option ${index + 1} of ${numItems}`}>
                 {item.icon && (
diff --git a/src/view/com/util/images/AutoSizedImage.tsx b/src/view/com/util/images/AutoSizedImage.tsx
index e6aba46f3..9c6f25cae 100644
--- a/src/view/com/util/images/AutoSizedImage.tsx
+++ b/src/view/com/util/images/AutoSizedImage.tsx
@@ -64,15 +64,14 @@ export function AutoSizedImage({
         delayPressIn={DELAY_PRESS_IN}
         style={[styles.container, style]}
         accessible={true}
-        accessibilityLabel="Share image"
-        accessibilityHint="Opens ways of sharing image">
+        accessibilityRole="button"
+        accessibilityLabel={alt || 'Image'}
+        accessibilityHint="Tap to view fully">
         <Image
           style={[styles.image, {aspectRatio}]}
           source={uri}
-          accessible={true} // Must set for `accessibilityLabel` to work
+          accessible={false} // Must set for `accessibilityLabel` to work
           accessibilityIgnoresInvertColors
-          accessibilityLabel={alt}
-          accessibilityHint=""
         />
         {children}
       </TouchableOpacity>
diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx
index a7a64b171..01a7d574a 100644
--- a/src/view/com/util/images/Gallery.tsx
+++ b/src/view/com/util/images/Gallery.tsx
@@ -34,7 +34,7 @@ export const GalleryItem: FC<GalleryItemProps> = ({
         onPressIn={onPressIn ? () => onPressIn(index) : undefined}
         onLongPress={onLongPress ? () => onLongPress(index) : undefined}
         accessibilityRole="button"
-        accessibilityLabel="View image"
+        accessibilityLabel={image.alt || 'Image'}
         accessibilityHint="">
         <Image
           source={{uri: image.thumb}}
@@ -47,7 +47,9 @@ export const GalleryItem: FC<GalleryItemProps> = ({
       </TouchableOpacity>
       {image.alt === '' ? null : (
         <View style={styles.altContainer}>
-          <Text style={styles.alt}>ALT</Text>
+          <Text style={styles.alt} accessible={false}>
+            ALT
+          </Text>
         </View>
       )}
     </View>
diff --git a/src/view/com/util/moderation/PostHider.tsx b/src/view/com/util/moderation/PostHider.tsx
index 50ccf595b..f2b6dbddd 100644
--- a/src/view/com/util/moderation/PostHider.tsx
+++ b/src/view/com/util/moderation/PostHider.tsx
@@ -72,8 +72,7 @@ export function PostHider({
       style={style}
       href={href}
       noFeedback
-      accessible={true}
-      accessibilityRole="none"
+      accessible={false}
       {...props}>
       {children}
     </Link>
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index 12d4c48c8..cd6db408c 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -19,6 +19,7 @@ import {Text} from '../text/Text'
 import {PostDropdownBtn} from '../forms/DropdownButton'
 import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
 import {s, colors} from 'lib/styles'
+import {pluralize} from 'lib/strings/helpers'
 import {useTheme} from 'lib/ThemeContext'
 import {useStores} from 'state/index'
 import {RepostButton} from './RepostButton'
@@ -170,7 +171,9 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         hitSlop={HITSLOP}
         onPress={opts.onPressReply}
         accessibilityRole="button"
-        accessibilityLabel="Reply"
+        accessibilityLabel={`Reply (${opts.replyCount} ${
+          opts.replyCount === 1 ? 'reply' : 'replies'
+        })`}
         accessibilityHint="reply composer">
         <CommentBottomArrow
           style={[defaultCtrlColor, opts.big ? s.mt2 : styles.mt1]}
@@ -190,7 +193,9 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         hitSlop={HITSLOP}
         onPress={onPressToggleLikeWrapper}
         accessibilityRole="button"
-        accessibilityLabel={opts.isLiked ? 'Unlike' : 'Like'}
+        accessibilityLabel={`${opts.isLiked ? 'Unlike' : 'Like'} (${
+          opts.likeCount
+        } ${pluralize(opts.likeCount || 0, 'like')})`}
         accessibilityHint="">
         {opts.isLiked ? (
           <HeartIconSolid
diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx
index 59f7f6ee1..4338e4c59 100644
--- a/src/view/com/util/post-ctrls/RepostButton.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.tsx
@@ -4,6 +4,7 @@ import {RepostIcon} from 'lib/icons'
 import {s, colors} from 'lib/styles'
 import {useTheme} from 'lib/ThemeContext'
 import {Text} from '../text/Text'
+import {pluralize} from 'lib/strings/helpers'
 import {useStores} from 'state/index'
 
 const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5}
@@ -49,7 +50,9 @@ export const RepostButton = ({
       onPress={onPressToggleRepostWrapper}
       style={styles.control}
       accessibilityRole="button"
-      accessibilityLabel={isReposted ? 'Undo repost' : 'Repost'}
+      accessibilityLabel={`${
+        isReposted ? 'Undo repost' : 'Repost'
+      } (${repostCount} ${pluralize(repostCount || 0, 'repost')})`}
       accessibilityHint="">
       <RepostIcon
         style={
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index edcef7039..372b36359 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -129,7 +129,9 @@ export function PostEmbeds({
               style={styles.singleImage}>
               {alt === '' ? null : (
                 <View style={styles.altContainer}>
-                  <Text style={styles.alt}>ALT</Text>
+                  <Text style={styles.alt} accessible={false}>
+                    ALT
+                  </Text>
                 </View>
               )}
             </AutoSizedImage>