diff --git a/src/App.native.tsx b/src/App.native.tsx
index c26052a92d..9e999ba0b3 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -172,31 +172,31 @@ function App() {
* that is set up in the InnerApp component above.
*/
return (
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
)
}
diff --git a/src/App.web.tsx b/src/App.web.tsx
index fa1fba031b..88fd80248a 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -151,29 +151,29 @@ function App() {
* that is set up in the InnerApp component above.
*/
return (
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
)
}
diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer.tsx
index c990054890..74802a9930 100644
--- a/src/state/shell/composer.tsx
+++ b/src/state/shell/composer.tsx
@@ -5,8 +5,11 @@ import {
AppBskyRichtextFacet,
ModerationDecision,
} from '@atproto/api'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
+import * as Toast from '#/view/com/util/Toast'
export interface ComposerOptsPostRef {
uri: string
@@ -22,12 +25,7 @@ export interface ComposerOptsQuote {
text: string
facets?: AppBskyRichtextFacet.Main[]
indexedAt: string
- author: {
- did: string
- handle: string
- displayName?: string
- avatar?: string
- }
+ author: AppBskyActorDefs.ProfileViewBasic
embeds?: AppBskyEmbedRecord.ViewRecord['embeds']
}
export interface ComposerOpts {
@@ -56,10 +54,25 @@ const controlsContext = React.createContext({
})
export function Provider({children}: React.PropsWithChildren<{}>) {
+ const {_} = useLingui()
const [state, setState] = React.useState()
const openComposer = useNonReactiveCallback((opts: ComposerOpts) => {
- setState(opts)
+ const author = opts.replyTo?.author || opts.quote?.author
+ const isBlocked = Boolean(
+ author &&
+ (author.viewer?.blocking ||
+ author.viewer?.blockedBy ||
+ author.viewer?.blockingByList),
+ )
+ if (isBlocked) {
+ Toast.show(
+ _(msg`Cannot interact with a blocked user`),
+ 'exclamation-circle',
+ )
+ } else {
+ setState(opts)
+ }
})
const closeComposer = useNonReactiveCallback(() => {
diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx
index f577e16831..05a14ed7a1 100644
--- a/src/view/com/util/post-ctrls/PostCtrls.tsx
+++ b/src/view/com/util/post-ctrls/PostCtrls.tsx
@@ -89,6 +89,11 @@ let PostCtrls = ({
const {captureAction} = useProgressGuideControls()
const playHaptic = useHaptics()
const gate = useGate()
+ const isBlocked = Boolean(
+ post.author.viewer?.blocking ||
+ post.author.viewer?.blockedBy ||
+ post.author.viewer?.blockingByList,
+ )
const shouldShowLoggedOutWarning = React.useMemo(() => {
return (
@@ -105,6 +110,14 @@ let PostCtrls = ({
) as StyleProp
const onPressToggleLike = React.useCallback(async () => {
+ if (isBlocked) {
+ Toast.show(
+ _(msg`Cannot interact with a blocked user`),
+ 'exclamation-circle',
+ )
+ return
+ }
+
try {
if (!post.viewer?.like) {
playHaptic()
@@ -124,6 +137,7 @@ let PostCtrls = ({
}
}
}, [
+ _,
playHaptic,
post.uri,
post.viewer?.like,
@@ -132,9 +146,18 @@ let PostCtrls = ({
sendInteraction,
captureAction,
feedContext,
+ isBlocked,
])
const onRepost = useCallback(async () => {
+ if (isBlocked) {
+ Toast.show(
+ _(msg`Cannot interact with a blocked user`),
+ 'exclamation-circle',
+ )
+ return
+ }
+
try {
if (!post.viewer?.repost) {
sendInteraction({
@@ -152,15 +175,25 @@ let PostCtrls = ({
}
}
}, [
+ _,
post.uri,
post.viewer?.repost,
queueRepost,
queueUnrepost,
sendInteraction,
feedContext,
+ isBlocked,
])
const onQuote = useCallback(() => {
+ if (isBlocked) {
+ Toast.show(
+ _(msg`Cannot interact with a blocked user`),
+ 'exclamation-circle',
+ )
+ return
+ }
+
sendInteraction({
item: post.uri,
event: 'app.bsky.feed.defs#interactionQuote',
@@ -178,6 +211,7 @@ let PostCtrls = ({
onPost: onPostReply,
})
}, [
+ _,
sendInteraction,
post.uri,
post.cid,
@@ -188,6 +222,7 @@ let PostCtrls = ({
openComposer,
record.text,
onPostReply,
+ isBlocked,
])
const onShare = useCallback(() => {