2022-05-11 13:26:37 -07:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
|
|
|
import { useHistory } from 'react-router-dom';
|
|
|
|
|
|
|
|
import { remoteInteraction } from 'soapbox/actions/interactions';
|
|
|
|
import { Button, Modal, Stack, Text } from 'soapbox/components/ui';
|
2023-01-14 17:18:13 -08:00
|
|
|
import { useAppSelector, useAppDispatch, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks';
|
2022-12-20 08:34:53 -08:00
|
|
|
import toast from 'soapbox/toast';
|
2022-05-11 13:26:37 -07:00
|
|
|
|
|
|
|
const messages = defineMessages({
|
|
|
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
|
|
|
accountPlaceholder: { id: 'remote_interaction.account_placeholder', defaultMessage: 'Enter your username@domain you want to act from' },
|
|
|
|
userNotFoundError: { id: 'remote_interaction.user_not_found_error', defaultMessage: 'Couldn\'t find given user' },
|
|
|
|
});
|
|
|
|
|
|
|
|
interface IUnauthorizedModal {
|
|
|
|
/** Unauthorized action type. */
|
2022-09-21 14:27:53 -07:00
|
|
|
action: 'FOLLOW' | 'REPLY' | 'REBLOG' | 'FAVOURITE' | 'POLL_VOTE' | 'JOIN',
|
2022-05-11 13:26:37 -07:00
|
|
|
/** Close event handler. */
|
|
|
|
onClose: (modalType: string) => void,
|
|
|
|
/** ActivityPub ID of the account OR status being acted upon. */
|
|
|
|
ap_id?: string,
|
|
|
|
/** Account ID of the account being acted upon. */
|
|
|
|
account?: string,
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Modal to display when a logged-out user tries to do something that requires login. */
|
|
|
|
const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, account: accountId, ap_id: apId }) => {
|
|
|
|
const intl = useIntl();
|
|
|
|
const history = useHistory();
|
|
|
|
const dispatch = useAppDispatch();
|
2022-11-26 08:38:16 -08:00
|
|
|
const instance = useInstance();
|
2023-01-14 17:18:13 -08:00
|
|
|
const { isOpen } = useRegistrationStatus();
|
2022-05-11 13:26:37 -07:00
|
|
|
|
|
|
|
const username = useAppSelector(state => state.accounts.get(accountId)?.display_name);
|
|
|
|
const features = useFeatures();
|
|
|
|
|
|
|
|
const [account, setAccount] = useState('');
|
|
|
|
|
|
|
|
const onAccountChange: React.ChangeEventHandler<HTMLInputElement> = e => {
|
|
|
|
setAccount(e.target.value);
|
|
|
|
};
|
|
|
|
|
|
|
|
const onClickClose = () => {
|
|
|
|
onClose('UNAUTHORIZED');
|
|
|
|
};
|
|
|
|
|
2022-05-13 03:59:56 -07:00
|
|
|
const onSubmit: React.FormEventHandler = e => {
|
2022-05-11 13:26:37 -07:00
|
|
|
e.preventDefault();
|
|
|
|
|
2022-06-20 00:26:45 -07:00
|
|
|
dispatch(remoteInteraction(apId!, account))
|
2022-05-11 13:26:37 -07:00
|
|
|
.then(url => {
|
|
|
|
window.open(url, '_new', 'noopener,noreferrer');
|
|
|
|
onClose('UNAUTHORIZED');
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
if (error.message === 'Couldn\'t find user') {
|
2022-12-20 08:34:53 -08:00
|
|
|
toast.error(intl.formatMessage(messages.userNotFoundError));
|
2022-05-11 13:26:37 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const onLogin = () => {
|
|
|
|
history.push('/login');
|
|
|
|
onClickClose();
|
|
|
|
};
|
|
|
|
|
|
|
|
const onRegister = () => {
|
|
|
|
history.push('/signup');
|
|
|
|
onClickClose();
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderRemoteInteractions = () => {
|
|
|
|
let header;
|
|
|
|
let button;
|
|
|
|
|
|
|
|
if (action === 'FOLLOW') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.follow_title' defaultMessage='Follow {user} remotely' values={{ user: username }} />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.follow' defaultMessage='Proceed to follow' />;
|
|
|
|
} else if (action === 'REPLY') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.reply_title' defaultMessage='Reply to a post remotely' />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.reply' defaultMessage='Proceed to reply' />;
|
|
|
|
} else if (action === 'REBLOG') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.reblog_title' defaultMessage='Reblog a post remotely' />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.reblog' defaultMessage='Proceed to repost' />;
|
|
|
|
} else if (action === 'FAVOURITE') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.favourite_title' defaultMessage='Like a post remotely' />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.favourite' defaultMessage='Proceed to like' />;
|
|
|
|
} else if (action === 'POLL_VOTE') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.poll_vote_title' defaultMessage='Vote in a poll remotely' />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.poll_vote' defaultMessage='Proceed to vote' />;
|
2022-09-21 14:27:53 -07:00
|
|
|
} else if (action === 'JOIN') {
|
|
|
|
header = <FormattedMessage id='remote_interaction.event_join_title' defaultMessage='Join an event remotely' />;
|
|
|
|
button = <FormattedMessage id='remote_interaction.event_join' defaultMessage='Proceed to join' />;
|
2022-05-11 13:26:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal
|
|
|
|
title={header}
|
|
|
|
onClose={onClickClose}
|
2023-01-14 17:18:13 -08:00
|
|
|
confirmationAction={onLogin}
|
2022-05-11 13:26:37 -07:00
|
|
|
confirmationText={<FormattedMessage id='account.login' defaultMessage='Log in' />}
|
2023-01-14 17:18:13 -08:00
|
|
|
secondaryAction={isOpen ? onRegister : undefined}
|
|
|
|
secondaryText={isOpen ? <FormattedMessage id='account.register' defaultMessage='Sign up' /> : undefined}
|
2022-05-11 13:26:37 -07:00
|
|
|
>
|
|
|
|
<div className='remote-interaction-modal__content'>
|
2022-05-13 03:59:56 -07:00
|
|
|
<form className='simple_form remote-interaction-modal__fields' onSubmit={onSubmit}>
|
2022-05-11 13:26:37 -07:00
|
|
|
<input
|
|
|
|
type='text'
|
|
|
|
placeholder={intl.formatMessage(messages.accountPlaceholder)}
|
|
|
|
name='remote_follow[acct]'
|
|
|
|
value={account}
|
|
|
|
autoCorrect='off'
|
|
|
|
autoCapitalize='off'
|
|
|
|
onChange={onAccountChange}
|
|
|
|
required
|
|
|
|
/>
|
2022-05-13 03:59:56 -07:00
|
|
|
<Button type='submit' theme='primary'>{button}</Button>
|
2022-05-11 13:26:37 -07:00
|
|
|
</form>
|
|
|
|
<div className='remote-interaction-modal__divider'>
|
|
|
|
<Text align='center'>
|
|
|
|
<FormattedMessage id='remote_interaction.divider' defaultMessage='or' />
|
|
|
|
</Text>
|
|
|
|
</div>
|
2023-01-14 17:18:13 -08:00
|
|
|
{isOpen && (
|
2022-05-11 13:26:37 -07:00
|
|
|
<Text size='lg' weight='medium'>
|
2022-11-26 08:38:16 -08:00
|
|
|
<FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{ site_title: instance.title }} />
|
2022-05-11 13:26:37 -07:00
|
|
|
</Text>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-06-04 23:45:51 -07:00
|
|
|
if (action && features.remoteInteractions && features.federating) {
|
2022-05-11 13:26:37 -07:00
|
|
|
return renderRemoteInteractions();
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal
|
2022-11-26 08:38:16 -08:00
|
|
|
title={<FormattedMessage id='unauthorized_modal.title' defaultMessage='Sign up for {site_title}' values={{ site_title: instance.title }} />}
|
2022-05-11 13:26:37 -07:00
|
|
|
onClose={onClickClose}
|
|
|
|
confirmationAction={onLogin}
|
|
|
|
confirmationText={<FormattedMessage id='account.login' defaultMessage='Log in' />}
|
2023-01-14 17:18:13 -08:00
|
|
|
secondaryAction={isOpen ? onRegister : undefined}
|
|
|
|
secondaryText={isOpen ? <FormattedMessage id='account.register' defaultMessage='Sign up' /> : undefined}
|
2022-05-11 13:26:37 -07:00
|
|
|
>
|
|
|
|
<Stack>
|
|
|
|
<Text>
|
|
|
|
<FormattedMessage id='unauthorized_modal.text' defaultMessage='You need to be logged in to do that.' />
|
|
|
|
</Text>
|
|
|
|
</Stack>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default UnauthorizedModal;
|