mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-25 08:30:58 -05:00
feat: add reactions
This commit is contained in:
parent
dbe8a64ffc
commit
084c90613f
7 changed files with 95 additions and 20 deletions
|
@ -141,7 +141,7 @@
|
|||
"remark-math": "^5.1.1",
|
||||
"remark-parse": "^10.0.1",
|
||||
"remark-rehype": "^10.1.0",
|
||||
"revolt.js": "6.0.9",
|
||||
"revolt.js": "6.0.12",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass": "^1.35.1",
|
||||
"semver": "^7.3.7",
|
||||
|
|
|
@ -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 && (
|
||||
|
|
71
src/components/common/messaging/attachments/Reactions.tsx
Normal file
71
src/components/common/messaging/attachments/Reactions.tsx
Normal 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>
|
||||
);
|
||||
});
|
|
@ -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])
|
||||
: `${
|
||||
const url = RE_ULID.test(match)
|
||||
? `${
|
||||
clientController.getAvailableClient().configuration?.features
|
||||
.autumn.url
|
||||
}/emojis/${match}`;
|
||||
}/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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -3696,7 +3696,7 @@ __metadata:
|
|||
remark-math: ^5.1.1
|
||||
remark-parse: ^10.0.1
|
||||
remark-rehype: ^10.1.0
|
||||
revolt.js: 6.0.9
|
||||
revolt.js: 6.0.12
|
||||
rimraf: ^3.0.2
|
||||
sass: ^1.35.1
|
||||
semver: ^7.3.7
|
||||
|
@ -7890,9 +7890,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"revolt.js@npm:6.0.9":
|
||||
version: 6.0.9
|
||||
resolution: "revolt.js@npm:6.0.9"
|
||||
"revolt.js@npm:6.0.12":
|
||||
version: 6.0.12
|
||||
resolution: "revolt.js@npm:6.0.12"
|
||||
dependencies:
|
||||
"@insertish/exponential-backoff": 3.1.0-patch.2
|
||||
"@insertish/isomorphic-ws": ^4.0.1
|
||||
|
@ -7906,7 +7906,7 @@ __metadata:
|
|||
revolt-api: 0.5.5
|
||||
ulid: ^2.3.0
|
||||
ws: ^8.2.2
|
||||
checksum: a3ea924a6793f6a4aa5f62e660b249bd76bbe2f0048d9b374a449f064ee6d65df1b8e4e3af1d15267707ea6d35b6a3101349b0bf41fa323cb5c298ab98de8d45
|
||||
checksum: 1ff667daf3e7c9b32ee383d56f79db9d5112b1ca87eb406c749fa3ce5f8adb59cd48ec3cb935932a5cc5da0af6f82e2dd7b5b83fa0705e02f66c050bc848401a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in a new issue