feat: add reactions

This commit is contained in:
Paul Makles
2022-07-16 15:17:02 +01:00
parent bd1bc79996
commit af7cd15681
7 changed files with 95 additions and 20 deletions

View File

@@ -25,6 +25,7 @@ import MessageBase, {
} from "./MessageBase";
import Attachment from "./attachments/Attachment";
import { MessageReply } from "./attachments/MessageReply";
import { Reactions } from "./attachments/Reactions";
import { MessageOverlayBar } from "./bars/MessageOverlayBar";
import Embed from "./embed/Embed";
import InviteList from "./embed/EmbedInvite";
@@ -180,6 +181,7 @@ const Message = observer(
{message.embeds?.map((embed, index) => (
<Embed key={index} embed={embed} />
))}
<Reactions message={message} />
{mouseHovering &&
!replacement &&
!isTouchscreenDevice && (

View File

@@ -0,0 +1,71 @@
import { observer } from "mobx-react-lite";
import { Message } from "revolt.js";
import styled, { css } from "styled-components";
import { useClient } from "../../../../controllers/client/ClientController";
import { RenderEmoji } from "../../../markdown/plugins/emoji";
interface Props {
message: Message;
}
const List = styled.div`
gap: 0.4em;
display: flex;
flex-wrap: wrap;
margin-top: 0.2em;
`;
const Reaction = styled.div<{ active: boolean }>`
padding: 0.4em;
cursor: pointer;
user-select: none;
vertical-align: middle;
color: var(--secondary-foreground);
border-radius: var(--border-radius);
background: var(--secondary-background);
img {
width: 1.2em;
height: 1.2em;
object-fit: contain;
}
&:hover {
filter: brightness(0.9);
}
&:active {
filter: brightness(0.75);
}
${(props) =>
props.active &&
css`
border: 1px solid var(--accent);
`}
`;
export const Reactions = observer(({ message }: Props) => {
const client = useClient();
if (message.reactions.size === 0) return null;
return (
<List>
{Array.from(message.reactions, ([key, user_ids]) => {
const active = user_ids.has(client.user!._id);
return (
<Reaction
key={key}
active={active}
onClick={() =>
active ? message.unreact(key) : message.react(key)
}>
<RenderEmoji match={key} /> {user_ids.size}
</Reaction>
);
})}
</List>
);
});

View File

@@ -25,15 +25,21 @@ const Emoji = styled.img`
}
`;
const RE_EMOJI = /:([a-zA-Z0-9_+]+):/g;
const RE_ULID = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
export function RenderEmoji({ match }: CustomComponentProps) {
const [fail, setFail] = useState(false);
const url =
match in emojiDictionary
? parseEmoji(emojiDictionary[match as keyof typeof emojiDictionary])
: `${
clientController.getAvailableClient().configuration?.features
.autumn.url
}/emojis/${match}`;
const url = RE_ULID.test(match)
? `${
clientController.getAvailableClient().configuration?.features
.autumn.url
}/emojis/${match}`
: parseEmoji(
match in emojiDictionary
? emojiDictionary[match as keyof typeof emojiDictionary]
: match,
);
if (fail) return <span>{`:${match}:`}</span>;
@@ -49,9 +55,6 @@ export function RenderEmoji({ match }: CustomComponentProps) {
);
}
const RE_EMOJI = /:([a-zA-Z0-9_+]+):/g;
const RE_ULID = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
export const remarkEmoji = createComponent(
"emoji",
RE_EMOJI,

View File

@@ -6,9 +6,9 @@ import { visit } from "unist-util-visit";
* Props given to custom components
*/
export interface CustomComponentProps {
type: string;
type?: string;
match: string;
arg1: string;
arg1?: string;
}
/**

View File

@@ -1,5 +1,4 @@
import { API, Channel, Member, Server } from "revolt.js";
import { Permission } from "revolt.js";
import { API, Channel, Permission, Server } from "revolt.js";
import { PermissionSelect } from "./PermissionSelect";