mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-25 08:30:58 -05:00
feat: implement useClient
from client controller
This commit is contained in:
parent
ce88fab714
commit
5f2311b09c
72 changed files with 330 additions and 457 deletions
|
@ -106,6 +106,7 @@
|
|||
"eslint": "^7.28.0",
|
||||
"eslint-config-preact": "^1.1.4",
|
||||
"eslint-plugin-jsdoc": "^39.3.2",
|
||||
"eslint-plugin-mobx": "^0.0.8",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"history": "4",
|
||||
"json-stringify-deterministic": "^1.0.2",
|
||||
|
|
|
@ -3,9 +3,8 @@ import styled, { css } from "styled-components/macro";
|
|||
|
||||
import { StateUpdater, useState } from "preact/hooks";
|
||||
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { emojiDictionary } from "../../assets/emojis";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import ChannelIcon from "./ChannelIcon";
|
||||
import Emoji from "./Emoji";
|
||||
import UserIcon from "./user/UserIcon";
|
||||
|
|
|
@ -2,12 +2,9 @@ import { Hash, VolumeFull } from "@styled-icons/boxicons-regular";
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Channel } from "revolt.js";
|
||||
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import fallback from "./assets/group.png";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { ImageIconBase, IconBaseProps } from "./IconBase";
|
||||
|
||||
interface Props extends IconBaseProps<Channel> {
|
||||
|
@ -22,7 +19,7 @@ export default observer(
|
|||
keyof Props | "children" | "as"
|
||||
>,
|
||||
) => {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
|
||||
const {
|
||||
size,
|
||||
|
|
|
@ -4,8 +4,7 @@ import styled from "styled-components/macro";
|
|||
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { IconBaseProps, ImageIconBase } from "./IconBase";
|
||||
|
||||
interface Props extends IconBaseProps<Server> {
|
||||
|
@ -34,7 +33,7 @@ export default observer(
|
|||
keyof Props | "children" | "as"
|
||||
>,
|
||||
) => {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
|
||||
const { target, attachment, size, animate, server_name, ...imgProps } =
|
||||
props;
|
||||
|
|
|
@ -14,8 +14,8 @@ import { QueuedMessage } from "../../../mobx/stores/MessageQueue";
|
|||
|
||||
import { I18nError } from "../../../context/Locale";
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import Markdown from "../../markdown/Markdown";
|
||||
import UserIcon from "../user/UserIcon";
|
||||
import { Username } from "../user/UserShort";
|
||||
|
@ -52,7 +52,7 @@ const Message = observer(
|
|||
queued,
|
||||
hideReply,
|
||||
}: Props) => {
|
||||
const client = useClient();
|
||||
const client = message.client;
|
||||
const user = message.author;
|
||||
|
||||
const { openScreen } = useIntermediate();
|
||||
|
|
|
@ -29,9 +29,9 @@ import {
|
|||
grabFiles,
|
||||
uploadFile,
|
||||
} from "../../../context/revoltjs/FileUploads";
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../../../context/revoltjs/util";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
import AutoComplete, { useAutoComplete } from "../AutoComplete";
|
||||
import { PermissionTooltip } from "../Tooltip";
|
||||
|
@ -148,7 +148,7 @@ export default observer(({ channel }: Props) => {
|
|||
});
|
||||
const [typing, setTyping] = useState<boolean | number>(false);
|
||||
const [replies, setReplies] = useState<Reply[]>([]);
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const translate = useTranslation();
|
||||
|
||||
const renderer = getRenderer(channel);
|
||||
|
|
|
@ -3,10 +3,9 @@ import { API } from "revolt.js";
|
|||
import styles from "./Attachment.module.scss";
|
||||
import classNames from "classnames";
|
||||
import { useTriggerEvents } from "preact-context-menu";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
|
||||
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
||||
import { useState } from "preact/hooks";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
import AttachmentActions from "./AttachmentActions";
|
||||
import { SizedGrid } from "./Grid";
|
||||
import ImageFile from "./ImageFile";
|
||||
|
@ -21,7 +20,7 @@ interface Props {
|
|||
const MAX_ATTACHMENT_WIDTH = 480;
|
||||
|
||||
export default function Attachment({ attachment, hasContent }: Props) {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { filename, metadata } = attachment;
|
||||
const [spoiler, setSpoiler] = useState(filename.startsWith("SPOILER_"));
|
||||
|
||||
|
|
|
@ -15,14 +15,14 @@ import { IconButton } from "@revoltchat/ui";
|
|||
|
||||
import { determineFileSize } from "../../../../lib/fileSize";
|
||||
|
||||
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
attachment: API.File;
|
||||
}
|
||||
|
||||
export default function AttachmentActions({ attachment }: Props) {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { filename, metadata, size } = attachment;
|
||||
|
||||
const url = client.generateFileURL(attachment);
|
||||
|
|
|
@ -5,7 +5,8 @@ import classNames from "classnames";
|
|||
import { useContext, useState } from "preact/hooks";
|
||||
|
||||
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
||||
import { AppContext } from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
|
||||
enum ImageLoadingState {
|
||||
Loading,
|
||||
|
@ -19,7 +20,7 @@ type Props = JSX.HTMLAttributes<HTMLImageElement> & {
|
|||
|
||||
export default function ImageFile({ attachment, ...props }: Props) {
|
||||
const [loading, setLoading] = useState(ImageLoadingState.Loading);
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { openScreen } = useIntermediate();
|
||||
const url = client.generateFileURL(attachment)!;
|
||||
|
||||
|
|
|
@ -3,15 +3,13 @@ import { API } from "revolt.js";
|
|||
|
||||
import styles from "./Attachment.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Button, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import RequiresOnline from "../../../../context/revoltjs/RequiresOnline";
|
||||
import {
|
||||
AppContext,
|
||||
StatusContext,
|
||||
} from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
attachment: API.File;
|
||||
|
@ -23,9 +21,8 @@ export default function TextFile({ attachment }: Props) {
|
|||
const [gated, setGated] = useState(attachment.size > 100_000);
|
||||
const [content, setContent] = useState<undefined | string>(undefined);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const status = useContext(StatusContext);
|
||||
const client = useContext(AppContext);
|
||||
|
||||
const client = useClient();
|
||||
const url = client.generateFileURL(attachment)!;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -56,7 +53,7 @@ export default function TextFile({ attachment }: Props) {
|
|||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, [content, loading, gated, status, attachment._id, attachment.size, url]);
|
||||
}, [content, loading, gated, attachment._id, attachment.size, url]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -7,7 +7,6 @@ import {
|
|||
Notification,
|
||||
} from "@styled-icons/boxicons-solid";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Permission } from "revolt.js";
|
||||
import { Message as MessageObject } from "revolt.js";
|
||||
import styled from "styled-components";
|
||||
|
||||
|
@ -24,8 +23,8 @@ import {
|
|||
Screen,
|
||||
useIntermediate,
|
||||
} from "../../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
import Tooltip from "../../../common/Tooltip";
|
||||
|
||||
interface Props {
|
||||
|
@ -88,7 +87,7 @@ const Divider = styled.div`
|
|||
`;
|
||||
|
||||
export const MessageOverlayBar = observer(({ message, queued }: Props) => {
|
||||
const client = useClient();
|
||||
const client = message.client;
|
||||
const { openScreen, writeClipboard } = useIntermediate();
|
||||
const isAuthor = message.author_id === client.user!._id;
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import classNames from "classnames";
|
|||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
import { MessageAreaWidthContext } from "../../../../pages/channels/messaging/MessageArea";
|
||||
import Markdown from "../../../markdown/Markdown";
|
||||
import Attachment from "../attachments/Attachment";
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Group } from "@styled-icons/boxicons-solid";
|
||||
import { reaction } from "mobx";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Message, API } from "revolt.js";
|
||||
|
@ -12,14 +11,13 @@ import { Button, Category, Preloader } from "@revoltchat/ui";
|
|||
import { isTouchscreenDevice } from "../../../../lib/isTouchscreenDevice";
|
||||
|
||||
import { I18nError } from "../../../../context/Locale";
|
||||
import {
|
||||
AppContext,
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../../../../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../../../../context/revoltjs/util";
|
||||
|
||||
import ServerIcon from "../../../../components/common/ServerIcon";
|
||||
import {
|
||||
useClient,
|
||||
useSession,
|
||||
} from "../../../../controllers/client/ClientController";
|
||||
|
||||
const EmbedInviteBase = styled.div`
|
||||
width: 400px;
|
||||
|
@ -78,8 +76,8 @@ type Props = {
|
|||
|
||||
export function EmbedInvite({ code }: Props) {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
const [joinError, setJoinError] = useState<string | undefined>(undefined);
|
||||
|
@ -90,7 +88,7 @@ export function EmbedInvite({ code }: Props) {
|
|||
useEffect(() => {
|
||||
if (
|
||||
typeof invite === "undefined" &&
|
||||
(status === ClientStatus.ONLINE || status === ClientStatus.READY)
|
||||
(session.state === "Online" || session.state === "Ready")
|
||||
) {
|
||||
client
|
||||
.fetchInvite(code)
|
||||
|
@ -99,7 +97,7 @@ export function EmbedInvite({ code }: Props) {
|
|||
)
|
||||
.catch((err) => setError(takeError(err)));
|
||||
}
|
||||
}, [client, code, invite, status]);
|
||||
}, [client, code, invite, session.state]);
|
||||
|
||||
if (typeof invite === "undefined") {
|
||||
return error ? (
|
||||
|
|
|
@ -4,7 +4,8 @@ import { API } from "revolt.js";
|
|||
import styles from "./Embed.module.scss";
|
||||
|
||||
import { useIntermediate } from "../../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
embed: API.Embed;
|
||||
|
|
|
@ -6,10 +6,9 @@ import styled, { css } from "styled-components/macro";
|
|||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import fallback from "../assets/user.png";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import IconBase, { IconBaseProps } from "../IconBase";
|
||||
|
||||
type VoiceStatus = "muted" | "deaf";
|
||||
|
@ -56,7 +55,7 @@ export default observer(
|
|||
keyof Props | "children" | "as"
|
||||
>,
|
||||
) => {
|
||||
const client = useApplicationState().client!;
|
||||
const client = useClient();
|
||||
|
||||
const {
|
||||
target,
|
||||
|
|
|
@ -9,8 +9,8 @@ import { Text } from "preact-i18n";
|
|||
import { internalEmit } from "../../../lib/eventEmitter";
|
||||
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import UserIcon from "./UserIcon";
|
||||
|
||||
const BotBadge = styled.div`
|
||||
|
|
|
@ -15,9 +15,9 @@ import { determineLink } from "../../lib/links";
|
|||
|
||||
import { dayjs } from "../../context/Locale";
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { emojiDictionary } from "../../assets/emojis";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { generateEmoji } from "../common/Emoji";
|
||||
import { MarkdownProps } from "./Markdown";
|
||||
import Prism from "./prism";
|
||||
|
@ -118,7 +118,7 @@ const RE_CHANNELS = /<#([A-z0-9]{26})>/g;
|
|||
const RE_TIME = /<t:([0-9]+):(\w)>/g;
|
||||
|
||||
export default function Renderer({ content, disallowBigEmoji }: MarkdownProps) {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { openLink } = useIntermediate();
|
||||
|
||||
if (typeof content === "undefined") return null;
|
||||
|
|
|
@ -9,8 +9,7 @@ import ConditionalLink from "../../lib/ConditionalLink";
|
|||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import UserIcon from "../common/user/UserIcon";
|
||||
|
||||
const Base = styled.div`
|
||||
|
|
|
@ -1,45 +1,43 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { Banner } from "@revoltchat/ui";
|
||||
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
|
||||
export default function ConnectionStatus() {
|
||||
const status = useContext(StatusContext);
|
||||
const client = useClient();
|
||||
function ConnectionStatus() {
|
||||
const session = useSession()!;
|
||||
|
||||
if (status === ClientStatus.OFFLINE) {
|
||||
if (session.state === "Offline") {
|
||||
return (
|
||||
<Banner>
|
||||
<Text id="app.special.status.offline" />
|
||||
</Banner>
|
||||
);
|
||||
} else if (status === ClientStatus.DISCONNECTED) {
|
||||
} else if (session.state === "Disconnected") {
|
||||
return (
|
||||
<Banner>
|
||||
<Text id="app.special.status.disconnected" /> <br />
|
||||
<a onClick={() => client.websocket.connect()}>
|
||||
<a
|
||||
onClick={() =>
|
||||
session.emit({
|
||||
action: "RETRY",
|
||||
})
|
||||
}>
|
||||
<Text id="app.special.status.reconnect" />
|
||||
</a>
|
||||
</Banner>
|
||||
);
|
||||
} else if (status === ClientStatus.CONNECTING) {
|
||||
return (
|
||||
<Banner>
|
||||
<Text id="app.special.status.connecting" />
|
||||
</Banner>
|
||||
);
|
||||
} else if (status === ClientStatus.RECONNECTING) {
|
||||
} else if (session.state === "Connecting") {
|
||||
return (
|
||||
<Banner>
|
||||
<Text id="app.special.status.reconnecting" />
|
||||
</Banner>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default observer(ConnectionStatus);
|
||||
|
|
|
@ -21,10 +21,10 @@ import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
|||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import placeholderSVG from "../items/placeholder.svg";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
|
||||
import ButtonItem, { ChannelButton } from "../items/ButtonItem";
|
||||
import ConnectionStatus from "../items/ConnectionStatus";
|
||||
|
@ -46,7 +46,7 @@ const Navbar = styled.div`
|
|||
|
||||
export default observer(() => {
|
||||
const { pathname } = useLocation();
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const state = useApplicationState();
|
||||
const { channel: channel_id } = useParams<{ channel: string }>();
|
||||
const { openScreen } = useIntermediate();
|
||||
|
|
|
@ -8,7 +8,8 @@ import { ServerList } from "@revoltchat/ui";
|
|||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
|
||||
/**
|
||||
* Server list sidebar shim component
|
||||
|
|
|
@ -14,8 +14,7 @@ import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
|||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import CollapsibleSection from "../../common/CollapsibleSection";
|
||||
import ServerHeader from "../../common/ServerHeader";
|
||||
import { ChannelButton } from "../items/ButtonItem";
|
||||
|
|
|
@ -4,14 +4,12 @@ import { observer } from "mobx-react-lite";
|
|||
import { useParams } from "react-router-dom";
|
||||
import { Channel, Server, User, API } from "revolt.js";
|
||||
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useSession,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
} from "../../../controllers/client/ClientController";
|
||||
import { GenericSidebarBase } from "../SidebarBase";
|
||||
import MemberList, { MemberListGroup } from "./MemberList";
|
||||
|
||||
|
@ -205,18 +203,18 @@ function shouldSkipOffline(id: string) {
|
|||
|
||||
export const ServerMemberSidebar = observer(
|
||||
({ channel }: { channel: Channel }) => {
|
||||
const client = useClient();
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
|
||||
useEffect(() => {
|
||||
const server_id = channel.server_id!;
|
||||
if (status === ClientStatus.ONLINE && !FETCHED.has(server_id)) {
|
||||
if (session.state === "Online" && !FETCHED.has(server_id)) {
|
||||
FETCHED.add(server_id);
|
||||
channel
|
||||
.server!.syncMembers(shouldSkipOffline(server_id))
|
||||
.catch(() => FETCHED.delete(server_id));
|
||||
}
|
||||
}, [status, channel]);
|
||||
}, [session.state, channel]);
|
||||
|
||||
const entries = useEntries(
|
||||
channel,
|
||||
|
|
|
@ -7,8 +7,7 @@ import { useEffect, useState } from "preact/hooks";
|
|||
|
||||
import { Button, Category, Error, InputBox, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import Message from "../../common/messaging/Message";
|
||||
import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
|
||||
|
||||
|
|
|
@ -2,19 +2,16 @@ import { Block } from "@styled-icons/boxicons-regular";
|
|||
import { Trash } from "@styled-icons/boxicons-solid";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { CategoryButton } from "@revoltchat/ui";
|
||||
|
||||
import {
|
||||
LogOutContext,
|
||||
clientController,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
} from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
export default function AccountManagement() {
|
||||
const logOut = useContext(LogOutContext);
|
||||
const client = useClient();
|
||||
|
||||
const callback = (route: "disable" | "delete") => () =>
|
||||
|
@ -27,7 +24,7 @@ export default function AccountManagement() {
|
|||
"X-MFA-Ticket": ticket.token,
|
||||
},
|
||||
})
|
||||
.then(() => logOut(true)),
|
||||
.then(clientController.logoutCurrent),
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Envelope, Key, Pencil } from "@styled-icons/boxicons-solid";
|
|||
import { observer } from "mobx-react-lite";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import {
|
||||
AccountDetail,
|
||||
|
@ -12,27 +12,22 @@ import {
|
|||
HiddenValue,
|
||||
} from "@revoltchat/ui";
|
||||
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
export default observer(() => {
|
||||
const client = useClient();
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
|
||||
const [email, setEmail] = useState("...");
|
||||
|
||||
useEffect(() => {
|
||||
if (email === "..." && status === ClientStatus.ONLINE) {
|
||||
if (email === "..." && session.state === "Online") {
|
||||
client.api
|
||||
.get("/auth/account/")
|
||||
.then((account) => setEmail(account.email));
|
||||
}
|
||||
}, [client, email, status]);
|
||||
}, [client, email, session.state]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -3,17 +3,13 @@ import { Lock } from "@styled-icons/boxicons-solid";
|
|||
import { API } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useCallback, useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useCallback, useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Category, CategoryButton, Error, Tip } from "@revoltchat/ui";
|
||||
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../../../context/revoltjs/util";
|
||||
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
/**
|
||||
|
@ -34,8 +30,8 @@ export function toConfig(token: string) {
|
|||
*/
|
||||
export default function MultiFactorAuthentication() {
|
||||
// Pull in prerequisites
|
||||
const client = useClient();
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
|
||||
// Keep track of MFA state
|
||||
const [mfa, setMFA] = useState<API.MultiFactorStatus>();
|
||||
|
@ -43,13 +39,13 @@ export default function MultiFactorAuthentication() {
|
|||
|
||||
// Fetch the current MFA status on account
|
||||
useEffect(() => {
|
||||
if (!mfa && status === ClientStatus.ONLINE) {
|
||||
client.api
|
||||
if (!mfa && session.state === "Online") {
|
||||
client!.api
|
||||
.get("/auth/mfa/")
|
||||
.then(setMFA)
|
||||
.catch((err) => setError(takeError(err)));
|
||||
}
|
||||
}, [client, mfa, status]);
|
||||
}, [mfa, client, session.state]);
|
||||
|
||||
// Action called when recovery code button is pressed
|
||||
const recoveryAction = useCallback(async () => {
|
||||
|
|
|
@ -6,8 +6,8 @@ import { useContext, useState } from "preact/hooks";
|
|||
|
||||
import { Category, InputBox, Modal } from "@revoltchat/ui";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { I18nError } from "../../Locale";
|
||||
import { AppContext } from "../../revoltjs/RevoltClient";
|
||||
import { takeError } from "../../revoltjs/util";
|
||||
|
||||
interface Props {
|
||||
|
@ -89,7 +89,7 @@ type SpecialProps = { onClose: () => void } & (
|
|||
|
||||
export function SpecialInputModal(props: SpecialProps) {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
|
||||
const { onClose } = props;
|
||||
switch (props.type) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import { ulid } from "ulid";
|
|||
|
||||
import styles from "./Prompt.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Category, Modal, InputBox, Radio } from "@revoltchat/ui";
|
||||
import type { Action } from "@revoltchat/ui/esm/components/design/atoms/display/Modal";
|
||||
|
@ -14,8 +14,8 @@ import { TextReact } from "../../../lib/i18n";
|
|||
|
||||
import Message from "../../../components/common/messaging/Message";
|
||||
import UserIcon from "../../../components/common/user/UserIcon";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { I18nError } from "../../Locale";
|
||||
import { AppContext } from "../../revoltjs/RevoltClient";
|
||||
import { takeError } from "../../revoltjs/util";
|
||||
import { useIntermediate } from "../Intermediate";
|
||||
|
||||
|
@ -81,7 +81,7 @@ type SpecialProps = { onClose: () => void } & (
|
|||
);
|
||||
|
||||
export const SpecialPromptModal = observer((props: SpecialProps) => {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const history = useHistory();
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [error, setError] = useState<undefined | string>(undefined);
|
||||
|
|
|
@ -2,13 +2,13 @@ import { SubmitHandler, useForm } from "react-hook-form";
|
|||
import { API } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
import { useState } from "preact/hooks";
|
||||
|
||||
import { Category, Modal } from "@revoltchat/ui";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import FormField from "../../../pages/login/FormField";
|
||||
import { I18nError } from "../../Locale";
|
||||
import { AppContext } from "../../revoltjs/RevoltClient";
|
||||
import { takeError } from "../../revoltjs/util";
|
||||
|
||||
interface Props {
|
||||
|
@ -21,7 +21,7 @@ interface FormInputs {
|
|||
}
|
||||
|
||||
export function CreateBotModal({ onClose, onCreate }: Props) {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { handleSubmit, register, errors } = useForm<FormInputs>();
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Modal } from "@revoltchat/ui";
|
|||
|
||||
import AttachmentActions from "../../../components/common/messaging/attachments/AttachmentActions";
|
||||
import EmbedMediaActions from "../../../components/common/messaging/embed/EmbedMediaActions";
|
||||
import { useClient } from "../../revoltjs/RevoltClient";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
|
|
|
@ -5,7 +5,7 @@ import { useState } from "preact/hooks";
|
|||
import { Modal } from "@revoltchat/ui";
|
||||
|
||||
import UserCheckbox from "../../../components/common/user/UserCheckbox";
|
||||
import { useClient } from "../../revoltjs/RevoltClient";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
omit?: string[];
|
||||
|
|
|
@ -34,11 +34,7 @@ import UserIcon from "../../../components/common/user/UserIcon";
|
|||
import { Username } from "../../../components/common/user/UserShort";
|
||||
import UserStatus from "../../../components/common/user/UserStatus";
|
||||
import Markdown from "../../../components/markdown/Markdown";
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../revoltjs/RevoltClient";
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
import { useIntermediate } from "../Intermediate";
|
||||
|
||||
interface Props {
|
||||
|
@ -63,8 +59,8 @@ export const UserProfile = observer(
|
|||
>();
|
||||
|
||||
const history = useHistory();
|
||||
const client = useClient();
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
const [tab, setTab] = useState("profile");
|
||||
|
||||
const user = client.users.get(user_id);
|
||||
|
@ -101,32 +97,26 @@ export const UserProfile = observer(
|
|||
|
||||
useEffect(() => {
|
||||
if (dummy) return;
|
||||
if (
|
||||
status === ClientStatus.ONLINE &&
|
||||
typeof mutual === "undefined"
|
||||
) {
|
||||
if (session.state === "Online" && typeof mutual === "undefined") {
|
||||
setMutual(null);
|
||||
user.fetchMutual().then(setMutual);
|
||||
}
|
||||
}, [mutual, status, dummy, user]);
|
||||
}, [mutual, session.state, dummy, user]);
|
||||
|
||||
useEffect(() => {
|
||||
if (dummy) return;
|
||||
if (
|
||||
status === ClientStatus.ONLINE &&
|
||||
typeof profile === "undefined"
|
||||
) {
|
||||
if (session.state === "Online" && typeof profile === "undefined") {
|
||||
setProfile(null);
|
||||
|
||||
if (user.permission & UserPermission.ViewProfile) {
|
||||
user.fetchProfile().then(setProfile).catch(noop);
|
||||
}
|
||||
}
|
||||
}, [profile, status, dummy, user]);
|
||||
}, [profile, session.state, dummy, user]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
status === ClientStatus.ONLINE &&
|
||||
session.state === "Online" &&
|
||||
user.bot &&
|
||||
typeof isPublicBot === "undefined"
|
||||
) {
|
||||
|
@ -136,7 +126,7 @@ export const UserProfile = observer(
|
|||
.then(() => setIsPublicBot(true))
|
||||
.catch(noop);
|
||||
}
|
||||
}, [isPublicBot, status, user, client.bots]);
|
||||
}, [isPublicBot, session.state, user, client.bots]);
|
||||
|
||||
const backgroundURL =
|
||||
profile &&
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { Redirect } from "react-router-dom";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useClient } from "./RevoltClient";
|
||||
import { useSession } from "../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
auth?: boolean;
|
||||
|
@ -12,14 +10,12 @@ interface Props {
|
|||
}
|
||||
|
||||
export const CheckAuth = (props: Props) => {
|
||||
const auth = useApplicationState().auth;
|
||||
const client = useClient();
|
||||
const ready = auth.isLoggedIn() && !!client?.user;
|
||||
const session = useSession();
|
||||
|
||||
if (props.auth && !ready) {
|
||||
if (props.auth && !session?.ready) {
|
||||
if (props.blockRender) return null;
|
||||
return <Redirect to="/login" />;
|
||||
} else if (!props.auth && ready) {
|
||||
} else if (!props.auth && session?.ready) {
|
||||
if (props.blockRender) return null;
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
|
|
|
@ -5,17 +5,15 @@ import Axios, { AxiosRequestConfig } from "axios";
|
|||
import styles from "./FileUploads.module.scss";
|
||||
import classNames from "classnames";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { IconButton, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { determineFileSize } from "../../lib/fileSize";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import { useIntermediate } from "../intermediate/Intermediate";
|
||||
import { AppContext } from "./RevoltClient";
|
||||
import { takeError } from "./util";
|
||||
|
||||
type BehaviourType =
|
||||
|
@ -115,7 +113,7 @@ export function grabFiles(
|
|||
export function FileUploader(props: Props) {
|
||||
const { fileType, maxFileSize, remove } = props;
|
||||
const { openScreen } = useIntermediate();
|
||||
const client = useApplicationState().client!;
|
||||
const client = useClient();
|
||||
|
||||
const [uploading, setUploading] = useState(false);
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ import { Route, Switch, useHistory, useParams } from "react-router-dom";
|
|||
import { Message, User } from "revolt.js";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
import { useCallback, useContext, useEffect } from "preact/hooks";
|
||||
import { useCallback, useEffect } from "preact/hooks";
|
||||
|
||||
import { useTranslation } from "../../lib/i18n";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { AppContext } from "./RevoltClient";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
|
||||
const notifications: { [key: string]: Notification } = {};
|
||||
|
||||
|
@ -30,7 +30,7 @@ function Notifier() {
|
|||
const notifs = state.notifications;
|
||||
const showNotification = state.settings.get("notifications:desktop");
|
||||
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const { guild: guild_id, channel: channel_id } = useParams<{
|
||||
guild: string;
|
||||
channel: string;
|
||||
|
|
|
@ -2,11 +2,10 @@ import { WifiOff } from "@styled-icons/boxicons-regular";
|
|||
import styled from "styled-components/macro";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { ClientStatus, StatusContext } from "./RevoltClient";
|
||||
import { useSession } from "../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
children: Children;
|
||||
|
@ -29,10 +28,12 @@ const Base = styled.div`
|
|||
`;
|
||||
|
||||
export default function RequiresOnline(props: Props) {
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession();
|
||||
|
||||
if (status === ClientStatus.CONNECTING) return <Preloader type="ring" />;
|
||||
if (status !== ClientStatus.ONLINE && status !== ClientStatus.READY)
|
||||
if (!session || session.state === "Connecting")
|
||||
return <Preloader type="ring" />;
|
||||
|
||||
if (!(session.state === "Online" || session.state === "Ready"))
|
||||
return (
|
||||
<Base>
|
||||
<WifiOff size={16} />
|
||||
|
|
|
@ -1,113 +1,27 @@
|
|||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Client } from "revolt.js";
|
||||
|
||||
import { createContext } from "preact";
|
||||
import { useCallback, useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect } from "preact/hooks";
|
||||
|
||||
import { Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { clientController } from "../../controllers/client/ClientController";
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import { registerEvents } from "./events";
|
||||
import { takeError } from "./util";
|
||||
|
||||
export enum ClientStatus {
|
||||
READY,
|
||||
LOADING,
|
||||
OFFLINE,
|
||||
DISCONNECTED,
|
||||
CONNECTING,
|
||||
RECONNECTING,
|
||||
ONLINE,
|
||||
}
|
||||
|
||||
export interface ClientOperations {
|
||||
logout: (shouldRequest?: boolean) => Promise<void>;
|
||||
}
|
||||
|
||||
export const AppContext = createContext<Client>(null!);
|
||||
export const StatusContext = createContext<ClientStatus>(null!);
|
||||
export const LogOutContext = createContext<(avoidReq?: boolean) => void>(null!);
|
||||
|
||||
type Props = {
|
||||
children: Children;
|
||||
};
|
||||
|
||||
export default observer(({ children }: Props) => {
|
||||
// const state = useApplicationState();
|
||||
/*const [client, setClient] = useState<Client>(null!);
|
||||
const [status, setStatus] = useState(ClientStatus.LOADING);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
|
||||
const logout = useCallback(
|
||||
(avoidReq?: boolean) => {
|
||||
setLoaded(false);
|
||||
client.logout(avoidReq);
|
||||
},
|
||||
[client],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (navigator.onLine) {
|
||||
state.config.createClient().api.get("/").then(state.config.set);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.auth.isLoggedIn()) {
|
||||
setLoaded(false);
|
||||
const client = state.config.createClient();
|
||||
setClient(client);
|
||||
|
||||
client
|
||||
.useExistingSession(state.auth.getSession()!)
|
||||
.catch((err) => {
|
||||
const error = takeError(err);
|
||||
if (error === "Forbidden" || error === "Unauthorized") {
|
||||
client.logout(true);
|
||||
modalController.push({ type: "signed_out" });
|
||||
} else {
|
||||
setStatus(ClientStatus.DISCONNECTED);
|
||||
modalController.push({
|
||||
type: "error",
|
||||
error,
|
||||
});
|
||||
}
|
||||
})
|
||||
.finally(() => setLoaded(true));
|
||||
} else {
|
||||
setStatus(ClientStatus.READY);
|
||||
setLoaded(true);
|
||||
}
|
||||
}, [state.auth.getSession()]);
|
||||
|
||||
useEffect(() => registerEvents(state, setStatus, client), [client]);
|
||||
|
||||
if (!loaded || status === ClientStatus.LOADING) {
|
||||
return <Preloader type="spinner" />;
|
||||
}*/
|
||||
|
||||
const session = clientController.getActiveSession();
|
||||
if (!session?.ready) {
|
||||
return <Preloader type="spinner" />;
|
||||
if (session) {
|
||||
if (!session.ready) return <Preloader type="spinner" />;
|
||||
|
||||
const client = session.client!;
|
||||
const state = useApplicationState();
|
||||
useEffect(() => state.registerListeners(client), [state, client]);
|
||||
}
|
||||
|
||||
const client = session.client!;
|
||||
const state = useApplicationState();
|
||||
useEffect(() => state.registerListeners(client), [state, client]);
|
||||
|
||||
return (
|
||||
<AppContext.Provider value={session.client!}>
|
||||
<StatusContext.Provider value={ClientStatus.ONLINE}>
|
||||
<LogOutContext.Provider value={() => void {}}>
|
||||
{children}
|
||||
</LogOutContext.Provider>
|
||||
</StatusContext.Provider>
|
||||
</AppContext.Provider>
|
||||
);
|
||||
return <>{children}</>;
|
||||
});
|
||||
|
||||
export const useClient = () => useContext(AppContext);
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/**
|
||||
* This file monitors the message cache to delete any queued messages that have already sent.
|
||||
*/
|
||||
import { Message } from "revolt.js";
|
||||
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { setGlobalEmojiPack } from "../../components/common/Emoji";
|
||||
|
||||
import { AppContext } from "./RevoltClient";
|
||||
|
||||
export default function StateMonitor() {
|
||||
const client = useContext(AppContext);
|
||||
const state = useApplicationState();
|
||||
|
||||
useEffect(() => {
|
||||
function add(msg: Message) {
|
||||
if (!msg.nonce) return;
|
||||
if (
|
||||
!state.queue.get(msg.channel_id).find((x) => x.id === msg.nonce)
|
||||
)
|
||||
return;
|
||||
state.queue.remove(msg.nonce);
|
||||
}
|
||||
|
||||
client.addListener("message", add);
|
||||
return () => client.removeListener("message", add);
|
||||
}, [client]);
|
||||
|
||||
// Set global emoji pack.
|
||||
useEffect(() => {
|
||||
const v = state.settings.get("appearance:emoji");
|
||||
v && setGlobalEmojiPack(v);
|
||||
}, [state.settings.get("appearance:emoji")]);
|
||||
|
||||
return null;
|
||||
}
|
|
@ -9,7 +9,7 @@ import { reportError } from "../../lib/ErrorBoundary";
|
|||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useClient } from "./RevoltClient";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
|
||||
export default function SyncManager() {
|
||||
const client = useClient();
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
import { Client, Server } from "revolt.js";
|
||||
export const _ = "";
|
||||
|
||||
import { StateUpdater } from "preact/hooks";
|
||||
|
||||
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(
|
||||
/*export function registerEvents(
|
||||
state: State,
|
||||
setStatus: StateUpdater<ClientStatus>,
|
||||
client: Client,
|
||||
|
@ -86,4 +77,4 @@ export function registerEvents(
|
|||
window.removeEventListener("online", online);
|
||||
window.removeEventListener("offline", offline);
|
||||
};
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
import type { Nullable } from "revolt.js";
|
||||
import { Client, Nullable } from "revolt.js";
|
||||
|
||||
import Auth from "../../mobx/stores/Auth";
|
||||
|
||||
import { modalController } from "../modals/ModalController";
|
||||
import Session from "./Session";
|
||||
|
||||
class ClientController {
|
||||
/**
|
||||
* API client
|
||||
*/
|
||||
private apiClient: Client;
|
||||
|
||||
/**
|
||||
* Map of user IDs to sessions
|
||||
*/
|
||||
|
@ -17,10 +23,19 @@ class ClientController {
|
|||
private current: Nullable<string>;
|
||||
|
||||
constructor() {
|
||||
this.apiClient = new Client({
|
||||
apiURL: import.meta.env.VITE_API_URL,
|
||||
});
|
||||
|
||||
this.sessions = new ObservableMap();
|
||||
this.current = null;
|
||||
|
||||
makeAutoObservable(this);
|
||||
|
||||
this.logoutCurrent = this.logoutCurrent.bind(this);
|
||||
|
||||
// Inject globally
|
||||
(window as any).clientController = this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,12 +44,23 @@ class ClientController {
|
|||
*/
|
||||
@action hydrate(auth: Auth) {
|
||||
for (const entry of auth.getAccounts()) {
|
||||
const user_id = entry.session.user_id!;
|
||||
|
||||
const session = new Session();
|
||||
this.sessions.set(entry.session._id!, session);
|
||||
session.emit({
|
||||
action: "LOGIN",
|
||||
session: entry.session,
|
||||
});
|
||||
this.sessions.set(user_id, session);
|
||||
|
||||
session
|
||||
.emit({
|
||||
action: "LOGIN",
|
||||
session: entry.session,
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error === "Forbidden" || error === "Unauthorized") {
|
||||
this.sessions.delete(user_id);
|
||||
auth.removeSession(user_id);
|
||||
modalController.push({ type: "signed_out" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.current = this.sessions.keys().next().value ?? null;
|
||||
|
@ -44,6 +70,14 @@ class ClientController {
|
|||
return this.sessions.get(this.current!);
|
||||
}
|
||||
|
||||
@computed getAnonymousClient() {
|
||||
return this.apiClient;
|
||||
}
|
||||
|
||||
@computed getAvailableClient() {
|
||||
return this.getActiveSession()?.client ?? this.apiClient;
|
||||
}
|
||||
|
||||
@computed isLoggedIn() {
|
||||
return this.current === null;
|
||||
}
|
||||
|
@ -59,6 +93,41 @@ class ClientController {
|
|||
session.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@action logoutCurrent() {
|
||||
if (this.current) {
|
||||
this.logout(this.current);
|
||||
}
|
||||
}
|
||||
|
||||
@action switchAccount(user_id: string) {
|
||||
this.current = user_id;
|
||||
}
|
||||
}
|
||||
|
||||
export const clientController = new ClientController();
|
||||
|
||||
/**
|
||||
* Get the currently active session.
|
||||
* @returns Session
|
||||
*/
|
||||
export function useSession() {
|
||||
return clientController.getActiveSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently active client or an unauthorised
|
||||
* client for API requests, whichever is available.
|
||||
* @returns Revolt.js Client
|
||||
*/
|
||||
export function useClient() {
|
||||
return clientController.getAvailableClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unauthorised client for API requests.
|
||||
* @returns Revolt.js Client
|
||||
*/
|
||||
export function useApi() {
|
||||
return clientController.getAnonymousClient().api;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ type Transition =
|
|||
|
||||
export default class Session {
|
||||
state: State = window.navigator.onLine ? "Ready" : "Offline";
|
||||
user_id: string | null = null;
|
||||
client: Client | null = null;
|
||||
|
||||
constructor() {
|
||||
|
@ -83,6 +84,7 @@ export default class Session {
|
|||
|
||||
private destroyClient() {
|
||||
this.client!.removeAllListeners();
|
||||
this.user_id = null;
|
||||
this.client = null;
|
||||
}
|
||||
|
||||
|
@ -101,7 +103,7 @@ export default class Session {
|
|||
}
|
||||
|
||||
@action async emit(data: Transition) {
|
||||
console.info("Handle event:", data);
|
||||
console.info(`[FSM ${this.user_id ?? "Anonymous"}]`, data);
|
||||
|
||||
switch (data.action) {
|
||||
// Login with session
|
||||
|
@ -112,6 +114,7 @@ export default class Session {
|
|||
|
||||
try {
|
||||
await this.client!.useExistingSession(data.session);
|
||||
this.user_id = this.client!.user!._id;
|
||||
} catch (err) {
|
||||
this.state = "Ready";
|
||||
throw err;
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
import { SubmitHandler, useForm } from "react-hook-form";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
import { useState } from "preact/hooks";
|
||||
|
||||
import { Category, Error, Modal } from "@revoltchat/ui";
|
||||
|
||||
import { noopTrue } from "../../../lib/js";
|
||||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../../../context/revoltjs/util";
|
||||
|
||||
import FormField from "../../../pages/login/FormField";
|
||||
import { useClient } from "../../client/ClientController";
|
||||
import { ModalProps } from "../types";
|
||||
|
||||
interface FormInputs {
|
||||
|
@ -30,7 +28,7 @@ export default function ModifyAccount({
|
|||
field,
|
||||
...props
|
||||
}: ModalProps<"modify_account">) {
|
||||
const client = useApplicationState().client!;
|
||||
const client = useClient();
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const { handleSubmit, register, errors } = useForm<FormInputs>();
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
openContextMenu,
|
||||
} from "preact-context-menu";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { IconButton, LineDivider } from "@revoltchat/ui";
|
||||
|
||||
|
@ -28,16 +27,12 @@ import { QueuedMessage } from "../mobx/stores/MessageQueue";
|
|||
import { NotificationState } from "../mobx/stores/NotificationOptions";
|
||||
|
||||
import { Screen, useIntermediate } from "../context/intermediate/Intermediate";
|
||||
import {
|
||||
AppContext,
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../context/revoltjs/util";
|
||||
import CMNotifications from "./contextmenu/CMNotifications";
|
||||
|
||||
import Tooltip from "../components/common/Tooltip";
|
||||
import UserStatus from "../components/common/user/UserStatus";
|
||||
import { useSession } from "../controllers/client/ClientController";
|
||||
import { modalController } from "../controllers/modals/ModalController";
|
||||
import { internalEmit } from "./eventEmitter";
|
||||
import { getRenderer } from "./renderer/Singleton";
|
||||
|
@ -122,12 +117,12 @@ type Action =
|
|||
// Tip: This should just be split into separate context menus per logical area.
|
||||
export default function ContextMenus() {
|
||||
const { openScreen, writeClipboard } = useIntermediate();
|
||||
const client = useContext(AppContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
const userId = client.user!._id;
|
||||
const status = useContext(StatusContext);
|
||||
const isOnline = status === ClientStatus.ONLINE;
|
||||
const state = useApplicationState();
|
||||
const history = useHistory();
|
||||
const isOnline = session.state === "Online";
|
||||
|
||||
function contextClick(data?: Action) {
|
||||
if (typeof data === "undefined") return;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
|
||||
import { useMemo } from "preact/hooks";
|
||||
|
||||
import { useApplicationState } from "../mobx/State";
|
||||
|
||||
import { AppContext } from "../context/revoltjs/RevoltClient";
|
||||
|
||||
export default observer(({ children }: { children: Children }) => {
|
||||
const config = useApplicationState().config;
|
||||
const client = useMemo(() => config.createClient(), [config.get()]);
|
||||
return <AppContext.Provider value={client}>{children}</AppContext.Provider>;
|
||||
});
|
|
@ -140,6 +140,9 @@ export default class State {
|
|||
if (client) {
|
||||
this.client = client;
|
||||
this.plugins.onClient(client);
|
||||
|
||||
// Register message listener for clearing queue.
|
||||
this.client.addListener("message", this.queue.onMessage);
|
||||
}
|
||||
|
||||
// Register all the listeners required for saving and syncing state.
|
||||
|
@ -225,6 +228,11 @@ export default class State {
|
|||
});
|
||||
|
||||
return () => {
|
||||
// Remove any listeners attached to client.
|
||||
if (client) {
|
||||
client.removeListener("message", this.queue.onMessage);
|
||||
}
|
||||
|
||||
// Stop exposing the client.
|
||||
this.client = undefined;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
makeAutoObservable,
|
||||
observable,
|
||||
} from "mobx";
|
||||
import { Message } from "revolt.js";
|
||||
|
||||
import Store from "../interfaces/Store";
|
||||
|
||||
|
@ -47,6 +48,8 @@ export default class MessageQueue implements Store {
|
|||
constructor() {
|
||||
this.messages = observable.array([]);
|
||||
makeAutoObservable(this);
|
||||
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
}
|
||||
|
||||
get id() {
|
||||
|
@ -105,4 +108,16 @@ export default class MessageQueue implements Store {
|
|||
@computed get(channel: string) {
|
||||
return this.messages.filter((x) => x.channel === channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming Message
|
||||
* @param message Message
|
||||
*/
|
||||
@action onMessage(message: Message) {
|
||||
if (!message.nonce) return;
|
||||
if (!this.get(message.channel_id).find((x) => x.id === message.nonce))
|
||||
return;
|
||||
|
||||
this.remove(message.nonce);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ import { mapToRecord } from "../../lib/conversion";
|
|||
|
||||
import { Fonts, MonospaceFonts, Overrides } from "../../context/Theme";
|
||||
|
||||
import { EmojiPack } from "../../components/common/Emoji";
|
||||
import { MIGRATIONS } from "../State";
|
||||
import { EmojiPack, setGlobalEmojiPack } from "../../components/common/Emoji";
|
||||
import Persistent from "../interfaces/Persistent";
|
||||
import Store from "../interfaces/Store";
|
||||
import Syncable from "../interfaces/Syncable";
|
||||
|
@ -79,6 +78,11 @@ export default class Settings
|
|||
* @param value Value
|
||||
*/
|
||||
@action set<T extends keyof ISettings>(key: T, value: ISettings[T]) {
|
||||
// Emoji needs to be immediately applied.
|
||||
if (key === 'appearance:emoji') {
|
||||
setGlobalEmojiPack(value as EmojiPack);
|
||||
}
|
||||
|
||||
this.data.set(key, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,25 +2,20 @@
|
|||
import { useHistory, useParams } from "react-router-dom";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect } from "preact/hooks";
|
||||
import { useEffect } from "preact/hooks";
|
||||
|
||||
import { Header } from "@revoltchat/ui";
|
||||
|
||||
import {
|
||||
AppContext,
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useSession } from "../controllers/client/ClientController";
|
||||
import { modalController } from "../controllers/modals/ModalController";
|
||||
|
||||
export default function Open() {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
if (status !== ClientStatus.ONLINE) {
|
||||
if (session.state !== "Online") {
|
||||
return (
|
||||
<Header palette="primary">
|
||||
<Text id="general.loading" />
|
||||
|
|
|
@ -9,7 +9,6 @@ import { isTouchscreenDevice } from "../lib/isTouchscreenDevice";
|
|||
|
||||
import Popovers from "../context/intermediate/Popovers";
|
||||
import Notifications from "../context/revoltjs/Notifications";
|
||||
import StateMonitor from "../context/revoltjs/StateMonitor";
|
||||
|
||||
import { Titlebar } from "../components/native/Titlebar";
|
||||
import BottomNavigation from "../components/navigation/BottomNavigation";
|
||||
|
@ -235,7 +234,6 @@ export default function App() {
|
|||
<ContextMenus />
|
||||
<Popovers />
|
||||
<Notifications />
|
||||
<StateMonitor />
|
||||
</OverlappingPanels>
|
||||
</AppContainer>
|
||||
</>
|
||||
|
|
|
@ -5,7 +5,6 @@ import { lazy, Suspense } from "preact/compat";
|
|||
import { Masks, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import ErrorBoundary from "../lib/ErrorBoundary";
|
||||
import FakeClient from "../lib/FakeClient";
|
||||
|
||||
import Context from "../context";
|
||||
import { CheckAuth } from "../context/revoltjs/CheckAuth";
|
||||
|
@ -36,9 +35,7 @@ export function App() {
|
|||
</Route>
|
||||
<Route path="/invite/:code">
|
||||
<CheckAuth blockRender>
|
||||
<FakeClient>
|
||||
<Invite />
|
||||
</FakeClient>
|
||||
<Invite />
|
||||
</CheckAuth>
|
||||
<CheckAuth auth blockRender>
|
||||
<Invite />
|
||||
|
|
|
@ -16,8 +16,6 @@ import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
|||
import { useApplicationState } from "../../mobx/State";
|
||||
import { SIDEBAR_MEMBERS } from "../../mobx/stores/Layout";
|
||||
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import AgeGate from "../../components/common/AgeGate";
|
||||
import MessageBox from "../../components/common/messaging/MessageBox";
|
||||
import JumpToBottom from "../../components/common/messaging/bars/JumpToBottom";
|
||||
|
@ -25,6 +23,7 @@ import NewMessages from "../../components/common/messaging/bars/NewMessages";
|
|||
import TypingIndicator from "../../components/common/messaging/bars/TypingIndicator";
|
||||
import RightSidebar from "../../components/navigation/RightSidebar";
|
||||
import { PageHeader } from "../../components/ui/Header";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import ChannelHeader from "./ChannelHeader";
|
||||
import { MessageArea } from "./messaging/MessageArea";
|
||||
import VoiceHeader from "./voice/VoiceHeader";
|
||||
|
|
|
@ -25,11 +25,8 @@ import { ScrollState } from "../../../lib/renderer/types";
|
|||
|
||||
import { IntermediateContext } from "../../../context/intermediate/Intermediate";
|
||||
import RequiresOnline from "../../../context/revoltjs/RequiresOnline";
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
import ConversationStart from "./ConversationStart";
|
||||
import MessageRenderer from "./MessageRenderer";
|
||||
|
||||
|
@ -65,7 +62,7 @@ export const MESSAGE_AREA_PADDING = 82;
|
|||
|
||||
export const MessageArea = observer(({ last_id, channel }: Props) => {
|
||||
const history = useHistory();
|
||||
const status = useContext(StatusContext);
|
||||
const session = useSession()!;
|
||||
const { focusTaken } = useContext(IntermediateContext);
|
||||
|
||||
// ? Required data for message links.
|
||||
|
@ -213,8 +210,8 @@ export const MessageArea = observer(({ last_id, channel }: Props) => {
|
|||
|
||||
// ? If we are waiting for network, try again.
|
||||
useEffect(() => {
|
||||
switch (status) {
|
||||
case ClientStatus.ONLINE:
|
||||
switch (session.state) {
|
||||
case "Online":
|
||||
if (renderer.state === "WAITING_FOR_NETWORK") {
|
||||
renderer.init();
|
||||
} else {
|
||||
|
@ -222,13 +219,13 @@ export const MessageArea = observer(({ last_id, channel }: Props) => {
|
|||
}
|
||||
|
||||
break;
|
||||
case ClientStatus.OFFLINE:
|
||||
case ClientStatus.DISCONNECTED:
|
||||
case ClientStatus.CONNECTING:
|
||||
case "Offline":
|
||||
case "Disconnected":
|
||||
case "Connecting":
|
||||
renderer.markStale();
|
||||
break;
|
||||
}
|
||||
}, [renderer, status]);
|
||||
}, [renderer, session.state]);
|
||||
|
||||
// ? When the container is scrolled.
|
||||
// ? Also handle StayAtBottom
|
||||
|
|
|
@ -3,9 +3,7 @@ import { X } from "@styled-icons/boxicons-regular";
|
|||
import dayjs from "dayjs";
|
||||
import isEqual from "lodash.isequal";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { API } from "revolt.js";
|
||||
import { Message as MessageI } from "revolt.js";
|
||||
import { Nullable } from "revolt.js";
|
||||
import { API, Message as MessageI, Nullable } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
import { decodeTime } from "ulid";
|
||||
|
||||
|
@ -20,10 +18,10 @@ import { ChannelRenderer } from "../../../lib/renderer/Singleton";
|
|||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import RequiresOnline from "../../../context/revoltjs/RequiresOnline";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import Message from "../../../components/common/messaging/Message";
|
||||
import { SystemMessage } from "../../../components/common/messaging/SystemMessage";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import ConversationStart from "./ConversationStart";
|
||||
import MessageEditor from "./MessageEditor";
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ import { Button } from "@revoltchat/ui";
|
|||
import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState";
|
||||
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import Tooltip from "../../../components/common/Tooltip";
|
||||
import UserIcon from "../../../components/common/user/UserIcon";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import { Wrench } from "@styled-icons/boxicons-solid";
|
||||
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import PaintCounter from "../../lib/PaintCounter";
|
||||
import { TextReact } from "../../lib/i18n";
|
||||
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { PageHeader } from "../../components/ui/Header";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
|
||||
export default function Developer() {
|
||||
// const voice = useContext(VoiceContext);
|
||||
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const userPermission = client.user!.permission;
|
||||
const [ping, setPing] = useState<undefined | number>(client.websocket.ping);
|
||||
const [crash, setCrash] = useState(false);
|
||||
|
|
|
@ -13,12 +13,12 @@ import { TextReact } from "../../lib/i18n";
|
|||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import CollapsibleSection from "../../components/common/CollapsibleSection";
|
||||
import Tooltip from "../../components/common/Tooltip";
|
||||
import UserIcon from "../../components/common/user/UserIcon";
|
||||
import { PageHeader } from "../../components/ui/Header";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import { Friend } from "./Friend";
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import styled from "styled-components/macro";
|
|||
import styles from "./Home.module.scss";
|
||||
import "./snow.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useMemo } from "preact/hooks";
|
||||
import { useMemo } from "preact/hooks";
|
||||
|
||||
import { CategoryButton } from "@revoltchat/ui";
|
||||
|
||||
|
@ -24,11 +24,11 @@ import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
|||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import wideSVG from "/assets/wide.svg";
|
||||
|
||||
import { PageHeader } from "../../components/ui/Header";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
|
||||
const Overlay = styled.div`
|
||||
display: grid;
|
||||
|
@ -45,7 +45,7 @@ const Overlay = styled.div`
|
|||
|
||||
export default observer(() => {
|
||||
const { openScreen } = useIntermediate();
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const state = useApplicationState();
|
||||
|
||||
const seasonalTheme = state.settings.get("appearance:seasonal", true);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { ArrowBack } from "@styled-icons/boxicons-regular";
|
||||
import { autorun } from "mobx";
|
||||
import { Redirect, useHistory, useParams } from "react-router-dom";
|
||||
import { API } from "revolt.js";
|
||||
|
||||
import styles from "./Invite.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Button, Category, Error, Preloader } from "@revoltchat/ui";
|
||||
|
||||
|
@ -14,23 +13,22 @@ import { TextReact } from "../../lib/i18n";
|
|||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import RequiresOnline from "../../context/revoltjs/RequiresOnline";
|
||||
import {
|
||||
AppContext,
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
} from "../../context/revoltjs/RevoltClient";
|
||||
import { takeError } from "../../context/revoltjs/util";
|
||||
|
||||
import ServerIcon from "../../components/common/ServerIcon";
|
||||
import UserIcon from "../../components/common/user/UserIcon";
|
||||
import {
|
||||
useClient,
|
||||
useSession,
|
||||
} from "../../controllers/client/ClientController";
|
||||
|
||||
export default function Invite() {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const session = useSession();
|
||||
const client = useClient();
|
||||
|
||||
const layout = useApplicationState().layout;
|
||||
|
||||
const status = useContext(StatusContext);
|
||||
const { code } = useParams<{ code: string }>();
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [error, setError] = useState<string | undefined>(undefined);
|
||||
|
@ -45,7 +43,7 @@ export default function Invite() {
|
|||
.then((data) => setInvite(data))
|
||||
.catch((err) => setError(takeError(err)));
|
||||
}
|
||||
}, [client, code, invite, status]);
|
||||
}, [code, invite]);
|
||||
|
||||
if (code === undefined) return <Redirect to={layout.getLastPath()} />;
|
||||
|
||||
|
@ -154,7 +152,7 @@ export default function Invite() {
|
|||
<Button
|
||||
palette="secondary"
|
||||
onClick={async () => {
|
||||
if (status === ClientStatus.READY) {
|
||||
if (!session) {
|
||||
return history.push("/");
|
||||
}
|
||||
|
||||
|
@ -172,7 +170,7 @@ export default function Invite() {
|
|||
setProcessing(false);
|
||||
}
|
||||
}}>
|
||||
{status === ClientStatus.READY ? (
|
||||
{!session ? (
|
||||
<Text id="app.special.invite.login" />
|
||||
) : (
|
||||
<Text id="app.special.invite.accept" />
|
||||
|
|
|
@ -6,10 +6,9 @@ import { useEffect, useState } from "preact/hooks";
|
|||
|
||||
import { Button, Category, ComboBox, Preloader, Tip } from "@revoltchat/ui";
|
||||
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import UserIcon from "../../components/common/user/UserIcon";
|
||||
import Markdown from "../../components/markdown/Markdown";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
|
||||
const BotInfo = styled.div`
|
||||
gap: 12px;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { useEffect, useState } from "preact/hooks";
|
|||
|
||||
import { Modal, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
import { useApi } from "../../controllers/client/ClientController";
|
||||
|
||||
const Centre = styled.div`
|
||||
display: flex;
|
||||
|
@ -14,15 +14,12 @@ const Centre = styled.div`
|
|||
`;
|
||||
|
||||
export default function ConfirmDelete() {
|
||||
const state = useApplicationState();
|
||||
const api = useApi();
|
||||
const [deleted, setDeleted] = useState(true);
|
||||
const { token } = useParams<{ token: string }>();
|
||||
|
||||
useEffect(() => {
|
||||
state.config
|
||||
.createClient()
|
||||
.api.put("/auth/account/delete", { token })
|
||||
.then(() => setDeleted(true));
|
||||
api.put("/auth/account/delete", { token }).then(() => setDeleted(true));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
import { useHistory, useParams } from "react-router-dom";
|
||||
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useApi } from "../../../controllers/client/ClientController";
|
||||
import { Form } from "./Form";
|
||||
|
||||
export function FormSendReset() {
|
||||
const config = useApplicationState().config;
|
||||
const client = config.createClient();
|
||||
const api = useApi();
|
||||
|
||||
return (
|
||||
<Form
|
||||
page="send_reset"
|
||||
callback={async (data) => {
|
||||
await client.api.post("/auth/account/reset_password", data);
|
||||
await api.post("/auth/account/reset_password", data);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -24,15 +18,14 @@ export function FormSendReset() {
|
|||
|
||||
export function FormReset() {
|
||||
const { token } = useParams<{ token: string }>();
|
||||
const config = useApplicationState().config;
|
||||
const client = config.createClient();
|
||||
const history = useHistory();
|
||||
const api = useApi();
|
||||
|
||||
return (
|
||||
<Form
|
||||
page="reset"
|
||||
callback={async (data) => {
|
||||
await client.api.patch("/auth/account/reset_password", {
|
||||
await api.patch("/auth/account/reset_password", {
|
||||
token,
|
||||
...data,
|
||||
});
|
||||
|
|
|
@ -4,22 +4,20 @@ import { useEffect, useState } from "preact/hooks";
|
|||
|
||||
import { Category, Preloader } from "@revoltchat/ui";
|
||||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { I18nError } from "../../../context/Locale";
|
||||
import { takeError } from "../../../context/revoltjs/util";
|
||||
|
||||
import { useApi } from "../../../controllers/client/ClientController";
|
||||
import { Form } from "./Form";
|
||||
|
||||
export function FormResend() {
|
||||
const config = useApplicationState().config;
|
||||
const client = config.createClient();
|
||||
const api = useApi();
|
||||
|
||||
return (
|
||||
<Form
|
||||
page="resend"
|
||||
callback={async (data) => {
|
||||
await client.api.post("/auth/account/reverify", data);
|
||||
await api.post("/auth/account/reverify", data);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -28,13 +26,11 @@ export function FormResend() {
|
|||
export function FormVerify() {
|
||||
const [error, setError] = useState<undefined | string>(undefined);
|
||||
const { token } = useParams<{ token: string }>();
|
||||
const config = useApplicationState().config;
|
||||
const client = config.createClient();
|
||||
const history = useHistory();
|
||||
const api = useApi();
|
||||
|
||||
useEffect(() => {
|
||||
client.api
|
||||
.post(`/auth/account/verify/${token as ""}`)
|
||||
api.post(`/auth/account/verify/${token as ""}`)
|
||||
.then(() => history.push("/login"))
|
||||
.catch((err) => setError(takeError(err)));
|
||||
// eslint-disable-next-line
|
||||
|
|
|
@ -4,9 +4,9 @@ import { Route, Switch, useHistory, useParams } from "react-router-dom";
|
|||
|
||||
import { Text } from "preact-i18n";
|
||||
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
import { getChannelName } from "../../context/revoltjs/util";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { GenericSettings } from "./GenericSettings";
|
||||
import Overview from "./channel/Overview";
|
||||
import Permissions from "./channel/Permissions";
|
||||
|
|
|
@ -17,9 +17,9 @@ import { LineDivider } from "@revoltchat/ui";
|
|||
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import RequiresOnline from "../../context/revoltjs/RequiresOnline";
|
||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import ButtonItem from "../../components/navigation/items/ButtonItem";
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { GenericSettings } from "./GenericSettings";
|
||||
import { Bans } from "./server/Bans";
|
||||
import { Categories } from "./server/Categories";
|
||||
|
|
|
@ -28,7 +28,6 @@ import styled from "styled-components/macro";
|
|||
import styles from "./Settings.module.scss";
|
||||
import { openContextMenu } from "preact-context-menu";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { LineDivider } from "@revoltchat/ui";
|
||||
|
||||
|
@ -36,12 +35,15 @@ import { useApplicationState } from "../../mobx/State";
|
|||
|
||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||
import RequiresOnline from "../../context/revoltjs/RequiresOnline";
|
||||
import { AppContext, LogOutContext } from "../../context/revoltjs/RevoltClient";
|
||||
|
||||
import UserIcon from "../../components/common/user/UserIcon";
|
||||
import { Username } from "../../components/common/user/UserShort";
|
||||
import UserStatus from "../../components/common/user/UserStatus";
|
||||
import ButtonItem from "../../components/navigation/items/ButtonItem";
|
||||
import {
|
||||
useClient,
|
||||
clientController,
|
||||
} from "../../controllers/client/ClientController";
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import { GIT_BRANCH, GIT_REVISION, REPO_URL } from "../../revision";
|
||||
import { APP_VERSION } from "../../version";
|
||||
|
@ -118,8 +120,7 @@ const AccountHeader = styled.div`
|
|||
|
||||
export default observer(() => {
|
||||
const history = useHistory();
|
||||
const client = useContext(AppContext);
|
||||
const logout = useContext(LogOutContext);
|
||||
const client = useClient();
|
||||
const { openScreen } = useIntermediate();
|
||||
const experiments = useApplicationState().experiments;
|
||||
|
||||
|
@ -288,7 +289,7 @@ export default observer(() => {
|
|||
</a>
|
||||
<LineDivider compact />
|
||||
<ButtonItem
|
||||
onClick={() => logout()}
|
||||
onClick={clientController.logoutCurrent}
|
||||
className={styles.logOut}
|
||||
compact>
|
||||
<LogOut size={20} />
|
||||
|
|
|
@ -3,8 +3,7 @@ import { Key, Clipboard, Globe, Plus } from "@styled-icons/boxicons-regular";
|
|||
import { LockAlt, HelpCircle } from "@styled-icons/boxicons-solid";
|
||||
import type { AxiosError } from "axios";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { API } from "revolt.js";
|
||||
import { User } from "revolt.js";
|
||||
import { API, User } from "revolt.js";
|
||||
import styled from "styled-components/macro";
|
||||
|
||||
import styles from "./Panes.module.scss";
|
||||
|
@ -26,7 +25,6 @@ import { stopPropagation } from "../../../lib/stopPropagation";
|
|||
|
||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import AutoComplete, {
|
||||
useAutoComplete,
|
||||
|
@ -34,6 +32,7 @@ import AutoComplete, {
|
|||
import CollapsibleSection from "../../../components/common/CollapsibleSection";
|
||||
import Tooltip from "../../../components/common/Tooltip";
|
||||
import UserIcon from "../../../components/common/user/UserIcon";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
interface Data {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { observer } from "mobx-react-lite";
|
|||
|
||||
import styles from "./Panes.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Checkbox, Column } from "@revoltchat/ui";
|
||||
|
||||
|
@ -10,12 +10,11 @@ import { urlBase64ToUint8Array } from "../../../lib/conversion";
|
|||
|
||||
import { useApplicationState } from "../../../mobx/State";
|
||||
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
export const Notifications = observer(() => {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const settings = useApplicationState().settings;
|
||||
const [pushEnabled, setPushEnabled] = useState<undefined | boolean>(
|
||||
undefined,
|
||||
|
|
|
@ -14,20 +14,16 @@ import { useTranslation } from "../../../lib/i18n";
|
|||
|
||||
import { UserProfile } from "../../../context/intermediate/popovers/UserProfile";
|
||||
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
||||
import {
|
||||
ClientStatus,
|
||||
StatusContext,
|
||||
useClient,
|
||||
} from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import AutoComplete, {
|
||||
useAutoComplete,
|
||||
} from "../../../components/common/AutoComplete";
|
||||
import { useSession } from "../../../controllers/client/ClientController";
|
||||
|
||||
export const Profile = observer(() => {
|
||||
const status = useContext(StatusContext);
|
||||
const translate = useTranslation();
|
||||
const client = useClient();
|
||||
const session = useSession()!;
|
||||
const client = session.client!;
|
||||
const history = useHistory();
|
||||
|
||||
const [profile, setProfile] = useState<undefined | API.UserProfile>(
|
||||
|
@ -43,10 +39,10 @@ export const Profile = observer(() => {
|
|||
}, [client.user, setProfile]);
|
||||
|
||||
useEffect(() => {
|
||||
if (profile === undefined && status === ClientStatus.ONLINE) {
|
||||
if (profile === undefined && session.state === "Online") {
|
||||
refreshProfile();
|
||||
}
|
||||
}, [profile, status, refreshProfile]);
|
||||
}, [profile, session.state, refreshProfile]);
|
||||
|
||||
const [changed, setChanged] = useState(false);
|
||||
function setContent(content?: string) {
|
||||
|
|
|
@ -16,7 +16,7 @@ import { decodeTime } from "ulid";
|
|||
|
||||
import styles from "./Panes.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import {
|
||||
Button,
|
||||
|
@ -27,14 +27,14 @@ import {
|
|||
} from "@revoltchat/ui";
|
||||
|
||||
import { dayjs } from "../../../context/Locale";
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { modalController } from "../../../controllers/modals/ModalController";
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
export function Sessions() {
|
||||
const client = useContext(AppContext);
|
||||
const client = useClient();
|
||||
const deviceId =
|
||||
typeof client.session === "object" ? client.session._id : undefined;
|
||||
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -3572,6 +3572,7 @@ __metadata:
|
|||
eslint: ^7.28.0
|
||||
eslint-config-preact: ^1.1.4
|
||||
eslint-plugin-jsdoc: ^39.3.2
|
||||
eslint-plugin-mobx: ^0.0.8
|
||||
eventemitter3: ^4.0.7
|
||||
fs-extra: ^10.0.0
|
||||
history: 4
|
||||
|
@ -4375,6 +4376,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-mobx@npm:^0.0.8":
|
||||
version: 0.0.8
|
||||
resolution: "eslint-plugin-mobx@npm:0.0.8"
|
||||
peerDependencies:
|
||||
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
checksum: c4d9977ccbde2041ad4fec405b36763cd0bc738c7cc4bde6054b560d4b0d3929371927fedf5a37f9b039c712a382f62455931ca255a142fd9089ce8b53d0d66b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-react-hooks@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "eslint-plugin-react-hooks@npm:4.2.0"
|
||||
|
|
Loading…
Reference in a new issue