闭社主体 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.

874 lines
22 KiB

  1. import api, { getLinks } from '../api';
  2. import Immutable from 'immutable';
  3. export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
  4. export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
  5. export const ACCOUNT_FETCH_FAIL = 'ACCOUNT_FETCH_FAIL';
  6. export const ACCOUNT_FOLLOW_REQUEST = 'ACCOUNT_FOLLOW_REQUEST';
  7. export const ACCOUNT_FOLLOW_SUCCESS = 'ACCOUNT_FOLLOW_SUCCESS';
  8. export const ACCOUNT_FOLLOW_FAIL = 'ACCOUNT_FOLLOW_FAIL';
  9. export const ACCOUNT_UNFOLLOW_REQUEST = 'ACCOUNT_UNFOLLOW_REQUEST';
  10. export const ACCOUNT_UNFOLLOW_SUCCESS = 'ACCOUNT_UNFOLLOW_SUCCESS';
  11. export const ACCOUNT_UNFOLLOW_FAIL = 'ACCOUNT_UNFOLLOW_FAIL';
  12. export const ACCOUNT_BLOCK_REQUEST = 'ACCOUNT_BLOCK_REQUEST';
  13. export const ACCOUNT_BLOCK_SUCCESS = 'ACCOUNT_BLOCK_SUCCESS';
  14. export const ACCOUNT_BLOCK_FAIL = 'ACCOUNT_BLOCK_FAIL';
  15. export const ACCOUNT_UNBLOCK_REQUEST = 'ACCOUNT_UNBLOCK_REQUEST';
  16. export const ACCOUNT_UNBLOCK_SUCCESS = 'ACCOUNT_UNBLOCK_SUCCESS';
  17. export const ACCOUNT_UNBLOCK_FAIL = 'ACCOUNT_UNBLOCK_FAIL';
  18. export const ACCOUNT_MUTE_REQUEST = 'ACCOUNT_MUTE_REQUEST';
  19. export const ACCOUNT_MUTE_SUCCESS = 'ACCOUNT_MUTE_SUCCESS';
  20. export const ACCOUNT_MUTE_FAIL = 'ACCOUNT_MUTE_FAIL';
  21. export const ACCOUNT_UNMUTE_REQUEST = 'ACCOUNT_UNMUTE_REQUEST';
  22. export const ACCOUNT_UNMUTE_SUCCESS = 'ACCOUNT_UNMUTE_SUCCESS';
  23. export const ACCOUNT_UNMUTE_FAIL = 'ACCOUNT_UNMUTE_FAIL';
  24. export const ACCOUNT_TIMELINE_FETCH_REQUEST = 'ACCOUNT_TIMELINE_FETCH_REQUEST';
  25. export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS';
  26. export const ACCOUNT_TIMELINE_FETCH_FAIL = 'ACCOUNT_TIMELINE_FETCH_FAIL';
  27. export const ACCOUNT_TIMELINE_EXPAND_REQUEST = 'ACCOUNT_TIMELINE_EXPAND_REQUEST';
  28. export const ACCOUNT_TIMELINE_EXPAND_SUCCESS = 'ACCOUNT_TIMELINE_EXPAND_SUCCESS';
  29. export const ACCOUNT_TIMELINE_EXPAND_FAIL = 'ACCOUNT_TIMELINE_EXPAND_FAIL';
  30. export const ACCOUNT_MEDIA_TIMELINE_FETCH_REQUEST = 'ACCOUNT_MEDIA_TIMELINE_FETCH_REQUEST';
  31. export const ACCOUNT_MEDIA_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_MEDIA_TIMELINE_FETCH_SUCCESS';
  32. export const ACCOUNT_MEDIA_TIMELINE_FETCH_FAIL = 'ACCOUNT_MEDIA_TIMELINE_FETCH_FAIL';
  33. export const ACCOUNT_MEDIA_TIMELINE_EXPAND_REQUEST = 'ACCOUNT_MEDIA_TIMELINE_EXPAND_REQUEST';
  34. export const ACCOUNT_MEDIA_TIMELINE_EXPAND_SUCCESS = 'ACCOUNT_MEDIA_TIMELINE_EXPAND_SUCCESS';
  35. export const ACCOUNT_MEDIA_TIMELINE_EXPAND_FAIL = 'ACCOUNT_MEDIA_TIMELINE_EXPAND_FAIL';
  36. export const FOLLOWERS_FETCH_REQUEST = 'FOLLOWERS_FETCH_REQUEST';
  37. export const FOLLOWERS_FETCH_SUCCESS = 'FOLLOWERS_FETCH_SUCCESS';
  38. export const FOLLOWERS_FETCH_FAIL = 'FOLLOWERS_FETCH_FAIL';
  39. export const FOLLOWERS_EXPAND_REQUEST = 'FOLLOWERS_EXPAND_REQUEST';
  40. export const FOLLOWERS_EXPAND_SUCCESS = 'FOLLOWERS_EXPAND_SUCCESS';
  41. export const FOLLOWERS_EXPAND_FAIL = 'FOLLOWERS_EXPAND_FAIL';
  42. export const FOLLOWING_FETCH_REQUEST = 'FOLLOWING_FETCH_REQUEST';
  43. export const FOLLOWING_FETCH_SUCCESS = 'FOLLOWING_FETCH_SUCCESS';
  44. export const FOLLOWING_FETCH_FAIL = 'FOLLOWING_FETCH_FAIL';
  45. export const FOLLOWING_EXPAND_REQUEST = 'FOLLOWING_EXPAND_REQUEST';
  46. export const FOLLOWING_EXPAND_SUCCESS = 'FOLLOWING_EXPAND_SUCCESS';
  47. export const FOLLOWING_EXPAND_FAIL = 'FOLLOWING_EXPAND_FAIL';
  48. export const RELATIONSHIPS_FETCH_REQUEST = 'RELATIONSHIPS_FETCH_REQUEST';
  49. export const RELATIONSHIPS_FETCH_SUCCESS = 'RELATIONSHIPS_FETCH_SUCCESS';
  50. export const RELATIONSHIPS_FETCH_FAIL = 'RELATIONSHIPS_FETCH_FAIL';
  51. export const FOLLOW_REQUESTS_FETCH_REQUEST = 'FOLLOW_REQUESTS_FETCH_REQUEST';
  52. export const FOLLOW_REQUESTS_FETCH_SUCCESS = 'FOLLOW_REQUESTS_FETCH_SUCCESS';
  53. export const FOLLOW_REQUESTS_FETCH_FAIL = 'FOLLOW_REQUESTS_FETCH_FAIL';
  54. export const FOLLOW_REQUESTS_EXPAND_REQUEST = 'FOLLOW_REQUESTS_EXPAND_REQUEST';
  55. export const FOLLOW_REQUESTS_EXPAND_SUCCESS = 'FOLLOW_REQUESTS_EXPAND_SUCCESS';
  56. export const FOLLOW_REQUESTS_EXPAND_FAIL = 'FOLLOW_REQUESTS_EXPAND_FAIL';
  57. export const FOLLOW_REQUEST_AUTHORIZE_REQUEST = 'FOLLOW_REQUEST_AUTHORIZE_REQUEST';
  58. export const FOLLOW_REQUEST_AUTHORIZE_SUCCESS = 'FOLLOW_REQUEST_AUTHORIZE_SUCCESS';
  59. export const FOLLOW_REQUEST_AUTHORIZE_FAIL = 'FOLLOW_REQUEST_AUTHORIZE_FAIL';
  60. export const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST';
  61. export const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS';
  62. export const FOLLOW_REQUEST_REJECT_FAIL = 'FOLLOW_REQUEST_REJECT_FAIL';
  63. export function fetchAccount(id) {
  64. return (dispatch, getState) => {
  65. dispatch(fetchRelationships([id]));
  66. if (getState().getIn(['accounts', id], null) !== null) {
  67. return;
  68. }
  69. dispatch(fetchAccountRequest(id));
  70. api(getState).get(`/api/v1/accounts/${id}`).then(response => {
  71. dispatch(fetchAccountSuccess(response.data));
  72. }).catch(error => {
  73. dispatch(fetchAccountFail(id, error));
  74. });
  75. };
  76. };
  77. export function fetchAccountTimeline(id, replace = false) {
  78. return (dispatch, getState) => {
  79. const ids = getState().getIn(['timelines', 'accounts_timelines', id, 'items'], Immutable.List());
  80. const newestId = ids.size > 0 ? ids.first() : null;
  81. let params = {};
  82. let skipLoading = false;
  83. replace = replace || newestId === null;
  84. if (!replace) {
  85. params.since_id = newestId;
  86. skipLoading = true;
  87. }
  88. dispatch(fetchAccountTimelineRequest(id, skipLoading));
  89. api(getState).get(`/api/v1/accounts/${id}/statuses`, { params }).then(response => {
  90. const next = getLinks(response).refs.find(link => link.rel === 'next');
  91. dispatch(fetchAccountTimelineSuccess(id, response.data, replace, skipLoading, next));
  92. }).catch(error => {
  93. dispatch(fetchAccountTimelineFail(id, error, skipLoading));
  94. });
  95. };
  96. };
  97. export function fetchAccountMediaTimeline(id, replace = false) {
  98. return (dispatch, getState) => {
  99. const ids = getState().getIn(['timelines', 'accounts_media_timelines', id, 'items'], Immutable.List());
  100. const newestId = ids.size > 0 ? ids.first() : null;
  101. let params = { only_media: 'true', limit: 12 };
  102. let skipLoading = false;
  103. replace = replace || newestId === null;
  104. if (!replace) {
  105. params.since_id = newestId;
  106. skipLoading = true;
  107. }
  108. dispatch(fetchAccountMediaTimelineRequest(id, skipLoading));
  109. api(getState).get(`/api/v1/accounts/${id}/statuses`, { params }).then(response => {
  110. const next = getLinks(response).refs.find(link => link.rel === 'next');
  111. dispatch(fetchAccountMediaTimelineSuccess(id, response.data, replace, skipLoading, next));
  112. }).catch(error => {
  113. dispatch(fetchAccountMediaTimelineFail(id, error, skipLoading));
  114. });
  115. };
  116. };
  117. export function expandAccountTimeline(id) {
  118. return (dispatch, getState) => {
  119. const lastId = getState().getIn(['timelines', 'accounts_timelines', id, 'items'], Immutable.List()).last();
  120. dispatch(expandAccountTimelineRequest(id));
  121. api(getState).get(`/api/v1/accounts/${id}/statuses`, {
  122. params: {
  123. limit: 10,
  124. max_id: lastId,
  125. },
  126. }).then(response => {
  127. const next = getLinks(response).refs.find(link => link.rel === 'next');
  128. dispatch(expandAccountTimelineSuccess(id, response.data, next));
  129. }).catch(error => {
  130. dispatch(expandAccountTimelineFail(id, error));
  131. });
  132. };
  133. };
  134. export function expandAccountMediaTimeline(id) {
  135. return (dispatch, getState) => {
  136. const lastId = getState().getIn(['timelines', 'accounts_media_timelines', id, 'items'], Immutable.List()).last();
  137. dispatch(expandAccountMediaTimelineRequest(id));
  138. api(getState).get(`/api/v1/accounts/${id}/statuses`, {
  139. params: {
  140. limit: 12,
  141. only_media: 'true',
  142. max_id: lastId,
  143. },
  144. }).then(response => {
  145. const next = getLinks(response).refs.find(link => link.rel === 'next');
  146. dispatch(expandAccountMediaTimelineSuccess(id, response.data, next));
  147. }).catch(error => {
  148. dispatch(expandAccountMediaTimelineFail(id, error));
  149. });
  150. };
  151. };
  152. export function fetchAccountRequest(id) {
  153. return {
  154. type: ACCOUNT_FETCH_REQUEST,
  155. id,
  156. };
  157. };
  158. export function fetchAccountSuccess(account) {
  159. return {
  160. type: ACCOUNT_FETCH_SUCCESS,
  161. account,
  162. };
  163. };
  164. export function fetchAccountFail(id, error) {
  165. return {
  166. type: ACCOUNT_FETCH_FAIL,
  167. id,
  168. error,
  169. skipAlert: true,
  170. };
  171. };
  172. export function followAccount(id) {
  173. return (dispatch, getState) => {
  174. dispatch(followAccountRequest(id));
  175. api(getState).post(`/api/v1/accounts/${id}/follow`).then(response => {
  176. dispatch(followAccountSuccess(response.data));
  177. }).catch(error => {
  178. dispatch(followAccountFail(error));
  179. });
  180. };
  181. };
  182. export function unfollowAccount(id) {
  183. return (dispatch, getState) => {
  184. dispatch(unfollowAccountRequest(id));
  185. api(getState).post(`/api/v1/accounts/${id}/unfollow`).then(response => {
  186. dispatch(unfollowAccountSuccess(response.data));
  187. }).catch(error => {
  188. dispatch(unfollowAccountFail(error));
  189. });
  190. };
  191. };
  192. export function followAccountRequest(id) {
  193. return {
  194. type: ACCOUNT_FOLLOW_REQUEST,
  195. id,
  196. };
  197. };
  198. export function followAccountSuccess(relationship) {
  199. return {
  200. type: ACCOUNT_FOLLOW_SUCCESS,
  201. relationship,
  202. };
  203. };
  204. export function followAccountFail(error) {
  205. return {
  206. type: ACCOUNT_FOLLOW_FAIL,
  207. error,
  208. };
  209. };
  210. export function unfollowAccountRequest(id) {
  211. return {
  212. type: ACCOUNT_UNFOLLOW_REQUEST,
  213. id,
  214. };
  215. };
  216. export function unfollowAccountSuccess(relationship) {
  217. return {
  218. type: ACCOUNT_UNFOLLOW_SUCCESS,
  219. relationship,
  220. };
  221. };
  222. export function unfollowAccountFail(error) {
  223. return {
  224. type: ACCOUNT_UNFOLLOW_FAIL,
  225. error,
  226. };
  227. };
  228. export function fetchAccountTimelineRequest(id, skipLoading) {
  229. return {
  230. type: ACCOUNT_TIMELINE_FETCH_REQUEST,
  231. id,
  232. skipLoading,
  233. };
  234. };
  235. export function fetchAccountTimelineSuccess(id, statuses, replace, skipLoading, next) {
  236. return {
  237. type: ACCOUNT_TIMELINE_FETCH_SUCCESS,
  238. id,
  239. statuses,
  240. replace,
  241. skipLoading,
  242. next,
  243. };
  244. };
  245. export function fetchAccountTimelineFail(id, error, skipLoading) {
  246. return {
  247. type: ACCOUNT_TIMELINE_FETCH_FAIL,
  248. id,
  249. error,
  250. skipLoading,
  251. skipAlert: error.response.status === 404,
  252. };
  253. };
  254. export function fetchAccountMediaTimelineRequest(id, skipLoading) {
  255. return {
  256. type: ACCOUNT_MEDIA_TIMELINE_FETCH_REQUEST,
  257. id,
  258. skipLoading,
  259. };
  260. };
  261. export function fetchAccountMediaTimelineSuccess(id, statuses, replace, skipLoading, next) {
  262. return {
  263. type: ACCOUNT_MEDIA_TIMELINE_FETCH_SUCCESS,
  264. id,
  265. statuses,
  266. replace,
  267. skipLoading,
  268. next,
  269. };
  270. };
  271. export function fetchAccountMediaTimelineFail(id, error, skipLoading) {
  272. return {
  273. type: ACCOUNT_MEDIA_TIMELINE_FETCH_FAIL,
  274. id,
  275. error,
  276. skipLoading,
  277. skipAlert: error.response.status === 404,
  278. };
  279. };
  280. export function expandAccountTimelineRequest(id) {
  281. return {
  282. type: ACCOUNT_TIMELINE_EXPAND_REQUEST,
  283. id,
  284. };
  285. };
  286. export function expandAccountTimelineSuccess(id, statuses, next) {
  287. return {
  288. type: ACCOUNT_TIMELINE_EXPAND_SUCCESS,
  289. id,
  290. statuses,
  291. next,
  292. };
  293. };
  294. export function expandAccountTimelineFail(id, error) {
  295. return {
  296. type: ACCOUNT_TIMELINE_EXPAND_FAIL,
  297. id,
  298. error,
  299. };
  300. };
  301. export function expandAccountMediaTimelineRequest(id) {
  302. return {
  303. type: ACCOUNT_MEDIA_TIMELINE_EXPAND_REQUEST,
  304. id,
  305. };
  306. };
  307. export function expandAccountMediaTimelineSuccess(id, statuses, next) {
  308. return {
  309. type: ACCOUNT_MEDIA_TIMELINE_EXPAND_SUCCESS,
  310. id,
  311. statuses,
  312. next,
  313. };
  314. };
  315. export function expandAccountMediaTimelineFail(id, error) {
  316. return {
  317. type: ACCOUNT_MEDIA_TIMELINE_EXPAND_FAIL,
  318. id,
  319. error,
  320. };
  321. };
  322. export function blockAccount(id) {
  323. return (dispatch, getState) => {
  324. dispatch(blockAccountRequest(id));
  325. api(getState).post(`/api/v1/accounts/${id}/block`).then(response => {
  326. // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
  327. dispatch(blockAccountSuccess(response.data, getState().get('statuses')));
  328. }).catch(error => {
  329. dispatch(blockAccountFail(id, error));
  330. });
  331. };
  332. };
  333. export function unblockAccount(id) {
  334. return (dispatch, getState) => {
  335. dispatch(unblockAccountRequest(id));
  336. api(getState).post(`/api/v1/accounts/${id}/unblock`).then(response => {
  337. dispatch(unblockAccountSuccess(response.data));
  338. }).catch(error => {
  339. dispatch(unblockAccountFail(id, error));
  340. });
  341. };
  342. };
  343. export function blockAccountRequest(id) {
  344. return {
  345. type: ACCOUNT_BLOCK_REQUEST,
  346. id,
  347. };
  348. };
  349. export function blockAccountSuccess(relationship, statuses) {
  350. return {
  351. type: ACCOUNT_BLOCK_SUCCESS,
  352. relationship,
  353. statuses,
  354. };
  355. };
  356. export function blockAccountFail(error) {
  357. return {
  358. type: ACCOUNT_BLOCK_FAIL,
  359. error,
  360. };
  361. };
  362. export function unblockAccountRequest(id) {
  363. return {
  364. type: ACCOUNT_UNBLOCK_REQUEST,
  365. id,
  366. };
  367. };
  368. export function unblockAccountSuccess(relationship) {
  369. return {
  370. type: ACCOUNT_UNBLOCK_SUCCESS,
  371. relationship,
  372. };
  373. };
  374. export function unblockAccountFail(error) {
  375. return {
  376. type: ACCOUNT_UNBLOCK_FAIL,
  377. error,
  378. };
  379. };
  380. export function muteAccount(id) {
  381. return (dispatch, getState) => {
  382. dispatch(muteAccountRequest(id));
  383. api(getState).post(`/api/v1/accounts/${id}/mute`).then(response => {
  384. // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
  385. dispatch(muteAccountSuccess(response.data, getState().get('statuses')));
  386. }).catch(error => {
  387. dispatch(muteAccountFail(id, error));
  388. });
  389. };
  390. };
  391. export function unmuteAccount(id) {
  392. return (dispatch, getState) => {
  393. dispatch(unmuteAccountRequest(id));
  394. api(getState).post(`/api/v1/accounts/${id}/unmute`).then(response => {
  395. dispatch(unmuteAccountSuccess(response.data));
  396. }).catch(error => {
  397. dispatch(unmuteAccountFail(id, error));
  398. });
  399. };
  400. };
  401. export function muteAccountRequest(id) {
  402. return {
  403. type: ACCOUNT_MUTE_REQUEST,
  404. id,
  405. };
  406. };
  407. export function muteAccountSuccess(relationship, statuses) {
  408. return {
  409. type: ACCOUNT_MUTE_SUCCESS,
  410. relationship,
  411. statuses,
  412. };
  413. };
  414. export function muteAccountFail(error) {
  415. return {
  416. type: ACCOUNT_MUTE_FAIL,
  417. error,
  418. };
  419. };
  420. export function unmuteAccountRequest(id) {
  421. return {
  422. type: ACCOUNT_UNMUTE_REQUEST,
  423. id,
  424. };
  425. };
  426. export function unmuteAccountSuccess(relationship) {
  427. return {
  428. type: ACCOUNT_UNMUTE_SUCCESS,
  429. relationship,
  430. };
  431. };
  432. export function unmuteAccountFail(error) {
  433. return {
  434. type: ACCOUNT_UNMUTE_FAIL,
  435. error,
  436. };
  437. };
  438. export function fetchFollowers(id) {
  439. return (dispatch, getState) => {
  440. dispatch(fetchFollowersRequest(id));
  441. api(getState).get(`/api/v1/accounts/${id}/followers`).then(response => {
  442. const next = getLinks(response).refs.find(link => link.rel === 'next');
  443. dispatch(fetchFollowersSuccess(id, response.data, next ? next.uri : null));
  444. dispatch(fetchRelationships(response.data.map(item => item.id)));
  445. }).catch(error => {
  446. dispatch(fetchFollowersFail(id, error));
  447. });
  448. };
  449. };
  450. export function fetchFollowersRequest(id) {
  451. return {
  452. type: FOLLOWERS_FETCH_REQUEST,
  453. id,
  454. };
  455. };
  456. export function fetchFollowersSuccess(id, accounts, next) {
  457. return {
  458. type: FOLLOWERS_FETCH_SUCCESS,
  459. id,
  460. accounts,
  461. next,
  462. };
  463. };
  464. export function fetchFollowersFail(id, error) {
  465. return {
  466. type: FOLLOWERS_FETCH_FAIL,
  467. id,
  468. error,
  469. };
  470. };
  471. export function expandFollowers(id) {
  472. return (dispatch, getState) => {
  473. const url = getState().getIn(['user_lists', 'followers', id, 'next']);
  474. if (url === null) {
  475. return;
  476. }
  477. dispatch(expandFollowersRequest(id));
  478. api(getState).get(url).then(response => {
  479. const next = getLinks(response).refs.find(link => link.rel === 'next');
  480. dispatch(expandFollowersSuccess(id, response.data, next ? next.uri : null));
  481. dispatch(fetchRelationships(response.data.map(item => item.id)));
  482. }).catch(error => {
  483. dispatch(expandFollowersFail(id, error));
  484. });
  485. };
  486. };
  487. export function expandFollowersRequest(id) {
  488. return {
  489. type: FOLLOWERS_EXPAND_REQUEST,
  490. id,
  491. };
  492. };
  493. export function expandFollowersSuccess(id, accounts, next) {
  494. return {
  495. type: FOLLOWERS_EXPAND_SUCCESS,
  496. id,
  497. accounts,
  498. next,
  499. };
  500. };
  501. export function expandFollowersFail(id, error) {
  502. return {
  503. type: FOLLOWERS_EXPAND_FAIL,
  504. id,
  505. error,
  506. };
  507. };
  508. export function fetchFollowing(id) {
  509. return (dispatch, getState) => {
  510. dispatch(fetchFollowingRequest(id));
  511. api(getState).get(`/api/v1/accounts/${id}/following`).then(response => {
  512. const next = getLinks(response).refs.find(link => link.rel === 'next');
  513. dispatch(fetchFollowingSuccess(id, response.data, next ? next.uri : null));
  514. dispatch(fetchRelationships(response.data.map(item => item.id)));
  515. }).catch(error => {
  516. dispatch(fetchFollowingFail(id, error));
  517. });
  518. };
  519. };
  520. export function fetchFollowingRequest(id) {
  521. return {
  522. type: FOLLOWING_FETCH_REQUEST,
  523. id,
  524. };
  525. };
  526. export function fetchFollowingSuccess(id, accounts, next) {
  527. return {
  528. type: FOLLOWING_FETCH_SUCCESS,
  529. id,
  530. accounts,
  531. next,
  532. };
  533. };
  534. export function fetchFollowingFail(id, error) {
  535. return {
  536. type: FOLLOWING_FETCH_FAIL,
  537. id,
  538. error,
  539. };
  540. };
  541. export function expandFollowing(id) {
  542. return (dispatch, getState) => {
  543. const url = getState().getIn(['user_lists', 'following', id, 'next']);
  544. if (url === null) {
  545. return;
  546. }
  547. dispatch(expandFollowingRequest(id));
  548. api(getState).get(url).then(response => {
  549. const next = getLinks(response).refs.find(link => link.rel === 'next');
  550. dispatch(expandFollowingSuccess(id, response.data, next ? next.uri : null));
  551. dispatch(fetchRelationships(response.data.map(item => item.id)));
  552. }).catch(error => {
  553. dispatch(expandFollowingFail(id, error));
  554. });
  555. };
  556. };
  557. export function expandFollowingRequest(id) {
  558. return {
  559. type: FOLLOWING_EXPAND_REQUEST,
  560. id,
  561. };
  562. };
  563. export function expandFollowingSuccess(id, accounts, next) {
  564. return {
  565. type: FOLLOWING_EXPAND_SUCCESS,
  566. id,
  567. accounts,
  568. next,
  569. };
  570. };
  571. export function expandFollowingFail(id, error) {
  572. return {
  573. type: FOLLOWING_EXPAND_FAIL,
  574. id,
  575. error,
  576. };
  577. };
  578. export function fetchRelationships(accountIds) {
  579. return (dispatch, getState) => {
  580. const loadedRelationships = getState().get('relationships');
  581. const newAccountIds = accountIds.filter(id => loadedRelationships.get(id, null) === null);
  582. if (newAccountIds.length === 0) {
  583. return;
  584. }
  585. dispatch(fetchRelationshipsRequest(newAccountIds));
  586. api(getState).get(`/api/v1/accounts/relationships?${newAccountIds.map(id => `id[]=${id}`).join('&')}`).then(response => {
  587. dispatch(fetchRelationshipsSuccess(response.data));
  588. }).catch(error => {
  589. dispatch(fetchRelationshipsFail(error));
  590. });
  591. };
  592. };
  593. export function fetchRelationshipsRequest(ids) {
  594. return {
  595. type: RELATIONSHIPS_FETCH_REQUEST,
  596. ids,
  597. skipLoading: true,
  598. };
  599. };
  600. export function fetchRelationshipsSuccess(relationships) {
  601. return {
  602. type: RELATIONSHIPS_FETCH_SUCCESS,
  603. relationships,
  604. skipLoading: true,
  605. };
  606. };
  607. export function fetchRelationshipsFail(error) {
  608. return {
  609. type: RELATIONSHIPS_FETCH_FAIL,
  610. error,
  611. skipLoading: true,
  612. };
  613. };
  614. export function fetchFollowRequests() {
  615. return (dispatch, getState) => {
  616. dispatch(fetchFollowRequestsRequest());
  617. api(getState).get('/api/v1/follow_requests').then(response => {
  618. const next = getLinks(response).refs.find(link => link.rel === 'next');
  619. dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
  620. }).catch(error => dispatch(fetchFollowRequestsFail(error)));
  621. };
  622. };
  623. export function fetchFollowRequestsRequest() {
  624. return {
  625. type: FOLLOW_REQUESTS_FETCH_REQUEST,
  626. };
  627. };
  628. export function fetchFollowRequestsSuccess(accounts, next) {
  629. return {
  630. type: FOLLOW_REQUESTS_FETCH_SUCCESS,
  631. accounts,
  632. next,
  633. };
  634. };
  635. export function fetchFollowRequestsFail(error) {
  636. return {
  637. type: FOLLOW_REQUESTS_FETCH_FAIL,
  638. error,
  639. };
  640. };
  641. export function expandFollowRequests() {
  642. return (dispatch, getState) => {
  643. const url = getState().getIn(['user_lists', 'follow_requests', 'next']);
  644. if (url === null) {
  645. return;
  646. }
  647. dispatch(expandFollowRequestsRequest());
  648. api(getState).get(url).then(response => {
  649. const next = getLinks(response).refs.find(link => link.rel === 'next');
  650. dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
  651. }).catch(error => dispatch(expandFollowRequestsFail(error)));
  652. };
  653. };
  654. export function expandFollowRequestsRequest() {
  655. return {
  656. type: FOLLOW_REQUESTS_EXPAND_REQUEST,
  657. };
  658. };
  659. export function expandFollowRequestsSuccess(accounts, next) {
  660. return {
  661. type: FOLLOW_REQUESTS_EXPAND_SUCCESS,
  662. accounts,
  663. next,
  664. };
  665. };
  666. export function expandFollowRequestsFail(error) {
  667. return {
  668. type: FOLLOW_REQUESTS_EXPAND_FAIL,
  669. error,
  670. };
  671. };
  672. export function authorizeFollowRequest(id) {
  673. return (dispatch, getState) => {
  674. dispatch(authorizeFollowRequestRequest(id));
  675. api(getState)
  676. .post(`/api/v1/follow_requests/${id}/authorize`)
  677. .then(response => dispatch(authorizeFollowRequestSuccess(id)))
  678. .catch(error => dispatch(authorizeFollowRequestFail(id, error)));
  679. };
  680. };
  681. export function authorizeFollowRequestRequest(id) {
  682. return {
  683. type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
  684. id,
  685. };
  686. };
  687. export function authorizeFollowRequestSuccess(id) {
  688. return {
  689. type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
  690. id,
  691. };
  692. };
  693. export function authorizeFollowRequestFail(id, error) {
  694. return {
  695. type: FOLLOW_REQUEST_AUTHORIZE_FAIL,
  696. id,
  697. error,
  698. };
  699. };
  700. export function rejectFollowRequest(id) {
  701. return (dispatch, getState) => {
  702. dispatch(rejectFollowRequestRequest(id));
  703. api(getState)
  704. .post(`/api/v1/follow_requests/${id}/reject`)
  705. .then(response => dispatch(rejectFollowRequestSuccess(id)))
  706. .catch(error => dispatch(rejectFollowRequestFail(id, error)));
  707. };
  708. };
  709. export function rejectFollowRequestRequest(id) {
  710. return {
  711. type: FOLLOW_REQUEST_REJECT_REQUEST,
  712. id,
  713. };
  714. };
  715. export function rejectFollowRequestSuccess(id) {
  716. return {
  717. type: FOLLOW_REQUEST_REJECT_SUCCESS,
  718. id,
  719. };
  720. };
  721. export function rejectFollowRequestFail(id, error) {
  722. return {
  723. type: FOLLOW_REQUEST_REJECT_FAIL,
  724. id,
  725. error,
  726. };
  727. };