Change translation strings of grouped notification label to have full context (#31486)
parent
b91264b1f3
commit
8c7642cd18
|
@ -0,0 +1,22 @@
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
|
export const DisplayedName: React.FC<{
|
||||||
|
accountIds: string[];
|
||||||
|
}> = ({ accountIds }) => {
|
||||||
|
const lastAccountId = accountIds[0] ?? '0';
|
||||||
|
const account = useAppSelector((state) => state.accounts.get(lastAccountId));
|
||||||
|
|
||||||
|
if (!account) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to={`/@${account.acct}`}
|
||||||
|
title={`@${account.acct}`}
|
||||||
|
data-hover-card-account={account.id}
|
||||||
|
>
|
||||||
|
<bdi dangerouslySetInnerHTML={{ __html: account.display_name_html }} />
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,51 +0,0 @@
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { useAppSelector } from 'mastodon/store';
|
|
||||||
|
|
||||||
export const NamesList: React.FC<{
|
|
||||||
accountIds: string[];
|
|
||||||
total: number;
|
|
||||||
seeMoreHref?: string;
|
|
||||||
}> = ({ accountIds, total, seeMoreHref }) => {
|
|
||||||
const lastAccountId = accountIds[0] ?? '0';
|
|
||||||
const account = useAppSelector((state) => state.accounts.get(lastAccountId));
|
|
||||||
|
|
||||||
if (!account) return null;
|
|
||||||
|
|
||||||
const displayedName = (
|
|
||||||
<Link
|
|
||||||
to={`/@${account.acct}`}
|
|
||||||
title={`@${account.acct}`}
|
|
||||||
data-hover-card-account={account.id}
|
|
||||||
>
|
|
||||||
<bdi dangerouslySetInnerHTML={{ __html: account.display_name_html }} />
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (total === 1) {
|
|
||||||
return displayedName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seeMoreHref)
|
|
||||||
return (
|
|
||||||
<FormattedMessage
|
|
||||||
id='name_and_others_with_link'
|
|
||||||
defaultMessage='{name} and <a>{count, plural, one {# other} other {# others}}</a>'
|
|
||||||
values={{
|
|
||||||
name: displayedName,
|
|
||||||
count: total - 1,
|
|
||||||
a: (chunks) => <Link to={seeMoreHref}>{chunks}</Link>,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormattedMessage
|
|
||||||
id='name_and_others'
|
|
||||||
defaultMessage='{name} and {count, plural, one {# other} other {# others}}'
|
|
||||||
values={{ name: displayedName, count: total - 1 }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -6,13 +6,27 @@ import type { NotificationGroupAdminSignUp } from 'mastodon/models/notification_
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||||
|
if (total === 1)
|
||||||
|
return (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.admin.sign_up'
|
id='notification.admin.sign_up'
|
||||||
defaultMessage='{name} signed up'
|
defaultMessage='{name} signed up'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.admin.sign_up.name_and_others'
|
||||||
|
defaultMessage='{name} and {count, plural, one {# other} other {# others}} signed up'
|
||||||
|
values={{
|
||||||
|
name: displayedName,
|
||||||
|
count: total - 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const NotificationAdminSignUp: React.FC<{
|
export const NotificationAdminSignUp: React.FC<{
|
||||||
notification: NotificationGroupAdminSignUp;
|
notification: NotificationGroupAdminSignUp;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
|
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
|
||||||
import type { NotificationGroupFavourite } from 'mastodon/models/notification_group';
|
import type { NotificationGroupFavourite } from 'mastodon/models/notification_group';
|
||||||
import { useAppSelector } from 'mastodon/store';
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
@ -7,13 +9,29 @@ import { useAppSelector } from 'mastodon/store';
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName, total, seeMoreHref) => {
|
||||||
|
if (total === 1)
|
||||||
|
return (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.favourite'
|
id='notification.favourite'
|
||||||
defaultMessage='{name} favorited your status'
|
defaultMessage='{name} favorited your status'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.favourite.name_and_others_with_link'
|
||||||
|
defaultMessage='{name} and <a>{count, plural, one {# other} other {# others}}</a> favorited your post'
|
||||||
|
values={{
|
||||||
|
name: displayedName,
|
||||||
|
count: total - 1,
|
||||||
|
a: (chunks) =>
|
||||||
|
seeMoreHref ? <Link to={seeMoreHref}>{chunks}</Link> : chunks,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const NotificationFavourite: React.FC<{
|
export const NotificationFavourite: React.FC<{
|
||||||
notification: NotificationGroupFavourite;
|
notification: NotificationGroupFavourite;
|
||||||
|
|
|
@ -10,13 +10,27 @@ import { useAppSelector } from 'mastodon/store';
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||||
|
if (total === 1)
|
||||||
|
return (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.follow'
|
id='notification.follow'
|
||||||
defaultMessage='{name} followed you'
|
defaultMessage='{name} followed you'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.follow.name_and_others'
|
||||||
|
defaultMessage='{name} and {count, plural, one {# other} other {# others}} followed you'
|
||||||
|
values={{
|
||||||
|
name: displayedName,
|
||||||
|
count: total - 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const FollowerCount: React.FC<{ accountId: string }> = ({ accountId }) => {
|
const FollowerCount: React.FC<{ accountId: string }> = ({ accountId }) => {
|
||||||
const account = useAppSelector((s) => s.accounts.get(accountId));
|
const account = useAppSelector((s) => s.accounts.get(accountId));
|
||||||
|
|
|
@ -21,13 +21,27 @@ const messages = defineMessages({
|
||||||
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
|
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||||
|
if (total === 1)
|
||||||
|
return (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.follow_request'
|
id='notification.follow_request'
|
||||||
defaultMessage='{name} has requested to follow you'
|
defaultMessage='{name} has requested to follow you'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.follow_request.name_and_others'
|
||||||
|
defaultMessage='{name} and {count, plural, one {# other} other {# others}} has requested to follow you'
|
||||||
|
values={{
|
||||||
|
name: displayedName,
|
||||||
|
count: total - 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const NotificationFollowRequest: React.FC<{
|
export const NotificationFollowRequest: React.FC<{
|
||||||
notification: NotificationGroupFollowRequest;
|
notification: NotificationGroupFollowRequest;
|
||||||
|
|
|
@ -12,11 +12,13 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||||
import { useAppDispatch } from 'mastodon/store';
|
import { useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { AvatarGroup } from './avatar_group';
|
import { AvatarGroup } from './avatar_group';
|
||||||
|
import { DisplayedName } from './displayed_name';
|
||||||
import { EmbeddedStatus } from './embedded_status';
|
import { EmbeddedStatus } from './embedded_status';
|
||||||
import { NamesList } from './names_list';
|
|
||||||
|
|
||||||
export type LabelRenderer = (
|
export type LabelRenderer = (
|
||||||
values: Record<string, React.ReactNode>,
|
displayedName: JSX.Element,
|
||||||
|
total: number,
|
||||||
|
seeMoreHref?: string,
|
||||||
) => JSX.Element;
|
) => JSX.Element;
|
||||||
|
|
||||||
export const NotificationGroupWithStatus: React.FC<{
|
export const NotificationGroupWithStatus: React.FC<{
|
||||||
|
@ -50,15 +52,11 @@ export const NotificationGroupWithStatus: React.FC<{
|
||||||
|
|
||||||
const label = useMemo(
|
const label = useMemo(
|
||||||
() =>
|
() =>
|
||||||
labelRenderer({
|
labelRenderer(
|
||||||
name: (
|
<DisplayedName accountIds={accountIds} />,
|
||||||
<NamesList
|
count,
|
||||||
accountIds={accountIds}
|
labelSeeMoreHref,
|
||||||
total={count}
|
|
||||||
seeMoreHref={labelSeeMoreHref}
|
|
||||||
/>
|
|
||||||
),
|
),
|
||||||
}),
|
|
||||||
[labelRenderer, accountIds, count, labelSeeMoreHref],
|
[labelRenderer, accountIds, count, labelSeeMoreHref],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||||
import type { NotificationGroupReblog } from 'mastodon/models/notification_group';
|
import type { NotificationGroupReblog } from 'mastodon/models/notification_group';
|
||||||
import { useAppSelector } from 'mastodon/store';
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
@ -7,13 +9,29 @@ import { useAppSelector } from 'mastodon/store';
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName, total, seeMoreHref) => {
|
||||||
|
if (total === 1)
|
||||||
|
return (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.reblog'
|
id='notification.reblog'
|
||||||
defaultMessage='{name} boosted your status'
|
defaultMessage='{name} boosted your status'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.reblog.name_and_others_with_link'
|
||||||
|
defaultMessage='{name} and <a>{count, plural, one {# other} other {# others}}</a> boosted your post'
|
||||||
|
values={{
|
||||||
|
name: displayedName,
|
||||||
|
count: total - 1,
|
||||||
|
a: (chunks) =>
|
||||||
|
seeMoreHref ? <Link to={seeMoreHref}>{chunks}</Link> : chunks,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const NotificationReblog: React.FC<{
|
export const NotificationReblog: React.FC<{
|
||||||
notification: NotificationGroupReblog;
|
notification: NotificationGroupReblog;
|
||||||
|
|
|
@ -6,11 +6,11 @@ import type { NotificationGroupStatus } from 'mastodon/models/notification_group
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationWithStatus } from './notification_with_status';
|
import { NotificationWithStatus } from './notification_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName) => (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.status'
|
id='notification.status'
|
||||||
defaultMessage='{name} just posted'
|
defaultMessage='{name} just posted'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ import type { NotificationGroupUpdate } from 'mastodon/models/notification_group
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
import { NotificationWithStatus } from './notification_with_status';
|
import { NotificationWithStatus } from './notification_with_status';
|
||||||
|
|
||||||
const labelRenderer: LabelRenderer = (values) => (
|
const labelRenderer: LabelRenderer = (displayedName) => (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notification.update'
|
id='notification.update'
|
||||||
defaultMessage='{name} edited a post'
|
defaultMessage='{name} edited a post'
|
||||||
values={values}
|
values={{ name: displayedName }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { Icon } from 'mastodon/components/icon';
|
||||||
import Status from 'mastodon/containers/status_container';
|
import Status from 'mastodon/containers/status_container';
|
||||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { NamesList } from './names_list';
|
import { DisplayedName } from './displayed_name';
|
||||||
import type { LabelRenderer } from './notification_group_with_status';
|
import type { LabelRenderer } from './notification_group_with_status';
|
||||||
|
|
||||||
export const NotificationWithStatus: React.FC<{
|
export const NotificationWithStatus: React.FC<{
|
||||||
|
@ -40,10 +40,7 @@ export const NotificationWithStatus: React.FC<{
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const label = useMemo(
|
const label = useMemo(
|
||||||
() =>
|
() => labelRenderer(<DisplayedName accountIds={accountIds} />, count),
|
||||||
labelRenderer({
|
|
||||||
name: <NamesList accountIds={accountIds} total={count} />,
|
|
||||||
}),
|
|
||||||
[labelRenderer, accountIds, count],
|
[labelRenderer, accountIds, count],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -463,8 +463,6 @@
|
||||||
"mute_modal.title": "Mute user?",
|
"mute_modal.title": "Mute user?",
|
||||||
"mute_modal.you_wont_see_mentions": "You won't see posts that mention them.",
|
"mute_modal.you_wont_see_mentions": "You won't see posts that mention them.",
|
||||||
"mute_modal.you_wont_see_posts": "They can still see your posts, but you won't see theirs.",
|
"mute_modal.you_wont_see_posts": "They can still see your posts, but you won't see theirs.",
|
||||||
"name_and_others": "{name} and {count, plural, one {# other} other {# others}}",
|
|
||||||
"name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a>",
|
|
||||||
"navigation_bar.about": "About",
|
"navigation_bar.about": "About",
|
||||||
"navigation_bar.advanced_interface": "Open in advanced web interface",
|
"navigation_bar.advanced_interface": "Open in advanced web interface",
|
||||||
"navigation_bar.blocks": "Blocked users",
|
"navigation_bar.blocks": "Blocked users",
|
||||||
|
@ -497,9 +495,13 @@
|
||||||
"notification.admin.report_statuses": "{name} reported {target} for {category}",
|
"notification.admin.report_statuses": "{name} reported {target} for {category}",
|
||||||
"notification.admin.report_statuses_other": "{name} reported {target}",
|
"notification.admin.report_statuses_other": "{name} reported {target}",
|
||||||
"notification.admin.sign_up": "{name} signed up",
|
"notification.admin.sign_up": "{name} signed up",
|
||||||
|
"notification.admin.sign_up.name_and_others": "{name} and {count, plural, one {# other} other {# others}} signed up",
|
||||||
"notification.favourite": "{name} favorited your post",
|
"notification.favourite": "{name} favorited your post",
|
||||||
|
"notification.favourite.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> favorited your post",
|
||||||
"notification.follow": "{name} followed you",
|
"notification.follow": "{name} followed you",
|
||||||
|
"notification.follow.name_and_others": "{name} and {count, plural, one {# other} other {# others}} followed you",
|
||||||
"notification.follow_request": "{name} has requested to follow you",
|
"notification.follow_request": "{name} has requested to follow you",
|
||||||
|
"notification.follow_request.name_and_others": "{name} and {count, plural, one {# other} other {# others}} has requested to follow you",
|
||||||
"notification.label.mention": "Mention",
|
"notification.label.mention": "Mention",
|
||||||
"notification.label.private_mention": "Private mention",
|
"notification.label.private_mention": "Private mention",
|
||||||
"notification.label.private_reply": "Private reply",
|
"notification.label.private_reply": "Private reply",
|
||||||
|
@ -517,6 +519,7 @@
|
||||||
"notification.own_poll": "Your poll has ended",
|
"notification.own_poll": "Your poll has ended",
|
||||||
"notification.poll": "A poll you voted in has ended",
|
"notification.poll": "A poll you voted in has ended",
|
||||||
"notification.reblog": "{name} boosted your post",
|
"notification.reblog": "{name} boosted your post",
|
||||||
|
"notification.reblog.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> boosted your post",
|
||||||
"notification.relationships_severance_event": "Lost connections with {name}",
|
"notification.relationships_severance_event": "Lost connections with {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.",
|
"notification.relationships_severance_event.account_suspension": "An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.",
|
||||||
"notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
|
"notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
|
||||||
|
|
Loading…
Reference in New Issue