diff --git a/src/app/components/message/Reaction.tsx b/src/app/components/message/Reaction.tsx index b9e69788f..b106b233a 100644 --- a/src/app/components/message/Reaction.tsx +++ b/src/app/components/message/Reaction.tsx @@ -13,13 +13,21 @@ export const Reaction = as< mx: MatrixClient; count: number; reaction: string; + /** Custom-emoji shortcode from the reaction event, used for its label. */ + shortcode?: string; useAuthentication?: boolean; } ->(({ className, mx, count, reaction, useAuthentication, ...props }, ref) => { - const shortcode = reaction.startsWith('mxc://') - ? 'custom emoji' - : (getShortcodeFor(getHexcodeForEmoji(reaction)) ?? reaction); - const label = `${shortcode} reaction, ${count} ${count === 1 ? 'person' : 'people'}`; +>(({ className, mx, count, reaction, shortcode, useAuthentication, ...props }, ref) => { + // Name a unicode reaction by the emoji itself: screen readers speak it by its + // proper name ("party popper"). Don't use getShortcodeFor here — it returns + // undefined until the lazy emoji data loads, so the same button would flip + // between "🎉 reaction" and "tada reaction" depending on timing (#179). + const name = reaction.startsWith('mxc://') + ? shortcode + ? `:${shortcode}:` + : 'custom emoji' + : reaction; + const label = `${name} reaction, ${count} ${count === 1 ? 'person' : 'people'}`; return ( ( key={key} mx={mx} reaction={key} + shortcode={rEvents.find(eventWithShortcode)?.getContent().shortcode} count={events.size} onClick={canSendReaction ? () => onReactionToggle(mEventId, key) : undefined} onContextMenu={handleViewReaction} diff --git a/src/app/features/room/reaction-viewer/ReactionViewer.tsx b/src/app/features/room/reaction-viewer/ReactionViewer.tsx index eee010893..0517ca1df 100644 --- a/src/app/features/room/reaction-viewer/ReactionViewer.tsx +++ b/src/app/features/room/reaction-viewer/ReactionViewer.tsx @@ -107,6 +107,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>( key={key} mx={mx} reaction={key} + shortcode={Array.from(evts).find(eventWithShortcode)?.getContent().shortcode} count={evts.size} role="option" aria-selected={key === selectedKey}