feat(channels): show reactor's short name next to emoji reactions (#4243) - #4247
Conversation
) The reacting node's short name was only reachable via the bubble's `title` attribute -- a hover tooltip, which is unusable on touch and invisible at a glance. `getNodeShortName(reaction.from)` was already being called at this exact call site to feed that tooltip. Render it inline beside the emoji instead. The tooltip is kept, so this is additive rather than a replacement. Adds the first test file for ChannelsTab. It mocks useNodes / useSettings / useNotificationMuteSettings rather than standing up the provider tree, and stubs ResizeObserver locally rather than editing the shared test setup. Verified the test actually catches the regression: with the source change reverted, the two behavior assertions fail and the two unchanged-behavior guards still pass. Closes #4243 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bxVewVnissUKiGZmhf9FW
|
Claude finished @Yeraze's task —— View job PR Review: feat(channels): show reactor's short name next to emoji reactions (#4243)Tasks:
SummaryThis is a clean, well-scoped change. The implementation is minimal and correct, and notably this PR establishes the first test file for ChannelsTab.tsx
const reactorName = getNodeShortName(reaction.from);
return (
<span
key={reaction.id}
className={`reaction ${isMyMessage(reaction) ? 'mine' : 'theirs'}`}
{ name: reactorName })}
onClick={() => handleSendTapback(reaction.text, msg)}
>
{reaction.text}
{reactorName && (
<span className="reaction__author">{reactorName}</span>
)}
</span>
);Minor observation: No issues with the implementation itself. nodes.css
.reaction__author {
margin-left: 4px;
font-size: 11px;
font-weight: 600;
line-height: 1;
white-space: nowrap;
}
.reaction.mine .reaction__author {
color: var(--ctp-base);
}
.reaction.theirs .reaction__author {
color: var(--ctp-subtext0);
}
Minor observation: Node short names can be up to 4 chars (typical Meshtastic limit is 4 characters), but emoji short names (used when a node's short name is itself an emoji) could render in the author slot as an emoji sequence. ChannelsTab.reactions.test.tsxThis is a solid test file for the new behavior. A few observations: Positive:
Observation on test fixture — markMessagesAsRead: noop,
markMessagesAsRead: asyncNoop,Observation on test structure: The tests use Overall Assessment✅ Code quality — Clean, minimal implementation following existing patterns in the codebase This PR is ready to merge with just the minor nit above to consider. Good work establishing test coverage for |
Closes #4243
Problem
In Channel Messages, the reacting node's short name was only available through the reaction bubble's
titleattribute — a browser hover tooltip. That's unreachable on touch devices and invisible at a glance, so reactions read as anonymous.getNodeShortName(reaction.from)was already being called at that exact call site purely to feed the tooltip.Change
Render the short name inline beside the emoji (
.reaction__author), keeping the tooltip. The label is smaller and lighter than the emoji so the emoji stays the primary mark, and it picks up a contrasting color in.minevs.theirsbubbles.getNodeShortNamenever returns empty — it falls back to the last 4 chars of the node id — so the label always renders; the truthiness guard is defensive only.Tests
This adds the first test file for ChannelsTab. The component takes all 37 required values as props and uses no
useContextdirectly, but it does call three hooks internally (useNodes,useSettings,useNotificationMuteSettings), so those are mocked rather than standing up the full provider tree.ResizeObserveris stubbed locally rather than insrc/test/setup.ts, to avoid changing the environment for every other test in this PR.I verified the test catches the regression rather than assuming it: with the source change stashed, the two behavior assertions fail and the two unchanged-behavior guards (tooltip preserved, parent not rendered as a bubble) still pass.
Validation
ChannelsTab.reactions.test.tsx— 4 tests,success: truenpx tsc --noEmit— no errorsnpx eslinton both changed source files — cleanNote
Multiple reactors with the same emoji already render as separate bubbles, so each gets its own name label — there's no grouping/count behavior to reconcile. If you'd prefer grouped bubbles (
👍 3with names in the tooltip), that's a different design and worth its own issue.🤖 Generated with Claude Code
https://claude.ai/code/session_016bxVewVnissUKiGZmhf9FW