about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx44
-rw-r--r--src/view/com/post/Post.tsx40
-rw-r--r--src/view/com/posts/FeedItem.tsx40
-rw-r--r--src/view/com/util/moderation/PostHider.tsx34
-rw-r--r--src/view/com/util/post-ctrls/PostCtrls.tsx4
-rw-r--r--src/view/com/util/post-ctrls/RepostButton.tsx6
6 files changed, 138 insertions, 30 deletions
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index f61701788..4ba2e1a40 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, {useCallback, useMemo} from 'react'
 import {observer} from 'mobx-react-lite'
 import {Linking, StyleSheet, View} from 'react-native'
 import Clipboard from '@react-native-clipboard/clipboard'
@@ -133,6 +133,40 @@ 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 => {
+      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" />
   }
@@ -154,7 +188,9 @@ 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}>
+        moderation={item.moderation.thread}
+        accessibilityActions={accessibilityActions}
+        onAccessibilityAction={onAccessibilityAction}>
         <View style={styles.layout}>
           <View style={styles.layoutAvi}>
             <Link
@@ -324,7 +360,9 @@ export const PostThreadItem = observer(function PostThreadItem({
             pal.view,
             item._showParentReplyLine && styles.noTopBorder,
           ]}
-          moderation={item.moderation.thread}>
+          moderation={item.moderation.thread}
+          accessibilityActions={accessibilityActions}
+          onAccessibilityAction={onAccessibilityAction}>
           {item._showParentReplyLine && (
             <View
               style={[
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 5139d5830..a1f8298ff 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -1,4 +1,4 @@
-import React, {useState, useEffect} from 'react'
+import React, {useCallback, useEffect, useMemo, useState} from 'react'
 import {
   ActivityIndicator,
   Linking,
@@ -205,11 +205,47 @@ 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 => {
+        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}>
+        moderation={item.moderation.list}
+        accessibilityActions={accessibilityActions}
+        onAccessibilityAction={onAccessibilityAction}>
         {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 553c3a244..413300bbc 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -1,4 +1,4 @@
-import React, {useMemo, useState} from 'react'
+import React, {useCallback, useMemo, useState} from 'react'
 import {observer} from 'mobx-react-lite'
 import {Linking, StyleSheet, View} from 'react-native'
 import Clipboard from '@react-native-clipboard/clipboard'
@@ -158,12 +158,48 @@ 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 => {
+      switch (event.nativeEvent.actionName) {
+        case 'like':
+          onPressToggleLike()
+          break
+        case 'reply':
+          onPressReply()
+          break
+        case 'repost':
+          onPressToggleRepost()
+          break
+        default:
+          break
+      }
+    },
+    [onPressReply, onPressToggleLike, onPressToggleRepost],
+  )
+
   return (
     <PostHider
       testID={`feedItem-by-${item.post.author.handle}`}
       style={outerStyles}
       href={itemHref}
-      moderation={moderation}>
+      moderation={moderation}
+      accessibilityActions={accessibilityActions}
+      onAccessibilityAction={onAccessibilityAction}>
       {isThreadChild && (
         <View
           style={[styles.topReplyLine, {borderColor: pal.colors.replyLine}]}
diff --git a/src/view/com/util/moderation/PostHider.tsx b/src/view/com/util/moderation/PostHider.tsx
index 2cc7ea62b..50ccf595b 100644
--- a/src/view/com/util/moderation/PostHider.tsx
+++ b/src/view/com/util/moderation/PostHider.tsx
@@ -1,11 +1,5 @@
-import React from 'react'
-import {
-  StyleProp,
-  StyleSheet,
-  TouchableOpacity,
-  View,
-  ViewStyle,
-} from 'react-native'
+import React, {ComponentProps} from 'react'
+import {StyleSheet, TouchableOpacity, View} from 'react-native'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {usePalette} from 'lib/hooks/usePalette'
 import {Link} from '../Link'
@@ -13,18 +7,21 @@ import {Text} from '../text/Text'
 import {addStyle} from 'lib/styles'
 import {ModerationBehaviorCode, ModerationBehavior} from 'lib/labeling/types'
 
+interface Props extends ComponentProps<typeof Link> {
+  // testID?: string
+  // href?: string
+  // style: StyleProp<ViewStyle>
+  moderation: ModerationBehavior
+}
+
 export function PostHider({
   testID,
   href,
   moderation,
   style,
   children,
-}: React.PropsWithChildren<{
-  testID?: string
-  href?: string
-  moderation: ModerationBehavior
-  style: StyleProp<ViewStyle>
-}>) {
+  ...props
+}: Props) {
   const pal = usePalette('default')
   const [override, setOverride] = React.useState(false)
   const bg = override ? pal.viewLight : pal.view
@@ -70,7 +67,14 @@ export function PostHider({
 
   // NOTE: any further label enforcement should occur in ContentContainer
   return (
-    <Link testID={testID} style={style} href={href} noFeedback>
+    <Link
+      testID={testID}
+      style={style}
+      href={href}
+      noFeedback
+      accessible={true}
+      accessibilityRole="none"
+      {...props}>
       {children}
     </Link>
   )
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index 41d66641f..12d4c48c8 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -191,9 +191,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
         onPress={onPressToggleLikeWrapper}
         accessibilityRole="button"
         accessibilityLabel={opts.isLiked ? 'Unlike' : 'Like'}
-        accessibilityHint={
-          opts.isReposted ? 'Removes like from the post' : 'Like the post'
-        }>
+        accessibilityHint="">
         {opts.isLiked ? (
           <HeartIconSolid
             style={styles.ctrlIconLiked}
diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx
index e6de4cb19..59f7f6ee1 100644
--- a/src/view/com/util/post-ctrls/RepostButton.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.tsx
@@ -50,11 +50,7 @@ export const RepostButton = ({
       style={styles.control}
       accessibilityRole="button"
       accessibilityLabel={isReposted ? 'Undo repost' : 'Repost'}
-      accessibilityHint={
-        isReposted
-          ? `Remove your repost of the post`
-          : `Repost or quote post the post`
-      }>
+      accessibilityHint="">
       <RepostIcon
         style={
           isReposted