Bluesky app fork with some witchin' additions 💫

feat: add disable composer prompt toggle in settings

xan.lol 9e44a1b3 83f9cfb5

verified
+90 -4
+19
src/screens/Settings/DeerSettings.tsx
··· 23 23 useSetDirectFetchRecords, 24 24 } from '#/state/preferences/direct-fetch-records' 25 25 import { 26 + useDisableComposerPrompt, 27 + useSetDisableComposerPrompt, 28 + } from '#/state/preferences/disable-composer-prompt' 29 + import { 26 30 useDisableFollowedByMetrics, 27 31 useSetDisableFollowedByMetrics, 28 32 } from '#/state/preferences/disable-followed-by-metrics' ··· 281 285 282 286 const disableViaRepostNotification = useDisableViaRepostNotification() 283 287 const setDisableViaRepostNotification = useSetDisableViaRepostNotification() 288 + 289 + const disableComposerPrompt = useDisableComposerPrompt() 290 + const setDisableComposerPrompt = useSetDisableComposerPrompt() 284 291 285 292 const disableLikesMetrics = useDisableLikesMetrics() 286 293 const setDisableLikesMetrics = useSetDisableLikesMetrics() ··· 603 610 postgates or other restrictions). Does not affect thread views. 604 611 </Trans> 605 612 </Admonition> 613 + 614 + <Toggle.Item 615 + name="disable_composer_prompt" 616 + label={_(msg`Disable composer prompt`)} 617 + value={disableComposerPrompt} 618 + onChange={value => setDisableComposerPrompt(value)} 619 + style={[a.w_full]}> 620 + <Toggle.LabelText style={[a.flex_1]}> 621 + <Trans>Disable composer prompt</Trans> 622 + </Toggle.LabelText> 623 + <Toggle.Platform /> 624 + </Toggle.Item> 606 625 607 626 <Toggle.Item 608 627 name="disable_verify_email_reminder"
+2
src/state/persisted/schema.ts
··· 147 147 showLinkInHandle: z.boolean().optional(), 148 148 hideFeedsPromoTab: z.boolean().optional(), 149 149 disableViaRepostNotification: z.boolean().optional(), 150 + disableComposerPrompt: z.boolean().optional(), 150 151 disableLikesMetrics: z.boolean().optional(), 151 152 disableRepostsMetrics: z.boolean().optional(), 152 153 disableQuotesMetrics: z.boolean().optional(), ··· 238 239 showLinkInHandle: true, 239 240 hideFeedsPromoTab: false, 240 241 disableViaRepostNotification: false, 242 + disableComposerPrompt: true, 241 243 disableLikesMetrics: false, 242 244 disableRepostsMetrics: false, 243 245 disableQuotesMetrics: false,
+55
src/state/preferences/disable-composer-prompt.tsx
··· 1 + import React from 'react' 2 + 3 + import * as persisted from '#/state/persisted' 4 + 5 + // Preference: disableComposerPrompt – when true, disables the composer prompt 6 + 7 + type StateContext = persisted.Schema['disableComposerPrompt'] 8 + // Same setter signature used across other preference modules 9 + type SetContext = (v: persisted.Schema['disableComposerPrompt']) => void 10 + 11 + const stateContext = React.createContext<StateContext>( 12 + persisted.defaults.disableComposerPrompt, 13 + ) 14 + const setContext = React.createContext<SetContext>( 15 + (_: persisted.Schema['disableComposerPrompt']) => {}, 16 + ) 17 + 18 + export function Provider({children}: React.PropsWithChildren<{}>) { 19 + const [state, setState] = React.useState( 20 + persisted.get('disableComposerPrompt'), 21 + ) 22 + 23 + const setStateWrapped = React.useCallback( 24 + (disableComposerPrompt: persisted.Schema['disableComposerPrompt']) => { 25 + setState(disableComposerPrompt) 26 + persisted.write('disableComposerPrompt', disableComposerPrompt) 27 + }, 28 + [setState], 29 + ) 30 + 31 + React.useEffect(() => { 32 + return persisted.onUpdate( 33 + 'disableComposerPrompt', 34 + nextDisableComposerPrompt => { 35 + setState(nextDisableComposerPrompt) 36 + }, 37 + ) 38 + }, [setStateWrapped]) 39 + 40 + return ( 41 + <stateContext.Provider value={state}> 42 + <setContext.Provider value={setStateWrapped}> 43 + {children} 44 + </setContext.Provider> 45 + </stateContext.Provider> 46 + ) 47 + } 48 + 49 + export function useDisableComposerPrompt() { 50 + return React.useContext(stateContext) 51 + } 52 + 53 + export function useSetDisableComposerPrompt() { 54 + return React.useContext(setContext) 55 + }
+10 -3
src/state/preferences/index.tsx
··· 6 6 import {Provider as ConstellationInstanceProvider} from './constellation-instance' 7 7 import {Provider as DeerVerificationProvider} from './deer-verification' 8 8 import {Provider as DirectFetchRecordsProvider} from './direct-fetch-records' 9 + import {Provider as DisableComposerPromptProvider} from './disable-composer-prompt' 9 10 import {Provider as DisableFollowedByMetricsProvider} from './disable-followed-by-metrics' 10 11 import {Provider as DisableFollowersMetricsProvider} from './disable-followers-metrics' 11 12 import {Provider as DisableFollowingMetricsProvider} from './disable-following-metrics' ··· 46 47 useSetRequireAltTextEnabled, 47 48 } from './alt-text-required' 48 49 export {useAutoplayDisabled, useSetAutoplayDisabled} from './autoplay' 50 + export { 51 + useDisableComposerPrompt, 52 + useSetDisableComposerPrompt, 53 + } from './disable-composer-prompt' 49 54 export {useHapticsDisabled, useSetHapticsDisabled} from './disable-haptics' 50 55 export { 51 56 useExternalEmbedsPrefs, ··· 107 112 <EnableSquareButtonsProvider> 108 113 <DisableVerifyEmailReminderProvider> 109 114 <TranslationServicePreferenceProvider> 110 - { 111 - children 112 - } 115 + <DisableComposerPromptProvider> 116 + { 117 + children 118 + } 119 + </DisableComposerPromptProvider> 113 120 </TranslationServicePreferenceProvider> 114 121 </DisableVerifyEmailReminderProvider> 115 122 </EnableSquareButtonsProvider>
+4 -1
src/view/com/posts/PostFeed.tsx
··· 36 36 import {usePostAuthorShadowFilter} from '#/state/cache/profile-shadow' 37 37 import {listenPostCreated} from '#/state/events' 38 38 import {useFeedFeedbackContext} from '#/state/feed-feedback' 39 + import {useDisableComposerPrompt} from '#/state/preferences/disable-composer-prompt' 39 40 import {useHideUnreplyablePosts} from '#/state/preferences/hide-unreplyable-posts' 40 41 import {useRepostCarouselEnabled} from '#/state/preferences/repost-carousel-enabled' 41 42 import {useTrendingSettings} from '#/state/preferences/trending' ··· 441 442 442 443 const repostCarouselEnabled = useRepostCarouselEnabled() 443 444 const hideUnreplyablePosts = useHideUnreplyablePosts() 445 + const disableComposerPrompt = useDisableComposerPrompt() 444 446 445 447 if (feedType === 'following') { 446 448 useRepostCarousel = repostCarouselEnabled ··· 624 626 // Show composer prompt for Discover and Following feeds 625 627 if ( 626 628 hasSession && 629 + !disableComposerPrompt && 627 630 (feedUriOrActorDid === DISCOVER_FEED_URI || 628 631 feed === 'following') 629 632 ) { ··· 648 651 } else if (feedKind === 'following') { 649 652 if (sliceIndex === 0) { 650 653 // Show composer prompt for Following feed 651 - if (hasSession) { 654 + if (hasSession && !disableComposerPrompt) { 652 655 arr.push({ 653 656 type: 'composerPrompt', 654 657 key: 'composerPrompt-' + sliceIndex,