[Glitch] Add editing for published statuses

Port 63002cde03 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
master
Eugen Rochko 2022-02-10 00:15:30 +01:00 committed by Claire
parent abd113167b
commit 5e67858fbc
11 changed files with 170 additions and 71 deletions

View File

@ -75,6 +75,8 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL';
export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION'; export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION';
export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS'; export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS';
export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
const messages = defineMessages({ const messages = defineMessages({
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' }, uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' }, uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
@ -88,6 +90,15 @@ export const ensureComposeIsVisible = (getState, routerHistory) => {
} }
}; };
export function setComposeToStatus(status, text, spoiler_text) {
return{
type: COMPOSE_SET_STATUS,
status,
text,
spoiler_text,
};
};
export function changeCompose(text) { export function changeCompose(text) {
return { return {
type: COMPOSE_CHANGE, type: COMPOSE_CHANGE,
@ -150,8 +161,9 @@ export function directCompose(account, routerHistory) {
export function submitCompose(routerHistory) { export function submitCompose(routerHistory) {
return function (dispatch, getState) { return function (dispatch, getState) {
let status = getState().getIn(['compose', 'text'], ''); let status = getState().getIn(['compose', 'text'], '');
let media = getState().getIn(['compose', 'media_attachments']); const media = getState().getIn(['compose', 'media_attachments']);
const statusId = getState().getIn(['compose', 'id'], null);
const spoilers = getState().getIn(['compose', 'spoiler']) || getState().getIn(['local_settings', 'always_show_spoilers_field']); const spoilers = getState().getIn(['compose', 'spoiler']) || getState().getIn(['local_settings', 'always_show_spoilers_field']);
let spoilerText = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : ''; let spoilerText = spoilers ? getState().getIn(['compose', 'spoiler_text'], '') : '';
@ -159,20 +171,25 @@ export function submitCompose(routerHistory) {
return; return;
} }
dispatch(submitComposeRequest());
if (getState().getIn(['compose', 'advanced_options', 'do_not_federate'])) { if (getState().getIn(['compose', 'advanced_options', 'do_not_federate'])) {
status = status + ' 👁️'; status = status + ' 👁️';
} }
api(getState).post('/api/v1/statuses', {
status, dispatch(submitComposeRequest());
content_type: getState().getIn(['compose', 'content_type']),
in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), api(getState).request({
media_ids: media.map(item => item.get('id')), url: statusId === null ? '/api/v1/statuses' : `/api/v1/statuses/${statusId}`,
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0), method: statusId === null ? 'post' : 'put',
spoiler_text: spoilerText, data: {
visibility: getState().getIn(['compose', 'privacy']), status,
poll: getState().getIn(['compose', 'poll'], null), content_type: getState().getIn(['compose', 'content_type']),
}, { in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
media_ids: media.map(item => item.get('id')),
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
spoiler_text: spoilerText,
visibility: getState().getIn(['compose', 'privacy']),
poll: getState().getIn(['compose', 'poll'], null),
},
headers: { headers: {
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
}, },
@ -202,14 +219,16 @@ export function submitCompose(routerHistory) {
} }
}; };
insertIfOnline('home'); if (statusId === null) {
insertIfOnline('home');
}
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') { if (statusId === null && response.data.in_reply_to_id === null && response.data.visibility === 'public') {
insertIfOnline('community'); insertIfOnline('community');
if (!response.data.local_only) { if (!response.data.local_only) {
insertIfOnline('public'); insertIfOnline('public');
} }
} else if (response.data.visibility === 'direct') { } else if (statusId === null && response.data.visibility === 'direct') {
insertIfOnline('direct'); insertIfOnline('direct');
} }
}).catch(function (error) { }).catch(function (error) {

View File

@ -2,7 +2,7 @@ import api from 'flavours/glitch/util/api';
import { deleteFromTimelines } from './timelines'; import { deleteFromTimelines } from './timelines';
import { importFetchedStatus, importFetchedStatuses } from './importer'; import { importFetchedStatus, importFetchedStatuses } from './importer';
import { ensureComposeIsVisible } from './compose'; import { ensureComposeIsVisible, setComposeToStatus } from './compose';
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST'; export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS'; export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
@ -26,6 +26,10 @@ export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
export const REDRAFT = 'REDRAFT'; export const REDRAFT = 'REDRAFT';
export const STATUS_FETCH_SOURCE_REQUEST = 'STATUS_FETCH_SOURCE_REQUEST';
export const STATUS_FETCH_SOURCE_SUCCESS = 'STATUS_FETCH_SOURCE_SUCCESS';
export const STATUS_FETCH_SOURCE_FAIL = 'STATUS_FETCH_SOURCE_FAIL';
export function fetchStatusRequest(id, skipLoading) { export function fetchStatusRequest(id, skipLoading) {
return { return {
type: STATUS_FETCH_REQUEST, type: STATUS_FETCH_REQUEST,
@ -81,6 +85,37 @@ export function redraft(status, raw_text, content_type) {
}; };
}; };
export const editStatus = (id, routerHistory) => (dispatch, getState) => {
let status = getState().getIn(['statuses', id]);
if (status.get('poll')) {
status = status.set('poll', getState().getIn(['polls', status.get('poll')]));
}
dispatch(fetchStatusSourceRequest());
api(getState).get(`/api/v1/statuses/${id}/source`).then(response => {
dispatch(fetchStatusSourceSuccess());
ensureComposeIsVisible(getState, routerHistory);
dispatch(setComposeToStatus(status, response.data.text, response.data.spoiler_text));
}).catch(error => {
dispatch(fetchStatusSourceFail(error));
});
};
export const fetchStatusSourceRequest = () => ({
type: STATUS_FETCH_SOURCE_REQUEST,
});
export const fetchStatusSourceSuccess = () => ({
type: STATUS_FETCH_SOURCE_SUCCESS,
});
export const fetchStatusSourceFail = error => ({
type: STATUS_FETCH_SOURCE_FAIL,
error,
});
export function deleteStatus(id, routerHistory, withRedraft = false) { export function deleteStatus(id, routerHistory, withRedraft = false) {
return (dispatch, getState) => { return (dispatch, getState) => {
let status = getState().getIn(['statuses', id]); let status = getState().getIn(['statuses', id]);

View File

@ -13,6 +13,7 @@ import classNames from 'classnames';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
@ -126,6 +127,10 @@ class StatusActionBar extends ImmutablePureComponent {
this.props.onDelete(this.props.status, this.context.router.history, true); this.props.onDelete(this.props.status, this.context.router.history, true);
} }
handleEditClick = () => {
this.props.onEdit(this.props.status, this.context.router.history);
}
handlePinClick = () => { handlePinClick = () => {
this.props.onPin(this.props.status); this.props.onPin(this.props.status);
} }
@ -225,6 +230,7 @@ class StatusActionBar extends ImmutablePureComponent {
} }
if (writtenByMe) { if (writtenByMe) {
menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
} else { } else {

View File

@ -17,7 +17,7 @@ import {
pin, pin,
unpin, unpin,
} from 'flavours/glitch/actions/interactions'; } from 'flavours/glitch/actions/interactions';
import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; import { muteStatus, unmuteStatus, deleteStatus, editStatus } from 'flavours/glitch/actions/statuses';
import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initMuteModal } from 'flavours/glitch/actions/mutes';
import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initBlockModal } from 'flavours/glitch/actions/blocks';
import { initReport } from 'flavours/glitch/actions/reports'; import { initReport } from 'flavours/glitch/actions/reports';
@ -169,6 +169,10 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
} }
}, },
onEdit (status, history) {
dispatch(editStatus(status.get('id'), history));
},
onDirect (account, router) { onDirect (account, router) {
dispatch(directCompose(account, router)); dispatch(directCompose(account, router));
}, },

View File

@ -47,6 +47,7 @@ class ComposeForm extends ImmutablePureComponent {
preselectDate: PropTypes.instanceOf(Date), preselectDate: PropTypes.instanceOf(Date),
isSubmitting: PropTypes.bool, isSubmitting: PropTypes.bool,
isChangingUpload: PropTypes.bool, isChangingUpload: PropTypes.bool,
isEditing: PropTypes.bool,
isUploading: PropTypes.bool, isUploading: PropTypes.bool,
onChange: PropTypes.func, onChange: PropTypes.func,
onSubmit: PropTypes.func, onSubmit: PropTypes.func,
@ -293,6 +294,7 @@ class ComposeForm extends ImmutablePureComponent {
spoilerText, spoilerText,
suggestions, suggestions,
spoilersAlwaysOn, spoilersAlwaysOn,
isEditing,
} = this.props; } = this.props;
const countText = this.getFulltextForCharacterCounting(); const countText = this.getFulltextForCharacterCounting();
@ -364,6 +366,7 @@ class ComposeForm extends ImmutablePureComponent {
<Publisher <Publisher
countText={countText} countText={countText}
disabled={!this.canSubmit()} disabled={!this.canSubmit()}
isEditing={isEditing}
onSecondarySubmit={handleSecondarySubmit} onSecondarySubmit={handleSecondarySubmit}
onSubmit={handleSubmit} onSubmit={handleSubmit}
privacy={privacy} privacy={privacy}

View File

@ -2,7 +2,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { length } from 'stringz'; import { length } from 'stringz';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
@ -23,6 +23,7 @@ const messages = defineMessages({
defaultMessage: '{publish}!', defaultMessage: '{publish}!',
id: 'compose_form.publish_loud', id: 'compose_form.publish_loud',
}, },
saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' },
}); });
export default @injectIntl export default @injectIntl
@ -36,6 +37,7 @@ class Publisher extends ImmutablePureComponent {
onSubmit: PropTypes.func, onSubmit: PropTypes.func,
privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']), privacy: PropTypes.oneOf(['direct', 'private', 'unlisted', 'public']),
sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']), sideArm: PropTypes.oneOf(['none', 'direct', 'private', 'unlisted', 'public']),
isEditing: PropTypes.bool,
}; };
handleSubmit = () => { handleSubmit = () => {
@ -43,7 +45,7 @@ class Publisher extends ImmutablePureComponent {
}; };
render () { render () {
const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm } = this.props; const { countText, disabled, intl, onSecondarySubmit, privacy, sideArm, isEditing } = this.props;
const diff = maxChars - length(countText || ''); const diff = maxChars - length(countText || '');
const computedClass = classNames('composer--publisher', { const computedClass = classNames('composer--publisher', {
@ -51,63 +53,37 @@ class Publisher extends ImmutablePureComponent {
over: diff < 0, over: diff < 0,
}); });
const privacyIcons = { direct: 'envelope', private: 'lock', public: 'globe', unlisted: 'unlock' };
let publishText;
if (isEditing) {
publishText = intl.formatMessage(messages.saveChanges);
} else if (privacy === 'private' || privacy === 'direct') {
const iconId = privacyIcons[privacy];
publishText = (
<span>
<Icon id={iconId} /> {intl.formatMessage(messages.publish)}
</span>
);
} else {
publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
}
return ( return (
<div className={computedClass}> <div className={computedClass}>
{sideArm && sideArm !== 'none' ? ( {sideArm && !isEditing && sideArm !== 'none' ? (
<Button <Button
className='side_arm' className='side_arm'
disabled={disabled} disabled={disabled}
onClick={onSecondarySubmit} onClick={onSecondarySubmit}
style={{ padding: null }} style={{ padding: null }}
text={ text={<Icon id={privacyIcons[sideArm]} />}
<span>
<Icon
id={{
public: 'globe',
unlisted: 'unlock',
private: 'lock',
direct: 'envelope',
}[sideArm]}
/>
</span>
}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArm}.short` })}`} title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${sideArm}.short` })}`}
/> />
) : null} ) : null}
<Button <Button
className='primary' className='primary'
text={function () { text={publishText}
switch (true) {
case !!sideArm && sideArm !== 'none':
case privacy === 'direct':
case privacy === 'private':
return (
<span>
<Icon
id={{
direct: 'envelope',
private: 'lock',
public: 'globe',
unlisted: 'unlock',
}[privacy]}
/>
{' '}
<FormattedMessage {...messages.publish} />
</span>
);
case privacy === 'public':
return (
<span>
<FormattedMessage
{...messages.publishLoud}
values={{ publish: <FormattedMessage {...messages.publish} /> }}
/>
</span>
);
default:
return <span><FormattedMessage {...messages.publish} /></span>;
}
}()}
title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${privacy}.short` })}`} title={`${intl.formatMessage(messages.publish)}: ${intl.formatMessage({ id: `privacy.${privacy}.short` })}`}
onClick={this.handleSubmit} onClick={this.handleSubmit}
disabled={disabled} disabled={disabled}

View File

@ -51,6 +51,7 @@ function mapStateToProps (state) {
focusDate: state.getIn(['compose', 'focusDate']), focusDate: state.getIn(['compose', 'focusDate']),
caretPosition: state.getIn(['compose', 'caretPosition']), caretPosition: state.getIn(['compose', 'caretPosition']),
isSubmitting: state.getIn(['compose', 'is_submitting']), isSubmitting: state.getIn(['compose', 'is_submitting']),
isEditing: state.getIn(['compose', 'id']) !== null,
isChangingUpload: state.getIn(['compose', 'is_changing_upload']), isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
isUploading: state.getIn(['compose', 'is_uploading']), isUploading: state.getIn(['compose', 'is_uploading']),
layout: state.getIn(['local_settings', 'layout']), layout: state.getIn(['local_settings', 'layout']),

View File

@ -1,14 +1,24 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { cancelReplyCompose } from 'flavours/glitch/actions/compose'; import { cancelReplyCompose } from 'flavours/glitch/actions/compose';
import { makeGetStatus } from 'flavours/glitch/selectors';
import ReplyIndicator from '../components/reply_indicator'; import ReplyIndicator from '../components/reply_indicator';
function makeMapStateToProps (state) { const makeMapStateToProps = () => {
const inReplyTo = state.getIn(['compose', 'in_reply_to']); const mapStateToProps = state => {
let statusId = state.getIn(['compose', 'id'], null);
let editing = true;
return { if (statusId === null) {
status: inReplyTo ? state.getIn(['statuses', inReplyTo]) : null, statusId = state.getIn(['compose', 'in_reply_to']);
editing = false;
}
return {
status: state.getIn(['statuses', statusId]),
editing,
};
}; };
return mapStateToProps;
}; };
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View File

@ -11,6 +11,7 @@ import classNames from 'classnames';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' }, redraft: { id: 'status.redraft', defaultMessage: 'Delete & re-draft' },
edit: { id: 'status.edit', defaultMessage: 'Edit' },
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
reply: { id: 'status.reply', defaultMessage: 'Reply' }, reply: { id: 'status.reply', defaultMessage: 'Reply' },
@ -52,6 +53,7 @@ class ActionBar extends React.PureComponent {
onMuteConversation: PropTypes.func, onMuteConversation: PropTypes.func,
onBlock: PropTypes.func, onBlock: PropTypes.func,
onDelete: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired,
onEdit: PropTypes.func.isRequired,
onDirect: PropTypes.func.isRequired, onDirect: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired,
onReport: PropTypes.func, onReport: PropTypes.func,
@ -84,6 +86,10 @@ class ActionBar extends React.PureComponent {
this.props.onDelete(this.props.status, this.context.router.history, true); this.props.onDelete(this.props.status, this.context.router.history, true);
} }
handleEditClick = () => {
this.props.onEdit(this.props.status, this.context.router.history);
}
handleDirectClick = () => { handleDirectClick = () => {
this.props.onDirect(this.props.status.get('account'), this.context.router.history); this.props.onDirect(this.props.status.get('account'), this.context.router.history);
} }
@ -166,6 +172,7 @@ class ActionBar extends React.PureComponent {
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick }); menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
menu.push(null); menu.push(null);
menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick }); menu.push({ text: intl.formatMessage(messages.redraft), action: this.handleRedraftClick });
} else { } else {

View File

@ -26,7 +26,7 @@ import {
directCompose, directCompose,
} from 'flavours/glitch/actions/compose'; } from 'flavours/glitch/actions/compose';
import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; import { muteStatus, unmuteStatus, deleteStatus, editStatus } from 'flavours/glitch/actions/statuses';
import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initMuteModal } from 'flavours/glitch/actions/mutes';
import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initBlockModal } from 'flavours/glitch/actions/blocks';
import { initReport } from 'flavours/glitch/actions/reports'; import { initReport } from 'flavours/glitch/actions/reports';
@ -307,6 +307,10 @@ class Status extends ImmutablePureComponent {
} }
} }
handleEditClick = (status, history) => {
this.props.dispatch(editStatus(status.get('id'), history));
}
handleDirectClick = (account, router) => { handleDirectClick = (account, router) => {
this.props.dispatch(directCompose(account, router)); this.props.dispatch(directCompose(account, router));
} }
@ -585,6 +589,7 @@ class Status extends ImmutablePureComponent {
onReblog={this.handleReblogClick} onReblog={this.handleReblogClick}
onBookmark={this.handleBookmarkClick} onBookmark={this.handleBookmarkClick}
onDelete={this.handleDeleteClick} onDelete={this.handleDeleteClick}
onEdit={this.handleEditClick}
onDirect={this.handleDirectClick} onDirect={this.handleDirectClick}
onMention={this.handleMentionClick} onMention={this.handleMentionClick}
onMute={this.handleMuteClick} onMute={this.handleMuteClick}

View File

@ -46,6 +46,7 @@ import {
INIT_MEDIA_EDIT_MODAL, INIT_MEDIA_EDIT_MODAL,
COMPOSE_CHANGE_MEDIA_DESCRIPTION, COMPOSE_CHANGE_MEDIA_DESCRIPTION,
COMPOSE_CHANGE_MEDIA_FOCUS, COMPOSE_CHANGE_MEDIA_FOCUS,
COMPOSE_SET_STATUS,
} from 'flavours/glitch/actions/compose'; } from 'flavours/glitch/actions/compose';
import { TIMELINE_DELETE } from 'flavours/glitch/actions/timelines'; import { TIMELINE_DELETE } from 'flavours/glitch/actions/timelines';
import { STORE_HYDRATE } from 'flavours/glitch/actions/store'; import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
@ -75,6 +76,7 @@ const initialState = ImmutableMap({
spoiler: false, spoiler: false,
spoiler_text: '', spoiler_text: '',
privacy: null, privacy: null,
id: null,
content_type: defaultContentType || 'text/plain', content_type: defaultContentType || 'text/plain',
text: '', text: '',
focusDate: null, focusDate: null,
@ -160,6 +162,7 @@ function apiStatusToTextHashtags (state, status) {
function clearAll(state) { function clearAll(state) {
return state.withMutations(map => { return state.withMutations(map => {
map.set('id', null);
map.set('text', ''); map.set('text', '');
if (defaultContentType) map.set('content_type', defaultContentType); if (defaultContentType) map.set('content_type', defaultContentType);
map.set('spoiler', false); map.set('spoiler', false);
@ -400,6 +403,7 @@ export default function compose(state = initialState, action) {
.set('elefriend', (state.get('elefriend') + 1) % totalElefriends); .set('elefriend', (state.get('elefriend') + 1) % totalElefriends);
case COMPOSE_REPLY: case COMPOSE_REPLY:
return state.withMutations(map => { return state.withMutations(map => {
map.set('id', null);
map.set('in_reply_to', action.status.get('id')); map.set('in_reply_to', action.status.get('id'));
map.set('text', statusToTextMentions(state, action.status)); map.set('text', statusToTextMentions(state, action.status));
map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy'))); map.set('privacy', privacyPreference(action.status.get('visibility'), state.get('default_privacy')));
@ -434,6 +438,7 @@ export default function compose(state = initialState, action) {
map.set('spoiler', false); map.set('spoiler', false);
map.set('spoiler_text', ''); map.set('spoiler_text', '');
map.set('privacy', state.get('default_privacy')); map.set('privacy', state.get('default_privacy'));
map.set('id', null);
map.set('poll', null); map.set('poll', null);
map.update( map.update(
'advanced_options', 'advanced_options',
@ -565,6 +570,34 @@ export default function compose(state = initialState, action) {
map.set('spoiler_text', ''); map.set('spoiler_text', '');
} }
if (action.status.get('poll')) {
map.set('poll', ImmutableMap({
options: action.status.getIn(['poll', 'options']).map(x => x.get('title')),
multiple: action.status.getIn(['poll', 'multiple']),
expires_in: expiresInFromExpiresAt(action.status.getIn(['poll', 'expires_at'])),
}));
}
});
case COMPOSE_SET_STATUS:
return state.withMutations(map => {
map.set('id', action.status.get('id'));
map.set('text', action.text);
map.set('in_reply_to', action.status.get('in_reply_to_id'));
map.set('privacy', action.status.get('visibility'));
map.set('media_attachments', action.status.get('media_attachments'));
map.set('focusDate', new Date());
map.set('caretPosition', null);
map.set('idempotencyKey', uuid());
map.set('sensitive', action.status.get('sensitive'));
if (action.spoiler_text.length > 0) {
map.set('spoiler', true);
map.set('spoiler_text', action.spoiler_text);
} else {
map.set('spoiler', false);
map.set('spoiler_text', '');
}
if (action.status.get('poll')) { if (action.status.get('poll')) {
map.set('poll', ImmutableMap({ map.set('poll', ImmutableMap({
options: action.status.getIn(['poll', 'options']).map(x => x.get('title')), options: action.status.getIn(['poll', 'options']).map(x => x.get('title')),