diff --git a/src/screens/Settings/DeerSettings.tsx b/src/screens/Settings/DeerSettings.tsx
index bcfdcb18c..d44748848 100644
--- a/src/screens/Settings/DeerSettings.tsx
+++ b/src/screens/Settings/DeerSettings.tsx
@@ -88,6 +88,10 @@ import {
useHideSimilarAccountsRecomm,
useSetHideSimilarAccountsRecomm,
} from '#/state/preferences/hide-similar-accounts-recommendations'
+import {
+ useHideUnreplyablePosts,
+ useSetHideUnreplyablePosts,
+} from '#/state/preferences/hide-unreplyable-posts'
import {
useHighQualityImages,
useSetHighQualityImages,
@@ -443,6 +447,9 @@ export function DeerSettingsScreen({}: Props) {
const hideSimilarAccountsRecomm = useHideSimilarAccountsRecomm()
const setHideSimilarAccountsRecomm = useSetHideSimilarAccountsRecomm()
+ const hideUnreplyablePosts = useHideUnreplyablePosts()
+ const setHideUnreplyablePosts = useSetHideUnreplyablePosts()
+
const disableVerifyEmailReminder = useDisableVerifyEmailReminder()
const setDisableVerifyEmailReminder = useSetDisableVerifyEmailReminder()
@@ -754,6 +761,24 @@ export function DeerSettingsScreen({}: Props) {
+ setHideUnreplyablePosts(value)}
+ style={[a.w_full]}>
+
+ Hide posts that cannot be replied to from feeds
+
+
+
+
+
+ Hides posts from feeds where replies are disabled (e.g. due to
+ postgates or other restrictions). Does not affect thread views.
+
+
+
void
+
+const stateContext = React.createContext(
+ persisted.defaults.hideUnreplyablePosts,
+)
+const setContext = React.createContext(
+ (_: persisted.Schema['hideUnreplyablePosts']) => {},
+)
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+ const [state, setState] = React.useState(
+ persisted.get('hideUnreplyablePosts'),
+ )
+
+ const setStateWrapped = React.useCallback(
+ (hideUnreplyablePosts: persisted.Schema['hideUnreplyablePosts']) => {
+ setState(hideUnreplyablePosts)
+ persisted.write('hideUnreplyablePosts', hideUnreplyablePosts)
+ },
+ [setState],
+ )
+
+ React.useEffect(() => {
+ return persisted.onUpdate('hideUnreplyablePosts', nextValue => {
+ setState(nextValue)
+ })
+ }, [setStateWrapped])
+
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+export function useHideUnreplyablePosts() {
+ return (
+ React.useContext(stateContext) ?? persisted.defaults.hideUnreplyablePosts
+ )
+}
+
+export function useSetHideUnreplyablePosts() {
+ return React.useContext(setContext)
+}
diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx
index e7a852ede..b7df1b568 100644
--- a/src/state/preferences/index.tsx
+++ b/src/state/preferences/index.tsx
@@ -26,6 +26,7 @@ import {Provider as GoLinksProvider} from './go-links-enabled'
import {Provider as HiddenPostsProvider} from './hidden-posts'
import {Provider as HideFeedsPromoTabProvider} from './hide-feeds-promo-tab'
import {Provider as HideSimilarAccountsRecommProvider} from './hide-similar-accounts-recommendations'
+import {Provider as HideUnreplyablePostsProvider} from './hide-unreplyable-posts'
import {Provider as HighQualityImagesProvider} from './high-quality-images'
import {Provider as InAppBrowserProvider} from './in-app-browser'
import {Provider as KawaiiProvider} from './kawaii'
@@ -96,13 +97,15 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
-
-
-
- {children}
-
-
-
+
+
+
+
+ {children}
+
+
+
+
diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx
index 25e3ab95b..83fd162f0 100644
--- a/src/view/com/posts/PostFeed.tsx
+++ b/src/view/com/posts/PostFeed.tsx
@@ -38,6 +38,7 @@ import {isIOS, isNative, isWeb} from '#/platform/detection'
import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow'
import {listenPostCreated} from '#/state/events'
import {useFeedFeedbackContext} from '#/state/feed-feedback'
+import {useHideUnreplyablePosts} from '#/state/preferences/hide-unreplyable-posts'
import {useRepostCarouselEnabled} from '#/state/preferences/repost-carousel-enabled'
import {useTrendingSettings} from '#/state/preferences/trending'
import {STALE} from '#/state/queries'
@@ -433,6 +434,7 @@ let PostFeed = ({
const {trendingDisabled, trendingVideoDisabled} = useTrendingSettings()
const repostCarouselEnabled = useRepostCarouselEnabled()
+ const hideUnreplyablePosts = useHideUnreplyablePosts()
if (feedType === 'following') {
useRepostCarousel = repostCarouselEnabled
@@ -562,6 +564,27 @@ let PostFeed = ({
? groupReposts(page.slices)
: (page.slices as FeedPostSliceOrGroup[])
+ // Filter out posts that cannot be replied to if the setting is enabled
+ if (hideUnreplyablePosts) {
+ slices = slices.filter(slice => {
+ if (slice.isRepostSlice) {
+ // For repost slices, filter the inner slices
+ slice.slices = slice.slices.filter(innerSlice => {
+ // Check if any item in the slice has replyDisabled
+ return !innerSlice.items.some(
+ item => item.post.viewer?.replyDisabled === true,
+ )
+ })
+ return slice.slices.length > 0
+ } else {
+ // For regular slices, check if any item has replyDisabled
+ return !slice.items.some(
+ item => item.post.viewer?.replyDisabled === true,
+ )
+ }
+ })
+ }
+
for (const slice of slices) {
sliceIndex++
@@ -769,6 +792,7 @@ let PostFeed = ({
isCurrentFeedAtStartupSelected,
gate,
blockedOrMutedAuthors,
+ hideUnreplyablePosts,
])
// events