mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-07 01:15:28 +00:00
chore: delete intermediate
This commit is contained in:
@@ -13,7 +13,6 @@ import ModalRenderer from "../controllers/modals/ModalRenderer";
|
||||
import Locale from "./Locale";
|
||||
import Theme from "./Theme";
|
||||
import { history } from "./history";
|
||||
import Intermediate from "./intermediate/Intermediate";
|
||||
|
||||
const uiContext = {
|
||||
Link,
|
||||
@@ -39,10 +38,8 @@ export default function Context({ children }: { children: Children }) {
|
||||
<Router history={history}>
|
||||
<UIProvider value={uiContext}>
|
||||
<Locale>
|
||||
<Intermediate>
|
||||
{children}
|
||||
<Binder />
|
||||
</Intermediate>
|
||||
<>{children}</>
|
||||
<Binder />
|
||||
<ModalRenderer />
|
||||
</Locale>
|
||||
</UIProvider>
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
import { Prompt } from "react-router";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { API, Channel, Message, Server, User } from "revolt.js";
|
||||
|
||||
import { createContext } from "preact";
|
||||
import {
|
||||
StateUpdater,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "preact/hooks";
|
||||
|
||||
import type { Action } from "@revoltchat/ui/esm/components/design/atoms/display/Modal";
|
||||
|
||||
import { internalSubscribe } from "../../lib/eventEmitter";
|
||||
import { determineLink } from "../../lib/links";
|
||||
|
||||
import { useApplicationState } from "../../mobx/State";
|
||||
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import Modals from "./Modals";
|
||||
|
||||
export type Screen =
|
||||
| { id: "none" }
|
||||
|
||||
// Modals
|
||||
| { id: "signed_out" }
|
||||
| { id: "error"; error: string }
|
||||
| { id: "clipboard"; text: string }
|
||||
| { id: "token_reveal"; token: string; username: string }
|
||||
| { id: "external_link_prompt"; link: string }
|
||||
| { id: "sessions"; confirm: () => void }
|
||||
| {
|
||||
id: "_prompt";
|
||||
question: Children;
|
||||
content?: Children;
|
||||
actions: Action[];
|
||||
}
|
||||
| ({ id: "special_prompt" } & (
|
||||
| { type: "leave_group"; target: Channel }
|
||||
| { type: "close_dm"; target: Channel }
|
||||
| { type: "leave_server"; target: Server }
|
||||
| { type: "delete_server"; target: Server }
|
||||
| { type: "delete_channel"; target: Channel }
|
||||
| {
|
||||
type: "delete_bot";
|
||||
target: string;
|
||||
name: string;
|
||||
cb?: () => void;
|
||||
}
|
||||
| { type: "delete_message"; target: Message }
|
||||
| {
|
||||
type: "create_invite";
|
||||
target: Channel;
|
||||
}
|
||||
| { type: "kick_member"; target: Server; user: User }
|
||||
| { type: "ban_member"; target: Server; user: User }
|
||||
| { type: "unfriend_user"; target: User }
|
||||
| { type: "block_user"; target: User }
|
||||
| {
|
||||
type: "create_channel";
|
||||
target: Server;
|
||||
cb?: (
|
||||
channel: Channel & {
|
||||
channel_type: "TextChannel" | "VoiceChannel";
|
||||
},
|
||||
) => void;
|
||||
}
|
||||
| { type: "create_category"; target: Server }
|
||||
))
|
||||
| ({ id: "special_input" } & (
|
||||
| {
|
||||
type:
|
||||
| "create_group"
|
||||
| "create_server"
|
||||
| "set_custom_status"
|
||||
| "add_friend";
|
||||
}
|
||||
| {
|
||||
type: "create_role";
|
||||
server: Server;
|
||||
callback: (id: string) => void;
|
||||
}
|
||||
))
|
||||
| {
|
||||
id: "_input";
|
||||
question: Children;
|
||||
field: Children;
|
||||
defaultValue?: string;
|
||||
callback: (value: string) => Promise<void>;
|
||||
}
|
||||
| {
|
||||
id: "onboarding";
|
||||
callback: (
|
||||
username: string,
|
||||
loginAfterSuccess?: true,
|
||||
) => Promise<void>;
|
||||
}
|
||||
|
||||
// Pop-overs
|
||||
| { id: "profile"; user_id: string }
|
||||
| {
|
||||
id: "user_picker";
|
||||
omit?: string[];
|
||||
callback: (users: string[]) => Promise<void>;
|
||||
}
|
||||
| { id: "image_viewer"; attachment?: API.File; embed?: API.Image }
|
||||
| { id: "channel_info"; channel: Channel }
|
||||
| { id: "pending_requests"; users: User[] }
|
||||
| { id: "modify_account"; field: "username" | "email" | "password" }
|
||||
| { id: "create_bot"; onCreate: (bot: API.Bot) => void }
|
||||
| {
|
||||
id: "server_identity";
|
||||
server: Server;
|
||||
};
|
||||
|
||||
export const IntermediateContext = createContext({
|
||||
screen: { id: "none" },
|
||||
focusTaken: false,
|
||||
});
|
||||
|
||||
export const IntermediateActionsContext = createContext<{
|
||||
openLink: (href?: string, trusted?: boolean) => boolean;
|
||||
openScreen: (screen: Screen) => void;
|
||||
writeClipboard: (text: string) => void;
|
||||
}>({
|
||||
openLink: null!,
|
||||
openScreen: null!,
|
||||
writeClipboard: null!,
|
||||
});
|
||||
|
||||
interface Props {
|
||||
children: Children;
|
||||
}
|
||||
|
||||
export let __thisIsAHack: StateUpdater<Screen>;
|
||||
|
||||
export default function Intermediate(props: Props) {
|
||||
const [screen, openScreen] = useState<Screen>({ id: "none" });
|
||||
__thisIsAHack = openScreen;
|
||||
const history = useHistory();
|
||||
|
||||
const value = {
|
||||
screen,
|
||||
focusTaken: screen.id !== "none",
|
||||
};
|
||||
|
||||
const actions = useMemo(() => {
|
||||
return {
|
||||
openLink: (href?: string, trusted?: boolean) => {
|
||||
return modalController.openLink(href, trusted);
|
||||
},
|
||||
openScreen: (screen: Screen) => openScreen(screen),
|
||||
writeClipboard: (a: string) => modalController.writeText(a),
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const openProfile = (user_id: string) =>
|
||||
modalController.push({ type: "user_profile", user_id });
|
||||
const navigate = (path: string) => history.push(path);
|
||||
|
||||
const subs = [
|
||||
internalSubscribe(
|
||||
"Intermediate",
|
||||
"openProfile",
|
||||
openProfile as (...args: unknown[]) => void,
|
||||
),
|
||||
internalSubscribe(
|
||||
"Intermediate",
|
||||
"navigate",
|
||||
navigate as (...args: unknown[]) => void,
|
||||
),
|
||||
];
|
||||
|
||||
return () => subs.map((unsub) => unsub());
|
||||
}, [history]);
|
||||
|
||||
return (
|
||||
<IntermediateContext.Provider value={value}>
|
||||
<IntermediateActionsContext.Provider value={actions}>
|
||||
{screen.id !== "onboarding" && props.children}
|
||||
<Modals
|
||||
{...value}
|
||||
{...actions}
|
||||
key={
|
||||
screen.id
|
||||
} /** By specifying a key, we reset state whenever switching screen. */
|
||||
/>
|
||||
<Prompt
|
||||
when={[
|
||||
"modify_account",
|
||||
"special_prompt",
|
||||
"special_input",
|
||||
"image_viewer",
|
||||
"profile",
|
||||
"channel_info",
|
||||
"pending_requests",
|
||||
"user_picker",
|
||||
].includes(screen.id)}
|
||||
message={(_, action) => {
|
||||
if (action === "POP") {
|
||||
openScreen({ id: "none" });
|
||||
setTimeout(() => history.push(history.location), 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}}
|
||||
/>
|
||||
</IntermediateActionsContext.Provider>
|
||||
</IntermediateContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const useIntermediate = () => useContext(IntermediateActionsContext);
|
||||
@@ -1,25 +0,0 @@
|
||||
//import { isModalClosing } from "../../components/ui/Modal";
|
||||
import { Screen } from "./Intermediate";
|
||||
import { InputModal } from "./modals/Input";
|
||||
import { PromptModal } from "./modals/Prompt";
|
||||
|
||||
export interface Props {
|
||||
screen: Screen;
|
||||
openScreen: (screen: Screen) => void;
|
||||
}
|
||||
|
||||
export default function Modals({ screen, openScreen }: Props) {
|
||||
const onClose = () =>
|
||||
//isModalClosing || screen.id === "onboarding"
|
||||
openScreen({ id: "none" });
|
||||
// : internalEmit("Modal", "close");
|
||||
|
||||
switch (screen.id) {
|
||||
case "_prompt":
|
||||
return <PromptModal onClose={onClose} {...screen} />;
|
||||
case "_input":
|
||||
return <InputModal onClose={onClose} {...screen} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { useContext } from "preact/hooks";
|
||||
|
||||
import { IntermediateContext, useIntermediate } from "./Intermediate";
|
||||
import { SpecialInputModal } from "./modals/Input";
|
||||
import { SpecialPromptModal } from "./modals/Prompt";
|
||||
|
||||
export default function Popovers() {
|
||||
const { screen } = useContext(IntermediateContext);
|
||||
const { openScreen } = useIntermediate();
|
||||
|
||||
const onClose = () =>
|
||||
//isModalClosing
|
||||
openScreen({ id: "none" });
|
||||
//: internalEmit("Modal", "close");
|
||||
|
||||
switch (screen.id) {
|
||||
case "special_prompt":
|
||||
// @ts-expect-error someone figure this out :)
|
||||
return <SpecialPromptModal onClose={onClose} {...screen} />;
|
||||
case "special_input":
|
||||
// @ts-expect-error someone figure this out :)
|
||||
return <SpecialInputModal onClose={onClose} {...screen} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import { useHistory } from "react-router";
|
||||
import { Server } from "revolt.js";
|
||||
|
||||
import { Text } from "preact-i18n";
|
||||
import { useContext, useState } from "preact/hooks";
|
||||
|
||||
import { Category, InputBox, Modal } from "@revoltchat/ui";
|
||||
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { I18nError } from "../../Locale";
|
||||
import { takeError } from "../../revoltjs/util";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
question: Children;
|
||||
field?: Children;
|
||||
description?: Children;
|
||||
defaultValue?: string;
|
||||
callback: (value: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export function InputModal({
|
||||
onClose,
|
||||
question,
|
||||
field,
|
||||
description,
|
||||
defaultValue,
|
||||
callback,
|
||||
}: Props) {
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [value, setValue] = useState(defaultValue ?? "");
|
||||
const [error, setError] = useState<undefined | string>(undefined);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={question}
|
||||
description={description}
|
||||
disabled={processing}
|
||||
actions={[
|
||||
{
|
||||
confirmation: true,
|
||||
children: <Text id="app.special.modals.actions.ok" />,
|
||||
onClick: () => {
|
||||
setProcessing(true);
|
||||
callback(value)
|
||||
.then(onClose)
|
||||
.catch((err) => {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
children: <Text id="app.special.modals.actions.cancel" />,
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
onClose={onClose}>
|
||||
{field ? (
|
||||
<Category>
|
||||
<I18nError error={error}>{field}</I18nError>
|
||||
</Category>
|
||||
) : (
|
||||
error && (
|
||||
<Category>
|
||||
<I18nError error={error} />
|
||||
</Category>
|
||||
)
|
||||
)}
|
||||
<InputBox
|
||||
value={value}
|
||||
style={{ width: "100%" }}
|
||||
onChange={(e) => setValue(e.currentTarget.value)}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
type SpecialProps = { onClose: () => void } & (
|
||||
| {
|
||||
type:
|
||||
| "create_group"
|
||||
| "create_server"
|
||||
| "set_custom_status"
|
||||
| "add_friend";
|
||||
}
|
||||
| { type: "create_role"; server: Server; callback: (id: string) => void }
|
||||
);
|
||||
|
||||
export function SpecialInputModal(props: SpecialProps) {
|
||||
const history = useHistory();
|
||||
const client = useClient();
|
||||
|
||||
const { onClose } = props;
|
||||
switch (props.type) {
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
.invite {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
code {
|
||||
padding: 1em;
|
||||
user-select: all;
|
||||
font-size: 1.4em;
|
||||
text-align: center;
|
||||
font-family: var(--monospace-font);
|
||||
}
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -1,561 +0,0 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Channel, Message as MessageI, Server, User } from "revolt.js";
|
||||
import { ulid } from "ulid";
|
||||
|
||||
import styles from "./Prompt.module.scss";
|
||||
import { Text } from "preact-i18n";
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { Category, Modal, InputBox, Radio } from "@revoltchat/ui";
|
||||
import type { Action } from "@revoltchat/ui/esm/components/design/atoms/display/Modal";
|
||||
|
||||
import { TextReact } from "../../../lib/i18n";
|
||||
|
||||
import Message from "../../../components/common/messaging/Message";
|
||||
import UserIcon from "../../../components/common/user/UserIcon";
|
||||
import { useClient } from "../../../controllers/client/ClientController";
|
||||
import { I18nError } from "../../Locale";
|
||||
import { takeError } from "../../revoltjs/util";
|
||||
import { useIntermediate } from "../Intermediate";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
question: Children;
|
||||
description?: Children;
|
||||
content?: Children;
|
||||
disabled?: boolean;
|
||||
actions: Action[];
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export function PromptModal({
|
||||
onClose,
|
||||
question,
|
||||
description,
|
||||
content,
|
||||
actions,
|
||||
disabled,
|
||||
error,
|
||||
}: Props) {
|
||||
return (
|
||||
<Modal
|
||||
title={question}
|
||||
description={description}
|
||||
actions={actions}
|
||||
onClose={onClose}
|
||||
disabled={disabled}>
|
||||
{error && (
|
||||
<Category>
|
||||
<I18nError error={error} />
|
||||
</Category>
|
||||
)}
|
||||
{content}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
type SpecialProps = { onClose: () => void } & (
|
||||
| { type: "leave_group"; target: Channel }
|
||||
| { type: "close_dm"; target: Channel }
|
||||
| { type: "delete_channel"; target: Channel }
|
||||
| {
|
||||
type: "create_invite";
|
||||
target: Channel;
|
||||
}
|
||||
|
||||
| { type: "leave_server"; target: Server }
|
||||
| { type: "delete_server"; target: Server }
|
||||
|
||||
| { type: "delete_bot"; target: string; name: string; cb?: () => void }
|
||||
|
||||
| { type: "delete_message"; target: MessageI }
|
||||
|
||||
| { type: "kick_member"; target: Server; user: User }
|
||||
| { type: "ban_member"; target: Server; user: User }
|
||||
|
||||
| { type: "unfriend_user"; target: User }
|
||||
| { type: "block_user"; target: User }
|
||||
|
||||
| {
|
||||
type: "create_channel";
|
||||
target: Server;
|
||||
cb?: (
|
||||
channel: Channel & {
|
||||
channel_type: "TextChannel" | "VoiceChannel";
|
||||
},
|
||||
) => void;
|
||||
}
|
||||
|
||||
| { type: "create_category"; target: Server }
|
||||
);
|
||||
|
||||
export const SpecialPromptModal = observer((props: SpecialProps) => {
|
||||
const client = useClient();
|
||||
const history = useHistory();
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [error, setError] = useState<undefined | string>(undefined);
|
||||
|
||||
const { onClose } = props;
|
||||
switch (props.type) {
|
||||
case "leave_group":
|
||||
case "close_dm":
|
||||
case "leave_server":
|
||||
case "delete_server":
|
||||
case "delete_channel":
|
||||
case "delete_bot":
|
||||
case "unfriend_user":
|
||||
case "block_user": {
|
||||
const EVENTS = {
|
||||
close_dm: ["confirm_close_dm", "close"],
|
||||
delete_server: ["confirm_delete", "delete"],
|
||||
delete_channel: ["confirm_delete", "delete"],
|
||||
delete_bot: ["confirm_delete", "delete"],
|
||||
leave_group: ["confirm_leave", "leave"],
|
||||
leave_server: ["confirm_leave", "leave"],
|
||||
unfriend_user: ["unfriend_user", "remove"],
|
||||
block_user: ["block_user", "block"],
|
||||
};
|
||||
|
||||
const event = EVENTS[props.type];
|
||||
let name;
|
||||
switch (props.type) {
|
||||
case "unfriend_user":
|
||||
case "block_user":
|
||||
name = props.target.username;
|
||||
break;
|
||||
case "close_dm":
|
||||
name = props.target.recipient?.username;
|
||||
break;
|
||||
case "delete_bot":
|
||||
name = props.name;
|
||||
break;
|
||||
default:
|
||||
name = props.target.name;
|
||||
}
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={
|
||||
<Text
|
||||
id={`app.special.modals.prompt.${event[0]}`}
|
||||
fields={{ name }}
|
||||
/>
|
||||
}
|
||||
description={
|
||||
<TextReact
|
||||
id={`app.special.modals.prompt.${event[0]}_long`}
|
||||
fields={{ name: <b>{name}</b> }}
|
||||
/>
|
||||
}
|
||||
actions={[
|
||||
{
|
||||
confirmation: true,
|
||||
palette: "error",
|
||||
children: (
|
||||
<Text
|
||||
id={`app.special.modals.actions.${event[1]}`}
|
||||
/>
|
||||
),
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
|
||||
try {
|
||||
switch (props.type) {
|
||||
case "unfriend_user":
|
||||
await props.target.removeFriend();
|
||||
break;
|
||||
case "block_user":
|
||||
await props.target.blockUser();
|
||||
break;
|
||||
case "leave_group":
|
||||
case "close_dm":
|
||||
case "delete_channel":
|
||||
case "leave_server":
|
||||
case "delete_server":
|
||||
if (props.type != "delete_channel")
|
||||
history.push("/");
|
||||
props.target.delete();
|
||||
break;
|
||||
case "delete_bot":
|
||||
client.bots.delete(props.target);
|
||||
props.cb?.();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "delete_message": {
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id={"app.context_menu.delete_message"} />}
|
||||
description={
|
||||
<Text
|
||||
id={`app.special.modals.prompt.confirm_delete_message_long`}
|
||||
/>
|
||||
}
|
||||
actions={[
|
||||
{
|
||||
confirmation: true,
|
||||
palette: "error",
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.delete" />
|
||||
),
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
|
||||
try {
|
||||
props.target.delete();
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
palette: "plain",
|
||||
},
|
||||
]}
|
||||
content={
|
||||
<Message message={props.target} head={true} contrast />
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "create_invite": {
|
||||
const [code, setCode] = useState("abcdef");
|
||||
const { writeClipboard } = useIntermediate();
|
||||
|
||||
useEffect(() => {
|
||||
setProcessing(true);
|
||||
|
||||
props.target
|
||||
.createInvite()
|
||||
.then(({ _id }) => setCode(_id))
|
||||
.catch((err) => setError(takeError(err)))
|
||||
.finally(() => setProcessing(false));
|
||||
}, [props.target]);
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id={`app.context_menu.create_invite`} />}
|
||||
actions={[
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.ok" />
|
||||
),
|
||||
confirmation: true,
|
||||
onClick: onClose,
|
||||
},
|
||||
{
|
||||
children: <Text id="app.context_menu.copy_link" />,
|
||||
onClick: () =>
|
||||
writeClipboard(
|
||||
`${window.location.protocol}//${window.location.host}/invite/${code}`,
|
||||
),
|
||||
},
|
||||
]}
|
||||
content={
|
||||
processing ? (
|
||||
<Text id="app.special.modals.prompt.create_invite_generate" />
|
||||
) : (
|
||||
<div className={styles.invite}>
|
||||
<Text id="app.special.modals.prompt.create_invite_created" />
|
||||
<code>{code}</code>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "kick_member": {
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id={`app.context_menu.kick_member`} />}
|
||||
actions={[
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.kick" />
|
||||
),
|
||||
palette: "error",
|
||||
confirmation: true,
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
|
||||
try {
|
||||
client.members
|
||||
.getKey({
|
||||
server: props.target._id,
|
||||
user: props.user._id,
|
||||
})
|
||||
?.kick();
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
content={
|
||||
<div className={styles.column}>
|
||||
<UserIcon target={props.user} size={64} />
|
||||
<Text
|
||||
id="app.special.modals.prompt.confirm_kick"
|
||||
fields={{ name: props.user?.username }}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "ban_member": {
|
||||
const [reason, setReason] = useState<string | undefined>(undefined);
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id={`app.context_menu.ban_member`} />}
|
||||
actions={[
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.ban" />
|
||||
),
|
||||
palette: "error",
|
||||
|
||||
confirmation: true,
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
|
||||
try {
|
||||
await props.target.banUser(props.user._id, {
|
||||
reason,
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
content={
|
||||
<div className={styles.column}>
|
||||
<UserIcon target={props.user} size={64} />
|
||||
<Text
|
||||
id="app.special.modals.prompt.confirm_ban"
|
||||
fields={{ name: props.user?.username }}
|
||||
/>
|
||||
<Category>
|
||||
<Text id="app.special.modals.prompt.confirm_ban_reason" />
|
||||
</Category>
|
||||
<InputBox
|
||||
value={reason ?? ""}
|
||||
onChange={(e) =>
|
||||
setReason(e.currentTarget.value)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "create_channel": {
|
||||
const [name, setName] = useState("");
|
||||
const [type, setType] = useState<"Text" | "Voice">("Text");
|
||||
const history = useHistory();
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id="app.context_menu.create_channel" />}
|
||||
actions={[
|
||||
{
|
||||
confirmation: true,
|
||||
palette: "secondary",
|
||||
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.create" />
|
||||
),
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
|
||||
try {
|
||||
const channel =
|
||||
await props.target.createChannel({
|
||||
type,
|
||||
name,
|
||||
});
|
||||
|
||||
if (props.cb) {
|
||||
props.cb(channel as any);
|
||||
} else {
|
||||
history.push(
|
||||
`/server/${props.target._id}/channel/${channel._id}`,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
content={
|
||||
<>
|
||||
<Category>
|
||||
<Text id="app.main.servers.channel_type" />
|
||||
</Category>
|
||||
<Radio
|
||||
title={
|
||||
<Text id="app.main.servers.text_channel" />
|
||||
}
|
||||
value={type === "Text"}
|
||||
onSelect={() => setType("Text")}
|
||||
/>
|
||||
<Radio
|
||||
title={
|
||||
<Text id="app.main.servers.voice_channel" />
|
||||
}
|
||||
value={type === "Voice"}
|
||||
onSelect={() => setType("Voice")}
|
||||
/>
|
||||
<Category>
|
||||
<Text id="app.main.servers.channel_name" />
|
||||
</Category>
|
||||
<InputBox
|
||||
value={name}
|
||||
onChange={(e) => setName(e.currentTarget.value)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case "create_category": {
|
||||
const [name, setName] = useState("");
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
onClose={onClose}
|
||||
question={<Text id="app.context_menu.create_category" />}
|
||||
actions={[
|
||||
{
|
||||
confirmation: true,
|
||||
palette: "secondary",
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.create" />
|
||||
),
|
||||
onClick: async () => {
|
||||
setProcessing(true);
|
||||
try {
|
||||
props.target.edit({
|
||||
categories: [
|
||||
...(props.target.categories ?? []),
|
||||
{
|
||||
id: ulid(),
|
||||
title: name,
|
||||
channels: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
setProcessing(false);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(takeError(err));
|
||||
setProcessing(false);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
children: (
|
||||
<Text id="app.special.modals.actions.cancel" />
|
||||
),
|
||||
onClick: onClose,
|
||||
},
|
||||
]}
|
||||
content={
|
||||
<>
|
||||
<Category>
|
||||
<Text id="app.main.servers.category_name" />
|
||||
</Category>
|
||||
<InputBox
|
||||
value={name}
|
||||
onChange={(e) => setName(e.currentTarget.value)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
disabled={processing}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
.list {
|
||||
max-width: 100%;
|
||||
max-height: 360px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import { determineFileSize } from "../../lib/fileSize";
|
||||
|
||||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import { modalController } from "../../controllers/modals/ModalController";
|
||||
import { useIntermediate } from "../intermediate/Intermediate";
|
||||
import { takeError } from "./util";
|
||||
|
||||
type BehaviourType =
|
||||
@@ -112,7 +111,6 @@ export function grabFiles(
|
||||
|
||||
export function FileUploader(props: Props) {
|
||||
const { fileType, maxFileSize, remove } = props;
|
||||
const { openScreen } = useIntermediate();
|
||||
const client = useClient();
|
||||
|
||||
const [uploading, setUploading] = useState(false);
|
||||
@@ -243,7 +241,7 @@ export function FileUploader(props: Props) {
|
||||
document.removeEventListener("dragover", dragover);
|
||||
document.removeEventListener("drop", drop);
|
||||
};
|
||||
}, [openScreen, props, props.append]);
|
||||
}, [props, props.append]);
|
||||
}
|
||||
|
||||
if (props.style === "icon" || props.style === "banner") {
|
||||
|
||||
Reference in New Issue
Block a user