pl-fe: cleanup

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-01-05 23:51:38 +01:00
parent 2daf78c2d1
commit f78cf96905
10 changed files with 44 additions and 95 deletions

View File

@ -1,6 +1,6 @@
import { Link, useMatch } from '@tanstack/react-router';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import Button from 'pl-fe/components/ui/button';
import Divider from 'pl-fe/components/ui/divider';
@ -23,17 +23,9 @@ interface IGroupPopoverContainer {
group: Group;
}
const messages = defineMessages({
title: { id: 'group.popover.title', defaultMessage: 'Membership required' },
summary: { id: 'group.popover.summary', defaultMessage: 'You must be a member of the group in order to reply to this status.' },
action: { id: 'group.popover.action', defaultMessage: 'View group' },
});
const GroupPopover = (props: IGroupPopoverContainer) => {
const { children, group, isEnabled } = props;
const intl = useIntl();
const shouldHideAction = !!useMatch({ from: groupTimelineRoute.fullPath, shouldThrow: false });
if (!isEnabled) {
@ -83,10 +75,10 @@ const GroupPopover = (props: IGroupPopoverContainer) => {
<Stack space={0.5} className='px-4'>
<Text weight='semibold'>
{intl.formatMessage(messages.title)}
<FormattedMessage id='group.popover.title' defaultMessage='Membership required' />
</Text>
<Text theme='muted'>
{intl.formatMessage(messages.summary)}
<FormattedMessage id='group.popover.summary' defaultMessage='You must be a member of the group in order to reply to this status.' />
</Text>
</Stack>
@ -94,7 +86,7 @@ const GroupPopover = (props: IGroupPopoverContainer) => {
<div className='px-4'>
<Link to='/groups/$groupId' params={{ groupId: group.id }}>
<Button type='button' theme='secondary' block>
{intl.formatMessage(messages.action)}
<FormattedMessage id='group.popover.action' defaultMessage='View group' />
</Button>
</Link>
</div>

View File

@ -1,6 +1,6 @@
import clsx from 'clsx';
import React, { useMemo } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import Button from 'pl-fe/components/ui/button';
import HStack from 'pl-fe/components/ui/hstack';
@ -37,18 +37,6 @@ const useShowOverlay = (status: Pick<Status, 'id' | 'filtered' | 'media_attachme
return !visible || showHideButton;
};
const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' },
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
deleteHeading: { id: 'confirmations.delete.heading', defaultMessage: 'Delete post' },
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this post?' },
hide: { id: 'moderation_overlay.hide', defaultMessage: 'Hide content' },
sensitiveTitle: { id: 'status.sensitive_warning', defaultMessage: 'Sensitive content' },
sensitiveSubtitle: { id: 'status.sensitive_warning.subtitle', defaultMessage: 'This content may not be suitable for all audiences.' },
show: { id: 'moderation_overlay.show', defaultMessage: 'Show content' },
matchesFilter: { id: 'status.sensitive_warning.matches_filter', defaultMessage: 'Matches filter “<span>{title}</span>”' },
});
interface ISensitiveContentOverlay {
status: Pick<Status, 'id' | 'filtered' | 'sensitive' | 'media_attachments'>;
}
@ -56,7 +44,6 @@ interface ISensitiveContentOverlay {
const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveContentOverlay>((props, ref) => {
const { status } = props;
const intl = useIntl();
const { displayMedia } = useSettings();
const [visible, filters] = useMediaVisible(status, displayMedia);
@ -85,7 +72,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
>
{visible ? (
<Button
text={intl.formatMessage(messages.hide)}
text={<FormattedMessage id='moderation_overlay.hide' defaultMessage='Hide content' />}
icon={require('@phosphor-icons/core/regular/eye-slash.svg')}
onClick={toggleVisibility}
theme='primary'
@ -96,14 +83,22 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
<div className='mx-auto space-y-4 text-center' ref={ref}>
<div className='space-y-1'>
<Text theme='white' weight='semibold'>
{intl.formatMessage(messages.sensitiveTitle)}
<FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />
</Text>
<Text theme='white' size='sm' weight='medium'>
{filters.length ? intl.formatMessage(messages.matchesFilter, {
{filters.length ? (
<FormattedMessage
id='status.sensitive_warning.matches_filter'
defaultMessage='Matches filter “<span>{title}</span>”'
values={{
title: matchedFilters.join(', '),
span: (chunks) => <span className='filter-name'>{chunks}</span>,
}) : intl.formatMessage(messages.sensitiveSubtitle)}
}}
/>
) : (
<FormattedMessage id='status.sensitive_warning.subtitle' defaultMessage='This content may not be suitable for all audiences.' />
)}
</Text>
</div>
@ -115,7 +110,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
icon={require('@phosphor-icons/core/regular/eye.svg')}
onClick={toggleVisibility}
>
{intl.formatMessage(messages.show)}
<FormattedMessage id='moderation_overlay.show' defaultMessage='Show content' />
</Button>
</HStack>
</div>

View File

@ -1,5 +1,5 @@
import React, { useRef } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
import Button from './button';
import HStack from './hstack';
@ -8,7 +8,6 @@ import Stack from './stack';
import Text from './text';
const messages = defineMessages({
add: { id: 'streamfield.add', defaultMessage: 'Add' },
remove: { id: 'streamfield.remove', defaultMessage: 'Remove' },
});
@ -129,7 +128,7 @@ const Streamfield: React.FC<IStreamfield> = ({
theme='secondary'
block
>
{intl.formatMessage(messages.add)}
<FormattedMessage id='streamfield.add' defaultMessage='Add' />
</Button>
)}
</Stack>

View File

@ -1,13 +1,12 @@
import { useNavigate } from '@tanstack/react-router';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import Widget from 'pl-fe/components/ui/widget';
import AccountContainer from 'pl-fe/containers/account-container';
import { useAdminAccounts } from 'pl-fe/queries/admin/use-accounts';
const messages = defineMessages({
title: { id: 'admin.latest_accounts_panel.title', defaultMessage: 'Latest Accounts' },
expand: { id: 'admin.latest_accounts_panel.more', defaultMessage: 'Click to see {count, plural, one {# account} other {# accounts}}' },
});
@ -33,7 +32,7 @@ const LatestAccountsPanel: React.FC<ILatestAccountsPanel> = ({ limit = 5 }) => {
return (
<Widget
title={intl.formatMessage(messages.title)}
title={<FormattedMessage id='admin.latest_accounts_panel.title' defaultMessage='Latest accounts' />}
onActionClick={handleAction}
actionTitle={intl.formatMessage(messages.expand, { count: total })}
>

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { defineMessages, IntlShape, useIntl } from 'react-intl';
import { defineMessages, FormattedMessage, IntlShape, useIntl } from 'react-intl';
import Button from 'pl-fe/components/ui/button';
import Combobox, { ComboboxInput, ComboboxList, ComboboxOption, ComboboxPopover } from 'pl-fe/components/ui/combobox';
@ -22,10 +22,6 @@ import type { Emoji, NativeEmoji } from 'pl-fe/features/emoji';
const messages = defineMessages({
placeholder: { id: 'chat.input.placeholder', defaultMessage: 'Type a message' },
send: { id: 'chat.actions.send', defaultMessage: 'Send' },
retry: { id: 'chat.retry', defaultMessage: 'Retry?' },
blocked: { id: 'chat_message_list.blocked', defaultMessage: 'You blocked this user' },
unblock: { id: 'chat_composer.unblock', defaultMessage: 'Unblock' },
unblockMessage: { id: 'chat_settings.unblock.message', defaultMessage: 'Unblocking will allow this profile to direct message you and view your content.' },
unblockHeading: { id: 'chat_settings.unblock.heading', defaultMessage: 'Unblock @{acct}' },
unblockConfirm: { id: 'chat_settings.unblock.confirm', defaultMessage: 'Unblock' },
@ -152,11 +148,11 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
<div className='mt-auto p-6 shadow-3xl dark:border-t-2 dark:border-solid dark:border-gray-800'>
<Stack space={3} alignItems='center'>
<Text align='center' theme='muted'>
{intl.formatMessage(messages.blocked)}
<FormattedMessage id='chat_message_list.blocked' defaultMessage='You blocked this user' />
</Text>
<Button theme='secondary' onClick={handleUnblockUser}>
{intl.formatMessage(messages.unblock)}
<FormattedMessage id='chat_composer.unblock' defaultMessage='Unblock' />
</Button>
</Stack>
</div>
@ -248,7 +244,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
<button onClick={onSubmit} className='flex hover:underline'>
<Text theme='primary' size='xs' tag='span'>
{intl.formatMessage(messages.retry)}
<FormattedMessage id='chat.retry' defaultMessage='Retry?' />
</Text>
</button>
</>

View File

@ -1,6 +1,6 @@
import { Link } from '@tanstack/react-router';
import React from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import Hashtag from 'pl-fe/components/hashtag';
import Text from 'pl-fe/components/ui/text';
@ -12,16 +12,7 @@ interface ITrendsPanel {
limit: number;
}
const messages = defineMessages({
viewAll: {
id: 'trends_panel.view_all',
defaultMessage: 'View all',
},
});
const TrendsPanel = ({ limit }: ITrendsPanel) => {
const intl = useIntl();
const { data: trends, isFetching } = useTrends();
if (!isFetching && !trends?.length) {
@ -34,7 +25,7 @@ const TrendsPanel = ({ limit }: ITrendsPanel) => {
action={
<Link className='text-right' to='/search' search={{ type: 'hashtags' }}>
<Text tag='span' theme='primary' size='sm' className='hover:underline'>
{intl.formatMessage(messages.viewAll)}
<FormattedMessage id='trends_panel.view_all' defaultMessage='View all' />
</Text>
</Link>
}

View File

@ -1,6 +1,6 @@
import { Link } from '@tanstack/react-router';
import React from 'react';
import { useIntl, defineMessages } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import HStack from 'pl-fe/components/ui/hstack';
import Text from 'pl-fe/components/ui/text';
@ -9,13 +9,6 @@ import { shortNumberFormat } from 'pl-fe/utils/numbers';
import type { Account } from 'pl-api';
const messages = defineMessages({
followers: { id: 'account.followers', defaultMessage: 'Followers' },
follows: { id: 'account.follows', defaultMessage: 'Following' },
statuses: { id: 'account.statuses', defaultMessage: 'Statuses' },
subscribers: { id: 'account.subscribers', defaultMessage: 'Subscribers' },
});
interface IProfileStats {
account: Pick<Account, 'acct' | 'followers_count' | 'following_count' | 'statuses_count' | 'subscribers_count'> | undefined;
onClickHandler?: React.MouseEventHandler;
@ -23,7 +16,6 @@ interface IProfileStats {
/** Display follower and following counts for an account. */
const ProfileStats: React.FC<IProfileStats> = ({ account, onClickHandler }) => {
const intl = useIntl();
const { demetricator } = useSettings();
if (!account) {
@ -38,7 +30,7 @@ const ProfileStats: React.FC<IProfileStats> = ({ account, onClickHandler }) => {
{shortNumberFormat(account.statuses_count)}
</Text>
<Text weight='bold' size='sm'>
{intl.formatMessage(messages.statuses)}
<FormattedMessage id='account.statuses' defaultMessage='Statuses' />
</Text>
</HStack>
)}
@ -51,7 +43,7 @@ const ProfileStats: React.FC<IProfileStats> = ({ account, onClickHandler }) => {
</Text>
)}
<Text weight='bold' size='sm'>
{intl.formatMessage(messages.followers)}
<FormattedMessage id='account.followers' defaultMessage='Followers' />
</Text>
</HStack>
</Link>
@ -64,7 +56,7 @@ const ProfileStats: React.FC<IProfileStats> = ({ account, onClickHandler }) => {
</Text>
)}
<Text weight='bold' size='sm'>
{intl.formatMessage(messages.follows)}
<FormattedMessage id='account.follows' defaultMessage='Following' />
</Text>
</HStack>
</Link>
@ -78,7 +70,7 @@ const ProfileStats: React.FC<IProfileStats> = ({ account, onClickHandler }) => {
</Text>
)}
<Text weight='bold' size='sm'>
{intl.formatMessage(messages.subscribers)}
<FormattedMessage id='account.subscribers' defaultMessage='Subscribers' />
</Text>
</HStack>
// </Link>

View File

@ -1,16 +1,9 @@
import React, { useMemo } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import Icon from 'pl-fe/components/ui/icon';
import Select from 'pl-fe/components/ui/select';
const messages = defineMessages({
light: { id: 'theme_toggle.light', defaultMessage: 'Light' },
dark: { id: 'theme_toggle.dark', defaultMessage: 'Dark' },
black: { id: 'theme_toggle.black', defaultMessage: 'Black' },
system: { id: 'theme_toggle.system', defaultMessage: 'System' },
});
interface IThemeSelector {
value: string;
onChange: (value: 'system' | 'light' | 'dark' | 'black') => void;
@ -18,7 +11,6 @@ interface IThemeSelector {
/** Pure theme selector. */
const ThemeSelector: React.FC<IThemeSelector> = ({ value, onChange }) => {
const intl = useIntl();
const themeIconSrc = useMemo(() => {
switch (value) {
@ -51,10 +43,10 @@ const ThemeSelector: React.FC<IThemeSelector> = ({ value, onChange }) => {
defaultValue={value}
className='!pl-10'
>
<option value='system'>{intl.formatMessage(messages.system)}</option>
<option value='light'>{intl.formatMessage(messages.light)}</option>
<option value='dark'>{intl.formatMessage(messages.dark)}</option>
<option value='black'>{intl.formatMessage(messages.black)}</option>
<option value='system'><FormattedMessage id='theme_toggle.system' defaultMessage='System' /></option>
<option value='light'><FormattedMessage id='theme_toggle.light' defaultMessage='Light' /></option>
<option value='dark'><FormattedMessage id='theme_toggle.dark' defaultMessage='Dark' /></option>
<option value='black'><FormattedMessage id='theme_toggle.black' defaultMessage='Black' /></option>
</Select>
<div className='pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3'>

View File

@ -178,7 +178,7 @@
"admin.edit_rule.save": "Save",
"admin.edit_rule.updated": "Rule edited",
"admin.latest_accounts_panel.more": "Click to see {count, plural, one {# account} other {# accounts}}",
"admin.latest_accounts_panel.title": "Latest Accounts",
"admin.latest_accounts_panel.title": "Latest accounts",
"admin.links.pending_reports": "{count, plural, one {{formattedCount} pending report} other {{formattedCount} pending reports}}",
"admin.links.pending_users": "{count, plural, one {{formattedCount} pending user} other {{formattedCount} pending users}}",
"admin.moderation_log.empty_message": "You have not performed any moderation actions yet. When you do, a history will be shown here.",

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import { CardHeader, CardTitle } from 'pl-fe/components/ui/card';
import Modal from 'pl-fe/components/ui/modal';
@ -14,18 +14,11 @@ import Search from './list-editor-modal/components/search';
import type { BaseModalProps } from 'pl-fe/features/ui/components/modal-root';
const messages = defineMessages({
addToCircle: { id: 'circles.add_to_circle', defaultMessage: 'Add to circle' },
removeFromCircle: { id: 'circles.remove_from_circle', defaultMessage: 'Remove from circle' },
});
interface CircleEditorModalProps {
circleId: string;
}
const CircleEditorModal: React.FC<BaseModalProps & CircleEditorModalProps> = ({ circleId, onClose }) => {
const intl = useIntl();
const [searchValue, setSearchValue] = useState('');
const { data: circle } = useCircle(circleId);
@ -52,7 +45,7 @@ const CircleEditorModal: React.FC<BaseModalProps & CircleEditorModalProps> = ({
{accountIds.length > 0 ? (
<div>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.removeFromCircle)} />
<CardTitle title={<FormattedMessage id='circles.remove_from_circle' defaultMessage='Remove from circle' />} />
</CardHeader>
<div className='max-h-48 overflow-y-auto'>
{accountIds.map(accountId => <Account key={accountId} accountId={accountId} added={accountIds.includes(accountId)} onAdd={onAdd} onRemove={onRemove} />)}
@ -66,7 +59,7 @@ const CircleEditorModal: React.FC<BaseModalProps & CircleEditorModalProps> = ({
<div>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.addToCircle)} />
<CardTitle title={<FormattedMessage id='circles.add_to_circle' defaultMessage='Add to circle' />} />
</CardHeader>
<Search value={searchValue} onSubmit={setSearchValue} />
<div className='max-h-48 overflow-y-auto'>