Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Tags menu/muted words improvements (#3002)

* Fix translations

* Handle loooong words

* Truncate on desktop web, revert mobile changes

* Break the words

* Small enough for mobile web

* Fix alignment on mobile web

* Clarify

authored by

Eric Bailey and committed by
GitHub
978bcc1b 6717f8f1

+53 -11
+13 -4
src/components/TagMenu/index.web.tsx
··· 12 12 useUpsertMutedWordsMutation, 13 13 useRemoveMutedWordMutation, 14 14 } from '#/state/queries/preferences' 15 + import {enforceLen} from '#/lib/strings/helpers' 16 + import {web} from '#/alf' 15 17 16 18 export function useTagMenuControl() {} 17 19 ··· 40 42 )) && 41 43 !(optimisticRemove?.value === sanitizedTag), 42 44 ) 45 + const truncatedTag = enforceLen(tag, 15, true, 'middle') 43 46 44 47 const dropdownItems = React.useMemo(() => { 45 48 return [ 46 49 { 47 - label: _(msg`See ${tag} posts`), 50 + label: _(msg`See ${truncatedTag} posts`), 48 51 onPress() { 49 52 navigation.navigate('Search', { 50 53 q: tag, ··· 61 64 }, 62 65 authorHandle && 63 66 !isInvalidHandle(authorHandle) && { 64 - label: _(msg`See ${tag} posts by this user`), 67 + label: _(msg`See ${truncatedTag} posts by user`), 65 68 onPress() { 66 69 navigation.navigate({ 67 70 name: 'Search', ··· 83 86 label: 'separator', 84 87 }, 85 88 preferences && { 86 - label: isMuted ? _(msg`Unmute ${tag}`) : _(msg`Mute ${tag}`), 89 + label: isMuted 90 + ? _(msg`Unmute ${truncatedTag}`) 91 + : _(msg`Mute ${truncatedTag}`), 87 92 onPress() { 88 93 if (isMuted) { 89 94 removeMutedWord({value: sanitizedTag, targets: ['tag']}) ··· 108 113 navigation, 109 114 preferences, 110 115 tag, 116 + truncatedTag, 111 117 sanitizedTag, 112 118 upsertMutedWord, 113 119 removeMutedWord, ··· 119 125 accessibilityLabel={_(msg`Click here to open tag menu for ${tag}`)} 120 126 accessibilityHint="" 121 127 // @ts-ignore 122 - items={dropdownItems}> 128 + items={dropdownItems} 129 + triggerStyle={web({ 130 + textAlign: 'left', 131 + })}> 123 132 {children} 124 133 </NativeDropdown> 125 134 </EventStopper>
+14 -2
src/components/dialogs/MutedWords.tsx
··· 10 10 useRemoveMutedWordMutation, 11 11 } from '#/state/queries/preferences' 12 12 import {isNative} from '#/platform/detection' 13 - import {atoms as a, useTheme, useBreakpoints, ViewStyleProp} from '#/alf' 13 + import {atoms as a, useTheme, useBreakpoints, ViewStyleProp, web} from '#/alf' 14 14 import {Text} from '#/components/Typography' 15 15 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 16 16 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' ··· 260 260 a.align_center, 261 261 a.justify_between, 262 262 a.rounded_md, 263 + a.gap_md, 263 264 style, 264 265 ]}> 265 - <Text style={[a.font_bold, t.atoms.text_contrast_high]}> 266 + <Text 267 + style={[ 268 + a.flex_1, 269 + a.leading_snug, 270 + a.w_full, 271 + a.font_bold, 272 + t.atoms.text_contrast_high, 273 + web({ 274 + overflowWrap: 'break-word', 275 + wordBreak: 'break-word', 276 + }), 277 + ]}> 266 278 {word.value} 267 279 </Text> 268 280
+19 -2
src/lib/strings/helpers.ts
··· 8 8 return base + 's' 9 9 } 10 10 11 - export function enforceLen(str: string, len: number, ellipsis = false): string { 11 + export function enforceLen( 12 + str: string, 13 + len: number, 14 + ellipsis = false, 15 + mode: 'end' | 'middle' = 'end', 16 + ): string { 12 17 str = str || '' 13 18 if (str.length > len) { 14 - return str.slice(0, len) + (ellipsis ? '...' : '') 19 + if (ellipsis) { 20 + if (mode === 'end') { 21 + return str.slice(0, len) + '…' 22 + } else if (mode === 'middle') { 23 + const half = Math.floor(len / 2) 24 + return str.slice(0, half) + '…' + str.slice(-half) 25 + } else { 26 + // fallback 27 + return str.slice(0, len) 28 + } 29 + } else { 30 + return str.slice(0, len) 31 + } 15 32 } 16 33 return str 17 34 }
+2 -1
src/view/com/util/forms/NativeDropdown.tsx
··· 1 1 import React from 'react' 2 2 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 3 3 import * as DropdownMenu from 'zeego/dropdown-menu' 4 - import {Pressable, StyleSheet, Platform, View} from 'react-native' 4 + import {Pressable, StyleSheet, Platform, View, ViewStyle} from 'react-native' 5 5 import {IconProp} from '@fortawesome/fontawesome-svg-core' 6 6 import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' 7 7 import {usePalette} from 'lib/hooks/usePalette' ··· 151 151 testID?: string 152 152 accessibilityLabel?: string 153 153 accessibilityHint?: string 154 + triggerStyle?: ViewStyle 154 155 } 155 156 156 157 /* The `NativeDropdown` function uses native iOS and Android dropdown menus.
+5 -2
src/view/com/util/forms/NativeDropdown.web.tsx
··· 1 1 import React from 'react' 2 2 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 3 3 import * as DropdownMenu from '@radix-ui/react-dropdown-menu' 4 - import {Pressable, StyleSheet, View, Text} from 'react-native' 4 + import {Pressable, StyleSheet, View, Text, ViewStyle} from 'react-native' 5 5 import {IconProp} from '@fortawesome/fontawesome-svg-core' 6 6 import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' 7 7 import {usePalette} from 'lib/hooks/usePalette' ··· 53 53 testID?: string 54 54 accessibilityLabel?: string 55 55 accessibilityHint?: string 56 + triggerStyle?: ViewStyle 56 57 } 57 58 58 59 export function NativeDropdown({ ··· 61 62 testID, 62 63 accessibilityLabel, 63 64 accessibilityHint, 65 + triggerStyle, 64 66 }: React.PropsWithChildren<Props>) { 65 67 const pal = usePalette('default') 66 68 const theme = useTheme() ··· 120 122 accessibilityLabel={accessibilityLabel} 121 123 accessibilityHint={accessibilityHint} 122 124 onPress={() => setOpen(o => !o)} 123 - hitSlop={HITSLOP_10}> 125 + hitSlop={HITSLOP_10} 126 + style={triggerStyle}> 124 127 {children} 125 128 </Pressable> 126 129 </DropdownMenu.Trigger>