]> cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/actions/compose.js
5f265a750116a996600dae5b9ced94cdb8b2e3b1
[mastodon.git] / app / javascript / mastodon / actions / compose.js
1 import api from '../api';
2
3 import {
4 updateTimeline,
5 refreshHomeTimeline,
6 refreshCommunityTimeline,
7 refreshPublicTimeline,
8 } from './timelines';
9
10 export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
11 export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
12 export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
13 export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
14 export const COMPOSE_REPLY = 'COMPOSE_REPLY';
15 export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL';
16 export const COMPOSE_MENTION = 'COMPOSE_MENTION';
17 export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
18 export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS';
19 export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL';
20 export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS';
21 export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO';
22
23 export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
24 export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
25 export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
26
27 export const COMPOSE_MOUNT = 'COMPOSE_MOUNT';
28 export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
29
30 export const COMPOSE_ADVANCED_OPTIONS_CHANGE = 'COMPOSE_ADVANCED_OPTIONS_CHANGE';
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';
37
38 export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
39
40 export function changeCompose(text) {
41 return {
42 type: COMPOSE_CHANGE,
43 text: text,
44 };
45 };
46
47 export function replyCompose(status, router) {
48 return (dispatch, getState) => {
49 dispatch({
50 type: COMPOSE_REPLY,
51 status: status,
52 });
53
54 if (!getState().getIn(['compose', 'mounted'])) {
55 router.push('/statuses/new');
56 }
57 };
58 };
59
60 export function cancelReplyCompose() {
61 return {
62 type: COMPOSE_REPLY_CANCEL,
63 };
64 };
65
66 export function mentionCompose(account, router) {
67 return (dispatch, getState) => {
68 dispatch({
69 type: COMPOSE_MENTION,
70 account: account,
71 });
72
73 if (!getState().getIn(['compose', 'mounted'])) {
74 router.push('/statuses/new');
75 }
76 };
77 };
78
79 export function submitCompose() {
80 return function (dispatch, getState) {
81 let status = getState().getIn(['compose', 'text'], '');
82
83 if (!status || !status.length) {
84 return;
85 }
86
87 dispatch(submitComposeRequest());
88 if (getState().getIn(['compose', 'advanced_options', 'do_not_federate'])) {
89 status = status + ' 👁️';
90 }
91 api(getState).post('/api/v1/statuses', {
92 status,
93 in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
94 media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')),
95 sensitive: getState().getIn(['compose', 'sensitive']),
96 spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
97 visibility: getState().getIn(['compose', 'privacy']),
98 }, {
99 headers: {
100 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
101 },
102 }).then(function (response) {
103 dispatch(submitComposeSuccess({ ...response.data }));
104
105 // To make the app more responsive, immediately get the status into the columns
106
107 const insertOrRefresh = (timelineId, refreshAction) => {
108 if (getState().getIn(['timelines', timelineId, 'online'])) {
109 dispatch(updateTimeline(timelineId, { ...response.data }));
110 } else if (getState().getIn(['timelines', timelineId, 'loaded'])) {
111 dispatch(refreshAction());
112 }
113 };
114
115 insertOrRefresh('home', refreshHomeTimeline);
116
117 if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
118 insertOrRefresh('community', refreshCommunityTimeline);
119 insertOrRefresh('public', refreshPublicTimeline);
120 }
121 }).catch(function (error) {
122 dispatch(submitComposeFail(error));
123 });
124 };
125 };
126
127 export function submitComposeRequest() {
128 return {
129 type: COMPOSE_SUBMIT_REQUEST,
130 };
131 };
132
133 export function submitComposeSuccess(status) {
134 return {
135 type: COMPOSE_SUBMIT_SUCCESS,
136 status: status,
137 };
138 };
139
140 export function submitComposeFail(error) {
141 return {
142 type: COMPOSE_SUBMIT_FAIL,
143 error: error,
144 };
145 };
146
147 export function uploadCompose(files) {
148 return function (dispatch, getState) {
149 if (getState().getIn(['compose', 'media_attachments']).size > 3) {
150 return;
151 }
152
153 dispatch(uploadComposeRequest());
154
155 let data = new FormData();
156 data.append('file', files[0]);
157
158 api(getState).post('/api/v1/media', data, {
159 onUploadProgress: function (e) {
160 dispatch(uploadComposeProgress(e.loaded, e.total));
161 },
162 }).then(function (response) {
163 dispatch(uploadComposeSuccess(response.data));
164 }).catch(function (error) {
165 dispatch(uploadComposeFail(error));
166 });
167 };
168 };
169
170 export function uploadComposeRequest() {
171 return {
172 type: COMPOSE_UPLOAD_REQUEST,
173 skipLoading: true,
174 };
175 };
176
177 export function uploadComposeProgress(loaded, total) {
178 return {
179 type: COMPOSE_UPLOAD_PROGRESS,
180 loaded: loaded,
181 total: total,
182 };
183 };
184
185 export function uploadComposeSuccess(media) {
186 return {
187 type: COMPOSE_UPLOAD_SUCCESS,
188 media: media,
189 skipLoading: true,
190 };
191 };
192
193 export function uploadComposeFail(error) {
194 return {
195 type: COMPOSE_UPLOAD_FAIL,
196 error: error,
197 skipLoading: true,
198 };
199 };
200
201 export function undoUploadCompose(media_id) {
202 return {
203 type: COMPOSE_UPLOAD_UNDO,
204 media_id: media_id,
205 };
206 };
207
208 export function clearComposeSuggestions() {
209 return {
210 type: COMPOSE_SUGGESTIONS_CLEAR,
211 };
212 };
213
214 export function fetchComposeSuggestions(token) {
215 return (dispatch, getState) => {
216 api(getState).get('/api/v1/accounts/search', {
217 params: {
218 q: token,
219 resolve: false,
220 limit: 4,
221 },
222 }).then(response => {
223 dispatch(readyComposeSuggestions(token, response.data));
224 });
225 };
226 };
227
228 export function readyComposeSuggestions(token, accounts) {
229 return {
230 type: COMPOSE_SUGGESTIONS_READY,
231 token,
232 accounts,
233 };
234 };
235
236 export function selectComposeSuggestion(position, token, accountId) {
237 return (dispatch, getState) => {
238 const completion = getState().getIn(['accounts', accountId, 'acct']);
239
240 dispatch({
241 type: COMPOSE_SUGGESTION_SELECT,
242 position,
243 token,
244 completion,
245 });
246 };
247 };
248
249 export function mountCompose() {
250 return {
251 type: COMPOSE_MOUNT,
252 };
253 };
254
255 export function unmountCompose() {
256 return {
257 type: COMPOSE_UNMOUNT,
258 };
259 };
260
261 export function toggleComposeAdvancedOption(option) {
262 return {
263 type: COMPOSE_ADVANCED_OPTIONS_CHANGE,
264 option: option,
265 };
266 }
267
268 export function changeComposeSensitivity() {
269 return {
270 type: COMPOSE_SENSITIVITY_CHANGE,
271 };
272 };
273
274 export function changeComposeSpoilerness() {
275 return {
276 type: COMPOSE_SPOILERNESS_CHANGE,
277 };
278 };
279
280 export function changeComposeSpoilerText(text) {
281 return {
282 type: COMPOSE_SPOILER_TEXT_CHANGE,
283 text,
284 };
285 };
286
287 export function changeComposeVisibility(value) {
288 return {
289 type: COMPOSE_VISIBILITY_CHANGE,
290 value,
291 };
292 };
293
294 export function insertEmojiCompose(position, emoji) {
295 return {
296 type: COMPOSE_EMOJI_INSERT,
297 position,
298 emoji,
299 };
300 };
301
302 export function changeComposing(value) {
303 return {
304 type: COMPOSE_COMPOSING_CHANGE,
305 value,
306 };
307 }
This page took 0.155669 seconds and 4 git commands to generate.