feat: add test emoji page

This commit is contained in:
Paul Makles 2022-07-07 17:33:33 +01:00
parent a766183f01
commit b541301cb1
7 changed files with 205 additions and 32 deletions

View file

@ -125,7 +125,7 @@
"preact-context-menu": "0.4.1", "preact-context-menu": "0.4.1",
"preact-i18n": "^2.4.0-preactx", "preact-i18n": "^2.4.0-preactx",
"prettier": "^2.3.1", "prettier": "^2.3.1",
"prismjs": "^1.23.0", "prismjs": "^1.28.0",
"qrcode.react": "^3.0.2", "qrcode.react": "^3.0.2",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
"react-device-detect": "2.2.2", "react-device-detect": "2.2.2",
@ -135,7 +135,7 @@
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scroll": "^1.8.2", "react-scroll": "^1.8.2",
"react-virtuoso": "^2.12.0", "react-virtuoso": "^2.12.0",
"revolt.js": "6.0.3", "revolt.js": "6.0.4",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.35.1", "sass": "^1.35.1",
"semver": "^7.3.7", "semver": "^7.3.7",
@ -156,5 +156,8 @@
"repository": "https://github.com/revoltchat/revite.git", "repository": "https://github.com/revoltchat/revite.git",
"author": "Paul <paulmakles@gmail.com>", "author": "Paul <paulmakles@gmail.com>",
"license": "MIT", "license": "MIT",
"packageManager": "yarn@3.2.0" "packageManager": "yarn@3.2.0",
"resolutions": {
"@revoltchat/ui": "portal:../components"
}
} }

View file

@ -99,7 +99,7 @@ export default function MemberList({
)} )}
{entry.type !== "no_offline" && ( {entry.type !== "no_offline" && (
<> <>
{" - "} {" "}
{entry.users.length} {entry.users.length}
</> </>
)} )}

View file

@ -0,0 +1,61 @@
import { Server } from "revolt.js";
import { useState } from "preact/hooks";
import { Form } from "@revoltchat/ui";
import { FileUploader } from "../../../controllers/client/jsx/legacy/FileUploads";
interface Props {
server: Server;
}
export function EmojiUploader({ server }: Props) {
const [fileId, setFileId] = useState<string>();
return (
<>
<h3>Upload Emoji</h3>
<Form
schema={{
name: "text",
file: "custom",
}}
data={{
name: {
field: "Name",
palette: "secondary",
},
file: {
element: (
<FileUploader
style="icon"
width={100}
height={100}
fileType="emojis"
behaviour="upload"
previewAfterUpload
maxFileSize={500000}
remove={async () => void setFileId("")}
onUpload={async (id) => void setFileId(id)}
/>
),
},
}}
submitBtn={{
children: "Save",
palette: "secondary",
disabled: !fileId,
}}
onSubmit={async ({ name }) => {
await server.client.api.put(`/custom/emoji/${fileId}`, {
name,
parent: { type: "Server", id: server._id },
});
setFileId("");
}}
/>
</>
);
}

View file

