This commit is contained in:
mgabdev
2020-04-07 21:06:59 -04:00
parent b5e3c2a94f
commit bb4fcdf32d
101 changed files with 1069 additions and 1886 deletions

View File

@@ -1,8 +1,8 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { length } from 'stringz'
import ImmutablePropTypes from 'react-immutable-proptypes'
import classNames from 'classnames/bind'
import { length } from 'stringz'
import CharacterCounter from '../../../../components/character_counter'
import UploadForm from '../upload_form'
import AutosuggestTextbox from '../../../../components/autosuggest_textbox'
@@ -15,7 +15,7 @@ import StatusVisibilityButton from '../../components/status_visibility_button'
import EmojiPickerButton from '../../components/emoji_picker_button'
import PollFormContainer from '../../containers/poll_form_container'
import SchedulePostButton from '../schedule_post_button'
import QuotedStatusPreviewContainer from '../../containers/quoted_status_preview_container'
import StatusContainer from '../../../../containers/status_container'
import Button from '../../../../components/button'
import Avatar from '../../../../components/avatar'
import { isMobile } from '../../../../utils/is_mobile'
@@ -29,7 +29,7 @@ const messages = defineMessages({
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
publish: { id: 'compose_form.publish', defaultMessage: 'Gab' },
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}' },
schedulePost: { id: 'compose_form.schedule_post', defaultMessage: 'Schedule Post' }
schedulePost: { id: 'compose_form.schedule_post', defaultMessage: 'Schedule Post' },
});
const cx = classNames.bind(_s)
@@ -79,6 +79,7 @@ class ComposeForm extends ImmutablePureComponent {
scheduledAt: PropTypes.instanceOf(Date),
setScheduledAt: PropTypes.func.isRequired,
replyToId: PropTypes.string,
hasPoll: PropTypes.bool,
};
static defaultProps = {
@@ -104,7 +105,7 @@ class ComposeForm extends ImmutablePureComponent {
handleClick = (e) => {
if (!this.form) return false;
if (e.target) {
if (e.target.classList.contains('react-datepicker__time-list-item')) return;
if (e.target.classList.contains('react-datepicker__time-list-item')) return false
}
if (!this.form.contains(e.target)) {
this.handleClickOutside();
@@ -162,11 +163,11 @@ class ComposeForm extends ImmutablePureComponent {
}
componentDidMount() {
document.addEventListener("click", this.handleClick, false);
document.addEventListener('click', this.handleClick, false);
}
componentWillUnmount() {
document.removeEventListener("click", this.handleClick, false);
document.removeEventListener('click', this.handleClick, false);
}
componentDidUpdate(prevProps) {
@@ -201,19 +202,19 @@ class ComposeForm extends ImmutablePureComponent {
}
setForm = (c) => {
this.form = c;
this.form = c
}
setSpoilerText = (c) => {
this.spoilerText = c;
this.spoilerText = c
}
handleEmojiPick = (data) => {
const { text } = this.props;
const position = this.autosuggestTextarea.textbox.selectionStart;
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
const { text } = this.props
const position = this.autosuggestTextarea.textbox.selectionStart
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1])
this.props.onPickEmoji(position, data, needsSpace);
this.props.onPickEmoji(position, data, needsSpace)
}
render() {
@@ -230,11 +231,13 @@ class ComposeForm extends ImmutablePureComponent {
edit,
scheduledAt,
spoiler,
replyToId
replyToId,
hasPoll,
isUploading,
} = this.props
const disabled = this.props.isSubmitting;
const text = [this.props.spoilerText, countableText(this.props.text)].join('');
const disabledButton = disabled || this.props.isUploading || this.props.isChangingUpload || length(text) > maxPostCharacterCount || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
const disabledButton = disabled || isUploading || this.props.isChangingUpload || length(text) > maxPostCharacterCount || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
const shouldAutoFocus = autoFocus && !showSearch && !isMobile(window.innerWidth)
const parentContainerClasses = cx({
@@ -255,7 +258,8 @@ class ComposeForm extends ImmutablePureComponent {
const actionsContainerClasses = cx({
default: 1,
flexRow: 1,
alignItemsCenter: 1,
alignItemsCenter: !shouldCondense,
alignItemsStart: shouldCondense,
mt10: !shouldCondense,
px15: !shouldCondense,
})
@@ -313,19 +317,25 @@ class ComposeForm extends ImmutablePureComponent {
autoFocus={shouldAutoFocus}
small={shouldCondense}
textarea
>
/>
{
(isUploading || anyMedia) &&
<div className={[_s.default, _s.px15].join(' ')}>
<UploadForm replyToId={replyToId} />
{
!edit &&
<PollFormContainer replyToId={replyToId} />
}
</div>
}
</AutosuggestTextbox>
{
!edit && hasPoll &&
<div className={[_s.default, _s.px15].join(' ')}>
<PollFormContainer replyToId={replyToId} />
</div>
}
{ /* quoteOfId && <QuotedStatusPreviewContainer id={quoteOfId} /> */}
{
/* : todo : quoteOfId && <StatusContainer id={quoteOfId} /> */
}
<div className={actionsContainerClasses}>
<div className={[_s.default, _s.flexRow, _s.marginRightAuto].join(' ')}>
@@ -358,8 +368,8 @@ class ComposeForm extends ImmutablePureComponent {
!shouldCondense &&
<CharacterCounter max={maxPostCharacterCount} text={text} />
}
{
{ /* : todo : show send on shouldCondense if any text */
!shouldCondense &&
<Button
className={[_s.fontSize15PX, _s.px15].join(' ')}

View File

@@ -7,7 +7,7 @@ const messages = defineMessages({
})
const mapStateToProps = state => ({
active: state.get('popover').popoverType === 'EMOJI_PICKER',
active: state.getIn(['popover', 'popoverType']) === 'EMOJI_PICKER',
})
const mapDispatchToProps = dispatch => ({

View File

@@ -9,7 +9,7 @@ const messages = defineMessages({
})
const mapStateToProps = (state) => ({
active: !!state.getIn(['compose', 'gif']) || state.get('modal').modalType === 'GIF_PICKER',
active: !!state.getIn(['compose', 'gif']) || state.getIn(['modal', 'modalType']) === 'GIF_PICKER',
})
const mapDispatchToProps = (dispatch) => ({

View File

@@ -1,23 +0,0 @@
import ImmutablePropTypes from 'react-immutable-proptypes';
import DisplayName from '../../../components/display_name';
import StatusContent from '../../../components/status_content';
// : todo : do we need this? make work inside of status/status content
export default class QuotedStatusPreview extends PureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
}
render() {
const { status, account } = this.props;
return (
<div className='compose-form__quote-preview'>
<DisplayName account={account} />
<StatusContent status={status} expanded={false} />
</div>
);
}
}

View File

@@ -28,6 +28,11 @@ class StatusVisibilityButton extends PureComponent {
intl: PropTypes.object.isRequired,
small: PropTypes.bool,
onOpenPopover: PropTypes.func.isRequired,
value: PropTypes.oneOf([
'private',
'unlisted',
'public',
]),
}
handleOnClick = () => {
@@ -42,20 +47,20 @@ class StatusVisibilityButton extends PureComponent {
const {
intl,
small,
value
value,
} = this.props
let icon;
switch (value) {
case 'unlisted':
icon = 'unlock-filled'
break;
case 'private':
icon = 'lock-filled'
break;
default:
icon = 'globe'
break;
case 'unlisted':
icon = 'unlock-filled'
break;
case 'private':
icon = 'lock-filled'
break;
default:
icon = 'globe'
break;
}
return (

View File

@@ -24,7 +24,7 @@ class UploadForm extends ImmutablePureComponent {
const {
mediaIds,
isUploading,
uploadProgress
uploadProgress,
} = this.props
return (

View File

@@ -71,7 +71,7 @@ class Compose extends ImmutablePureComponent {
render () {
const { showSearch, isSearchPage, intl } = this.props;
let header = '';
const header = '';
return (
<div className='drawer' role='region' aria-label={intl.formatMessage(messages.compose)}>

View File

@@ -35,10 +35,11 @@ const mapStateToProps = (state, { replyToId }) => {
isUploading: !isMatch ? false : state.getIn(['compose', 'is_uploading']),
showSearch: !isMatch ? false : state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
anyMedia: !isMatch ? false : state.getIn(['compose', 'media_attachments']).size > 0,
isModalOpen: !isMatch ? false : state.get('modal').modalType === 'COMPOSE',
isModalOpen: !isMatch ? false : state.getIn(['modal', 'modalType']) === 'COMPOSE',
quoteOfId: !isMatch ? null : state.getIn(['compose', 'quote_of_id']),
scheduledAt: !isMatch ? null : state.getIn(['compose', 'scheduled_at']),
account: state.getIn(['accounts', me]),
hasPoll: !isMatch ? false : state.getIn(['compose', 'poll']),
}
}
@@ -84,7 +85,7 @@ const mapDispatchToProps = (dispatch) => ({
function mergeProps(stateProps, dispatchProps, ownProps) {
return Object.assign({}, ownProps, {
...stateProps,
...dispatchProps
...dispatchProps,
})
}

View File

@@ -1,8 +0,0 @@
import QuotedStatusPreview from '../components/quoted_status_preview';
const mapStateToProps = (state, { id }) => ({
status: state.getIn(['statuses', id]),
account: state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
});
export default connect(mapStateToProps)(QuotedStatusPreview);

View File

@@ -1,9 +1,9 @@
import { urlRegex } from './url_regex';
import { urlRegex } from './url_regex'
const urlPlaceholder = 'xxxxxxxxxxxxxxxxxxxxxxx';
const urlPlaceholder = 'xxxxxxxxxxxxxxxxxxxxxxx'
export function countableText(inputText) {
return inputText
.replace(urlRegex, urlPlaceholder)
.replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3');
};
}