diff --git a/package.json b/package.json index 4a1c4419..7c9c9d87 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ } }, "dependencies": { - "preact": "^10.5.13" + "preact": "^10.5.13", + "revolt-api": "0.5.1-alpha.10-patch.0" }, "devDependencies": { "@fontsource/atkinson-hyperlegible": "^4.4.5", @@ -96,7 +97,7 @@ "react-router-dom": "^5.2.0", "react-scroll": "^1.8.2", "redux": "^4.1.0", - "revolt.js": "4.4.0-alpha.0", + "revolt.js": "5.0.0-alpha.5", "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", diff --git a/src/components/common/AgeGate.tsx b/src/components/common/AgeGate.tsx index adfb365d..03071212 100644 --- a/src/components/common/AgeGate.tsx +++ b/src/components/common/AgeGate.tsx @@ -1,11 +1,11 @@ import { observer } from "mobx-react-lite"; import { useHistory } from "react-router-dom"; +import { Channel } from "revolt.js/dist/maps/Channels"; import styled from "styled-components"; import { Text } from "preact-i18n"; import { useState } from "preact/hooks"; -import { Channel } from "../../mobx"; import { dispatch, getState } from "../../redux"; import Button from "../ui/Button"; diff --git a/src/components/common/AutoComplete.tsx b/src/components/common/AutoComplete.tsx index e457cbf8..28fecbf8 100644 --- a/src/components/common/AutoComplete.tsx +++ b/src/components/common/AutoComplete.tsx @@ -1,13 +1,11 @@ import { useStore } from "react-redux"; import { SYSTEM_USER_ID } from "revolt.js"; -import { Channels } from "revolt.js/dist/api/objects"; +import { Channel } from "revolt.js/dist/maps/Channels"; +import { User } from "revolt.js/dist/maps/Users"; import styled, { css } from "styled-components"; import { StateUpdater, useState } from "preact/hooks"; -import { Channel, User } from "../../mobx"; -import { useData } from "../../mobx/State"; - import { useClient } from "../../context/revoltjs/RevoltClient"; import { emojiDictionary } from "../../assets/emojis"; @@ -57,7 +55,6 @@ export function useAutoComplete( const [state, setState] = useState({ type: "none" }); const [focused, setFocused] = useState(false); const client = useClient(); - const store = useData(); function findSearchString( el: HTMLTextAreaElement, @@ -132,7 +129,7 @@ export function useAutoComplete( let users: User[] = []; switch (searchClues.users.type) { case "all": - users = [...store.users.values()]; + users = [...client.users.values()]; break; case "channel": { const channel = client.channels.get( @@ -141,22 +138,15 @@ export function useAutoComplete( switch (channel?.channel_type) { case "Group": case "DirectMessage": - users = channel.recipients - .map((x) => store.users.get(x)) - .filter( - (x) => typeof x !== "undefined", - ) as User[]; + users = channel.recipients!.filter( + (x) => typeof x !== "undefined", + ) as User[]; break; case "TextChannel": - const server = channel.server; - users = client.members - .toArray() - .filter( - (x) => x._id.substr(0, 26) === server, - ) - .map((x) => - store.users.get(x._id.substr(26)), - ) + const server = channel.server_id; + users = [...client.members.keys()] + .filter((x) => x.server === server) + .map((x) => client.users.get(x.user)) .filter( (x) => typeof x !== "undefined", ) as User[]; @@ -197,7 +187,7 @@ export function useAutoComplete( if (type === "channel" && searchClues?.channels) { const channels = client.servers .get(searchClues.channels.server) - ?.channels.map((x) => store.channels.get(x)) + ?.channels.map((x) => client.channels.get(x)) .filter((x) => typeof x !== "undefined") as Channel[]; const matches = ( diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 54099c66..ae914240 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -1,15 +1,14 @@ import { observer } from "mobx-react-lite"; +import { Message as MessageObject } from "revolt.js/dist/maps/Messages"; import { attachContextMenu } from "preact-context-menu"; import { memo } from "preact/compat"; -import { useContext, useState } from "preact/hooks"; +import { useState } from "preact/hooks"; -import { useData } from "../../../mobx/State"; import { QueuedMessage } from "../../../redux/reducers/queue"; import { useIntermediate } from "../../../context/intermediate/Intermediate"; -import { AppContext } from "../../../context/revoltjs/RevoltClient"; -import { MessageObject } from "../../../context/revoltjs/util"; +import { useClient } from "../../../context/revoltjs/RevoltClient"; import Overline from "../../ui/Overline"; @@ -46,15 +45,14 @@ const Message = observer( head: preferHead, queued, }: Props) => { - const store = useData(); - const user = store.users.get(message.author); + const client = useClient(); + const user = message.author; - const client = useContext(AppContext); const { openScreen } = useIntermediate(); const content = message.content as string; const head = - preferHead || (message.replies && message.replies.length > 0); + preferHead || (message.reply_ids && message.reply_ids.length > 0); // ! FIXME: tell fatal to make this type generic // bree: Fatal please... @@ -66,28 +64,33 @@ const Message = observer( : undefined; const openProfile = () => - openScreen({ id: "profile", user_id: message.author }); + openScreen({ id: "profile", user_id: message.author_id }); // ! FIXME: animate on hover const [animate, setAnimate] = useState(false); return (
- {message.replies?.map((message_id, index) => ( + {message.reply_ids?.map((message_id, index) => ( ))} 0) + (head && + !( + message.reply_ids && + message.reply_ids.length > 0 + )) ?? + false } contrast={contrast} sending={typeof queued !== "undefined"} - mention={message.mentions?.includes(client.user!._id)} + mention={message.mention_ids?.includes(client.user!._id)} failed={typeof queued?.error !== "undefined"} onContextMenu={ attachContext diff --git a/src/components/common/messaging/attachments/MessageReply.tsx b/src/components/common/messaging/attachments/MessageReply.tsx index dcf35178..9285fdcb 100644 --- a/src/components/common/messaging/attachments/MessageReply.tsx +++ b/src/components/common/messaging/attachments/MessageReply.tsx @@ -2,8 +2,10 @@ import { Reply } from "@styled-icons/boxicons-regular"; import { File } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; import { useHistory } from "react-router-dom"; +import { RelationshipStatus } from "revolt-api/types/Users"; import { SYSTEM_USER_ID } from "revolt.js"; -import { Users } from "revolt.js/dist/api/objects"; +import { Channel } from "revolt.js/dist/maps/Channels"; +import { Message } from "revolt.js/dist/maps/Messages"; import styled, { css } from "styled-components"; import { Text } from "preact-i18n"; @@ -11,17 +13,14 @@ import { useLayoutEffect, useState } from "preact/hooks"; import { useRenderState } from "../../../../lib/renderer/Singleton"; -import { useData } from "../../../../mobx/State"; - import { useClient } from "../../../../context/revoltjs/RevoltClient"; -import { mapMessage, MessageObject } from "../../../../context/revoltjs/util"; import Markdown from "../../../markdown/Markdown"; import UserShort from "../../user/UserShort"; import { SystemMessage } from "../SystemMessage"; interface Props { - channel: string; + channel: Channel; index: number; id: string; } @@ -124,13 +123,11 @@ export const ReplyBase = styled.div<{ `; export const MessageReply = observer(({ index, channel, id }: Props) => { - const client = useClient(); - const view = useRenderState(channel); + const view = useRenderState(channel._id); if (view?.type !== "RENDER") return null; - const [message, setMessage] = useState( - undefined, - ); + const [message, setMessage] = useState(undefined); + useLayoutEffect(() => { // ! FIXME: We should do this through the message renderer, so it can fetch it from cache if applicable. const m = view.messages.find((x) => x._id === id); @@ -138,9 +135,7 @@ export const MessageReply = observer(({ index, channel, id }: Props) => { if (m) { setMessage(m); } else { - client.channels - .fetchMessage(channel, id) - .then((m) => setMessage(mapMessage(m))); + channel.fetchMessage(id).then(setMessage); } }, [view.messages]); @@ -155,33 +150,32 @@ export const MessageReply = observer(({ index, channel, id }: Props) => { ); } - const store = useData(); - const user = store.users.get(message.author); const history = useHistory(); return ( - {user?.relationship === Users.Relationship.Blocked ? ( + {message.author?.relationship === RelationshipStatus.Blocked ? ( <> ) : ( <> - {message.author === SYSTEM_USER_ID ? ( + {message.author_id === SYSTEM_USER_ID ? ( ) : ( <>
- +
{ - const obj = client.channels.get(channel); - if (obj?.channel_type === "TextChannel") { + if ( + channel.channel_type === "TextChannel" + ) { history.push( - `/server/${obj.server}/channel/${obj._id}/${message._id}`, + `/server/${channel.server}/channel/${channel._id}/${message._id}`, ); } else { history.push( diff --git a/src/context/intermediate/Intermediate.tsx b/src/context/intermediate/Intermediate.tsx index f73cbae2..d472b09b 100644 --- a/src/context/intermediate/Intermediate.tsx +++ b/src/context/intermediate/Intermediate.tsx @@ -1,20 +1,17 @@ import { Prompt } from "react-router"; import { useHistory } from "react-router-dom"; -import { - Attachment, - Channels, - EmbedImage, - Servers, - Users, -} from "revolt.js/dist/api/objects"; +import type { Attachment } from "revolt-api/types/Autumn"; +import type { EmbedImage } from "revolt-api/types/January"; +import { Channel } from "revolt.js/dist/maps/Channels"; +import { Message } from "revolt.js/dist/maps/Messages"; +import { Server } from "revolt.js/dist/maps/Servers"; +import { User } from "revolt.js/dist/maps/Users"; import { createContext } from "preact"; import { useContext, useEffect, useMemo, useState } from "preact/hooks"; import { internalSubscribe } from "../../lib/eventEmitter"; -import { Channel, Server, User } from "../../mobx"; - import { Action } from "../../components/ui/Modal"; import { Children } from "../../types/Preact"; @@ -39,7 +36,7 @@ export type Screen = | { type: "leave_server"; target: Server } | { type: "delete_server"; target: Server } | { type: "delete_channel"; target: Channel } - | { type: "delete_message"; target: Channels.Message } + | { type: "delete_message"; target: Message } | { type: "create_invite"; target: Channel; diff --git a/src/context/revoltjs/util.tsx b/src/context/revoltjs/util.tsx index 439dbf62..5e259286 100644 --- a/src/context/revoltjs/util.tsx +++ b/src/context/revoltjs/util.tsx @@ -1,10 +1,8 @@ import { Client } from "revolt.js"; -import { Message } from "revolt.js/dist/api/objects"; +import { Channel } from "revolt.js/dist/maps/Channels"; import { Text } from "preact-i18n"; -import { Channel } from "../../mobx"; - import { Children } from "../../types/Preact"; export function takeError(error: any): string { @@ -25,7 +23,6 @@ export function takeError(error: any): string { } export function getChannelName( - client: Client, channel: Channel, prefixType?: boolean, ): Children { @@ -33,11 +30,10 @@ export function getChannelName( return ; if (channel.channel_type === "DirectMessage") { - const uid = client.channels.getRecipient(channel._id); return ( <> {prefixType && "@"} - {client.users.get(uid)?.username} + {channel.recipient!.username} ); } @@ -48,12 +44,3 @@ export function getChannelName( return <>{channel.name}; } - -export type MessageObject = Omit & { edited?: string }; -export function mapMessage(message: Partial) { - const { edited, ...msg } = message; - return { - ...msg, - edited: edited?.$date, - } as MessageObject; -} diff --git a/src/mobx/State.tsx b/src/mobx/State.tsx deleted file mode 100644 index 8c491ed8..00000000 --- a/src/mobx/State.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"; - -import { createContext } from "preact"; -import { useContext, useEffect, useState } from "preact/hooks"; - -import { useClient } from "../context/revoltjs/RevoltClient"; - -import { DataStore } from "."; -import { Children } from "../types/Preact"; - -interface Props { - children: Children; -} - -export const DataContext = createContext(null!); - -// ! later we can do seamless account switching, by hooking this into Redux -// ! and monitoring changes to active account and hence swapping stores. -// although this may need more work since we need a Client per account too. - -export default function StateLoader(props: Props) { - const client = useClient(); - const [store] = useState(new DataStore(client)); - - useEffect(() => { - const packet = (packet: ClientboundNotification) => - store.packet(packet); - client.addListener("packet", packet); - return () => client.removeListener("packet", packet); - }, [client]); - - return ( - - {props.children} - - ); -} - -export const useData = () => useContext(DataContext); diff --git a/src/mobx/index.ts b/src/mobx/index.ts deleted file mode 100644 index c5535ecc..00000000 --- a/src/mobx/index.ts +++ /dev/null @@ -1,443 +0,0 @@ -import isEqual from "lodash.isequal"; -import { - makeAutoObservable, - observable, - autorun, - runInAction, - reaction, - makeObservable, - action, - extendObservable, -} from "mobx"; -import { Client } from "revolt.js"; -import { - Attachment, - Channels, - Servers, - Users, -} from "revolt.js/dist/api/objects"; -import { - RemoveChannelField, - RemoveMemberField, - RemoveServerField, - RemoveUserField, -} from "revolt.js/dist/api/routes"; -import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"; - -type Nullable = T | null; -function toNullable(data?: T) { - return typeof data === "undefined" ? null : data; -} - -export class User { - _id: string; - username: string; - - avatar: Nullable; - badges: Nullable; - status: Nullable; - relationship: Nullable; - online: Nullable; - - constructor(data: Users.User) { - this._id = data._id; - this.username = data.username; - - this.avatar = toNullable(data.avatar); - this.badges = toNullable(data.badges); - this.status = toNullable(data.status); - this.relationship = toNullable(data.relationship); - this.online = toNullable(data.online); - - makeAutoObservable(this); - } - - @action update(data: Partial, clear?: RemoveUserField) { - const apply = (key: string) => { - // This code has been tested. - // @ts-expect-error - if (data[key] && !isEqual(this[key], data[key])) { - // @ts-expect-error - this[key] = data[key]; - } - }; - - switch (clear) { - case "Avatar": - this.avatar = null; - break; - case "StatusText": { - if (this.status) { - this.status.text = undefined; - } - } - } - - apply("username"); - apply("avatar"); - apply("badges"); - apply("status"); - apply("relationship"); - apply("online"); - } - - @action setRelationship(relationship: Users.Relationship) { - this.relationship = relationship; - } -} - -export class Channel { - _id: string; - channel_type: Channels.Channel["channel_type"]; - - // Direct Message - active: Nullable = null; - - // Group - owner: Nullable = null; - - // Server - server: Nullable = null; - - // Permissions - permissions: Nullable = null; - default_permissions: Nullable = null; - role_permissions: Nullable<{ [key: string]: number }> = null; - - // Common - name: Nullable = null; - icon: Nullable = null; - description: Nullable = null; - recipients: Nullable = null; - last_message: Nullable = null; - - constructor(data: Channels.Channel) { - this._id = data._id; - this.channel_type = data.channel_type; - - switch (data.channel_type) { - case "DirectMessage": { - this.active = toNullable(data.active); - this.recipients = toNullable(data.recipients); - this.last_message = toNullable(data.last_message); - break; - } - case "Group": { - this.recipients = toNullable(data.recipients); - this.name = toNullable(data.name); - this.owner = toNullable(data.owner); - this.description = toNullable(data.description); - this.last_message = toNullable(data.last_message); - this.icon = toNullable(data.icon); - this.permissions = toNullable(data.permissions); - break; - } - case "TextChannel": - case "VoiceChannel": { - this.server = toNullable(data.server); - this.name = toNullable(data.name); - this.description = toNullable(data.description); - this.icon = toNullable(data.icon); - this.default_permissions = toNullable(data.default_permissions); - this.role_permissions = toNullable(data.role_permissions); - - if (data.channel_type === "TextChannel") { - this.last_message = toNullable(data.last_message); - } - - break; - } - } - - makeAutoObservable(this); - } - - @action update( - data: Partial, - clear?: RemoveChannelField, - ) { - const apply = (key: string) => { - // This code has been tested. - // @ts-expect-error - if (data[key] && !isEqual(this[key], data[key])) { - // @ts-expect-error - this[key] = data[key]; - } - }; - - switch (clear) { - case "Description": - this.description = null; - break; - case "Icon": - this.icon = null; - break; - } - - apply("active"); - apply("owner"); - apply("permissions"); - apply("default_permissions"); - apply("role_permissions"); - apply("name"); - apply("icon"); - apply("description"); - apply("recipients"); - apply("last_message"); - } - - @action groupJoin(user: string) { - this.recipients?.push(user); - } - - @action groupLeave(user: string) { - this.recipients = toNullable( - this.recipients?.filter((x) => x !== user), - ); - } -} - -export class Server { - _id: string; - owner: string; - name: string; - description: Nullable = null; - - channels: string[] = []; - categories: Nullable = null; - system_messages: Nullable = null; - - roles: Nullable<{ [key: string]: Servers.Role }> = null; - default_permissions: Servers.PermissionTuple; - - icon: Nullable = null; - banner: Nullable = null; - - constructor(data: Servers.Server) { - this._id = data._id; - this.owner = data.owner; - this.name = data.name; - this.description = toNullable(data.description); - - this.channels = data.channels; - this.categories = toNullable(data.categories); - this.system_messages = toNullable(data.system_messages); - - this.roles = toNullable(data.roles); - this.default_permissions = data.default_permissions; - - this.icon = toNullable(data.icon); - this.banner = toNullable(data.banner); - - makeAutoObservable(this); - } - - @action update(data: Partial, clear?: RemoveServerField) { - const apply = (key: string) => { - // This code has been tested. - // @ts-expect-error - if (data[key] && !isEqual(this[key], data[key])) { - // @ts-expect-error - this[key] = data[key]; - } - }; - - switch (clear) { - case "Banner": - this.banner = null; - break; - case "Description": - this.description = null; - break; - case "Icon": - this.icon = null; - break; - } - - apply("owner"); - apply("name"); - apply("description"); - apply("channels"); - apply("categories"); - apply("system_messages"); - apply("roles"); - apply("default_permissions"); - apply("icon"); - apply("banner"); - } -} - -export class Member { - _id: Servers.MemberCompositeKey; - nickname: Nullable = null; - avatar: Nullable = null; - roles: Nullable = null; - - constructor(data: Servers.Member) { - this._id = data._id; - this.nickname = toNullable(data.nickname); - this.avatar = toNullable(data.avatar); - this.roles = toNullable(data.roles); - - makeAutoObservable(this); - } - - @action update(data: Partial, clear?: RemoveMemberField) { - const apply = (key: string) => { - // This code has been tested. - // @ts-expect-error - if (data[key] && !isEqual(this[key], data[key])) { - // @ts-expect-error - this[key] = data[key]; - } - }; - - switch (clear) { - case "Nickname": - this.nickname = null; - break; - case "Avatar": - this.avatar = null; - break; - } - - apply("nickname"); - apply("avatar"); - apply("roles"); - } -} - -export class DataStore { - client: Client; - - @observable users = new Map(); - @observable channels = new Map(); - @observable servers = new Map(); - @observable members = new Map(); - - constructor(client: Client) { - makeAutoObservable(this, undefined, { proxy: false }); - this.client = client; - } - - @action - async packet(packet: ClientboundNotification) { - switch (packet.type) { - case "Ready": { - for (let user of packet.users) { - this.users.set(user._id, new User(user)); - } - - for (let channel of packet.channels) { - this.channels.set(channel._id, new Channel(channel)); - } - - for (let server of packet.servers) { - this.servers.set(server._id, new Server(server)); - } - - break; - } - case "ChannelCreate": { - this.channels.set(packet._id, new Channel(packet)); - break; - } - case "ChannelUpdate": { - this.channels.get(packet.id)?.update(packet.data, packet.clear); - break; - } - case "ChannelDelete": { - this.channels.delete(packet.id); - break; - } - case "ChannelGroupJoin": { - this.channels.get(packet.id)?.groupJoin(packet.user); - - if (!this.users.has(packet.user)) { - let user = await this.client.users.fetch(packet.user); - this.users.set(packet.user, new User(user)); - } - - break; - } - case "ChannelGroupLeave": { - this.channels.get(packet.id)?.groupJoin(packet.user); - break; - } - case "UserUpdate": { - this.users.get(packet.id)?.update(packet.data, packet.clear); - break; - } - case "UserRelationship": { - if (!this.users.has(packet.user._id)) { - this.users.set(packet.user._id, new User(packet.user)); - } - - this.users.get(packet.user._id)?.setRelationship(packet.status); - break; - } - case "ServerUpdate": { - this.servers.get(packet.id)?.update(packet.data, packet.clear); - break; - } - case "ServerDelete": { - let server = this.servers.get(packet.id); - if (server) { - for (let channel of server.channels) { - this.channels.delete(channel); - } - } - - this.servers.delete(packet.id); - break; - } - case "ServerMemberUpdate": { - this.members.get(packet.id)?.update(packet.data, packet.clear); - break; - } - case "ServerMemberJoin": { - const _id = { server: packet.id, user: packet.user }; - this.members.set(_id, new Member({ _id })); - - if (!this.servers.has(packet.id)) { - let server = await this.client.servers.fetch(packet.id); - this.servers.set(packet.id, new Server(server)); - - for (let id of server.channels) { - let channel = this.client.channels.get(id); - if (channel) { - this.channels.set(id, new Channel(channel)); - } - } - } - - if (!this.users.has(packet.user)) { - let user = await this.client.users.fetch(packet.user); - this.users.set(packet.user, new User(user)); - } - - break; - } - case "ServerMemberLeave": { - this.members.delete({ server: packet.id, user: packet.user }); - if (packet.user === this.client.user!._id) { - await this.packet({ type: "ServerDelete", id: packet.id }); - } - - break; - } - } - } - - async fetchMembers(server: string) { - let res = await this.client.members.fetchMembers(server); - - for (let user of res.users) { - if (!this.users.has(user._id)) { - this.users.set(user._id, new User(user)); - } - } - - return res.members; - } -} diff --git a/src/pages/friends/Friend.tsx b/src/pages/friends/Friend.tsx index 1b3f458c..38ec535f 100644 --- a/src/pages/friends/Friend.tsx +++ b/src/pages/friends/Friend.tsx @@ -1,7 +1,8 @@ import { X, Plus } from "@styled-icons/boxicons-regular"; import { PhoneCall, Envelope, UserX } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; -import { Users } from "revolt.js/dist/api/objects"; +import { RelationshipStatus } from "revolt-api/types/Users"; +import { User } from "revolt.js/dist/maps/Users"; import styles from "./Friend.module.scss"; import classNames from "classnames"; @@ -11,8 +12,6 @@ import { useContext } from "preact/hooks"; import { stopPropagation } from "../../lib/stopPropagation"; -import { User } from "../../mobx"; - import { VoiceOperationsContext } from "../../context/Voice"; import { useIntermediate } from "../../context/intermediate/Intermediate"; import { @@ -39,7 +38,7 @@ export const Friend = observer(({ user }: Props) => { const actions: Children[] = []; let subtext: Children = null; - if (user.relationship === Users.Relationship.Friend) { + if (user.relationship === RelationshipStatus.Friend) { subtext = ; actions.push( <> @@ -61,14 +60,12 @@ export const Friend = observer(({ user }: Props) => { ); } - if (user.relationship === Users.Relationship.Incoming) { + if (user.relationship === RelationshipStatus.Incoming) { actions.push( - stopPropagation(ev, client.users.addFriend(user.username)) - }> + onClick={(ev) => stopPropagation(ev, user.addFriend())}> , ); @@ -76,14 +73,14 @@ export const Friend = observer(({ user }: Props) => { subtext = ; } - if (user.relationship === Users.Relationship.Outgoing) { + if (user.relationship === RelationshipStatus.Outgoing) { subtext = ; } if ( - user.relationship === Users.Relationship.Friend || - user.relationship === Users.Relationship.Outgoing || - user.relationship === Users.Relationship.Incoming + user.relationship === RelationshipStatus.Friend || + user.relationship === RelationshipStatus.Outgoing || + user.relationship === RelationshipStatus.Incoming ) { actions.push( { onClick={(ev) => stopPropagation( ev, - user.relationship === Users.Relationship.Friend + user.relationship === RelationshipStatus.Friend ? openScreen({ id: "special_prompt", type: "unfriend_user", target: user, }) - : client.users.removeFriend(user._id), + : user.removeFriend(), ) }> @@ -110,14 +107,12 @@ export const Friend = observer(({ user }: Props) => { ); } - if (user.relationship === Users.Relationship.Blocked) { + if (user.relationship === RelationshipStatus.Blocked) { actions.push( - stopPropagation(ev, client.users.unblockUser(user._id)) - }> + onClick={(ev) => stopPropagation(ev, user.unblockUser())}> , ); diff --git a/src/pages/friends/Friends.tsx b/src/pages/friends/Friends.tsx index 4b63d8f3..d33ef1b2 100644 --- a/src/pages/friends/Friends.tsx +++ b/src/pages/friends/Friends.tsx @@ -5,7 +5,8 @@ import { } from "@styled-icons/boxicons-regular"; import { UserDetail, MessageAdd, UserPlus } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; -import { Users } from "revolt.js/dist/api/objects"; +import { RelationshipStatus, Presence } from "revolt-api/types/Users"; +import { User } from "revolt.js/dist/maps/Users"; import styles from "./Friend.module.scss"; import { Text } from "preact-i18n"; @@ -13,10 +14,8 @@ import { Text } from "preact-i18n"; import { TextReact } from "../../lib/i18n"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; -import { User } from "../../mobx"; -import { useData } from "../../mobx/State"; - import { useIntermediate } from "../../context/intermediate/Intermediate"; +import { useClient } from "../../context/revoltjs/RevoltClient"; import CollapsibleSection from "../../components/common/CollapsibleSection"; import Tooltip from "../../components/common/Tooltip"; @@ -30,43 +29,40 @@ import { Friend } from "./Friend"; export default observer(() => { const { openScreen } = useIntermediate(); - const store = useData(); - const users = [...store.users.values()]; + const client = useClient(); + const users = [...client.users.values()]; users.sort((a, b) => a.username.localeCompare(b.username)); const friends = users.filter( - (x) => x.relationship === Users.Relationship.Friend, + (x) => x.relationship === RelationshipStatus.Friend, ); const lists = [ [ "", - users.filter((x) => x.relationship === Users.Relationship.Incoming), + users.filter((x) => x.relationship === RelationshipStatus.Incoming), ], [ "app.special.friends.sent", - users.filter((x) => x.relationship === Users.Relationship.Outgoing), + users.filter((x) => x.relationship === RelationshipStatus.Outgoing), "outgoing", ], [ "app.status.online", friends.filter( - (x) => - x.online && x.status?.presence !== Users.Presence.Invisible, + (x) => x.online && x.status?.presence !== Presence.Invisible, ), "online", ], [ "app.status.offline", friends.filter( - (x) => - !x.online || - x.status?.presence === Users.Presence.Invisible, + (x) => !x.online || x.status?.presence === Presence.Invisible, ), "offline", ], [ "app.special.friends.blocked", - users.filter((x) => x.relationship === Users.Relationship.Blocked), + users.filter((x) => x.relationship === RelationshipStatus.Blocked), "blocked", ], ] as [string, User[], string][]; diff --git a/src/pages/invite/Invite.tsx b/src/pages/invite/Invite.tsx index d8949320..056a464a 100644 --- a/src/pages/invite/Invite.tsx +++ b/src/pages/invite/Invite.tsx @@ -1,16 +1,13 @@ import { ArrowBack } from "@styled-icons/boxicons-regular"; import { autorun } from "mobx"; -import { useStore } from "react-redux"; import { useHistory, useParams } from "react-router-dom"; -import { Invites, Servers } from "revolt.js/dist/api/objects"; +import { RetrievedInvite } from "revolt-api/types/Invites"; import styles from "./Invite.module.scss"; import { useContext, useEffect, useState } from "preact/hooks"; import { defer } from "../../lib/defer"; -import { useData } from "../../mobx/State"; - import RequiresOnline from "../../context/revoltjs/RequiresOnline"; import { AppContext, @@ -26,14 +23,13 @@ import Overline from "../../components/ui/Overline"; import Preloader from "../../components/ui/Preloader"; export default function Invite() { - const store = useData(); const history = useHistory(); const client = useContext(AppContext); const status = useContext(StatusContext); const { code } = useParams<{ code: string }>(); const [processing, setProcessing] = useState(false); const [error, setError] = useState(undefined); - const [invite, setInvite] = useState( + const [invite, setInvite] = useState( undefined, ); @@ -122,7 +118,7 @@ export default function Invite() { } const dispose = autorun(() => { - let server = store.servers.get( + let server = client.servers.get( invite.server_id, ); diff --git a/src/pages/settings/ChannelSettings.tsx b/src/pages/settings/ChannelSettings.tsx index 79015adb..1cd7fecc 100644 --- a/src/pages/settings/ChannelSettings.tsx +++ b/src/pages/settings/ChannelSettings.tsx @@ -3,8 +3,6 @@ import { Route, useHistory, useParams } from "react-router-dom"; import { Text } from "preact-i18n"; -import { useData } from "../../mobx/State"; - import { useClient } from "../../context/revoltjs/RevoltClient"; import { getChannelName } from "../../context/revoltjs/util"; @@ -17,9 +15,8 @@ import Permissions from "./channel/Permissions"; export default function ChannelSettings() { const { channel: cid } = useParams<{ channel: string }>(); - const store = useData(); const client = useClient(); - const channel = store.channels.get(cid); + const channel = client.channels.get(cid); if (!channel) return null; if ( channel.channel_type === "SavedMessages" || @@ -53,7 +50,7 @@ export default function ChannelSettings() { category: ( ), id: "overview", diff --git a/src/pages/settings/ServerSettings.tsx b/src/pages/settings/ServerSettings.tsx index 98027cfe..d9fb474a 100644 --- a/src/pages/settings/ServerSettings.tsx +++ b/src/pages/settings/ServerSettings.tsx @@ -1,10 +1,12 @@ import { ListUl, ListCheck, ListMinus } from "@styled-icons/boxicons-regular"; import { XSquare, Share, Group } from "@styled-icons/boxicons-solid"; +import { observer } from "mobx-react-lite"; import { Route, useHistory, useParams } from "react-router-dom"; import { Text } from "preact-i18n"; import RequiresOnline from "../../context/revoltjs/RequiresOnline"; +import { useClient } from "../../context/revoltjs/RevoltClient"; import Category from "../../components/ui/Category"; @@ -15,12 +17,11 @@ import { Invites } from "./server/Invites"; import { Members } from "./server/Members"; import { Overview } from "./server/Overview"; import { Roles } from "./server/Roles"; -import { useData } from "../../mobx/State"; -export default function ServerSettings() { +export default observer(() => { const { server: sid } = useParams<{ server: string }>(); - const store = useData(); - const server = store.servers.get(sid); + const client = useClient(); + const server = client.servers.get(sid); if (!server) return null; const history = useHistory(); @@ -36,7 +37,7 @@ export default function ServerSettings() { , //TOFIX: Just add the server.name as a string, otherwise it makes a duplicate category + category: , id: "overview", icon: , title: ( @@ -110,4 +111,4 @@ export default function ServerSettings() { showExitButton /> ); -} +}); diff --git a/src/pages/settings/channel/Overview.tsx b/src/pages/settings/channel/Overview.tsx index cf1da074..cc8166d0 100644 --- a/src/pages/settings/channel/Overview.tsx +++ b/src/pages/settings/channel/Overview.tsx @@ -1,5 +1,5 @@ import { observer } from "mobx-react-lite"; -import { Channels } from "revolt.js/dist/api/objects"; +import { Channel } from "revolt.js/dist/maps/Channels"; import styled, { css } from "styled-components"; import { Text } from "preact-i18n"; @@ -7,8 +7,6 @@ import { useContext, useEffect, useState } from "preact/hooks"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; -import { Channel } from "../../../mobx"; - import { FileUploader } from "../../../context/revoltjs/FileUploads"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; @@ -51,7 +49,7 @@ export default observer(({ channel }: Props) => { if (description !== channel.description) changes.description = description; - client.channels.edit(channel._id, changes); + channel.edit(changes); setChanged(false); } @@ -65,17 +63,12 @@ export default observer(({ channel }: Props) => { fileType="icons" behaviour="upload" maxFileSize={2_500_000} - onUpload={(icon) => - client.channels.edit(channel._id, { icon }) - } - previewURL={client.channels.getIconURL( - channel._id, + onUpload={(icon) => channel.edit({ icon })} + previewURL={channel.generateIconURL( { max_side: 256 }, true, )} - remove={() => - client.channels.edit(channel._id, { remove: "Icon" }) - } + remove={() => channel.edit({ remove: "Icon" })} defaultPreview={ channel.channel_type === "Group" ? "/assets/group.png" diff --git a/src/pages/settings/channel/Permissions.tsx b/src/pages/settings/channel/Permissions.tsx index ba64a70e..54d67053 100644 --- a/src/pages/settings/channel/Permissions.tsx +++ b/src/pages/settings/channel/Permissions.tsx @@ -1,13 +1,10 @@ import { observer } from "mobx-react-lite"; -import { Channels } from "revolt.js/dist/api/objects"; import { ChannelPermission } from "revolt.js/dist/api/permissions"; +import { Channel } from "revolt.js/dist/maps/Channels"; import { useContext, useEffect, useState } from "preact/hooks"; -import { Channel } from "../../../mobx"; -import { useData } from "../../../mobx/State"; - -import { AppContext } from "../../../context/revoltjs/RevoltClient"; +import { AppContext, useClient } from "../../../context/revoltjs/RevoltClient"; import Button from "../../../components/ui/Button"; import Checkbox from "../../../components/ui/Checkbox"; @@ -30,13 +27,12 @@ interface Props { // ! FIXME: bad code :) export default observer(({ channel }: Props) => { const [selected, setSelected] = useState("default"); - const client = useContext(AppContext); - const store = useData(); + const client = useClient(); type R = { name: string; permissions: number }; const roles: { [key: string]: R } = {}; if (channel.channel_type !== "Group") { - const server = store.servers.get(channel.server!); + const server = channel.server; const a = server?.roles ?? {}; for (const b of Object.keys(a)) { roles[b] = { @@ -105,7 +101,7 @@ export default observer(({ channel }: Props) => { diff --git a/src/pages/settings/panes/Account.tsx b/src/pages/settings/panes/Account.tsx index d6ee7bca..867c659d 100644 --- a/src/pages/settings/panes/Account.tsx +++ b/src/pages/settings/panes/Account.tsx @@ -2,14 +2,12 @@ import { At } from "@styled-icons/boxicons-regular"; import { Envelope, Key, HelpCircle } from "@styled-icons/boxicons-solid"; import { observer } from "mobx-react-lite"; import { Link, useHistory } from "react-router-dom"; -import { Users } from "revolt.js/dist/api/objects"; +import { Profile } from "revolt-api/types/Users"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; -import { useData } from "../../../mobx/State"; - import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { ClientStatus, @@ -28,14 +26,10 @@ export const Account = observer(() => { const status = useContext(StatusContext); const client = useClient(); - const store = useData(); - const user = store.users.get(client.user!._id)!; const [email, setEmail] = useState("..."); const [revealEmail, setRevealEmail] = useState(false); - const [profile, setProfile] = useState( - undefined, - ); + const [profile, setProfile] = useState(undefined); const history = useHistory(); function switchPage(to: string) { @@ -50,8 +44,8 @@ export const Account = observer(() => { } if (profile === undefined && status === ClientStatus.ONLINE) { - client.users - .fetchProfile(user._id) + client + .user!.fetchProfile() .then((profile) => setProfile(profile ?? {})); } }, [status]); @@ -61,12 +55,14 @@ export const Account = observer(() => {
switchPage("profile")} />
-
@{user.username}
+
+ @{client.user!.username} +
@@ -85,7 +81,7 @@ export const Account = observer(() => {
{( [ - ["username", user.username, ], + ["username", client.user!.username, ], ["email", email, ], ["password", "***********", ], ] as const diff --git a/src/pages/settings/panes/Profile.tsx b/src/pages/settings/panes/Profile.tsx index 265e7998..7465195b 100644 --- a/src/pages/settings/panes/Profile.tsx +++ b/src/pages/settings/panes/Profile.tsx @@ -1,5 +1,3 @@ -import { Users } from "revolt.js/dist/api/objects"; - import styles from "./Panes.module.scss"; import { IntlContext, Text, translate } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; @@ -18,6 +16,7 @@ import AutoComplete, { useAutoComplete, } from "../../../components/common/AutoComplete"; import Button from "../../../components/ui/Button"; +import { Profile } from "revolt-api/types/Users"; export function Profile() { const { intl } = useContext(IntlContext); @@ -25,15 +24,15 @@ export function Profile() { const client = useClient(); - const [profile, setProfile] = useState( + const [profile, setProfile] = useState( undefined, ); // ! FIXME: temporary solution // ! we should just announce profile changes through WS function refreshProfile() { - client.users - .fetchProfile(client.user!._id) + client + .user!.fetchProfile() .then((profile) => setProfile(profile ?? {})); } @@ -85,20 +84,17 @@ export function Profile() { fileType="avatars" behaviour="upload" maxFileSize={4_000_000} - onUpload={(avatar) => client.users.editUser({ avatar })} + onUpload={(avatar) => client.users.edit({ avatar })} remove={() => - client.users.editUser({ remove: "Avatar" }) + client.users.edit({ remove: "Avatar" }) } - defaultPreview={client.users.getAvatarURL( - client.user!._id, + defaultPreview={client.user!.generateAvatarURL( { max_side: 256 }, true, )} - previewURL={client.users.getAvatarURL( - client.user!._id, + previewURL={client.user!.generateAvatarURL( { max_side: 256 }, true, - true, )} />
@@ -113,21 +109,21 @@ export function Profile() { fileType="backgrounds" maxFileSize={6_000_000} onUpload={async (background) => { - await client.users.editUser({ + await client.users.edit({ profile: { background }, }); refreshProfile(); }} remove={async () => { - await client.users.editUser({ + await client.users.edit({ remove: "ProfileBackground", }); setProfile({ ...profile, background: undefined }); }} previewURL={ profile?.background - ? client.users.getBackgroundURL( - profile, + ? client.generateFileURL( + profile.background, { width: 1000 }, true, ) @@ -169,7 +165,7 @@ export function Profile() { contrast onClick={() => { setChanged(false); - client.users.editUser({ + client.users.edit({ profile: { content: profile?.content }, }); }} diff --git a/src/pages/settings/server/Bans.tsx b/src/pages/settings/server/Bans.tsx index 93935de1..e44b5acf 100644 --- a/src/pages/settings/server/Bans.tsx +++ b/src/pages/settings/server/Bans.tsx @@ -1,14 +1,12 @@ import { XCircle } from "@styled-icons/boxicons-regular"; import { observer } from "mobx-react-lite"; -import { Servers, Users } from "revolt.js/dist/api/objects"; import { Route } from "revolt.js/dist/api/routes"; +import { Server } from "revolt.js/dist/maps/Servers"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; -import { Server } from "../../../mobx"; - import { AppContext } from "../../../context/revoltjs/RevoltClient"; import UserIcon from "../../../components/common/user/UserIcon"; @@ -27,7 +25,7 @@ export const Bans = observer(({ server }: Props) => { >(undefined); useEffect(() => { - client.servers.fetchBans(server._id).then(setData as any); + server.fetchBans().then(setData as any); }, []); return ( @@ -64,10 +62,7 @@ export const Bans = observer(({ server }: Props) => { onClick={async () => { setDelete([...deleting, x._id.user]); - await client.servers.unbanUser( - server._id, - x._id.user, - ); + await server.unbanUser(x._id.user); setData({ ...data, diff --git a/src/pages/settings/server/Categories.tsx b/src/pages/settings/server/Categories.tsx index ad68880a..d0d4dd0e 100644 --- a/src/pages/settings/server/Categories.tsx +++ b/src/pages/settings/server/Categories.tsx @@ -1,16 +1,10 @@ -import { XCircle } from "@styled-icons/boxicons-regular"; import isEqual from "lodash.isequal"; import { observer } from "mobx-react-lite"; -import { Channels, Servers, Users } from "revolt.js/dist/api/objects"; -import { Route } from "revolt.js/dist/api/routes"; +import { Category } from "revolt-api/types/Servers"; +import { Server } from "revolt.js/dist/maps/Servers"; import { ulid } from "ulid"; -import styles from "./Panes.module.scss"; -import { Text } from "preact-i18n"; -import { useContext, useEffect, useState } from "preact/hooks"; - -import { Server } from "../../../mobx"; -import { useData } from "../../../mobx/State"; +import { useContext, useState } from "preact/hooks"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; @@ -30,15 +24,9 @@ interface Props { // ! FIXME: really bad code export const Categories = observer(({ server }: Props) => { const client = useContext(AppContext); - const store = useData(); - const channels = server.channels - .map((id) => store.channels.get(id)!) - .filter((x) => typeof x !== "undefined"); - - const [cats, setCats] = useState( - server.categories ?? [], - ); + const channels = server.channels.filter((x) => typeof x !== "undefined"); + const [cats, setCats] = useState(server.categories ?? []); const [name, setName] = useState(""); return ( @@ -48,9 +36,7 @@ export const Categories = observer(({ server }: Props) => {

@@ -116,13 +102,13 @@ export const Categories = observer(({ server }: Props) => { }}>
{" "} - {channel.name} + {channel!.name}
- x.channels.includes(channel._id), + x.channels.includes(channel!._id), )?.id ?? "none" } onChange={(e) => @@ -132,11 +118,11 @@ export const Categories = observer(({ server }: Props) => { ...x, channels: [ ...x.channels.filter( - (y) => y !== channel._id, + (y) => y !== channel!._id, ), ...(e.currentTarget.value === x.id - ? [channel._id] + ? [channel!._id] : []), ], }; diff --git a/src/pages/settings/server/Invites.tsx b/src/pages/settings/server/Invites.tsx index 8c06e954..1ff32e6f 100644 --- a/src/pages/settings/server/Invites.tsx +++ b/src/pages/settings/server/Invites.tsx @@ -1,14 +1,12 @@ import { XCircle } from "@styled-icons/boxicons-regular"; import { observer } from "mobx-react-lite"; -import { Invites as InvitesNS, Servers } from "revolt.js/dist/api/objects"; +import { ServerInvite } from "revolt-api/types/Invites"; +import { Server } from "revolt.js/dist/maps/Servers"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useEffect, useState } from "preact/hooks"; -import { Server } from "../../../mobx"; -import { useData } from "../../../mobx/State"; - import { useClient } from "../../../context/revoltjs/RevoltClient"; import { getChannelName } from "../../../context/revoltjs/util"; @@ -22,21 +20,18 @@ interface Props { export const Invites = observer(({ server }: Props) => { const [deleting, setDelete] = useState([]); - const [invites, setInvites] = useState< - InvitesNS.ServerInvite[] | undefined - >(undefined); + const [invites, setInvites] = useState( + undefined, + ); - const store = useData(); const client = useClient(); - const users = invites?.map((invite) => store.users.get(invite.creator)); + const users = invites?.map((invite) => client.users.get(invite.creator)); const channels = invites?.map((invite) => - store.channels.get(invite.channel), + client.channels.get(invite.channel), ); useEffect(() => { - client.servers - .fetchInvites(server._id) - .then((invites) => setInvites(invites)); + server.fetchInvites().then(setInvites); }, []); return ( @@ -73,7 +68,7 @@ export const Invites = observer(({ server }: Props) => { {channel && creator - ? getChannelName(client, channel, true) + ? getChannelName(channel, true) : "#??"} { const [selected, setSelected] = useState(); - const [members, setMembers] = useState( - undefined, - ); + const [data, setData] = useState< + { members: Member[]; users: User[] } | undefined + >(undefined); - const store = useData(); const client = useClient(); - const users = members?.map((member) => store.users.get(member._id.user)); useEffect(() => { - client.members - .fetchMembers(server._id) - .then((members) => setMembers(members)); + server.fetchMembers().then(setData); }, []); const [roles, setRoles] = useState([]); useEffect(() => { if (selected) { setRoles( - members!.find((x) => x._id.user === selected)?.roles ?? [], + data!.members.find((x) => x._id.user === selected)?.roles ?? [], ); } }, [selected]); @@ -50,15 +45,15 @@ export const Members = observer(({ server }: Props) => { return (
- {members?.length ?? 0} Members + {data?.members.length ?? 0} Members
- {members && - members.length > 0 && - members + {data && + data.members.length > 0 && + data.members .map((member, index) => { return { member, - user: users![index], + user: data.users[index], }; }) .map(({ member, user }) => ( @@ -130,27 +125,11 @@ export const Members = observer(({ server }: Props) => { member.roles ?? [], roles, )} - onClick={async () => { - await client.members.editMember( - server._id, - member._id.user, - { - roles, - }, - ); - - setMembers( - members.map((x) => - x._id.user === - member._id.user - ? { - ...x, - roles, - } - : x, - ), - ); - }}> + onClick={() => + member.edit({ + roles, + }) + }>
diff --git a/src/pages/settings/server/Overview.tsx b/src/pages/settings/server/Overview.tsx index 93f128ee..69f79533 100644 --- a/src/pages/settings/server/Overview.tsx +++ b/src/pages/settings/server/Overview.tsx @@ -1,6 +1,6 @@ import isEqual from "lodash.isequal"; import { observer } from "mobx-react-lite"; -import { Servers } from "revolt.js/dist/api/objects"; +import { Server } from "revolt.js/dist/maps/Servers"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; @@ -8,11 +8,8 @@ import { useContext, useEffect, useState } from "preact/hooks"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; -import { Server } from "../../../mobx"; -import { useData } from "../../../mobx/State"; - import { FileUploader } from "../../../context/revoltjs/FileUploads"; -import { AppContext } from "../../../context/revoltjs/RevoltClient"; +import { AppContext, useClient } from "../../../context/revoltjs/RevoltClient"; import { getChannelName } from "../../../context/revoltjs/util"; import Button from "../../../components/ui/Button"; @@ -24,8 +21,7 @@ interface Props { } export const Overview = observer(({ server }: Props) => { - const client = useContext(AppContext); - const store = useData(); + const client = useClient(); const [name, setName] = useState(server.name); const [description, setDescription] = useState(server.description ?? ""); @@ -45,16 +41,14 @@ export const Overview = observer(({ server }: Props) => { const [changed, setChanged] = useState(false); function save() { - const changes: Partial< - Pick - > = {}; + const changes: Record = {}; if (name !== server.name) changes.name = name; if (description !== server.description) changes.description = description; if (!isEqual(systemMessages, server.system_messages)) changes.system_messages = systemMessages ?? undefined; - client.servers.edit(server._id, changes); + server.edit(changes); setChanged(false); } @@ -68,17 +62,9 @@ export const Overview = observer(({ server }: Props) => { fileType="icons" behaviour="upload" maxFileSize={2_500_000} - onUpload={(icon) => - client.servers.edit(server._id, { icon }) - } - previewURL={client.servers.getIconURL( - server._id, - { max_side: 256 }, - true, - )} - remove={() => - client.servers.edit(server._id, { remove: "Icon" }) - } + onUpload={(icon) => server.edit({ icon })} + previewURL={server.generateIconURL({ max_side: 256 }, true)} + remove={() => server.edit({ remove: "Icon" })} />

@@ -120,17 +106,9 @@ export const Overview = observer(({ server }: Props) => { fileType="banners" behaviour="upload" maxFileSize={6_000_000} - onUpload={(banner) => - client.servers.edit(server._id, { banner }) - } - previewURL={client.servers.getBannerURL( - server._id, - { width: 1000 }, - true, - )} - remove={() => - client.servers.edit(server._id, { remove: "Banner" }) - } + onUpload={(banner) => server.edit({ banner })} + previewURL={server.generateBannerURL({ width: 1000 }, true)} + remove={() => server.edit({ remove: "Banner" })} />

@@ -176,11 +154,10 @@ export const Overview = observer(({ server }: Props) => { {server.channels - .map((id) => store.channels.get(id)!) .filter((x) => typeof x !== "undefined") .map((channel) => ( - ))} diff --git a/src/pages/settings/server/Roles.tsx b/src/pages/settings/server/Roles.tsx index 12142e1b..4431e471 100644 --- a/src/pages/settings/server/Roles.tsx +++ b/src/pages/settings/server/Roles.tsx @@ -1,18 +1,13 @@ import { Plus } from "@styled-icons/boxicons-regular"; import isEqual from "lodash.isequal"; import { observer } from "mobx-react-lite"; -import { Servers } from "revolt.js/dist/api/objects"; -import { - ChannelPermission, - ServerPermission, -} from "revolt.js/dist/api/permissions"; +import { ChannelPermission, ServerPermission } from "revolt.js"; +import { Server } from "revolt.js/dist/maps/Servers"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; -import { Server } from "../../../mobx"; - import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; @@ -73,20 +68,20 @@ export const Roles = observer(({ server }: Props) => { const save = () => { if (!isEqual(perm, getPermissions(role))) { - client.servers.setPermissions(server._id, role, { + server.setPermissions(role, { server: perm[0], channel: perm[1], }); } if (!isEqual(name, roleName) || !isEqual(colour, roleColour)) { - client.servers.editRole(server._id, role, { name, colour }); + server.editRole(role, { name, colour }); } }; const deleteRole = () => { setRole("default"); - client.servers.deleteRole(server._id, role); + server.deleteRole(role); }; return ( diff --git a/src/redux/index.ts b/src/redux/index.ts index 171acfb9..99c16c03 100644 --- a/src/redux/index.ts +++ b/src/redux/index.ts @@ -1,6 +1,6 @@ import localForage from "localforage"; import { createStore } from "redux"; -import { Core } from "revolt.js/dist/api/objects"; +import { RevoltConfiguration } from "revolt-api/types/Core"; import { Language } from "../context/Locale"; @@ -18,7 +18,7 @@ import { Typing } from "./reducers/typing"; import { Unreads } from "./reducers/unreads"; export type State = { - config: Core.RevoltNodeConfiguration; + config: RevoltConfiguration; locale: Language; auth: AuthState; settings: Settings; diff --git a/src/redux/reducers/auth.ts b/src/redux/reducers/auth.ts index f2533346..2bb2ce99 100644 --- a/src/redux/reducers/auth.ts +++ b/src/redux/reducers/auth.ts @@ -1,9 +1,9 @@ -import type { Auth } from "revolt.js/dist/api/objects"; +import { Session } from "revolt-api/types/Auth"; export interface AuthState { accounts: { [key: string]: { - session: Auth.Session; + session: Session; }; }; active?: string; @@ -13,7 +13,7 @@ export type AuthAction = | { type: undefined } | { type: "LOGIN"; - session: Auth.Session; + session: Session; } | { type: "LOGOUT"; diff --git a/src/redux/reducers/notifications.ts b/src/redux/reducers/notifications.ts index ace9d56f..76e3679b 100644 --- a/src/redux/reducers/notifications.ts +++ b/src/redux/reducers/notifications.ts @@ -1,4 +1,5 @@ -import type { Channel, Message } from "revolt.js"; +import { Channel } from "revolt.js/dist/maps/Channels"; +import { Message } from "revolt.js/dist/maps/Messages"; import type { SyncUpdateAction } from "./sync"; @@ -35,7 +36,7 @@ export function shouldNotify( case "none": return false; case "mention": { - if (!message.mentions?.includes(user_id)) return false; + if (!message.mention_ids?.includes(user_id)) return false; } } diff --git a/src/redux/reducers/queue.ts b/src/redux/reducers/queue.ts index ce8ee124..ea3437af 100644 --- a/src/redux/reducers/queue.ts +++ b/src/redux/reducers/queue.ts @@ -1,5 +1,3 @@ -import type { MessageObject } from "../../context/revoltjs/util"; - export enum QueueStatus { SENDING = "sending", ERRORED = "errored", @@ -10,7 +8,7 @@ export interface Reply { mention: boolean; } -export type QueuedMessageData = Omit & { +export type QueuedMessageData = { content: string; replies: Reply[]; }; diff --git a/src/redux/reducers/server_config.ts b/src/redux/reducers/server_config.ts index 1b4da1df..916cb2d7 100644 --- a/src/redux/reducers/server_config.ts +++ b/src/redux/reducers/server_config.ts @@ -1,16 +1,16 @@ -import type { Core } from "revolt.js/dist/api/objects"; +import type { RevoltConfiguration } from "revolt-api/types/Core"; export type ConfigAction = | { type: undefined } | { type: "SET_CONFIG"; - config: Core.RevoltNodeConfiguration; + config: RevoltConfiguration; }; export function config( - state = {} as Core.RevoltNodeConfiguration, + state = {} as RevoltConfiguration, action: ConfigAction, -): Core.RevoltNodeConfiguration { +): RevoltConfiguration { switch (action.type) { case "SET_CONFIG": return action.config; diff --git a/src/redux/reducers/unreads.ts b/src/redux/reducers/unreads.ts index 1f1b2fb1..8f97301e 100644 --- a/src/redux/reducers/unreads.ts +++ b/src/redux/reducers/unreads.ts @@ -1,7 +1,7 @@ -import type { Sync } from "revolt.js/dist/api/objects"; +import type { ChannelUnread } from "revolt-api/types/Sync"; export interface Unreads { - [key: string]: Partial>; + [key: string]: Partial>; } export type UnreadsAction = @@ -13,7 +13,7 @@ export type UnreadsAction = } | { type: "UNREADS_SET"; - unreads: Sync.ChannelUnread[]; + unreads: ChannelUnread[]; } | { type: "UNREADS_MENTION"; diff --git a/src/sw.ts b/src/sw.ts index 370ea849..2f815b30 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -1,8 +1,8 @@ /// import { IDBPDatabase, openDB } from "idb"; import { getItem } from "localforage"; -import { Channel, Message, User } from "revolt.js"; -import { Server } from "revolt.js/dist/api/objects"; +// import { Channel, Message, User } from "revolt.js"; +// import { Server } from "revolt.js/dist/api/objects"; import { precacheAndRoute } from "workbox-precaching"; import type { State } from "./redux"; @@ -43,7 +43,8 @@ function decodeTime(id: string) { self.addEventListener("push", (event) => { async function process() { if (event.data === null) return; - const data: Message = event.data.json(); + // ! FIXME: removed until client data is saved to local storage + /* const data: Message = event.data.json(); const item = await localStorage.getItem("state"); if (!item) return; @@ -142,7 +143,7 @@ self.addEventListener("push", (event) => { channel?.channel_type === "TextChannel" ? `/server/${channel.server}/channel/${channel._id}` : `/channel/${data.channel}`, - }); + }); */ } event.waitUntil(process()); diff --git a/yarn.lock b/yarn.lock index f6c86fee..3673273c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1114,14 +1114,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== -"@insertish/mutable@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@insertish/mutable/-/mutable-1.1.0.tgz#06f95f855691ccb69ee3c339887a80bcd1498116" - integrity sha512-NH7aCGFAKRE1gFprrW/HsJoWCWQy18TZBarxLdeLVWdLFvkb2lD6Z5B70oOoUHFNpykiTC8IcRonsd9Xn13n8Q== - dependencies: - eventemitter3 "^4.0.7" - lodash.isequal "^4.5.0" - "@mdn/browser-compat-data@^2.0.7": version "2.0.7" resolved "https://registry.yarnpkg.com/@mdn/browser-compat-data/-/browser-compat-data-2.0.7.tgz#72ec37b9c1e00ce0b4e0309d753be18e2da12ee3" @@ -3573,17 +3565,23 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revolt.js@4.4.0-alpha.0: - version "4.4.0-alpha.0" - resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.4.0-alpha.0.tgz#6b8d7e5605c4e106800ebd7ddcda8215a8fb289b" - integrity sha512-TPb7FCC1xpAO0hJ19tXAC5ZwsceJ/yzkFlV/lESteVk4bboVINhRrsElYtJvjSKci7Ft70t0e4bbm8YSYjAblA== +revolt-api@0.5.1-alpha.10-patch.0: + version "0.5.1-alpha.10-patch.0" + resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.1-alpha.10-patch.0.tgz#97d31bec7dfa4573567097443acb059c4feaac20" + integrity sha512-UyM890HkGlYNQOxpHuEpUsJHLt8Ujnjg9/zPEDGpbvS4iy0jmHX23Hh8tOCfb/ewxbNrtT3G1HpSWKOneW/vYg== + +revolt.js@5.0.0-alpha.5: + version "5.0.0-alpha.5" + resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.0-alpha.5.tgz#96008a1bf91e80b17ff877b59ca3f4fd9151055d" + integrity sha512-HOMblFOR25pE1NMGK4EYgvWqfWADyiGTZlvFpio8CEca3lAmr2jWjJAly5BWMy1SwFcfHmtHIy6Lm5Pkgjop9Q== dependencies: - "@insertish/mutable" "1.1.0" axios "^0.19.2" eventemitter3 "^4.0.7" exponential-backoff "^3.1.0" isomorphic-ws "^4.0.1" lodash.defaultsdeep "^4.6.1" + lodash.isequal "^4.5.0" + mobx "^6.3.2" tsc-watch "^4.1.0" ulid "^2.3.0" ws "^7.2.1"