merge: branch 'master' into production

This commit is contained in:
Paul Makles 2022-09-02 14:42:47 +01:00
commit 8608257066
6 changed files with 70 additions and 57 deletions

2
external/components vendored

@ -1 +1 @@
Subproject commit 5e6e4a09c45baf18dcc44925f0113bad1d732e9c
Subproject commit 557094115d17a363eb6fb8f27c6e697e049ce623

2
external/lang vendored

@ -1 +1 @@
Subproject commit 8ec1e5571e3d29a93500c0199f6823d16056b6f8
Subproject commit 05e7213b2290dfced3d41d54cb85f49670404cf2

View file

@ -4,12 +4,15 @@ import {
shift,
useFloating,
} from "@floating-ui/react-dom-interactions";
import { Plus } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite";
import { Message } from "revolt.js";
import styled, { css } from "styled-components";
import { createPortal } from "preact/compat";
import { useCallback, useRef } from "preact/hooks";
import { useCallback, useRef, useState } from "preact/hooks";
import { IconButton } from "@revoltchat/ui";
import { emojiDictionary } from "../../../../assets/emojis";
import { useClient } from "../../../../controllers/client/ClientController";
@ -29,6 +32,14 @@ const List = styled.div`
flex-wrap: wrap;
margin-top: 0.2em;
align-items: center;
.add {
display: none;
}
&:hover .add {
display: grid;
}
`;
/**
@ -79,6 +90,7 @@ const Reaction = styled.div<{ active: boolean }>`
*/
export const Reactions = observer(({ message }: Props) => {
const client = useClient();
const [showPicker, setPicker] = useState(false);
/**
* Render individual reaction entries
@ -137,6 +149,16 @@ export const Reactions = observer(({ message }: Props) => {
{Array.from(optional, (id) => (
<Entry key={id} id={id} user_ids={message.reactions.get(id)} />
))}
{message.channel?.havePermission("React") && (
<ReactionWrapper
message={message}
open={showPicker}
setOpen={setPicker}>
<IconButton className={showPicker ? "" : "add"}>
<Plus size={20} />
</IconButton>
</ReactionWrapper>
)}
</List>
);
});

View file

@ -184,6 +184,11 @@ const Container = styled.div<{ largeEmoji: boolean }>`
*/
const RE_QUOTE = /(^(?:>\s?){5})[>\s?]+(.*$)/gm;
/**
* Regex for matching multi-line blockquotes
*/
const RE_BLOCKQUOTE = /^([^\S\r\n]*>[^\n]+\n?)+/gm;
/**
* Regex for matching HTML tags
*/
@ -214,6 +219,9 @@ function sanitise(content: string) {
// because remark renderer is collapsing empty
// or otherwise whitespace-only lines of text
.replace(RE_EMPTY_LINE, "")
// Ensure empty line after blockquotes for correct rendering
.replace(RE_BLOCKQUOTE, (match) => `${match}\n`)
);
}

View file

@ -1,8 +1,9 @@
import { Server } from "revolt.js";
import { Text } from "preact-i18n";
import { useState } from "preact/hooks";
import { Form } from "@revoltchat/ui";
import { Button, Column, Form, FormElement, Row } from "@revoltchat/ui";
import { FileUploader } from "../../../controllers/client/jsx/legacy/FileUploads";
@ -15,7 +16,9 @@ export function EmojiUploader({ server }: Props) {
return (
<>
<h3>Upload Emoji</h3>
<h3>
<Text id="app.settings.server_pages.emojis.upload" />
</h3>
<Form
schema={{
name: "text",
@ -42,11 +45,6 @@ export function EmojiUploader({ server }: Props) {
),
},
}}
submitBtn={{
children: "Save",
palette: "secondary",
disabled: !fileId,
}}
onSubmit={async ({ name }) => {
await server.client.api.put(`/custom/emoji/${fileId}`, {
name,
@ -54,8 +52,20 @@ export function EmojiUploader({ server }: Props) {
});
setFileId("");
}}
/>
}}>
<Row>
<FormElement id="file" />
<Column>
<FormElement id="name" />
<Button
type="submit"
palette="secondary"
disabled={!fileId}>
<Text id="app.special.modals.actions.save" />
</Button>
</Column>
</Row>
</Form>
</>
);
}

View file

@ -8,40 +8,24 @@ import { Button, Column, Row, Stacked } from "@revoltchat/ui";
import UserShort from "../../../components/common/user/UserShort";
import { EmojiUploader } from "../../../components/settings/customisation/EmojiUploader";
import { modalController } from "../../../controllers/modals/ModalController";
interface Props {
server: Server;
}
const List = styled.div`
gap: 8px;
display: flex;
flex-wrap: wrap;
`;
const Emoji = styled(Column)`
const Emoji = styled(Row)`
padding: 8px;
border-radius: var(--border-radius);
background: var(--secondary-background);
`;
const Preview = styled.img`
width: 72px;
height: 72px;
width: 32px;
height: 32px;
object-fit: contain;
border-radius: var(--border-radius);
`;
const UserInfo = styled(Row)`
font-size: 12px;
svg {
width: 14px;
height: 14px;
}
`;
export const Emojis = observer(({ server }: Props) => {
const emoji = [...server.client.emojis.values()].filter(
(x) => x.parent.type === "Server" && x.parent.id === server._id,
@ -57,33 +41,22 @@ export const Emojis = observer(({ server }: Props) => {
{" "}
{emoji.length}
</h3>
<List>
{emoji.map((emoji) => (
<Emoji key={emoji._id} centred>
<Stacked>
<Preview src={emoji.imageURL} />
</Stacked>
<span>{`:${emoji.name}:`}</span>
<UserInfo centred>
<UserShort user={emoji.creator} />
</UserInfo>
<Button
palette="plain"
onClick={() =>
modalController.writeText(emoji._id)
}>
<Text id="app.context_menu.copy_id" />
{emoji.map((emoji) => (
<Emoji key={emoji._id} centred>
<Stacked>
<Preview src={emoji.imageURL} />
</Stacked>
<span>{`:${emoji.name}:`}</span>
<Row centred>
<UserShort user={emoji.creator} />
</Row>
{server.havePermission("ManageCustomisation") && (
<Button palette="plain" onClick={() => emoji.delete()}>
<Text id="app.special.modals.actions.delete" />
</Button>
{server.havePermission("ManageCustomisation") && (
<Button
palette="plain"
onClick={() => emoji.delete()}>
<Text id="app.special.modals.actions.delete" />
</Button>
)}
</Emoji>
))}
</List>
)}
</Emoji>
))}
</Column>
);
});