Better enforcement of notification types
This commit is contained in:
parent
627e6c574f
commit
f66d65924a
3 changed files with 31 additions and 19 deletions
|
@ -9,9 +9,9 @@ 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: IntlShape, message: string, timestamp: Date) => {
|
const notificationForScreenReader = (intl: IntlShape, message: string, timestamp: Date) => {
|
||||||
|
@ -48,7 +48,7 @@ const icons: Record<NotificationType, string> = {
|
||||||
user_approved: require('@tabler/icons/icons/user-plus.svg'),
|
user_approved: require('@tabler/icons/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',
|
||||||
|
@ -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,9 +279,9 @@ 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 = messages[type] ? (
|
const ariaLabel = validType(type) ? (
|
||||||
notificationForScreenReader(
|
notificationForScreenReader(
|
||||||
intl,
|
intl,
|
||||||
intl.formatMessage(messages[type], {
|
intl.formatMessage(messages[type], {
|
||||||
|
|
|
@ -11,19 +11,6 @@ import {
|
||||||
|
|
||||||
import type { Account, Status, EmbeddedEntity } from 'soapbox/types/entities';
|
import type { Account, Status, EmbeddedEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
export type NotificationType =
|
|
||||||
'follow'
|
|
||||||
| 'follow_request'
|
|
||||||
| 'mention'
|
|
||||||
| 'reblog'
|
|
||||||
| 'favourite'
|
|
||||||
| 'poll'
|
|
||||||
| 'status'
|
|
||||||
| 'move'
|
|
||||||
| 'pleroma:chat_mention'
|
|
||||||
| 'pleroma:emoji_reaction'
|
|
||||||
| 'user_approved';
|
|
||||||
|
|
||||||
// https://docs.joinmastodon.org/entities/notification/
|
// https://docs.joinmastodon.org/entities/notification/
|
||||||
export const NotificationRecord = ImmutableRecord({
|
export const NotificationRecord = ImmutableRecord({
|
||||||
account: null as EmbeddedEntity<Account>,
|
account: null as EmbeddedEntity<Account>,
|
||||||
|
@ -33,7 +20,7 @@ export const NotificationRecord = ImmutableRecord({
|
||||||
id: '',
|
id: '',
|
||||||
status: null as EmbeddedEntity<Status>,
|
status: null as EmbeddedEntity<Status>,
|
||||||
target: null as EmbeddedEntity<Account>, // move
|
target: null as EmbeddedEntity<Account>, // move
|
||||||
type: '' as NotificationType | '',
|
type: '',
|
||||||
total_count: null as number | null, // grouped notifications
|
total_count: null as number | null, // grouped notifications
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
25
app/soapbox/utils/notification.ts
Normal file
25
app/soapbox/utils/notification.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/** Notification types known to Soapbox. */
|
||||||
|
const NOTIFICATION_TYPES = [
|
||||||
|
'follow',
|
||||||
|
'follow_request',
|
||||||
|
'mention',
|
||||||
|
'reblog',
|
||||||
|
'favourite',
|
||||||
|
'poll',
|
||||||
|
'status',
|
||||||
|
'move',
|
||||||
|
'pleroma:chat_mention',
|
||||||
|
'pleroma:emoji_reaction',
|
||||||
|
'user_approved',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
type NotificationType = typeof NOTIFICATION_TYPES[number];
|
||||||
|
|
||||||
|
/** Ensure the Notification is a valid, known type. */
|
||||||
|
const validType = (type: string): type is NotificationType => NOTIFICATION_TYPES.includes(type as any);
|
||||||
|
|
||||||
|
export {
|
||||||
|
NOTIFICATION_TYPES,
|
||||||
|
NotificationType,
|
||||||
|
validType,
|
||||||
|
};
|
Loading…
Reference in a new issue