mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-22 07:00:58 -05:00
Hide client behind context.
Use idb for saving data. Allow logins.
This commit is contained in:
parent
68a35751b3
commit
ec97dbebd0
13 changed files with 474 additions and 187 deletions
|
@ -29,7 +29,7 @@
|
||||||
"@preact/preset-vite": "^2.0.0",
|
"@preact/preset-vite": "^2.0.0",
|
||||||
"@styled-icons/bootstrap": "^10.34.0",
|
"@styled-icons/bootstrap": "^10.34.0",
|
||||||
"@styled-icons/feather": "^10.34.0",
|
"@styled-icons/feather": "^10.34.0",
|
||||||
"@types/node": "^15.12.3",
|
"@types/node": "^15.12.4",
|
||||||
"@types/preact-i18n": "^2.3.0",
|
"@types/preact-i18n": "^2.3.0",
|
||||||
"@types/react-helmet": "^6.1.1",
|
"@types/react-helmet": "^6.1.1",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.1.7",
|
||||||
|
@ -40,6 +40,7 @@
|
||||||
"detect-browser": "^5.2.0",
|
"detect-browser": "^5.2.0",
|
||||||
"eslint": "^7.28.0",
|
"eslint": "^7.28.0",
|
||||||
"eslint-config-preact": "^1.1.4",
|
"eslint-config-preact": "^1.1.4",
|
||||||
|
"idb": "^6.1.2",
|
||||||
"localforage": "^1.9.0",
|
"localforage": "^1.9.0",
|
||||||
"preact-i18n": "^2.4.0-preactx",
|
"preact-i18n": "^2.4.0-preactx",
|
||||||
"prettier": "^2.3.1",
|
"prettier": "^2.3.1",
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
"react-redux": "^7.2.4",
|
"react-redux": "^7.2.4",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"redux": "^4.1.0",
|
"redux": "^4.1.0",
|
||||||
"revolt.js": "4.2.0-alpha.3-patch.0",
|
"revolt.js": "4.3.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"sass": "^1.35.1",
|
"sass": "^1.35.1",
|
||||||
"styled-components": "^5.3.0",
|
"styled-components": "^5.3.0",
|
||||||
|
|
18
src/app.tsx
18
src/app.tsx
|
@ -4,6 +4,22 @@ import Context from "./context";
|
||||||
|
|
||||||
import { Login } from "./pages/login/Login";
|
import { Login } from "./pages/login/Login";
|
||||||
|
|
||||||
|
import { useForceUpdate, useSelf, useUser } from "./context/revoltjs/hooks";
|
||||||
|
|
||||||
|
function Test() {
|
||||||
|
const ctx = useForceUpdate();
|
||||||
|
|
||||||
|
let self = useSelf(ctx);
|
||||||
|
let bree = useUser('01EZZJ98RM1YVB1FW9FG221CAN', ctx);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>logged in as { self?.username }</h1>
|
||||||
|
<h4>bree: { JSON.stringify(bree) }</h4>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
return (
|
return (
|
||||||
<Context>
|
<Context>
|
||||||
|
@ -15,7 +31,7 @@ export function App() {
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<CheckAuth auth>
|
<CheckAuth auth>
|
||||||
<h1>revolt app</h1>
|
<Test />
|
||||||
</CheckAuth>
|
</CheckAuth>
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
|
import { openDB } from 'idb';
|
||||||
import { Client } from "revolt.js";
|
import { Client } from "revolt.js";
|
||||||
|
import { takeError } from "./error";
|
||||||
import { createContext } from "preact";
|
import { createContext } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
|
||||||
import { Children } from "../../types/Preact";
|
import { Children } from "../../types/Preact";
|
||||||
import { Route } from "revolt.js/dist/api/routes";
|
import { Route } from "revolt.js/dist/api/routes";
|
||||||
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { connectState } from "../../redux/connector";
|
import { connectState } from "../../redux/connector";
|
||||||
|
import Preloader from "../../components/ui/Preloader";
|
||||||
import { WithDispatcher } from "../../redux/reducers";
|
import { WithDispatcher } from "../../redux/reducers";
|
||||||
import { AuthState } from "../../redux/reducers/auth";
|
import { AuthState } from "../../redux/reducers/auth";
|
||||||
import { SyncOptions } from "../../redux/reducers/sync";
|
import { SyncOptions } from "../../redux/reducers/sync";
|
||||||
|
import { registerEvents, setReconnectDisallowed } from "./events";
|
||||||
|
|
||||||
export enum ClientStatus {
|
export enum ClientStatus {
|
||||||
|
INIT,
|
||||||
LOADING,
|
LOADING,
|
||||||
READY,
|
READY,
|
||||||
OFFLINE,
|
OFFLINE,
|
||||||
|
@ -26,19 +31,13 @@ export interface ClientOperations {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
|
client: Client;
|
||||||
status: ClientStatus;
|
status: ClientStatus;
|
||||||
operations: ClientOperations;
|
operations: ClientOperations;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AppContext = createContext<AppState>(undefined as any);
|
export const AppContext = createContext<AppState>(undefined as any);
|
||||||
|
|
||||||
export const RevoltClient = new Client({
|
|
||||||
autoReconnect: false,
|
|
||||||
apiURL: import.meta.env.VITE_API_URL,
|
|
||||||
debug: process.env.NODE_ENV === "development",
|
|
||||||
// db: new Db("state", 3, ["channels", "servers", "users", "members"])
|
|
||||||
});
|
|
||||||
|
|
||||||
type Props = WithDispatcher & {
|
type Props = WithDispatcher & {
|
||||||
auth: AuthState;
|
auth: AuthState;
|
||||||
sync: SyncOptions;
|
sync: SyncOptions;
|
||||||
|
@ -46,18 +45,176 @@ type Props = WithDispatcher & {
|
||||||
};
|
};
|
||||||
|
|
||||||
function Context({ auth, sync, children, dispatcher }: Props) {
|
function Context({ auth, sync, children, dispatcher }: Props) {
|
||||||
const [status, setStatus] = useState(ClientStatus.LOADING);
|
const [status, setStatus] = useState(ClientStatus.INIT);
|
||||||
|
const [client, setClient] = useState<Client>(undefined as unknown as Client);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
let db;
|
||||||
|
try {
|
||||||
|
db = await openDB('state', 3, {
|
||||||
|
upgrade(db) {
|
||||||
|
for (let store of [ "channels", "servers", "users", "members" ]) {
|
||||||
|
db.createObjectStore(store, {
|
||||||
|
keyPath: '_id'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to open IndexedDB store, continuing without.');
|
||||||
|
}
|
||||||
|
|
||||||
|
setClient(new Client({
|
||||||
|
autoReconnect: false,
|
||||||
|
apiURL: import.meta.env.VITE_API_URL,
|
||||||
|
debug: import.meta.env.DEV,
|
||||||
|
db
|
||||||
|
}));
|
||||||
|
|
||||||
|
setStatus(ClientStatus.LOADING);
|
||||||
|
})();
|
||||||
|
}, [ ]);
|
||||||
|
|
||||||
|
if (status === ClientStatus.INIT) return null;
|
||||||
|
|
||||||
const value: AppState = {
|
const value: AppState = {
|
||||||
|
client,
|
||||||
status,
|
status,
|
||||||
operations: {
|
operations: {
|
||||||
login: async data => {},
|
login: async data => {
|
||||||
logout: async shouldRequest => {},
|
setReconnectDisallowed(true);
|
||||||
loggedIn: () => false,
|
|
||||||
ready: () => false
|
try {
|
||||||
|
const onboarding = await client.login(data);
|
||||||
|
setReconnectDisallowed(false);
|
||||||
|
const login = () =>
|
||||||
|
dispatcher({
|
||||||
|
type: "LOGIN",
|
||||||
|
session: client.session as any
|
||||||
|
});
|
||||||
|
|
||||||
|
if (onboarding) {
|
||||||
|
/*openScreen({
|
||||||
|
id: "onboarding",
|
||||||
|
callback: async (username: string) => {
|
||||||
|
await (onboarding as any)(username, true);
|
||||||
|
login();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
} else {
|
||||||
|
login();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
setReconnectDisallowed(false);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logout: async shouldRequest => {
|
||||||
|
dispatcher({ type: "LOGOUT" });
|
||||||
|
|
||||||
|
delete client.user;
|
||||||
|
dispatcher({ type: "RESET" });
|
||||||
|
|
||||||
|
// openScreen({ id: "none" });
|
||||||
|
setStatus(ClientStatus.READY);
|
||||||
|
|
||||||
|
client.websocket.disconnect();
|
||||||
|
|
||||||
|
if (shouldRequest) {
|
||||||
|
try {
|
||||||
|
await client.logout();
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loggedIn: () => typeof auth.active !== "undefined",
|
||||||
|
ready: () => (
|
||||||
|
value.operations.loggedIn() &&
|
||||||
|
typeof client.user !== "undefined"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => registerEvents({ ...value, dispatcher }, setStatus, client),
|
||||||
|
[ client ]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
await client.restore();
|
||||||
|
|
||||||
|
if (auth.active) {
|
||||||
|
dispatcher({ type: "QUEUE_FAIL_ALL" });
|
||||||
|
|
||||||
|
const active = auth.accounts[auth.active];
|
||||||
|
client.user = client.users.get(active.session.user_id);
|
||||||
|
if (!navigator.onLine) {
|
||||||
|
return setStatus(ClientStatus.OFFLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.operations.ready())
|
||||||
|
setStatus(ClientStatus.CONNECTING);
|
||||||
|
|
||||||
|
if (navigator.onLine) {
|
||||||
|
await client
|
||||||
|
.fetchConfiguration()
|
||||||
|
.catch(() =>
|
||||||
|
console.error("Failed to connect to API server.")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.fetchConfiguration();
|
||||||
|
const callback = await client.useExistingSession(
|
||||||
|
active.session
|
||||||
|
);
|
||||||
|
|
||||||
|
//if (callback) {
|
||||||
|
/*openScreen({ id: "onboarding", callback });*/
|
||||||
|
//} else {
|
||||||
|
/*
|
||||||
|
// ! FIXME: all this code needs to be re-written
|
||||||
|
(async () => {
|
||||||
|
// ! FIXME: should be included in Ready payload
|
||||||
|
props.dispatcher({
|
||||||
|
type: 'SYNC_UPDATE',
|
||||||
|
// ! FIXME: write a procedure to resolve merge conflicts
|
||||||
|
update: mapSync(
|
||||||
|
await client.syncFetchSettings(DEFAULT_ENABLED_SYNC.filter(x => !props.sync?.disabled?.includes(x)))
|
||||||
|
)
|
||||||
|
});
|
||||||
|
})()
|
||||||
|
|
||||||
|
props.dispatcher({ type: 'UNREADS_SET', unreads: await client.syncFetchUnreads() });*/
|
||||||
|
//}
|
||||||
|
} catch (err) {
|
||||||
|
setStatus(ClientStatus.DISCONNECTED);
|
||||||
|
const error = takeError(err);
|
||||||
|
if (error === "Forbidden") {
|
||||||
|
value.operations.logout(true);
|
||||||
|
// openScreen({ id: "signed_out" });
|
||||||
|
} else {
|
||||||
|
// openScreen({ id: "error", error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await client
|
||||||
|
.fetchConfiguration()
|
||||||
|
.catch(() =>
|
||||||
|
console.error("Failed to connect to API server.")
|
||||||
|
);
|
||||||
|
setStatus(ClientStatus.READY);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (status === ClientStatus.LOADING) {
|
||||||
|
return <Preloader />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider value={value}>
|
<AppContext.Provider value={value}>
|
||||||
{ children }
|
{ children }
|
||||||
|
|
121
src/context/revoltjs/events.ts
Normal file
121
src/context/revoltjs/events.ts
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
|
||||||
|
import { WithDispatcher } from "../../redux/reducers";
|
||||||
|
import { Client, Message } from "revolt.js/dist";
|
||||||
|
import {
|
||||||
|
AppState,
|
||||||
|
ClientStatus
|
||||||
|
} from "./RevoltClient";
|
||||||
|
import { StateUpdater } from "preact/hooks";
|
||||||
|
|
||||||
|
export var preventReconnect = false;
|
||||||
|
let preventUntil = 0;
|
||||||
|
|
||||||
|
export function setReconnectDisallowed(allowed: boolean) {
|
||||||
|
preventReconnect = allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerEvents({
|
||||||
|
operations,
|
||||||
|
dispatcher
|
||||||
|
}: AppState & WithDispatcher, setStatus: StateUpdater<ClientStatus>, client: Client) {
|
||||||
|
const listeners = {
|
||||||
|
connecting: () =>
|
||||||
|
operations.ready() && setStatus(ClientStatus.CONNECTING),
|
||||||
|
|
||||||
|
dropped: () => {
|
||||||
|
operations.ready() && setStatus(ClientStatus.DISCONNECTED);
|
||||||
|
|
||||||
|
if (preventReconnect) return;
|
||||||
|
function reconnect() {
|
||||||
|
preventUntil = +new Date() + 2000;
|
||||||
|
client.websocket.connect().catch(err => console.error(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (+new Date() > preventUntil) {
|
||||||
|
setTimeout(reconnect, 2000);
|
||||||
|
} else {
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
packet: (packet: ClientboundNotification) => {
|
||||||
|
switch (packet.type) {
|
||||||
|
case "ChannelStartTyping": {
|
||||||
|
if (packet.user === client.user?._id) return;
|
||||||
|
dispatcher({
|
||||||
|
type: "TYPING_START",
|
||||||
|
channel: packet.id,
|
||||||
|
user: packet.user
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ChannelStopTyping": {
|
||||||
|
if (packet.user === client.user?._id) return;
|
||||||
|
dispatcher({
|
||||||
|
type: "TYPING_STOP",
|
||||||
|
channel: packet.id,
|
||||||
|
user: packet.user
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ChannelAck": {
|
||||||
|
dispatcher({
|
||||||
|
type: "UNREADS_MARK_READ",
|
||||||
|
channel: packet.id,
|
||||||
|
message: packet.message_id,
|
||||||
|
request: false
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
message: (message: Message) => {
|
||||||
|
if (message.mentions?.includes(client.user!._id)) {
|
||||||
|
dispatcher({
|
||||||
|
type: "UNREADS_MENTION",
|
||||||
|
channel: message.channel,
|
||||||
|
message: message._id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ready: () => {
|
||||||
|
setStatus(ClientStatus.ONLINE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let listenerFunc: { [key: string]: Function };
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
listenerFunc = {};
|
||||||
|
for (const listener of Object.keys(listeners)) {
|
||||||
|
listenerFunc[listener] = (...args: any[]) => {
|
||||||
|
console.debug(`Calling ${listener} with`, args);
|
||||||
|
(listeners as any)[listener](...args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listenerFunc = listeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const listener of Object.keys(listenerFunc)) {
|
||||||
|
client.addListener(listener, (listenerFunc as any)[listener]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*const online = () =>
|
||||||
|
operations.ready() && setStatus(ClientStatus.RECONNECTING);
|
||||||
|
const offline = () =>
|
||||||
|
operations.ready() && setStatus(ClientStatus.OFFLINE);
|
||||||
|
|
||||||
|
window.addEventListener("online", online);
|
||||||
|
window.addEventListener("offline", offline);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
for (const listener of Object.keys(listenerFunc)) {
|
||||||
|
RevoltClient.removeListener(listener, (listenerFunc as any)[listener]);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.removeEventListener("online", online);
|
||||||
|
window.removeEventListener("offline", offline);
|
||||||
|
};*/
|
||||||
|
}
|
108
src/context/revoltjs/hooks.ts
Normal file
108
src/context/revoltjs/hooks.ts
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import { useCallback, useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
|
||||||
|
import { Client, PermissionCalculator } from 'revolt.js';
|
||||||
|
import { AppContext } from "./RevoltClient";
|
||||||
|
|
||||||
|
interface HookContext {
|
||||||
|
client: Client,
|
||||||
|
forceUpdate: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useForceUpdate(context?: HookContext): HookContext {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
if (context) return context;
|
||||||
|
const [, updateState] = useState({});
|
||||||
|
return { client, forceUpdate: useCallback(() => updateState({}), []) };
|
||||||
|
}
|
||||||
|
|
||||||
|
function useObject(type: string, id?: string | string[], context?: HookContext) {
|
||||||
|
const ctx = useForceUpdate(context);
|
||||||
|
|
||||||
|
function mutation(target: string) {
|
||||||
|
if (typeof id === 'string' ? target === id :
|
||||||
|
Array.isArray(id) ? id.includes(target) : true) {
|
||||||
|
ctx.forceUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = (ctx.client as any)[type];
|
||||||
|
useEffect(() => {
|
||||||
|
map.addListener("update", mutation);
|
||||||
|
return () => map.removeListener("update", mutation);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
return typeof id === 'string' ? map.get(id)
|
||||||
|
: Array.isArray(id) ? id.map(x => map.get(x))
|
||||||
|
: map.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUser(id?: string, context?: HookContext) {
|
||||||
|
if (typeof id === "undefined") return;
|
||||||
|
return useObject('users', id, context) as Readonly<Users.User> | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelf(context?: HookContext) {
|
||||||
|
const ctx = useForceUpdate(context);
|
||||||
|
return useUser(ctx.client.user!._id, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUsers(ids?: string[], context?: HookContext) {
|
||||||
|
return useObject('users', ids, context) as (Readonly<Users.User> | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useChannel(id?: string, context?: HookContext) {
|
||||||
|
if (typeof id === "undefined") return;
|
||||||
|
return useObject('channels', id, context) as Readonly<Channels.Channel> | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useChannels(ids?: string[], context?: HookContext) {
|
||||||
|
return useObject('channels', ids, context) as (Readonly<Channels.Channel> | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useServer(id?: string, context?: HookContext) {
|
||||||
|
if (typeof id === "undefined") return;
|
||||||
|
return useObject('servers', id, context) as Readonly<Servers.Server> | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useServers(ids?: string[], context?: HookContext) {
|
||||||
|
return useObject('servers', ids, context) as (Readonly<Servers.Server> | undefined)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useUserPermission(id: string, context?: HookContext) {
|
||||||
|
const ctx = useForceUpdate(context);
|
||||||
|
|
||||||
|
const mutation = (target: string) => (target === id) && ctx.forceUpdate();
|
||||||
|
useEffect(() => {
|
||||||
|
ctx.client.users.addListener("update", mutation);
|
||||||
|
return () => ctx.client.users.removeListener("update", mutation);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
let calculator = new PermissionCalculator(ctx.client);
|
||||||
|
return calculator.forUser(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useChannelPermission(id: string, context?: HookContext) {
|
||||||
|
const ctx = useForceUpdate(context);
|
||||||
|
|
||||||
|
const mutation = (target: string) => (target === id) && ctx.forceUpdate();
|
||||||
|
useEffect(() => {
|
||||||
|
ctx.client.channels.addListener("update", mutation);
|
||||||
|
return () => ctx.client.channels.removeListener("update", mutation);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
let calculator = new PermissionCalculator(ctx.client);
|
||||||
|
return calculator.forChannel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useServerPermission(id: string, context?: HookContext) {
|
||||||
|
const ctx = useForceUpdate(context);
|
||||||
|
|
||||||
|
const mutation = (target: string) => (target === id) && ctx.forceUpdate();
|
||||||
|
useEffect(() => {
|
||||||
|
ctx.client.servers.addListener("update", mutation);
|
||||||
|
return () => ctx.client.servers.removeListener("update", mutation);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
let calculator = new PermissionCalculator(ctx.client);
|
||||||
|
return calculator.forServer(id);
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import { APP_VERSION } from "../../version";
|
||||||
import { LIBRARY_VERSION } from "revolt.js";
|
import { LIBRARY_VERSION } from "revolt.js";
|
||||||
import { Route, Switch } from "react-router-dom";
|
import { Route, Switch } from "react-router-dom";
|
||||||
import { ThemeContext } from "../../context/Theme";
|
import { ThemeContext } from "../../context/Theme";
|
||||||
import { RevoltClient } from "../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import background from "./background.jpg";
|
import background from "./background.jpg";
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import { FormReset, FormSendReset } from "./forms/FormReset";
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.login}>
|
<div className={styles.login}>
|
||||||
|
@ -27,7 +28,7 @@ export const Login = () => {
|
||||||
<div className={styles.attribution}>
|
<div className={styles.attribution}>
|
||||||
<span>
|
<span>
|
||||||
API:{" "}
|
API:{" "}
|
||||||
<code>{RevoltClient.configuration?.revolt ?? "???"}</code>{" "}
|
<code>{client.configuration?.revolt ?? "???"}</code>{" "}
|
||||||
· revolt.js: <code>{LIBRARY_VERSION}</code>{" "}
|
· revolt.js: <code>{LIBRARY_VERSION}</code>{" "}
|
||||||
· App: <code>{APP_VERSION}</code>
|
· App: <code>{APP_VERSION}</code>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useEffect } from "preact/hooks";
|
|
||||||
import styles from "../Login.module.scss";
|
import styles from "../Login.module.scss";
|
||||||
import HCaptcha from "@hcaptcha/react-hcaptcha";
|
import HCaptcha from "@hcaptcha/react-hcaptcha";
|
||||||
|
import { useContext, useEffect } from "preact/hooks";
|
||||||
import Preloader from "../../../components/ui/Preloader";
|
import Preloader from "../../../components/ui/Preloader";
|
||||||
import { RevoltClient } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
export interface CaptchaProps {
|
export interface CaptchaProps {
|
||||||
onSuccess: (token?: string) => void;
|
onSuccess: (token?: string) => void;
|
||||||
|
@ -11,19 +11,21 @@ export interface CaptchaProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CaptchaBlock(props: CaptchaProps) {
|
export function CaptchaBlock(props: CaptchaProps) {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!RevoltClient.configuration?.features.captcha.enabled) {
|
if (!client.configuration?.features.captcha.enabled) {
|
||||||
props.onSuccess();
|
props.onSuccess();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!RevoltClient.configuration?.features.captcha.enabled)
|
if (!client.configuration?.features.captcha.enabled)
|
||||||
return <Preloader />;
|
return <Preloader />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<HCaptcha
|
<HCaptcha
|
||||||
sitekey={RevoltClient.configuration.features.captcha.key}
|
sitekey={client.configuration.features.captcha.key}
|
||||||
onVerify={token => props.onSuccess(token)}
|
onVerify={token => props.onSuccess(token)}
|
||||||
/>
|
/>
|
||||||
<div className={styles.footer}>
|
<div className={styles.footer}>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Legal } from "./Legal";
|
import { Legal } from "./Legal";
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { useState } from "preact/hooks";
|
|
||||||
import styles from "../Login.module.scss";
|
import styles from "../Login.module.scss";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { MailProvider } from "./MailProvider";
|
import { MailProvider } from "./MailProvider";
|
||||||
|
import { useContext, useState } from "preact/hooks";
|
||||||
import { CheckCircle, Mail } from "@styled-icons/feather";
|
import { CheckCircle, Mail } from "@styled-icons/feather";
|
||||||
import { CaptchaBlock, CaptchaProps } from "./CaptchaBlock";
|
import { CaptchaBlock, CaptchaProps } from "./CaptchaBlock";
|
||||||
import { takeError } from "../../../context/revoltjs/error";
|
import { takeError } from "../../../context/revoltjs/error";
|
||||||
import { RevoltClient } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import FormField from "../FormField";
|
import FormField from "../FormField";
|
||||||
import Button from "../../../components/ui/Button";
|
import Button from "../../../components/ui/Button";
|
||||||
|
@ -34,6 +34,8 @@ function getInviteCode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Form({ page, callback }: Props) {
|
export function Form({ page, callback }: Props) {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [success, setSuccess] = useState<string | undefined>(undefined);
|
const [success, setSuccess] = useState<string | undefined>(undefined);
|
||||||
const [error, setGlobalError] = useState<string | undefined>(undefined);
|
const [error, setGlobalError] = useState<string | undefined>(undefined);
|
||||||
|
@ -73,7 +75,7 @@ export function Form({ page, callback }: Props) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
RevoltClient.configuration?.features.captcha.enabled &&
|
client.configuration?.features.captcha.enabled &&
|
||||||
page !== "reset"
|
page !== "reset"
|
||||||
) {
|
) {
|
||||||
setCaptcha({
|
setCaptcha({
|
||||||
|
@ -103,7 +105,7 @@ export function Form({ page, callback }: Props) {
|
||||||
if (typeof success !== "undefined") {
|
if (typeof success !== "undefined") {
|
||||||
return (
|
return (
|
||||||
<div className={styles.success}>
|
<div className={styles.success}>
|
||||||
{RevoltClient.configuration?.features.email ? (
|
{client.configuration?.features.email ? (
|
||||||
<>
|
<>
|
||||||
<Mail size={72} />
|
<Mail size={72} />
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -157,7 +159,7 @@ export function Form({ page, callback }: Props) {
|
||||||
error={errors.password?.message}
|
error={errors.password?.message}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{RevoltClient.configuration?.features.invite_only &&
|
{client.configuration?.features.invite_only &&
|
||||||
page === "create" && (
|
page === "create" && (
|
||||||
<FormField
|
<FormField
|
||||||
type="invite"
|
type="invite"
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { RevoltClient } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
import { useContext } from "preact/hooks";
|
||||||
import { Form } from "./Form";
|
import { Form } from "./Form";
|
||||||
|
|
||||||
export function FormCreate() {
|
export function FormCreate() {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
page="create"
|
page="create"
|
||||||
callback={async data => {
|
callback={async data => {
|
||||||
await RevoltClient.register(process.env.API_SERVER as string, data);
|
await client.register(import.meta.env.VITE_API_URL, data);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { RevoltClient } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
import { useContext } from "preact/hooks";
|
||||||
import { Form } from "./Form";
|
import { Form } from "./Form";
|
||||||
|
|
||||||
export function FormResend() {
|
export function FormResend() {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
page="resend"
|
page="resend"
|
||||||
callback={async data => {
|
callback={async data => {
|
||||||
await RevoltClient.req("POST", "/auth/resend", data);
|
await client.req("POST", "/auth/resend", data);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import { Form } from "./Form";
|
import { Form } from "./Form";
|
||||||
|
import { useContext } from "preact/hooks";
|
||||||
import { useHistory, useParams } from "react-router-dom";
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
import { RevoltClient } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
export function FormSendReset() {
|
export function FormSendReset() {
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
page="send_reset"
|
page="send_reset"
|
||||||
callback={async data => {
|
callback={async data => {
|
||||||
await RevoltClient.req("POST", "/auth/send_reset", data);
|
await client.req("POST", "/auth/send_reset", data);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -15,13 +18,14 @@ export function FormSendReset() {
|
||||||
|
|
||||||
export function FormReset() {
|
export function FormReset() {
|
||||||
const { token } = useParams<{ token: string }>();
|
const { token } = useParams<{ token: string }>();
|
||||||
|
const { client } = useContext(AppContext);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
page="reset"
|
page="reset"
|
||||||
callback={async data => {
|
callback={async data => {
|
||||||
await RevoltClient.req("POST", "/auth/reset" as any, {
|
await client.req("POST", "/auth/reset" as any, {
|
||||||
token,
|
token,
|
||||||
...(data as any)
|
...(data as any)
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,7 @@ export type State = {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const store = createStore((state: any, action: any) => {
|
export const store = createStore((state: any, action: any) => {
|
||||||
if (process.env.NODE_ENV === "development") {
|
if (import.meta.env.DEV) {
|
||||||
console.debug("State Update:", action);
|
console.debug("State Update:", action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
171
yarn.lock
171
yarn.lock
|
@ -960,26 +960,14 @@
|
||||||
resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-0.3.6.tgz#cbbb9abdaea451a4df408bc9d476e8b17f0b63f4"
|
resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-0.3.6.tgz#cbbb9abdaea451a4df408bc9d476e8b17f0b63f4"
|
||||||
integrity sha512-DQ5nvGVbbhd2IednxRhCV9wiPcCmclEV7bH98yGynGCXzO5XftO/XC0a1M1kEf9Ee+CLO/u+1HM/uE/PSrC3vQ==
|
integrity sha512-DQ5nvGVbbhd2IednxRhCV9wiPcCmclEV7bH98yGynGCXzO5XftO/XC0a1M1kEf9Ee+CLO/u+1HM/uE/PSrC3vQ==
|
||||||
|
|
||||||
"@insertish/mutable@1.0.6":
|
"@insertish/mutable@1.1.0":
|
||||||
version "1.0.6"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@insertish/mutable/-/mutable-1.0.6.tgz#f42eaba8528ff68cc8065d51f9bbbd30a24f34de"
|
resolved "https://registry.yarnpkg.com/@insertish/mutable/-/mutable-1.1.0.tgz#06f95f855691ccb69ee3c339887a80bcd1498116"
|
||||||
integrity sha512-FTaPbesmBwcr3iKfbA2udFto61/sL7rOiCM08vBbE2X0wC63nsvTos6gnkwa1Nwom1v15jjrc/4B0YqI3vbZ/Q==
|
integrity sha512-NH7aCGFAKRE1gFprrW/HsJoWCWQy18TZBarxLdeLVWdLFvkb2lD6Z5B70oOoUHFNpykiTC8IcRonsd9Xn13n8Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@insertish/zangodb" "^1.0.12"
|
|
||||||
eventemitter3 "^4.0.7"
|
eventemitter3 "^4.0.7"
|
||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
|
|
||||||
"@insertish/zangodb@1.0.12", "@insertish/zangodb@^1.0.12":
|
|
||||||
version "1.0.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@insertish/zangodb/-/zangodb-1.0.12.tgz#25264ec065720fa43c7549ec7245e4f3839cb0ea"
|
|
||||||
integrity sha512-JlLI12Xqt1xvv/p2/AHs163ZYMZsB3sJyjB8yaAs6QcG0tyRBTIyxV5ISEAkAPo5kzlFza5z5oH82yQe/qw5RQ==
|
|
||||||
dependencies:
|
|
||||||
clone "^2.1.2"
|
|
||||||
deepmerge "^4.2.2"
|
|
||||||
memoizee "^0.4.15"
|
|
||||||
object-hash "^2.1.1"
|
|
||||||
q "^1.5.1"
|
|
||||||
|
|
||||||
"@mdn/browser-compat-data@^2.0.7":
|
"@mdn/browser-compat-data@^2.0.7":
|
||||||
version "2.0.7"
|
version "2.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-2.0.7.tgz#72ec37b9c1e00ce0b4e0309d753be18e2da12ee3"
|
resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-2.0.7.tgz#72ec37b9c1e00ce0b4e0309d753be18e2da12ee3"
|
||||||
|
@ -1144,11 +1132,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
|
||||||
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
|
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
|
||||||
|
|
||||||
"@types/node@*", "@types/node@^15.12.3":
|
"@types/node@*":
|
||||||
version "15.12.3"
|
version "15.12.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.3.tgz#2817bf5f25bc82f56579018c53f7d41b1830b1af"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.3.tgz#2817bf5f25bc82f56579018c53f7d41b1830b1af"
|
||||||
integrity sha512-SNt65CPCXvGNDZ3bvk1TQ0Qxoe3y1RKH88+wZ2Uf05dduBCqqFQ76ADP9pbT+Cpvj60SkRppMCh2Zo8tDixqjQ==
|
integrity sha512-SNt65CPCXvGNDZ3bvk1TQ0Qxoe3y1RKH88+wZ2Uf05dduBCqqFQ76ADP9pbT+Cpvj60SkRppMCh2Zo8tDixqjQ==
|
||||||
|
|
||||||
|
"@types/node@^15.12.4":
|
||||||
|
version "15.12.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.4.tgz#e1cf817d70a1e118e81922c4ff6683ce9d422e26"
|
||||||
|
integrity sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==
|
||||||
|
|
||||||
"@types/preact-i18n@^2.3.0":
|
"@types/preact-i18n@^2.3.0":
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/preact-i18n/-/preact-i18n-2.3.0.tgz#d99d4a9ad03b0b65e57ed4d874447de74384e32f"
|
resolved "https://registry.yarnpkg.com/@types/preact-i18n/-/preact-i18n-2.3.0.tgz#d99d4a9ad03b0b65e57ed4d874447de74384e32f"
|
||||||
|
@ -1604,11 +1597,6 @@ chalk@^4.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
clone@^2.1.2:
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
|
|
||||||
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
|
|
||||||
|
|
||||||
color-convert@^1.9.0:
|
color-convert@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||||
|
@ -1706,14 +1694,6 @@ csstype@^3.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
||||||
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
||||||
|
|
||||||
d@1, d@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
|
|
||||||
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
|
|
||||||
dependencies:
|
|
||||||
es5-ext "^0.10.50"
|
|
||||||
type "^1.0.1"
|
|
||||||
|
|
||||||
dayjs@^1.10.5:
|
dayjs@^1.10.5:
|
||||||
version "1.10.5"
|
version "1.10.5"
|
||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
||||||
|
@ -1846,42 +1826,6 @@ es-to-primitive@^1.2.1:
|
||||||
is-date-object "^1.0.1"
|
is-date-object "^1.0.1"
|
||||||
is-symbol "^1.0.2"
|
is-symbol "^1.0.2"
|
||||||
|
|
||||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
|
|
||||||
version "0.10.53"
|
|
||||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
|
|
||||||
integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
|
|
||||||
dependencies:
|
|
||||||
es6-iterator "~2.0.3"
|
|
||||||
es6-symbol "~3.1.3"
|
|
||||||
next-tick "~1.0.0"
|
|
||||||
|
|
||||||
es6-iterator@^2.0.3, es6-iterator@~2.0.3:
|
|
||||||
version "2.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
|
||||||
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
|
|
||||||
dependencies:
|
|
||||||
d "1"
|
|
||||||
es5-ext "^0.10.35"
|
|
||||||
es6-symbol "^3.1.1"
|
|
||||||
|
|
||||||
es6-symbol@^3.1.1, es6-symbol@~3.1.3:
|
|
||||||
version "3.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
|
|
||||||
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
|
|
||||||
dependencies:
|
|
||||||
d "^1.0.1"
|
|
||||||
ext "^1.1.2"
|
|
||||||
|
|
||||||
es6-weak-map@^2.0.3:
|
|
||||||
version "2.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53"
|
|
||||||
integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
|
|
||||||
dependencies:
|
|
||||||
d "1"
|
|
||||||
es5-ext "^0.10.46"
|
|
||||||
es6-iterator "^2.0.3"
|
|
||||||
es6-symbol "^3.1.1"
|
|
||||||
|
|
||||||
esbuild@^0.12.5:
|
esbuild@^0.12.5:
|
||||||
version "0.12.9"
|
version "0.12.9"
|
||||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.9.tgz#bed4e7087c286cd81d975631f77d47feb1660070"
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.9.tgz#bed4e7087c286cd81d975631f77d47feb1660070"
|
||||||
|
@ -2087,14 +2031,6 @@ esutils@^2.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||||
|
|
||||||
event-emitter@^0.3.5:
|
|
||||||
version "0.3.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
|
||||||
integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
|
|
||||||
dependencies:
|
|
||||||
d "1"
|
|
||||||
es5-ext "~0.10.14"
|
|
||||||
|
|
||||||
event-stream@=3.3.4:
|
event-stream@=3.3.4:
|
||||||
version "3.3.4"
|
version "3.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
|
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
|
||||||
|
@ -2118,13 +2054,6 @@ exponential-backoff@^3.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.0.tgz#9409c7e579131f8bd4b32d7d8094a911040f2e68"
|
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.0.tgz#9409c7e579131f8bd4b32d7d8094a911040f2e68"
|
||||||
integrity sha512-oBuz5SYz5zzyuHINoe9ooePwSu0xApKWgeNzok4hZ5YKXFh9zrQBEM15CXqoZkJJPuI2ArvqjPQd8UKJA753XA==
|
integrity sha512-oBuz5SYz5zzyuHINoe9ooePwSu0xApKWgeNzok4hZ5YKXFh9zrQBEM15CXqoZkJJPuI2ArvqjPQd8UKJA753XA==
|
||||||
|
|
||||||
ext@^1.1.2:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
|
|
||||||
integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
|
|
||||||
dependencies:
|
|
||||||
type "^2.0.0"
|
|
||||||
|
|
||||||
extend@3.0.2:
|
extend@3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||||
|
@ -2354,6 +2283,11 @@ hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-
|
||||||
dependencies:
|
dependencies:
|
||||||
react-is "^16.7.0"
|
react-is "^16.7.0"
|
||||||
|
|
||||||
|
idb@^6.1.2:
|
||||||
|
version "6.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/idb/-/idb-6.1.2.tgz#82ef5c951b8e1f47875d36ccafa4bedafc62f2f1"
|
||||||
|
integrity sha512-1DNDVu3yDhAZkFDlJf0t7r+GLZ248F5pTAtA7V0oVG3yjmV125qZOx3g0XpAEkGZVYQiFDAsSOnGet2bhugc3w==
|
||||||
|
|
||||||
ignore@^4.0.6:
|
ignore@^4.0.6:
|
||||||
version "4.0.6"
|
version "4.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||||
|
@ -2482,11 +2416,6 @@ is-obj@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||||
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
|
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
|
||||||
|
|
||||||
is-promise@^2.2.2:
|
|
||||||
version "2.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
|
|
||||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
|
||||||
|
|
||||||
is-regex@^1.1.3:
|
is-regex@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
|
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
|
||||||
|
@ -2696,13 +2625,6 @@ lru-cache@^6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
lru-queue@^0.1.0:
|
|
||||||
version "0.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
|
|
||||||
integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=
|
|
||||||
dependencies:
|
|
||||||
es5-ext "~0.10.2"
|
|
||||||
|
|
||||||
magic-string@^0.25.0, magic-string@^0.25.7:
|
magic-string@^0.25.0, magic-string@^0.25.7:
|
||||||
version "0.25.7"
|
version "0.25.7"
|
||||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||||
|
@ -2715,20 +2637,6 @@ map-stream@~0.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
|
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
|
||||||
integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=
|
integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=
|
||||||
|
|
||||||
memoizee@^0.4.15:
|
|
||||||
version "0.4.15"
|
|
||||||
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72"
|
|
||||||
integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==
|
|
||||||
dependencies:
|
|
||||||
d "^1.0.1"
|
|
||||||
es5-ext "^0.10.53"
|
|
||||||
es6-weak-map "^2.0.3"
|
|
||||||
event-emitter "^0.3.5"
|
|
||||||
is-promise "^2.2.2"
|
|
||||||
lru-queue "^0.1.0"
|
|
||||||
next-tick "^1.1.0"
|
|
||||||
timers-ext "^0.1.7"
|
|
||||||
|
|
||||||
merge-stream@^2.0.0:
|
merge-stream@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||||
|
@ -2787,16 +2695,6 @@ natural-compare@^1.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
next-tick@1, next-tick@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
|
|
||||||
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
|
|
||||||
|
|
||||||
next-tick@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
|
||||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
|
||||||
|
|
||||||
node-cleanup@^2.1.2:
|
node-cleanup@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
|
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
|
||||||
|
@ -2817,11 +2715,6 @@ object-assign@^4.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
|
||||||
object-hash@^2.1.1:
|
|
||||||
version "2.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5"
|
|
||||||
integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==
|
|
||||||
|
|
||||||
object-inspect@^1.10.3, object-inspect@^1.9.0:
|
object-inspect@^1.10.3, object-inspect@^1.9.0:
|
||||||
version "1.10.3"
|
version "1.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
|
||||||
|
@ -3032,11 +2925,6 @@ punycode@^2.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
|
||||||
q@^1.5.1:
|
|
||||||
version "1.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
|
||||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
|
||||||
|
|
||||||
queue-microtask@^1.2.2:
|
queue-microtask@^1.2.2:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
|
@ -3243,13 +3131,12 @@ reusify@^1.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
revolt.js@4.2.0-alpha.3-patch.0:
|
revolt.js@4.3.0:
|
||||||
version "4.2.0-alpha.3-patch.0"
|
version "4.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.2.0-alpha.3-patch.0.tgz#ca79731c2b2fa9a8dbfbc5c9f84bef6ee2759918"
|
resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.0.tgz#dc396470da82dd58eac74150ed9e3d64f67c28db"
|
||||||
integrity sha512-g4eXHDbQyjKEiDOjj+3BxbRwPuVfOCYsnVqOiOXoAib4k48c27N+ZU0apYV25/AzCvIoYGDtVfY3I33UkTl1Rw==
|
integrity sha512-QFD0KQMk6e6bOioZJSSSnzgtx76yJLFSp9LyM1fIIelP02vrMpU1wO7s89lE+7jljh7SVgJqyCfZmlshdyb7Ew==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@insertish/mutable" "1.0.6"
|
"@insertish/mutable" "1.1.0"
|
||||||
"@insertish/zangodb" "1.0.12"
|
|
||||||
axios "^0.19.2"
|
axios "^0.19.2"
|
||||||
eventemitter3 "^4.0.7"
|
eventemitter3 "^4.0.7"
|
||||||
exponential-backoff "^3.1.0"
|
exponential-backoff "^3.1.0"
|
||||||
|
@ -3586,14 +3473,6 @@ through@2, through@~2.3, through@~2.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||||
|
|
||||||
timers-ext@^0.1.7:
|
|
||||||
version "0.1.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
|
|
||||||
integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==
|
|
||||||
dependencies:
|
|
||||||
es5-ext "~0.10.46"
|
|
||||||
next-tick "1"
|
|
||||||
|
|
||||||
tiny-invariant@^1.0.2:
|
tiny-invariant@^1.0.2:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
||||||
|
@ -3663,16 +3542,6 @@ type-fest@^0.20.2:
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||||
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
||||||
|
|
||||||
type@^1.0.1:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
|
|
||||||
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
|
|
||||||
|
|
||||||
type@^2.0.0:
|
|
||||||
version "2.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d"
|
|
||||||
integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
|
|
||||||
|
|
||||||
typescript@^4.3.2:
|
typescript@^4.3.2:
|
||||||
version "4.3.3"
|
version "4.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.3.tgz#5401db69bd3203daf1851a1a74d199cb3112c11a"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.3.tgz#5401db69bd3203daf1851a1a74d199cb3112c11a"
|
||||||
|
|
Loading…
Reference in a new issue