Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client
117
fork

Configure Feed

Select the types of activity you want to include in your feed.

add option to remove "Feeds" promo when one feed is selected

+84 -6
+20
src/screens/Settings/DeerSettings.tsx
··· 35 35 useSetDirectFetchRecords, 36 36 } from '#/state/preferences/direct-fetch-records' 37 37 import { 38 + useHideFeedsPromoTab, 39 + useSetHideFeedsPromoTab, 40 + } from '#/state/preferences/hide-feeds-promo-tab' 41 + import { 38 42 useHideFollowNotifications, 39 43 useSetHideFollowNotifications, 40 44 } from '#/state/preferences/hide-follow-notifications' ··· 262 266 263 267 const hideFollowNotifications = useHideFollowNotifications() 264 268 const setHideFollowNotifications = useSetHideFollowNotifications() 269 + 270 + const hideFeedsPromoTab = useHideFeedsPromoTab() 271 + const setHideFeedsPromoTab = useSetHideFeedsPromoTab() 265 272 266 273 const location = useGeolocation() 267 274 const setLocationControl = Dialog.useDialogControl() ··· 518 525 <Trans> 519 526 On non-bsky.social handles, show a link to that URL 520 527 </Trans> 528 + </Toggle.LabelText> 529 + <Toggle.Platform /> 530 + </Toggle.Item> 531 + <Toggle.Item 532 + name="hide_feeds_promo_tab" 533 + label={_( 534 + msg`Hide "Feeds ✨" tab when only one feed is selected`, 535 + )} 536 + value={hideFeedsPromoTab} 537 + onChange={value => setHideFeedsPromoTab(value)} 538 + style={[a.w_full]}> 539 + <Toggle.LabelText style={[a.flex_1]}> 540 + <Trans>Hide "Feeds ✨" tab when only one feed is selected</Trans> 521 541 </Toggle.LabelText> 522 542 <Toggle.Platform /> 523 543 </Toggle.Item>
+2
src/state/persisted/schema.ts
··· 134 134 hideFollowNotifications: z.boolean().optional(), 135 135 constellationInstance: z.string().optional(), 136 136 showLinkInHandle: z.boolean().optional(), 137 + hideFeedsPromoTab: z.boolean().optional(), 137 138 deerVerification: z 138 139 .object({ 139 140 enabled: z.boolean(), ··· 203 204 hideFollowNotifications: false, 204 205 constellationInstance: 'https://constellation.microcosm.blue/', 205 206 showLinkInHandle: false, 207 + hideFeedsPromoTab: false, 206 208 deerVerification: { 207 209 enabled: false, 208 210 // https://deer.social/profile/did:plc:p2cp5gopk7mgjegy6wadk3ep/post/3lndyqyyr4k2k
+50
src/state/preferences/hide-feeds-promo-tab.tsx
··· 1 + import React from 'react' 2 + 3 + import * as persisted from '#/state/persisted' 4 + 5 + // Preference: hideFeedsPromoTab – when true, suppress the "Feeds ✨" promotional tab in HomeHeader. 6 + 7 + type StateContext = persisted.Schema['hideFeedsPromoTab'] 8 + // Same setter signature used across other preference modules 9 + type SetContext = (v: persisted.Schema['hideFeedsPromoTab']) => void 10 + 11 + const stateContext = React.createContext<StateContext>( 12 + persisted.defaults.hideFeedsPromoTab, 13 + ) 14 + const setContext = React.createContext<SetContext>( 15 + (_: persisted.Schema['hideFeedsPromoTab']) => {}, 16 + ) 17 + 18 + export function Provider({children}: React.PropsWithChildren<{}>) { 19 + const [state, setState] = React.useState(persisted.get('hideFeedsPromoTab')) 20 + 21 + const setStateWrapped = React.useCallback( 22 + (value: persisted.Schema['hideFeedsPromoTab']) => { 23 + setState(value) 24 + persisted.write('hideFeedsPromoTab', value) 25 + }, 26 + [setState], 27 + ) 28 + 29 + React.useEffect(() => { 30 + return persisted.onUpdate('hideFeedsPromoTab', next => { 31 + setState(next) 32 + }) 33 + }, [setStateWrapped]) 34 + 35 + return ( 36 + <stateContext.Provider value={state}> 37 + <setContext.Provider value={setStateWrapped}> 38 + {children} 39 + </setContext.Provider> 40 + </stateContext.Provider> 41 + ) 42 + } 43 + 44 + export function useHideFeedsPromoTab() { 45 + return React.useContext(stateContext) 46 + } 47 + 48 + export function useSetHideFeedsPromoTab() { 49 + return React.useContext(setContext) 50 + }
+6 -2
src/state/preferences/index.tsx
··· 8 8 import {Provider as DirectFetchRecordsProvider} from './direct-fetch-records' 9 9 import {Provider as DisableHapticsProvider} from './disable-haptics' 10 10 import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs' 11 + import {Provider as FollowNotificationsProvider} from './hide-follow-notifications' 11 12 import {Provider as GoLinksProvider} from './go-links-enabled' 12 13 import {Provider as HiddenPostsProvider} from './hidden-posts' 13 - import {Provider as FollowNotificationsProvider} from './hide-follow-notifications' 14 + import {Provider as HideFeedsPromoTabProvider} from './hide-feeds-promo-tab' 14 15 import {Provider as InAppBrowserProvider} from './in-app-browser' 15 16 import {Provider as KawaiiProvider} from './kawaii' 16 17 import {Provider as LanguagesProvider} from './languages' ··· 35 36 } from './external-embeds-prefs' 36 37 export {useGoLinksEnabled, useSetGoLinksEnabled} from './go-links-enabled' 37 38 export * from './hidden-posts' 39 + export {useHideFeedsPromoTab, useSetHideFeedsPromoTab} from './hide-feeds-promo-tab' 38 40 export {useLabelDefinitions} from './label-defs' 39 41 export {useLanguagePrefs, useLanguagePrefsApi} from './languages' 40 42 export {useSetSubtitlesEnabled, useSubtitlesEnabled} from './subtitles' ··· 63 65 <TrendingSettingsProvider> 64 66 <RepostCarouselProvider> 65 67 <KawaiiProvider> 66 - {children} 68 + <HideFeedsPromoTabProvider> 69 + {children} 70 + </HideFeedsPromoTabProvider> 67 71 </KawaiiProvider> 68 72 </RepostCarouselProvider> 69 73 </TrendingSettingsProvider>
+6 -4
src/view/com/home/HomeHeader.tsx
··· 1 1 import React from 'react' 2 2 import {useNavigation} from '@react-navigation/native' 3 + import {useHideFeedsPromoTab} from '#/state/preferences/hide-feeds-promo-tab' 3 4 4 5 import {NavigationProp} from '#/lib/routes/types' 5 6 import {FeedSourceInfo} from '#/state/queries/feed' ··· 17 18 ) { 18 19 const {feeds} = props 19 20 const {hasSession} = useSession() 21 + const hideFeedsPromoTab = useHideFeedsPromoTab() 20 22 const navigation = useNavigation<NavigationProp>() 21 23 22 24 const hasPinnedCustom = React.useMemo<boolean>(() => { ··· 29 31 30 32 const items = React.useMemo(() => { 31 33 const pinnedNames = feeds.map(f => f.displayName) 32 - if (!hasPinnedCustom) { 34 + if (!hasPinnedCustom && !hideFeedsPromoTab) { 33 35 return pinnedNames.concat('Feeds ✨') 34 36 } 35 37 return pinnedNames 36 - }, [hasPinnedCustom, feeds]) 38 + }, [hasPinnedCustom, hideFeedsPromoTab, feeds]) 37 39 38 40 const onPressFeedsLink = React.useCallback(() => { 39 41 navigation.navigate('Feeds') ··· 41 43 42 44 const onSelect = React.useCallback( 43 45 (index: number) => { 44 - if (!hasPinnedCustom && index === items.length - 1) { 46 + if (!hasPinnedCustom && !hideFeedsPromoTab && index === items.length - 1) { 45 47 onPressFeedsLink() 46 48 } else if (props.onSelect) { 47 49 props.onSelect(index) 48 50 } 49 51 }, 50 - [items.length, onPressFeedsLink, props, hasPinnedCustom], 52 + [items.length, onPressFeedsLink, props, hasPinnedCustom, hideFeedsPromoTab], 51 53 ) 52 54 53 55 return (