mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-06 17:11:55 +00:00
Add category editor to servers.
This commit is contained in:
@@ -172,9 +172,9 @@ export const MessageContent = styled.div`
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
// overflow: hidden;
|
||||
font-size: var(--text-size);
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: var(--text-size);
|
||||
`;
|
||||
|
||||
export const DetailBase = styled.div`
|
||||
|
||||
@@ -55,11 +55,13 @@ export const TipBase = styled.div<Props>`
|
||||
`}
|
||||
`;
|
||||
|
||||
export default function Tip(props: Props & { children: Children }) {
|
||||
const { children, ...tipProps } = props;
|
||||
export default function Tip(
|
||||
props: Props & { children: Children; hideSeparator?: boolean },
|
||||
) {
|
||||
const { children, hideSeparator, ...tipProps } = props;
|
||||
return (
|
||||
<>
|
||||
<Separator />
|
||||
{!hideSeparator && <Separator />}
|
||||
<TipBase {...tipProps}>
|
||||
<InfoCircle size={20} />
|
||||
<span>{props.children}</span>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ListUl, ListCheck } from "@styled-icons/boxicons-regular";
|
||||
import { ListUl, ListCheck, ListMinus } from "@styled-icons/boxicons-regular";
|
||||
import { XSquare, Share, Group } from "@styled-icons/boxicons-solid";
|
||||
import { Route, useHistory, useParams } from "react-router-dom";
|
||||
|
||||
@@ -11,6 +11,7 @@ import Category from "../../components/ui/Category";
|
||||
|
||||
import { GenericSettings } from "./GenericSettings";
|
||||
import { Bans } from "./server/Bans";
|
||||
import { Categories } from "./server/Categories";
|
||||
import { Invites } from "./server/Invites";
|
||||
import { Members } from "./server/Members";
|
||||
import { Overview } from "./server/Overview";
|
||||
@@ -41,6 +42,13 @@ export default function ServerSettings() {
|
||||
<Text id="app.settings.server_pages.overview.title" />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "categories",
|
||||
icon: <ListMinus size={20} />,
|
||||
title: (
|
||||
<Text id="app.settings.server_pages.categories.title" />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "members",
|
||||
icon: <Group size={20} />,
|
||||
@@ -68,6 +76,9 @@ export default function ServerSettings() {
|
||||
},
|
||||
]}
|
||||
children={[
|
||||
<Route path="/server/:server/settings/categories">
|
||||
<Categories server={server} />
|
||||
</Route>,
|
||||
<Route path="/server/:server/settings/members">
|
||||
<RequiresOnline>
|
||||
<Members server={server} />
|
||||
|
||||
@@ -83,8 +83,10 @@ export default function Permissions({ channel }: Props) {
|
||||
</Checkbox>
|
||||
);
|
||||
})}
|
||||
<h2>channel per??issions</h2>
|
||||
<h2>channel permissions</h2>
|
||||
{Object.keys(ChannelPermission).map((perm) => {
|
||||
if (perm === "View") return null;
|
||||
|
||||
const value =
|
||||
ChannelPermission[perm as keyof typeof ChannelPermission];
|
||||
if (value & DEFAULT_PERMISSION_DM) {
|
||||
|
||||
153
src/pages/settings/server/Categories.tsx
Normal file
153
src/pages/settings/server/Categories.tsx
Normal file
@@ -0,0 +1,153 @@
|
||||
import { XCircle } from "@styled-icons/boxicons-regular";
|
||||
import isEqual from "lodash.isequal";
|
||||
import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
|
||||
import { Route } from "revolt.js/dist/api/routes";
|
||||
import { ulid } from "ulid";
|
||||
|
||||
import styles from "./Panes.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { AppContext } from "../../../context/revoltjs/RevoltClient";
|
||||
import { useChannels } from "../../../context/revoltjs/hooks";
|
||||
|
||||
import ChannelIcon from "../../../components/common/ChannelIcon";
|
||||
import UserIcon from "../../../components/common/user/UserIcon";
|
||||
import Button from "../../../components/ui/Button";
|
||||
import ComboBox from "../../../components/ui/ComboBox";
|
||||
import IconButton from "../../../components/ui/IconButton";
|
||||
import InputBox from "../../../components/ui/InputBox";
|
||||
import Preloader from "../../../components/ui/Preloader";
|
||||
import Tip from "../../../components/ui/Tip";
|
||||
|
||||
interface Props {
|
||||
server: Servers.Server;
|
||||
}
|
||||
|
||||
// ! FIXME: really bad code
|
||||
export function Categories({ server }: Props) {
|
||||
const client = useContext(AppContext);
|
||||
const channels = useChannels(server.channels) as (
|
||||
| Channels.TextChannel
|
||||
| Channels.VoiceChannel
|
||||
)[];
|
||||
|
||||
const [cats, setCats] = useState<Servers.Category[]>(
|
||||
server.categories ?? [],
|
||||
);
|
||||
|
||||
const [name, setName] = useState("");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tip warning>This section is under construction.</Tip>
|
||||
<p>
|
||||
<Button
|
||||
contrast
|
||||
disabled={isEqual(server.categories ?? [], cats)}
|
||||
onClick={() =>
|
||||
client.servers.edit(server._id, { categories: cats })
|
||||
}>
|
||||
save categories
|
||||
</Button>
|
||||
</p>
|
||||
<h2>categories</h2>
|
||||
{cats.map((category) => (
|
||||
<div style={{ background: "var(--hover)" }} key={category.id}>
|
||||
<InputBox
|
||||
value={category.title}
|
||||
onChange={(e) =>
|
||||
setCats(
|
||||
cats.map((y) =>
|
||||
y.id === category.id
|
||||
? {
|
||||
...y,
|
||||
title: e.currentTarget.value,
|
||||
}
|
||||
: y,
|
||||
),
|
||||
)
|
||||
}
|
||||
contrast
|
||||
/>
|
||||
<Button
|
||||
contrast
|
||||
onClick={() =>
|
||||
setCats(cats.filter((x) => x.id !== category.id))
|
||||
}>
|
||||
delete {category.title}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
<h2>create new</h2>
|
||||
<p>
|
||||
<InputBox
|
||||
value={name}
|
||||
onChange={(e) => setName(e.currentTarget.value)}
|
||||
contrast
|
||||
/>
|
||||
<Button
|
||||
contrast
|
||||
onClick={() => {
|
||||
setName("");
|
||||
setCats([
|
||||
...cats,
|
||||
{
|
||||
id: ulid(),
|
||||
title: name,
|
||||
channels: [],
|
||||
},
|
||||
]);
|
||||
}}>
|
||||
create
|
||||
</Button>
|
||||
</p>
|
||||
<h2>channels</h2>
|
||||
{channels.map((channel) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
gap: "12px",
|
||||
alignItems: "center",
|
||||
}}>
|
||||
<div style={{ flexShrink: 0 }}>
|
||||
<ChannelIcon target={channel} size={24} />{" "}
|
||||
<span>{channel.name}</span>
|
||||
</div>
|
||||
<ComboBox
|
||||
style={{ flexGrow: 1 }}
|
||||
value={
|
||||
cats.find((x) =>
|
||||
x.channels.includes(channel._id),
|
||||
)?.id ?? "none"
|
||||
}
|
||||
onChange={(e) =>
|
||||
setCats(
|
||||
cats.map((x) => {
|
||||
return {
|
||||
...x,
|
||||
channels: [
|
||||
...x.channels.filter(
|
||||
(y) => y !== channel._id,
|
||||
),
|
||||
...(e.currentTarget.value ===
|
||||
x.id
|
||||
? [channel._id]
|
||||
: []),
|
||||
],
|
||||
};
|
||||
}),
|
||||
)
|
||||
}>
|
||||
<option value="none">Uncategorised</option>
|
||||
{cats.map((x) => (
|
||||
<option value={x.id}>{x.title}</option>
|
||||
))}
|
||||
</ComboBox>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export const REPO_URL = "https://gitlab.insrt.uk/revolt/revite/-/commit";
|
||||
export const GIT_REVISION = "__GIT_REVISION__";
|
||||
export const GIT_BRANCH = "__GIT_BRANCH__";
|
||||
export const REPO_URL: string =
|
||||
"https://gitlab.insrt.uk/revolt/revite/-/commit";
|
||||
export const GIT_REVISION: string = "__GIT_REVISION__";
|
||||
export const GIT_BRANCH: string = "__GIT_BRANCH__";
|
||||
|
||||
Reference in New Issue
Block a user