Add support for custom emoji in reactions
Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
parent
e4f7c6add9
commit
20b99dce48
2 changed files with 33 additions and 5 deletions
|
@ -3,6 +3,7 @@ import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import './Message.scss';
|
import './Message.scss';
|
||||||
|
|
||||||
|
import { getShortcodeToCustomEmoji } from '../../organisms/emoji-board/custom-emoji';
|
||||||
import { twemojify } from '../../../util/twemojify';
|
import { twemojify } from '../../../util/twemojify';
|
||||||
|
|
||||||
import initMatrix from '../../../client/initMatrix';
|
import initMatrix from '../../../client/initMatrix';
|
||||||
|
@ -301,12 +302,12 @@ function genReactionMsg(userIds, reaction) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{userIds.map((userId, index) => (
|
{userIds.map((userId, index) => (
|
||||||
<>
|
<React.Fragment key={userId}>
|
||||||
{twemojify(getUsername(userId))}
|
{twemojify(getUsername(userId))}
|
||||||
<span style={{ opacity: '.6' }}>
|
<span style={{ opacity: '.6' }}>
|
||||||
{index === userIds.length - 1 ? ' and ' : ', '}
|
{index === userIds.length - 1 ? ' and ' : ', '}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
<span style={{ opacity: '.6' }}>{' reacted with '}</span>
|
<span style={{ opacity: '.6' }}>{' reacted with '}</span>
|
||||||
{twemojify(reaction, { className: 'react-emoji' })}
|
{twemojify(reaction, { className: 'react-emoji' })}
|
||||||
|
@ -315,8 +316,14 @@ function genReactionMsg(userIds, reaction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function MessageReaction({
|
function MessageReaction({
|
||||||
reaction, count, users, isActive, onClick,
|
shortcodeToEmoji, reaction, count, users, isActive, onClick,
|
||||||
}) {
|
}) {
|
||||||
|
const customEmojiMatch = reaction.match(/^:(\S+):$/);
|
||||||
|
let customEmojiUrl = null;
|
||||||
|
if (customEmojiMatch) {
|
||||||
|
const customEmoji = shortcodeToEmoji.get(customEmojiMatch[1]);
|
||||||
|
customEmojiUrl = initMatrix.matrixClient.mxcUrlToHttp(customEmoji?.mxc);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className="msg__reaction-tooltip"
|
className="msg__reaction-tooltip"
|
||||||
|
@ -327,13 +334,18 @@ function MessageReaction({
|
||||||
type="button"
|
type="button"
|
||||||
className={`msg__reaction${isActive ? ' msg__reaction--active' : ''}`}
|
className={`msg__reaction${isActive ? ' msg__reaction--active' : ''}`}
|
||||||
>
|
>
|
||||||
{ twemojify(reaction, { className: 'react-emoji' }) }
|
{
|
||||||
|
customEmojiUrl
|
||||||
|
? <img className="react-emoji" draggable="false" alt={reaction} src={customEmojiUrl} />
|
||||||
|
: twemojify(reaction, { className: 'react-emoji' })
|
||||||
|
}
|
||||||
<Text variant="b3" className="msg__reaction-count">{count}</Text>
|
<Text variant="b3" className="msg__reaction-count">{count}</Text>
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
MessageReaction.propTypes = {
|
MessageReaction.propTypes = {
|
||||||
|
shortcodeToEmoji: PropTypes.shape({}).isRequired,
|
||||||
reaction: PropTypes.node.isRequired,
|
reaction: PropTypes.node.isRequired,
|
||||||
count: PropTypes.number.isRequired,
|
count: PropTypes.number.isRequired,
|
||||||
users: PropTypes.arrayOf(PropTypes.string).isRequired,
|
users: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
@ -346,6 +358,7 @@ function MessageReactionGroup({ roomTimeline, mEvent }) {
|
||||||
const eventId = mEvent.getId();
|
const eventId = mEvent.getId();
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const reactions = {};
|
const reactions = {};
|
||||||
|
const shortcodeToEmoji = getShortcodeToCustomEmoji(roomTimeline.room);
|
||||||
|
|
||||||
const eventReactions = reactionTimeline.get(eventId);
|
const eventReactions = reactionTimeline.get(eventId);
|
||||||
const addReaction = (key, count, senderId, isActive) => {
|
const addReaction = (key, count, senderId, isActive) => {
|
||||||
|
@ -392,6 +405,7 @@ function MessageReactionGroup({ roomTimeline, mEvent }) {
|
||||||
Object.keys(reactions).map((key) => (
|
Object.keys(reactions).map((key) => (
|
||||||
<MessageReaction
|
<MessageReaction
|
||||||
key={key}
|
key={key}
|
||||||
|
shortcodeToEmoji={shortcodeToEmoji}
|
||||||
reaction={key}
|
reaction={key}
|
||||||
count={reactions[key].count}
|
count={reactions[key].count}
|
||||||
users={reactions[key].users}
|
users={reactions[key].users}
|
||||||
|
|
|
@ -147,6 +147,18 @@ function getShortcodeToEmoji(room) {
|
||||||
return allEmoji;
|
return allEmoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getShortcodeToCustomEmoji(room) {
|
||||||
|
const allEmoji = new Map();
|
||||||
|
|
||||||
|
getRelevantPacks(room).reverse()
|
||||||
|
.flatMap((pack) => pack.getEmojis())
|
||||||
|
.forEach((emoji) => {
|
||||||
|
allEmoji.set(emoji.shortcode, emoji);
|
||||||
|
});
|
||||||
|
|
||||||
|
return allEmoji;
|
||||||
|
}
|
||||||
|
|
||||||
// Produces a special list of emoji specifically for auto-completion
|
// Produces a special list of emoji specifically for auto-completion
|
||||||
//
|
//
|
||||||
// This list contains each emoji once, with all emoji being deduplicated by shortcode.
|
// This list contains each emoji once, with all emoji being deduplicated by shortcode.
|
||||||
|
@ -167,5 +179,7 @@ function getEmojiForCompletion(room) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getUserImagePack, getShortcodeToEmoji, getRelevantPacks, getEmojiForCompletion,
|
getUserImagePack,
|
||||||
|
getShortcodeToEmoji, getShortcodeToCustomEmoji,
|
||||||
|
getRelevantPacks, getEmojiForCompletion,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue