feat: add ServerInfo, port ChannelInfo

This commit is contained in:
Paul Makles 2022-06-30 19:06:49 +01:00
parent 8501e33103
commit 1664aaee15
10 changed files with 133 additions and 14 deletions

2
external/lang vendored

@ -1 +1 @@
Subproject commit 50838167d7d253de9d08715e6a6070c3ddc9fcc2 Subproject commit d4bc47b729c7e69ce97216469692b39f4cd1640e

View file

@ -9,6 +9,7 @@ import { Text } from "preact-i18n";
import { IconButton } from "@revoltchat/ui"; import { IconButton } from "@revoltchat/ui";
import { modalController } from "../../controllers/modals/ModalController";
import Tooltip from "./Tooltip"; import Tooltip from "./Tooltip";
interface Props { interface Props {
@ -60,6 +61,9 @@ const ServerBanner = styled.div<Omit<Props, "server">>`
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
flex-grow: 1; flex-grow: 1;
cursor: pointer;
color: var(--foreground);
} }
} }
`; `;
@ -121,7 +125,13 @@ export default observer(({ server }: Props) => {
</svg> </svg>
</Tooltip> </Tooltip>
) : undefined} ) : undefined}
<div className="title">{server.name}</div> <a
className="title"
onClick={() =>
modalController.push({ type: "server_info", server })
}>
{server.name}
</a>
{server.havePermission("ManageServer") && ( {server.havePermission("ManageServer") && (
<Link to={`/server/${server._id}/settings`}> <Link to={`/server/${server._id}/settings`}>
<IconButton> <IconButton>

View file

@ -1,4 +1,6 @@
.markdown { .markdown {
user-select: text;
:global(.emoji) { :global(.emoji) {
object-fit: contain; object-fit: contain;

View file

@ -3,7 +3,6 @@ import { useContext } from "preact/hooks";
import { IntermediateContext, useIntermediate } from "./Intermediate"; import { IntermediateContext, useIntermediate } from "./Intermediate";
import { SpecialInputModal } from "./modals/Input"; import { SpecialInputModal } from "./modals/Input";
import { SpecialPromptModal } from "./modals/Prompt"; import { SpecialPromptModal } from "./modals/Prompt";
import { ChannelInfo } from "./popovers/ChannelInfo";
import { CreateBotModal } from "./popovers/CreateBot"; import { CreateBotModal } from "./popovers/CreateBot";
import { ImageViewer } from "./popovers/ImageViewer"; import { ImageViewer } from "./popovers/ImageViewer";
import { UserPicker } from "./popovers/UserPicker"; import { UserPicker } from "./popovers/UserPicker";
@ -27,9 +26,6 @@ export default function Popovers() {
return <UserPicker {...screen} onClose={onClose} />; return <UserPicker {...screen} onClose={onClose} />;
case "image_viewer": case "image_viewer":
return <ImageViewer {...screen} onClose={onClose} />; return <ImageViewer {...screen} onClose={onClose} />;
case "channel_info":
// @ts-expect-error someone figure this out :)
return <ChannelInfo {...screen} onClose={onClose} />;
case "create_bot": case "create_bot":
// @ts-expect-error someone figure this out :) // @ts-expect-error someone figure this out :)
return <CreateBotModal onClose={onClose} {...screen} />; return <CreateBotModal onClose={onClose} {...screen} />;

View file

@ -18,6 +18,7 @@ import { __thisIsAHack } from "../../context/intermediate/Intermediate";
// import { determineLink } from "../../lib/links"; // import { determineLink } from "../../lib/links";
import Changelog from "./components/Changelog"; import Changelog from "./components/Changelog";
import ChannelInfo from "./components/ChannelInfo";
import Clipboard from "./components/Clipboard"; import Clipboard from "./components/Clipboard";
import Error from "./components/Error"; import Error from "./components/Error";
import LinkWarning from "./components/LinkWarning"; import LinkWarning from "./components/LinkWarning";
@ -28,6 +29,7 @@ import ModifyAccount from "./components/ModifyAccount";
import OutOfDate from "./components/OutOfDate"; import OutOfDate from "./components/OutOfDate";
import PendingFriendRequests from "./components/PendingFriendRequests"; import PendingFriendRequests from "./components/PendingFriendRequests";
import ServerIdentity from "./components/ServerIdentity"; import ServerIdentity from "./components/ServerIdentity";
import ServerInfo from "./components/ServerInfo";
import ShowToken from "./components/ShowToken"; import ShowToken from "./components/ShowToken";
import SignOutSessions from "./components/SignOutSessions"; import SignOutSessions from "./components/SignOutSessions";
import SignedOut from "./components/SignedOut"; import SignedOut from "./components/SignedOut";
@ -54,6 +56,8 @@ class ModalController<T extends Modal> {
isVisible: computed, isVisible: computed,
}); });
this.close = this.close.bind(this);
// Inject globally // Inject globally
injectController("modal", this); injectController("modal", this);
} }
@ -82,6 +86,13 @@ class ModalController<T extends Modal> {
); );
} }
/**
* Close the top modal
*/
close() {
this.pop("close");
}
/** /**
* Remove the keyed modal from the stack * Remove the keyed modal from the stack
*/ */
@ -208,6 +219,7 @@ class ModalControllerExtended extends ModalController<Modal> {
export const modalController = new ModalControllerExtended({ export const modalController = new ModalControllerExtended({
changelog: Changelog, changelog: Changelog,
channel_info: ChannelInfo,
clipboard: Clipboard, clipboard: Clipboard,
error: Error, error: Error,
link_warning: LinkWarning, link_warning: LinkWarning,
@ -218,6 +230,7 @@ export const modalController = new ModalControllerExtended({
out_of_date: OutOfDate, out_of_date: OutOfDate,
pending_friend_requests: PendingFriendRequests, pending_friend_requests: PendingFriendRequests,
server_identity: ServerIdentity, server_identity: ServerIdentity,
server_info: ServerInfo,
show_token: ShowToken, show_token: ShowToken,
signed_out: SignedOut, signed_out: SignedOut,
sign_out_sessions: SignOutSessions, sign_out_sessions: SignOutSessions,

View file

@ -0,0 +1,29 @@
import { X } from "@styled-icons/boxicons-regular";
import { Column, H1, IconButton, Modal, Row } from "@revoltchat/ui";
import Markdown from "../../../components/markdown/Markdown";
import { modalController } from "../ModalController";
import { ModalProps } from "../types";
export default function ChannelInfo({
channel,
...props
}: ModalProps<"channel_info">) {
return (
<Modal
{...props}
title={
<Row centred>
<Column grow>
<H1>{`#${channel.name}`}</H1>
</Column>
<IconButton onClick={modalController.close}>
<X size={36} />
</IconButton>
</Row>
}>
<Markdown content={channel.description!} />
</Modal>
);
}