@ -17,7 +17,11 @@ import { takeError } from "../error";
type BehaviourType = type BehaviourType =
| { behaviour: "ask"; onChange: (file: File) => void } | { behaviour: "ask"; onChange: (file: File) => void }
| { behaviour: "upload"; onUpload: (id: string) => Promise<void> } | {
behaviour: "upload";
onUpload: (id: string) => Promise<void>;
previewAfterUpload?: boolean;
}
| { | {
behaviour: "multi"; behaviour: "multi";
onChange: (files: File[]) => void; onChange: (files: File[]) => void;
@ -48,7 +52,8 @@ type Props = BehaviourType &
| "icons" | "icons"
| "avatars" | "avatars"
| "attachments" | "attachments"
| "banners"; | "banners"
| "emojis";
maxFileSize: number; maxFileSize: number;
remove: () => Promise<void>; remove: () => Promise<void>;
}; };
@ -114,6 +119,17 @@ export function FileUploader(props: Props) {
const client = useClient(); const client = useClient();
const [uploading, setUploading] = useState(false); const [uploading, setUploading] = useState(false);
const [previewFile, setPreviewFile] = useState<File>(null!);
const [generatedPreviewURL, setGeneratedPreviewURL] = useState("");
useEffect(() => {
if (previewFile) {
const url: string = URL.createObjectURL(previewFile);
setGeneratedPreviewURL(url);
return () => URL.revokeObjectURL(url);
}
setGeneratedPreviewURL("");
}, [previewFile]);
function onClick() { function onClick() {
if (uploading) return; if (uploading) return;
@ -136,6 +152,10 @@ export function FileUploader(props: Props) {
files[0], files[0],
), ),
); );
if (props.previewAfterUpload) {
setPreviewFile(files[0]);
}
} }
} catch (err) { } catch (err) {
return modalController.push({ return modalController.push({
@ -164,7 +184,11 @@ export function FileUploader(props: Props) {
} else { } else {
onClick(); onClick();
} }
} else if (props.previewURL) { } else if (props.previewURL || previewFile) {
if (previewFile) {
setPreviewFile(null!);
}
props.remove(); props.remove();
} else { } else {
onClick(); onClick();
@ -266,7 +290,11 @@ export function FileUploader(props: Props) {
style={{ style={{
backgroundImage: backgroundImage:
style === "icon" style === "icon"
? `url('${previewURL ?? defaultPreview}')` ? `url('${
generatedPreviewURL ??
previewURL ??
defaultPreview
}')`
: previewURL : previewURL
? `linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url('${previewURL}')` ? `linear-gradient( rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5) ), url('${previewURL}')`
: "none", : "none",
@ -288,7 +316,7 @@ export function FileUploader(props: Props) {
<span onClick={removeOrUpload}> <span onClick={removeOrUpload}>
{uploading ? ( {uploading ? (
<Text id="app.main.channel.uploading_file" /> <Text id="app.main.channel.uploading_file" />
) : props.previewURL ? ( ) : props.previewURL || previewFile ? (
<Text id="app.settings.actions.remove" /> <Text id="app.settings.actions.remove" />
) : ( ) : (
<Text id="app.settings.actions.upload" /> <Text id="app.settings.actions.upload" />

View file

@ -6,6 +6,7 @@ import {
Envelope, Envelope,
UserX, UserX,
Trash, Trash,
HappyBeaming,
} from "@styled-icons/boxicons-solid"; } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { Route, Switch, useHistory, useParams } from "react-router-dom"; import { Route, Switch, useHistory, useParams } from "react-router-dom";
@ -22,6 +23,7 @@ import { modalController } from "../../controllers/modals/ModalController";
import { GenericSettings } from "./GenericSettings"; import { GenericSettings } from "./GenericSettings";
import { Bans } from "./server/Bans"; import { Bans } from "./server/Bans";
import { Categories } from "./server/Categories"; import { Categories } from "./server/Categories";
import { Emojis } from "./server/Emojis";
import { Invites } from "./server/Invites"; import { Invites } from "./server/Invites";
import { Members } from "./server/Members"; import { Members } from "./server/Members";
import { Overview } from "./server/Overview"; import { Overview } from "./server/Overview";
@ -68,6 +70,14 @@ export default observer(() => {
title: <Text id="app.settings.server_pages.roles.title" />, title: <Text id="app.settings.server_pages.roles.title" />,
hideTitle: true, hideTitle: true,
}, },
{
category: (
<Text id="app.settings.server_pages.customisation.title" />
),
id: "emojis",
icon: <HappyBeaming size={20} />,
title: <Text id="app.settings.server_pages.emojis.title" />,
},
{ {
category: ( category: (
<Text id="app.settings.server_pages.management.title" /> <Text id="app.settings.server_pages.management.title" />
@ -116,6 +126,11 @@ export default observer(() => {
<Roles server={server} /> <Roles server={server} />
</RequiresOnline> </RequiresOnline>
</Route> </Route>
<Route path="/server/:server/settings/emojis">
<RequiresOnline>
<Emojis server={server} />
</RequiresOnline>
</Route>
<Route> <Route>
<Overview server={server} /> <Overview server={server} />
</Route> </Route>

View file

@ -0,0 +1,74 @@
import { observer } from "mobx-react-lite";
import { Server } from "revolt.js";
import styled from "styled-components";
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)`
padding: 8px;
border-radius: var(--border-radius);
background: var(--secondary-background);
`;
const Preview = styled.img`
width: 72px;
height: 72px;
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.id === server._id,
);
return (
<Column>
<EmojiUploader server={server} />
<h3>Emojis {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)
}>
Copy ID
</Button>
</Emoji>
))}
</List>
</Column>
);
});

View file

@ -2231,9 +2231,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@revoltchat/ui@npm:1.0.69": "@revoltchat/ui@portal:../components::locator=client%40workspace%3A.":
version: 1.0.69 version: 0.0.0-use.local
resolution: "@revoltchat/ui@npm:1.0.69" resolution: "@revoltchat/ui@portal:../components::locator=client%40workspace%3A."
dependencies: dependencies:
"@styled-icons/boxicons-logos": ^10.38.0 "@styled-icons/boxicons-logos": ^10.38.0
"@styled-icons/boxicons-regular": ^10.38.0 "@styled-icons/boxicons-regular": ^10.38.0
@ -2247,9 +2247,8 @@ __metadata:
react-virtuoso: ^2.12.0 react-virtuoso: ^2.12.0
peerDependencies: peerDependencies:
revolt.js: "*" revolt.js: "*"
checksum: bb67870911689d7dccd82f96affdb0e3e89b2e688d4a7403ee9bbb6a0245dfc296f35636ababd5ed6b43a3ce26777cee03c453728088b4a29fed350dcc89ea37
languageName: node languageName: node
linkType: hard linkType: soft
"@rollup/plugin-babel@npm:^5.2.0": "@rollup/plugin-babel@npm:^5.2.0":
version: 5.3.0 version: 5.3.0
@ -3608,7 +3607,7 @@ __metadata:
preact-context-menu: 0.4.1 preact-context-menu: 0.4.1
preact-i18n: ^2.4.0-preactx preact-i18n: ^2.4.0-preactx
prettier: ^2.3.1 prettier: ^2.3.1
prismjs: ^1.23.0 prismjs: ^1.28.0
qrcode.react: ^3.0.2 qrcode.react: ^3.0.2
react-beautiful-dnd: ^13.1.0 react-beautiful-dnd: ^13.1.0
react-device-detect: 2.2.2 react-device-detect: 2.2.2
@ -3618,7 +3617,7 @@ __metadata:
react-router-dom: ^5.2.0 react-router-dom: ^5.2.0
react-scroll: ^1.8.2 react-scroll: ^1.8.2
react-virtuoso: ^2.12.0 react-virtuoso: ^2.12.0
revolt.js: 6.0.3 revolt.js: 6.0.4
rimraf: ^3.0.2 rimraf: ^3.0.2
sass: ^1.35.1 sass: ^1.35.1
semver: ^7.3.7 semver: ^7.3.7
@ -6546,13 +6545,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"prismjs@npm:^1.23.0":
version: 1.24.1
resolution: "prismjs@npm:1.24.1"
checksum: e5d14a4ba56773122039295bd760c72106acc964e04cb9831b9ae7e7a58f67ccac6c053e77e21f1018a3684f31d35bb065c0c81fd4ff00b73b1570c3ace4aef0
languageName: node
linkType: hard
"prismjs@npm:^1.28.0": "prismjs@npm:^1.28.0":
version: 1.28.0 version: 1.28.0
resolution: "prismjs@npm:1.28.0" resolution: "prismjs@npm:1.28.0"
@ -6995,20 +6987,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"revolt-api@npm:0.5.3-7": "revolt-api@npm:0.5.4":
version: 0.5.3-7 version: 0.5.4
resolution: "revolt-api@npm:0.5.3-7" resolution: "revolt-api@npm:0.5.4"
dependencies: dependencies:
"@insertish/oapi": 0.1.16 "@insertish/oapi": 0.1.16
axios: ^0.26.1 axios: ^0.26.1
lodash.defaultsdeep: ^4.6.1 lodash.defaultsdeep: ^4.6.1
checksum: acc2f412d1be90f0cfa8a24ba715d8257813762c56ba0e48c649efff349674517036a8fa5939eda61ce31fd64a37f0c54af3d8fae56edf4596f05b10304e090e checksum: bd40acabac1b6c5848b1d6e555297de5aa3e0950a4de67523c4cf986a8037380e3addc5e16babebc8dfa6570cd1d1957efe9a3aaa6a206b9286e5b7f5941d699
languageName: node languageName: node
linkType: hard linkType: hard
"revolt.js@npm:6.0.3": "revolt.js@npm:6.0.4":
version: 6.0.3 version: 6.0.4
resolution: "revolt.js@npm:6.0.3" resolution: "revolt.js@npm:6.0.4"
dependencies: dependencies:
"@insertish/exponential-backoff": 3.1.0-patch.2 "@insertish/exponential-backoff": 3.1.0-patch.2
"@insertish/isomorphic-ws": ^4.0.1 "@insertish/isomorphic-ws": ^4.0.1
@ -7019,10 +7011,10 @@ __metadata:
lodash.isequal: ^4.5.0 lodash.isequal: ^4.5.0
long: ^5.2.0 long: ^5.2.0
mobx: ^6.3.2 mobx: ^6.3.2
revolt-api: 0.5.3-7 revolt-api: 0.5.4
ulid: ^2.3.0 ulid: ^2.3.0
ws: ^8.2.2 ws: ^8.2.2
checksum: cfecbde7a9b795da75bfac3cec05f2aed5fd02cd14fcac1b2fad26285de1b887cf7ccb339e8a63a019f1e83058b041305927e029d7b5eedcc00823582d9a842a checksum: 7e203388c3ca8d715c4fb5b18871f97a8b966ae080bed52b9cdc6f77fdaceafe56085076f55b5cc3a9380de70fffb5b575a5e25a69792d5cb9bfd02c7e0ed426
languageName: node languageName: node
linkType: hard linkType: hard