闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

275 lines
6.7 KiB

8 years ago
8 years ago
7 years ago
7 years ago
8 years ago
  1. import api from '../api';
  2. import { updateTimeline } from './timelines';
  3. import * as emojione from 'emojione';
  4. export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
  5. export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
  6. export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
  7. export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
  8. export const COMPOSE_REPLY = 'COMPOSE_REPLY';
  9. export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL';
  10. export const COMPOSE_MENTION = 'COMPOSE_MENTION';
  11. export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
  12. export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS';
  13. export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL';
  14. export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS';
  15. export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO';
  16. export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR';
  17. export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY';
  18. export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
  19. export const COMPOSE_MOUNT = 'COMPOSE_MOUNT';
  20. export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
  21. export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
  22. export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
  23. export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
  24. export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
  25. export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
  26. export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
  27. export function changeCompose(text) {
  28. return {
  29. type: COMPOSE_CHANGE,
  30. text: text
  31. };
  32. };
  33. export function replyCompose(status, router) {
  34. return (dispatch, getState) => {
  35. dispatch({
  36. type: COMPOSE_REPLY,
  37. status: status
  38. });
  39. if (!getState().getIn(['compose', 'mounted'])) {
  40. router.push('/statuses/new');
  41. }
  42. };
  43. };
  44. export function cancelReplyCompose() {
  45. return {
  46. type: COMPOSE_REPLY_CANCEL
  47. };
  48. };
  49. export function mentionCompose(account, router) {
  50. return (dispatch, getState) => {
  51. dispatch({
  52. type: COMPOSE_MENTION,
  53. account: account
  54. });
  55. if (!getState().getIn(['compose', 'mounted'])) {
  56. router.push('/statuses/new');
  57. }
  58. };
  59. };
  60. export function submitCompose() {
  61. return function (dispatch, getState) {
  62. const status = emojione.shortnameToUnicode(getState().getIn(['compose', 'text'], ''));
  63. if (!status || !status.length) {
  64. return;
  65. }
  66. dispatch(submitComposeRequest());
  67. api(getState).post('/api/v1/statuses', {
  68. status,
  69. in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
  70. media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')),
  71. sensitive: getState().getIn(['compose', 'sensitive']),
  72. spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
  73. visibility: getState().getIn(['compose', 'privacy'])
  74. }).then(function (response) {
  75. dispatch(submitComposeSuccess({ ...response.data }));
  76. // To make the app more responsive, immediately get the status into the columns
  77. dispatch(updateTimeline('home', { ...response.data }));
  78. if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
  79. if (getState().getIn(['timelines', 'community', 'loaded'])) {
  80. dispatch(updateTimeline('community', { ...response.data }));
  81. }
  82. if (getState().getIn(['timelines', 'public', 'loaded'])) {
  83. dispatch(updateTimeline('public', { ...response.data }));
  84. }
  85. }
  86. }).catch(function (error) {
  87. dispatch(submitComposeFail(error));
  88. });
  89. };
  90. };
  91. export function submitComposeRequest() {
  92. return {
  93. type: COMPOSE_SUBMIT_REQUEST
  94. };
  95. };
  96. export function submitComposeSuccess(status) {
  97. return {
  98. type: COMPOSE_SUBMIT_SUCCESS,
  99. status: status
  100. };
  101. };
  102. export function submitComposeFail(error) {
  103. return {
  104. type: COMPOSE_SUBMIT_FAIL,
  105. error: error
  106. };
  107. };
  108. export function uploadCompose(files) {
  109. return function (dispatch, getState) {
  110. if (getState().getIn(['compose', 'media_attachments']).size > 3) {
  111. return;
  112. }
  113. dispatch(uploadComposeRequest());
  114. let data = new FormData();
  115. data.append('file', files[0]);
  116. api(getState).post('/api/v1/media', data, {
  117. onUploadProgress: function (e) {
  118. dispatch(uploadComposeProgress(e.loaded, e.total));
  119. }
  120. }).then(function (response) {
  121. dispatch(uploadComposeSuccess(response.data));
  122. }).catch(function (error) {
  123. dispatch(uploadComposeFail(error));
  124. });
  125. };
  126. };
  127. export function uploadComposeRequest() {
  128. return {
  129. type: COMPOSE_UPLOAD_REQUEST,
  130. skipLoading: true
  131. };
  132. };
  133. export function uploadComposeProgress(loaded, total) {
  134. return {
  135. type: COMPOSE_UPLOAD_PROGRESS,
  136. loaded: loaded,
  137. total: total
  138. };
  139. };
  140. export function uploadComposeSuccess(media) {
  141. return {
  142. type: COMPOSE_UPLOAD_SUCCESS,
  143. media: media,
  144. skipLoading: true
  145. };
  146. };
  147. export function uploadComposeFail(error) {
  148. return {
  149. type: COMPOSE_UPLOAD_FAIL,
  150. error: error,
  151. skipLoading: true
  152. };
  153. };
  154. export function undoUploadCompose(media_id) {
  155. return {
  156. type: COMPOSE_UPLOAD_UNDO,
  157. media_id: media_id
  158. };
  159. };
  160. export function clearComposeSuggestions() {
  161. return {
  162. type: COMPOSE_SUGGESTIONS_CLEAR
  163. };
  164. };
  165. export function fetchComposeSuggestions(token) {
  166. return (dispatch, getState) => {
  167. api(getState).get('/api/v1/accounts/search', {
  168. params: {
  169. q: token,
  170. resolve: false,
  171. limit: 4
  172. }
  173. }).then(response => {
  174. dispatch(readyComposeSuggestions(token, response.data));
  175. });
  176. };
  177. };
  178. export function readyComposeSuggestions(token, accounts) {
  179. return {
  180. type: COMPOSE_SUGGESTIONS_READY,
  181. token,
  182. accounts
  183. };
  184. };
  185. export function selectComposeSuggestion(position, token, accountId) {
  186. return (dispatch, getState) => {
  187. const completion = getState().getIn(['accounts', accountId, 'acct']);
  188. dispatch({
  189. type: COMPOSE_SUGGESTION_SELECT,
  190. position,
  191. token,
  192. completion
  193. });
  194. };
  195. };
  196. export function mountCompose() {
  197. return {
  198. type: COMPOSE_MOUNT
  199. };
  200. };
  201. export function unmountCompose() {
  202. return {
  203. type: COMPOSE_UNMOUNT
  204. };
  205. };
  206. export function changeComposeSensitivity() {
  207. return {
  208. type: COMPOSE_SENSITIVITY_CHANGE,
  209. };
  210. };
  211. export function changeComposeSpoilerness() {
  212. return {
  213. type: COMPOSE_SPOILERNESS_CHANGE
  214. };
  215. };
  216. export function changeComposeSpoilerText(text) {
  217. return {
  218. type: COMPOSE_SPOILER_TEXT_CHANGE,
  219. text
  220. };
  221. };
  222. export function changeComposeVisibility(value) {
  223. return {
  224. type: COMPOSE_VISIBILITY_CHANGE,
  225. value
  226. };
  227. };
  228. export function insertEmojiCompose(position, emoji) {
  229. return {
  230. type: COMPOSE_EMOJI_INSERT,
  231. position,
  232. emoji
  233. };
  234. };