Threaded mode~
This commit is contained in:
@@ -7,6 +7,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import {
|
||||
cancelReplyCompose,
|
||||
changeCompose,
|
||||
changeComposeAdvancedOption,
|
||||
changeComposeSensitivity,
|
||||
changeComposeSpoilerText,
|
||||
changeComposeSpoilerness,
|
||||
@@ -18,7 +19,6 @@ import {
|
||||
mountCompose,
|
||||
selectComposeSuggestion,
|
||||
submitCompose,
|
||||
toggleComposeAdvancedOption,
|
||||
undoUploadCompose,
|
||||
unmountCompose,
|
||||
uploadCompose,
|
||||
@@ -49,8 +49,8 @@ function mapStateToProps (state) {
|
||||
const inReplyTo = state.getIn(['compose', 'in_reply_to']);
|
||||
return {
|
||||
acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']).toArray().join(','),
|
||||
advancedOptions: state.getIn(['compose', 'advanced_options']),
|
||||
amUnlocked: !state.getIn(['accounts', me, 'locked']),
|
||||
doNotFederate: state.getIn(['compose', 'advanced_options', 'do_not_federate']),
|
||||
focusDate: state.getIn(['compose', 'focusDate']),
|
||||
isSubmitting: state.getIn(['compose', 'is_submitting']),
|
||||
isUploading: state.getIn(['compose', 'is_uploading']),
|
||||
@@ -76,6 +76,7 @@ function mapStateToProps (state) {
|
||||
// Dispatch mapping.
|
||||
const mapDispatchToProps = {
|
||||
onCancelReply: cancelReplyCompose,
|
||||
onChangeAdvancedOption: changeComposeAdvancedOption,
|
||||
onChangeDescription: changeUploadCompose,
|
||||
onChangeSensitivity: changeComposeSensitivity,
|
||||
onChangeSpoilerText: changeComposeSpoilerText,
|
||||
@@ -91,7 +92,6 @@ const mapDispatchToProps = {
|
||||
onOpenDoodleModal: openModal.bind(null, 'DOODLE', { noEsc: true }),
|
||||
onSelectSuggestion: selectComposeSuggestion,
|
||||
onSubmit: submitCompose,
|
||||
onToggleAdvancedOption: toggleComposeAdvancedOption,
|
||||
onUndoUpload: undoUploadCompose,
|
||||
onUnmount: unmountCompose,
|
||||
onUpload: uploadCompose,
|
||||
@@ -267,14 +267,15 @@ class Composer extends React.Component {
|
||||
} = this.handlers;
|
||||
const {
|
||||
acceptContentTypes,
|
||||
advancedOptions,
|
||||
amUnlocked,
|
||||
doNotFederate,
|
||||
intl,
|
||||
isSubmitting,
|
||||
isUploading,
|
||||
layout,
|
||||
media,
|
||||
onCancelReply,
|
||||
onChangeAdvancedOption,
|
||||
onChangeDescription,
|
||||
onChangeSensitivity,
|
||||
onChangeSpoilerness,
|
||||
@@ -285,7 +286,6 @@ class Composer extends React.Component {
|
||||
onFetchSuggestions,
|
||||
onOpenActionsModal,
|
||||
onOpenDoodleModal,
|
||||
onToggleAdvancedOption,
|
||||
onUndoUpload,
|
||||
onUpload,
|
||||
privacy,
|
||||
@@ -321,6 +321,7 @@ class Composer extends React.Component {
|
||||
/>
|
||||
) : null}
|
||||
<ComposerTextarea
|
||||
advancedOptions={advancedOptions}
|
||||
autoFocus={!showSearch && !isMobile(window.innerWidth, layout)}
|
||||
disabled={isSubmitting}
|
||||
intl={intl}
|
||||
@@ -347,19 +348,19 @@ class Composer extends React.Component {
|
||||
) : null}
|
||||
<ComposerOptions
|
||||
acceptContentTypes={acceptContentTypes}
|
||||
advancedOptions={advancedOptions}
|
||||
disabled={isSubmitting}
|
||||
doNotFederate={doNotFederate}
|
||||
full={media.size >= 4 || media.some(
|
||||
item => item.get('type') === 'video'
|
||||
)}
|
||||
hasMedia={!!media.size}
|
||||
intl={intl}
|
||||
onChangeAdvancedOption={onChangeAdvancedOption}
|
||||
onChangeSensitivity={onChangeSensitivity}
|
||||
onChangeVisibility={onChangeVisibility}
|
||||
onDoodleOpen={onOpenDoodleModal}
|
||||
onModalClose={onCloseModal}
|
||||
onModalOpen={onOpenActionsModal}
|
||||
onToggleAdvancedOption={onToggleAdvancedOption}
|
||||
onToggleSpoiler={onChangeSpoilerness}
|
||||
onUpload={onUpload}
|
||||
privacy={privacy}
|
||||
@@ -368,7 +369,7 @@ class Composer extends React.Component {
|
||||
spoiler={spoiler}
|
||||
/>
|
||||
<ComposerPublisher
|
||||
countText={`${spoilerText}${countableText(text)}${doNotFederate ? ' 👁️' : ''}`}
|
||||
countText={`${spoilerText}${countableText(text)}${advancedOptions.get('do_not_federate') ? ' 👁️' : ''}`}
|
||||
disabled={isSubmitting || isUploading || !!text.length && !text.trim().length}
|
||||
intl={intl}
|
||||
onSecondarySubmit={handleSecondarySubmit}
|
||||
@@ -388,8 +389,8 @@ Composer.propTypes = {
|
||||
|
||||
// State props.
|
||||
acceptContentTypes: PropTypes.string,
|
||||
advancedOptions: ImmutablePropTypes.map,
|
||||
amUnlocked: PropTypes.bool,
|
||||
doNotFederate: PropTypes.bool,
|
||||
focusDate: PropTypes.instanceOf(Date),
|
||||
isSubmitting: PropTypes.bool,
|
||||
isUploading: PropTypes.bool,
|
||||
@@ -412,6 +413,7 @@ Composer.propTypes = {
|
||||
|
||||
// Dispatch props.
|
||||
onCancelReply: PropTypes.func,
|
||||
onChangeAdvancedOption: PropTypes.func,
|
||||
onChangeDescription: PropTypes.func,
|
||||
onChangeSensitivity: PropTypes.func,
|
||||
onChangeSpoilerText: PropTypes.func,
|
||||
@@ -427,7 +429,6 @@ Composer.propTypes = {
|
||||
onOpenDoodleModal: PropTypes.func,
|
||||
onSelectSuggestion: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
onToggleAdvancedOption: PropTypes.func,
|
||||
onUndoUpload: PropTypes.func,
|
||||
onUnmount: PropTypes.func,
|
||||
onUpload: PropTypes.func,
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// Package imports.
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import {
|
||||
FormattedMessage,
|
||||
defineMessages,
|
||||
@@ -47,11 +48,11 @@ const messages = defineMessages({
|
||||
},
|
||||
local_only_long: {
|
||||
defaultMessage: 'Do not post to other instances',
|
||||
id: 'advanced-options.local-only.long',
|
||||
id: 'advanced_options.local-only.long',
|
||||
},
|
||||
local_only_short: {
|
||||
defaultMessage: 'Local-only',
|
||||
id: 'advanced-options.local-only.short',
|
||||
id: 'advanced_options.local-only.short',
|
||||
},
|
||||
private_long: {
|
||||
defaultMessage: 'Post to followers only',
|
||||
@@ -77,6 +78,14 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Hide text behind warning',
|
||||
id: 'compose_form.spoiler',
|
||||
},
|
||||
threaded_mode_long: {
|
||||
defaultMessage: 'Automatically opens a reply on posting',
|
||||
id: 'advanced_options.threaded_mode.long',
|
||||
},
|
||||
threaded_mode_short: {
|
||||
defaultMessage: 'Threaded mode',
|
||||
id: 'advanced_options.threaded_mode.short',
|
||||
},
|
||||
unlisted_long: {
|
||||
defaultMessage: 'Do not show in public timelines',
|
||||
id: 'privacy.unlisted.long',
|
||||
@@ -149,16 +158,16 @@ export default class ComposerOptions extends React.PureComponent {
|
||||
} = this.handlers;
|
||||
const {
|
||||
acceptContentTypes,
|
||||
advancedOptions,
|
||||
disabled,
|
||||
doNotFederate,
|
||||
full,
|
||||
hasMedia,
|
||||
intl,
|
||||
onChangeAdvancedOption,
|
||||
onChangeSensitivity,
|
||||
onChangeVisibility,
|
||||
onModalClose,
|
||||
onModalOpen,
|
||||
onToggleAdvancedOption,
|
||||
onToggleSpoiler,
|
||||
privacy,
|
||||
resetFileKey,
|
||||
@@ -283,23 +292,31 @@ export default class ComposerOptions extends React.PureComponent {
|
||||
onClick={onToggleSpoiler}
|
||||
title={intl.formatMessage(messages.spoiler)}
|
||||
/>
|
||||
<Dropdown
|
||||
active={doNotFederate}
|
||||
disabled={disabled}
|
||||
icon='home'
|
||||
items={[
|
||||
{
|
||||
meta: <FormattedMessage {...messages.local_only_long} />,
|
||||
name: 'do_not_federate',
|
||||
on: doNotFederate,
|
||||
text: <FormattedMessage {...messages.local_only_short} />,
|
||||
},
|
||||
]}
|
||||
onChange={onToggleAdvancedOption}
|
||||
onModalClose={onModalClose}
|
||||
onModalOpen={onModalOpen}
|
||||
title={intl.formatMessage(messages.advanced_options_icon_title)}
|
||||
/>
|
||||
{advancedOptions ? (
|
||||
<Dropdown
|
||||
active={advancedOptions.some(value => !!value)}
|
||||
disabled={disabled}
|
||||
icon='ellipsis-h'
|
||||
items={[
|
||||
{
|
||||
meta: <FormattedMessage {...messages.local_only_long} />,
|
||||
name: 'do_not_federate',
|
||||
on: advancedOptions.get('do_not_federate'),
|
||||
text: <FormattedMessage {...messages.local_only_short} />,
|
||||
},
|
||||
{
|
||||
meta: <FormattedMessage {...messages.threaded_mode_long} />,
|
||||
name: 'threaded_mode',
|
||||
on: advancedOptions.get('threaded_mode'),
|
||||
text: <FormattedMessage {...messages.threaded_mode_short} />,
|
||||
},
|
||||
]}
|
||||
onChange={onChangeAdvancedOption}
|
||||
onModalClose={onModalClose}
|
||||
onModalOpen={onModalOpen}
|
||||
title={intl.formatMessage(messages.advanced_options_icon_title)}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -309,17 +326,17 @@ export default class ComposerOptions extends React.PureComponent {
|
||||
// Props.
|
||||
ComposerOptions.propTypes = {
|
||||
acceptContentTypes: PropTypes.string,
|
||||
advancedOptions: ImmutablePropTypes.map,
|
||||
disabled: PropTypes.bool,
|
||||
doNotFederate: PropTypes.bool,
|
||||
full: PropTypes.bool,
|
||||
hasMedia: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onChangeAdvancedOption: PropTypes.func,
|
||||
onChangeSensitivity: PropTypes.func,
|
||||
onChangeVisibility: PropTypes.func,
|
||||
onDoodleOpen: PropTypes.func,
|
||||
onModalClose: PropTypes.func,
|
||||
onModalOpen: PropTypes.func,
|
||||
onToggleAdvancedOption: PropTypes.func,
|
||||
onToggleSpoiler: PropTypes.func,
|
||||
onUpload: PropTypes.func,
|
||||
privacy: PropTypes.string,
|
||||
|
@@ -10,6 +10,7 @@ import Textarea from 'react-textarea-autosize';
|
||||
|
||||
// Components.
|
||||
import EmojiPicker from 'flavours/glitch/features/emoji_picker';
|
||||
import ComposerTextareaIcons from './icons';
|
||||
import ComposerTextareaSuggestions from './suggestions';
|
||||
|
||||
// Utils.
|
||||
@@ -232,6 +233,7 @@ export default class ComposerTextarea extends React.Component {
|
||||
handleRefTextarea,
|
||||
} = this.handlers;
|
||||
const {
|
||||
advancedOptions,
|
||||
autoFocus,
|
||||
disabled,
|
||||
intl,
|
||||
@@ -249,6 +251,10 @@ export default class ComposerTextarea extends React.Component {
|
||||
<div className='composer--textarea'>
|
||||
<label>
|
||||
<span {...hiddenComponent}><FormattedMessage {...messages.placeholder} /></span>
|
||||
<ComposerTextareaIcons
|
||||
advancedOptions={advancedOptions}
|
||||
intl={intl}
|
||||
/>
|
||||
<Textarea
|
||||
aria-autocomplete='list'
|
||||
autoFocus={autoFocus}
|
||||
@@ -280,6 +286,7 @@ export default class ComposerTextarea extends React.Component {
|
||||
|
||||
// Props.
|
||||
ComposerTextarea.propTypes = {
|
||||
advancedOptions: ImmutablePropTypes.map,
|
||||
autoFocus: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
|
Reference in New Issue
Block a user