Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Option for large alt badges (#4571)

* add pref for large alt badge

* add to settings

* do the large badge bit

* Tweak wording

---------

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>

authored by

Samuel Newman
Dan Abramov
and committed by
GitHub
0f931933 22c5aa4d

+113 -43
+2
src/state/persisted/schema.ts
··· 60 60 appLanguage: z.string(), 61 61 }), 62 62 requireAltTextEnabled: z.boolean(), // should move to server 63 + largeAltBadgeEnabled: z.boolean().optional(), 63 64 externalEmbeds: z 64 65 .object({ 65 66 giphy: z.enum(externalEmbedOptions).optional(), ··· 112 113 appLanguage: deviceLocales[0] || 'en', 113 114 }, 114 115 requireAltTextEnabled: false, 116 + largeAltBadgeEnabled: false, 115 117 externalEmbeds: {}, 116 118 mutedThreads: [], 117 119 invites: {
+1
src/state/preferences/alt-text-required.tsx
··· 1 1 import React from 'react' 2 + 2 3 import * as persisted from '#/state/persisted' 3 4 4 5 type StateContext = persisted.Schema['requireAltTextEnabled']
+1
src/state/preferences/hidden-posts.tsx
··· 1 1 import React from 'react' 2 + 2 3 import * as persisted from '#/state/persisted' 3 4 4 5 type SetStateCb = (
+14 -11
src/state/preferences/index.tsx
··· 8 8 import {Provider as InAppBrowserProvider} from './in-app-browser' 9 9 import {Provider as KawaiiProvider} from './kawaii' 10 10 import {Provider as LanguagesProvider} from './languages' 11 + import {Provider as LargeAltBadgeProvider} from './large-alt-badge' 11 12 12 13 export { 13 14 useRequireAltTextEnabled, ··· 27 28 return ( 28 29 <LanguagesProvider> 29 30 <AltTextRequiredProvider> 30 - <ExternalEmbedsProvider> 31 - <HiddenPostsProvider> 32 - <InAppBrowserProvider> 33 - <DisableHapticsProvider> 34 - <AutoplayProvider> 35 - <KawaiiProvider>{children}</KawaiiProvider> 36 - </AutoplayProvider> 37 - </DisableHapticsProvider> 38 - </InAppBrowserProvider> 39 - </HiddenPostsProvider> 40 - </ExternalEmbedsProvider> 31 + <LargeAltBadgeProvider> 32 + <ExternalEmbedsProvider> 33 + <HiddenPostsProvider> 34 + <InAppBrowserProvider> 35 + <DisableHapticsProvider> 36 + <AutoplayProvider> 37 + <KawaiiProvider>{children}</KawaiiProvider> 38 + </AutoplayProvider> 39 + </DisableHapticsProvider> 40 + </InAppBrowserProvider> 41 + </HiddenPostsProvider> 42 + </ExternalEmbedsProvider> 43 + </LargeAltBadgeProvider> 41 44 </AltTextRequiredProvider> 42 45 </LanguagesProvider> 43 46 )
+49
src/state/preferences/large-alt-badge.tsx
··· 1 + import React from 'react' 2 + 3 + import * as persisted from '#/state/persisted' 4 + 5 + type StateContext = persisted.Schema['largeAltBadgeEnabled'] 6 + type SetContext = (v: persisted.Schema['largeAltBadgeEnabled']) => void 7 + 8 + const stateContext = React.createContext<StateContext>( 9 + persisted.defaults.largeAltBadgeEnabled, 10 + ) 11 + const setContext = React.createContext<SetContext>( 12 + (_: persisted.Schema['largeAltBadgeEnabled']) => {}, 13 + ) 14 + 15 + export function Provider({children}: React.PropsWithChildren<{}>) { 16 + const [state, setState] = React.useState( 17 + persisted.get('largeAltBadgeEnabled'), 18 + ) 19 + 20 + const setStateWrapped = React.useCallback( 21 + (largeAltBadgeEnabled: persisted.Schema['largeAltBadgeEnabled']) => { 22 + setState(largeAltBadgeEnabled) 23 + persisted.write('largeAltBadgeEnabled', largeAltBadgeEnabled) 24 + }, 25 + [setState], 26 + ) 27 + 28 + React.useEffect(() => { 29 + return persisted.onUpdate(() => { 30 + setState(persisted.get('largeAltBadgeEnabled')) 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 useLargeAltBadgeEnabled() { 44 + return React.useContext(stateContext) 45 + } 46 + 47 + export function useSetLargeAltBadgeEnabled() { 48 + return React.useContext(setContext) 49 + }
+10 -12
src/view/com/util/images/Gallery.tsx
··· 5 5 import {msg} from '@lingui/macro' 6 6 import {useLingui} from '@lingui/react' 7 7 8 - import {isWeb} from 'platform/detection' 8 + import {isWeb} from '#/platform/detection' 9 + import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' 10 + import {atoms as a} from '#/alf' 9 11 10 12 type EventFunction = (index: number) => void 11 13 ··· 27 29 onLongPress, 28 30 }) => { 29 31 const {_} = useLingui() 32 + const largeAltBadge = useLargeAltBadgeEnabled() 30 33 const image = images[index] 31 34 return ( 32 - <View style={styles.fullWidth}> 35 + <View style={a.flex_1}> 33 36 <Pressable 34 37 onPress={onPress ? () => onPress(index) : undefined} 35 38 onPressIn={onPressIn ? () => onPressIn(index) : undefined} 36 39 onLongPress={onLongPress ? () => onLongPress(index) : undefined} 37 - style={styles.fullWidth} 40 + style={a.flex_1} 38 41 accessibilityRole="button" 39 42 accessibilityLabel={image.alt || _(msg`Image`)} 40 43 accessibilityHint=""> 41 44 <Image 42 45 source={{uri: image.thumb}} 43 - style={[styles.image, imageStyle]} 46 + style={[a.flex_1, a.rounded_xs, imageStyle]} 44 47 accessible={true} 45 48 accessibilityLabel={image.alt} 46 49 accessibilityHint="" ··· 49 52 </Pressable> 50 53 {image.alt === '' ? null : ( 51 54 <View style={styles.altContainer}> 52 - <Text style={styles.alt} accessible={false}> 55 + <Text 56 + style={[styles.alt, largeAltBadge && a.text_xs]} 57 + accessible={false}> 53 58 ALT 54 59 </Text> 55 60 </View> ··· 59 64 } 60 65 61 66 const styles = StyleSheet.create({ 62 - fullWidth: { 63 - flex: 1, 64 - }, 65 - image: { 66 - flex: 1, 67 - borderRadius: 4, 68 - }, 69 67 altContainer: { 70 68 backgroundColor: 'rgba(0, 0, 0, 0.75)', 71 69 borderRadius: 6,
+5 -1
src/view/com/util/post-embeds/GifEmbed.tsx
··· 8 8 import {HITSLOP_20} from '#/lib/constants' 9 9 import {parseAltFromGIFDescription} from '#/lib/gif-alt-text' 10 10 import {isWeb} from '#/platform/detection' 11 + import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' 11 12 import {EmbedPlayerParams} from 'lib/strings/embed-player' 12 13 import {useAutoplayDisabled} from 'state/preferences' 13 14 import {atoms as a, useTheme} from '#/alf' ··· 157 158 158 159 function AltText({text}: {text: string}) { 159 160 const control = Prompt.usePromptControl() 161 + const largeAltBadge = useLargeAltBadgeEnabled() 160 162 161 163 const {_} = useLingui() 162 164 return ( ··· 169 171 hitSlop={HITSLOP_20} 170 172 onPress={control.open} 171 173 style={styles.altContainer}> 172 - <Text style={styles.alt} accessible={false}> 174 + <Text 175 + style={[styles.alt, largeAltBadge && a.text_xs]} 176 + accessible={false}> 173 177 <Trans>ALT</Trans> 174 178 </Text> 175 179 </TouchableOpacity>
+7 -8
src/view/com/util/post-embeds/index.tsx
··· 21 21 import {ImagesLightbox, useLightboxControls} from '#/state/lightbox' 22 22 import {usePalette} from 'lib/hooks/usePalette' 23 23 import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard' 24 + import {atoms as a} from '#/alf' 24 25 import {ContentHider} from '../../../../components/moderation/ContentHider' 25 26 import {AutoSizedImage} from '../images/AutoSizedImage' 26 27 import {ImageLayoutGrid} from '../images/ImageLayoutGrid' ··· 28 29 import {ListEmbed} from './ListEmbed' 29 30 import {MaybeQuoteEmbed} from './QuoteEmbed' 30 31 import hairlineWidth = StyleSheet.hairlineWidth 32 + import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' 31 33 32 34 type Embed = 33 35 | AppBskyEmbedRecord.View ··· 51 53 }) { 52 54 const pal = usePalette('default') 53 55 const {openLightbox} = useLightboxControls() 56 + const largeAltBadge = useLargeAltBadgeEnabled() 54 57 55 58 // quote post with media 56 59 // = ··· 130 133 dimensionsHint={aspectRatio} 131 134 onPress={() => _openLightbox(0)} 132 135 onPressIn={() => onPressIn(0)} 133 - style={[styles.singleImage]}> 136 + style={a.rounded_sm}> 134 137 {alt === '' ? null : ( 135 138 <View style={styles.altContainer}> 136 - <Text style={styles.alt} accessible={false}> 139 + <Text 140 + style={[styles.alt, largeAltBadge && a.text_xs]} 141 + accessible={false}> 137 142 ALT 138 143 </Text> 139 144 </View> ··· 151 156 images={embed.images} 152 157 onPress={_openLightbox} 153 158 onPressIn={onPressIn} 154 - style={ 155 - embed.images.length === 1 ? [styles.singleImage] : undefined 156 - } 157 159 /> 158 160 </View> 159 161 </ContentHider> ··· 178 180 const styles = StyleSheet.create({ 179 181 imagesContainer: { 180 182 marginTop: 8, 181 - }, 182 - singleImage: { 183 - borderRadius: 8, 184 183 }, 185 184 altContainer: { 186 185 backgroundColor: 'rgba(0, 0, 0, 0.75)',
+24 -11
src/view/screens/AccessibilitySettings.tsx
··· 4 4 import {useLingui} from '@lingui/react' 5 5 import {useFocusEffect} from '@react-navigation/native' 6 6 7 + import {useAnalytics} from '#/lib/analytics/analytics' 8 + import {usePalette} from '#/lib/hooks/usePalette' 9 + import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 10 + import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' 11 + import {s} from '#/lib/styles' 7 12 import {isNative} from '#/platform/detection' 8 - import {useSetMinimalShellMode} from '#/state/shell' 9 - import {useAnalytics} from 'lib/analytics/analytics' 10 - import {usePalette} from 'lib/hooks/usePalette' 11 - import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 12 - import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' 13 - import {s} from 'lib/styles' 14 13 import { 15 14 useAutoplayDisabled, 16 15 useHapticsDisabled, ··· 18 17 useSetAutoplayDisabled, 19 18 useSetHapticsDisabled, 20 19 useSetRequireAltTextEnabled, 21 - } from 'state/preferences' 22 - import {ToggleButton} from 'view/com/util/forms/ToggleButton' 23 - import {SimpleViewHeader} from '../com/util/SimpleViewHeader' 24 - import {Text} from '../com/util/text/Text' 25 - import {ScrollView} from '../com/util/Views' 20 + } from '#/state/preferences' 21 + import { 22 + useLargeAltBadgeEnabled, 23 + useSetLargeAltBadgeEnabled, 24 + } from '#/state/preferences/large-alt-badge' 25 + import {useSetMinimalShellMode} from '#/state/shell' 26 + import {ToggleButton} from '#/view/com/util/forms/ToggleButton' 27 + import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader' 28 + import {Text} from '#/view/com/util/text/Text' 29 + import {ScrollView} from '#/view/com/util/Views' 26 30 27 31 type Props = NativeStackScreenProps< 28 32 CommonNavigatorParams, ··· 41 45 const setAutoplayDisabled = useSetAutoplayDisabled() 42 46 const hapticsDisabled = useHapticsDisabled() 43 47 const setHapticsDisabled = useSetHapticsDisabled() 48 + const largeAltBadgeEnabled = useLargeAltBadgeEnabled() 49 + const setLargeAltBadgeEnabled = useSetLargeAltBadgeEnabled() 44 50 45 51 useFocusEffect( 46 52 React.useCallback(() => { ··· 83 89 labelType="lg" 84 90 isSelected={requireAltTextEnabled} 85 91 onPress={() => setRequireAltTextEnabled(!requireAltTextEnabled)} 92 + /> 93 + <ToggleButton 94 + type="default-light" 95 + label={_(msg`Display larger alt text badges`)} 96 + labelType="lg" 97 + isSelected={!!largeAltBadgeEnabled} 98 + onPress={() => setLargeAltBadgeEnabled(!largeAltBadgeEnabled)} 86 99 /> 87 100 </View> 88 101 <Text type="xl-bold" style={[pal.text, styles.heading]}>