diff --git a/src/context/intermediate/Intermediate.tsx b/src/context/intermediate/Intermediate.tsx
index 51be4c1d..ac3f8f47 100644
--- a/src/context/intermediate/Intermediate.tsx
+++ b/src/context/intermediate/Intermediate.tsx
@@ -86,6 +86,10 @@ export type Screen =
id: "user_picker";
omit?: string[];
callback: (users: string[]) => Promise
;
+ }
+ | {
+ id: "server_identity";
+ server: Server;
};
export const IntermediateContext = createContext({
diff --git a/src/context/intermediate/Popovers.tsx b/src/context/intermediate/Popovers.tsx
index fa0f0b7d..199dc349 100644
--- a/src/context/intermediate/Popovers.tsx
+++ b/src/context/intermediate/Popovers.tsx
@@ -11,6 +11,7 @@ import { ChannelInfo } from "./popovers/ChannelInfo";
import { ImageViewer } from "./popovers/ImageViewer";
import { ModifyAccountModal } from "./popovers/ModifyAccount";
import { PendingRequests } from "./popovers/PendingRequests";
+import { ServerIdentityModal } from "./popovers/ServerIdentityModal";
import { UserPicker } from "./popovers/UserPicker";
import { UserProfile } from "./popovers/UserProfile";
@@ -40,6 +41,8 @@ export default function Popovers() {
return ;
case "special_input":
return ;
+ case "server_identity":
+ return ;
}
return null;
diff --git a/src/context/intermediate/popovers/ServerIdentityModal.tsx b/src/context/intermediate/popovers/ServerIdentityModal.tsx
new file mode 100644
index 00000000..eb6e449e
--- /dev/null
+++ b/src/context/intermediate/popovers/ServerIdentityModal.tsx
@@ -0,0 +1,71 @@
+import { observer } from "mobx-react-lite";
+import { Server } from "revolt.js/dist/maps/Servers";
+
+import { useEffect, useState } from "preact/hooks";
+
+import Button from "../../../components/ui/Button";
+import InputBox from "../../../components/ui/InputBox";
+import Modal from "../../../components/ui/Modal";
+import Overline from "../../../components/ui/Overline";
+
+import { FileUploader } from "../../revoltjs/FileUploads";
+import { useClient } from "../../revoltjs/RevoltClient";
+
+interface Props {
+ server: Server;
+ onClose: () => void;
+}
+
+export const ServerIdentityModal = observer(({ server, onClose }: Props) => {
+ const client = useClient();
+ const member = client.members.getKey({
+ server: server._id,
+ user: client.user!._id,
+ });
+
+ if (!member) return null;
+
+ const [nickname, setNickname] = useState("");
+ useEffect(() => setNickname(member.nickname ?? ""), [member.nickname]);
+
+ return (
+
+ Nickname
+
+ setNickname(e.currentTarget.value)}
+ />
+
+
+
+
+
+
+
+ Avatar
+ member.edit({ avatar })}
+ remove={() => member.edit({ remove: "Avatar" })}
+ defaultPreview={client.generateFileURL(
+ member.avatar ?? undefined,
+ { max_side: 256 },
+ true,
+ )}
+ previewURL={client.generateFileURL(
+ member.avatar ?? undefined,
+ { max_side: 256 },
+ true,
+ )}
+ />
+
+ );
+});
diff --git a/src/lib/ContextMenus.tsx b/src/lib/ContextMenus.tsx
index 97a8d416..c3b33e1f 100644
--- a/src/lib/ContextMenus.tsx
+++ b/src/lib/ContextMenus.tsx
@@ -114,6 +114,7 @@ type Action =
| { action: "close_dm"; target: Channel }
| { action: "leave_server"; target: Server }
| { action: "delete_server"; target: Server }
+ | { action: "edit_identity"; target: Server }
| { action: "open_notification_options"; channel: Channel }
| { action: "open_settings" }
| { action: "open_channel_settings"; id: string }
@@ -408,6 +409,13 @@ function ContextMenus(props: Props) {
} as unknown as Screen);
break;
+ case "edit_identity":
+ openScreen({
+ id: "server_identity",
+ server: data.target,
+ });
+ break;
+
case "ban_member":
case "kick_member":
openScreen({
@@ -850,6 +858,17 @@ function ContextMenus(props: Props) {
}
if (sid && server) {
+ if (
+ serverPermissions &
+ ServerPermission.ChangeNickname ||
+ serverPermissions &
+ ServerPermission.ChangeAvatar
+ )
+ generateAction(
+ { action: "edit_identity", target: server },
+ "edit_identity",
+ );
+
if (
serverPermissions &
ServerPermission.ManageServer