mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-25 08:30:58 -05:00
feat: add ServerInfo
, port ChannelInfo
This commit is contained in:
parent
8501e33103
commit
1664aaee15
10 changed files with 133 additions and 14 deletions
2
external/lang
vendored
2
external/lang
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 50838167d7d253de9d08715e6a6070c3ddc9fcc2
|
Subproject commit d4bc47b729c7e69ce97216469692b39f4cd1640e
|
|
@ -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>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
.markdown {
|
.markdown {
|
||||||
|
user-select: text;
|
||||||
|
|
||||||
:global(.emoji) {
|
:global(.emoji) {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
|
|
||||||
|
|
|
@ -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} />;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
29
src/controllers/modals/components/ChannelInfo.tsx
Normal file
29
src/controllers/modals/components/ChannelInfo.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
48
src/controllers/modals/components/ServerInfo.tsx
Normal file
48
src/controllers/modals/components/ServerInfo.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
|
@ -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 } & {
|
||||||
|
|
16
src/controllers/safety/index.ts
Normal file
16
src/controllers/safety/index.ts
Normal 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!`,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
}
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
|
|
Loading…
Reference in a new issue