mirror of https://github.com/mastodon/mastodon.git
Fix the remaining lint issues
parent
15dfb345eb
commit
6b6577e2d2
|
@ -17,9 +17,13 @@ export const fetchNotifications = createDataLoadingThunk(
|
|||
fetchedAccounts.push(...notification.sample_accounts);
|
||||
}
|
||||
|
||||
// if (notification.type === 'admin.report') {
|
||||
// fetchedAccounts.push(...notification.report.target_account);
|
||||
// }
|
||||
if (notification.type === 'admin.report') {
|
||||
fetchedAccounts.push(notification.report.target_account);
|
||||
}
|
||||
|
||||
if (notification.type === 'moderation_warning') {
|
||||
fetchedAccounts.push(notification.moderation_warning.target_account);
|
||||
}
|
||||
|
||||
if ('status' in notification) {
|
||||
fetchedStatuses.push(notification.status);
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
// See app/serializers/rest/notification_group_serializer.rb
|
||||
|
||||
import type { AccountWarningAction } from 'mastodon/models/notification_group';
|
||||
|
||||
import type { ApiAccountJSON } from './accounts';
|
||||
import type { ApiReportJSON } from './reports';
|
||||
import type { ApiStatusJSON } from './statuses';
|
||||
|
||||
// See app/model/notification.rb
|
||||
|
@ -26,7 +29,7 @@ export interface BaseNotificationGroupJSON {
|
|||
notifications_count: number;
|
||||
type: NotificationType;
|
||||
sample_accounts: ApiAccountJSON[];
|
||||
latest_page_notification_at?: string;
|
||||
latest_page_notification_at: string; // FIXME: This will only be present if the notification group is returned in a paginated list, not requested directly
|
||||
page_min_id?: string;
|
||||
page_max_id?: string;
|
||||
}
|
||||
|
@ -38,19 +41,39 @@ interface NotificationGroupWithStatusJSON extends BaseNotificationGroupJSON {
|
|||
|
||||
interface ReportNotificationGroupJSON extends BaseNotificationGroupJSON {
|
||||
type: 'admin.report';
|
||||
report: unknown;
|
||||
report: ApiReportJSON;
|
||||
}
|
||||
|
||||
export interface ApiAccountWarningJSON {
|
||||
id: string;
|
||||
action: AccountWarningAction;
|
||||
text: string;
|
||||
status_ids: string[];
|
||||
created_at: string;
|
||||
target_account: ApiAccountJSON;
|
||||
appeal: unknown;
|
||||
}
|
||||
|
||||
interface ModerationWarningNotificationGroupJSON
|
||||
extends BaseNotificationGroupJSON {
|
||||
type: 'moderation_warning';
|
||||
moderation_warning: unknown;
|
||||
moderation_warning: ApiAccountWarningJSON;
|
||||
}
|
||||
|
||||
export interface ApiAccountRelationshipSeveranceEventJSON {
|
||||
id: string;
|
||||
type: 'account_suspension' | 'domain_block' | 'user_domain_block';
|
||||
purged: boolean;
|
||||
target_name: string;
|
||||
followers_count: number;
|
||||
following_count: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface AccountRelationshipSeveranceNotificationGroupJSON
|
||||
extends BaseNotificationGroupJSON {
|
||||
type: 'severed_relationships';
|
||||
account_relationship_severance_event: unknown;
|
||||
event: ApiAccountRelationshipSeveranceEventJSON;
|
||||
}
|
||||
|
||||
export type NotificationGroupJSON =
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import type { ApiAccountJSON } from './accounts';
|
||||
|
||||
export type ReportCategory = 'other' | 'spam' | 'legal' | 'violation';
|
||||
|
||||
export interface ApiReportJSON {
|
||||
id: string;
|
||||
action_taken: unknown;
|
||||
action_taken_at: unknown;
|
||||
category: ReportCategory;
|
||||
comment: string;
|
||||
forwarded: boolean;
|
||||
created_at: string;
|
||||
status_ids: string[];
|
||||
rule_ids: string[];
|
||||
target_account: ApiAccountJSON;
|
||||
}
|
|
@ -4,6 +4,7 @@ import classNames from 'classnames';
|
|||
|
||||
import GavelIcon from '@/material-icons/400-24px/gavel.svg?react';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import type { AccountWarningAction } from 'mastodon/models/notification_group';
|
||||
|
||||
// This needs to be kept in sync with app/models/account_warning.rb
|
||||
const messages = defineMessages({
|
||||
|
@ -38,17 +39,10 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
interface Props {
|
||||
action:
|
||||
| 'none'
|
||||
| 'disable'
|
||||
| 'mark_statuses_as_sensitive'
|
||||
| 'delete_statuses'
|
||||
| 'sensitive'
|
||||
| 'silence'
|
||||
| 'suspend';
|
||||
action: AccountWarningAction;
|
||||
id: string;
|
||||
hidden: boolean;
|
||||
unread: boolean;
|
||||
hidden?: boolean;
|
||||
unread?: boolean;
|
||||
}
|
||||
|
||||
export const ModerationWarning: React.FC<Props> = ({
|
||||
|
@ -70,7 +64,7 @@ export const ModerationWarning: React.FC<Props> = ({
|
|||
'notification-group notification-group--link notification-group--moderation-warning focusable',
|
||||
{ 'notification-group--unread': unread },
|
||||
)}
|
||||
tabIndex='0'
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className='notification-group__icon'>
|
||||
<Icon id='warning' icon={GavelIcon} />
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import type { List } from 'immutable';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import type { List as ImmutableList, RecordOf } from 'immutable';
|
||||
|
||||
import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react';
|
||||
import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react';
|
||||
|
@ -11,8 +13,11 @@ import { DisplayName } from 'mastodon/components/display_name';
|
|||
import { Icon } from 'mastodon/components/icon';
|
||||
import type { Status } from 'mastodon/models/status';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { EmbeddedStatusContent } from './embedded_status_content';
|
||||
|
||||
export type Mention = RecordOf<{ url: string; acct: string }>;
|
||||
|
||||
export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
|
||||
statusId,
|
||||
}) => {
|
||||
|
@ -27,6 +32,8 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
|
|||
);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (!account) return;
|
||||
|
||||
history.push(`/@${account.acct}/${statusId}`);
|
||||
}, [statusId, account, history]);
|
||||
|
||||
|
@ -38,9 +45,9 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
|
|||
const contentHtml = status.get('contentHtml') as string;
|
||||
const poll = status.get('poll');
|
||||
const language = status.get('language') as string;
|
||||
const mentions = status.get('mentions');
|
||||
const mentions = status.get('mentions') as ImmutableList<Mention>;
|
||||
const mediaAttachmentsSize = (
|
||||
status.get('media_attachments') as List<unknown>
|
||||
status.get('media_attachments') as ImmutableList<unknown>
|
||||
).size;
|
||||
|
||||
return (
|
||||
|
@ -62,7 +69,7 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
|
|||
<div className='notification-group__embedded-status__attachments reply-indicator__attachments'>
|
||||
{!!poll && (
|
||||
<>
|
||||
<Icon icon={BarChart4BarsIcon} />
|
||||
<Icon icon={BarChart4BarsIcon} id='bar-chart-4-bars' />
|
||||
<FormattedMessage
|
||||
id='reply_indicator.poll'
|
||||
defaultMessage='Poll'
|
||||
|
@ -71,7 +78,7 @@ export const EmbeddedStatus: React.FC<{ statusId: string }> = ({
|
|||
)}
|
||||
{mediaAttachmentsSize > 0 && (
|
||||
<>
|
||||
<Icon icon={PhotoLibraryIcon} />
|
||||
<Icon icon={PhotoLibraryIcon} id='photo-library' />
|
||||
<FormattedMessage
|
||||
id='reply_indicator.attachments'
|
||||
defaultMessage='{count, plural, one {# attachment} other {# attachments}}'
|
||||
|
|
|
@ -1,14 +1,29 @@
|
|||
import { useCallback, useRef } from 'react';
|
||||
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
const handleMentionClick = (history: unknown, mention: unknown, e: Event) => {
|
||||
import type { List } from 'immutable';
|
||||
|
||||
import type { History } from 'history';
|
||||
|
||||
import type { Mention } from './embedded_status';
|
||||
|
||||
const handleMentionClick = (
|
||||
history: History,
|
||||
mention: Mention,
|
||||
e: MouseEvent,
|
||||
) => {
|
||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
history.push(`/@${mention.get('acct')}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleHashtagClick = (history: unknown, hashtag: string, e: Event) => {
|
||||
const handleHashtagClick = (
|
||||
history: History,
|
||||
hashtag: string,
|
||||
e: MouseEvent,
|
||||
) => {
|
||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
history.push(`/tags/${hashtag.replace(/^#/, '')}`);
|
||||
|
@ -17,22 +32,22 @@ const handleHashtagClick = (history: unknown, hashtag: string, e: Event) => {
|
|||
|
||||
export const EmbeddedStatusContent: React.FC<{
|
||||
content: string;
|
||||
mentions: unknown;
|
||||
mentions: List<Mention>;
|
||||
language: string;
|
||||
onClick?: unknown;
|
||||
onClick?: () => void;
|
||||
className?: string;
|
||||
}> = ({ content, mentions, language, onClick, className }) => {
|
||||
const clickCoordinatesRef = useRef();
|
||||
const clickCoordinatesRef = useRef<[number, number] | null>();
|
||||
const history = useHistory();
|
||||
|
||||
const handleMouseDown = useCallback(
|
||||
const handleMouseDown = useCallback<React.MouseEventHandler<HTMLDivElement>>(
|
||||
({ clientX, clientY }) => {
|
||||
clickCoordinatesRef.current = [clientX, clientY];
|
||||
},
|
||||
[clickCoordinatesRef],
|
||||
);
|
||||
|
||||
const handleMouseUp = useCallback(
|
||||
const handleMouseUp = useCallback<React.MouseEventHandler<HTMLDivElement>>(
|
||||
({ clientX, clientY, target, button }) => {
|
||||
const [startX, startY] = clickCoordinatesRef.current ?? [0, 0];
|
||||
const [deltaX, deltaY] = [
|
||||
|
@ -40,7 +55,7 @@ export const EmbeddedStatusContent: React.FC<{
|
|||
Math.abs(clientY - startY),
|
||||
];
|
||||
|
||||
let element = target;
|
||||
let element: HTMLDivElement | null = target as HTMLDivElement;
|
||||
|
||||
while (element) {
|
||||
if (
|
||||
|
@ -51,7 +66,7 @@ export const EmbeddedStatusContent: React.FC<{
|
|||
return;
|
||||
}
|
||||
|
||||
element = element.parentNode;
|
||||
element = element.parentNode as HTMLDivElement | null;
|
||||
}
|
||||
|
||||
if (deltaX + deltaY < 5 && button === 0 && onClick) {
|
||||
|
@ -63,29 +78,39 @@ export const EmbeddedStatusContent: React.FC<{
|
|||
[clickCoordinatesRef, onClick],
|
||||
);
|
||||
|
||||
const handleMouseEnter = useCallback(({ currentTarget }) => {
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
const handleMouseEnter = useCallback<React.MouseEventHandler<HTMLDivElement>>(
|
||||
({ currentTarget }) => {
|
||||
const emojis =
|
||||
currentTarget.querySelectorAll<HTMLImageElement>('.custom-emoji');
|
||||
|
||||
for (const emoji of emojis) {
|
||||
emoji.src = emoji.getAttribute('data-original');
|
||||
}
|
||||
}, []);
|
||||
for (const emoji of emojis) {
|
||||
const newSrc = emoji.getAttribute('data-original');
|
||||
if (newSrc) emoji.src = newSrc;
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const handleMouseLeave = useCallback(({ currentTarget }) => {
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
const handleMouseLeave = useCallback<React.MouseEventHandler<HTMLDivElement>>(
|
||||
({ currentTarget }) => {
|
||||
const emojis =
|
||||
currentTarget.querySelectorAll<HTMLImageElement>('.custom-emoji');
|
||||
|
||||
for (const emoji of emojis) {
|
||||
emoji.src = emoji.getAttribute('data-static');
|
||||
}
|
||||
}, []);
|
||||
for (const emoji of emojis) {
|
||||
const newSrc = emoji.getAttribute('data-static');
|
||||
if (newSrc) emoji.src = newSrc;
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const handleContentRef = useCallback(
|
||||
(node) => {
|
||||
(node: HTMLDivElement | null) => {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const links = node.querySelectorAll('a');
|
||||
const links = node.querySelectorAll<HTMLAnchorElement>('a');
|
||||
|
||||
for (const link of links) {
|
||||
if (link.classList.contains('status-link')) {
|
||||
|
@ -105,12 +130,8 @@ export const EmbeddedStatusContent: React.FC<{
|
|||
link.setAttribute('title', `@${mention.get('acct')}`);
|
||||
link.setAttribute('href', `/@${mention.get('acct')}`);
|
||||
} else if (
|
||||
link.textContent[0] === '#' ||
|
||||
(link.previousSibling &&
|
||||
link.previousSibling.textContent &&
|
||||
link.previousSibling.textContent[
|
||||
link.previousSibling.textContent.length - 1
|
||||
] === '#')
|
||||
link.textContent?.[0] === '#' ||
|
||||
link.previousSibling?.textContent?.endsWith('#')
|
||||
) {
|
||||
link.addEventListener(
|
||||
'click',
|
||||
|
@ -130,7 +151,7 @@ export const EmbeddedStatusContent: React.FC<{
|
|||
return (
|
||||
<div
|
||||
role='button'
|
||||
tabIndex='0'
|
||||
tabIndex={0}
|
||||
className={className}
|
||||
ref={handleContentRef}
|
||||
lang={language}
|
||||
|
|
|
@ -30,15 +30,18 @@ const messages = defineMessages({
|
|||
|
||||
export const NotificationAdminReport: React.FC<{
|
||||
notification: NotificationGroupAdminReport;
|
||||
unread: boolean;
|
||||
unread?: boolean;
|
||||
}> = ({ notification, notification: { report }, unread }) => {
|
||||
const intl = useIntl();
|
||||
const targetAccount = useAppSelector((state) =>
|
||||
state.getIn(['accounts', report.target_account.id]),
|
||||
state.accounts.get(report.targetAccountId),
|
||||
);
|
||||
const account = useAppSelector((state) =>
|
||||
state.getIn(['accounts', notification.sampleAccountsIds[0]]),
|
||||
state.accounts.get(notification.sampleAccountsIds[0] ?? '0'),
|
||||
);
|
||||
|
||||
if (!account || !targetAccount) return null;
|
||||
|
||||
const values = {
|
||||
name: (
|
||||
<bdi
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationAdminSignUp: React.FC<{
|
|||
<NotificationGroupWithStatus
|
||||
type='admin-sign-up'
|
||||
icon={PersonAddIcon}
|
||||
iconId='person-add'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
count={notification.notifications_count}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationFavourite: React.FC<{
|
|||
<NotificationGroupWithStatus
|
||||
type='favourite'
|
||||
icon={StarIcon}
|
||||
iconId='star'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
statusId={notification.statusId}
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationFollow: React.FC<{
|
|||
<NotificationGroupWithStatus
|
||||
type='follow'
|
||||
icon={PersonAddIcon}
|
||||
iconId='person-add'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
count={notification.notifications_count}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationFollowRequest: React.FC<{
|
|||
<NotificationGroupWithStatus
|
||||
type='follow-request'
|
||||
icon={PersonAddIcon}
|
||||
iconId='person-add'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
count={notification.notifications_count}
|
||||
|
|
|
@ -21,8 +21,8 @@ import { NotificationUpdate } from './notification_update';
|
|||
export const NotificationGroup: React.FC<{
|
||||
notificationGroupId: NotificationGroupModel['group_key'];
|
||||
unread: boolean;
|
||||
onMoveUp: unknown;
|
||||
onMoveDown: unknown;
|
||||
onMoveUp: (groupId: string) => void;
|
||||
onMoveDown: (groupId: string) => void;
|
||||
}> = ({ notificationGroupId, unread, onMoveUp, onMoveDown }) => {
|
||||
const notificationGroup = useAppSelector((state) =>
|
||||
state.notificationsGroups.groups.find(
|
||||
|
|
|
@ -16,6 +16,7 @@ export type LabelRenderer = (
|
|||
|
||||
export const NotificationGroupWithStatus: React.FC<{
|
||||
icon: IconProp;
|
||||
iconId: string;
|
||||
statusId?: string;
|
||||
count: number;
|
||||
accountIds: string[];
|
||||
|
@ -25,6 +26,7 @@ export const NotificationGroupWithStatus: React.FC<{
|
|||
unread: boolean;
|
||||
}> = ({
|
||||
icon,
|
||||
iconId,
|
||||
timestamp,
|
||||
accountIds,
|
||||
count,
|
||||
|
@ -48,10 +50,10 @@ export const NotificationGroupWithStatus: React.FC<{
|
|||
`notification-group focusable notification-group--${type}`,
|
||||
{ 'notification-group--unread': unread },
|
||||
)}
|
||||
tabIndex='0'
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className='notification-group__icon'>
|
||||
<Icon icon={icon} />
|
||||
<Icon icon={icon} id={iconId} />
|
||||
</div>
|
||||
|
||||
<div className='notification-group__main'>
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationMention: React.FC<{
|
|||
<NotificationWithStatus
|
||||
type='mention'
|
||||
icon={ReplyIcon}
|
||||
iconId='reply'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
count={notification.notifications_count}
|
||||
statusId={notification.statusId}
|
||||
|
|
|
@ -4,6 +4,10 @@ import type { NotificationGroupModerationWarning } from 'mastodon/models/notific
|
|||
export const NotificationModerationWarning: React.FC<{
|
||||
notification: NotificationGroupModerationWarning;
|
||||
unread: boolean;
|
||||
}> = ({ notification: { event }, unread }) => (
|
||||
<ModerationWarning action={event.action} id={event.id} unread={unread} />
|
||||
}> = ({ notification: { moderationWarning }, unread }) => (
|
||||
<ModerationWarning
|
||||
action={moderationWarning.action}
|
||||
id={moderationWarning.id}
|
||||
unread={unread}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -27,6 +27,7 @@ export const NotificationPoll: React.FC<{
|
|||
<NotificationWithStatus
|
||||
type='poll'
|
||||
icon={BarChart4BarsIcon}
|
||||
iconId='bar-chart-4-bars'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
count={notification.notifications_count}
|
||||
statusId={notification.statusId}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationReblog: React.FC<{
|
|||
<NotificationGroupWithStatus
|
||||
type='reblog'
|
||||
icon={RepeatIcon}
|
||||
iconId='repeat'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
statusId={notification.statusId}
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationStatus: React.FC<{
|
|||
<NotificationWithStatus
|
||||
type='status'
|
||||
icon={NotificationsActiveIcon}
|
||||
iconId='notifications-active'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
count={notification.notifications_count}
|
||||
statusId={notification.statusId}
|
||||
|
|
|
@ -21,6 +21,7 @@ export const NotificationUpdate: React.FC<{
|
|||
<NotificationWithStatus
|
||||
type='update'
|
||||
icon={EditIcon}
|
||||
iconId='edit'
|
||||
accountIds={notification.sampleAccountsIds}
|
||||
count={notification.notifications_count}
|
||||
statusId={notification.statusId}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { useMemo } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import type { IconProp } from 'mastodon/components/icon';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import classNames from 'classnames';
|
||||
import Status from 'mastodon/containers/status_container';
|
||||
|
||||
import { NamesList } from './names_list';
|
||||
|
@ -11,12 +12,22 @@ import type { LabelRenderer } from './notification_group_with_status';
|
|||
export const NotificationWithStatus: React.FC<{
|
||||
type: string;
|
||||
icon: IconProp;
|
||||
iconId: string;
|
||||
accountIds: string[];
|
||||
statusId: string;
|
||||
count: number;
|
||||
labelRenderer: LabelRenderer;
|
||||
unread: boolean;
|
||||
}> = ({ icon, accountIds, statusId, count, labelRenderer, type, unread }) => {
|
||||
}> = ({
|
||||
icon,
|
||||
iconId,
|
||||
accountIds,
|
||||
statusId,
|
||||
count,
|
||||
labelRenderer,
|
||||
type,
|
||||
unread,
|
||||
}) => {
|
||||
const label = useMemo(
|
||||
() =>
|
||||
labelRenderer({
|
||||
|
@ -32,11 +43,11 @@ export const NotificationWithStatus: React.FC<{
|
|||
`notification-ungrouped focusable notification-ungrouped--${type}`,
|
||||
{ 'notification-ungrouped--unread': unread },
|
||||
)}
|
||||
tabIndex='0'
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className='notification-ungrouped__header'>
|
||||
<div className='notification-ungrouped__header__icon'>
|
||||
<Icon icon={icon} />
|
||||
<Icon icon={icon} id={iconId} />
|
||||
</div>
|
||||
{label}
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import type {
|
||||
ApiAccountRelationshipSeveranceEventJSON,
|
||||
ApiAccountWarningJSON,
|
||||
BaseNotificationGroupJSON,
|
||||
NotificationGroupJSON,
|
||||
NotificationType,
|
||||
NotificationWithStatusType,
|
||||
} from 'mastodon/api_types/notifications';
|
||||
import type { ApiReportJSON } from 'mastodon/api_types/reports';
|
||||
|
||||
interface BaseNotificationGroup
|
||||
extends Omit<BaseNotificationGroupJSON, 'sample_accounts'> {
|
||||
|
@ -32,12 +35,39 @@ export type NotificationGroupFollow = BaseNotification<'follow'>;
|
|||
export type NotificationGroupFollowRequest = BaseNotification<'follow_request'>;
|
||||
export type NotificationGroupAdminSignUp = BaseNotification<'admin.sign_up'>;
|
||||
|
||||
// TODO: those two will need special types
|
||||
export type NotificationGroupModerationWarning =
|
||||
BaseNotification<'moderation_warning'>;
|
||||
export type NotificationGroupAdminReport = BaseNotification<'admin.report'>;
|
||||
export type NotificationGroupSeveredRelationships =
|
||||
BaseNotification<'severed_relationships'>;
|
||||
export type AccountWarningAction =
|
||||
| 'none'
|
||||
| 'disable'
|
||||
| 'mark_statuses_as_sensitive'
|
||||
| 'delete_statuses'
|
||||
| 'sensitive'
|
||||
| 'silence'
|
||||
| 'suspend';
|
||||
export interface AccountWarning
|
||||
extends Omit<ApiAccountWarningJSON, 'target_account'> {
|
||||
targetAccountId: string;
|
||||
}
|
||||
|
||||
export interface NotificationGroupModerationWarning
|
||||
extends BaseNotification<'moderation_warning'> {
|
||||
moderationWarning: AccountWarning;
|
||||
}
|
||||
|
||||
type AccountRelationshipSeveranceEvent =
|
||||
ApiAccountRelationshipSeveranceEventJSON;
|
||||
export interface NotificationGroupSeveredRelationships
|
||||
extends BaseNotification<'severed_relationships'> {
|
||||
event: AccountRelationshipSeveranceEvent;
|
||||
}
|
||||
|
||||
interface Report extends Omit<ApiReportJSON, 'target_account'> {
|
||||
targetAccountId: string;
|
||||
}
|
||||
|
||||
export interface NotificationGroupAdminReport
|
||||
extends BaseNotification<'admin.report'> {
|
||||
report: Report;
|
||||
}
|
||||
|
||||
export type NotificationGroup =
|
||||
| NotificationGroupFavourite
|
||||
|
@ -53,6 +83,30 @@ export type NotificationGroup =
|
|||
| NotificationGroupAdminSignUp
|
||||
| NotificationGroupAdminReport;
|
||||
|
||||
function createReportFromJSON(reportJSON: ApiReportJSON): Report {
|
||||
const { target_account, ...report } = reportJSON;
|
||||
return {
|
||||
targetAccountId: target_account.id,
|
||||
...report,
|
||||
};
|
||||
}
|
||||
|
||||
function createAccountWarningFromJSON(
|
||||
warningJSON: ApiAccountWarningJSON,
|
||||
): AccountWarning {
|
||||
const { target_account, ...warning } = warningJSON;
|
||||
return {
|
||||
targetAccountId: target_account.id,
|
||||
...warning,
|
||||
};
|
||||
}
|
||||
|
||||
function createAccountRelationshipSeveranceEventFromJSON(
|
||||
eventJson: ApiAccountRelationshipSeveranceEventJSON,
|
||||
): AccountRelationshipSeveranceEvent {
|
||||
return eventJson;
|
||||
}
|
||||
|
||||
export function createNotificationGroupFromJSON(
|
||||
groupJson: NotificationGroupJSON,
|
||||
): NotificationGroup {
|
||||
|
@ -68,8 +122,36 @@ export function createNotificationGroupFromJSON(
|
|||
};
|
||||
}
|
||||
|
||||
return {
|
||||
sampleAccountsIds,
|
||||
...group,
|
||||
};
|
||||
if ('report' in group) {
|
||||
const { report, ...groupWithoutTargetAccount } = group;
|
||||
return {
|
||||
report: createReportFromJSON(report),
|
||||
sampleAccountsIds,
|
||||
...groupWithoutTargetAccount,
|
||||
};
|
||||
}
|
||||
|
||||
switch (group.type) {
|
||||
case 'severed_relationships':
|
||||
return {
|
||||
...group,
|
||||
event: createAccountRelationshipSeveranceEventFromJSON(group.event),
|
||||
sampleAccountsIds,
|
||||
};
|
||||
|
||||
case 'moderation_warning': {
|
||||
const { moderation_warning, ...groupWithoutModerationWarning } = group;
|
||||
return {
|
||||
...groupWithoutModerationWarning,
|
||||
moderationWarning: createAccountWarningFromJSON(moderation_warning),
|
||||
sampleAccountsIds,
|
||||
};
|
||||
}
|
||||
// This is commented out because all group types are covered in the previous statement and have their returns
|
||||
// default:
|
||||
// return {
|
||||
// sampleAccountsIds,
|
||||
// ...group,
|
||||
// };
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue