From 3d1ee73032b93e91239918bf2ec179db59a6d330 Mon Sep 17 00:00:00 2001 From: TaiAurori <31465218+TaiAurori@users.noreply.github.com> Date: Mon, 30 Aug 2021 18:21:49 -0400 Subject: [PATCH 1/5] invite embeds preview --- src/components/common/messaging/Message.tsx | 18 +++ .../common/messaging/embed/EmbedInvite.tsx | 141 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/components/common/messaging/embed/EmbedInvite.tsx diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 095db5da..7c008cb6 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -24,6 +24,7 @@ import MessageBase, { import Attachment from "./attachments/Attachment"; import { MessageReply } from "./attachments/MessageReply"; import Embed from "./embed/Embed"; +import EmbedInvite from "./embed/EmbedInvite"; interface Props { attachContext?: boolean; @@ -36,6 +37,7 @@ interface Props { hideReply?: boolean; } + const Message = observer( ({ highlight, @@ -142,6 +144,22 @@ const Message = observer( )} {replacement ?? } + {(() => { + if (content.includes(".revolt.chat/invite/") || content.includes("rvlt.gg/")) { + const inviteRegex = /(?:(?:app|nightly)\.revolt\.chat\/invite|rvlt.gg)\/([A-Za-z0-9]*)/g; + if (inviteRegex.test(content)) { + let results = []; + let match; + inviteRegex.lastIndex = 0; + while ((match = inviteRegex.exec(content)) !== null) { + if (!results.includes(match[1])) { + results.push(match[1]); + } + } + return results.map(code => ); + } + } + })()} {queued?.error && ( )} diff --git a/src/components/common/messaging/embed/EmbedInvite.tsx b/src/components/common/messaging/embed/EmbedInvite.tsx new file mode 100644 index 00000000..48bc59c2 --- /dev/null +++ b/src/components/common/messaging/embed/EmbedInvite.tsx @@ -0,0 +1,141 @@ +import styled from "styled-components"; + +import { autorun } from "mobx"; +import { useHistory } from "react-router-dom"; + +import { useContext, useEffect, useState } from "preact/hooks"; + +import { defer } from "../../../../lib/defer"; + +import { dispatch } from "../../../../redux"; + +import { useClient } from "../../../../context/revoltjs/RevoltClient"; + +import { + AppContext, + ClientStatus, + StatusContext, +} from "../../../../context/revoltjs/RevoltClient"; +import { takeError } from "../../../../context/revoltjs/util"; + +import ServerIcon from "../../../../components/common/ServerIcon"; +import Button from "../../../../components/ui/Button"; +import Overline from "../../../ui/Overline"; +import Preloader from "../../../ui/Preloader"; + + +const EmbedInviteBase = styled.div` + width: 400px; + height: 80px; + background-color: var(--secondary-background); + border-radius: 6px; + display: flex; + align-items: center; + padding: 0 12px; + margin-top: 2px; +`; +const EmbedInviteDetails = styled.div` + flex-grow: 1; + padding-left: 12px; +`; +const EmbedInviteName = styled.div` + font-weight: bold; +`; +const EmbedInviteMemberCount = styled.div` + font-size: 0.8em; +`; + + +export default function EmbedInvite(props) { + const history = useHistory(); + const client = useContext(AppContext); + const status = useContext(StatusContext); + const code = props.code; + const [processing, setProcessing] = useState(false); + const [error, setError] = useState(undefined); + const [invite, setInvite] = useState( + undefined, + ); + + useEffect(() => { + if ( + typeof invite === "undefined" && + (status === ClientStatus.ONLINE || status === ClientStatus.READY) + ) { + client + .fetchInvite(code) + .then((data) => setInvite(data)) + .catch((err) => setError(takeError(err))); + } + }, [client, code, invite, status]); + + if (typeof invite === "undefined") { + return + {error ? ( + + ) : ( + + )} + + } + + return + + + + {invite.server_name} + + + {invite.member_count} members + + + + +} From 0b0d1186eb215dd09398690c2039174485c7ed96 Mon Sep 17 00:00:00 2001 From: TaiAurori <31465218+TaiAurori@users.noreply.github.com> Date: Tue, 31 Aug 2021 20:30:02 +0000 Subject: [PATCH 2/5] invite embeds 2: electric boogaloo --- src/components/common/messaging/Message.tsx | 27 ++++++++++++++----- .../common/messaging/embed/EmbedInvite.tsx | 8 ++++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 7c008cb6..62e758b5 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -26,6 +26,14 @@ import { MessageReply } from "./attachments/MessageReply"; import Embed from "./embed/Embed"; import EmbedInvite from "./embed/EmbedInvite"; +const INVITE_PATHS = [ + location.hostname + "/invite", + "app.revolt.chat/invite", + "nightly.revolt.chat/invite", + "local.revolt.chat/invite", + "rvlt.gg" +] + interface Props { attachContext?: boolean; queued?: QueuedMessage; @@ -37,7 +45,6 @@ interface Props { hideReply?: boolean; } - const Message = observer( ({ highlight, @@ -145,15 +152,21 @@ const Message = observer( )} {replacement ?? } {(() => { - if (content.includes(".revolt.chat/invite/") || content.includes("rvlt.gg/")) { - const inviteRegex = /(?:(?:app|nightly)\.revolt\.chat\/invite|rvlt.gg)\/([A-Za-z0-9]*)/g; + let isInvite = false; + INVITE_PATHS.forEach(path => { + if (content.includes(path)) { + isInvite = true; + } + }) + if (isInvite) { + const inviteRegex = new RegExp("(?:" + INVITE_PATHS.map((path, index) => path.split(".").join("\\.") + (index !== INVITE_PATHS.length - 1 ? "|" : "")).join("") + ")/([A-Za-z0-9]*)", "g"); if (inviteRegex.test(content)) { - let results = []; - let match; + let results: string[] = []; + let match: RegExpExecArray | null; inviteRegex.lastIndex = 0; while ((match = inviteRegex.exec(content)) !== null) { - if (!results.includes(match[1])) { - results.push(match[1]); + if (!results.includes(match[match.length - 1])) { + results.push(match[match.length - 1]); } } return results.map(code => ); diff --git a/src/components/common/messaging/embed/EmbedInvite.tsx b/src/components/common/messaging/embed/EmbedInvite.tsx index 48bc59c2..2bb1fc78 100644 --- a/src/components/common/messaging/embed/EmbedInvite.tsx +++ b/src/components/common/messaging/embed/EmbedInvite.tsx @@ -2,6 +2,7 @@ import styled from "styled-components"; import { autorun } from "mobx"; import { useHistory } from "react-router-dom"; +import { RetrievedInvite } from "revolt-api/types/Invites"; import { useContext, useEffect, useState } from "preact/hooks"; @@ -28,7 +29,7 @@ const EmbedInviteBase = styled.div` width: 400px; height: 80px; background-color: var(--secondary-background); - border-radius: 6px; + border-radius: var(--border-radius); display: flex; align-items: center; padding: 0 12px; @@ -45,8 +46,11 @@ const EmbedInviteMemberCount = styled.div` font-size: 0.8em; `; +type Props = { + code: string +} -export default function EmbedInvite(props) { +export default function EmbedInvite(props: Props) { const history = useHistory(); const client = useContext(AppContext); const status = useContext(StatusContext); From f9bb332605fb36ca35bb29b376948f8858c30f9b Mon Sep 17 00:00:00 2001 From: TaiAurori <31465218+TaiAurori@users.noreply.github.com> Date: Tue, 31 Aug 2021 20:45:01 +0000 Subject: [PATCH 3/5] reindent --- src/components/common/messaging/Message.tsx | 28 ++++++------- .../common/messaging/embed/EmbedInvite.tsx | 40 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 62e758b5..c2f5df74 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -158,20 +158,20 @@ const Message = observer( isInvite = true; } }) - if (isInvite) { - const inviteRegex = new RegExp("(?:" + INVITE_PATHS.map((path, index) => path.split(".").join("\\.") + (index !== INVITE_PATHS.length - 1 ? "|" : "")).join("") + ")/([A-Za-z0-9]*)", "g"); - if (inviteRegex.test(content)) { - let results: string[] = []; - let match: RegExpExecArray | null; - inviteRegex.lastIndex = 0; - while ((match = inviteRegex.exec(content)) !== null) { - if (!results.includes(match[match.length - 1])) { - results.push(match[match.length - 1]); - } - } - return results.map(code => ); - } - } + if (isInvite) { + const inviteRegex = new RegExp("(?:" + INVITE_PATHS.map((path, index) => path.split(".").join("\\.") + (index !== INVITE_PATHS.length - 1 ? "|" : "")).join("") + ")/([A-Za-z0-9]*)", "g"); + if (inviteRegex.test(content)) { + let results: string[] = []; + let match: RegExpExecArray | null; + inviteRegex.lastIndex = 0; + while ((match = inviteRegex.exec(content)) !== null) { + if (!results.includes(match[match.length - 1])) { + results.push(match[match.length - 1]); + } + } + return results.map(code => ); + } + } })()} {queued?.error && ( diff --git a/src/components/common/messaging/embed/EmbedInvite.tsx b/src/components/common/messaging/embed/EmbedInvite.tsx index 2bb1fc78..06783d9a 100644 --- a/src/components/common/messaging/embed/EmbedInvite.tsx +++ b/src/components/common/messaging/embed/EmbedInvite.tsx @@ -74,29 +74,29 @@ export default function EmbedInvite(props: Props) { }, [client, code, invite, status]); if (typeof invite === "undefined") { - return - {error ? ( - - ) : ( - - )} - + return + {error ? ( + + ) : ( + + )} + } - - return + + return - - - {invite.server_name} - - - {invite.member_count} members - - + + + {invite.server_name} + + + {invite.member_count} members + + - + {client.servers.get(invite.server_id) ? "Joined" : "Join"} + + } From a10e5100d3b5d68d3366deded78629ad92f2a9d6 Mon Sep 17 00:00:00 2001 From: TaiAurori <31465218+TaiAurori@users.noreply.github.com> Date: Tue, 31 Aug 2021 21:22:19 +0000 Subject: [PATCH 4/5] add proper placeholder for invalid invite --- .../common/messaging/embed/EmbedInvite.tsx | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/components/common/messaging/embed/EmbedInvite.tsx b/src/components/common/messaging/embed/EmbedInvite.tsx index 06783d9a..42996477 100644 --- a/src/components/common/messaging/embed/EmbedInvite.tsx +++ b/src/components/common/messaging/embed/EmbedInvite.tsx @@ -74,13 +74,22 @@ export default function EmbedInvite(props: Props) { }, [client, code, invite, status]); if (typeof invite === "undefined") { - return - {error ? ( - - ) : ( + return error ? ( + + + + + Invalid invite! + + + + ) : ( + - )} - + + ) } return From 2f950aab5367de0557c93f8ca06fd34ad50c2dd3 Mon Sep 17 00:00:00 2001 From: TaiAurori <31465218+TaiAurori@users.noreply.github.com> Date: Tue, 31 Aug 2021 21:37:42 +0000 Subject: [PATCH 5/5] add visible joining indicator --- .../common/messaging/embed/EmbedInvite.tsx | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/src/components/common/messaging/embed/EmbedInvite.tsx b/src/components/common/messaging/embed/EmbedInvite.tsx index 42996477..8a1ee19c 100644 --- a/src/components/common/messaging/embed/EmbedInvite.tsx +++ b/src/components/common/messaging/embed/EmbedInvite.tsx @@ -106,49 +106,56 @@ export default function EmbedInvite(props: Props) { {invite.member_count} members - + }}> + {client.servers.get(invite.server_id) ? "Joined" : "Join"} + + )} }