1 import api
from '../api';
2 import { emojiIndex
} from 'emoji-mart';
7 refreshCommunityTimeline
,
11 export const COMPOSE_CHANGE
= 'COMPOSE_CHANGE';
12 export const COMPOSE_SUBMIT_REQUEST
= 'COMPOSE_SUBMIT_REQUEST';
13 export const COMPOSE_SUBMIT_SUCCESS
= 'COMPOSE_SUBMIT_SUCCESS';
14 export const COMPOSE_SUBMIT_FAIL
= 'COMPOSE_SUBMIT_FAIL';
15 export const COMPOSE_REPLY
= 'COMPOSE_REPLY';
16 export const COMPOSE_REPLY_CANCEL
= 'COMPOSE_REPLY_CANCEL';
17 export const COMPOSE_MENTION
= 'COMPOSE_MENTION';
18 export const COMPOSE_UPLOAD_REQUEST
= 'COMPOSE_UPLOAD_REQUEST';
19 export const COMPOSE_UPLOAD_SUCCESS
= 'COMPOSE_UPLOAD_SUCCESS';
20 export const COMPOSE_UPLOAD_FAIL
= 'COMPOSE_UPLOAD_FAIL';
21 export const COMPOSE_UPLOAD_PROGRESS
= 'COMPOSE_UPLOAD_PROGRESS';
22 export const COMPOSE_UPLOAD_UNDO
= 'COMPOSE_UPLOAD_UNDO';
24 export const COMPOSE_SUGGESTIONS_CLEAR
= 'COMPOSE_SUGGESTIONS_CLEAR';
25 export const COMPOSE_SUGGESTIONS_READY
= 'COMPOSE_SUGGESTIONS_READY';
26 export const COMPOSE_SUGGESTION_SELECT
= 'COMPOSE_SUGGESTION_SELECT';
28 export const COMPOSE_MOUNT
= 'COMPOSE_MOUNT';
29 export const COMPOSE_UNMOUNT
= 'COMPOSE_UNMOUNT';
31 export const COMPOSE_SENSITIVITY_CHANGE
= 'COMPOSE_SENSITIVITY_CHANGE';
32 export const COMPOSE_SPOILERNESS_CHANGE
= 'COMPOSE_SPOILERNESS_CHANGE';
33 export const COMPOSE_SPOILER_TEXT_CHANGE
= 'COMPOSE_SPOILER_TEXT_CHANGE';
34 export const COMPOSE_VISIBILITY_CHANGE
= 'COMPOSE_VISIBILITY_CHANGE';
35 export const COMPOSE_LISTABILITY_CHANGE
= 'COMPOSE_LISTABILITY_CHANGE';
36 export const COMPOSE_COMPOSING_CHANGE
= 'COMPOSE_COMPOSING_CHANGE';
38 export const COMPOSE_EMOJI_INSERT
= 'COMPOSE_EMOJI_INSERT';
40 export function changeCompose(text
) {
47 export function replyCompose(status
, router
) {
48 return (dispatch
, getState
) => {
54 if (!getState().getIn(['compose', 'mounted'])) {
55 router
.push('/statuses/new');
60 export function cancelReplyCompose() {
62 type: COMPOSE_REPLY_CANCEL
,
66 export function mentionCompose(account
, router
) {
67 return (dispatch
, getState
) => {
69 type: COMPOSE_MENTION
,
73 if (!getState().getIn(['compose', 'mounted'])) {
74 router
.push('/statuses/new');
79 export function submitCompose() {
80 return function (dispatch
, getState
) {
81 const status
= getState().getIn(['compose', 'text'], '');
83 if (!status
|| !status
.length
) {
87 dispatch(submitComposeRequest());
89 api(getState
).post('/api/v1/statuses', {
91 in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
92 media_ids: getState().getIn(['compose', 'media_attachments']).map(item
=> item
.get('id')),
93 sensitive: getState().getIn(['compose', 'sensitive']),
94 spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
95 visibility: getState().getIn(['compose', 'privacy']),
98 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
100 }).then(function (response
) {
101 dispatch(submitComposeSuccess({ ...response
.data
}));
103 // To make the app more responsive, immediately get the status into the columns
105 const insertOrRefresh
= (timelineId
, refreshAction
) => {
106 if (getState().getIn(['timelines', timelineId
, 'online'])) {
107 dispatch(updateTimeline(timelineId
, { ...response
.data
}));
108 } else if (getState().getIn(['timelines', timelineId
, 'loaded'])) {
109 dispatch(refreshAction());
113 insertOrRefresh('home', refreshHomeTimeline
);
115 if (response
.data
.in_reply_to_id
=== null && response
.data
.visibility
=== 'public') {
116 insertOrRefresh('community', refreshCommunityTimeline
);
117 insertOrRefresh('public', refreshPublicTimeline
);
119 }).catch(function (error
) {
120 dispatch(submitComposeFail(error
));
125 export function submitComposeRequest() {
127 type: COMPOSE_SUBMIT_REQUEST
,
131 export function submitComposeSuccess(status
) {
133 type: COMPOSE_SUBMIT_SUCCESS
,
138 export function submitComposeFail(error
) {
140 type: COMPOSE_SUBMIT_FAIL
,
145 export function uploadCompose(files
) {
146 return function (dispatch
, getState
) {
147 if (getState().getIn(['compose', 'media_attachments']).size
> 3) {
151 dispatch(uploadComposeRequest());
153 let data
= new FormData();
154 data
.append('file', files
[0]);
156 api(getState
).post('/api/v1/media', data
, {
157 onUploadProgress: function (e
) {
158 dispatch(uploadComposeProgress(e
.loaded
, e
.total
));
160 }).then(function (response
) {
161 dispatch(uploadComposeSuccess(response
.data
));
162 }).catch(function (error
) {
163 dispatch(uploadComposeFail(error
));
168 export function uploadComposeRequest() {
170 type: COMPOSE_UPLOAD_REQUEST
,
175 export function uploadComposeProgress(loaded
, total
) {
177 type: COMPOSE_UPLOAD_PROGRESS
,
183 export function uploadComposeSuccess(media
) {
185 type: COMPOSE_UPLOAD_SUCCESS
,
191 export function uploadComposeFail(error
) {
193 type: COMPOSE_UPLOAD_FAIL
,
199 export function undoUploadCompose(media_id
) {
201 type: COMPOSE_UPLOAD_UNDO
,
206 export function clearComposeSuggestions() {
208 type: COMPOSE_SUGGESTIONS_CLEAR
,
212 export function fetchComposeSuggestions(token
) {
213 return (dispatch
, getState
) => {
214 if (token
[0] === ':') {
215 const results
= emojiIndex
.search(token
.replace(':', ''), { maxResults: 3 });
216 dispatch(readyComposeSuggestionsEmojis(token
, results
));
220 api(getState
).get('/api/v1/accounts/search', {
226 }).then(response
=> {
227 dispatch(readyComposeSuggestionsAccounts(token
, response
.data
));
232 export function readyComposeSuggestionsEmojis(token
, emojis
) {
234 type: COMPOSE_SUGGESTIONS_READY
,
240 export function readyComposeSuggestionsAccounts(token
, accounts
) {
242 type: COMPOSE_SUGGESTIONS_READY
,
248 export function selectComposeSuggestion(position
, token
, suggestion
) {
249 return (dispatch
, getState
) => {
250 let completion
, startPosition
;
252 if (typeof suggestion
=== 'object' && suggestion
.id
) {
253 completion
= suggestion
.native || suggestion
.colons
;
254 startPosition
= position
- 1;
256 completion
= getState().getIn(['accounts', suggestion
, 'acct']);
257 startPosition
= position
;
261 type: COMPOSE_SUGGESTION_SELECT
,
262 position: startPosition
,
269 export function mountCompose() {
275 export function unmountCompose() {
277 type: COMPOSE_UNMOUNT
,
281 export function changeComposeSensitivity() {
283 type: COMPOSE_SENSITIVITY_CHANGE
,
287 export function changeComposeSpoilerness() {
289 type: COMPOSE_SPOILERNESS_CHANGE
,
293 export function changeComposeSpoilerText(text
) {
295 type: COMPOSE_SPOILER_TEXT_CHANGE
,
300 export function changeComposeVisibility(value
) {
302 type: COMPOSE_VISIBILITY_CHANGE
,
307 export function insertEmojiCompose(position
, emoji
) {
309 type: COMPOSE_EMOJI_INSERT
,
315 export function changeComposing(value
) {
317 type: COMPOSE_COMPOSING_CHANGE
,