|
|
@ -9,12 +9,12 @@ import { HStack, Text, Emoji } from 'soapbox/components/ui';
|
|
|
|
import AccountContainer from 'soapbox/containers/account_container';
|
|
|
|
import AccountContainer from 'soapbox/containers/account_container';
|
|
|
|
import StatusContainer from 'soapbox/containers/status_container';
|
|
|
|
import StatusContainer from 'soapbox/containers/status_container';
|
|
|
|
import { useAppSelector } from 'soapbox/hooks';
|
|
|
|
import { useAppSelector } from 'soapbox/hooks';
|
|
|
|
|
|
|
|
import { NotificationType, validType } from 'soapbox/utils/notification';
|
|
|
|
|
|
|
|
|
|
|
|
import type { ScrollPosition } from 'soapbox/components/status';
|
|
|
|
import type { ScrollPosition } from 'soapbox/components/status';
|
|
|
|
import type { NotificationType } from 'soapbox/normalizers/notification';
|
|
|
|
|
|
|
|
import type { Account, Status, Notification as NotificationEntity } from 'soapbox/types/entities';
|
|
|
|
import type { Account, Status, Notification as NotificationEntity } from 'soapbox/types/entities';
|
|
|
|
|
|
|
|
|
|
|
|
const notificationForScreenReader = (intl: ReturnType<typeof useIntl>, message: string, timestamp: Date) => {
|
|
|
|
const notificationForScreenReader = (intl: IntlShape, message: string, timestamp: Date) => {
|
|
|
|
const output = [message];
|
|
|
|
const output = [message];
|
|
|
|
|
|
|
|
|
|
|
|
output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
|
|
|
|
output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
|
|
|
@ -48,7 +48,7 @@ const icons: Record<NotificationType, string> = {
|
|
|
|
user_approved: require('@tabler/icons/user-plus.svg'),
|
|
|
|
user_approved: require('@tabler/icons/user-plus.svg'),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const messages: Record<string | number | symbol, MessageDescriptor> = defineMessages({
|
|
|
|
const messages: Record<NotificationType, MessageDescriptor> = defineMessages({
|
|
|
|
follow: {
|
|
|
|
follow: {
|
|
|
|
id: 'notification.follow',
|
|
|
|
id: 'notification.follow',
|
|
|
|
defaultMessage: '{name} followed you',
|
|
|
|
defaultMessage: '{name} followed you',
|
|
|
@ -82,7 +82,7 @@ const messages: Record<string | number | symbol, MessageDescriptor> = defineMess
|
|
|
|
defaultMessage: '{name} moved to {targetName}',
|
|
|
|
defaultMessage: '{name} moved to {targetName}',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'pleroma:chat_mention': {
|
|
|
|
'pleroma:chat_mention': {
|
|
|
|
id: 'notification.chat_mention',
|
|
|
|
id: 'notification.pleroma:chat_mention',
|
|
|
|
defaultMessage: '{name} sent you a message',
|
|
|
|
defaultMessage: '{name} sent you a message',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'pleroma:emoji_reaction': {
|
|
|
|
'pleroma:emoji_reaction': {
|
|
|
@ -221,7 +221,7 @@ const Notification: React.FC<INotificaton> = (props) => {
|
|
|
|
className='w-4 h-4 flex-none'
|
|
|
|
className='w-4 h-4 flex-none'
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
} else if (type) {
|
|
|
|
} else if (validType(type)) {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Icon
|
|
|
|
<Icon
|
|
|
|
src={icons[type]}
|
|
|
|
src={icons[type]}
|
|
|
@ -279,27 +279,25 @@ const Notification: React.FC<INotificaton> = (props) => {
|
|
|
|
|
|
|
|
|
|
|
|
const targetName = notification.target && typeof notification.target === 'object' ? notification.target.acct : '';
|
|
|
|
const targetName = notification.target && typeof notification.target === 'object' ? notification.target.acct : '';
|
|
|
|
|
|
|
|
|
|
|
|
const message: React.ReactNode = type && account && typeof account === 'object' ? buildMessage(intl, type, account, notification.total_count, targetName, instance.title) : null;
|
|
|
|
const message: React.ReactNode = validType(type) && account && typeof account === 'object' ? buildMessage(intl, type, account, notification.total_count, targetName, instance.title) : null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ariaLabel = validType(type) ? (
|
|
|
|
|
|
|
|
notificationForScreenReader(
|
|
|
|
|
|
|
|
intl,
|
|
|
|
|
|
|
|
intl.formatMessage(messages[type], {
|
|
|
|
|
|
|
|
name: account && typeof account === 'object' ? account.acct : '',
|
|
|
|
|
|
|
|
targetName,
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
notification.created_at,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
) : '';
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<HotKeys handlers={getHandlers()} data-testid='notification'>
|
|
|
|
<HotKeys handlers={getHandlers()} data-testid='notification'>
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
className='notification focusable'
|
|
|
|
className='notification focusable'
|
|
|
|
tabIndex={0}
|
|
|
|
tabIndex={0}
|
|
|
|
aria-label={
|
|
|
|
aria-label={ariaLabel}
|
|
|
|
notificationForScreenReader(
|
|
|
|
|
|
|
|
intl,
|
|
|
|
|
|
|
|
intl.formatMessage({
|
|
|
|
|
|
|
|
id: type && messages[type].id,
|
|
|
|
|
|
|
|
defaultMessage: type && messages[type].defaultMessage,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
name: account && typeof account === 'object' ? account.acct : '',
|
|
|
|
|
|
|
|
targetName,
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
notification.created_at,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<div className='p-4 focusable'>
|
|
|
|
<div className='p-4 focusable'>
|
|
|
|
<div className='mb-2'>
|
|
|
|
<div className='mb-2'>
|
|
|
|