Merge branch 'scheduled-post-validations' into 'develop'

Scheduled statuses validation

Closes #663 and #659

See merge request soapbox-pub/soapbox-fe!563
merge-requests/557/merge
Alex Gleason 3 years ago
commit 86a90112a1

@ -15,6 +15,7 @@ import { getFeatures } from 'soapbox/utils/features';
import { uploadMedia } from './media';
import { isLoggedIn } from 'soapbox/utils/auth';
import { createStatus } from './statuses';
import snackbar from 'soapbox/actions/snackbar';
let cancelFetchComposeSuggestionsAccounts;
@ -71,6 +72,7 @@ export const COMPOSE_SCHEDULE_REMOVE = 'COMPOSE_SCHEDULE_REMOVE';
const messages = defineMessages({
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
scheduleError: { id: 'compose.invalid_schedule', defaultMessage: 'You must schedule a post at least 5 minutes out.' },
});
const COMPOSE_PANEL_BREAKPOINT = 600 + (285 * 1) + (10 * 1);
@ -170,6 +172,15 @@ const needsDescriptions = state => {
return missingDescriptionModal && hasMissing;
};
const validateSchedule = state => {
const schedule = state.getIn(['compose', 'schedule']);
if (!schedule) return true;
const fiveMinutesFromNow = new Date(new Date().getTime() + 300000);
return schedule.getTime() > fiveMinutesFromNow.getTime();
};
export function submitCompose(routerHistory, force = false) {
return function(dispatch, getState) {
if (!isLoggedIn(getState)) return;
@ -178,6 +189,11 @@ export function submitCompose(routerHistory, force = false) {
const status = state.getIn(['compose', 'text'], '');
const media = state.getIn(['compose', 'media_attachments']);
if (!validateSchedule(state)) {
dispatch(snackbar.error(messages.scheduleError));
return;
}
if ((!status || !status.length) && media.size === 0) {
return;
}

@ -8,6 +8,7 @@ import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import IconButton from 'soapbox/components/icon_button';
import { removeSchedule } from 'soapbox/actions/compose';
import classNames from 'classnames';
const messages = defineMessages({
schedule: { id: 'schedule.post_time', defaultMessage: 'Post Date/Time' },
@ -66,7 +67,7 @@ class ScheduleForm extends React.Component {
const { intl, scheduledAt } = this.props;
return (
<div className='datepicker'>
<div className={classNames('datepicker', { 'datepicker--error': !this.isFiveMinutesFromNow(scheduledAt) })}>
<div className='datepicker__hint'>
<FormattedMessage id='datepicker.hint' defaultMessage='Scheduled to post at…' />
</div>

@ -84,10 +84,6 @@ const initialPoll = ImmutableMap({
multiple: false,
});
const initialSchedule = new Date();
initialSchedule.setDate(initialSchedule.getDate() - 1);
function statusToTextMentions(state, status, account) {
const author = status.getIn(['account', 'acct']);
const mentions = status.get('mentions', []).map(m => m.get('acct'));
@ -407,7 +403,7 @@ export default function compose(state = initialState, action) {
case COMPOSE_POLL_REMOVE:
return state.set('poll', null);
case COMPOSE_SCHEDULE_ADD:
return state.set('schedule', initialSchedule);
return state.set('schedule', new Date());
case COMPOSE_SCHEDULE_SET:
return state.set('schedule', action.date);
case COMPOSE_SCHEDULE_REMOVE:

@ -20,6 +20,10 @@
&__cancel {
padding-left: 10px;
}
&--error .react-datepicker__input-container {
border-color: $error-red !important;
}
}
.datepicker .react-datepicker {

Loading…
Cancel
Save