diff --git a/src/components/TagMenu/index.web.tsx b/src/components/TagMenu/index.web.tsx index 930e47a1..31187112 100644 --- a/src/components/TagMenu/index.web.tsx +++ b/src/components/TagMenu/index.web.tsx @@ -12,6 +12,8 @@ import { useUpsertMutedWordsMutation, useRemoveMutedWordMutation, } from '#/state/queries/preferences' +import {enforceLen} from '#/lib/strings/helpers' +import {web} from '#/alf' export function useTagMenuControl() {} @@ -40,11 +42,12 @@ export function TagMenu({ )) && !(optimisticRemove?.value === sanitizedTag), ) + const truncatedTag = enforceLen(tag, 15, true, 'middle') const dropdownItems = React.useMemo(() => { return [ { - label: _(msg`See ${tag} posts`), + label: _(msg`See ${truncatedTag} posts`), onPress() { navigation.navigate('Search', { q: tag, @@ -61,7 +64,7 @@ export function TagMenu({ }, authorHandle && !isInvalidHandle(authorHandle) && { - label: _(msg`See ${tag} posts by this user`), + label: _(msg`See ${truncatedTag} posts by user`), onPress() { navigation.navigate({ name: 'Search', @@ -83,7 +86,9 @@ export function TagMenu({ label: 'separator', }, preferences && { - label: isMuted ? _(msg`Unmute ${tag}`) : _(msg`Mute ${tag}`), + label: isMuted + ? _(msg`Unmute ${truncatedTag}`) + : _(msg`Mute ${truncatedTag}`), onPress() { if (isMuted) { removeMutedWord({value: sanitizedTag, targets: ['tag']}) @@ -108,6 +113,7 @@ export function TagMenu({ navigation, preferences, tag, + truncatedTag, sanitizedTag, upsertMutedWord, removeMutedWord, @@ -119,7 +125,10 @@ export function TagMenu({ accessibilityLabel={_(msg`Click here to open tag menu for ${tag}`)} accessibilityHint="" // @ts-ignore - items={dropdownItems}> + items={dropdownItems} + triggerStyle={web({ + textAlign: 'left', + })}> {children} diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx index 138cc533..7c0d4fbc 100644 --- a/src/components/dialogs/MutedWords.tsx +++ b/src/components/dialogs/MutedWords.tsx @@ -10,7 +10,7 @@ import { useRemoveMutedWordMutation, } from '#/state/queries/preferences' import {isNative} from '#/platform/detection' -import {atoms as a, useTheme, useBreakpoints, ViewStyleProp} from '#/alf' +import {atoms as a, useTheme, useBreakpoints, ViewStyleProp, web} from '#/alf' import {Text} from '#/components/Typography' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' @@ -260,9 +260,21 @@ function MutedWordRow({ a.align_center, a.justify_between, a.rounded_md, + a.gap_md, style, ]}> - + {word.value} diff --git a/src/lib/strings/helpers.ts b/src/lib/strings/helpers.ts index e2abe901..de4562d2 100644 --- a/src/lib/strings/helpers.ts +++ b/src/lib/strings/helpers.ts @@ -8,10 +8,27 @@ export function pluralize(n: number, base: string, plural?: string): string { return base + 's' } -export function enforceLen(str: string, len: number, ellipsis = false): string { +export function enforceLen( + str: string, + len: number, + ellipsis = false, + mode: 'end' | 'middle' = 'end', +): string { str = str || '' if (str.length > len) { - return str.slice(0, len) + (ellipsis ? '...' : '') + if (ellipsis) { + if (mode === 'end') { + return str.slice(0, len) + '…' + } else if (mode === 'middle') { + const half = Math.floor(len / 2) + return str.slice(0, half) + '…' + str.slice(-half) + } else { + // fallback + return str.slice(0, len) + } + } else { + return str.slice(0, len) + } } return str } diff --git a/src/view/com/util/forms/NativeDropdown.tsx b/src/view/com/util/forms/NativeDropdown.tsx index 08228506..0a47569f 100644 --- a/src/view/com/util/forms/NativeDropdown.tsx +++ b/src/view/com/util/forms/NativeDropdown.tsx @@ -1,7 +1,7 @@ import React from 'react' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from 'zeego/dropdown-menu' -import {Pressable, StyleSheet, Platform, View} from 'react-native' +import {Pressable, StyleSheet, Platform, View, ViewStyle} from 'react-native' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {usePalette} from 'lib/hooks/usePalette' @@ -151,6 +151,7 @@ type Props = { testID?: string accessibilityLabel?: string accessibilityHint?: string + triggerStyle?: ViewStyle } /* The `NativeDropdown` function uses native iOS and Android dropdown menus. diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index 052e7ca1..6abeb16c 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -1,7 +1,7 @@ import React from 'react' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from '@radix-ui/react-dropdown-menu' -import {Pressable, StyleSheet, View, Text} from 'react-native' +import {Pressable, StyleSheet, View, Text, ViewStyle} from 'react-native' import {IconProp} from '@fortawesome/fontawesome-svg-core' import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {usePalette} from 'lib/hooks/usePalette' @@ -53,6 +53,7 @@ type Props = { testID?: string accessibilityLabel?: string accessibilityHint?: string + triggerStyle?: ViewStyle } export function NativeDropdown({ @@ -61,6 +62,7 @@ export function NativeDropdown({ testID, accessibilityLabel, accessibilityHint, + triggerStyle, }: React.PropsWithChildren) { const pal = usePalette('default') const theme = useTheme() @@ -120,7 +122,8 @@ export function NativeDropdown({ accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} onPress={() => setOpen(o => !o)} - hitSlop={HITSLOP_10}> + hitSlop={HITSLOP_10} + style={triggerStyle}> {children}