import { useState, useCallback, useId } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; import type { IntlShape } from 'react-intl'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; import { AxiosError } from 'axios'; import { apiSubscribeByEmail } from '@/mastodon/api/accounts'; import type { ValidationErrorResponse, ValidationError, } from '@/mastodon/api_types/errors'; import { useAppSelector } from '@/mastodon/store'; import { Button } from '../button'; import { DisplayName } from '../display_name'; import type { FieldStatus } from '../form_fields'; import { TextInputField } from '../form_fields/text_input_field'; import classes from './styles.module.scss'; const messages = defineMessages({ emailInvalid: { id: 'email_subscriptions.validation.email.invalid', defaultMessage: 'Invalid email address', }, emailBlocked: { id: 'email_subscriptions.validation.email.blocked', defaultMessage: 'Blocked email provider', }, email: { id: 'email_subscriptions.email', defaultMessage: 'Email', }, }); const isValidationErrorResponse = ( data: unknown, ): data is ValidationErrorResponse => typeof data === 'object' && data !== null && 'error' in data && 'details' in data; const fieldStatusFromErrors = ( intl: IntlShape, errors: ValidationError[], ): FieldStatus | undefined => { const error = errors[0]; if (!error) { return undefined; } let message: string; switch (error.error) { case 'ERR_BLOCKED': message = intl.formatMessage(messages.emailBlocked); break; case 'ERR_INVALID': default: message = intl.formatMessage(messages.emailInvalid); break; } return { variant: 'error', message }; }; export const AccountSubscriptionForm: React.FC<{ accountId: string }> = ({ accountId, }) => { const account = useAppSelector((state) => state.accounts.get(accountId)); const intl = useIntl(); const accessibilityId = useId(); const [email, setEmail] = useState(''); const [submitting, setSubmitting] = useState(false); const [submitted, setSubmitted] = useState(false); const [errors, setErrors] = useState>({}); const handleChange = useCallback>( (e) => { setEmail(e.target.value); setErrors({}); }, [], ); const handleSubmit = useCallback( (e) => { e.preventDefault(); if (email.length === 0) { return; } setSubmitting(true); apiSubscribeByEmail(accountId, email) .then(() => { setSubmitting(false); setSubmitted(true); }) .catch((err: unknown) => { setSubmitting(false); if (err instanceof AxiosError && err.response) { const data: unknown = err.response.data; if (isValidationErrorResponse(data)) { if (data.details.email?.some((k) => k.error === 'ERR_TAKEN')) { setSubmitted(true); return; } setErrors(data.details); } } }); }, [accountId, email], ); if (submitted) { return (
); } return (
, }} />
{str} }} />
); };