Schedule posts See merge request soapbox-pub/soapbox-fe!536merge-requests/539/merge
commit
1cb7f730ae
@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import IconButton from '../../../components/icon_button';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
add_schedule: { id: 'schedule_button.add_schedule', defaultMessage: 'Schedule post for later' },
|
||||
remove_schedule: { id: 'schedule_button.remove_schedule', defaultMessage: 'Post immediately' },
|
||||
});
|
||||
|
||||
const iconStyle = {
|
||||
height: null,
|
||||
lineHeight: '27px',
|
||||
};
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class ScheduleButton extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
active: PropTypes.bool,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onClick();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, active, disabled } = this.props;
|
||||
|
||||
return (
|
||||
<div className='compose-form__schedule-button'>
|
||||
<IconButton
|
||||
icon='calendar'
|
||||
title={intl.formatMessage(active ? messages.remove_schedule : messages.add_schedule)}
|
||||
disabled={disabled}
|
||||
onClick={this.handleClick}
|
||||
className={`compose-form__schedule-button-icon ${active ? 'active' : ''}`}
|
||||
size={18}
|
||||
inverted
|
||||
style={iconStyle}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import DatePicker from 'react-datepicker';
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
|
||||
const messages = defineMessages({
|
||||
schedule: { id: 'schedule.post_time', defaultMessage: 'Post Date/Time' },
|
||||
});
|
||||
|
||||
class ScheduleForm extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
schedule: PropTypes.instanceOf(Date),
|
||||
intl: PropTypes.object.isRequired,
|
||||
onSchedule: PropTypes.func.isRequired,
|
||||
active: PropTypes.bool,
|
||||
};
|
||||
|
||||
setSchedule(date)
|
||||
{
|
||||
this.setState({ schedule: date });
|
||||
this.props.onSchedule(date);
|
||||
}
|
||||
|
||||
openDatePicker(datePicker)
|
||||
{
|
||||
if (!datePicker)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
datePicker.setOpen(true);
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
this.setState({ schedule: this.props.schedule });
|
||||
}
|
||||
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
|
||||
this.setSchedule = this.setSchedule.bind(this);
|
||||
}
|
||||
|
||||
isCurrentOrFutureDate(date)
|
||||
{
|
||||
return date && new Date().setHours(0, 0, 0, 0) <= date.setHours(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
isFiveMinutesFromNow(time)
|
||||
{
|
||||
const fiveMinutesFromNow = new Date(new Date().getTime() + 300000); // now, plus five minutes (Pleroma won't schedule posts )
|
||||
const selectedDate = new Date(time);
|
||||
|
||||
return fiveMinutesFromNow.getTime() < selectedDate.getTime();
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.props.active || !this.state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const { schedule } = this.state;
|
||||
|
||||
return (
|
||||
<DatePicker
|
||||
selected={schedule}
|
||||
showTimeSelect
|
||||
dateFormat='MMMM d, yyyy h:mm aa'
|
||||
timeIntervals={15}
|
||||
timeFormat='HH:mm'
|
||||
timeInputLabel='Time:'
|
||||
wrapperClassName='react-datepicker-wrapper'
|
||||
onChange={this.setSchedule}
|
||||
placeholderText={this.props.intl.formatMessage(messages.schedule)}
|
||||
filterDate={this.isCurrentOrFutureDate}
|
||||
filterTime={this.isFiveMinutesFromNow}
|
||||
ref={this.isCurrentOrFutureDate(schedule) ? null : this.openDatePicker}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
schedule: state.getIn(['compose', 'schedule']),
|
||||
});
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(ScheduleForm));
|
@ -0,0 +1,23 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ScheduleButton from '../components/schedule_button';
|
||||
import { addSchedule, removeSchedule } from '../../../actions/compose';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
active: state.getIn(['compose', 'schedule']) ? true : false,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
||||
onClick() {
|
||||
dispatch((_, getState) => {
|
||||
if (getState().getIn(['compose', 'schedule'])) {
|
||||
dispatch(removeSchedule());
|
||||
} else {
|
||||
dispatch(addSchedule());
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleButton);
|
@ -0,0 +1,16 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ScheduleForm from '../components/schedule_form';
|
||||
import { setSchedule } from '../../../actions/compose';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
schedule: state.getIn(['compose', 'schedule']),
|
||||
active: state.getIn(['compose', 'schedule']) ? true : false,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onSchedule(date) {
|
||||
dispatch(setSchedule(date));
|
||||
},
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleForm);
|
Loading…
Reference in new issue