/** * Renders the inline editor of the signed-in user's description, under their * profile's header. * * @module */ import { t } from "@lingui/core/macro"; import { Trans } from "@lingui/react/macro"; import { Controller, FormProvider } from "react-hook-form"; import { API_URL } from "../../config/api.ts"; import { VALIDATION } from "../../../shared/validation.ts"; import type { Wire } from "../../../shared/api.ts"; import type { PublicUser, UpdateUserRequest } from "../../../shared/user.ts"; import { expectOk } from "../../utils/shared/api.ts"; import { useAuth } from "../../hooks/auth/useAuth.ts"; import { useApiForm } from "../../hooks/form/useApiForm.ts"; import { TextEditor } from "../editor/TextEditor.tsx"; import { FormError } from "../form/FormError.tsx"; import { SubmitButton } from "../form/SubmitButton.tsx"; /** * Passed to {@link DescriptionEditor} by `ProfileDescription`, which shows it * in place of the description while editing. */ export interface DescriptionEditorProps { initialDescription: string; onCancel: () => void; onSaved: (description: string | undefined) => void; } /** * Renders the description's Markdown editor, saved to `PATCH /api/me`. * Other browsers see the change through the socket's `user_updated` event. */ export function DescriptionEditor( { initialDescription, onCancel, onSaved }: DescriptionEditorProps, ): React.JSX.Element { const { authFetch } = useAuth(); const form = useApiForm<{ description: string }>({ defaultValues: { description: initialDescription }, }); const description = form.watch("description"); const submitting = form.formState.isSubmitting; const onSubmit = form.submit(async ({ description }) => { const trimmed = description.trim(); // Sent even when empty, since the server keeps the old one when it is left // out. await expectOk>( await authFetch(`${API_URL}/api/me`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify( { description: trimmed } satisfies UpdateUserRequest, ), }), ); onSaved(trimmed || undefined); }); return (
( void onSubmit()} onCancel={submitting ? undefined : onCancel} placeholder={t`Who am I?`} autoResize maxLength={VALIDATION.USER_DESCRIPTION_MAX} /> )} />
Saving…} disabled={description.length > VALIDATION.USER_DESCRIPTION_MAX} > Save
); }