View file

@ -0,0 +1,48 @@
import { X } from "@styled-icons/boxicons-regular";
import { Text } from "preact-i18n";
import { Column, H1, IconButton, Modal, Row } from "@revoltchat/ui";
import Markdown from "../../../components/markdown/Markdown";
import { report } from "../../safety";
import { modalController } from "../ModalController";
import { ModalProps } from "../types";
export default function ServerInfo({
server,
...props
}: ModalProps<"server_info">) {
return (
<Modal
{...props}
title={
<Row centred>
<Column grow>
<H1>{server.name}</H1>
</Column>
<IconButton onClick={modalController.close}>
<X size={36} />
</IconButton>
</Row>
}
actions={[
{
onClick: () =>
modalController.push({
type: "server_identity",
member: server.member!,
}),
children: "Edit Identity",
palette: "primary",
},
{
onClick: () => report(server),
children: <Text id="app.special.modals.actions.report" />,
palette: "error",
},
]}>
<Markdown content={server.description!} />
</Modal>
);
}

View file

@ -1,4 +1,4 @@
import { API, Client, User, Member } from "revolt.js"; import { API, Client, User, Member, Channel, Server } from "revolt.js";
export type Modal = { export type Modal = {
key?: string; key?: string;
@ -72,6 +72,14 @@ export type Modal = {
| { | {
type: "signed_out"; type: "signed_out";
} }
| {
type: "channel_info";
channel: Channel;
}
| {
type: "server_info";
server: Server;
}
); );
export type ModalProps<T extends Modal["type"]> = Modal & { type: T } & { export type ModalProps<T extends Modal["type"]> = Modal & { type: T } & {

View file

@ -0,0 +1,16 @@
import { Server } from "revolt.js";
export function report(object: Server) {
let type;
if (object instanceof Server) {
type = "Server";
}
window.open(
`mailto:abuse@revolt.chat?subject=${encodeURIComponent(
`${type} Report`,
)}&body=${encodeURIComponent(
`${type} ID: ${object._id}\nWrite more information here!`,
)}`,
);
}

View file

@ -1,19 +1,18 @@
import { At, Hash } from "@styled-icons/boxicons-regular"; import { At, Hash } from "@styled-icons/boxicons-regular";
import { Notepad, Group } from "@styled-icons/boxicons-solid"; import { Notepad, Group } from "@styled-icons/boxicons-solid";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { Channel } from "revolt.js"; import { Channel, User } from "revolt.js";
import { User } from "revolt.js";
import styled from "styled-components/macro"; import styled from "styled-components/macro";
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
import { useIntermediate } from "../../context/intermediate/Intermediate";
import { getChannelName } from "../../context/revoltjs/util"; import { getChannelName } from "../../context/revoltjs/util";
import { useStatusColour } from "../../components/common/user/UserIcon"; import { useStatusColour } from "../../components/common/user/UserIcon";
import UserStatus from "../../components/common/user/UserStatus"; import UserStatus from "../../components/common/user/UserStatus";
import Markdown from "../../components/markdown/Markdown"; import Markdown from "../../components/markdown/Markdown";
import { PageHeader } from "../../components/ui/Header"; import { PageHeader } from "../../components/ui/Header";
import { modalController } from "../../controllers/modals/ModalController";
import HeaderActions from "./actions/HeaderActions"; import HeaderActions from "./actions/HeaderActions";
export interface ChannelHeaderProps { export interface ChannelHeaderProps {
@ -65,8 +64,6 @@ const Info = styled.div`
`; `;
export default observer(({ channel }: ChannelHeaderProps) => { export default observer(({ channel }: ChannelHeaderProps) => {
const { openScreen } = useIntermediate();
const name = getChannelName(channel); const name = getChannelName(channel);
let icon, recipient: User | undefined; let icon, recipient: User | undefined;
switch (channel.channel_type) { switch (channel.channel_type) {
@ -114,8 +111,8 @@ export default observer(({ channel }: ChannelHeaderProps) => {
<span <span
className="desc" className="desc"
onClick={() => onClick={() =>
openScreen({ modalController.push({
id: "channel_info", type: "channel_info",
channel, channel,
}) })
}> }>