diff --git a/external/lang b/external/lang index 58a9fb69..1a854216 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit 58a9fb697de00f570d445be4d12e3ce4a5e3522e +Subproject commit 1a8542166173445602c0a4a8f821806002fd2fc4 diff --git a/package.json b/package.json index 16a74c74..cf936e57 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 76c3afc1..b1fae6a6 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -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) => ( ))} + {mouseHovering && !replacement && !isTouchscreenDevice && ( diff --git a/src/components/common/messaging/attachments/Reactions.tsx b/src/components/common/messaging/attachments/Reactions.tsx new file mode 100644 index 00000000..b9c7380a --- /dev/null +++ b/src/components/common/messaging/attachments/Reactions.tsx @@ -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 ( + + {Array.from(message.reactions, ([key, user_ids]) => { + const active = user_ids.has(client.user!._id); + + return ( + + active ? message.unreact(key) : message.react(key) + }> + {user_ids.size} + + ); + })} + + ); +}); diff --git a/src/components/common/user/UserShort.tsx b/src/components/common/user/UserShort.tsx index b2ca22b2..6f9071de 100644 --- a/src/components/common/user/UserShort.tsx +++ b/src/components/common/user/UserShort.tsx @@ -1,7 +1,7 @@ import { observer } from "mobx-react-lite"; import { useParams } from "react-router-dom"; import { User, API } from "revolt.js"; -import styled from "styled-components/macro"; +import styled, { css } from "styled-components/macro"; import { Ref } from "preact"; import { Text } from "preact-i18n"; @@ -39,10 +39,18 @@ type UsernameProps = Omit< }; const Name = styled.span<{ colour?: string | null }>` - background: ${(props) => props.colour ?? "var(--foreground)"}; - background-clip: text; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; + ${(props) => + props.colour && + (props.colour.includes("gradient") + ? css` + background: ${props.colour}; + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + ` + : css` + color: ${props.colour}; + `)} `; export const Username = observer( diff --git a/src/components/markdown/plugins/emoji.tsx b/src/components/markdown/plugins/emoji.tsx index 15ca52e4..9993189d 100644 --- a/src/components/markdown/plugins/emoji.tsx +++ b/src/components/markdown/plugins/emoji.tsx @@ -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 {`:${match}:`}; @@ -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, diff --git a/src/components/markdown/plugins/remarkRegexComponent.ts b/src/components/markdown/plugins/remarkRegexComponent.ts index 6693f7b5..47095c7c 100644 --- a/src/components/markdown/plugins/remarkRegexComponent.ts +++ b/src/components/markdown/plugins/remarkRegexComponent.ts @@ -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; } /** diff --git a/src/components/settings/roles/PermissionList.tsx b/src/components/settings/roles/PermissionList.tsx index ce514f9f..79039fb2 100644 --- a/src/components/settings/roles/PermissionList.tsx +++ b/src/components/settings/roles/PermissionList.tsx @@ -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"; diff --git a/yarn.lock b/yarn.lock index dc947708..1b3ac129 100644 --- a/yarn.lock +++ b/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