Handle reaction app packets without reply id (#495)

* Handle reaction app packets without reply id

* render emoji text rather then emoji boolean
This commit is contained in:
l5y
2025-11-22 21:19:48 +01:00
committed by GitHub
parent d60d774e73
commit 0067d7834f
2 changed files with 73 additions and 9 deletions

View File

@@ -102,3 +102,52 @@ test('buildMessageBody suppresses reaction slot markers and formats counts', ()
assert.equal(countedBody, 'EMOJI(✨) ESC(×2)');
});
test('buildMessageBody treats REACTION_APP packets without reply identifiers as reactions', () => {
const reactionAppPacket = {
text: '1',
emoji: '🚀',
portnum: 'REACTION_APP'
};
const body = buildMessageBody({
message: reactionAppPacket,
escapeHtml: value => `ESC(${value})`,
renderEmojiHtml: value => `EMOJI(${value})`
});
assert.equal(body, 'EMOJI(🚀)');
});
test('buildMessageBody renders reaction emoji from text when emoji field carries placeholder counts', () => {
const placeholderEmojiMessage = {
text: '💩',
emoji: '1',
reply_id: 98822809,
portnum: 'TEXT_MESSAGE_APP'
};
const body = buildMessageBody({
message: placeholderEmojiMessage,
escapeHtml: value => `ESC(${value})`,
renderEmojiHtml: value => `EMOJI(${value})`
});
assert.equal(body, 'EMOJI(💩)');
});
test('buildMessageBody appends reaction counts for REACTION_APP packets without reply identifiers', () => {
const countedReactionAppPacket = {
text: '2',
emoji: '🌶',
portnum: 'REACTION_APP'
};
const body = buildMessageBody({
message: countedReactionAppPacket,
escapeHtml: value => `ESC(${value})`,
renderEmojiHtml: value => `EMOJI(${value})`
});
assert.equal(body, 'EMOJI(🌶) ESC(×2)');
});

View File

@@ -290,14 +290,16 @@ function isReactionMessage(message) {
return false;
}
const portnum = toTrimmedString(message.portnum ?? message.portNum);
if (portnum && portnum.toUpperCase() === 'REACTION_APP') {
const reactionPort = portnum && portnum.toUpperCase() === 'REACTION_APP';
if (reactionPort) {
return true;
}
const hasEmoji = !!normaliseEmojiValue(message.emoji);
if (!hasEmoji) {
return false;
}
return message.reply_id != null || message.replyId != null || !!portnum;
const hasReplyId = message.reply_id != null || message.replyId != null;
return hasReplyId || !!portnum;
}
/**
@@ -357,20 +359,33 @@ export function buildMessageBody({ message, escapeHtml, renderEmojiHtml }) {
return '';
}
const segments = [];
const segments = [];
const reaction = isReactionMessage(message);
const textSegment = resolveMessageTextSegment(message, reaction);
const reactionCount = reaction && textSegment && /^×\d+$/.test(textSegment) ? textSegment : null;
if (textSegment && !reaction) {
const emoji = normaliseEmojiValue(message.emoji);
const emojiIsNumericPlaceholder = reaction && emoji && /^\d+$/.test(emoji);
let reactionEmoji = reaction && !emojiIsNumericPlaceholder ? emoji : null;
if (!reaction && textSegment) {
segments.push(escapeHtml(textSegment));
}
const emoji = normaliseEmojiValue(message.emoji);
if (emoji) {
if (reaction) {
if (!reactionEmoji && textSegment && !reactionCount) {
reactionEmoji = textSegment;
}
if (reactionEmoji) {
segments.push(renderEmojiHtml(reactionEmoji));
} else if (textSegment && !reactionCount) {
segments.push(escapeHtml(textSegment));
}
if (reactionCount) {
segments.push(escapeHtml(reactionCount));
}
} else if (emoji) {
segments.push(renderEmojiHtml(emoji));
}
if (reactionCount) {
segments.push(escapeHtml(reactionCount));
}
if (segments.length === 0) {
return '';