-
+ {!isScheduledStatusEditting &&
}
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index 10e8bfd8a..7f87ad677 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -29,6 +29,8 @@ const mapStateToProps = state => ({
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
prohibitedVisibilities: state.getIn(['compose', 'prohibited_visibilities']),
prohibitedWords: state.getIn(['compose', 'prohibited_words']),
+ isScheduled: !!state.getIn(['compose', 'scheduled']),
+ isScheduledStatusEditting: !!state.getIn(['compose', 'scheduled_status_id']),
});
const mapDispatchToProps = (dispatch, { intl }) => ({
diff --git a/app/javascript/mastodon/features/compose/containers/quote_indicator_container.js b/app/javascript/mastodon/features/compose/containers/quote_indicator_container.js
index 8a3ad4959..3928bd2a9 100644
--- a/app/javascript/mastodon/features/compose/containers/quote_indicator_container.js
+++ b/app/javascript/mastodon/features/compose/containers/quote_indicator_container.js
@@ -8,6 +8,7 @@ const makeMapStateToProps = () => {
const mapStateToProps = state => ({
status: getStatus(state, { id: state.getIn(['compose', 'quote_from']) }),
+ isScheduledStatusEditting: !!state.getIn(['compose', 'scheduled_status_id']),
});
return mapStateToProps;
diff --git a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
index 5eb1eb72a..39360c1c5 100644
--- a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
+++ b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js
@@ -8,6 +8,7 @@ const makeMapStateToProps = () => {
const mapStateToProps = state => ({
status: getStatus(state, { id: state.getIn(['compose', 'in_reply_to']) }),
+ isScheduledStatusEditting: !!state.getIn(['compose', 'scheduled_status_id']),
});
return mapStateToProps;
diff --git a/app/javascript/mastodon/features/compose/containers/warning_container.js b/app/javascript/mastodon/features/compose/containers/warning_container.js
index 99023144d..1a9be7de3 100644
--- a/app/javascript/mastodon/features/compose/containers/warning_container.js
+++ b/app/javascript/mastodon/features/compose/containers/warning_container.js
@@ -1,9 +1,12 @@
-import React from 'react';
+import React, { Fragment } from 'react';
import { connect } from 'react-redux';
import Warning from '../components/warning';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { me } from '../../../initial_state';
+import { cancelScheduledStatusCompose } from '../../../actions/compose';
+import Icon from 'mastodon/components/icon';
+import IconButton from 'mastodon/components/icon_button';
const buildHashtagRE = () => {
try {
@@ -37,9 +40,38 @@ const mapStateToProps = state => ({
limitedMessageWarning: state.getIn(['compose', 'privacy']) === 'limited',
mutualMessageWarning: state.getIn(['compose', 'privacy']) === 'mutual',
personalMessageWarning: state.getIn(['compose', 'privacy']) === 'personal',
+ isScheduledStatusEditting: !!state.getIn(['compose', 'scheduled_status_id']),
});
-const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning, limitedMessageWarning, mutualMessageWarning, personalMessageWarning }) => {
+const mapDispatchToProps = dispatch => ({
+
+ onCancel () {
+ dispatch(cancelScheduledStatusCompose());
+ },
+
+});
+
+const ScheduledStatusWarningWrapper = ({ isScheduledStatusEditting, onCancel }) => {
+ if (!isScheduledStatusEditting) {
+ return null;
+ }
+
+ return (
+
+ );
+};
+
+ScheduledStatusWarningWrapper.propTypes = {
+ isScheduledStatusEditting: PropTypes.bool,
+ onCancel: PropTypes.func.isRequired,
+};
+
+const PrivacyWarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning, limitedMessageWarning, mutualMessageWarning, personalMessageWarning }) => {
if (needsLockWarning) {
return }} />} />;
}
@@ -73,7 +105,7 @@ const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning
return null;
};
-WarningWrapper.propTypes = {
+PrivacyWarningWrapper.propTypes = {
needsLockWarning: PropTypes.bool,
hashtagWarning: PropTypes.bool,
directMessageWarning: PropTypes.bool,
@@ -82,4 +114,24 @@ WarningWrapper.propTypes = {
personalMessageWarning: PropTypes.bool,
};
-export default connect(mapStateToProps)(WarningWrapper);
+const WarningWrapper = (props) => {
+ return (
+
+
+
+
+ );
+};
+
+WarningWrapper.propTypes = {
+ needsLockWarning: PropTypes.bool,
+ hashtagWarning: PropTypes.bool,
+ directMessageWarning: PropTypes.bool,
+ limitedMessageWarning: PropTypes.bool,
+ mutualMessageWarning: PropTypes.bool,
+ personalMessageWarning: PropTypes.bool,
+ isScheduledStatusEditting: PropTypes.bool,
+ onCancel: PropTypes.func.isRequired,
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(WarningWrapper);
diff --git a/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js b/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js
index 94cef81a7..1068822fe 100644
--- a/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js
+++ b/app/javascript/mastodon/features/direct_timeline/containers/conversation_container.js
@@ -37,7 +37,7 @@ const mapDispatchToProps = (dispatch, { intl, conversationId }) => ({
dispatch((_, getState) => {
let state = getState();
- if (state.getIn(['compose', 'text']).trim().length !== 0) {
+ if (state.getIn(['compose', 'text']).trim().length !== 0 && state.getIn(['compose', 'dirty'])) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index 2fffffc8a..dffc74305 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -11,6 +11,7 @@ import { me, profile_directory, showTrends, enableLimitedTimeline, enablePersona
import { fetchFollowRequests } from 'mastodon/actions/accounts';
import { fetchFavouriteDomains } from 'mastodon/actions/favourite_domains';
import { fetchFavouriteTags } from 'mastodon/actions/favourite_tags';
+import { fetchScheduledStatuses } from 'mastodon/actions/scheduled_statuses';
import { List as ImmutableList } from 'immutable';
import NavigationContainer from '../compose/containers/navigation_container';
import Icon from 'mastodon/components/icon';
@@ -31,6 +32,7 @@ const messages = defineMessages({
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
+ scheduled_statuses: { id: 'navigation_bar.scheduled_statuses', defaultMessage: 'Scheduled Posts' },
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
emoji_reactions: { id: 'navigation_bar.emoji_reactions', defaultMessage: 'Emoji reactions' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
@@ -60,6 +62,7 @@ const mapStateToProps = state => ({
myAccount: state.getIn(['accounts', me]),
columns: state.getIn(['settings', 'columns']),
unreadFollowRequests: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
+ scheduledStatusesCount: state.getIn(['scheduled_statuses', 'items'], ImmutableList()).size,
lists: getOrderedLists(state),
favourite_domains: getOrderedDomains(state),
favourite_tags: getOrderedTags(state),
@@ -70,6 +73,7 @@ const mapDispatchToProps = dispatch => ({
fetchFollowRequests: () => dispatch(fetchFollowRequests()),
fetchFavouriteDomains: () => dispatch(fetchFavouriteDomains()),
fetchFavouriteTags: () => dispatch(fetchFavouriteTags()),
+ fetchScheduledStatuses: () => dispatch(fetchScheduledStatuses()),
});
const badgeDisplay = (number, limit) => {
@@ -101,7 +105,9 @@ class GettingStarted extends ImmutablePureComponent {
fetchFollowRequests: PropTypes.func.isRequired,
fetchFavouriteDomains: PropTypes.func.isRequired,
fetchFavouriteTags: PropTypes.func.isRequired,
+ fetchScheduledStatuses: PropTypes.func.isRequired,
unreadFollowRequests: PropTypes.number,
+ scheduledStatusesCount: PropTypes.number,
unreadNotifications: PropTypes.number,
lists: ImmutablePropTypes.list,
favourite_domains: ImmutablePropTypes.list,
@@ -109,7 +115,7 @@ class GettingStarted extends ImmutablePureComponent {
};
componentDidMount () {
- const { fetchFollowRequests, fetchFavouriteDomains, fetchFavouriteTags, multiColumn } = this.props;
+ const { fetchFollowRequests, fetchFavouriteDomains, fetchFavouriteTags, fetchScheduledStatuses, multiColumn } = this.props;
if (!multiColumn && window.innerWidth >= NAVIGATION_PANEL_BREAKPOINT) {
this.context.router.history.replace('/timelines/home');
@@ -119,10 +125,11 @@ class GettingStarted extends ImmutablePureComponent {
fetchFollowRequests();
fetchFavouriteDomains();
fetchFavouriteTags();
+ fetchScheduledStatuses();
}
render () {
- const { intl, myAccount, columns, multiColumn, unreadFollowRequests, lists, favourite_domains, favourite_tags, columnWidth } = this.props;
+ const { intl, myAccount, columns, multiColumn, unreadFollowRequests, scheduledStatusesCount, lists, favourite_domains, favourite_tags, columnWidth } = this.props;
const navItems = [];
let height = (multiColumn) ? 0 : 60;
@@ -245,14 +252,24 @@ class GettingStarted extends ImmutablePureComponent {
height += 48*6;
+ if (myAccount.get('locked') || unreadFollowRequests > 0) {
+ navItems.push(
);
+ height += 48;
+ }
+
+ if (scheduledStatusesCount > 0) {
+ navItems.push(
);
+ height += 48;
+ }
+
if (lists && !lists.isEmpty()) {
navItems.push(
);
height += 34;
lists.map(list => {
navItems.push(
);
- height += 48
- })
+ height += 48;
+ });
}
if (favourite_domains && !favourite_domains.isEmpty()) {
@@ -261,8 +278,8 @@ class GettingStarted extends ImmutablePureComponent {
favourite_domains.map(favourite_domain => {
navItems.push(
);
- height += 48
- })
+ height += 48;
+ });
}
if (favourite_tags && !favourite_tags.isEmpty()) {
@@ -271,13 +288,8 @@ class GettingStarted extends ImmutablePureComponent {
favourite_tags.map(favourite_tag => {
navItems.push(
);
- height += 48
- })
- }
-
- if (myAccount.get('locked') || unreadFollowRequests > 0) {
- navItems.push(
);
- height += 48;
+ height += 48;
+ });
}
if (!multiColumn) {
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js
index efe9dd98e..6c2369d65 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.js
@@ -178,6 +178,16 @@ export default class ColumnSettings extends React.PureComponent {