Add secondary post button back
This commit is contained in:
parent
61559a42a9
commit
118bb5bc81
5 changed files with 97 additions and 8 deletions
|
@ -179,7 +179,7 @@ export function directCompose(account, routerHistory) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function submitCompose(routerHistory) {
|
export function submitCompose(routerHistory, overridePrivacy = null) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
let status = getState().getIn(['compose', 'text'], '');
|
let status = getState().getIn(['compose', 'text'], '');
|
||||||
const media = getState().getIn(['compose', 'media_attachments']);
|
const media = getState().getIn(['compose', 'media_attachments']);
|
||||||
|
@ -228,7 +228,7 @@ export function submitCompose(routerHistory) {
|
||||||
media_attributes,
|
media_attributes,
|
||||||
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
|
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
|
||||||
spoiler_text: spoilerText,
|
spoiler_text: spoilerText,
|
||||||
visibility: getState().getIn(['compose', 'privacy']),
|
visibility: overridePrivacy || getState().getIn(['compose', 'privacy']),
|
||||||
poll: getState().getIn(['compose', 'poll'], null),
|
poll: getState().getIn(['compose', 'poll'], null),
|
||||||
language: getState().getIn(['compose', 'language']),
|
language: getState().getIn(['compose', 'language']),
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { EditIndicator } from './edit_indicator';
|
||||||
import { NavigationBar } from './navigation_bar';
|
import { NavigationBar } from './navigation_bar';
|
||||||
import { PollForm } from "./poll_form";
|
import { PollForm } from "./poll_form";
|
||||||
import { ReplyIndicator } from './reply_indicator';
|
import { ReplyIndicator } from './reply_indicator';
|
||||||
|
import { SecondaryPrivacyButton } from './secondary_privacy_button';
|
||||||
|
|
||||||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
spoiler: PropTypes.bool,
|
spoiler: PropTypes.bool,
|
||||||
spoilerAlwaysOn: PropTypes.bool,
|
spoilerAlwaysOn: PropTypes.bool,
|
||||||
privacy: PropTypes.string,
|
privacy: PropTypes.string,
|
||||||
|
sideArm: PropTypes.string,
|
||||||
spoilerText: PropTypes.string,
|
spoilerText: PropTypes.string,
|
||||||
focusDate: PropTypes.instanceOf(Date),
|
focusDate: PropTypes.instanceOf(Date),
|
||||||
caretPosition: PropTypes.number,
|
caretPosition: PropTypes.number,
|
||||||
|
@ -96,6 +98,10 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||||
this.handleSubmit();
|
this.handleSubmit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.keyCode === 13 && e.altKey) {
|
||||||
|
this.handleSecondarySubmit();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getFulltextForCharacterCounting = () => {
|
getFulltextForCharacterCounting = () => {
|
||||||
|
@ -110,7 +116,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
|
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (e, overridePrivacy = null) => {
|
||||||
if (this.props.text !== this.textareaRef.current.value) {
|
if (this.props.text !== this.textareaRef.current.value) {
|
||||||
// Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
|
// Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
|
||||||
// Update the state to match the current text
|
// Update the state to match the current text
|
||||||
|
@ -121,13 +127,18 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onSubmit(this.props.history || null);
|
this.props.onSubmit(this.props.history || null, overridePrivacy);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleSecondarySubmit = () => {
|
||||||
|
const { sideArm } = this.props;
|
||||||
|
this.handleSubmit(null, sideArm === 'none' ? null : sideArm);
|
||||||
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
};
|
};
|
||||||
|
@ -303,6 +314,12 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='compose-form__submit'>
|
<div className='compose-form__submit'>
|
||||||
|
<SecondaryPrivacyButton
|
||||||
|
disabled={!this.canSubmit()}
|
||||||
|
privacy={this.props.sideArm}
|
||||||
|
isEditing={this.props.isEditing}
|
||||||
|
onClick={this.handleSecondarySubmit}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
type='submit'
|
type='submit'
|
||||||
text={intl.formatMessage(this.props.isEditing ? messages.saveChanges : (this.props.isInReply ? messages.reply : messages.publish))}
|
text={intl.formatMessage(this.props.isEditing ? messages.saveChanges : (this.props.isInReply ? messages.reply : messages.publish))}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
||||||
|
import MailIcon from '@/material-icons/400-24px/mail.svg?react';
|
||||||
|
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||||
|
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
|
||||||
|
import { Button } from 'flavours/glitch/components/button';
|
||||||
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
public: { id: 'privacy.public.short', defaultMessage: 'Public' },
|
||||||
|
unlisted: { id: 'privacy.unlisted.short', defaultMessage: 'Quiet public' },
|
||||||
|
private: { id: 'privacy.private.short', defaultMessage: 'Followers' },
|
||||||
|
direct: { id: 'privacy.direct.short', defaultMessage: 'Specific people' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SecondaryPrivacyButton = ({ disabled, privacy, isEditing, onClick }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
if (isEditing || !privacy || privacy === 'none') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const privacyProps = {
|
||||||
|
direct: { icon: 'envelope', iconComponent: MailIcon, title: messages.direct },
|
||||||
|
private: { icon: 'lock', iconComponent: LockIcon, title: messages.private },
|
||||||
|
public: { icon: 'globe', iconComponent: PublicIcon, title: messages.public },
|
||||||
|
unlisted: { icon: 'unlock', iconComponent: QuietTimeIcon, title: messages.unlisted },
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button className='secondary-post-button' disabled={disabled} onClick={onClick} title={intl.formatMessage(privacyProps[privacy].title)}>
|
||||||
|
<Icon id={privacyProps[privacy].id} icon={privacyProps[privacy].iconComponent} />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SecondaryPrivacyButton.propTypes = {
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
privacy: PropTypes.string,
|
||||||
|
isEditing: PropTypes.bool,
|
||||||
|
onClick: PropTypes.func.isRequired,
|
||||||
|
};
|
|
@ -1,5 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { privacyPreference } from 'flavours/glitch/utils/privacy_preference';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
changeCompose,
|
changeCompose,
|
||||||
submitCompose,
|
submitCompose,
|
||||||
|
@ -12,6 +14,23 @@ import {
|
||||||
} from '../../../actions/compose';
|
} from '../../../actions/compose';
|
||||||
import ComposeForm from '../components/compose_form';
|
import ComposeForm from '../components/compose_form';
|
||||||
|
|
||||||
|
const sideArmPrivacy = state => {
|
||||||
|
const inReplyTo = state.getIn(['compose', 'in_reply_to']);
|
||||||
|
const replyPrivacy = inReplyTo ? state.getIn(['statuses', inReplyTo, 'visibility']) : null;
|
||||||
|
const sideArmBasePrivacy = state.getIn(['local_settings', 'side_arm']);
|
||||||
|
const sideArmRestrictedPrivacy = replyPrivacy ? privacyPreference(replyPrivacy, sideArmBasePrivacy) : null;
|
||||||
|
let sideArmPrivacy = null;
|
||||||
|
switch (state.getIn(['local_settings', 'side_arm_reply_mode'])) {
|
||||||
|
case 'copy':
|
||||||
|
sideArmPrivacy = replyPrivacy;
|
||||||
|
break;
|
||||||
|
case 'restrict':
|
||||||
|
sideArmPrivacy = sideArmRestrictedPrivacy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sideArmPrivacy || sideArmBasePrivacy;
|
||||||
|
};
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
text: state.getIn(['compose', 'text']),
|
text: state.getIn(['compose', 'text']),
|
||||||
suggestions: state.getIn(['compose', 'suggestions']),
|
suggestions: state.getIn(['compose', 'suggestions']),
|
||||||
|
@ -29,6 +48,7 @@ const mapStateToProps = state => ({
|
||||||
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||||
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
|
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
|
||||||
lang: state.getIn(['compose', 'language']),
|
lang: state.getIn(['compose', 'language']),
|
||||||
|
sideArm: sideArmPrivacy(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
@ -37,8 +57,8 @@ const mapDispatchToProps = (dispatch) => ({
|
||||||
dispatch(changeCompose(text));
|
dispatch(changeCompose(text));
|
||||||
},
|
},
|
||||||
|
|
||||||
onSubmit (router) {
|
onSubmit (router, overridePrivacy = null) {
|
||||||
dispatch(submitCompose(router));
|
dispatch(submitCompose(router, overridePrivacy));
|
||||||
},
|
},
|
||||||
|
|
||||||
onClearSuggestions () {
|
onClearSuggestions () {
|
||||||
|
|
|
@ -750,10 +750,17 @@ body > [data-popper-placement] {
|
||||||
|
|
||||||
&__submit {
|
&__submit {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex: 1 0 100%; // glitch: always on its own line
|
||||||
flex: 1 1 auto;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
gap: 5px; // glitch: handle secondary post privacy
|
||||||
|
align-items: stretch; // glitch: handle secondary post privacy
|
||||||
|
|
||||||
|
.button.secondary-post-button {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__buttons {
|
&__buttons {
|
||||||
|
|
Loading…
Reference in a new issue