diff --git a/app/soapbox/features/auth-login/components/login-form.tsx b/app/soapbox/features/auth-login/components/login-form.tsx index a919986710..9a4768903d 100644 --- a/app/soapbox/features/auth-login/components/login-form.tsx +++ b/app/soapbox/features/auth-login/components/login-form.tsx @@ -3,13 +3,18 @@ import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { Button, Form, FormActions, FormGroup, Input, Stack } from 'soapbox/components/ui'; +import { useFeatures } from 'soapbox/hooks'; import ConsumersList from './consumers-list'; const messages = defineMessages({ username: { id: 'login.fields.username_label', - defaultMessage: 'Email or username', + defaultMessage: 'E-mail or username', + }, + email: { + id: 'login.fields.email_label', + defaultMessage: 'E-mail address', }, password: { id: 'login.fields.password_placeholder', @@ -24,6 +29,10 @@ interface ILoginForm { const LoginForm: React.FC = ({ isLoading, handleSubmit }) => { const intl = useIntl(); + const features = useFeatures(); + + const usernameLabel = intl.formatMessage(features.logInWithUsername ? messages.username : messages.email); + const passwordLabel = intl.formatMessage(messages.password); return (
@@ -33,10 +42,10 @@ const LoginForm: React.FC = ({ isLoading, handleSubmit }) => {
- + = ({ isLoading, handleSubmit }) => { = ({ isLoading, handleSubmit }) => { } > { const dispatch = useAppDispatch(); const intl = useIntl(); + const features = useFeatures(); const [isLoading, setIsLoading] = useState(false); const [success, setSuccess] = useState(false); @@ -43,7 +45,7 @@ const PasswordReset = () => {
- + { const dispatch = useAppDispatch(); const intl = useIntl(); + const features = useFeatures(); const account = useOwnAccount(); const soapboxConfig = useSoapboxConfig(); @@ -123,7 +125,7 @@ const Header = () => { value={username} onChange={(event) => setUsername(event.target.value.trim())} type='text' - placeholder={intl.formatMessage(messages.username)} + placeholder={intl.formatMessage(features.logInWithUsername ? messages.username : messages.email)} className='max-w-[200px]' autoCorrect='off' autoCapitalize='off' diff --git a/app/soapbox/features/ui/components/navbar.tsx b/app/soapbox/features/ui/components/navbar.tsx index 6cfb287280..422d225619 100644 --- a/app/soapbox/features/ui/components/navbar.tsx +++ b/app/soapbox/features/ui/components/navbar.tsx @@ -9,7 +9,7 @@ import { openSidebar } from 'soapbox/actions/sidebar'; import SiteLogo from 'soapbox/components/site-logo'; import { Avatar, Button, Form, HStack, IconButton, Input, Tooltip } from 'soapbox/components/ui'; import Search from 'soapbox/features/compose/components/search'; -import { useAppDispatch, useOwnAccount, useRegistrationStatus } from 'soapbox/hooks'; +import { useAppDispatch, useFeatures, useOwnAccount, useRegistrationStatus } from 'soapbox/hooks'; import ProfileDropdown from './profile-dropdown'; @@ -17,7 +17,8 @@ import type { AxiosError } from 'axios'; const messages = defineMessages({ login: { id: 'navbar.login.action', defaultMessage: 'Log in' }, - username: { id: 'navbar.login.username.placeholder', defaultMessage: 'Email or username' }, + username: { id: 'navbar.login.username.placeholder', defaultMessage: 'E-mail or username' }, + email: { id: 'navbar.login.email.placeholder', defaultMessage: 'E-mail address' }, password: { id: 'navbar.login.password.label', defaultMessage: 'Password' }, forgotPassword: { id: 'navbar.login.forgot_password', defaultMessage: 'Forgot password?' }, }); @@ -25,6 +26,7 @@ const messages = defineMessages({ const Navbar = () => { const dispatch = useAppDispatch(); const intl = useIntl(); + const features = useFeatures(); const { isOpen } = useRegistrationStatus(); const account = useOwnAccount(); const node = useRef(null); @@ -111,7 +113,7 @@ const Navbar = () => { value={username} onChange={(event) => setUsername(event.target.value)} type='text' - placeholder={intl.formatMessage(messages.username)} + placeholder={intl.formatMessage(features.logInWithUsername ? messages.username : messages.email)} className='max-w-[200px]' /> diff --git a/app/soapbox/locales/en.json b/app/soapbox/locales/en.json index 89608c4d5d..a4d547d8e5 100644 --- a/app/soapbox/locales/en.json +++ b/app/soapbox/locales/en.json @@ -842,6 +842,7 @@ "hashtag.column_header.tag_mode.any": "or {additional}", "hashtag.column_header.tag_mode.none": "without {additional}", "header.home.label": "Home", + "header.login.email.placeholder": "E-mail address", "header.login.forgot_password": "Forgot password?", "header.login.label": "Log in", "header.login.password.label": "Password", @@ -926,6 +927,7 @@ "lists.subheading": "Your lists", "loading_indicator.label": "Loading…", "location_search.placeholder": "Find an address", + "login.fields.email_label": "E-mail address", "login.fields.instance_label": "Instance", "login.fields.instance_placeholder": "example.com", "login.fields.otp_code_hint": "Enter the two-factor code generated by your phone app or use one of your recovery codes", @@ -1014,6 +1016,7 @@ "mute_modal.duration": "Duration", "mute_modal.hide_notifications": "Hide notifications from this user?", "navbar.login.action": "Log in", + "navbar.login.email.placeholder": "E-mail address", "navbar.login.forgot_password": "Forgot password?", "navbar.login.password.label": "Password", "navbar.login.username.placeholder": "Email or username", @@ -1116,6 +1119,7 @@ "onboarding.suggestions.title": "Suggested accounts", "onboarding.view_feed": "View Feed", "password_reset.confirmation": "Check your email for confirmation.", + "password_reset.fields.email_placeholder": "E-mail address", "password_reset.fields.username_placeholder": "Email or username", "password_reset.header": "Reset Password", "password_reset.reset": "Reset password", diff --git a/app/soapbox/utils/features.ts b/app/soapbox/utils/features.ts index afbece3b42..b24e75525e 100644 --- a/app/soapbox/utils/features.ts +++ b/app/soapbox/utils/features.ts @@ -597,6 +597,14 @@ const getInstanceFeatures = (instance: Instance) => { v.software === PLEROMA && gte(v.version, '0.9.9'), ]), + /** + * Can sign in using username instead of e-mail address. + */ + logInWithUsername: any([ + v.software === PLEROMA, + v.software === TRUTHSOCIAL, + ]), + /** * Can perform moderation actions with account and reports. * @see {@link https://docs.joinmastodon.org/methods/admin/}