merge: branch 'quark/permissions'
commit
8125ccee1d
|
|
@ -7,6 +7,9 @@ dist-ssr
|
|||
*.log
|
||||
/.idea
|
||||
|
||||
.yarn/cache
|
||||
.yarn/install-state.gz
|
||||
|
||||
public/assets
|
||||
public/assets_*
|
||||
!public/assets_default
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,9 @@
|
|||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
|
||||
spec: "@yarnpkg/plugin-typescript"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.0.cjs
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 6a72c5c952eedfbeb8a193a8a4b97927cc44cd6f
|
||||
Subproject commit 50a710d761330632716b3f6d17ed964465d79213
|
||||
24
package.json
24
package.json
|
|
@ -61,7 +61,6 @@
|
|||
"dependencies": {
|
||||
"@fontsource/bitter": "^4.5.0",
|
||||
"@insertish/vite-plugin-babel-macros": "^1.0.5",
|
||||
"color-rgba": "^2.3.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"klaw": "^3.0.0",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
|
|
@ -81,7 +80,7 @@
|
|||
"@fontsource/noto-sans": "^4.4.5",
|
||||
"@fontsource/open-sans": "^4.5.2",
|
||||
"@fontsource/opendyslexic": "^4.5.2",
|
||||
"@fontsource/poppins": "^4.4.5",
|
||||
"@fontsource/poppins": "^4.4.5",
|
||||
"@fontsource/raleway": "^4.4.5",
|
||||
"@fontsource/roboto": "^4.4.5",
|
||||
"@fontsource/roboto-mono": "^4.4.5",
|
||||
|
|
@ -91,16 +90,16 @@
|
|||
"@fontsource/ubuntu-mono": "^4.4.5",
|
||||
"@hcaptcha/react-hcaptcha": "^0.3.6",
|
||||
"@preact/preset-vite": "^2.0.0",
|
||||
"@revoltchat/ui": "1.0.28",
|
||||
"@rollup/plugin-replace": "^2.4.2",
|
||||
"@styled-icons/boxicons-logos": "^10.34.0",
|
||||
"@styled-icons/boxicons-regular": "^10.34.0",
|
||||
"@styled-icons/boxicons-solid": "^10.37.0",
|
||||
"@styled-icons/boxicons-logos": "^10.38.0",
|
||||
"@styled-icons/boxicons-regular": "^10.38.0",
|
||||
"@styled-icons/boxicons-solid": "^10.38.0",
|
||||
"@styled-icons/simple-icons": "^10.33.0",
|
||||
"@tippyjs/react": "^4.2.5",
|
||||
"@traptitech/markdown-it-katex": "^3.4.3",
|
||||
"@traptitech/markdown-it-spoiler": "^1.1.6",
|
||||
"@trivago/prettier-plugin-sort-imports": "^2.0.2",
|
||||
"@types/color-rgba": "^2.1.0",
|
||||
"@types/lodash.defaultsdeep": "^4.6.6",
|
||||
"@types/lodash.isequal": "^4.5.5",
|
||||
"@types/markdown-it": "^12.0.2",
|
||||
|
|
@ -118,6 +117,7 @@
|
|||
"@typescript-eslint/parser": "^4.27.0",
|
||||
"@vitejs/plugin-legacy": "^1.7.1",
|
||||
"classnames": "^2.3.1",
|
||||
"color-rgba": "^2.4.0",
|
||||
"dayjs": "^1.10.6",
|
||||
"detect-browser": "^5.2.0",
|
||||
"eslint": "^7.28.0",
|
||||
|
|
@ -127,13 +127,14 @@
|
|||
"localforage": "^1.9.0",
|
||||
"lodash.defaultsdeep": "^4.6.1",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"long": "^5.2.0",
|
||||
"markdown-it": "^12.0.6",
|
||||
"markdown-it-emoji": "^2.0.0",
|
||||
"markdown-it-sub": "^1.0.0",
|
||||
"markdown-it-sup": "^1.0.0",
|
||||
"mediasoup-client": "npm:@insertish/mediasoup-client@3.6.36-esnext",
|
||||
"mobx": "^6.3.2",
|
||||
"mobx-react-lite": "^3.2.0",
|
||||
"mobx-react-lite": "^3.3.0",
|
||||
"preact": "^10.5.14",
|
||||
"preact-context-menu": "0.4.0-patch.0",
|
||||
"preact-i18n": "^2.4.0-preactx",
|
||||
|
|
@ -147,8 +148,7 @@
|
|||
"react-scroll": "^1.8.2",
|
||||
"react-virtualized-auto-sizer": "^1.0.5",
|
||||
"react-virtuoso": "^1.10.4",
|
||||
"revolt-api": "^0.5.3-alpha.12",
|
||||
"revolt.js": "^5.2.8",
|
||||
"revolt.js": "6.0.0-rc.21",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass": "^1.35.1",
|
||||
"shade-blend-color": "^1.0.0",
|
||||
|
|
@ -160,10 +160,10 @@
|
|||
"vite-plugin-pwa": "^0.11.13",
|
||||
"workbox-precaching": "^6.1.5"
|
||||
},
|
||||
"packageManager": "yarn@1.22.17",
|
||||
"name": "client",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/revoltchat/revite.git",
|
||||
"author": "Paul <paulmakles@gmail.com>",
|
||||
"license": "MIT"
|
||||
}
|
||||
"license": "MIT",
|
||||
"packageManager": "yarn@3.2.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
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 styled from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel, User } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { StateUpdater, useState } from "preact/hooks";
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import { Hash, VolumeFull } 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 { useContext } from "preact/hooks";
|
||||
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { ImageIconBase, IconBaseProps } from "./IconBase";
|
||||
import fallback from "./assets/group.png";
|
||||
|
||||
import { ImageIconBase, IconBaseProps } from "./IconBase";
|
||||
|
||||
interface Props extends IconBaseProps<Channel> {
|
||||
isServerChannel?: boolean;
|
||||
}
|
||||
|
|
@ -32,7 +33,7 @@ export default observer(
|
|||
...imgProps
|
||||
} = props;
|
||||
const iconURL = client.generateFileURL(
|
||||
target?.icon ?? attachment,
|
||||
target?.icon ?? attachment ?? undefined,
|
||||
{ max_side: 256 },
|
||||
animate,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Attachment } from "revolt-api/types/Autumn";
|
||||
import { API } from "revolt.js";
|
||||
import { Nullable } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Ref } from "preact";
|
||||
|
|
@ -6,7 +7,7 @@ import { Ref } from "preact";
|
|||
export interface IconBaseProps<T> {
|
||||
target?: T;
|
||||
url?: string;
|
||||
attachment?: Attachment;
|
||||
attachment?: Nullable<API.File>;
|
||||
|
||||
size: number;
|
||||
hover?: boolean;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,11 @@ import { Check } from "@styled-icons/boxicons-regular";
|
|||
import { Cog } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link } from "react-router-dom";
|
||||
import { ServerPermission } from "revolt.js/dist/api/permissions";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Server } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
|
||||
import IconButton from "../ui/IconButton";
|
||||
|
||||
import Tooltip from "./Tooltip";
|
||||
|
|
@ -125,7 +122,7 @@ export default observer(({ server }: Props) => {
|
|||
</Tooltip>
|
||||
) : undefined}
|
||||
<div className="title">{server.name}</div>
|
||||
{(server.permission & ServerPermission.ManageServer) > 0 && (
|
||||
{server.havePermission("ManageServer") && (
|
||||
<Link to={`/server/${server._id}/settings`}>
|
||||
<IconButton>
|
||||
<Cog size={20} />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Server } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { useContext } from "preact/hooks";
|
||||
|
|
@ -39,7 +39,7 @@ export default observer(
|
|||
const { target, attachment, size, animate, server_name, ...imgProps } =
|
||||
props;
|
||||
const iconURL = client.generateFileURL(
|
||||
target?.icon ?? attachment,
|
||||
target?.icon ?? attachment ?? undefined,
|
||||
{ max_side: 256 },
|
||||
animate,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = (
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
) : (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -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 } = {};
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}}>
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
import { Shield } from "@styled-icons/boxicons-regular";
|
||||
import { Badges } from "revolt-api/types/Users";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Localizer, Text } from "preact-i18n";
|
||||
|
||||
import Tooltip from "../Tooltip";
|
||||
|
||||
enum Badges {
|
||||
Developer = 1,
|
||||
Translator = 2,
|
||||
Supporter = 4,
|
||||
ResponsibleDisclosure = 8,
|
||||
Founder = 16,
|
||||
PlatformModeration = 32,
|
||||
ActiveSupporter = 64,
|
||||
Paw = 128,
|
||||
EarlyAdopter = 256,
|
||||
ReservedRelevantJokeBadge1 = 512,
|
||||
}
|
||||
|
||||
const BadgesBase = styled.div`
|
||||
gap: 8px;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User } from "revolt.js";
|
||||
|
||||
import Checkbox, { CheckboxProps } from "../../ui/Checkbox";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Cog } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link } from "react-router-dom";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { openContextMenu } from "preact-context-menu";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Children } from "../../../types/Preact";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { VolumeMute, MicrophoneOff } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Masquerade } from "revolt-api/types/Channels";
|
||||
import { Presence } from "revolt-api/types/Users";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User, API } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
|
@ -18,17 +16,17 @@ type VoiceStatus = "muted" | "deaf";
|
|||
interface Props extends IconBaseProps<User> {
|
||||
status?: boolean;
|
||||
voice?: VoiceStatus;
|
||||
masquerade?: Masquerade;
|
||||
masquerade?: API.Masquerade;
|
||||
showServerIdentity?: boolean;
|
||||
}
|
||||
|
||||
export function useStatusColour(user?: User) {
|
||||
const theme = useApplicationState().settings.theme;
|
||||
|
||||
return user?.online && user?.status?.presence !== Presence.Invisible
|
||||
? user?.status?.presence === Presence.Idle
|
||||
return user?.online && user?.status?.presence !== "Invisible"
|
||||
? user?.status?.presence === "Idle"
|
||||
? theme.getVariable("status-away")
|
||||
: user?.status?.presence === Presence.Busy
|
||||
: user?.status?.presence === "Busy"
|
||||
? theme.getVariable("status-busy")
|
||||
: theme.getVariable("status-online")
|
||||
: theme.getVariable("status-invisible");
|
||||
|
|
@ -95,7 +93,7 @@ export default observer(
|
|||
|
||||
url =
|
||||
client.generateFileURL(
|
||||
override ?? target?.avatar ?? attachment,
|
||||
override ?? target?.avatar ?? attachment ?? undefined,
|
||||
{ max_side: 256 },
|
||||
animate,
|
||||
) ?? (target ? target.defaultAvatarURL : fallback);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Masquerade } from "revolt-api/types/Channels";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
import { User, API } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Ref } from "preact";
|
||||
|
|
@ -32,7 +30,7 @@ const BotBadge = styled.div`
|
|||
type UsernameProps = JSX.HTMLAttributes<HTMLElement> & {
|
||||
user?: User;
|
||||
prefixAt?: boolean;
|
||||
masquerade?: Masquerade;
|
||||
masquerade?: API.Masquerade;
|
||||
showServerIdentity?: boolean | "both";
|
||||
|
||||
innerRef?: Ref<any>;
|
||||
|
|
@ -120,7 +118,7 @@ export default function UserShort({
|
|||
user?: User;
|
||||
size?: number;
|
||||
prefixAt?: boolean;
|
||||
masquerade?: Masquerade;
|
||||
masquerade?: API.Masquerade;
|
||||
showServerIdentity?: boolean;
|
||||
}) {
|
||||
const { openScreen } = useIntermediate();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Presence } from "revolt-api/types/Users";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User, API } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
|
|
@ -25,15 +24,15 @@ export default observer(({ user, tooltip }: Props) => {
|
|||
return <>{user.status.text}</>;
|
||||
}
|
||||
|
||||
if (user.status?.presence === Presence.Busy) {
|
||||
if (user.status?.presence === "Busy") {
|
||||
return <Text id="app.status.busy" />;
|
||||
}
|
||||
|
||||
if (user.status?.presence === Presence.Idle) {
|
||||
if (user.status?.presence === "Idle") {
|
||||
return <Text id="app.status.idle" />;
|
||||
}
|
||||
|
||||
if (user.status?.presence === Presence.Invisible) {
|
||||
if (user.status?.presence === "Invisible") {
|
||||
return <Text id="app.status.offline" />;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Suspense, lazy } from "preact/compat";
|
|||
const Renderer = lazy(() => import("./Renderer"));
|
||||
|
||||
export interface MarkdownProps {
|
||||
content?: string;
|
||||
content?: string | null;
|
||||
disallowBigEmoji?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ export default function Renderer({ content, disallowBigEmoji }: MarkdownProps) {
|
|||
const { openLink } = useIntermediate();
|
||||
|
||||
if (typeof content === "undefined") return null;
|
||||
if (content.length === 0) return null;
|
||||
if (!content || content.length === 0) return null;
|
||||
|
||||
// We replace the message with the mention at the time of render.
|
||||
// We don't care if the mention changes.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { X } from "@styled-icons/boxicons-regular";
|
||||
import { Crown } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Presence } from "revolt-api/types/Users";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User, Channel } from "revolt.js";
|
||||
|
||||
import styles from "./Item.module.scss";
|
||||
import classNames from "classnames";
|
||||
|
|
@ -65,7 +63,7 @@ export const UserButton = observer((props: UserProps) => {
|
|||
data-alert={typeof alert === "string"}
|
||||
data-online={
|
||||
typeof channel !== "undefined" ||
|
||||
(user.online && user.status?.presence !== Presence.Invisible)
|
||||
(user.online && user.status?.presence !== "Invisible")
|
||||
}
|
||||
{...useTriggerEvents("Menu", {
|
||||
user: user._id,
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ import { useContext } from "preact/hooks";
|
|||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import Banner from "../../ui/Banner";
|
||||
|
||||
export default function ConnectionStatus() {
|
||||
const status = useContext(StatusContext);
|
||||
const client = useClient();
|
||||
|
||||
if (status === ClientStatus.OFFLINE) {
|
||||
return (
|
||||
|
|
@ -20,7 +22,10 @@ export default function ConnectionStatus() {
|
|||
} else if (status === ClientStatus.DISCONNECTED) {
|
||||
return (
|
||||
<Banner>
|
||||
<Text id="app.special.status.disconnected" />
|
||||
<Text id="app.special.status.disconnected" /> <br />
|
||||
<a onClick={() => client.websocket.connect()}>
|
||||
<Text id="app.special.status.reconnect" />
|
||||
</a>
|
||||
</Banner>
|
||||
);
|
||||
} else if (status === ClientStatus.CONNECTING) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import {
|
|||
} from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link, useLocation, useParams } from "react-router-dom";
|
||||
import { RelationshipStatus } from "revolt-api/types/Users";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
@ -47,14 +46,16 @@ export default observer(() => {
|
|||
const { pathname } = useLocation();
|
||||
const client = useContext(AppContext);
|
||||
const state = useApplicationState();
|
||||
const { channel: currentChannel } = useParams<{ channel: string }>();
|
||||
const { channel: channel_id } = useParams<{ channel: string }>();
|
||||
const { openScreen } = useIntermediate();
|
||||
|
||||
const channels = [...client.channels.values()].filter(
|
||||
(x) => x.channel_type === "DirectMessage" || x.channel_type === "Group",
|
||||
(x) =>
|
||||
(x.channel_type === "DirectMessage" && x.active) ||
|
||||
x.channel_type === "Group",
|
||||
);
|
||||
|
||||
const obj = client.channels.get(currentChannel);
|
||||
const channel = client.channels.get(channel_id);
|
||||
|
||||
// ! FIXME: move this globally
|
||||
// Track what page the user was last on (in home page).
|
||||
|
|
@ -66,7 +67,7 @@ export default observer(() => {
|
|||
|
||||
// ! FIXME: must be a better way
|
||||
const incoming = [...client.users.values()].filter(
|
||||
(user) => user?.relationship === RelationshipStatus.Incoming,
|
||||
(user) => user?.relationship === "Incoming",
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
@ -104,9 +105,10 @@ export default observer(() => {
|
|||
</>
|
||||
)}
|
||||
<ConditionalLink
|
||||
active={obj?.channel_type === "SavedMessages"}
|
||||
active={channel?.channel_type === "SavedMessages"}
|
||||
to="/open/saved">
|
||||
<ButtonItem active={obj?.channel_type === "SavedMessages"}>
|
||||
<ButtonItem
|
||||
active={channel?.channel_type === "SavedMessages"}>
|
||||
<Notepad size={20} />
|
||||
<span>
|
||||
<Text id="app.navigation.tabs.saved" />
|
||||
|
|
@ -152,7 +154,7 @@ export default observer(() => {
|
|||
return (
|
||||
<ConditionalLink
|
||||
key={channel._id}
|
||||
active={channel._id === currentChannel}
|
||||
active={channel._id === channel_id}
|
||||
to={`/channel/${channel._id}`}>
|
||||
<ChannelButton
|
||||
user={user}
|
||||
|
|
@ -165,7 +167,7 @@ export default observer(() => {
|
|||
: undefined
|
||||
}
|
||||
alertCount={mentionCount}
|
||||
active={channel._id === currentChannel}
|
||||
active={channel._id === channel_id}
|
||||
/>
|
||||
</ConditionalLink>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ import { Plus } from "@styled-icons/boxicons-regular";
|
|||
import { Cog, Compass } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link, useHistory, useLocation, useParams } from "react-router-dom";
|
||||
import { RelationshipStatus } from "revolt-api/types/Users";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Ref } from "preact";
|
||||
import { useTriggerEvents } from "preact-context-menu";
|
||||
|
||||
import ConditionalLink from "../../../lib/ConditionalLink";
|
||||
|
|
@ -248,7 +246,7 @@ export default observer(() => {
|
|||
const { openScreen } = useIntermediate();
|
||||
|
||||
let alertCount = [...client.users.values()].filter(
|
||||
(x) => x.relationship === RelationshipStatus.Incoming,
|
||||
(x) => x.relationship === "Incoming",
|
||||
).length;
|
||||
|
||||
const homeActive =
|
||||
|
|
@ -290,7 +288,7 @@ export default observer(() => {
|
|||
{channels
|
||||
.filter(
|
||||
(x) =>
|
||||
(x.channel_type === "DirectMessage" ||
|
||||
((x.channel_type === "DirectMessage" && x.active) ||
|
||||
x.channel_type === "Group") &&
|
||||
x.unread,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Redirect, useParams } from "react-router";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Server } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Ref } from "preact";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Channel } from "revolt.js";
|
||||
|
||||
import { getRenderer } from "../../../lib/renderer/Singleton";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { Link } from "react-router-dom";
|
||||
import { GroupedVirtuoso } from "react-virtuoso";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel, User } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@
|
|||
import { autorun } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Role } from "revolt-api/types/Servers";
|
||||
import { Presence } from "revolt-api/types/Users";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel, Server, User, API } from "revolt.js";
|
||||
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
|
||||
|
|
@ -62,7 +58,7 @@ function useEntries(
|
|||
.map((id) => {
|
||||
return [id, roles![id], roles![id].rank ?? 0] as [
|
||||
string,
|
||||
Role,
|
||||
API.Role,
|
||||
number,
|
||||
];
|
||||
})
|
||||
|
|
@ -96,7 +92,7 @@ function useEntries(
|
|||
const sort = member?.nickname ?? u.username;
|
||||
const entry = [u, sort] as [User, string];
|
||||
|
||||
if (!u.online || u.status?.presence === Presence.Invisible) {
|
||||
if (!u.online || u.status?.presence === "Invisible") {
|
||||
categories.offline.push(entry);
|
||||
} else {
|
||||
if (isServer) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Link, useParams } from "react-router-dom";
|
||||
import { Message as MessageI } from "revolt.js/dist/maps/Messages";
|
||||
import { Message as MessageI } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import { API } from "revolt.js";
|
||||
import { Permission } from "revolt.js";
|
||||
|
||||
import { PermissionSelect } from "./PermissionSelect";
|
||||
|
||||
interface Props {
|
||||
value: API.OverrideField | number;
|
||||
onChange: (v: API.OverrideField | number) => void;
|
||||
|
||||
filter?: (keyof typeof Permission)[];
|
||||
}
|
||||
|
||||
export function PermissionList({ value, onChange, filter }: Props) {
|
||||
return (
|
||||
<>
|
||||
{(Object.keys(Permission) as (keyof typeof Permission)[])
|
||||
.filter(
|
||||
(key) =>
|
||||
![
|
||||
"GrantAllSafe",
|
||||
"TimeoutMembers",
|
||||
"ReadMessageHistory",
|
||||
"Speak",
|
||||
"Video",
|
||||
"MuteMembers",
|
||||
"DeafenMembers",
|
||||
"MoveMembers",
|
||||
].includes(key) &&
|
||||
(!filter || filter.includes(key)),
|
||||
)
|
||||
.map((x) => (
|
||||
<PermissionSelect
|
||||
id={x}
|
||||
key={x}
|
||||
permission={Permission[x]}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
import Long from "long";
|
||||
import { API } from "revolt.js";
|
||||
import { Permission } from "revolt.js";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useMemo } from "preact/hooks";
|
||||
|
||||
import Checkbox from "../../ui/Checkbox";
|
||||
import { OverrideSwitch } from "@revoltchat/ui";
|
||||
|
||||
interface PermissionSelectProps {
|
||||
id: keyof typeof Permission;
|
||||
permission: number;
|
||||
value: API.OverrideField | number;
|
||||
onChange: (value: API.OverrideField | number) => void;
|
||||
}
|
||||
|
||||
type State = "Allow" | "Neutral" | "Deny";
|
||||
|
||||
const PermissionEntry = styled.label`
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
margin: 8px 0;
|
||||
display: flex;
|
||||
font-size: 1.1em;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
flex-grow: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.8em;
|
||||
color: var(--secondary-foreground);
|
||||
}
|
||||
`;
|
||||
|
||||
export function PermissionSelect({
|
||||
id,
|
||||
permission,
|
||||
value,
|
||||
onChange,
|
||||
}: PermissionSelectProps) {
|
||||
const state: State = useMemo(() => {
|
||||
if (typeof value === "object") {
|
||||
if (Long.fromNumber(value.d).and(permission).eq(permission)) {
|
||||
return "Deny";
|
||||
}
|
||||
|
||||
if (Long.fromNumber(value.a).and(permission).eq(permission)) {
|
||||
return "Allow";
|
||||
}
|
||||
|
||||
return "Neutral";
|
||||
} else {
|
||||
if (Long.fromNumber(value).and(permission).eq(permission)) {
|
||||
return "Allow";
|
||||
}
|
||||
|
||||
return "Neutral";
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
function onSwitch(state: State) {
|
||||
if (typeof value !== "object") throw "!";
|
||||
|
||||
// Convert to Long so we can do bitwise ops.
|
||||
let allow = Long.fromNumber(value.a);
|
||||
let deny = Long.fromNumber(value.d);
|
||||
|
||||
// Clear the current permission value.
|
||||
if (allow.and(permission).eq(permission)) {
|
||||
allow = allow.xor(permission);
|
||||
}
|
||||
|
||||
if (deny.and(permission).eq(permission)) {
|
||||
deny = deny.xor(permission);
|
||||
}
|
||||
|
||||
// Apply the current permission state.
|
||||
if (state === "Allow") {
|
||||
allow = allow.or(permission);
|
||||
}
|
||||
|
||||
if (state === "Deny") {
|
||||
deny = deny.or(permission);
|
||||
}
|
||||
|
||||
// Invoke state change.
|
||||
onChange({
|
||||
a: allow.toNumber(),
|
||||
d: deny.toNumber(),
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<PermissionEntry>
|
||||
<span class="title">
|
||||
<Text id={`permissions.${id}.t`}>{id}</Text>
|
||||
<span class="description">
|
||||
<Text id={`permissions.${id}.d`} />
|
||||
</span>
|
||||
</span>
|
||||
{typeof value === "object" ? (
|
||||
<OverrideSwitch state={state} onChange={onSwitch} />
|
||||
) : (
|
||||
<Checkbox
|
||||
checked={state === "Allow"}
|
||||
onChange={() =>
|
||||
onChange(
|
||||
Long.fromNumber(value, false)
|
||||
.xor(permission)
|
||||
.toNumber(),
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</PermissionEntry>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { API } from "revolt.js";
|
||||
|
||||
export type RoleOrDefault = (
|
||||
| API.Role
|
||||
| {
|
||||
name: string;
|
||||
permissions: number;
|
||||
colour?: string;
|
||||
hoist?: boolean;
|
||||
rank?: number;
|
||||
}
|
||||
) & { id: string };
|
||||
|
|
@ -89,7 +89,7 @@ export interface CheckboxProps {
|
|||
disabled?: boolean;
|
||||
contrast?: boolean;
|
||||
className?: string;
|
||||
children: Children;
|
||||
children?: Children;
|
||||
description?: Children;
|
||||
onChange: (state: boolean) => void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-expect-error No typings.
|
||||
import rgba from "color-rgba";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Helmet } from "react-helmet";
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
import { Prompt } from "react-router";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import type { Attachment } from "revolt-api/types/Autumn";
|
||||
import { Bot } from "revolt-api/types/Bots";
|
||||
import { TextChannel, VoiceChannel } from "revolt-api/types/Channels";
|
||||
import type { EmbedImage } from "revolt-api/types/January";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { API, Channel, Message, Server, User } from "revolt.js";
|
||||
|
||||
import { createContext } from "preact";
|
||||
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
||||
|
|
@ -61,7 +54,11 @@ export type Screen =
|
|||
| {
|
||||
type: "create_channel";
|
||||
target: Server;
|
||||
cb?: (channel: TextChannel | VoiceChannel) => void;
|
||||
cb?: (
|
||||
channel: Channel & {
|
||||
channel_type: "TextChannel" | "VoiceChannel";
|
||||
},
|
||||
) => void;
|
||||
}
|
||||
| { type: "create_category"; target: Server }
|
||||
))
|
||||
|
|
@ -101,11 +98,11 @@ export type Screen =
|
|||
omit?: string[];
|
||||
callback: (users: string[]) => Promise<void>;
|
||||
}
|
||||
| { id: "image_viewer"; attachment?: Attachment; embed?: EmbedImage }
|
||||
| { id: "image_viewer"; attachment?: API.File; embed?: API.Image }
|
||||
| { id: "channel_info"; channel: Channel }
|
||||
| { id: "pending_requests"; users: User[] }
|
||||
| { id: "modify_account"; field: "username" | "email" | "password" }
|
||||
| { id: "create_bot"; onCreate: (bot: Bot) => void }
|
||||
| { id: "create_bot"; onCreate: (bot: API.Bot) => void }
|
||||
| {
|
||||
id: "server_identity";
|
||||
server: Server;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export function ErrorModal({ onClose, error }: Props) {
|
|||
return (
|
||||
<Modal
|
||||
visible={true}
|
||||
onClose={() => false}
|
||||
onClose={onClose}
|
||||
title={<Text id="app.special.modals.error" />}
|
||||
actions={[
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useHistory } from "react-router";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Server } from "revolt.js";
|
||||
import { ulid } from "ulid";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
@ -69,6 +69,7 @@ export function InputModal({
|
|||
)}
|
||||
<InputBox
|
||||
value={value}
|
||||
style={{ width: "100%" }}
|
||||
onChange={(e) => setValue(e.currentTarget.value)}
|
||||
/>
|
||||
</Modal>
|
||||
|
|
@ -101,7 +102,6 @@ export function SpecialInputModal(props: SpecialProps) {
|
|||
callback={async (name) => {
|
||||
const group = await client.channels.createGroup({
|
||||
name,
|
||||
nonce: ulid(),
|
||||
users: [],
|
||||
});
|
||||
|
||||
|
|
@ -130,7 +130,6 @@ export function SpecialInputModal(props: SpecialProps) {
|
|||
callback={async (name) => {
|
||||
const server = await client.servers.createServer({
|
||||
name,
|
||||
nonce: ulid(),
|
||||
});
|
||||
|
||||
history.push(`/server/${server._id}`);
|
||||
|
|
@ -159,7 +158,7 @@ export function SpecialInputModal(props: SpecialProps) {
|
|||
onClose={onClose}
|
||||
question={<Text id="app.context_menu.set_custom_status" />}
|
||||
field={<Text id="app.context_menu.custom_status" />}
|
||||
defaultValue={client.user?.status?.text}
|
||||
defaultValue={client.user?.status?.text ?? undefined}
|
||||
callback={(text) =>
|
||||
client.users.edit({
|
||||
status: {
|
||||
|
|
@ -177,11 +176,8 @@ export function SpecialInputModal(props: SpecialProps) {
|
|||
onClose={onClose}
|
||||
question={"Add Friend"}
|
||||
callback={(username) =>
|
||||
client
|
||||
.req(
|
||||
"PUT",
|
||||
`/users/${username}/friend` as "/users/id/friend",
|
||||
)
|
||||
client.api
|
||||
.put(`/users/${username as ""}/friend`)
|
||||
.then(undefined)
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
&.form {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { TextChannel, VoiceChannel } from "revolt-api/types/Channels";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Message as MessageI } from "revolt.js/dist/maps/Messages";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel, Message as MessageI, Server, User } from "revolt.js";
|
||||
import { ulid } from "ulid";
|
||||
|
||||
import styles from "./Prompt.module.scss";
|
||||
|
|
@ -74,7 +70,11 @@ type SpecialProps = { onClose: () => void } & (
|
|||
| {
|
||||
type: "create_channel";
|
||||
target: Server;
|
||||
cb?: (channel: TextChannel | VoiceChannel) => void;
|
||||
cb?: (
|
||||
channel: Channel & {
|
||||
channel_type: "TextChannel" | "VoiceChannel";
|
||||
},
|
||||
) => void;
|
||||
}
|
||||
| { type: "create_category"; target: Server }
|
||||
);
|
||||
|
|
@ -254,7 +254,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
|
|||
|
||||
props.target
|
||||
.createInvite()
|
||||
.then((code) => setCode(code))
|
||||
.then(({ _id }) => setCode(_id))
|
||||
.catch((err) => setError(takeError(err)))
|
||||
.finally(() => setProcessing(false));
|
||||
}, [props.target]);
|
||||
|
|
@ -429,11 +429,10 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
|
|||
await props.target.createChannel({
|
||||
type,
|
||||
name,
|
||||
nonce: ulid(),
|
||||
});
|
||||
|
||||
if (props.cb) {
|
||||
props.cb(channel);
|
||||
props.cb(channel as any);
|
||||
} else {
|
||||
history.push(
|
||||
`/server/${props.target._id}/channel/${channel._id}`,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { X } 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 styles from "./ChannelInfo.module.scss";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { SubmitHandler, useForm } from "react-hook-form";
|
||||
import { Bot } from "revolt-api/types/Bots";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
|
|
@ -13,7 +13,7 @@ import { takeError } from "../../revoltjs/util";
|
|||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
onCreate: (bot: Bot) => void;
|
||||
onCreate: (bot: API.Bot) => void;
|
||||
}
|
||||
|
||||
interface FormInputs {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { Attachment, AttachmentMetadata } from "revolt-api/types/Autumn";
|
||||
import { EmbedImage } from "revolt-api/types/January";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import styles from "./ImageViewer.module.scss";
|
||||
|
||||
|
|
@ -12,11 +11,11 @@ import { useClient } from "../../revoltjs/RevoltClient";
|
|||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
embed?: EmbedImage;
|
||||
attachment?: Attachment;
|
||||
embed?: API.Image;
|
||||
attachment?: API.File;
|
||||
}
|
||||
|
||||
type ImageMetadata = AttachmentMetadata & { type: "Image" };
|
||||
type ImageMetadata = API.Metadata & { type: "Image" };
|
||||
|
||||
export function ImageViewer({ attachment, embed, onClose }: Props) {
|
||||
if (attachment && attachment.metadata.type !== "Image") {
|
||||
|
|
|
|||
|
|
@ -43,19 +43,19 @@ export function ModifyAccountModal({ onClose, field }: Props) {
|
|||
|
||||
try {
|
||||
if (field === "email") {
|
||||
await client.req("PATCH", "/auth/account/change/email", {
|
||||
await client.api.patch("/auth/account/change/email", {
|
||||
current_password: password,
|
||||
email: new_email,
|
||||
});
|
||||
onClose();
|
||||
} else if (field === "password") {
|
||||
await client.req("PATCH", "/auth/account/change/password", {
|
||||
await client.api.patch("/auth/account/change/password", {
|
||||
current_password: password,
|
||||
password: new_password,
|
||||
});
|
||||
onClose();
|
||||
} else if (field === "username") {
|
||||
await client.req("PATCH", "/users/id/username", {
|
||||
await client.api.patch("/users/@me/username", {
|
||||
username: new_username,
|
||||
password,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { User } from "revolt.js";
|
||||
|
||||
import styles from "./UserPicker.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
import { Server } from "revolt.js";
|
||||
|
||||
import styles from "./ServerIdentityModal.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { noop } from "../../../lib/js";
|
||||
|
||||
import Button from "../../../components/ui/Button";
|
||||
import InputBox from "../../../components/ui/InputBox";
|
||||
import Modal from "../../../components/ui/Modal";
|
||||
|
|
@ -57,8 +58,12 @@ export const ServerIdentityModal = observer(({ server, onClose }: Props) => {
|
|||
fileType="avatars"
|
||||
behaviour="upload"
|
||||
maxFileSize={4_000_000}
|
||||
onUpload={(avatar) => member.edit({ avatar })}
|
||||
remove={() => member.edit({ remove: "Avatar" })}
|
||||
onUpload={(avatar) =>
|
||||
member.edit({ avatar }).then(noop)
|
||||
}
|
||||
remove={() =>
|
||||
member.edit({ remove: ["Avatar"] }).then(noop)
|
||||
}
|
||||
defaultPreview={client.user?.generateAvatarURL(
|
||||
{
|
||||
max_side: 256,
|
||||
|
|
@ -92,7 +97,7 @@ export const ServerIdentityModal = observer(({ server, onClose }: Props) => {
|
|||
<Button
|
||||
plain
|
||||
onClick={() =>
|
||||
member.edit({ remove: "Nickname" })
|
||||
member.edit({ remove: ["Nickname"] })
|
||||
}>
|
||||
<Text id="app.special.modals.actions.remove" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { RelationshipStatus } from "revolt-api/types/Users";
|
||||
|
||||
import styles from "./UserPicker.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useState } from "preact/hooks";
|
||||
|
|
@ -37,7 +35,7 @@ export function UserPicker(props: Props) {
|
|||
.filter(
|
||||
(x) =>
|
||||
x &&
|
||||
x.relationship === RelationshipStatus.Friend &&
|
||||
x.relationship === "Friend" &&
|
||||
!omit.includes(x._id),
|
||||
)
|
||||
.map((x) => (
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ import {
|
|||
} from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Link, useHistory } from "react-router-dom";
|
||||
import { Profile, RelationshipStatus } from "revolt-api/types/Users";
|
||||
import { UserPermission } from "revolt.js/dist/api/permissions";
|
||||
import { Route } from "revolt.js/dist/api/routes";
|
||||
import { UserPermission, API } from "revolt.js";
|
||||
|
||||
import styles from "./UserProfile.module.scss";
|
||||
import { Localizer, Text } from "preact-i18n";
|
||||
|
|
@ -44,18 +42,18 @@ interface Props {
|
|||
user_id: string;
|
||||
dummy?: boolean;
|
||||
onClose?: () => void;
|
||||
dummyProfile?: Profile;
|
||||
dummyProfile?: API.UserProfile;
|
||||
}
|
||||
|
||||
export const UserProfile = observer(
|
||||
({ user_id, onClose, dummy, dummyProfile }: Props) => {
|
||||
const { openScreen, writeClipboard } = useIntermediate();
|
||||
|
||||
const [profile, setProfile] = useState<undefined | null | Profile>(
|
||||
undefined,
|
||||
);
|
||||
const [profile, setProfile] = useState<
|
||||
undefined | null | API.UserProfile
|
||||
>(undefined);
|
||||
const [mutual, setMutual] = useState<
|
||||
undefined | null | Route<"GET", "/users/id/mutual">["response"]
|
||||
undefined | null | API.MutualResponse
|
||||
>(undefined);
|
||||
const [isPublicBot, setIsPublicBot] = useState<
|
||||
undefined | null | boolean
|
||||
|
|
@ -139,7 +137,11 @@ export const UserProfile = observer(
|
|||
|
||||
const backgroundURL =
|
||||
profile &&
|
||||
client.generateFileURL(profile.background, { width: 1000 }, true);
|
||||
client.generateFileURL(
|
||||
profile.background as any,
|
||||
{ width: 1000 },
|
||||
true,
|
||||
);
|
||||
|
||||
const badges = user.badges ?? 0;
|
||||
const flags = user.flags ?? 0;
|
||||
|
|
@ -198,7 +200,7 @@ export const UserProfile = observer(
|
|||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
{user.relationship === RelationshipStatus.Friend && (
|
||||
{user.relationship === "Friend" && (
|
||||
<Localizer>
|
||||
<Tooltip
|
||||
content={
|
||||
|
|
@ -214,28 +216,25 @@ export const UserProfile = observer(
|
|||
</Tooltip>
|
||||
</Localizer>
|
||||
)}
|
||||
{user.relationship === RelationshipStatus.User &&
|
||||
!dummy && (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
onClose?.();
|
||||
history.push(`/settings/profile`);
|
||||
}}>
|
||||
<Edit size={28} />
|
||||
</IconButton>
|
||||
)}
|
||||
{user.relationship === "User" && !dummy && (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
onClose?.();
|
||||
history.push(`/settings/profile`);
|
||||
}}>
|
||||
<Edit size={28} />
|
||||
</IconButton>
|
||||
)}
|
||||
{!user.bot &&
|
||||
flags != 2 &&
|
||||
flags != 4 &&
|
||||
(user.relationship ===
|
||||
RelationshipStatus.Incoming ||
|
||||
user.relationship ===
|
||||
RelationshipStatus.None) && (
|
||||
(user.relationship === "Incoming" ||
|
||||
user.relationship === "None") && (
|
||||
<IconButton onClick={() => user.addFriend()}>
|
||||
<UserPlus size={28} />
|
||||
</IconButton>
|
||||
)}
|
||||
{user.relationship === RelationshipStatus.Outgoing && (
|
||||
{user.relationship === "Outgoing" && (
|
||||
<IconButton onClick={() => user.removeFriend()}>
|
||||
<UserX size={28} />
|
||||
</IconButton>
|
||||
|
|
@ -247,7 +246,7 @@ export const UserProfile = observer(
|
|||
onClick={() => setTab("profile")}>
|
||||
<Text id="app.special.popovers.user_profile.profile" />
|
||||
</div>
|
||||
{user.relationship !== RelationshipStatus.User && (
|
||||
{user.relationship !== "User" && (
|
||||
<>
|
||||
<div
|
||||
data-active={tab === "friends"}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ export function grabFiles(
|
|||
input.addEventListener("change", async (e) => {
|
||||
const files = (e.currentTarget as HTMLInputElement)?.files;
|
||||
if (!files) return;
|
||||
|
||||
for (const file of files) {
|
||||
if (file.size > maxFileSize) {
|
||||
return tooLarge();
|
||||
|
|
@ -184,6 +185,7 @@ export function FileUploader(props: Props) {
|
|||
id: "error",
|
||||
error: "FileTooLarge",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
files.push(blob);
|
||||
|
|
@ -212,6 +214,7 @@ export function FileUploader(props: Props) {
|
|||
for (const item of dropped) {
|
||||
if (item.size > props.maxFileSize) {
|
||||
openScreen({ id: "error", error: "FileTooLarge" });
|
||||
continue;
|
||||
}
|
||||
|
||||
files.push(item);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { Route, Switch, useHistory, useParams } from "react-router-dom";
|
||||
import { Presence, RelationshipStatus } from "revolt-api/types/Users";
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Message, User } from "revolt.js";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
import { useCallback, useContext, useEffect } from "preact/hooks";
|
||||
|
|
@ -84,7 +82,7 @@ function Notifier() {
|
|||
}
|
||||
|
||||
let body, icon;
|
||||
if (typeof msg.content === "string") {
|
||||
if (msg.content) {
|
||||
body = client.markdownToText(msg.content);
|
||||
|
||||
if (msg.masquerade?.avatar) {
|
||||
|
|
@ -92,22 +90,23 @@ function Notifier() {
|
|||
} else {
|
||||
icon = msg.author?.generateAvatarURL({ max_side: 256 });
|
||||
}
|
||||
} else {
|
||||
} else if (msg.system) {
|
||||
const users = client.users;
|
||||
switch (msg.content.type) {
|
||||
|
||||
switch (msg.system.type) {
|
||||
case "user_added":
|
||||
case "user_remove":
|
||||
{
|
||||
const user = users.get(msg.content.id);
|
||||
const user = users.get(msg.system.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${
|
||||
msg.content.type === "user_added"
|
||||
msg.system.type === "user_added"
|
||||
? "added_by"
|
||||
: "removed_by"
|
||||
}`,
|
||||
{
|
||||
user: user?.username,
|
||||
other_user: users.get(msg.content.by)
|
||||
other_user: users.get(msg.system.by)
|
||||
?.username,
|
||||
},
|
||||
);
|
||||
|
|
@ -121,9 +120,9 @@ function Notifier() {
|
|||
case "user_kicked":
|
||||
case "user_banned":
|
||||
{
|
||||
const user = users.get(msg.content.id);
|
||||
const user = users.get(msg.system.id);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
`app.main.channel.system.${msg.system.type}`,
|
||||
{ user: user?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
|
|
@ -133,12 +132,12 @@ function Notifier() {
|
|||
break;
|
||||
case "channel_renamed":
|
||||
{
|
||||
const user = users.get(msg.content.by);
|
||||
const user = users.get(msg.system.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.channel_renamed`,
|
||||
{
|
||||
user: users.get(msg.content.by)?.username,
|
||||
name: msg.content.name,
|
||||
user: users.get(msg.system.by)?.username,
|
||||
name: msg.system.name,
|
||||
},
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
|
|
@ -149,10 +148,10 @@ function Notifier() {
|
|||
case "channel_description_changed":
|
||||
case "channel_icon_changed":
|
||||
{
|
||||
const user = users.get(msg.content.by);
|
||||
const user = users.get(msg.system.by);
|
||||
body = translate(
|
||||
`app.main.channel.system.${msg.content.type}`,
|
||||
{ user: users.get(msg.content.by)?.username },
|
||||
`app.main.channel.system.${msg.system.type}`,
|
||||
{ user: users.get(msg.system.by)?.username },
|
||||
);
|
||||
icon = user?.generateAvatarURL({
|
||||
max_side: 256,
|
||||
|
|
@ -210,17 +209,17 @@ function Notifier() {
|
|||
|
||||
const relationship = useCallback(
|
||||
async (user: User) => {
|
||||
if (client.user?.status?.presence === Presence.Busy) return;
|
||||
if (client.user?.status?.presence === "Busy") return;
|
||||
if (!showNotification) return;
|
||||
|
||||
let event;
|
||||
switch (user.relationship) {
|
||||
case RelationshipStatus.Incoming:
|
||||
case "Incoming":
|
||||
event = translate("notifications.sent_request", {
|
||||
person: user.username,
|
||||
});
|
||||
break;
|
||||
case RelationshipStatus.Friend:
|
||||
case "Friend":
|
||||
event = translate("notifications.now_friends", {
|
||||
person: user.username,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default observer(({ children }: Props) => {
|
|||
|
||||
useEffect(() => {
|
||||
if (navigator.onLine) {
|
||||
state.config.createClient().req("GET", "/").then(state.config.set);
|
||||
state.config.createClient().api.get("/").then(state.config.set);
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ export default observer(({ children }: Props) => {
|
|||
}
|
||||
}, [state.auth.getSession()]);
|
||||
|
||||
useEffect(() => registerEvents(state.auth, setStatus, client), [client]);
|
||||
useEffect(() => registerEvents(state, setStatus, client), [client]);
|
||||
|
||||
if (!loaded || status === ClientStatus.LOADING) {
|
||||
return <Preloader type="spinner" />;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This file monitors the message cache to delete any queued messages that have already sent.
|
||||
*/
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Message } from "revolt.js";
|
||||
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This file monitors changes to settings and syncs them to the server.
|
||||
*/
|
||||
import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
|
||||
import { ClientboundNotification } from "revolt.js";
|
||||
|
||||
import { useEffect } from "preact/hooks";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
import { Client } from "revolt.js/dist";
|
||||
import { Client, Server } from "revolt.js";
|
||||
|
||||
import { StateUpdater } from "preact/hooks";
|
||||
|
||||
import Auth from "../../mobx/stores/Auth";
|
||||
import { deleteRenderer } from "../../lib/renderer/Singleton";
|
||||
|
||||
import State from "../../mobx/State";
|
||||
|
||||
import { resetMemberSidebarFetched } from "../../components/navigation/right/MemberSidebar";
|
||||
import { ClientStatus } from "./RevoltClient";
|
||||
|
||||
export function registerEvents(
|
||||
auth: Auth,
|
||||
state: State,
|
||||
setStatus: StateUpdater<ClientStatus>,
|
||||
client: Client,
|
||||
) {
|
||||
|
|
@ -25,9 +27,22 @@ export function registerEvents(
|
|||
},
|
||||
|
||||
logout: () => {
|
||||
auth.logout();
|
||||
state.auth.logout();
|
||||
state.reset();
|
||||
setStatus(ClientStatus.READY);
|
||||
},
|
||||
|
||||
"channel/delete": (channel_id: string) => {
|
||||
deleteRenderer(channel_id);
|
||||
},
|
||||
|
||||
"server/delete": (_, server: Server) => {
|
||||
if (server) {
|
||||
for (const channel_id of server.channel_ids) {
|
||||
deleteRenderer(channel_id);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Channel } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
|
|
@ -6,23 +6,23 @@ import { Children } from "../../types/Preact";
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function takeError(error: any): string {
|
||||
const type = error?.response?.data?.type;
|
||||
const id = type;
|
||||
if (!type) {
|
||||
if (
|
||||
error?.response?.status === 401 ||
|
||||
error?.response?.status === 403
|
||||
) {
|
||||
return "Unauthorized";
|
||||
} else if (error && !!error.isAxiosError && !error.response) {
|
||||
return "NetworkError";
|
||||
if (error.response) {
|
||||
const status = error.response.status;
|
||||
switch (status) {
|
||||
case 429:
|
||||
return "TooManyRequests";
|
||||
case 401:
|
||||
case 403:
|
||||
return "Unauthorized";
|
||||
default:
|
||||
return error.response.type ?? "UnknownError";
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
return "UnknownError";
|
||||
} else if (error.request) {
|
||||
return "NetworkError";
|
||||
}
|
||||
|
||||
return id;
|
||||
console.error(error);
|
||||
return "UnknownError";
|
||||
}
|
||||
|
||||
export function getChannelName(
|
||||
|
|
|
|||
|
|
@ -12,17 +12,8 @@ import {
|
|||
} from "@styled-icons/boxicons-regular";
|
||||
import { Cog, UserVoice } from "@styled-icons/boxicons-solid";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Attachment } from "revolt-api/types/Autumn";
|
||||
import { Presence, RelationshipStatus } from "revolt-api/types/Users";
|
||||
import {
|
||||
ChannelPermission,
|
||||
ServerPermission,
|
||||
UserPermission,
|
||||
} from "revolt.js/dist/api/permissions";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel, Message, Server, User, API } from "revolt.js";
|
||||
import { Permission, UserPermission } from "revolt.js";
|
||||
|
||||
import {
|
||||
ContextMenuWithData,
|
||||
|
|
@ -60,7 +51,7 @@ interface ContextMenuData {
|
|||
server_list?: string;
|
||||
channel?: string;
|
||||
message?: Message;
|
||||
attachment?: Attachment;
|
||||
attachment?: API.File;
|
||||
|
||||
unread?: boolean;
|
||||
queued?: QueuedMessage;
|
||||
|
|
@ -82,9 +73,9 @@ type Action =
|
|||
| { action: "quote_message"; content: string }
|
||||
| { action: "edit_message"; id: string }
|
||||
| { action: "delete_message"; target: Message }
|
||||
| { action: "open_file"; attachment: Attachment }
|
||||
| { action: "save_file"; attachment: Attachment }
|
||||
| { action: "copy_file_link"; attachment: Attachment }
|
||||
| { action: "open_file"; attachment: API.File }
|
||||
| { action: "save_file"; attachment: API.File }
|
||||
| { action: "copy_file_link"; attachment: API.File }
|
||||
| { action: "open_link"; link: string }
|
||||
| { action: "copy_link"; link: string }
|
||||
| { action: "remove_member"; channel: Channel; user: User }
|
||||
|
|
@ -97,7 +88,7 @@ type Action =
|
|||
| { action: "add_friend"; user: User }
|
||||
| { action: "remove_friend"; user: User }
|
||||
| { action: "cancel_friend"; user: User }
|
||||
| { action: "set_presence"; presence: Presence }
|
||||
| { action: "set_presence"; presence: API.Presence }
|
||||
| { action: "set_status" }
|
||||
| { action: "clear_status" }
|
||||
| { action: "create_channel"; target: Server }
|
||||
|
|
@ -505,9 +496,8 @@ export default function ContextMenus() {
|
|||
|
||||
if (server_list) {
|
||||
const server = client.servers.get(server_list)!;
|
||||
const permissions = server.permission;
|
||||
if (server) {
|
||||
if (permissions & ServerPermission.ManageChannels) {
|
||||
if (server.havePermission("ManageChannel")) {
|
||||
generateAction({
|
||||
action: "create_category",
|
||||
target: server,
|
||||
|
|
@ -517,7 +507,8 @@ export default function ContextMenus() {
|
|||
target: server,
|
||||
});
|
||||
}
|
||||
if (permissions & ServerPermission.ManageServer)
|
||||
|
||||
if (server.havePermission("ManageServer"))
|
||||
generateAction({
|
||||
action: "open_server_settings",
|
||||
id: server_list,
|
||||
|
|
@ -592,29 +583,29 @@ export default function ContextMenus() {
|
|||
if (!user.bot) {
|
||||
let actions: Action["action"][];
|
||||
switch (user.relationship) {
|
||||
case RelationshipStatus.User:
|
||||
case "User":
|
||||
actions = [];
|
||||
break;
|
||||
case RelationshipStatus.Friend:
|
||||
case "Friend":
|
||||
actions = ["remove_friend", "block_user"];
|
||||
break;
|
||||
case RelationshipStatus.Incoming:
|
||||
case "Incoming":
|
||||
actions = [
|
||||
"add_friend",
|
||||
"cancel_friend",
|
||||
"block_user",
|
||||
];
|
||||
break;
|
||||
case RelationshipStatus.Outgoing:
|
||||
case "Outgoing":
|
||||
actions = ["cancel_friend", "block_user"];
|
||||
break;
|
||||
case RelationshipStatus.Blocked:
|
||||
case "Blocked":
|
||||
actions = ["unblock_user"];
|
||||
break;
|
||||
case RelationshipStatus.BlockedOther:
|
||||
case "BlockedOther":
|
||||
actions = ["block_user"];
|
||||
break;
|
||||
case RelationshipStatus.None:
|
||||
case "None":
|
||||
default:
|
||||
if (
|
||||
(user.flags && 2) ||
|
||||
|
|
@ -673,9 +664,7 @@ export default function ContextMenus() {
|
|||
userId !== uid &&
|
||||
uid !== server.owner
|
||||
) {
|
||||
if (
|
||||
serverPermissions & ServerPermission.KickMembers
|
||||
)
|
||||
if (serverPermissions & Permission.KickMembers)
|
||||
generateAction(
|
||||
{
|
||||
action: "kick_member",
|
||||
|
|
@ -688,7 +677,7 @@ export default function ContextMenus() {
|
|||
"var(--error)", // the only relevant part really
|
||||
);
|
||||
|
||||
if (serverPermissions & ServerPermission.BanMembers)
|
||||
if (serverPermissions & Permission.BanMembers)
|
||||
generateAction(
|
||||
{
|
||||
action: "ban_member",
|
||||
|
|
@ -718,8 +707,7 @@ export default function ContextMenus() {
|
|||
if (message && !queued) {
|
||||
const sendPermission =
|
||||
message.channel &&
|
||||
message.channel.permission &
|
||||
ChannelPermission.SendMessage;
|
||||
message.channel.permission & Permission.SendMessage;
|
||||
|
||||
if (sendPermission) {
|
||||
generateAction({
|
||||
|
|
@ -759,8 +747,7 @@ export default function ContextMenus() {
|
|||
|
||||
if (
|
||||
message.author_id === userId ||
|
||||
channelPermissions &
|
||||
ChannelPermission.ManageMessages
|
||||
channelPermissions & Permission.ManageMessages
|
||||
) {
|
||||
generateAction({
|
||||
action: "delete_message",
|
||||
|
|
@ -903,7 +890,7 @@ export default function ContextMenus() {
|
|||
case "VoiceChannel":
|
||||
if (
|
||||
channelPermissions &
|
||||
ChannelPermission.InviteOthers
|
||||
Permission.InviteOthers
|
||||
) {
|
||||
generateAction({
|
||||
action: "create_invite",
|
||||
|
|
@ -913,7 +900,7 @@ export default function ContextMenus() {
|
|||
|
||||
if (
|
||||
serverPermissions &
|
||||
ServerPermission.ManageServer
|
||||
Permission.ManageServer
|
||||
)
|
||||
generateAction(
|
||||
{
|
||||
|
|
@ -926,7 +913,7 @@ export default function ContextMenus() {
|
|||
|
||||
if (
|
||||
serverPermissions &
|
||||
ServerPermission.ManageChannels
|
||||
Permission.ManageChannel
|
||||
)
|
||||
generateAction({
|
||||
action: "delete_channel",
|
||||
|
|
@ -958,20 +945,15 @@ export default function ContextMenus() {
|
|||
);
|
||||
|
||||
if (
|
||||
serverPermissions &
|
||||
ServerPermission.ChangeNickname ||
|
||||
serverPermissions &
|
||||
ServerPermission.ChangeAvatar
|
||||
serverPermissions & Permission.ChangeNickname ||
|
||||
serverPermissions & Permission.ChangeAvatar
|
||||
)
|
||||
generateAction(
|
||||
{ action: "edit_identity", target: server },
|
||||
"edit_identity",
|
||||
);
|
||||
|
||||
if (
|
||||
serverPermissions &
|
||||
ServerPermission.ManageServer
|
||||
)
|
||||
if (serverPermissions & Permission.ManageServer)
|
||||
generateAction(
|
||||
{
|
||||
action: "open_server_settings",
|
||||
|
|
@ -1060,7 +1042,7 @@ export default function ContextMenus() {
|
|||
<MenuItem
|
||||
data={{
|
||||
action: "set_presence",
|
||||
presence: Presence.Online,
|
||||
presence: "Online",
|
||||
}}
|
||||
disabled={!isOnline}>
|
||||
<div className="indicator online" />
|
||||
|
|
@ -1069,7 +1051,7 @@ export default function ContextMenus() {
|
|||
<MenuItem
|
||||
data={{
|
||||
action: "set_presence",
|
||||
presence: Presence.Idle,
|
||||
presence: "Idle",
|
||||
}}
|
||||
disabled={!isOnline}>
|
||||
<div className="indicator idle" />
|
||||
|
|
@ -1078,7 +1060,7 @@ export default function ContextMenus() {
|
|||
<MenuItem
|
||||
data={{
|
||||
action: "set_presence",
|
||||
presence: Presence.Busy,
|
||||
presence: "Busy",
|
||||
}}
|
||||
disabled={!isOnline}>
|
||||
<div className="indicator busy" />
|
||||
|
|
@ -1087,7 +1069,7 @@ export default function ContextMenus() {
|
|||
<MenuItem
|
||||
data={{
|
||||
action: "set_presence",
|
||||
presence: Presence.Invisible,
|
||||
presence: "Invisible",
|
||||
}}
|
||||
disabled={!isOnline}>
|
||||
<div className="indicator invisible" />
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import {
|
|||
LeftArrowAlt,
|
||||
} from "@styled-icons/boxicons-regular";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Channel } from "revolt.js";
|
||||
import { Server } from "revolt.js";
|
||||
|
||||
import { ContextMenuWithData, MenuItem } from "preact-context-menu";
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { action, makeAutoObservable } from "mobx";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
import { Channel } from "revolt.js";
|
||||
import { Message } from "revolt.js";
|
||||
import { Nullable } from "revolt.js";
|
||||
|
||||
import { SimpleRenderer } from "./simple/SimpleRenderer";
|
||||
import { RendererRoutines, ScrollState } from "./types";
|
||||
|
|
@ -222,3 +222,7 @@ export function getRenderer(channel: Channel) {
|
|||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
export function deleteRenderer(channel_id: string) {
|
||||
delete renderers[channel_id];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Message } from "revolt.js";
|
||||
|
||||
import { ChannelRenderer } from "./Singleton";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { action, makeAutoObservable, runInAction } from "mobx";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Nullable, toNullable } from "revolt.js/dist/util/null";
|
||||
import { Channel } from "revolt.js";
|
||||
import { Nullable, toNullable } from "revolt.js";
|
||||
|
||||
import type { ProduceType, VoiceUser } from "./Types";
|
||||
import type VoiceClient from "./VoiceClient";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// @ts-expect-error No typings.
|
||||
import stringify from "json-stringify-deterministic";
|
||||
import localforage from "localforage";
|
||||
import { makeAutoObservable, reaction } from "mobx";
|
||||
import { makeAutoObservable, reaction, runInAction } from "mobx";
|
||||
import { Client } from "revolt.js";
|
||||
|
||||
import { reportError } from "../lib/ErrorBoundary";
|
||||
|
|
@ -184,10 +184,12 @@ export default class State {
|
|||
}
|
||||
|
||||
if (Object.keys(obj).length > 0) {
|
||||
client.syncSetSettings(
|
||||
obj as any,
|
||||
revision,
|
||||
);
|
||||
if (client.websocket.connected) {
|
||||
client.syncSetSettings(
|
||||
obj as any,
|
||||
revision,
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -198,12 +200,14 @@ export default class State {
|
|||
}
|
||||
|
||||
this.sync.setRevision(id, revision);
|
||||
client.syncSetSettings(
|
||||
(
|
||||
store as unknown as Syncable
|
||||
).toSyncable(),
|
||||
revision,
|
||||
);
|
||||
if (client.websocket.connected) {
|
||||
client.syncSetSettings(
|
||||
(
|
||||
store as unknown as Syncable
|
||||
).toSyncable(),
|
||||
revision,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -263,6 +267,26 @@ export default class State {
|
|||
// Post-hydration, init plugins.
|
||||
this.plugins.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset known state values.
|
||||
*/
|
||||
reset() {
|
||||
runInAction(() => {
|
||||
this.draft = new Draft();
|
||||
this.experiments = new Experiments();
|
||||
this.layout = new Layout();
|
||||
this.notifications = new NotificationOptions();
|
||||
this.queue = new MessageQueue();
|
||||
this.settings = new Settings();
|
||||
this.sync = new Sync(this);
|
||||
|
||||
this.save();
|
||||
|
||||
this.persistent = [];
|
||||
this.register();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var state: State;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { runInAction } from "mobx";
|
||||
import { Session } from "revolt-api/types/Auth";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import { Fonts, MonospaceFonts, Overrides } from "../../context/Theme";
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ export interface LegacySyncOptions {
|
|||
export interface LegacyAuthState {
|
||||
accounts: {
|
||||
[key: string]: {
|
||||
session: Session;
|
||||
session: API.Session;
|
||||
};
|
||||
};
|
||||
active?: string;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
import { Session } from "revolt-api/types/Auth";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
import { API } from "revolt.js";
|
||||
import { Nullable } from "revolt.js";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ import Persistent from "../interfaces/Persistent";
|
|||
import Store from "../interfaces/Store";
|
||||
|
||||
interface Account {
|
||||
session: Session;
|
||||
session: API.Session;
|
||||
}
|
||||
|
||||
export interface Data {
|
||||
|
|
@ -82,7 +82,7 @@ export default class Auth implements Store, Persistent<Data> {
|
|||
* Add a new session to the auth manager.
|
||||
* @param session Session
|
||||
*/
|
||||
@action setSession(session: Session) {
|
||||
@action setSession(session: API.Session) {
|
||||
this.sessions.set(session.user_id, { session });
|
||||
this.current = session.user_id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
import { Presence, RelationshipStatus } from "revolt-api/types/Users";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Server } from "revolt.js/dist/maps/Servers";
|
||||
import { Channel } from "revolt.js";
|
||||
import { Message } from "revolt.js";
|
||||
import { Server } from "revolt.js";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
|
|
@ -113,7 +112,7 @@ export default class NotificationOptions
|
|||
*/
|
||||
shouldNotify(message: Message) {
|
||||
// Make sure the author is not blocked.
|
||||
if (message.author?.relationship === RelationshipStatus.Blocked) {
|
||||
if (message.author?.relationship === "Blocked") {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +123,7 @@ export default class NotificationOptions
|
|||
}
|
||||
|
||||
// Check whether we are busy.
|
||||
if (user.status?.presence === Presence.Busy) {
|
||||
if (user.status?.presence === "Busy") {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { action, computed, makeAutoObservable } from "mobx";
|
||||
import { RevoltConfiguration } from "revolt-api/types/Core";
|
||||
import { API } from "revolt.js";
|
||||
import { Client } from "revolt.js";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
import { Nullable } from "revolt.js";
|
||||
|
||||
import { isDebug } from "../../revision";
|
||||
import Persistent from "../interfaces/Persistent";
|
||||
|
|
@ -11,9 +11,9 @@ import Store from "../interfaces/Store";
|
|||
* Stores server configuration data.
|
||||
*/
|
||||
export default class ServerConfig
|
||||
implements Store, Persistent<RevoltConfiguration>
|
||||
implements Store, Persistent<API.RevoltConfig>
|
||||
{
|
||||
private config: Nullable<RevoltConfiguration>;
|
||||
private config: Nullable<API.RevoltConfig>;
|
||||
|
||||
/**
|
||||
* Construct new ServerConfig store.
|
||||
|
|
@ -32,7 +32,7 @@ export default class ServerConfig
|
|||
return JSON.parse(JSON.stringify(this.config));
|
||||
}
|
||||
|
||||
@action hydrate(data: RevoltConfiguration) {
|
||||
@action hydrate(data: API.RevoltConfig) {
|
||||
this.config = data ?? null;
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ export default class ServerConfig
|
|||
* Set server configuration.
|
||||
* @param config Server configuration
|
||||
*/
|
||||
@action set(config: RevoltConfiguration) {
|
||||
@action set(config: API.RevoltConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
runInAction,
|
||||
} from "mobx";
|
||||
import { Client } from "revolt.js";
|
||||
import { UserSettings } from "revolt-api/types/Sync";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
|
|
@ -104,7 +103,7 @@ export default class Sync implements Store, Persistent<Data> {
|
|||
return this.revision.get(key);
|
||||
}
|
||||
|
||||
@action apply(data: UserSettings) {
|
||||
@action apply(data: Record<string, [number, string]>) {
|
||||
const tryRead = (key: string) => {
|
||||
if (key in data) {
|
||||
const revision = data[key][0];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// @ts-expect-error No typings.
|
||||
import rgba from "color-rgba";
|
||||
import { makeAutoObservable, computed, action } from "mobx";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Ghost } from "@styled-icons/boxicons-solid";
|
|||
import { reaction } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Redirect, useParams } from "react-router-dom";
|
||||
import { Channel as ChannelI } from "revolt.js/dist/maps/Channels";
|
||||
import { Channel as ChannelI } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
@ -97,29 +97,35 @@ const PlaceholderBase = styled.div`
|
|||
}
|
||||
`;
|
||||
|
||||
export function Channel({ id, server_id }: { id: string; server_id: string }) {
|
||||
const client = useClient();
|
||||
const channel = client.channels.get(id);
|
||||
export const Channel = observer(
|
||||
({ id, server_id }: { id: string; server_id: string }) => {
|
||||
const client = useClient();
|
||||
|
||||
if (server_id && !channel) {
|
||||
const server = client.servers.get(server_id);
|
||||
if (server && server.channel_ids.length > 0) {
|
||||
return (
|
||||
<Redirect
|
||||
to={`/server/${server_id}/channel/${server.channel_ids[0]}`}
|
||||
/>
|
||||
);
|
||||
if (!client.channels.exists(id)) {
|
||||
if (server_id) {
|
||||
const server = client.servers.get(server_id);
|
||||
if (server && server.channel_ids.length > 0) {
|
||||
return (
|
||||
<Redirect
|
||||
to={`/server/${server_id}/channel/${server.channel_ids[0]}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
|
||||
return <ChannelPlaceholder />;
|
||||
}
|
||||
}
|
||||
|
||||
if (!channel) return <ChannelPlaceholder />;
|
||||
const channel = client.channels.get(id)!;
|
||||
if (channel.channel_type === "VoiceChannel") {
|
||||
return <VoiceChannel channel={channel} />;
|
||||
}
|
||||
|
||||
if (channel.channel_type === "VoiceChannel") {
|
||||
return <VoiceChannel channel={channel} />;
|
||||
}
|
||||
|
||||
return <TextChannel channel={channel} />;
|
||||
}
|
||||
return <TextChannel channel={channel} />;
|
||||
},
|
||||
);
|
||||
|
||||
const TextChannel = observer(({ channel }: { channel: ChannelI }) => {
|
||||
const layout = useApplicationState().layout;
|
||||
|
|
@ -143,9 +149,9 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => {
|
|||
// Mark channel as read.
|
||||
useEffect(() => {
|
||||
setLastId(
|
||||
channel.unread
|
||||
(channel.unread
|
||||
? channel.client.unreads?.getUnread(channel._id)?.last_id
|
||||
: undefined ?? undefined,
|
||||
: undefined) ?? undefined,
|
||||
);
|
||||
|
||||
const checkUnread = () =>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import {
|
|||
} from "@styled-icons/boxicons-regular";
|
||||
import { Notepad, Group } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import { Channel } from "revolt.js";
|
||||
import { User } from "revolt.js";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Channel } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { runInAction } from "mobx";
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { animateScroll } from "react-scroll";
|
||||
import { Channel } from "revolt.js/dist/maps/Channels";
|
||||
import { Channel } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
import useResizeObserver from "use-resize-observer";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from "revolt.js/dist/maps/Messages";
|
||||
import { Message } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
import { X } from "@styled-icons/boxicons-regular";
|
||||
import isEqual from "lodash.isequal";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Masquerade } from "revolt-api/types/Channels";
|
||||
import { RelationshipStatus } from "revolt-api/types/Users";
|
||||
import { Message as MessageI } from "revolt.js/dist/maps/Messages";
|
||||
import { Nullable } from "revolt.js/dist/util/null";
|
||||
import { API } from "revolt.js";
|
||||
import { Message as MessageI } from "revolt.js";
|
||||
import { Nullable } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
|
|
@ -99,10 +98,10 @@ export default observer(({ last_id, renderer, highlight }: Props) => {
|
|||
function compare(
|
||||
current: string,
|
||||
curAuthor: string,
|
||||
currentMasq: Nullable<Masquerade>,
|
||||
currentMasq: Nullable<API.Masquerade>,
|
||||
previous: string,
|
||||
prevAuthor: string,
|
||||
previousMasq: Nullable<Masquerade>,
|
||||
previousMasq: Nullable<API.Masquerade>,
|
||||
) {
|
||||
head = false;
|
||||
const atime = decodeTime(current),
|
||||
|
|
@ -172,9 +171,7 @@ export default observer(({ last_id, renderer, highlight }: Props) => {
|
|||
highlight={highlight === message._id}
|
||||
/>,
|
||||
);
|
||||
} else if (
|
||||
message.author?.relationship === RelationshipStatus.Blocked
|
||||
) {
|
||||
} else if (message.author?.relationship === "Blocked") {
|
||||
blocked++;
|
||||
} else {
|
||||
if (blocked > 0) pushBlocked();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { X, Plus } from "@styled-icons/boxicons-regular";
|
|||
import { PhoneCall, Envelope, UserX } 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 { User } from "revolt.js/dist/maps/Users";
|
||||
import { User } from "revolt.js";
|
||||
|
||||
import styles from "./Friend.module.scss";
|
||||
import classNames from "classnames";
|
||||
|
|
@ -33,7 +32,7 @@ export const Friend = observer(({ user }: Props) => {
|
|||
const actions: Children[] = [];
|
||||
let subtext: Children = null;
|
||||
|
||||
if (user.relationship === RelationshipStatus.Friend) {
|
||||
if (user.relationship === "Friend") {
|
||||
subtext = <UserStatus user={user} />;
|
||||
actions.push(
|
||||
<>
|
||||
|
|
@ -70,7 +69,7 @@ export const Friend = observer(({ user }: Props) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (user.relationship === RelationshipStatus.Incoming) {
|
||||
if (user.relationship === "Incoming") {
|
||||
actions.push(
|
||||
<IconButton
|
||||
type="circle"
|
||||
|
|
@ -83,14 +82,14 @@ export const Friend = observer(({ user }: Props) => {
|
|||
subtext = <Text id="app.special.friends.incoming" />;
|
||||
}
|
||||
|
||||
if (user.relationship === RelationshipStatus.Outgoing) {
|
||||
if (user.relationship === "Outgoing") {
|
||||
subtext = <Text id="app.special.friends.outgoing" />;
|
||||
}
|
||||
|
||||
if (
|
||||
user.relationship === RelationshipStatus.Friend ||
|
||||
user.relationship === RelationshipStatus.Outgoing ||
|
||||
user.relationship === RelationshipStatus.Incoming
|
||||
user.relationship === "Friend" ||
|
||||
user.relationship === "Outgoing" ||
|
||||
user.relationship === "Incoming"
|
||||
) {
|
||||
actions.push(
|
||||
<IconButton
|
||||
|
|
@ -103,7 +102,7 @@ export const Friend = observer(({ user }: Props) => {
|
|||
onClick={(ev) =>
|
||||
stopPropagation(
|
||||
ev,
|
||||
user.relationship === RelationshipStatus.Friend
|
||||
user.relationship === "Friend"
|
||||
? openScreen({
|
||||
id: "special_prompt",
|
||||
type: "unfriend_user",
|
||||
|
|
@ -117,7 +116,7 @@ export const Friend = observer(({ user }: Props) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (user.relationship === RelationshipStatus.Blocked) {
|
||||
if (user.relationship === "Blocked") {
|
||||
actions.push(
|
||||
<IconButton
|
||||
type="circle"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { ChevronRight } from "@styled-icons/boxicons-regular";
|
||||
import { UserDetail, MessageAdd, UserPlus } from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { RelationshipStatus, Presence } from "revolt-api/types/Users";
|
||||
import { User } from "revolt.js/dist/maps/Users";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
import { User } from "revolt.js";
|
||||
|
||||
import styles from "./Friend.module.scss";
|
||||
import classNames from "classnames";
|
||||
|
|
@ -31,36 +29,32 @@ export default observer(() => {
|
|||
const users = [...client.users.values()];
|
||||
users.sort((a, b) => a.username.localeCompare(b.username));
|
||||
|
||||
const friends = users.filter(
|
||||
(x) => x.relationship === RelationshipStatus.Friend,
|
||||
);
|
||||
const friends = users.filter((x) => x.relationship === "Friend");
|
||||
|
||||
const lists = [
|
||||
[
|
||||
"",
|
||||
users.filter((x) => x.relationship === RelationshipStatus.Incoming),
|
||||
],
|
||||
["", users.filter((x) => x.relationship === "Incoming")],
|
||||
[
|
||||
"app.special.friends.sent",
|
||||
users.filter((x) => x.relationship === RelationshipStatus.Outgoing),
|
||||
users.filter((x) => x.relationship === "Outgoing"),
|
||||
"outgoing",
|
||||
],
|
||||
[
|
||||
"app.status.online",
|
||||
friends.filter(
|
||||
(x) => x.online && x.status?.presence !== Presence.Invisible,
|
||||
(x) => x.online && x.status?.presence !== "Invisible",
|
||||
),
|
||||
"online",
|
||||
],
|
||||
[
|
||||
"app.status.offline",
|
||||
friends.filter(
|
||||
(x) => !x.online || x.status?.presence === Presence.Invisible,
|
||||
(x) => !x.online || x.status?.presence === "Invisible",
|
||||
),
|
||||
"offline",
|
||||
],
|
||||
[
|
||||
"app.special.friends.blocked",
|
||||
users.filter((x) => x.relationship === RelationshipStatus.Blocked),
|
||||
users.filter((x) => x.relationship === "Blocked"),
|
||||
"blocked",
|
||||
],
|
||||
] as [string, User[], string][];
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
|||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import Tooltip from "../../components/common/Tooltip";
|
||||
import { PageHeader } from "../../components/ui/Header";
|
||||
import CategoryButton from "../../components/ui/fluent/CategoryButton";
|
||||
import wideSVG from "/assets/wide.svg";
|
||||
|
|
@ -42,6 +42,7 @@ const Overlay = styled.div`
|
|||
`;
|
||||
|
||||
export default observer(() => {
|
||||
const { openScreen } = useIntermediate();
|
||||
const client = useContext(AppContext);
|
||||
const state = useApplicationState();
|
||||
|
||||
|
|
@ -93,7 +94,13 @@ export default observer(() => {
|
|||
<img src={wideSVG} />
|
||||
</h3>
|
||||
<div className={styles.actions}>
|
||||
<Link to="/settings">
|
||||
<a
|
||||
onClick={() =>
|
||||
openScreen({
|
||||
id: "special_input",
|
||||
type: "create_group",
|
||||
})
|
||||
}>
|
||||
<CategoryButton
|
||||
action="chevron"
|
||||
icon={<PlusCircle size={32} />}
|
||||
|
|
@ -102,7 +109,7 @@ export default observer(() => {
|
|||
}>
|
||||
<Text id="app.home.group" />
|
||||
</CategoryButton>
|
||||
</Link>
|
||||
</a>
|
||||
<Link to="/discover">
|
||||
<a>
|
||||
<CategoryButton
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ArrowBack } from "@styled-icons/boxicons-regular";
|
||||
import { autorun } from "mobx";
|
||||
import { Redirect, useHistory, useParams } from "react-router-dom";
|
||||
import { RetrievedInvite } from "revolt-api/types/Invites";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import styles from "./Invite.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
|
|
@ -36,7 +36,7 @@ export default function Invite() {
|
|||
const { code } = useParams<{ code: string }>();
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
const [invite, setInvite] = useState<RetrievedInvite | undefined>(
|
||||
const [invite, setInvite] = useState<API.InviteResponse | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
|
|
@ -92,6 +92,8 @@ export default function Invite() {
|
|||
);
|
||||
}
|
||||
|
||||
if (invite.type === "Group") return <h1>unimplemented</h1>;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.invite}
|
||||
|
|
@ -156,42 +158,17 @@ export default function Invite() {
|
|||
return history.push("/");
|
||||
}
|
||||
|
||||
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}`,
|
||||
);
|
||||
}
|
||||
|
||||
const dispose = autorun(() => {
|
||||
const server = client.servers.get(
|
||||
invite.server_id,
|
||||
);
|
||||
|
||||
defer(() => {
|
||||
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) {
|
||||
setError(takeError(err));
|
||||
} finally {
|
||||
setProcessing(false);
|
||||
}
|
||||
}}>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { useParams } from "react-router-dom";
|
||||
import { ServerPermission } from "revolt.js";
|
||||
import { Route } from "revolt.js/dist/api/routes";
|
||||
import { API, Permission } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
|
@ -37,8 +36,7 @@ const Option = styled.div`
|
|||
export default function InviteBot() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const client = useClient();
|
||||
const [data, setData] =
|
||||
useState<Route<"GET", "/bots/id/invite">["response"]>();
|
||||
const [data, setData] = useState<API.PublicBot>();
|
||||
|
||||
useEffect(() => {
|
||||
client.bots.fetchPublic(id).then(setData);
|
||||
|
|
@ -72,11 +70,7 @@ export default function InviteBot() {
|
|||
onChange={(e) => setServer(e.currentTarget.value)}>
|
||||
<option value="none">Select a server</option>
|
||||
{[...client.servers.values()]
|
||||
.filter(
|
||||
(x) =>
|
||||
x.permission &
|
||||
ServerPermission.ManageServer,
|
||||
)
|
||||
.filter((x) => x.havePermission("ManageServer"))
|
||||
.map((server) => (
|
||||
<option value={server._id} key={server._id}>
|
||||
{server.name}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { detect } from "detect-browser";
|
||||
import { Session } from "revolt-api/types/Auth";
|
||||
import { Client } from "revolt.js";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
|
|
@ -44,25 +43,26 @@ export function FormLogin() {
|
|||
// This should be replaced in the future.
|
||||
const client = state.config.createClient();
|
||||
await client.fetchConfiguration();
|
||||
const session = (await client.req(
|
||||
"POST",
|
||||
"/auth/session/login",
|
||||
{ ...data, friendly_name },
|
||||
)) as unknown as Session;
|
||||
const session = await client.api.post("/auth/session/login", {
|
||||
...data,
|
||||
friendly_name,
|
||||
});
|
||||
|
||||
client.session = session;
|
||||
(client as any).Axios.defaults.headers = {
|
||||
"x-session-token": session?.token,
|
||||
};
|
||||
|
||||
async function login() {
|
||||
state.auth.setSession(session);
|
||||
if (session.result !== "Success") {
|
||||
alert("unsupported!");
|
||||
return;
|
||||
}
|
||||
|
||||
const { onboarding } = await client.req(
|
||||
"GET",
|
||||
"/onboard/hello",
|
||||
);
|
||||
const s = session;
|
||||
|
||||
client.session = session;
|
||||
(client as any).$updateHeaders();
|
||||
|
||||
async function login() {
|
||||
state.auth.setSession(s);
|
||||
}
|
||||
|
||||
const { onboarding } = await client.api.get("/onboard/hello");
|
||||
|
||||
if (onboarding) {
|
||||
openScreen({
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export function FormSendReset() {
|
|||
<Form
|
||||
page="send_reset"
|
||||
callback={async (data) => {
|
||||
await client.req("POST", "/auth/account/reset_password", data);
|
||||
await client.api.post("/auth/account/reset_password", data);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
@ -32,7 +32,7 @@ export function FormReset() {
|
|||
<Form
|
||||
page="reset"
|
||||
callback={async (data) => {
|
||||
await client.req("PATCH", "/auth/account/reset_password", {
|
||||
await client.api.patch("/auth/account/reset_password", {
|
||||
token,
|
||||
...data,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export function FormResend() {
|
|||
<Form
|
||||
page="resend"
|
||||
callback={async (data) => {
|
||||
await client.req("POST", "/auth/account/reverify", data);
|
||||
await client.api.post("/auth/account/reverify", data);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
@ -34,11 +34,8 @@ export function FormVerify() {
|
|||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
client
|
||||
.req(
|
||||
"POST",
|
||||
`/auth/account/verify/${token}` as "/auth/account/verify/:code",
|
||||
)
|
||||
client.api
|
||||
.post(`/auth/account/verify/${token as ""}`)
|
||||
.then(() => history.push("/login"))
|
||||
.catch((err) => setError(takeError(err)));
|
||||
// eslint-disable-next-line
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue