Add collection report modal (#37961)
This commit is contained in:
1 parent
72406a1cd1
commit
919b1e69b8
8 files changed
+476
-148
No files matched your search
@@ -10,6 +10,7 @@ import {
|
||||
BlockModal,
|
||||
DomainBlockModal,
|
||||
ReportModal,
|
||||
ReportCollectionModal,
|
||||
EmbedModal,
|
||||
ListAdder,
|
||||
CompareHistoryModal,
|
||||
@@ -77,6 +78,7 @@ export const MODAL_COMPONENTS = {
|
||||
'BLOCK': BlockModal,
|
||||
'DOMAIN_BLOCK': DomainBlockModal,
|
||||
'REPORT': ReportModal,
|
||||
'REPORT_COLLECTION': ReportCollectionModal,
|
||||
'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
|
||||
'EMBED': EmbedModal,
|
||||
'FOCAL_POINT': () => Promise.resolve({ default: AltTextModal }),
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { Callout } from '@/mastodon/components/callout';
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
import { submitReport } from 'mastodon/actions/reports';
|
||||
import { fetchServer } from 'mastodon/actions/server';
|
||||
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
|
||||
import { Button } from 'mastodon/components/button';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
import { useAccount } from 'mastodon/hooks/useAccount';
|
||||
import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
import Comment from '../../report/comment';
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
});
|
||||
|
||||
const CollectionThanks: React.FC<{
|
||||
onClose: () => void;
|
||||
}> = ({ onClose }) => {
|
||||
return (
|
||||
<>
|
||||
<h3 className='report-dialog-modal__title'>
|
||||
<FormattedMessage
|
||||
id='report.thanks.title_actionable'
|
||||
defaultMessage="Thanks for reporting, we'll look into this."
|
||||
/>
|
||||
</h3>
|
||||
|
||||
<div className='flex-spacer' />
|
||||
|
||||
<div className='report-dialog-modal__actions'>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage id='report.close' defaultMessage='Done' />
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const ReportCollectionModal: React.FC<{
|
||||
collection: ApiCollectionJSON;
|
||||
onClose: () => void;
|
||||
}> = ({ collection, onClose }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { id: collectionId, name, account_id } = collection;
|
||||
const account = useAccount(account_id);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchServer());
|
||||
}, [dispatch]);
|
||||
|
||||
const [submitState, setSubmitState] = useState<
|
||||
'idle' | 'submitting' | 'submitted' | 'error'
|
||||
>('idle');
|
||||
|
||||
const [step, setStep] = useState<'comment' | 'thanks'>('comment');
|
||||
|
||||
const [comment, setComment] = useState('');
|
||||
const [selectedDomains, setSelectedDomains] = useState<string[]>([]);
|
||||
|
||||
const handleDomainToggle = useCallback((domain: string, checked: boolean) => {
|
||||
if (checked) {
|
||||
setSelectedDomains((domains) => [...domains, domain]);
|
||||
} else {
|
||||
setSelectedDomains((domains) => domains.filter((d) => d !== domain));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
setSubmitState('submitting');
|
||||
|
||||
dispatch(
|
||||
submitReport(
|
||||
{
|
||||
account_id,
|
||||
status_ids: [],
|
||||
collection_ids: [collectionId],
|
||||
forward_to_domains: selectedDomains,
|
||||
comment,
|
||||
forward: selectedDomains.length > 0,
|
||||
category: 'spam',
|
||||
},
|
||||
() => {
|
||||
setSubmitState('submitted');
|
||||
setStep('thanks');
|
||||
},
|
||||
() => {
|
||||
setSubmitState('error');
|
||||
},
|
||||
),
|
||||
);
|
||||
}, [account_id, comment, dispatch, collectionId, selectedDomains]);
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const domain = account.get('acct').split('@')[1];
|
||||
const isRemote = !!domain;
|
||||
|
||||
let stepComponent;
|
||||
|
||||
switch (step) {
|
||||
case 'comment':
|
||||
stepComponent = (
|
||||
<Comment
|
||||
modalTitle={
|
||||
<FormattedMessage
|
||||
id='report.collection_comment'
|
||||
defaultMessage='Why do you want to report this collection?'
|
||||
/>
|
||||
}
|
||||
submitError={
|
||||
submitState === 'error' && (
|
||||
<Callout
|
||||
variant='error'
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='report.submission_error'
|
||||
defaultMessage='Report could not be submitted'
|
||||
/>
|
||||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='report.submission_error_details'
|
||||
defaultMessage='Please check your network connection and try again later.'
|
||||
/>
|
||||
</Callout>
|
||||
)
|
||||
}
|
||||
onSubmit={handleSubmit}
|
||||
isSubmitting={submitState === 'submitting'}
|
||||
isRemote={isRemote}
|
||||
comment={comment}
|
||||
domain={domain}
|
||||
onChangeComment={setComment}
|
||||
statusIds={[]}
|
||||
selectedDomains={selectedDomains}
|
||||
onToggleDomain={handleDomainToggle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case 'thanks':
|
||||
stepComponent = <CollectionThanks onClose={onClose} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal report-dialog-modal'>
|
||||
<div className='report-modal__target'>
|
||||
<IconButton
|
||||
className='report-modal__close'
|
||||
title={intl.formatMessage(messages.close)}
|
||||
icon='times'
|
||||
iconComponent={CloseIcon}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='report.target'
|
||||
defaultMessage='Report {target}'
|
||||
values={{ target: <strong>{name}</strong> }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='report-dialog-modal__container'>{stepComponent}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user