nicolium: prefer FormattedMessage for i18n

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-03-07 10:56:53 +01:00
parent 20b132f388
commit af3d777efa
9 changed files with 178 additions and 115 deletions

View File

@ -25,13 +25,12 @@ THE SOFTWARE.
import clsx from 'clsx';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import Icon from './icon';
const messages = defineMessages({
placeholder: { id: 'select.placeholder', defaultMessage: 'Select' },
noOptions: { id: 'select.no_options', defaultMessage: 'No options available' },
removeItem: { id: 'select.remove_item', defaultMessage: 'Remove item' },
});
@ -261,7 +260,9 @@ const Multiselect: React.FC<IMultiselect> = ({
>
<ul className='optionContainer'>
{visibleOptions.length === 0 && (
<span className='notFound'>{intl.formatMessage(messages.noOptions)}</span>
<span className='notFound'>
<FormattedMessage id='select.no_options' defaultMessage='No options available' />
</span>
)}
{visibleOptions.map((option, i) => (
<li

View File

@ -1,7 +1,7 @@
import clsx from 'clsx';
import fuzzysort from 'fuzzysort';
import React, { useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import DropdownMenu from '@/components/dropdown-menu';
import Icon from '@/components/ui/icon';
@ -184,7 +184,12 @@ const getLanguageDropdown =
return (
<>
<label className='⁂-language-dropdown__search'>
<span>{intl.formatMessage(messages.search)}</span>
<span>
<FormattedMessage
id='compose.language_dropdown.search'
defaultMessage='Search language…'
/>
</span>
<Input
ref={input}

View File

@ -326,7 +326,12 @@ const ImageComponent = ({
)}
>
<label>
<span style={{ display: 'none' }}>{intl.formatMessage(messages.description)}</span>
<span className='sr-only'>
<FormattedMessage
id='upload_form.description'
defaultMessage='Describe for the visually impaired'
/>
</span>
<textarea
className='m-0 w-full rounded-md border border-solid border-white/25 bg-transparent p-2.5 text-sm text-white placeholder:text-white/60'

View File

@ -1,6 +1,6 @@
import clsx from 'clsx';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import Icon from '@/components/icon';
import Button from '@/components/ui/button';
@ -60,7 +60,9 @@ const Search: React.FC<ISearch> = ({ value, onSubmit }) => {
</div>
</label>
<Button onClick={handleSubmit}>{intl.formatMessage(messages.searchTitle)}</Button>
<Button onClick={handleSubmit}>
<FormattedMessage id='tabs_bar.search' defaultMessage='Search' />
</Button>
</HStack>
</Form>
);

View File

@ -1,5 +1,5 @@
import React, { useCallback, useMemo, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import { submitReport, ReportableEntities } from '@/actions/reports';
import AttachmentThumbs from '@/components/media/attachment-thumbs';
@ -22,18 +22,6 @@ import ReasonStep from './steps/reason-step';
import type { BaseModalProps } from '@/features/ui/components/modal-root';
const messages = defineMessages({
blankslate: {
id: 'report.reason.blankslate',
defaultMessage: 'You have removed all statuses from being selected.',
},
done: { id: 'report.done', defaultMessage: 'Done' },
next: { id: 'report.next', defaultMessage: 'Next' },
submit: { id: 'report.submit', defaultMessage: 'Submit' },
cancel: { id: 'common.cancel', defaultMessage: 'Cancel' },
previous: { id: 'report.previous', defaultMessage: 'Previous' },
});
enum Steps {
ONE = 'ONE',
TWO = 'TWO',
@ -83,7 +71,6 @@ const ReportModal: React.FC<BaseModalProps & ReportModalProps> = ({
statusIds,
}) => {
const dispatch = useAppDispatch();
const intl = useIntl();
const { data: account } = useAccount(accountId || undefined);
@ -126,7 +113,12 @@ const ReportModal: React.FC<BaseModalProps & ReportModalProps> = ({
case 0:
return (
<div className='flex w-full items-center justify-center rounded-lg bg-gray-100 p-4 dark:bg-gray-800'>
<Text theme='muted'>{intl.formatMessage(messages.blankslate)}</Text>
<Text theme='muted'>
<FormattedMessage
id='report.reason.blankslate'
defaultMessage='You have removed all statuses from being selected.'
/>
</Text>
</div>
);
default:
@ -137,9 +129,9 @@ const ReportModal: React.FC<BaseModalProps & ReportModalProps> = ({
const cancelText = useMemo(() => {
switch (currentStep) {
case Steps.ONE:
return intl.formatMessage(messages.cancel);
return <FormattedMessage id='common.cancel' defaultMessage='Cancel' />;
default:
return intl.formatMessage(messages.previous);
return <FormattedMessage id='report.previous' defaultMessage='Previous' />;
}
}, [currentStep]);
@ -159,13 +151,13 @@ const ReportModal: React.FC<BaseModalProps & ReportModalProps> = ({
const confirmationText = useMemo(() => {
switch (currentStep) {
case Steps.ONE:
return intl.formatMessage(messages.next);
return <FormattedMessage id='report.next' defaultMessage='Next' />;
case Steps.TWO:
return intl.formatMessage(messages.submit);
return <FormattedMessage id='report.submit' defaultMessage='Submit' />;
case Steps.THREE:
return intl.formatMessage(messages.done);
return <FormattedMessage id='report.done' defaultMessage='Done' />;
default:
return intl.formatMessage(messages.next);
return <FormattedMessage id='report.next' defaultMessage='Next' />;
}
}, [currentStep]);

View File

@ -1,7 +1,7 @@
import { useNavigate } from '@tanstack/react-router';
import { GroupRoles } from 'pl-api';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import List, { ListItem } from '@/components/list';
import { CardBody, CardHeader, CardTitle } from '@/components/ui/card';
@ -17,19 +17,7 @@ import toast from '@/toast';
const messages = defineMessages({
heading: { id: 'column.manage_group', defaultMessage: 'Manage group' },
editGroup: { id: 'manage_group.edit_group', defaultMessage: 'Edit group' },
pendingRequests: { id: 'manage_group.pending_requests', defaultMessage: 'Pending requests' },
blockedMembers: { id: 'manage_group.blocked_members', defaultMessage: 'Banned members' },
deleteGroup: { id: 'manage_group.delete_group', defaultMessage: 'Delete group' },
deleteConfirm: { id: 'confirmations.delete_group.confirm', defaultMessage: 'Delete' },
deleteHeading: { id: 'confirmations.delete_group.heading', defaultMessage: 'Delete group' },
deleteMessage: {
id: 'confirmations.delete_group.message',
defaultMessage:
'Are you sure you want to delete this group? This is a permanent action that cannot be undone.',
},
members: { id: 'group.tabs.members', defaultMessage: 'Members' },
other: { id: 'settings.other', defaultMessage: 'Other options' },
deleteSuccess: { id: 'group.delete.success', defaultMessage: 'Group successfully deleted' },
});
@ -64,8 +52,13 @@ const ManageGroup: React.FC = () => {
const onDeleteGroup = () => {
openModal('CONFIRM', {
heading: intl.formatMessage(messages.deleteHeading),
message: intl.formatMessage(messages.deleteMessage),
confirm: intl.formatMessage(messages.deleteConfirm),
message: (
<FormattedMessage
id='confirmations.delete_group.message'
defaultMessage='Are you sure you want to delete this group? This is a permanent action that cannot be undone.'
/>
),
confirm: <FormattedMessage id='confirmations.delete_group.confirm' defaultMessage='Delete' />,
onConfirm: () => {
deleteGroup(undefined, {
onSuccess() {
@ -87,12 +80,18 @@ const ManageGroup: React.FC = () => {
{isOwner && (
<>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.editGroup)} />
<CardTitle
title={
<FormattedMessage id='manage_group.edit_group' defaultMessage='Edit group' />
}
/>
</CardHeader>
<List>
<ListItem
label={intl.formatMessage(messages.editGroup)}
label={
<FormattedMessage id='manage_group.edit_group' defaultMessage='Edit group' />
}
to='/groups/$groupId/manage/edit'
params={{ groupId: group.id }}
>
@ -105,18 +104,27 @@ const ManageGroup: React.FC = () => {
)}
<CardHeader>
<CardTitle title={intl.formatMessage(messages.members)} />
<CardTitle
title={<FormattedMessage id='group.tabs.members' defaultMessage='Members' />}
/>
</CardHeader>
<List>
<ListItem
label={intl.formatMessage(messages.pendingRequests)}
label={
<FormattedMessage
id='manage_group.pending_requests'
defaultMessage='Pending requests'
/>
}
to='/groups/$groupId/manage/requests'
params={{ groupId: group.id }}
/>
<ListItem
label={intl.formatMessage(messages.blockedMembers)}
label={
<FormattedMessage id='manage_group.blocked_members' defaultMessage='Banned members' />
}
to='/groups/$groupId/manage/blocks'
params={{ groupId: group.id }}
/>
@ -125,12 +133,21 @@ const ManageGroup: React.FC = () => {
{isOwner && (
<>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.other)} />
<CardTitle
title={<FormattedMessage id='settings.other' defaultMessage='Other options' />}
/>
</CardHeader>
<List>
<ListItem
label={<Text theme='danger'>{intl.formatMessage(messages.deleteGroup)}</Text>}
label={
<Text theme='danger'>
<FormattedMessage
id='manage_group.delete_group'
defaultMessage='Delete group'
/>
</Text>
}
onClick={onDeleteGroup}
/>
</List>

View File

@ -26,7 +26,6 @@ const messages = defineMessages({
delete: { id: 'column.aliases.delete', defaultMessage: 'Delete' },
add: { id: 'aliases.account.add', defaultMessage: 'Create alias' },
search: { id: 'aliases.search', defaultMessage: 'Search your old account' },
searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' },
clear: { id: 'search.clear', defaultMessage: 'Clear input' },
});
@ -133,7 +132,9 @@ const Search: React.FC<IAliasesSearch> = ({ onSubmit }) => {
/>
</button>
</label>
<Button onClick={handleSubmit}>{intl.formatMessage(messages.searchTitle)}</Button>
<Button onClick={handleSubmit}>
<FormattedMessage id='tabs_bar.search' defaultMessage='Search' />
</Button>
</div>
);
};

View File

@ -19,16 +19,10 @@ import type { OauthToken } from 'pl-api';
const messages = defineMessages({
header: { id: 'column.tokens', defaultMessage: 'Active sessions' },
revoke: { id: 'security.tokens.revoke', defaultMessage: 'Revoke' },
revokeSessionHeading: {
id: 'confirmations.revoke_session.heading',
defaultMessage: 'Revoke current session',
},
revokeSessionMessage: {
id: 'confirmations.revoke_session.message',
defaultMessage: 'You are about to revoke your current session. You will be signed out.',
},
revokeSessionConfirm: { id: 'confirmations.revoke_session.confirm', defaultMessage: 'Revoke' },
});
interface IAuthToken {
@ -47,8 +41,15 @@ const AuthToken: React.FC<IAuthToken> = ({ token, isCurrent }) => {
if (isCurrent)
openModal('CONFIRM', {
heading: intl.formatMessage(messages.revokeSessionHeading),
message: intl.formatMessage(messages.revokeSessionMessage),
confirm: intl.formatMessage(messages.revokeSessionConfirm),
message: (
<FormattedMessage
id='confirmations.revoke_session.message'
defaultMessage='You are about to revoke your current session. You will be signed out.'
/>
),
confirm: (
<FormattedMessage id='confirmations.revoke_session.confirm' defaultMessage='Revoke' />
),
onConfirm: () => {
revokeMutation.mutate();
},
@ -144,7 +145,9 @@ const AuthToken: React.FC<IAuthToken> = ({ token, isCurrent }) => {
)}
</div>
<div className={clsx('⁂-token__actions')}>
<button onClick={handleRevoke}>{intl.formatMessage(messages.revoke)}</button>
<button onClick={handleRevoke}>
<FormattedMessage id='security.tokens.revoke' defaultMessage='Revoke' />
</button>
</div>
</div>
);

View File

@ -12,35 +12,7 @@ import { useOwnAccount } from '@/hooks/use-own-account';
import { useMfaConfig } from '@/queries/security/use-mfa';
const messages = defineMessages({
accountAliases: { id: 'column.aliases', defaultMessage: 'Account aliases' },
accountMigration: { id: 'column.migration', defaultMessage: 'Move account' },
backups: { id: 'column.backups', defaultMessage: 'Backups' },
blocks: { id: 'column.blocks', defaultMessage: 'Blocks' },
changeEmail: { id: 'column.change_email', defaultMessage: 'Change email' },
changePassword: { id: 'column.change_password', defaultMessage: 'Change password' },
configureMfa: { id: 'settings.configure_mfa', defaultMessage: 'Configure MFA' },
deleteAccount: { id: 'column.delete_account', defaultMessage: 'Delete account' },
developers: { id: 'column.developers', defaultMessage: 'Developers' },
domainBlocks: { id: 'column.domain_blocks', defaultMessage: 'Domain blocks' },
editProfile: { id: 'settings.edit_profile', defaultMessage: 'Edit profile' },
exportData: { id: 'column.export_data', defaultMessage: 'Export data' },
filters: { id: 'column.filters', defaultMessage: 'Muted words' },
importData: { id: 'column.import_data', defaultMessage: 'Import data' },
interactionPolicies: {
id: 'column.interaction_policies',
defaultMessage: 'Interaction policies',
},
mfaDisabled: { id: 'mfa.disabled', defaultMessage: 'Disabled' },
mfaEnabled: { id: 'mfa.enabled', defaultMessage: 'Enabled' },
mutes: { id: 'column.mutes', defaultMessage: 'Mutes' },
mutesAndBlocks: { id: 'settings.mutes_blocks', defaultMessage: 'Mutes and blocks' },
other: { id: 'settings.other', defaultMessage: 'Other options' },
preferences: { id: 'column.preferences', defaultMessage: 'Preferences' },
profile: { id: 'settings.profile', defaultMessage: 'Profile' },
security: { id: 'settings.security', defaultMessage: 'Security' },
sessions: { id: 'column.tokens', defaultMessage: 'Active sessions' },
settings: { id: 'settings.settings', defaultMessage: 'Settings' },
privacy: { id: 'column.privacy', defaultMessage: 'Privacy' },
});
/** User settings page. */
@ -61,34 +33,60 @@ const SettingsPage = () => {
<Column label={intl.formatMessage(messages.settings)} transparent withHeader={false}>
<Card className='space-y-4' variant='rounded'>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.profile)} />
<CardTitle title={<FormattedMessage id='settings.profile' defaultMessage='Profile' />} />
</CardHeader>
<CardBody>
<List>
<ListItem label={intl.formatMessage(messages.editProfile)} to='/settings/profile'>
<ListItem
label={<FormattedMessage id='settings.edit_profile' defaultMessage='Edit profile' />}
to='/settings/profile'
>
<span className='max-w-full truncate'>{displayName}</span>
</ListItem>
</List>
</CardBody>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.mutesAndBlocks)} />
<CardTitle
title={
<FormattedMessage id='settings.mutes_blocks' defaultMessage='Mutes and blocks' />
}
/>
</CardHeader>
<CardBody>
<List>
<ListItem label={intl.formatMessage(messages.mutes)} to='/mutes' />
<ListItem label={intl.formatMessage(messages.blocks)} to='/blocks' />
<ListItem
label={<FormattedMessage id='column.mutes' defaultMessage='Mutes' />}
to='/mutes'
/>
<ListItem
label={<FormattedMessage id='column.blocks' defaultMessage='Blocks' />}
to='/blocks'
/>
{(features.filters || features.filtersV2) && (
<ListItem label={intl.formatMessage(messages.filters)} to='/filters' />
<ListItem
label={<FormattedMessage id='column.filters' defaultMessage='Muted words' />}
to='/filters'
/>
)}
{features.federating && (
<ListItem label={intl.formatMessage(messages.domainBlocks)} to='/domain_blocks' />
<ListItem
label={
<FormattedMessage id='column.domain_blocks' defaultMessage='Domain blocks' />
}
to='/domain_blocks'
/>
)}
{(features.interactionRequests || features.quoteApprovalPolicies) && (
<ListItem
label={intl.formatMessage(messages.interactionPolicies)}
label={
<FormattedMessage
id='column.interaction_policies'
defaultMessage='Interaction policies'
/>
}
to='/settings/interaction_policies'
/>
)}
@ -96,33 +94,50 @@ const SettingsPage = () => {
</CardBody>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.security)} />
<CardTitle
title={<FormattedMessage id='settings.security' defaultMessage='Security' />}
/>
</CardHeader>
<CardBody>
<List>
{features.changeEmail && (
<ListItem label={intl.formatMessage(messages.changeEmail)} to='/settings/email' />
<ListItem
label={<FormattedMessage id='column.change_email' defaultMessage='Change email' />}
to='/settings/email'
/>
)}
{features.changePassword && (
<ListItem
label={intl.formatMessage(messages.changePassword)}
label={
<FormattedMessage id='column.change_password' defaultMessage='Change password' />
}
to='/settings/password'
/>
)}
{features.manageMfa && (
<>
<ListItem label={intl.formatMessage(messages.configureMfa)} to='/settings/mfa'>
<ListItem
label={
<FormattedMessage id='settings.configure_mfa' defaultMessage='Configure MFA' />
}
to='/settings/mfa'
>
<span>
{isMfaEnabled
? intl.formatMessage(messages.mfaEnabled)
: intl.formatMessage(messages.mfaDisabled)}
{isMfaEnabled ? (
<FormattedMessage id='mfa.enabled' defaultMessage='Enabled' />
) : (
<FormattedMessage id='mfa.disabled' defaultMessage='Disabled' />
)}
</span>
</ListItem>
</>
)}
{features.sessions && (
<ListItem label={intl.formatMessage(messages.sessions)} to='/settings/tokens' />
<ListItem
label={<FormattedMessage id='column.tokens' defaultMessage='Active sessions' />}
to='/settings/tokens'
/>
)}
<ListItem
label={<FormattedMessage id='settings.privacy' defaultMessage='Privacy' />}
@ -144,7 +159,9 @@ const SettingsPage = () => {
) : null}
<CardHeader>
<CardTitle title={intl.formatMessage(messages.preferences)} />
<CardTitle
title={<FormattedMessage id='column.preferences' defaultMessage='Preferences' />}
/>
</CardHeader>
<CardBody>
@ -152,33 +169,49 @@ const SettingsPage = () => {
</CardBody>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.other)} />
<CardTitle
title={<FormattedMessage id='settings.other' defaultMessage='Other options' />}
/>
</CardHeader>
<CardBody>
<List>
{(features.importBlocks || features.importFollows || features.importMutes) && (
<ListItem label={intl.formatMessage(messages.importData)} to='/settings/import' />
<ListItem
label={<FormattedMessage id='column.import_data' defaultMessage='Import data' />}
to='/settings/import'
/>
)}
<ListItem label={intl.formatMessage(messages.exportData)} to='/settings/export' />
<ListItem
label={<FormattedMessage id='column.export_data' defaultMessage='Export data' />}
to='/settings/export'
/>
{features.accountBackups && (
<ListItem label={intl.formatMessage(messages.backups)} to='/settings/backups' />
<ListItem
label={<FormattedMessage id='column.backups' defaultMessage='Backups' />}
to='/settings/backups'
/>
)}
<ListItem label={intl.formatMessage(messages.developers)} to='/developers' />
<ListItem
label={<FormattedMessage id='column.developers' defaultMessage='Developers' />}
to='/developers'
/>
{features.federating &&
(features.accountMoving ? (
<ListItem
label={intl.formatMessage(messages.accountMigration)}
label={<FormattedMessage id='column.migration' defaultMessage='Move account' />}
to='/settings/migration'
/>
) : (
features.manageAccountAliases && (
<ListItem
label={intl.formatMessage(messages.accountAliases)}
label={
<FormattedMessage id='column.aliases' defaultMessage='Account aliases' />
}
to='/settings/aliases'
/>
)
@ -186,7 +219,11 @@ const SettingsPage = () => {
{(features.deleteAccount || features.deleteAccountWithoutPassword) && (
<ListItem
label={<Text theme='danger'>{intl.formatMessage(messages.deleteAccount)}</Text>}
label={
<Text theme='danger'>
<FormattedMessage id='column.delete_account' defaultMessage='Delete account' />
</Text>
}
to='/settings/account'
/>
)}