diff --git a/components/modal/modals/ServerIdentity.tsx b/components/modal/modals/ServerIdentity.tsx new file mode 100644 index 00000000..4a6983d7 --- /dev/null +++ b/components/modal/modals/ServerIdentity.tsx @@ -0,0 +1,345 @@ +import { BiRegularX, BiSolidEditAlt, BiSolidSave } from "solid-icons/bi"; +import { Show, createSignal } from "solid-js"; + +import { ServerMember } from "revolt.js"; + +import { clientController } from "@revolt/client"; +import { useTranslation } from "@revolt/i18n"; +import { userInformation } from "@revolt/markdown/users"; +import { + Avatar, + Button, + CategoryButton, + Column, + Input, + NonBreakingText, + OverflowingText, + Preloader, + Row, + Typography, + Username, + styled, + useTheme, +} from "@revolt/ui"; +import { generateTypographyCSS } from "@revolt/ui/components/design/atoms/display/Typography"; + +import { PropGenerator } from "../types"; + +const [avatarId, setAvatarId] = createSignal(null); +const [uploading, setUploading] = createSignal(); + +async function uploadToAutumn(file) { + setUploading(true); + try { + const url = "https://autumn.revolt.chat/avatars"; + const formData = new FormData(); + formData.append("file", file); + + const response = await fetch(url, { + method: "POST", + headers: { + "x-session-token": `${clientController.getCurrentClient()?.sessionId}`, + }, + body: formData, + }); + + const json = await response.json(); + setAvatarId(json["id"]); + setUploading(false); + + return json; + } catch (error) { + console.error("POST request error:", error); + setUploading(false); + } +} + +/** + * Modal to display server identity + */ + +const ServerIdentity: PropGenerator<"server_identity"> = (props) => { + const t = useTranslation(); + const [nickname, setNickname] = createSignal(); + + setUploading(false); + + let fileInputRef: HTMLInputElement | null = null; + const openFilePicker = () => { + fileInputRef?.click(); + }; + + const handleFileSelect = async (event: Event) => { + const file = event.target?.files[0]; + const json = await uploadToAutumn(file); + + if (json !== undefined) { + props.member.edit({ avatar: avatarId() }); + } + }; + + return { + title: ( + + + {t("app.special.popovers.server_identity.title", { + server: props.member.server?.name as string, + })} + + + ), + children: ( + <> + + + {t("app.special.popovers.server_identity.nickname")} + + + + setNickname(event.currentTarget.value)} + /> + + + + + + + + + + + {t("app.special.popovers.server_identity.avatar")} + + + + + +
+ + {}}> + {t("app.settings.actions.upload")} + + + + + + { + props.member.edit({ remove: ["Avatar"] }); + }} + > + {t("app.settings.actions.remove")} + + +
+ + + {t("app.settings.actions.max_filesize", { + filesize: "4.00 MB", + })} + +
+
+ + + + {t("app.special.modals.actions.preview")} + + + + +
+ + ), + }; +}; + +export default ServerIdentity; + +function AvatarEdit(props: { member: ServerMember }) { + const [isHovered, setIsHovered] = createSignal(false); + + function onMouseEnter() { + setIsHovered(true); + } + + function onMouseLeave() { + setIsHovered(false); + } + + const user = () => userInformation(props.member.user, props.member); + + let fileInputRef: HTMLInputElement | null = null; + const openFilePicker = () => { + fileInputRef?.click(); + }; + + const handleFileSelect = async (event: Event) => { + const file = event.target?.files[0]; + const json = await uploadToAutumn(file); + + if (json !== undefined) { + props.member.edit({ avatar: avatarId() }); + } + }; + return ( +
+
+ + + + + + + {" "} + + + +
+ + + + +
+ ); +} + +function Preview(props: { member: ServerMember }) { + const theme = useTheme(); + + /** + * Right-side message content + */ + const Content = styled(Column)` + gap: 3px; + min-width: 0; + overflow: hidden; + max-height: 200vh; + padding-inline-end: ${(props) => props.theme!.gap.lg}; + `; + + /** + * Information text + */ + const InfoText = styled(Row)` + color: ${(props) => props.theme!.colours["foreground-400"]}; + ${(props) => generateTypographyCSS(props.theme!, "small")} + `; + + const user = () => userInformation(props.member.user, props.member); + + return ( + + + + + + + + + + + + Today at 19:00 + + + + content + + + + ); +} diff --git a/components/modal/modals/ServerInfo.tsx b/components/modal/modals/ServerInfo.tsx index 4caac9bc..2e6dd970 100644 --- a/components/modal/modals/ServerInfo.tsx +++ b/components/modal/modals/ServerInfo.tsx @@ -47,7 +47,7 @@ const ServerInfo: PropGenerator<"server_info"> = (props, onClose) => { }); return true; }, - children: "Edit Identity", + children: t("app.context_menu.edit_identity"), palette: "secondary", }, { diff --git a/components/modal/modals/index.tsx b/components/modal/modals/index.tsx index 1ebb7f80..c8a51431 100644 --- a/components/modal/modals/index.tsx +++ b/components/modal/modals/index.tsx @@ -29,6 +29,7 @@ import mfa_flow from "./MFAFlow"; import mfa_recovery from "./MFARecovery"; import onboarding from "./Onboarding"; import rename_session from "./RenameSession"; +import server_identity from "./ServerIdentity"; import server_info from "./ServerInfo"; import settings from "./Settings"; import sign_out_sessions from "./SignOutSessions"; @@ -60,6 +61,7 @@ const Modals: Record> = { onboarding, rename_session, server_info, + server_identity, settings, signed_out, sign_out_sessions,