Adds a toggle to hide posts that can't be replied to (e.g they are postgated to you). I have no idea how to test this one.
+25
src/screens/Settings/DeerSettings.tsx
+25
src/screens/Settings/DeerSettings.tsx
···
88
88
useHideSimilarAccountsRecomm,
89
89
useSetHideSimilarAccountsRecomm,
90
90
} from '#/state/preferences/hide-similar-accounts-recommendations'
91
+
import {
92
+
useHideUnreplyablePosts,
93
+
useSetHideUnreplyablePosts,
94
+
} from '#/state/preferences/hide-unreplyable-posts'
91
95
import {
92
96
useHighQualityImages,
93
97
useSetHighQualityImages,
···
443
447
const hideSimilarAccountsRecomm = useHideSimilarAccountsRecomm()
444
448
const setHideSimilarAccountsRecomm = useSetHideSimilarAccountsRecomm()
445
449
450
+
const hideUnreplyablePosts = useHideUnreplyablePosts()
451
+
const setHideUnreplyablePosts = useSetHideUnreplyablePosts()
452
+
446
453
const disableVerifyEmailReminder = useDisableVerifyEmailReminder()
447
454
const setDisableVerifyEmailReminder = useSetDisableVerifyEmailReminder()
448
455
···
754
761
<Toggle.Platform />
755
762
</Toggle.Item>
756
763
764
+
<Toggle.Item
765
+
name="hide_unreplyable_posts"
766
+
label={_(msg`Hide posts that cannot be replied to from feeds`)}
767
+
value={hideUnreplyablePosts}
768
+
onChange={value => setHideUnreplyablePosts(value)}
769
+
style={[a.w_full]}>
770
+
<Toggle.LabelText style={[a.flex_1]}>
771
+
<Trans>Hide posts that cannot be replied to from feeds</Trans>
772
+
</Toggle.LabelText>
773
+
<Toggle.Platform />
774
+
</Toggle.Item>
775
+
<Admonition type="info" style={[a.flex_1]}>
776
+
<Trans>
777
+
Hides posts from feeds where replies are disabled (e.g. due to
778
+
postgates or other restrictions). Does not affect thread views.
779
+
</Trans>
780
+
</Admonition>
781
+
757
782
<Toggle.Item
758
783
name="disable_verify_email_reminder"
759
784
label={_(msg`Disable verify email reminder`)}
+2
src/state/persisted/schema.ts
+2
src/state/persisted/schema.ts
···
166
166
})
167
167
.optional(),
168
168
highQualityImages: z.boolean().optional(),
169
+
hideUnreplyablePosts: z.boolean().optional(),
169
170
170
171
showExternalShareButtons: z.boolean().optional(),
171
172
···
269
270
],
270
271
},
271
272
highQualityImages: false,
273
+
hideUnreplyablePosts: false,
272
274
showExternalShareButtons: false,
273
275
}
274
276
+51
src/state/preferences/hide-unreplyable-posts.tsx
+51
src/state/preferences/hide-unreplyable-posts.tsx
···
1
+
import React from 'react'
2
+
3
+
import * as persisted from '#/state/persisted'
4
+
5
+
type StateContext = persisted.Schema['hideUnreplyablePosts']
6
+
type SetContext = (v: persisted.Schema['hideUnreplyablePosts']) => void
7
+
8
+
const stateContext = React.createContext<StateContext>(
9
+
persisted.defaults.hideUnreplyablePosts,
10
+
)
11
+
const setContext = React.createContext<SetContext>(
12
+
(_: persisted.Schema['hideUnreplyablePosts']) => {},
13
+
)
14
+
15
+
export function Provider({children}: React.PropsWithChildren<{}>) {
16
+
const [state, setState] = React.useState(
17
+
persisted.get('hideUnreplyablePosts'),
18
+
)
19
+
20
+
const setStateWrapped = React.useCallback(
21
+
(hideUnreplyablePosts: persisted.Schema['hideUnreplyablePosts']) => {
22
+
setState(hideUnreplyablePosts)
23
+
persisted.write('hideUnreplyablePosts', hideUnreplyablePosts)
24
+
},
25
+
[setState],
26
+
)
27
+
28
+
React.useEffect(() => {
29
+
return persisted.onUpdate('hideUnreplyablePosts', nextValue => {
30
+
setState(nextValue)
31
+
})
32
+
}, [setStateWrapped])
33
+
34
+
return (
35
+
<stateContext.Provider value={state}>
36
+
<setContext.Provider value={setStateWrapped}>
37
+
{children}
38
+
</setContext.Provider>
39
+
</stateContext.Provider>
40
+
)
41
+
}
42
+
43
+
export function useHideUnreplyablePosts() {
44
+
return (
45
+
React.useContext(stateContext) ?? persisted.defaults.hideUnreplyablePosts
46
+
)
47
+
}
48
+
49
+
export function useSetHideUnreplyablePosts() {
50
+
return React.useContext(setContext)
51
+
}
+10
-7
src/state/preferences/index.tsx
+10
-7
src/state/preferences/index.tsx
···
26
26
import {Provider as HiddenPostsProvider} from './hidden-posts'
27
27
import {Provider as HideFeedsPromoTabProvider} from './hide-feeds-promo-tab'
28
28
import {Provider as HideSimilarAccountsRecommProvider} from './hide-similar-accounts-recommendations'
29
+
import {Provider as HideUnreplyablePostsProvider} from './hide-unreplyable-posts'
29
30
import {Provider as HighQualityImagesProvider} from './high-quality-images'
30
31
import {Provider as InAppBrowserProvider} from './in-app-browser'
31
32
import {Provider as KawaiiProvider} from './kawaii'
···
96
97
<DisableFollowedByMetricsProvider>
97
98
<DisablePostsMetricsProvider>
98
99
<HideSimilarAccountsRecommProvider>
99
-
<EnableSquareAvatarsProvider>
100
-
<EnableSquareButtonsProvider>
101
-
<DisableVerifyEmailReminderProvider>
102
-
{children}
103
-
</DisableVerifyEmailReminderProvider>
104
-
</EnableSquareButtonsProvider>
105
-
</EnableSquareAvatarsProvider>
100
+
<HideUnreplyablePostsProvider>
101
+
<EnableSquareAvatarsProvider>
102
+
<EnableSquareButtonsProvider>
103
+
<DisableVerifyEmailReminderProvider>
104
+
{children}
105
+
</DisableVerifyEmailReminderProvider>
106
+
</EnableSquareButtonsProvider>
107
+
</EnableSquareAvatarsProvider>
108
+
</HideUnreplyablePostsProvider>
106
109
</HideSimilarAccountsRecommProvider>
107
110
</DisablePostsMetricsProvider>
108
111
</DisableFollowedByMetricsProvider>
+24
src/view/com/posts/PostFeed.tsx
+24
src/view/com/posts/PostFeed.tsx
···
38
38
import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow'
39
39
import {listenPostCreated} from '#/state/events'
40
40
import {useFeedFeedbackContext} from '#/state/feed-feedback'
41
+
import {useHideUnreplyablePosts} from '#/state/preferences/hide-unreplyable-posts'
41
42
import {useRepostCarouselEnabled} from '#/state/preferences/repost-carousel-enabled'
42
43
import {useTrendingSettings} from '#/state/preferences/trending'
43
44
import {STALE} from '#/state/queries'
···
433
434
const {trendingDisabled, trendingVideoDisabled} = useTrendingSettings()
434
435
435
436
const repostCarouselEnabled = useRepostCarouselEnabled()
437
+
const hideUnreplyablePosts = useHideUnreplyablePosts()
436
438
437
439
if (feedType === 'following') {
438
440
useRepostCarousel = repostCarouselEnabled
···
562
564
? groupReposts(page.slices)
563
565
: (page.slices as FeedPostSliceOrGroup[])
564
566
567
+
// Filter out posts that cannot be replied to if the setting is enabled
568
+
if (hideUnreplyablePosts) {
569
+
slices = slices.filter(slice => {
570
+
if (slice.isRepostSlice) {
571
+
// For repost slices, filter the inner slices
572
+
slice.slices = slice.slices.filter(innerSlice => {
573
+
// Check if any item in the slice has replyDisabled
574
+
return !innerSlice.items.some(
575
+
item => item.post.viewer?.replyDisabled === true,
576
+
)
577
+
})
578
+
return slice.slices.length > 0
579
+
} else {
580
+
// For regular slices, check if any item has replyDisabled
581
+
return !slice.items.some(
582
+
item => item.post.viewer?.replyDisabled === true,
583
+
)
584
+
}
585
+
})
586
+
}
587
+
565
588
for (const slice of slices) {
566
589
sliceIndex++
567
590
···
769
792
isCurrentFeedAtStartupSelected,
770
793
gate,
771
794
blockedOrMutedAuthors,
795
+
hideUnreplyablePosts,
772
796
])
773
797
774
798
// events