diff --git a/src/components/RichTextTag.tsx b/src/components/RichTextTag.tsx index 4f1af6e1ea..219ead634e 100644 --- a/src/components/RichTextTag.tsx +++ b/src/components/RichTextTag.tsx @@ -48,10 +48,11 @@ export function RichTextTag({ reset: resetRemove, } = useRemoveMutedWordsMutation() const navigation = useNavigation() - const label = _(msg`Hashtag ${tag}`) + const isCashtag = tag.startsWith('$') + const label = isCashtag ? _(msg`Cashtag ${tag}`) : _(msg`Hashtag ${tag}`) const hint = isNative - ? _(msg`Long press to open tag menu for #${tag}`) - : _(msg`Click to open tag menu for ${tag}`) + ? _(msg`Long press to open tag menu for ${isCashtag ? tag : `#${tag}`}`) + : _(msg`Click to open tag menu for ${isCashtag ? tag : `#${tag}`}`) const isMuted = Boolean( (preferences?.moderationPrefs.mutedWords?.find( @@ -109,20 +110,24 @@ export function RichTextTag({ { navigation.push('Hashtag', { tag: encodeURIComponent(tag), }) }}> - See #{tag} posts + {isCashtag ? ( + See {tag} posts + ) : ( + See #{tag} posts + )} {authorHandle && !isInvalidHandle(authorHandle) && ( { navigation.push('Hashtag', { tag: encodeURIComponent(tag), @@ -130,7 +135,11 @@ export function RichTextTag({ }) }}> - See #{tag} posts by user + {isCashtag ? ( + See {tag} posts by user + ) : ( + See #{tag} posts by user + )} diff --git a/src/screens/Hashtag.tsx b/src/screens/Hashtag.tsx index b57b73edb6..56d994ad88 100644 --- a/src/screens/Hashtag.tsx +++ b/src/screens/Hashtag.tsx @@ -46,13 +46,22 @@ export default function HashtagScreen({ const {tag, author} = route.params const {_} = useLingui() - const fullTag = React.useMemo(() => { - return `#${decodeURIComponent(tag)}` + const decodedTag = React.useMemo(() => { + return decodeURIComponent(tag) }, [tag]) + const isCashtag = decodedTag.startsWith('$') + + const fullTag = React.useMemo(() => { + // Cashtags already include the $ prefix, hashtags need # added + return isCashtag ? decodedTag : `#${decodedTag}` + }, [decodedTag, isCashtag]) + const headerTitle = React.useMemo(() => { - return enforceLen(fullTag.toLowerCase(), 24, true, 'middle') - }, [fullTag]) + // Keep cashtags uppercase, lowercase hashtags + const displayTag = isCashtag ? fullTag.toUpperCase() : fullTag.toLowerCase() + return enforceLen(displayTag, 24, true, 'middle') + }, [fullTag, isCashtag]) const sanitizedAuthor = React.useMemo(() => { if (!author) return @@ -255,7 +264,7 @@ function HashtagScreenTab({ isError={isError} onRetry={refetch} emptyType="results" - emptyMessage={_(msg`We couldn't find any results for that hashtag.`)} + emptyMessage={_(msg`We couldn't find any results for that tag.`)} /> ) : ( 5) continue + + // Calculate positions: leading char + $ + ticker + const matchedFrom = match.index + leading.length + const matchedTo = matchedFrom + 1 + ticker.length // +1 for $ + + const start = pos + matchedFrom + const end = pos + matchedTo + + decorations.push( + Decoration.inline(start, end, { + class: 'autolink', + }), + ) + } } })