]> cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/actions/statuses.js
Add redraft function (#7735)
[mastodon.git] / app / javascript / mastodon / actions / statuses.js
1 import api from '../api';
2 import openDB from '../storage/db';
3 import { evictStatus } from '../storage/modifier';
4
5 import { deleteFromTimelines } from './timelines';
6 import { fetchStatusCard } from './cards';
7 import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer';
8
9 export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
10 export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
11 export const STATUS_FETCH_FAIL = 'STATUS_FETCH_FAIL';
12
13 export const STATUS_DELETE_REQUEST = 'STATUS_DELETE_REQUEST';
14 export const STATUS_DELETE_SUCCESS = 'STATUS_DELETE_SUCCESS';
15 export const STATUS_DELETE_FAIL = 'STATUS_DELETE_FAIL';
16
17 export const CONTEXT_FETCH_REQUEST = 'CONTEXT_FETCH_REQUEST';
18 export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
19 export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
20
21 export const STATUS_MUTE_REQUEST = 'STATUS_MUTE_REQUEST';
22 export const STATUS_MUTE_SUCCESS = 'STATUS_MUTE_SUCCESS';
23 export const STATUS_MUTE_FAIL = 'STATUS_MUTE_FAIL';
24
25 export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST';
26 export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS';
27 export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
28
29 export const STATUS_REVEAL = 'STATUS_REVEAL';
30 export const STATUS_HIDE = 'STATUS_HIDE';
31
32 export const REDRAFT = 'REDRAFT';
33
34 export function fetchStatusRequest(id, skipLoading) {
35 return {
36 type: STATUS_FETCH_REQUEST,
37 id,
38 skipLoading,
39 };
40 };
41
42 function getFromDB(dispatch, getState, accountIndex, index, id) {
43 return new Promise((resolve, reject) => {
44 const request = index.get(id);
45
46 request.onerror = reject;
47
48 request.onsuccess = () => {
49 const promises = [];
50
51 if (!request.result) {
52 reject();
53 return;
54 }
55
56 dispatch(importStatus(request.result));
57
58 if (getState().getIn(['accounts', request.result.account], null) === null) {
59 promises.push(new Promise((accountResolve, accountReject) => {
60 const accountRequest = accountIndex.get(request.result.account);
61
62 accountRequest.onerror = accountReject;
63 accountRequest.onsuccess = () => {
64 if (!request.result) {
65 accountReject();
66 return;
67 }
68
69 dispatch(importAccount(accountRequest.result));
70 accountResolve();
71 };
72 }));
73 }
74
75 if (request.result.reblog && getState().getIn(['statuses', request.result.reblog], null) === null) {
76 promises.push(getFromDB(dispatch, getState, accountIndex, index, request.result.reblog));
77 }
78
79 resolve(Promise.all(promises));
80 };
81 });
82 }
83
84 export function fetchStatus(id) {
85 return (dispatch, getState) => {
86 const skipLoading = getState().getIn(['statuses', id], null) !== null;
87
88 dispatch(fetchContext(id));
89 dispatch(fetchStatusCard(id));
90
91 if (skipLoading) {
92 return;
93 }
94
95 dispatch(fetchStatusRequest(id, skipLoading));
96
97 openDB().then(db => {
98 const transaction = db.transaction(['accounts', 'statuses'], 'read');
99 const accountIndex = transaction.objectStore('accounts').index('id');
100 const index = transaction.objectStore('statuses').index('id');
101
102 return getFromDB(dispatch, getState, accountIndex, index, id).then(() => {
103 db.close();
104 }, error => {
105 db.close();
106 throw error;
107 });
108 }).then(() => {
109 dispatch(fetchStatusSuccess(skipLoading));
110 }, () => api(getState).get(`/api/v1/statuses/${id}`).then(response => {
111 dispatch(importFetchedStatus(response.data));
112 dispatch(fetchStatusSuccess(skipLoading));
113 })).catch(error => {
114 dispatch(fetchStatusFail(id, error, skipLoading));
115 });
116 };
117 };
118
119 export function fetchStatusSuccess(skipLoading) {
120 return {
121 type: STATUS_FETCH_SUCCESS,
122 skipLoading,
123 };
124 };
125
126 export function fetchStatusFail(id, error, skipLoading) {
127 return {
128 type: STATUS_FETCH_FAIL,
129 id,
130 error,
131 skipLoading,
132 skipAlert: true,
133 };
134 };
135
136 export function redraft(status) {
137 return {
138 type: REDRAFT,
139 status,
140 };
141 };
142
143 export function deleteStatus(id, withRedraft = false) {
144 return (dispatch, getState) => {
145 const status = getState().getIn(['statuses', id]);
146
147 dispatch(deleteStatusRequest(id));
148
149 api(getState).delete(`/api/v1/statuses/${id}`).then(() => {
150 evictStatus(id);
151 dispatch(deleteStatusSuccess(id));
152 dispatch(deleteFromTimelines(id));
153
154 if (withRedraft) {
155 dispatch(redraft(status));
156 }
157 }).catch(error => {
158 dispatch(deleteStatusFail(id, error));
159 });
160 };
161 };
162
163 export function deleteStatusRequest(id) {
164 return {
165 type: STATUS_DELETE_REQUEST,
166 id: id,
167 };
168 };
169
170 export function deleteStatusSuccess(id) {
171 return {
172 type: STATUS_DELETE_SUCCESS,
173 id: id,
174 };
175 };
176
177 export function deleteStatusFail(id, error) {
178 return {
179 type: STATUS_DELETE_FAIL,
180 id: id,
181 error: error,
182 };
183 };
184
185 export function fetchContext(id) {
186 return (dispatch, getState) => {
187 dispatch(fetchContextRequest(id));
188
189 api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
190 dispatch(importFetchedStatuses(response.data.ancestors.concat(response.data.descendants)));
191 dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
192
193 }).catch(error => {
194 if (error.response && error.response.status === 404) {
195 dispatch(deleteFromTimelines(id));
196 }
197
198 dispatch(fetchContextFail(id, error));
199 });
200 };
201 };
202
203 export function fetchContextRequest(id) {
204 return {
205 type: CONTEXT_FETCH_REQUEST,
206 id,
207 };
208 };
209
210 export function fetchContextSuccess(id, ancestors, descendants) {
211 return {
212 type: CONTEXT_FETCH_SUCCESS,
213 id,
214 ancestors,
215 descendants,
216 statuses: ancestors.concat(descendants),
217 };
218 };
219
220 export function fetchContextFail(id, error) {
221 return {
222 type: CONTEXT_FETCH_FAIL,
223 id,
224 error,
225 skipAlert: true,
226 };
227 };
228
229 export function muteStatus(id) {
230 return (dispatch, getState) => {
231 dispatch(muteStatusRequest(id));
232
233 api(getState).post(`/api/v1/statuses/${id}/mute`).then(() => {
234 dispatch(muteStatusSuccess(id));
235 }).catch(error => {
236 dispatch(muteStatusFail(id, error));
237 });
238 };
239 };
240
241 export function muteStatusRequest(id) {
242 return {
243 type: STATUS_MUTE_REQUEST,
244 id,
245 };
246 };
247
248 export function muteStatusSuccess(id) {
249 return {
250 type: STATUS_MUTE_SUCCESS,
251 id,
252 };
253 };
254
255 export function muteStatusFail(id, error) {
256 return {
257 type: STATUS_MUTE_FAIL,
258 id,
259 error,
260 };
261 };
262
263 export function unmuteStatus(id) {
264 return (dispatch, getState) => {
265 dispatch(unmuteStatusRequest(id));
266
267 api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => {
268 dispatch(unmuteStatusSuccess(id));
269 }).catch(error => {
270 dispatch(unmuteStatusFail(id, error));
271 });
272 };
273 };
274
275 export function unmuteStatusRequest(id) {
276 return {
277 type: STATUS_UNMUTE_REQUEST,
278 id,
279 };
280 };
281
282 export function unmuteStatusSuccess(id) {
283 return {
284 type: STATUS_UNMUTE_SUCCESS,
285 id,
286 };
287 };
288
289 export function unmuteStatusFail(id, error) {
290 return {
291 type: STATUS_UNMUTE_FAIL,
292 id,
293 error,
294 };
295 };
296
297 export function hideStatus(ids) {
298 if (!Array.isArray(ids)) {
299 ids = [ids];
300 }
301
302 return {
303 type: STATUS_HIDE,
304 ids,
305 };
306 };
307
308 export function revealStatus(ids) {
309 if (!Array.isArray(ids)) {
310 ids = [ids];
311 }
312
313 return {
314 type: STATUS_REVEAL,
315 ids,
316 };
317 };
This page took 0.143704 seconds and 4 git commands to generate.