import MDInput from "@tensamin/markdown/input"; import { useMTP } from "@tensamin/mtp"; import { mtp } from "@tensamin/shared/data"; import { useStorage } from "@tensamin/storage/context"; import { Avatar, AvatarFallback, AvatarImage, Button, cn, Input, useIsMobile } from "@methanium/ui"; import { useUser, type User } from "@tensamin/user/context"; import { Check } from "lucide-react"; import { useEffect, useRef, useState } from "react"; async function prepImage(file: File, size = 300, quality = 0.8): Promise { const bitmap = await createImageBitmap(file); const canvas = document.createElement("canvas"); canvas.width = size; canvas.height = size; const context = canvas.getContext("2d"); if (!context) throw new Error("Could not get canvas context"); const scale = Math.max(size / bitmap.width, size / bitmap.height); const width = bitmap.width * scale; const height = bitmap.height * scale; context.drawImage(bitmap, (size - width) / 2, (size - height) / 2, width, height); return canvas.toDataURL("image/webp", quality); } export default function Page() { const { get } = useUser(); const { load } = useStorage(); const { send } = useMTP(); const isMobile = useIsMobile(); const [currentUser, setCurrentUser] = useState(null); const [draftUser, setDraftUser] = useState>({}); const [errorMessage, setErrorMessage] = useState(""); const [saveSucceeded, setSaveSucceeded] = useState(false); const avatarUploadRef = useRef(null); const draftInitializedRef = useRef(false); const effectiveAvatar = draftUser.Avatar === "none" ? undefined : draftUser.Avatar; const updateDraftUser = (updater: (previous: Partial) => Partial) => { setSaveSucceeded(false); setErrorMessage(""); setDraftUser(updater); }; useEffect(() => { void (async () => setCurrentUser(await get(await load("user_id"))))(); }, [get, load]); useEffect(() => { if (!currentUser || draftInitializedRef.current) return; setDraftUser(currentUser); draftInitializedRef.current = true; }, [currentUser]); async function handleAvatarUpload(file: File) { const avatar = await prepImage(file); updateDraftUser((previous) => ({ ...previous, avatar })); if (avatarUploadRef.current) avatarUploadRef.current.value = ""; } if (!currentUser) return

Loading...

; return <> event.target.files?.[0] && handleAvatarUpload(event.target.files[0])} type="file" />
{draftUser.Display?.slice(0, 2).toUpperCase() || currentUser.Display.slice(0, 2).toUpperCase()}

Avatar

GIFs are supported in decentralised mode or with Tensamin Premium.
Maximum file size is 16mb.

updateDraftUser((previous) => ({ ...previous, display: event.target.value }))} placeholder="Display Name" value={draftUser.Display || ""} /> updateDraftUser((previous) => ({ ...previous, username: event.target.value }))} placeholder="Username" value={draftUser.Username || ""} /> updateDraftUser((previous) => ({ ...previous, about: value }))} value={draftUser.About || ""} /> {errorMessage &&

{errorMessage}

}
; }