invite embeds preview

This commit is contained in:
TaiAurori 2021-08-30 18:21:49 -04:00
parent 5c5c9c7d22
commit 3d1ee73032
2 changed files with 159 additions and 0 deletions

View file

@ -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(
</span>
)}
{replacement ?? <Markdown content={content} />}
{(() => {
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 => <EmbedInvite code={code} />);
}
}
})()}
{queued?.error && (
<Overline type="error" error={queued.error} />
)}

View file

@ -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<string | undefined>(undefined);
const [invite, setInvite] = useState<RetrievedInvite | undefined>(
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 <EmbedInviteBase>
{error ? (
<Overline type="error" error={error} />
) : (
<Preloader type="ring" />
)}
</EmbedInviteBase>
}
return <EmbedInviteBase>
<ServerIcon
attachment={invite.server_icon}
server_name={invite.server_name}
size={55}
/>
<EmbedInviteDetails>
<EmbedInviteName>
{invite.server_name}
</EmbedInviteName>
<EmbedInviteMemberCount>
{invite.member_count} members
</EmbedInviteMemberCount>
</EmbedInviteDetails>
<Button onClick={async () => {
try {
setProcessing(true);
if (invite.type === "Server") {
if (
client.servers.get(invite.server_id)
) {
history.push(
`/server/${invite.server_id}/channel/${invite.channel_id}`,
);
}
const dispose = autorun(() => {
const server = client.servers.get(
invite.server_id,
);
defer(() => {
if (server) {
dispatch({
type: "UNREADS_MARK_MULTIPLE_READ",
channels:
server.channel_ids,
});
history.push(
`/server/${server._id}/channel/${invite.channel_id}`,
);
}
});
dispose();
});
}
await client.joinInvite(code);
} catch (err) {
setError(takeError(err));
setProcessing(false);
}
}}>
{client.servers.get(invite.server_id) ? "Joined" : "Join"}
</Button>
</EmbedInviteBase>
}