mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-26 23:42:11 -05:00
Remove useChannel
This commit is contained in:
parent
0571c065bd
commit
411fac2527
28 changed files with 259 additions and 257 deletions
|
@ -1,10 +1,11 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { Channel } from "revolt.js";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
|
|
||||||
|
import { Channel } from "../../mobx";
|
||||||
import { dispatch, getState } from "../../redux";
|
import { dispatch, getState } from "../../redux";
|
||||||
|
|
||||||
import Button from "../ui/Button";
|
import Button from "../ui/Button";
|
||||||
|
@ -46,7 +47,7 @@ type Props = {
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AgeGate(props: Props) {
|
export default observer((props: Props) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [consent, setConsent] = useState(
|
const [consent, setConsent] = useState(
|
||||||
getState().sectionToggle["nsfw"] ?? false,
|
getState().sectionToggle["nsfw"] ?? false,
|
||||||
|
@ -105,4 +106,4 @@ export default function AgeGate(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
</Base>
|
</Base>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ import styled, { css } from "styled-components";
|
||||||
|
|
||||||
import { StateUpdater, useState } from "preact/hooks";
|
import { StateUpdater, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { User } from "../../mobx";
|
import { Channel, User } from "../../mobx";
|
||||||
import { useData } from "../../mobx/State";
|
import { useData } from "../../mobx/State";
|
||||||
|
|
||||||
import { useClient } from "../../context/revoltjs/RevoltClient";
|
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||||
|
@ -28,7 +28,7 @@ export type AutoCompleteState =
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: "channel";
|
type: "channel";
|
||||||
matches: Channels.TextChannel[];
|
matches: Channel[];
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -197,15 +197,13 @@ export function useAutoComplete(
|
||||||
if (type === "channel" && searchClues?.channels) {
|
if (type === "channel" && searchClues?.channels) {
|
||||||
const channels = client.servers
|
const channels = client.servers
|
||||||
.get(searchClues.channels.server)
|
.get(searchClues.channels.server)
|
||||||
?.channels.map((x) => client.channels.get(x))
|
?.channels.map((x) => store.channels.get(x))
|
||||||
.filter(
|
.filter((x) => typeof x !== "undefined") as Channel[];
|
||||||
(x) => typeof x !== "undefined",
|
|
||||||
) as Channels.TextChannel[];
|
|
||||||
|
|
||||||
const matches = (
|
const matches = (
|
||||||
search.length > 0
|
search.length > 0
|
||||||
? channels.filter((channel) =>
|
? channels.filter((channel) =>
|
||||||
channel.name.toLowerCase().match(regex),
|
channel.name!.toLowerCase().match(regex),
|
||||||
)
|
)
|
||||||
: channels
|
: channels
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,65 +1,67 @@
|
||||||
import { Hash, VolumeFull } from "@styled-icons/boxicons-regular";
|
import { Hash, VolumeFull } from "@styled-icons/boxicons-regular";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Channels } from "revolt.js/dist/api/objects";
|
import { Channels } from "revolt.js/dist/api/objects";
|
||||||
|
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
|
|
||||||
|
import { Channel } from "../../mobx";
|
||||||
|
|
||||||
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
import { ImageIconBase, IconBaseProps } from "./IconBase";
|
import { ImageIconBase, IconBaseProps } from "./IconBase";
|
||||||
import fallback from "./assets/group.png";
|
import fallback from "./assets/group.png";
|
||||||
|
|
||||||
interface Props
|
interface Props extends IconBaseProps<Channel> {
|
||||||
extends IconBaseProps<
|
|
||||||
Channels.GroupChannel | Channels.TextChannel | Channels.VoiceChannel
|
|
||||||
> {
|
|
||||||
isServerChannel?: boolean;
|
isServerChannel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ChannelIcon(
|
export default observer(
|
||||||
props: Props & Omit<JSX.HTMLAttributes<HTMLImageElement>, keyof Props>,
|
(
|
||||||
) {
|
props: Props & Omit<JSX.HTMLAttributes<HTMLImageElement>, keyof Props>,
|
||||||
const client = useContext(AppContext);
|
) => {
|
||||||
|
const client = useContext(AppContext);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
size,
|
size,
|
||||||
target,
|
target,
|
||||||
attachment,
|
attachment,
|
||||||
isServerChannel: server,
|
isServerChannel: server,
|
||||||
animate,
|
animate,
|
||||||
children,
|
children,
|
||||||
as,
|
as,
|
||||||
...imgProps
|
...imgProps
|
||||||
} = props;
|
} = props;
|
||||||
const iconURL = client.generateFileURL(
|
const iconURL = client.generateFileURL(
|
||||||
target?.icon ?? attachment,
|
target?.icon ?? attachment,
|
||||||
{ max_side: 256 },
|
{ max_side: 256 },
|
||||||
animate,
|
animate,
|
||||||
);
|
);
|
||||||
const isServerChannel =
|
const isServerChannel =
|
||||||
server ||
|
server ||
|
||||||
(target &&
|
(target &&
|
||||||
(target.channel_type === "TextChannel" ||
|
(target.channel_type === "TextChannel" ||
|
||||||
target.channel_type === "VoiceChannel"));
|
target.channel_type === "VoiceChannel"));
|
||||||
|
|
||||||
if (typeof iconURL === "undefined") {
|
if (typeof iconURL === "undefined") {
|
||||||
if (isServerChannel) {
|
if (isServerChannel) {
|
||||||
if (target?.channel_type === "VoiceChannel") {
|
if (target?.channel_type === "VoiceChannel") {
|
||||||
return <VolumeFull size={size} />;
|
return <VolumeFull size={size} />;
|
||||||
|
}
|
||||||
|
return <Hash size={size} />;
|
||||||
}
|
}
|
||||||
return <Hash size={size} />;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// ! fixme: replace fallback with <picture /> + <source />
|
// ! fixme: replace fallback with <picture /> + <source />
|
||||||
<ImageIconBase
|
<ImageIconBase
|
||||||
{...imgProps}
|
{...imgProps}
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
square={isServerChannel}
|
square={isServerChannel}
|
||||||
src={iconURL ?? fallback}
|
src={iconURL ?? fallback}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Send, HappyAlt, ShieldX } from "@styled-icons/boxicons-solid";
|
import { Send, HappyAlt, ShieldX } from "@styled-icons/boxicons-solid";
|
||||||
import { Styleshare } from "@styled-icons/simple-icons";
|
import { Styleshare } from "@styled-icons/simple-icons";
|
||||||
import Axios, { CancelTokenSource } from "axios";
|
import Axios, { CancelTokenSource } from "axios";
|
||||||
import { Channel } from "revolt.js";
|
|
||||||
import { ChannelPermission } from "revolt.js/dist/api/permissions";
|
import { ChannelPermission } from "revolt.js/dist/api/permissions";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
|
@ -20,6 +19,7 @@ import {
|
||||||
SMOOTH_SCROLL_ON_RECEIVE,
|
SMOOTH_SCROLL_ON_RECEIVE,
|
||||||
} from "../../../lib/renderer/Singleton";
|
} from "../../../lib/renderer/Singleton";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
import { dispatch, getState } from "../../../redux";
|
import { dispatch, getState } from "../../../redux";
|
||||||
import { Reply } from "../../../redux/reducers/queue";
|
import { Reply } from "../../../redux/reducers/queue";
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ export default function MessageBox({ channel }: Props) {
|
||||||
users: { type: "channel", id: channel._id },
|
users: { type: "channel", id: channel._id },
|
||||||
channels:
|
channels:
|
||||||
channel.channel_type === "TextChannel"
|
channel.channel_type === "TextChannel"
|
||||||
? { server: channel.server }
|
? { server: channel.server! }
|
||||||
: undefined,
|
: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Localizer, Text } from "preact-i18n";
|
||||||
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
|
||||||
import { stopPropagation } from "../../../lib/stopPropagation";
|
import { stopPropagation } from "../../../lib/stopPropagation";
|
||||||
|
|
||||||
import { User } from "../../../mobx";
|
import { Channel, User } from "../../../mobx";
|
||||||
|
|
||||||
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
import { useIntermediate } from "../../../context/intermediate/Intermediate";
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ type CommonProps = Omit<
|
||||||
|
|
||||||
type UserProps = CommonProps & {
|
type UserProps = CommonProps & {
|
||||||
user: User;
|
user: User;
|
||||||
context?: Channels.Channel;
|
context?: Channel;
|
||||||
channel?: Channels.DirectMessageChannel;
|
channel?: Channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserButton = observer((props: UserProps) => {
|
export const UserButton = observer((props: UserProps) => {
|
||||||
|
@ -73,7 +73,7 @@ export const UserButton = observer((props: UserProps) => {
|
||||||
{
|
{
|
||||||
<div className={styles.subText}>
|
<div className={styles.subText}>
|
||||||
{channel?.last_message && alert ? (
|
{channel?.last_message && alert ? (
|
||||||
channel.last_message.short
|
(channel.last_message as { short: string }).short
|
||||||
) : (
|
) : (
|
||||||
<UserStatus user={user} />
|
<UserStatus user={user} />
|
||||||
)}
|
)}
|
||||||
|
@ -115,12 +115,12 @@ export const UserButton = observer((props: UserProps) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
type ChannelProps = CommonProps & {
|
type ChannelProps = CommonProps & {
|
||||||
channel: Channels.Channel & { unread?: string };
|
channel: Channel & { unread?: string };
|
||||||
user?: User;
|
user?: User;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ChannelButton(props: ChannelProps) {
|
export const ChannelButton = observer((props: ChannelProps) => {
|
||||||
const { active, alert, alertCount, channel, user, compact, ...divProps } =
|
const { active, alert, alertCount, channel, user, compact, ...divProps } =
|
||||||
props;
|
props;
|
||||||
|
|
||||||
|
@ -153,12 +153,12 @@ export function ChannelButton(props: ChannelProps) {
|
||||||
{channel.channel_type === "Group" && (
|
{channel.channel_type === "Group" && (
|
||||||
<div className={styles.subText}>
|
<div className={styles.subText}>
|
||||||
{channel.last_message && alert ? (
|
{channel.last_message && alert ? (
|
||||||
channel.last_message.short
|
(channel.last_message as { short: string }).short
|
||||||
) : (
|
) : (
|
||||||
<Text
|
<Text
|
||||||
id="quantities.members"
|
id="quantities.members"
|
||||||
plural={channel.recipients.length}
|
plural={channel.recipients!.length}
|
||||||
fields={{ count: channel.recipients.length }}
|
fields={{ count: channel.recipients!.length }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,7 +186,7 @@ export function ChannelButton(props: ChannelProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
type ButtonProps = CommonProps & {
|
type ButtonProps = CommonProps & {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
|
|
@ -43,10 +43,16 @@ const HomeSidebar = observer((props: Props) => {
|
||||||
const { channel } = useParams<{ channel: string }>();
|
const { channel } = useParams<{ channel: string }>();
|
||||||
const { openScreen } = useIntermediate();
|
const { openScreen } = useIntermediate();
|
||||||
|
|
||||||
const ctx = useForceUpdate();
|
const store = useData();
|
||||||
const channels = useDMs(ctx);
|
const channels = [...store.channels.values()]
|
||||||
|
.filter(
|
||||||
|
(x) =>
|
||||||
|
x.channel_type === "DirectMessage" ||
|
||||||
|
x.channel_type === "Group",
|
||||||
|
)
|
||||||
|
.map((x) => mapChannelWithUnread(x, props.unreads));
|
||||||
|
|
||||||
const obj = channels.find((x) => x?._id === channel);
|
const obj = store.channels.get(channel);
|
||||||
if (channel && !obj) return <Redirect to="/" />;
|
if (channel && !obj) return <Redirect to="/" />;
|
||||||
if (obj) useUnreads({ ...props, channel: obj });
|
if (obj) useUnreads({ ...props, channel: obj });
|
||||||
|
|
||||||
|
@ -60,12 +66,7 @@ const HomeSidebar = observer((props: Props) => {
|
||||||
});
|
});
|
||||||
}, [channel]);
|
}, [channel]);
|
||||||
|
|
||||||
const channelsArr = channels
|
channels.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
|
||||||
.filter((x) => x.channel_type !== "SavedMessages")
|
|
||||||
.map((x) => mapChannelWithUnread(x, props.unreads));
|
|
||||||
|
|
||||||
const store = useData();
|
|
||||||
channelsArr.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GenericSidebarBase padding>
|
<GenericSidebarBase padding>
|
||||||
|
@ -132,20 +133,22 @@ const HomeSidebar = observer((props: Props) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{channelsArr.length === 0 && (
|
{channels.length === 0 && (
|
||||||
<img src={placeholderSVG} loading="eager" />
|
<img src={placeholderSVG} loading="eager" />
|
||||||
)}
|
)}
|
||||||
{channelsArr.map((x) => {
|
{channels.map((x) => {
|
||||||
let user;
|
let user;
|
||||||
if (x.channel_type === "DirectMessage") {
|
if (x.channel.channel_type === "DirectMessage") {
|
||||||
if (!x.active) return null;
|
if (!x.channel.active) return null;
|
||||||
|
|
||||||
const recipient = client.channels.getRecipient(x._id);
|
const recipient = client.channels.getRecipient(
|
||||||
|
x.channel._id,
|
||||||
|
);
|
||||||
user = store.users.get(recipient);
|
user = store.users.get(recipient);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Skipped DM ${x._id} because user was missing.`,
|
`Skipped DM ${x.channel._id} because user was missing.`,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -153,14 +156,14 @@ const HomeSidebar = observer((props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionalLink
|
<ConditionalLink
|
||||||
active={x._id === channel}
|
active={x.channel._id === channel}
|
||||||
to={`/channel/${x._id}`}>
|
to={`/channel/${x.channel._id}`}>
|
||||||
<ChannelButton
|
<ChannelButton
|
||||||
user={user}
|
user={user}
|
||||||
channel={x}
|
channel={x.channel}
|
||||||
alert={x.unread}
|
alert={x.unread}
|
||||||
alertCount={x.alertCount}
|
alertCount={x.alertCount}
|
||||||
active={x._id === channel}
|
active={x.channel._id === channel}
|
||||||
/>
|
/>
|
||||||
</ConditionalLink>
|
</ConditionalLink>
|
||||||
);
|
);
|
||||||
|
|
|
@ -186,16 +186,18 @@ export const ServerListSidebar = observer(({ unreads, lastOpened }: Props) => {
|
||||||
|
|
||||||
const ctx = useForceUpdate();
|
const ctx = useForceUpdate();
|
||||||
const activeServers = useServers(undefined, ctx) as Servers.Server[];
|
const activeServers = useServers(undefined, ctx) as Servers.Server[];
|
||||||
const channels = (useChannels(undefined, ctx) as Channel[]).map((x) =>
|
const channels = [...store.channels.values()].map((x) =>
|
||||||
mapChannelWithUnread(x, unreads),
|
mapChannelWithUnread(x, unreads),
|
||||||
);
|
);
|
||||||
|
|
||||||
const unreadChannels = channels.filter((x) => x.unread).map((x) => x._id);
|
const unreadChannels = channels
|
||||||
|
.filter((x) => x.unread)
|
||||||
|
.map((x) => x.channel?._id);
|
||||||
|
|
||||||
const servers = activeServers.map((server) => {
|
const servers = activeServers.map((server) => {
|
||||||
let alertCount = 0;
|
let alertCount = 0;
|
||||||
for (const id of server.channels) {
|
for (const id of server.channels) {
|
||||||
const channel = channels.find((x) => x._id === id);
|
const channel = channels.find((x) => x.channel?._id === id);
|
||||||
if (channel?.alertCount) {
|
if (channel?.alertCount) {
|
||||||
alertCount += channel.alertCount;
|
alertCount += channel.alertCount;
|
||||||
}
|
}
|
||||||
|
@ -224,8 +226,9 @@ export const ServerListSidebar = observer(({ unreads, lastOpened }: Props) => {
|
||||||
let alertCount = 0;
|
let alertCount = 0;
|
||||||
for (const x of channels) {
|
for (const x of channels) {
|
||||||
if (
|
if (
|
||||||
((x.channel_type === "DirectMessage" && x.active) ||
|
(x.channel?.channel_type === "DirectMessage"
|
||||||
x.channel_type === "Group") &&
|
? x.channel?.active
|
||||||
|
: true) &&
|
||||||
x.unread
|
x.unread
|
||||||
) {
|
) {
|
||||||
homeUnread = "unread";
|
homeUnread = "unread";
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Redirect, useParams } from "react-router";
|
import { Redirect, useParams } from "react-router";
|
||||||
import { Channels } from "revolt.js/dist/api/objects";
|
import { Channels } from "revolt.js/dist/api/objects";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
@ -8,6 +9,7 @@ import { useEffect } from "preact/hooks";
|
||||||
import ConditionalLink from "../../../lib/ConditionalLink";
|
import ConditionalLink from "../../../lib/ConditionalLink";
|
||||||
import PaintCounter from "../../../lib/PaintCounter";
|
import PaintCounter from "../../../lib/PaintCounter";
|
||||||
|
|
||||||
|
import { useData } from "../../../mobx/State";
|
||||||
import { dispatch } from "../../../redux";
|
import { dispatch } from "../../../redux";
|
||||||
import { connectState } from "../../../redux/connector";
|
import { connectState } from "../../../redux/connector";
|
||||||
import { Unreads } from "../../../redux/reducers/unreads";
|
import { Unreads } from "../../../redux/reducers/unreads";
|
||||||
|
@ -53,7 +55,7 @@ const ServerList = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function ServerSidebar(props: Props) {
|
const ServerSidebar = observer((props: Props) => {
|
||||||
const { server: server_id, channel: channel_id } =
|
const { server: server_id, channel: channel_id } =
|
||||||
useParams<{ server?: string; channel?: string }>();
|
useParams<{ server?: string; channel?: string }>();
|
||||||
const ctx = useForceUpdate();
|
const ctx = useForceUpdate();
|
||||||
|
@ -61,13 +63,9 @@ function ServerSidebar(props: Props) {
|
||||||
const server = useServer(server_id, ctx);
|
const server = useServer(server_id, ctx);
|
||||||
if (!server) return <Redirect to="/" />;
|
if (!server) return <Redirect to="/" />;
|
||||||
|
|
||||||
const channels = (
|
const store = useData();
|
||||||
useChannels(server.channels, ctx).filter(
|
|
||||||
(entry) => typeof entry !== "undefined",
|
|
||||||
) as Readonly<Channels.TextChannel | Channels.VoiceChannel>[]
|
|
||||||
).map((x) => mapChannelWithUnread(x, props.unreads));
|
|
||||||
|
|
||||||
const channel = channels.find((x) => x?._id === channel_id);
|
const channel = channel_id ? store.channels.get(channel_id) : undefined;
|
||||||
if (channel_id && !channel) return <Redirect to={`/server/${server_id}`} />;
|
if (channel_id && !channel) return <Redirect to={`/server/${server_id}`} />;
|
||||||
if (channel) useUnreads({ ...props, channel }, ctx);
|
if (channel) useUnreads({ ...props, channel }, ctx);
|
||||||
|
|
||||||
|
@ -85,7 +83,7 @@ function ServerSidebar(props: Props) {
|
||||||
const elements = [];
|
const elements = [];
|
||||||
|
|
||||||
function addChannel(id: string) {
|
function addChannel(id: string) {
|
||||||
const entry = channels.find((x) => x._id === id);
|
const entry = store.channels.get(id);
|
||||||
if (!entry) return;
|
if (!entry) return;
|
||||||
|
|
||||||
const active = channel?._id === entry._id;
|
const active = channel?._id === entry._id;
|
||||||
|
@ -98,7 +96,8 @@ function ServerSidebar(props: Props) {
|
||||||
<ChannelButton
|
<ChannelButton
|
||||||
channel={entry}
|
channel={entry}
|
||||||
active={active}
|
active={active}
|
||||||
alert={entry.unread}
|
// ! FIXME: pull it out directly
|
||||||
|
alert={mapChannelWithUnread(entry, props.unreads).unread}
|
||||||
compact
|
compact
|
||||||
/>
|
/>
|
||||||
</ConditionalLink>
|
</ConditionalLink>
|
||||||
|
@ -141,7 +140,7 @@ function ServerSidebar(props: Props) {
|
||||||
<PaintCounter small />
|
<PaintCounter small />
|
||||||
</ServerBase>
|
</ServerBase>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export default connectState(ServerSidebar, (state) => {
|
export default connectState(ServerSidebar, (state) => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Channel } from "revolt.js";
|
|
||||||
|
|
||||||
import { useLayoutEffect } from "preact/hooks";
|
import { useLayoutEffect } from "preact/hooks";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
import { dispatch } from "../../../redux";
|
import { dispatch } from "../../../redux";
|
||||||
import { Unreads } from "../../../redux/reducers/unreads";
|
import { Unreads } from "../../../redux/reducers/unreads";
|
||||||
|
|
||||||
|
@ -63,12 +62,12 @@ export function mapChannelWithUnread(channel: Channel, unreads: Unreads) {
|
||||||
channel.channel_type === "DirectMessage" ||
|
channel.channel_type === "DirectMessage" ||
|
||||||
channel.channel_type === "Group"
|
channel.channel_type === "Group"
|
||||||
) {
|
) {
|
||||||
last_message_id = channel.last_message?._id;
|
last_message_id = (channel.last_message as { _id: string })?._id;
|
||||||
} else if (channel.channel_type === "TextChannel") {
|
} else if (channel.channel_type === "TextChannel") {
|
||||||
last_message_id = channel.last_message;
|
last_message_id = channel.last_message as string;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
...channel,
|
channel,
|
||||||
unread: undefined,
|
unread: undefined,
|
||||||
alertCount: undefined,
|
alertCount: undefined,
|
||||||
timestamp: channel._id,
|
timestamp: channel._id,
|
||||||
|
@ -85,7 +84,7 @@ export function mapChannelWithUnread(channel: Channel, unreads: Unreads) {
|
||||||
unread = "mention";
|
unread = "mention";
|
||||||
} else if (
|
} else if (
|
||||||
u.last_id &&
|
u.last_id &&
|
||||||
last_message_id.localeCompare(u.last_id) > 0
|
(last_message_id as string).localeCompare(u.last_id) > 0
|
||||||
) {
|
) {
|
||||||
unread = "unread";
|
unread = "unread";
|
||||||
}
|
}
|
||||||
|
@ -95,7 +94,7 @@ export function mapChannelWithUnread(channel: Channel, unreads: Unreads) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...channel,
|
channel,
|
||||||
timestamp: last_message_id ?? channel._id,
|
timestamp: last_message_id ?? channel._id,
|
||||||
unread,
|
unread,
|
||||||
alertCount,
|
alertCount,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useContext, useEffect, useState } from "preact/hooks";
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
import { useData } from "../../../mobx/State";
|
import { useData } from "../../../mobx/State";
|
||||||
import { getState } from "../../../redux";
|
import { getState } from "../../../redux";
|
||||||
|
|
||||||
|
@ -17,11 +18,7 @@ import {
|
||||||
ClientStatus,
|
ClientStatus,
|
||||||
StatusContext,
|
StatusContext,
|
||||||
} from "../../../context/revoltjs/RevoltClient";
|
} from "../../../context/revoltjs/RevoltClient";
|
||||||
import {
|
import { HookContext } from "../../../context/revoltjs/hooks";
|
||||||
HookContext,
|
|
||||||
useChannel,
|
|
||||||
useForceUpdate,
|
|
||||||
} from "../../../context/revoltjs/hooks";
|
|
||||||
|
|
||||||
import CollapsibleSection from "../../common/CollapsibleSection";
|
import CollapsibleSection from "../../common/CollapsibleSection";
|
||||||
import Button from "../../ui/Button";
|
import Button from "../../ui/Button";
|
||||||
|
@ -34,27 +31,19 @@ import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
|
||||||
import { UserButton } from "../items/ButtonItem";
|
import { UserButton } from "../items/ButtonItem";
|
||||||
import { ChannelDebugInfo } from "./ChannelDebugInfo";
|
import { ChannelDebugInfo } from "./ChannelDebugInfo";
|
||||||
|
|
||||||
interface Props {
|
export default function MemberSidebar({ channel }: { channel?: Channel }) {
|
||||||
ctx: HookContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function MemberSidebar(props: { channel?: Channels.Channel }) {
|
|
||||||
const ctx = useForceUpdate();
|
|
||||||
const { channel: cid } = useParams<{ channel: string }>();
|
|
||||||
const channel = props.channel ?? useChannel(cid, ctx);
|
|
||||||
|
|
||||||
switch (channel?.channel_type) {
|
switch (channel?.channel_type) {
|
||||||
case "Group":
|
case "Group":
|
||||||
return <GroupMemberSidebar channel={channel} ctx={ctx} />;
|
return <GroupMemberSidebar channel={channel} />;
|
||||||
case "TextChannel":
|
case "TextChannel":
|
||||||
return <ServerMemberSidebar channel={channel} ctx={ctx} />;
|
return <ServerMemberSidebar channel={channel} />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GroupMemberSidebar = observer(
|
export const GroupMemberSidebar = observer(
|
||||||
({ channel }: Props & { channel: Channels.GroupChannel }) => {
|
({ channel }: { channel: Channel }) => {
|
||||||
const { openScreen } = useIntermediate();
|
const { openScreen } = useIntermediate();
|
||||||
|
|
||||||
const store = useData();
|
const store = useData();
|
||||||
|
@ -77,7 +66,7 @@ export const GroupMemberSidebar = observer(
|
||||||
voiceParticipants.sort((a, b) => a.username.localeCompare(b.username));
|
voiceParticipants.sort((a, b) => a.username.localeCompare(b.username));
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
members.sort((a, b) => {
|
members?.sort((a, b) => {
|
||||||
// ! FIXME: should probably rewrite all this code
|
// ! FIXME: should probably rewrite all this code
|
||||||
const l =
|
const l =
|
||||||
+(
|
+(
|
||||||
|
@ -141,21 +130,21 @@ export const GroupMemberSidebar = observer(
|
||||||
text={
|
text={
|
||||||
<span>
|
<span>
|
||||||
<Text id="app.main.categories.members" />{" "}
|
<Text id="app.main.categories.members" />{" "}
|
||||||
— {channel.recipients.length}
|
— {channel.recipients?.length ?? 0}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}>
|
}>
|
||||||
{members.length === 0 && (
|
{members?.length === 0 && (
|
||||||
<img src={placeholderSVG} loading="eager" />
|
<img src={placeholderSVG} loading="eager" />
|
||||||
)}
|
)}
|
||||||
{members.map(
|
{members?.map(
|
||||||
(user) =>
|
(user) =>
|
||||||
user && (
|
user && (
|
||||||
<UserButton
|
<UserButton
|
||||||
key={user._id}
|
key={user._id}
|
||||||
user={user}
|
user={user}
|
||||||
context={channel}
|
context={channel!}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openScreen({
|
openScreen({
|
||||||
id: "profile",
|
id: "profile",
|
||||||
|
@ -173,7 +162,7 @@ export const GroupMemberSidebar = observer(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const ServerMemberSidebar = observer(
|
export const ServerMemberSidebar = observer(
|
||||||
({ channel }: Props & { channel: Channels.TextChannel }) => {
|
({ channel }: { channel: Channel }) => {
|
||||||
const [members, setMembers] = useState<Servers.Member[] | undefined>(
|
const [members, setMembers] = useState<Servers.Member[] | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
@ -193,7 +182,7 @@ export const ServerMemberSidebar = observer(
|
||||||
typeof members === "undefined"
|
typeof members === "undefined"
|
||||||
) {
|
) {
|
||||||
client.members
|
client.members
|
||||||
.fetchMembers(channel.server)
|
.fetchMembers(channel.server!)
|
||||||
.then((members) => setMembers(members));
|
.then((members) => setMembers(members));
|
||||||
}
|
}
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { internalSubscribe } from "../../lib/eventEmitter";
|
import { internalSubscribe } from "../../lib/eventEmitter";
|
||||||
|
|
||||||
import { User } from "../../mobx";
|
import { Channel, User } from "../../mobx";
|
||||||
|
|
||||||
import { Action } from "../../components/ui/Modal";
|
import { Action } from "../../components/ui/Modal";
|
||||||
|
|
||||||
|
@ -34,15 +34,15 @@ export type Screen =
|
||||||
actions: Action[];
|
actions: Action[];
|
||||||
}
|
}
|
||||||
| ({ id: "special_prompt" } & (
|
| ({ id: "special_prompt" } & (
|
||||||
| { type: "leave_group"; target: Channels.GroupChannel }
|
| { type: "leave_group"; target: Channel }
|
||||||
| { type: "close_dm"; target: Channels.DirectMessageChannel }
|
| { type: "close_dm"; target: Channel }
|
||||||
| { type: "leave_server"; target: Servers.Server }
|
| { type: "leave_server"; target: Servers.Server }
|
||||||
| { type: "delete_server"; target: Servers.Server }
|
| { type: "delete_server"; target: Servers.Server }
|
||||||
| { type: "delete_channel"; target: Channels.TextChannel }
|
| { type: "delete_channel"; target: Channel }
|
||||||
| { type: "delete_message"; target: Channels.Message }
|
| { type: "delete_message"; target: Channels.Message }
|
||||||
| {
|
| {
|
||||||
type: "create_invite";
|
type: "create_invite";
|
||||||
target: Channels.TextChannel | Channels.GroupChannel;
|
target: Channel;
|
||||||
}
|
}
|
||||||
| { type: "kick_member"; target: Servers.Server; user: User }
|
| { type: "kick_member"; target: Servers.Server; user: User }
|
||||||
| { type: "ban_member"; target: Servers.Server; user: User }
|
| { type: "ban_member"; target: Servers.Server; user: User }
|
||||||
|
@ -83,7 +83,7 @@ export type Screen =
|
||||||
| { id: "image_viewer"; attachment?: Attachment; embed?: EmbedImage }
|
| { id: "image_viewer"; attachment?: Attachment; embed?: EmbedImage }
|
||||||
| { id: "modify_account"; field: "username" | "email" | "password" }
|
| { id: "modify_account"; field: "username" | "email" | "password" }
|
||||||
| { id: "profile"; user_id: string }
|
| { id: "profile"; user_id: string }
|
||||||
| { id: "channel_info"; channel_id: string }
|
| { id: "channel_info"; channel: Channel }
|
||||||
| { id: "pending_requests"; users: User[] }
|
| { id: "pending_requests"; users: User[] }
|
||||||
| {
|
| {
|
||||||
id: "user_picker";
|
id: "user_picker";
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { TextReact } from "../../../lib/i18n";
|
import { TextReact } from "../../../lib/i18n";
|
||||||
|
|
||||||
import { User } from "../../../mobx";
|
import { Channel, User } from "../../../mobx";
|
||||||
import { useData } from "../../../mobx/State";
|
import { useData } from "../../../mobx/State";
|
||||||
|
|
||||||
import Message from "../../../components/common/messaging/Message";
|
import Message from "../../../components/common/messaging/Message";
|
||||||
|
@ -55,15 +55,15 @@ export function PromptModal({
|
||||||
}
|
}
|
||||||
|
|
||||||
type SpecialProps = { onClose: () => void } & (
|
type SpecialProps = { onClose: () => void } & (
|
||||||
| { type: "leave_group"; target: Channels.GroupChannel }
|
| { type: "leave_group"; target: Channel }
|
||||||
| { type: "close_dm"; target: Channels.DirectMessageChannel }
|
| { type: "close_dm"; target: Channel }
|
||||||
| { type: "leave_server"; target: Servers.Server }
|
| { type: "leave_server"; target: Servers.Server }
|
||||||
| { type: "delete_server"; target: Servers.Server }
|
| { type: "delete_server"; target: Servers.Server }
|
||||||
| { type: "delete_channel"; target: Channels.TextChannel }
|
| { type: "delete_channel"; target: Channel }
|
||||||
| { type: "delete_message"; target: Channels.Message }
|
| { type: "delete_message"; target: Channels.Message }
|
||||||
| {
|
| {
|
||||||
type: "create_invite";
|
type: "create_invite";
|
||||||
target: Channels.TextChannel | Channels.GroupChannel;
|
target: Channel;
|
||||||
}
|
}
|
||||||
| { type: "kick_member"; target: Servers.Server; user: User }
|
| { type: "kick_member"; target: Servers.Server; user: User }
|
||||||
| { type: "ban_member"; target: Servers.Server; user: User }
|
| { type: "ban_member"; target: Servers.Server; user: User }
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import { X } from "@styled-icons/boxicons-regular";
|
import { X } from "@styled-icons/boxicons-regular";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
import styles from "./ChannelInfo.module.scss";
|
import styles from "./ChannelInfo.module.scss";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
|
|
||||||
import Modal from "../../../components/ui/Modal";
|
import Modal from "../../../components/ui/Modal";
|
||||||
|
|
||||||
import Markdown from "../../../components/markdown/Markdown";
|
import Markdown from "../../../components/markdown/Markdown";
|
||||||
import { useChannel, useForceUpdate } from "../../revoltjs/hooks";
|
import { useClient } from "../../revoltjs/RevoltClient";
|
||||||
|
import { useForceUpdate } from "../../revoltjs/hooks";
|
||||||
import { getChannelName } from "../../revoltjs/util";
|
import { getChannelName } from "../../revoltjs/util";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
channel_id: string;
|
channel: Channel;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ChannelInfo({ channel_id, onClose }: Props) {
|
export const ChannelInfo = observer(({ channel, onClose }: Props) => {
|
||||||
const ctx = useForceUpdate();
|
|
||||||
const channel = useChannel(channel_id, ctx);
|
|
||||||
if (!channel) return null;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
channel.channel_type === "DirectMessage" ||
|
channel.channel_type === "DirectMessage" ||
|
||||||
channel.channel_type === "SavedMessages"
|
channel.channel_type === "SavedMessages"
|
||||||
|
@ -26,19 +26,20 @@ export function ChannelInfo({ channel_id, onClose }: Props) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const client = useClient();
|
||||||
return (
|
return (
|
||||||
<Modal visible={true} onClose={onClose}>
|
<Modal visible={true} onClose={onClose}>
|
||||||
<div className={styles.info}>
|
<div className={styles.info}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<h1>{getChannelName(ctx.client, channel, true)}</h1>
|
<h1>{getChannelName(client, channel, true)}</h1>
|
||||||
<div onClick={onClose}>
|
<div onClick={onClose}>
|
||||||
<X size={36} />
|
<X size={36} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<Markdown content={channel.description} />
|
<Markdown content={channel.description!} />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -27,11 +27,7 @@ import {
|
||||||
StatusContext,
|
StatusContext,
|
||||||
useClient,
|
useClient,
|
||||||
} from "../../revoltjs/RevoltClient";
|
} from "../../revoltjs/RevoltClient";
|
||||||
import {
|
import { useForceUpdate, useUserPermission } from "../../revoltjs/hooks";
|
||||||
useChannels,
|
|
||||||
useForceUpdate,
|
|
||||||
useUserPermission,
|
|
||||||
} from "../../revoltjs/hooks";
|
|
||||||
import { useIntermediate } from "../Intermediate";
|
import { useIntermediate } from "../Intermediate";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -65,7 +61,6 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) {
|
||||||
const [tab, setTab] = useState("profile");
|
const [tab, setTab] = useState("profile");
|
||||||
|
|
||||||
const ctx = useForceUpdate();
|
const ctx = useForceUpdate();
|
||||||
const channels = useChannels(undefined, ctx);
|
|
||||||
const permissions = useUserPermission(client.user!._id, ctx);
|
const permissions = useUserPermission(client.user!._id, ctx);
|
||||||
|
|
||||||
const store = useData();
|
const store = useData();
|
||||||
|
@ -77,6 +72,12 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) {
|
||||||
const user = store.users.get(user_id)!;
|
const user = store.users.get(user_id)!;
|
||||||
const users = mutual?.users.map((id) => store.users.get(id));
|
const users = mutual?.users.map((id) => store.users.get(id));
|
||||||
|
|
||||||
|
const mutualGroups = [...store.channels.values()].filter(
|
||||||
|
(channel) =>
|
||||||
|
channel?.channel_type === "Group" &&
|
||||||
|
channel.recipients!.includes(user_id),
|
||||||
|
);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!user_id) return;
|
if (!user_id) return;
|
||||||
if (typeof profile !== "undefined") setProfile(undefined);
|
if (typeof profile !== "undefined") setProfile(undefined);
|
||||||
|
@ -111,12 +112,6 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) {
|
||||||
}
|
}
|
||||||
}, [profile, status]);
|
}, [profile, status]);
|
||||||
|
|
||||||
const mutualGroups = channels.filter(
|
|
||||||
(channel) =>
|
|
||||||
channel?.channel_type === "Group" &&
|
|
||||||
channel.recipients.includes(user_id),
|
|
||||||
);
|
|
||||||
|
|
||||||
const backgroundURL =
|
const backgroundURL =
|
||||||
profile &&
|
profile &&
|
||||||
client.users.getBackgroundURL(profile, { width: 1000 }, true);
|
client.users.getBackgroundURL(profile, { width: 1000 }, true);
|
||||||
|
|
|
@ -77,13 +77,6 @@ function useObject(
|
||||||
: map.toArray();
|
: map.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
export function useChannels(ids?: string[], context?: HookContext) {
|
||||||
return useObject("channels", ids, context) as (
|
return useObject("channels", ids, context) as (
|
||||||
| Readonly<Channels.Channel>
|
| Readonly<Channels.Channel>
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Client } from "revolt.js";
|
import { Client } from "revolt.js";
|
||||||
import { Channel, Message, User } from "revolt.js/dist/api/objects";
|
import { Message } from "revolt.js/dist/api/objects";
|
||||||
|
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
|
|
||||||
|
import { Channel } from "../../mobx";
|
||||||
|
|
||||||
import { Children } from "../../types/Preact";
|
import { Children } from "../../types/Preact";
|
||||||
|
|
||||||
export function takeError(error: any): string {
|
export function takeError(error: any): string {
|
||||||
|
|
|
@ -34,7 +34,7 @@ import {
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
|
|
||||||
import { User } from "../mobx";
|
import { Channel, User } from "../mobx";
|
||||||
import { useData } from "../mobx/State";
|
import { useData } from "../mobx/State";
|
||||||
import { dispatch } from "../redux";
|
import { dispatch } from "../redux";
|
||||||
import { connectState } from "../redux/connector";
|
import { connectState } from "../redux/connector";
|
||||||
|
@ -53,7 +53,6 @@ import {
|
||||||
useClient,
|
useClient,
|
||||||
} from "../context/revoltjs/RevoltClient";
|
} from "../context/revoltjs/RevoltClient";
|
||||||
import {
|
import {
|
||||||
useChannel,
|
|
||||||
useChannelPermission,
|
useChannelPermission,
|
||||||
useForceUpdate,
|
useForceUpdate,
|
||||||
useServer,
|
useServer,
|
||||||
|
@ -86,7 +85,7 @@ type Action =
|
||||||
| { action: "copy_id"; id: string }
|
| { action: "copy_id"; id: string }
|
||||||
| { action: "copy_selection" }
|
| { action: "copy_selection" }
|
||||||
| { action: "copy_text"; content: string }
|
| { action: "copy_text"; content: string }
|
||||||
| { action: "mark_as_read"; channel: Channels.Channel }
|
| { action: "mark_as_read"; channel: Channel }
|
||||||
| { action: "retry_message"; message: QueuedMessage }
|
| { action: "retry_message"; message: QueuedMessage }
|
||||||
| { action: "cancel_message"; message: QueuedMessage }
|
| { action: "cancel_message"; message: QueuedMessage }
|
||||||
| { action: "mention"; user: string }
|
| { action: "mention"; user: string }
|
||||||
|
@ -115,20 +114,17 @@ type Action =
|
||||||
| { action: "create_channel"; target: Servers.Server }
|
| { action: "create_channel"; target: Servers.Server }
|
||||||
| {
|
| {
|
||||||
action: "create_invite";
|
action: "create_invite";
|
||||||
target:
|
target: Channel;
|
||||||
| Channels.GroupChannel
|
|
||||||
| Channels.TextChannel
|
|
||||||
| Channels.VoiceChannel;
|
|
||||||
}
|
}
|
||||||
| { action: "leave_group"; target: Channels.GroupChannel }
|
| { action: "leave_group"; target: Channel }
|
||||||
| {
|
| {
|
||||||
action: "delete_channel";
|
action: "delete_channel";
|
||||||
target: Channels.TextChannel | Channels.VoiceChannel;
|
target: Channel;
|
||||||
}
|
}
|
||||||
| { action: "close_dm"; target: Channels.DirectMessageChannel }
|
| { action: "close_dm"; target: Channel }
|
||||||
| { action: "leave_server"; target: Servers.Server }
|
| { action: "leave_server"; target: Servers.Server }
|
||||||
| { action: "delete_server"; target: Servers.Server }
|
| { action: "delete_server"; target: Servers.Server }
|
||||||
| { action: "open_notification_options"; channel: Channels.Channel }
|
| { action: "open_notification_options"; channel: Channel }
|
||||||
| { action: "open_settings" }
|
| { action: "open_settings" }
|
||||||
| { action: "open_channel_settings"; id: string }
|
| { action: "open_channel_settings"; id: string }
|
||||||
| { action: "open_server_settings"; id: string }
|
| { action: "open_server_settings"; id: string }
|
||||||
|
@ -172,9 +168,10 @@ function ContextMenus(props: Props) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const message =
|
const message =
|
||||||
data.channel.channel_type === "TextChannel"
|
typeof data.channel.last_message === "string"
|
||||||
? data.channel.last_message
|
? data.channel.last_message
|
||||||
: data.channel.last_message._id;
|
: data.channel.last_message!._id;
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "UNREADS_MARK_READ",
|
type: "UNREADS_MARK_READ",
|
||||||
channel: data.channel._id,
|
channel: data.channel._id,
|
||||||
|
@ -529,8 +526,10 @@ function ContextMenus(props: Props) {
|
||||||
pushDivider();
|
pushDivider();
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = useChannel(cid, forceUpdate);
|
const channel = cid ? store.channels.get(cid) : undefined;
|
||||||
const contextualChannel = useChannel(cxid, forceUpdate);
|
const contextualChannel = cxid
|
||||||
|
? store.channels.get(cxid)
|
||||||
|
: undefined;
|
||||||
const targetChannel = channel ?? contextualChannel;
|
const targetChannel = channel ?? contextualChannel;
|
||||||
|
|
||||||
const user = uid ? store.users.get(uid) : undefined;
|
const user = uid ? store.users.get(uid) : undefined;
|
||||||
|
@ -541,7 +540,7 @@ function ContextMenus(props: Props) {
|
||||||
? targetChannel
|
? targetChannel
|
||||||
: undefined;
|
: undefined;
|
||||||
const server = useServer(
|
const server = useServer(
|
||||||
serverChannel ? serverChannel.server : sid,
|
serverChannel ? serverChannel.server! : sid,
|
||||||
forceUpdate,
|
forceUpdate,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -551,7 +550,10 @@ function ContextMenus(props: Props) {
|
||||||
const serverPermissions = server
|
const serverPermissions = server
|
||||||
? useServerPermission(server._id, forceUpdate)
|
? useServerPermission(server._id, forceUpdate)
|
||||||
: serverChannel
|
: serverChannel
|
||||||
? useServerPermission(serverChannel.server, forceUpdate)
|
? useServerPermission(
|
||||||
|
serverChannel.server!,
|
||||||
|
forceUpdate,
|
||||||
|
)
|
||||||
: 0;
|
: 0;
|
||||||
const userPermissions = user
|
const userPermissions = user
|
||||||
? useUserPermission(user._id, forceUpdate)
|
? useUserPermission(user._id, forceUpdate)
|
||||||
|
@ -819,7 +821,7 @@ function ContextMenus(props: Props) {
|
||||||
generateAction(
|
generateAction(
|
||||||
{
|
{
|
||||||
action: "open_server_channel_settings",
|
action: "open_server_channel_settings",
|
||||||
server: channel.server,
|
server: channel.server!,
|
||||||
id: channel._id,
|
id: channel._id,
|
||||||
},
|
},
|
||||||
"open_channel_settings",
|
"open_channel_settings",
|
||||||
|
|
|
@ -73,7 +73,7 @@ export class User {
|
||||||
|
|
||||||
export class Channel {
|
export class Channel {
|
||||||
_id: string;
|
_id: string;
|
||||||
type: Channels.Channel["channel_type"];
|
channel_type: Channels.Channel["channel_type"];
|
||||||
|
|
||||||
// Direct Message
|
// Direct Message
|
||||||
active: Nullable<boolean> = null;
|
active: Nullable<boolean> = null;
|
||||||
|
@ -98,7 +98,7 @@ export class Channel {
|
||||||
|
|
||||||
constructor(data: Channels.Channel) {
|
constructor(data: Channels.Channel) {
|
||||||
this._id = data._id;
|
this._id = data._id;
|
||||||
this.type = data.channel_type;
|
this.channel_type = data.channel_type;
|
||||||
|
|
||||||
switch (data.channel_type) {
|
switch (data.channel_type) {
|
||||||
case "DirectMessage": {
|
case "DirectMessage": {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { useParams, useHistory } from "react-router-dom";
|
import { useParams, useHistory } from "react-router-dom";
|
||||||
import { Channels } from "revolt.js/dist/api/objects";
|
import { Channels } from "revolt.js/dist/api/objects";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
@ -6,10 +7,10 @@ import { useState } from "preact/hooks";
|
||||||
|
|
||||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||||
|
|
||||||
|
import { Channel as MobXChannel } from "../../mobx";
|
||||||
|
import { useData } from "../../mobx/State";
|
||||||
import { dispatch, getState } from "../../redux";
|
import { dispatch, getState } from "../../redux";
|
||||||
|
|
||||||
import { useChannel, useForceUpdate } from "../../context/revoltjs/hooks";
|
|
||||||
|
|
||||||
import AgeGate from "../../components/common/AgeGate";
|
import AgeGate from "../../components/common/AgeGate";
|
||||||
import MessageBox from "../../components/common/messaging/MessageBox";
|
import MessageBox from "../../components/common/messaging/MessageBox";
|
||||||
import JumpToBottom from "../../components/common/messaging/bars/JumpToBottom";
|
import JumpToBottom from "../../components/common/messaging/bars/JumpToBottom";
|
||||||
|
@ -36,19 +37,19 @@ const ChannelContent = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function Channel({ id }: { id: string }) {
|
export function Channel({ id }: { id: string }) {
|
||||||
const ctx = useForceUpdate();
|
const store = useData();
|
||||||
const channel = useChannel(id, ctx);
|
const channel = store.channels.get(id);
|
||||||
|
|
||||||
if (!channel) return null;
|
if (!channel) return null;
|
||||||
|
|
||||||
if (channel.channel_type === "VoiceChannel") {
|
if (channel.channel_type === "VoiceChannel") {
|
||||||
return <VoiceChannel channel={channel} />;
|
return <VoiceChannel channel={channel} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <TextChannel channel={channel} />;
|
return <TextChannel channel={channel} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MEMBERS_SIDEBAR_KEY = "sidebar_members";
|
const MEMBERS_SIDEBAR_KEY = "sidebar_members";
|
||||||
function TextChannel({ channel }: { channel: Channels.Channel }) {
|
const TextChannel = observer(({ channel }: { channel: MobXChannel }) => {
|
||||||
const [showMembers, setMembers] = useState(
|
const [showMembers, setMembers] = useState(
|
||||||
getState().sectionToggle[MEMBERS_SIDEBAR_KEY] ?? true,
|
getState().sectionToggle[MEMBERS_SIDEBAR_KEY] ?? true,
|
||||||
);
|
);
|
||||||
|
@ -61,7 +62,9 @@ function TextChannel({ channel }: { channel: Channels.Channel }) {
|
||||||
gated={
|
gated={
|
||||||
(channel.channel_type === "TextChannel" ||
|
(channel.channel_type === "TextChannel" ||
|
||||||
channel.channel_type === "Group") &&
|
channel.channel_type === "Group") &&
|
||||||
channel.name.includes("nsfw")
|
channel.name?.includes("nsfw")
|
||||||
|
? true
|
||||||
|
: false
|
||||||
}>
|
}>
|
||||||
<ChannelHeader
|
<ChannelHeader
|
||||||
channel={channel}
|
channel={channel}
|
||||||
|
@ -96,9 +99,9 @@ function TextChannel({ channel }: { channel: Channels.Channel }) {
|
||||||
</ChannelMain>
|
</ChannelMain>
|
||||||
</AgeGate>
|
</AgeGate>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
function VoiceChannel({ channel }: { channel: Channels.Channel }) {
|
function VoiceChannel({ channel }: { channel: MobXChannel }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ChannelHeader channel={channel} />
|
<ChannelHeader channel={channel} />
|
||||||
|
|
|
@ -2,14 +2,13 @@ import { At, Hash, Menu } from "@styled-icons/boxicons-regular";
|
||||||
import { Notepad, Group } from "@styled-icons/boxicons-solid";
|
import { Notepad, Group } from "@styled-icons/boxicons-solid";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Channel } from "revolt.js";
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
import { useContext } from "preact/hooks";
|
import { useContext } from "preact/hooks";
|
||||||
|
|
||||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||||
|
|
||||||
import { User } from "../../mobx";
|
import { Channel, User } from "../../mobx";
|
||||||
import { useData } from "../../mobx/State";
|
import { useData } from "../../mobx/State";
|
||||||
|
|
||||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||||
|
@ -131,7 +130,7 @@ export default observer(({ channel, toggleSidebar }: ChannelHeaderProps) => {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openScreen({
|
openScreen({
|
||||||
id: "channel_info",
|
id: "channel_info",
|
||||||
channel_id: channel._id,
|
channel,
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
<Markdown
|
<Markdown
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default function HeaderActions({
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openScreen({
|
openScreen({
|
||||||
id: "user_picker",
|
id: "user_picker",
|
||||||
omit: channel.recipients,
|
omit: channel.recipients!,
|
||||||
callback: async (users) => {
|
callback: async (users) => {
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
await client.channels.addMember(
|
await client.channels.addMember(
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
|
|
||||||
import { useChannel, useForceUpdate } from "../../../context/revoltjs/hooks";
|
import { useData } from "../../../mobx/State";
|
||||||
|
|
||||||
|
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||||
import { getChannelName } from "../../../context/revoltjs/util";
|
import { getChannelName } from "../../../context/revoltjs/util";
|
||||||
|
|
||||||
const StartBase = styled.div`
|
const StartBase = styled.div`
|
||||||
|
@ -24,17 +27,18 @@ interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ConversationStart({ id }: Props) {
|
export default observer(({ id }: Props) => {
|
||||||
const ctx = useForceUpdate();
|
const store = useData();
|
||||||
const channel = useChannel(id, ctx);
|
const client = useClient();
|
||||||
|
const channel = store.channels.get(id);
|
||||||
if (!channel) return null;
|
if (!channel) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StartBase>
|
<StartBase>
|
||||||
<h1>{getChannelName(ctx.client, channel, true)}</h1>
|
<h1>{getChannelName(client, channel, true)}</h1>
|
||||||
<h4>
|
<h4>
|
||||||
<Text id="app.main.channel.start.group" />
|
<Text id="app.main.channel.start.group" />
|
||||||
</h4>
|
</h4>
|
||||||
</StartBase>
|
</StartBase>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -3,7 +3,9 @@ import { Route, useHistory, useParams } from "react-router-dom";
|
||||||
|
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
|
|
||||||
import { useChannel, useForceUpdate } from "../../context/revoltjs/hooks";
|
import { useData } from "../../mobx/State";
|
||||||
|
|
||||||
|
import { useClient } from "../../context/revoltjs/RevoltClient";
|
||||||
import { getChannelName } from "../../context/revoltjs/util";
|
import { getChannelName } from "../../context/revoltjs/util";
|
||||||
|
|
||||||
import Category from "../../components/ui/Category";
|
import Category from "../../components/ui/Category";
|
||||||
|
@ -14,8 +16,10 @@ import Permissions from "./channel/Permissions";
|
||||||
|
|
||||||
export default function ChannelSettings() {
|
export default function ChannelSettings() {
|
||||||
const { channel: cid } = useParams<{ channel: string }>();
|
const { channel: cid } = useParams<{ channel: string }>();
|
||||||
const ctx = useForceUpdate();
|
|
||||||
const channel = useChannel(cid, ctx);
|
const store = useData();
|
||||||
|
const client = useClient();
|
||||||
|
const channel = store.channels.get(cid);
|
||||||
if (!channel) return null;
|
if (!channel) return null;
|
||||||
if (
|
if (
|
||||||
channel.channel_type === "SavedMessages" ||
|
channel.channel_type === "SavedMessages" ||
|
||||||
|
@ -49,7 +53,7 @@ export default function ChannelSettings() {
|
||||||
category: (
|
category: (
|
||||||
<Category
|
<Category
|
||||||
variant="uniform"
|
variant="uniform"
|
||||||
text={getChannelName(ctx.client, channel, true)}
|
text={getChannelName(client, channel, true)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
id: "overview",
|
id: "overview",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Channels } from "revolt.js/dist/api/objects";
|
import { Channels } from "revolt.js/dist/api/objects";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
|
||||||
|
@ -6,6 +7,8 @@ import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
|
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
|
|
||||||
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
||||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
|
|
||||||
|
@ -13,10 +16,7 @@ import Button from "../../../components/ui/Button";
|
||||||
import InputBox from "../../../components/ui/InputBox";
|
import InputBox from "../../../components/ui/InputBox";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
channel:
|
channel: Channel;
|
||||||
| Channels.GroupChannel
|
|
||||||
| Channels.TextChannel
|
|
||||||
| Channels.VoiceChannel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Row = styled.div`
|
const Row = styled.div`
|
||||||
|
@ -32,13 +32,13 @@ const Row = styled.div`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function Overview({ channel }: Props) {
|
export default observer(({ channel }: Props) => {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
|
|
||||||
const [name, setName] = useState(channel.name);
|
const [name, setName] = useState(channel.name ?? undefined);
|
||||||
const [description, setDescription] = useState(channel.description ?? "");
|
const [description, setDescription] = useState(channel.description ?? "");
|
||||||
|
|
||||||
useEffect(() => setName(channel.name), [channel.name]);
|
useEffect(() => setName(channel.name ?? undefined), [channel.name]);
|
||||||
useEffect(
|
useEffect(
|
||||||
() => setDescription(channel.description ?? ""),
|
() => setDescription(channel.description ?? ""),
|
||||||
[channel.description],
|
[channel.description],
|
||||||
|
@ -127,4 +127,4 @@ export default function Overview({ channel }: Props) {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Channels } from "revolt.js/dist/api/objects";
|
import { Channels } from "revolt.js/dist/api/objects";
|
||||||
import { ChannelPermission } from "revolt.js/dist/api/permissions";
|
import { ChannelPermission } from "revolt.js/dist/api/permissions";
|
||||||
|
|
||||||
import { useContext, useEffect, useState } from "preact/hooks";
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
import { Channel } from "../../../mobx";
|
||||||
|
|
||||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
import { useServer } from "../../../context/revoltjs/hooks";
|
import { useServer } from "../../../context/revoltjs/hooks";
|
||||||
|
|
||||||
|
@ -21,21 +24,18 @@ const DEFAULT_PERMISSION_DM =
|
||||||
ChannelPermission.UploadFiles;
|
ChannelPermission.UploadFiles;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
channel:
|
channel: Channel;
|
||||||
| Channels.GroupChannel
|
|
||||||
| Channels.TextChannel
|
|
||||||
| Channels.VoiceChannel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! FIXME: bad code :)
|
// ! FIXME: bad code :)
|
||||||
export default function Permissions({ channel }: Props) {
|
export default observer(({ channel }: Props) => {
|
||||||
const [selected, setSelected] = useState("default");
|
const [selected, setSelected] = useState("default");
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
|
|
||||||
type R = { name: string; permissions: number };
|
type R = { name: string; permissions: number };
|
||||||
const roles: { [key: string]: R } = {};
|
const roles: { [key: string]: R } = {};
|
||||||
if (channel.channel_type !== "Group") {
|
if (channel.channel_type !== "Group") {
|
||||||
const server = useServer(channel.server);
|
const server = useServer(channel.server!);
|
||||||
const a = server?.roles ?? {};
|
const a = server?.roles ?? {};
|
||||||
for (const b of Object.keys(a)) {
|
for (const b of Object.keys(a)) {
|
||||||
roles[b] = {
|
roles[b] = {
|
||||||
|
@ -110,4 +110,4 @@ export default function Permissions({ channel }: Props) {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { XCircle } from "@styled-icons/boxicons-regular";
|
import { XCircle } from "@styled-icons/boxicons-regular";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
|
import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
|
||||||
import { Route } from "revolt.js/dist/api/routes";
|
import { Route } from "revolt.js/dist/api/routes";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
|
@ -8,8 +9,9 @@ import styles from "./Panes.module.scss";
|
||||||
import { Text } from "preact-i18n";
|
import { Text } from "preact-i18n";
|
||||||
import { useContext, useEffect, useState } from "preact/hooks";
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
|
import { useData } from "../../../mobx/State";
|
||||||
|
|
||||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
import { useChannels } from "../../../context/revoltjs/hooks";
|
|
||||||
|
|
||||||
import ChannelIcon from "../../../components/common/ChannelIcon";
|
import ChannelIcon from "../../../components/common/ChannelIcon";
|
||||||
import UserIcon from "../../../components/common/user/UserIcon";
|
import UserIcon from "../../../components/common/user/UserIcon";
|
||||||
|
@ -25,12 +27,12 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! FIXME: really bad code
|
// ! FIXME: really bad code
|
||||||
export function Categories({ server }: Props) {
|
export const Categories = observer(({ server }: Props) => {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
const channels = useChannels(server.channels) as (
|
const store = useData();
|
||||||
| Channels.TextChannel
|
const channels = server.channels
|
||||||
| Channels.VoiceChannel
|
.map((id) => store.channels.get(id)!)
|
||||||
)[];
|
.filter((x) => typeof x !== "undefined");
|
||||||
|
|
||||||
const [cats, setCats] = useState<Servers.Category[]>(
|
const [cats, setCats] = useState<Servers.Category[]>(
|
||||||
server.categories ?? [],
|
server.categories ?? [],
|
||||||
|
@ -150,4 +152,4 @@ export function Categories({ server }: Props) {
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { useEffect, useState } from "preact/hooks";
|
||||||
import { useData } from "../../../mobx/State";
|
import { useData } from "../../../mobx/State";
|
||||||
|
|
||||||
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
import { useClient } from "../../../context/revoltjs/RevoltClient";
|
||||||
import { useChannels, useForceUpdate } from "../../../context/revoltjs/hooks";
|
|
||||||
import { getChannelName } from "../../../context/revoltjs/util";
|
import { getChannelName } from "../../../context/revoltjs/util";
|
||||||
|
|
||||||
import UserIcon from "../../../components/common/user/UserIcon";
|
import UserIcon from "../../../components/common/user/UserIcon";
|
||||||
|
@ -26,14 +25,15 @@ export const Invites = observer(({ server }: Props) => {
|
||||||
InvitesNS.ServerInvite[] | undefined
|
InvitesNS.ServerInvite[] | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
|
|
||||||
const ctx = useForceUpdate();
|
|
||||||
const channels = useChannels(invites?.map((x) => x.channel) ?? [], ctx);
|
|
||||||
|
|
||||||
const store = useData();
|
const store = useData();
|
||||||
|
const client = useClient();
|
||||||
const users = invites?.map((invite) => store.users.get(invite.creator));
|
const users = invites?.map((invite) => store.users.get(invite.creator));
|
||||||
|
const channels = invites?.map((invite) =>
|
||||||
|
store.channels.get(invite.channel),
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ctx.client.servers
|
client.servers
|
||||||
.fetchInvites(server._id)
|
.fetchInvites(server._id)
|
||||||
.then((invites) => setInvites(invites));
|
.then((invites) => setInvites(invites));
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -57,7 +57,7 @@ export const Invites = observer(({ server }: Props) => {
|
||||||
{typeof invites === "undefined" && <Preloader type="ring" />}
|
{typeof invites === "undefined" && <Preloader type="ring" />}
|
||||||
{invites?.map((invite, index) => {
|
{invites?.map((invite, index) => {
|
||||||
const creator = users![index];
|
const creator = users![index];
|
||||||
const channel = channels.find((x) => x?._id === invite.channel);
|
const channel = channels![index];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -72,14 +72,14 @@ export const Invites = observer(({ server }: Props) => {
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{channel && creator
|
{channel && creator
|
||||||
? getChannelName(ctx.client, channel, true)
|
? getChannelName(client, channel, true)
|
||||||
: "#??"}
|
: "#??"}
|
||||||
</span>
|
</span>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setDelete([...deleting, invite._id]);
|
setDelete([...deleting, invite._id]);
|
||||||
|
|
||||||
await ctx.client.deleteInvite(invite._id);
|
await client.deleteInvite(invite._id);
|
||||||
|
|
||||||
setInvites(
|
setInvites(
|
||||||
invites?.filter(
|
invites?.filter(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
import { Servers, Server } from "revolt.js/dist/api/objects";
|
import { Servers, Server } from "revolt.js/dist/api/objects";
|
||||||
|
|
||||||
import styles from "./Panes.module.scss";
|
import styles from "./Panes.module.scss";
|
||||||
|
@ -7,6 +8,8 @@ import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
|
|
||||||
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
|
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
|
||||||
|
|
||||||
|
import { useData } from "../../../mobx/State";
|
||||||
|
|
||||||
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
import { FileUploader } from "../../../context/revoltjs/FileUploads";
|
||||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||||
import { getChannelName } from "../../../context/revoltjs/util";
|
import { getChannelName } from "../../../context/revoltjs/util";
|
||||||
|
@ -19,8 +22,9 @@ interface Props {
|
||||||
server: Servers.Server;
|
server: Servers.Server;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Overview({ server }: Props) {
|
export const Overview = observer(({ server }: Props) => {
|
||||||
const client = useContext(AppContext);
|
const client = useContext(AppContext);
|
||||||
|
const store = useData();
|
||||||
|
|
||||||
const [name, setName] = useState(server.name);
|
const [name, setName] = useState(server.name);
|
||||||
const [description, setDescription] = useState(server.description ?? "");
|
const [description, setDescription] = useState(server.description ?? "");
|
||||||
|
@ -170,15 +174,14 @@ export function Overview({ server }: Props) {
|
||||||
<option value="disabled">
|
<option value="disabled">
|
||||||
<Text id="general.disabled" />
|
<Text id="general.disabled" />
|
||||||
</option>
|
</option>
|
||||||
{server.channels.map((id) => {
|
{server.channels
|
||||||
const channel = client.channels.get(id);
|
.map((id) => store.channels.get(id)!)
|
||||||
if (!channel) return null;
|
.filter((x) => typeof x !== "undefined")
|
||||||
return (
|
.map((channel) => (
|
||||||
<option value={id}>
|
<option value={channel._id}>
|
||||||
{getChannelName(client, channel, true)}
|
{getChannelName(client, channel, true)}
|
||||||
</option>
|
</option>
|
||||||
);
|
))}
|
||||||
})}
|
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
|
@ -190,4 +193,4 @@ export function Overview({ server }: Props) {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
Loading…
Reference in a new issue