merge: branch 'quark/permissions'

This commit is contained in:
Paul Makles
2022-04-29 13:48:38 +01:00
117 changed files with 10609 additions and 6253 deletions

View File

@@ -1,5 +1,5 @@
import { observer } from "mobx-react-lite";
import { Message as MessageObject } from "revolt.js/dist/maps/Messages";
import { Message as MessageObject } from "revolt.js";
import { useTriggerEvents } from "preact-context-menu";
import { memo } from "preact/compat";

View File

@@ -1,5 +1,5 @@
import { observer } from "mobx-react-lite";
import { Message } from "revolt.js/dist/maps/Messages";
import { Message } from "revolt.js";
import styled, { css, keyframes } from "styled-components/macro";
import { decodeTime } from "ulid";

View File

@@ -1,8 +1,16 @@
import { Send, ShieldX, HappyBeaming, Box } from "@styled-icons/boxicons-solid";
import { Send, ShieldX } from "@styled-icons/boxicons-solid";
import Axios, { CancelTokenSource } from "axios";
import Long from "long";
import { observer } from "mobx-react-lite";
import { ChannelPermission } from "revolt.js/dist/api/permissions";
import { Channel } from "revolt.js/dist/maps/Channels";
import {
Channel,
DEFAULT_PERMISSION_DIRECT_MESSAGE,
DEFAULT_PERMISSION_VIEW_ONLY,
Permission,
Server,
U32_MAX,
UserPermission,
} from "revolt.js";
import styled, { css } from "styled-components/macro";
import { ulid } from "ulid";
@@ -125,6 +133,11 @@ const FileAction = styled.div`
display: flex;
align-items: center;
justify-content: center;
}
`;
const ThisCodeWillBeReplacedAnywaysSoIMightAsWellJustDoItThisWay__Padding = styled.div`
width: 16px;
`;
// For sed replacement
@@ -150,7 +163,7 @@ export default observer(({ channel }: Props) => {
const renderer = getRenderer(channel);
if (!(channel.permission & ChannelPermission.SendMessage)) {
if (!channel.havePermission("SendMessage")) {
return (
<Base>
<Blocked>
@@ -231,7 +244,7 @@ export default observer(({ channel }: Props) => {
);
renderer.messages.reverse();
if (msg) {
if (msg?.content) {
// eslint-disable-next-line prefer-const
let [_, toReplace, newText, flags] = content.split(/\//);
@@ -493,7 +506,7 @@ export default observer(({ channel }: Props) => {
setReplies={setReplies}
/>
<Base>
{channel.permission & ChannelPermission.UploadFiles ? (
{channel.havePermission("UploadFiles") ? (
<FileAction>
<FileUploader
size={24}
@@ -530,7 +543,9 @@ export default observer(({ channel }: Props) => {
}}
/>
</FileAction>
) : undefined}
) : (
<ThisCodeWillBeReplacedAnywaysSoIMightAsWellJustDoItThisWay__Padding />
)}
<TextAreaAutoSize
autoFocus
hideBorder

View File

@@ -11,8 +11,7 @@ import {
MessageSquareEdit,
} from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { SystemMessage as SystemMessageI } from "revolt-api/types/Channels";
import { Message } from "revolt.js/dist/maps/Messages";
import { Message, API } from "revolt.js";
import styled from "styled-components/macro";
import { useTriggerEvents } from "preact-context-menu";
@@ -75,13 +74,11 @@ export const SystemMessage = observer(
({ attachContext, message, highlight, hideInfo }: Props) => {
const data = message.asSystemMessage;
const SystemMessageIcon =
iconDictionary[data.type as SystemMessageI["type"]] ?? InfoCircle;
iconDictionary[data.type as API.SystemMessage["type"]] ??
InfoCircle;
let children;
let children = null;
switch (data.type) {
case "text":
children = <span>{data.content}</span>;
break;
case "user_added":
case "user_remove":
children = (

View File

@@ -1,4 +1,4 @@
import { Attachment as AttachmentI } from "revolt-api/types/Autumn";
import { API } from "revolt.js";
import styles from "./Attachment.module.scss";
import classNames from "classnames";
@@ -14,7 +14,7 @@ import Spoiler from "./Spoiler";
import TextFile from "./TextFile";
interface Props {
attachment: AttachmentI;
attachment: API.File;
hasContent?: boolean;
}

View File

@@ -4,7 +4,7 @@ import {
Download,
} from "@styled-icons/boxicons-regular";
import { File, Video } from "@styled-icons/boxicons-solid";
import { Attachment } from "revolt-api/types/Autumn";
import { API } from "revolt.js";
import styles from "./AttachmentActions.module.scss";
import classNames from "classnames";
@@ -17,7 +17,7 @@ import { AppContext } from "../../../../context/revoltjs/RevoltClient";
import IconButton from "../../../ui/IconButton";
interface Props {
attachment: Attachment;
attachment: API.File;
}
export default function AttachmentActions({ attachment }: Props) {

View File

@@ -1,4 +1,4 @@
import { Attachment } from "revolt-api/types/Autumn";
import { API } from "revolt.js";
import styles from "./Attachment.module.scss";
import classNames from "classnames";
@@ -10,12 +10,12 @@ import { AppContext } from "../../../../context/revoltjs/RevoltClient";
enum ImageLoadingState {
Loading,
Loaded,
Error
Error,
}
type Props = JSX.HTMLAttributes<HTMLImageElement> & {
attachment: Attachment;
}
attachment: API.File;
};
export default function ImageFile({ attachment, ...props }: Props) {
const [loading, setLoading] = useState(ImageLoadingState.Loading);
@@ -23,25 +23,19 @@ export default function ImageFile({ attachment, ...props }: Props) {
const { openScreen } = useIntermediate();
const url = client.generateFileURL(attachment)!;
return <img
{...props}
src={url}
alt={attachment.filename}
loading="lazy"
className={classNames(styles.image, {
[styles.loading]: loading !== ImageLoadingState.Loaded
})}
onClick={() =>
openScreen({ id: "image_viewer", attachment })
}
onMouseDown={(ev) =>
ev.button === 1 && window.open(url, "_blank")
}
onLoad={() =>
setLoading(ImageLoadingState.Loaded)
}
onError={() =>
setLoading(ImageLoadingState.Error)
}
/>
return (
<img
{...props}
src={url}
alt={attachment.filename}
loading="lazy"
className={classNames(styles.image, {
[styles.loading]: loading !== ImageLoadingState.Loaded,
})}
onClick={() => openScreen({ id: "image_viewer", attachment })}
onMouseDown={(ev) => ev.button === 1 && window.open(url, "_blank")}
onLoad={() => setLoading(ImageLoadingState.Loaded)}
onError={() => setLoading(ImageLoadingState.Error)}
/>
);
}

View File

@@ -2,9 +2,7 @@ import { Reply } from "@styled-icons/boxicons-regular";
import { File } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { useHistory } from "react-router-dom";
import { RelationshipStatus } from "revolt-api/types/Users";
import { Channel } from "revolt.js/dist/maps/Channels";
import { Message } from "revolt.js/dist/maps/Messages";
import { Channel, Message, API } from "revolt.js";
import styled, { css } from "styled-components/macro";
import { Text } from "preact-i18n";
@@ -174,7 +172,7 @@ export const MessageReply = observer(
<ReplyBase head={index === 0}>
{/*<Reply size={16} />*/}
{message.author?.relationship === RelationshipStatus.Blocked ? (
{message.author?.relationship === "Blocked" ? (
<Text id="app.main.channel.misc.blocked_user" />
) : (
<>

View File

@@ -1,5 +1,5 @@
import axios from "axios";
import { Attachment } from "revolt-api/types/Autumn";
import { API } from "revolt.js";
import styles from "./Attachment.module.scss";
import { useContext, useEffect, useState } from "preact/hooks";
@@ -13,7 +13,7 @@ import {
import Preloader from "../../../ui/Preloader";
interface Props {
attachment: Attachment;
attachment: API.File;
}
const fileCache: { [key: string]: string } = {};

View File

@@ -1,6 +1,6 @@
import { DownArrowAlt } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite";
import { Channel } from "revolt.js/dist/maps/Channels";
import { Channel } from "revolt.js";
import styled, { css } from "styled-components/macro";
import { Text } from "preact-i18n";

View File

@@ -7,8 +7,8 @@ import {
Notification,
} from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { ChannelPermission } from "revolt.js";
import { Message as MessageObject } from "revolt.js/dist/maps/Messages";
import { Permission } from "revolt.js";
import { Message as MessageObject } from "revolt.js";
import styled from "styled-components";
import { openContextMenu } from "preact-context-menu";
@@ -131,8 +131,7 @@ export const MessageOverlayBar = observer(({ message, queued }: Props) => {
)}
{isAuthor ||
(message.channel &&
message.channel.permission &
ChannelPermission.ManageMessages) ? (
message.channel.havePermission("ManageMessages")) ? (
<Tooltip content="Delete">
<Entry
onClick={(e) =>

View File

@@ -1,7 +1,7 @@
import { UpArrowAlt } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite";
import { useHistory } from "react-router-dom";
import { Channel } from "revolt.js/dist/maps/Channels";
import { Channel } from "revolt.js";
import { decodeTime } from "ulid";
import { Text } from "preact-i18n";

View File

@@ -1,8 +1,7 @@
import { At, Reply as ReplyIcon } from "@styled-icons/boxicons-regular";
import { At } from "@styled-icons/boxicons-regular";
import { File, XCircle } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite";
import { Channel } from "revolt.js/dist/maps/Channels";
import { Message } from "revolt.js/dist/maps/Messages";
import { Channel, Message } from "revolt.js";
import styled from "styled-components/macro";
import { Text } from "preact-i18n";

View File

@@ -1,6 +1,5 @@
import { observer } from "mobx-react-lite";
import { RelationshipStatus } from "revolt-api/types/Users";
import { Channel } from "revolt.js/dist/maps/Channels";
import { Channel } from "revolt.js";
import styled from "styled-components/macro";
import { Text } from "preact-i18n";
@@ -65,7 +64,7 @@ export default observer(({ channel }: Props) => {
(x) =>
typeof x !== "undefined" &&
x._id !== x.client.user!._id &&
x.relationship !== RelationshipStatus.Blocked,
x.relationship !== "Blocked",
);
if (users.length > 0) {

View File

@@ -1,4 +1,4 @@
import { Embed as EmbedI } from "revolt-api/types/Channels";
import { API } from "revolt.js";
import styles from "./Embed.module.scss";
import classNames from "classnames";
@@ -13,7 +13,7 @@ import Attachment from "../attachments/Attachment";
import EmbedMedia from "./EmbedMedia";
interface Props {
embed: EmbedI;
embed: API.Embed;
}
const MAX_EMBED_WIDTH = 480;
@@ -128,7 +128,7 @@ export default function Embed({ embed }: Props) {
<a
onMouseDown={(ev) =>
(ev.button === 0 || ev.button === 1) &&
openLink(embed.url)
openLink(embed.url!)
}
className={styles.title}>
{embed.title}

View File

@@ -1,14 +1,12 @@
import { Group } from "@styled-icons/boxicons-solid";
import { autorun, reaction } from "mobx";
import { reaction } from "mobx";
import { observer } from "mobx-react-lite";
import { useHistory } from "react-router-dom";
import { RetrievedInvite } from "revolt-api/types/Invites";
import { Message } from "revolt.js/dist/maps/Messages";
import { Message, API } from "revolt.js";
import styled, { css } from "styled-components/macro";
import { useContext, useEffect, useState } from "preact/hooks";
import { defer } from "../../../../lib/defer";
import { isTouchscreenDevice } from "../../../../lib/isTouchscreenDevice";
import {
@@ -85,9 +83,9 @@ export function EmbedInvite({ code }: Props) {
const [processing, setProcessing] = useState(false);
const [error, setError] = useState<string | undefined>(undefined);
const [joinError, setJoinError] = useState<string | undefined>(undefined);
const [invite, setInvite] = useState<RetrievedInvite | undefined>(
undefined,
);
const [invite, setInvite] = useState<
(API.InviteResponse & { type: "Server" }) | undefined
>(undefined);
useEffect(() => {
if (
@@ -96,7 +94,9 @@ export function EmbedInvite({ code }: Props) {
) {
client
.fetchInvite(code)
.then((data) => setInvite(data))
.then((data) =>
setInvite(data as API.InviteResponse & { type: "Server" }),
)
.catch((err) => setError(takeError(err)));
}
}, [client, code, invite, status]);
@@ -139,42 +139,17 @@ export function EmbedInvite({ code }: Props) {
) : (
<Button
onClick={async () => {
setProcessing(true);
try {
setProcessing(true);
await client.joinInvite(invite);
if (invite.type === "Server") {
if (client.servers.get(invite.server_id)) {
history.push(
`/server/${invite.server_id}/channel/${invite.channel_id}`,
);
return;
}
const dispose = reaction(
() =>
client.servers.get(
invite.server_id,
),
(server) => {
if (server) {
client.unreads!.markMultipleRead(
server.channel_ids,
);
history.push(
`/server/${server._id}/channel/${invite.channel_id}`,
);
dispose();
}
},
);
}
await client.joinInvite(code);
history.push(
`/server/${invite.server_id}/channel/${invite.channel_id}`,
);
} catch (err) {
setJoinError(takeError(err));
} finally {
setProcessing(false);
}
}}>

View File

@@ -1,5 +1,5 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { JanuaryEmbed } from "revolt-api/types/January";
import { API } from "revolt.js";
import styles from "./Embed.module.scss";
@@ -7,7 +7,7 @@ import { useIntermediate } from "../../../../context/intermediate/Intermediate";
import { useClient } from "../../../../context/revoltjs/RevoltClient";
interface Props {
embed: JanuaryEmbed;
embed: API.Embed;
width?: number;
height: number;
}
@@ -94,7 +94,7 @@ export default function EmbedMedia({ embed, width, height }: Props) {
onClick={() =>
openScreen({
id: "image_viewer",
embed: embed.image,
embed: embed.image!,
})
}
onMouseDown={(ev) =>

View File

@@ -1,12 +1,12 @@
import { LinkExternal } from "@styled-icons/boxicons-regular";
import { EmbedImage } from "revolt-api/types/January";
import { API } from "revolt.js";
import styles from "./Embed.module.scss";
import IconButton from "../../../ui/IconButton";
interface Props {
embed: EmbedImage;
embed: API.Image;
}
export default function EmbedMediaActions({ embed }: Props) {