The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

215 lines
7.3 KiB

  1. import api, { getLinks } from '../api';
  2. import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
  3. export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
  4. export const TIMELINE_DELETE = 'TIMELINE_DELETE';
  5. export const TIMELINE_REFRESH_REQUEST = 'TIMELINE_REFRESH_REQUEST';
  6. export const TIMELINE_REFRESH_SUCCESS = 'TIMELINE_REFRESH_SUCCESS';
  7. export const TIMELINE_REFRESH_FAIL = 'TIMELINE_REFRESH_FAIL';
  8. export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
  9. export const TIMELINE_EXPAND_SUCCESS = 'TIMELINE_EXPAND_SUCCESS';
  10. export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
  11. export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
  12. export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
  13. export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
  14. export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
  15. export function refreshTimelineSuccess(timeline, statuses, skipLoading, next, partial) {
  16. return {
  17. type: TIMELINE_REFRESH_SUCCESS,
  18. timeline,
  19. statuses,
  20. skipLoading,
  21. next,
  22. partial,
  23. };
  24. };
  25. export function updateTimeline(timeline, status) {
  26. return (dispatch, getState) => {
  27. const references = status.reblog ? getState().get('statuses').filter((item, itemId) => (itemId === status.reblog.id || item.get('reblog') === status.reblog.id)).map((_, itemId) => itemId) : [];
  28. const parents = [];
  29. if (status.in_reply_to_id) {
  30. let parent = getState().getIn(['statuses', status.in_reply_to_id]);
  31. while (parent && parent.get('in_reply_to_id')) {
  32. parents.push(parent.get('id'));
  33. parent = getState().getIn(['statuses', parent.get('in_reply_to_id')]);
  34. }
  35. }
  36. dispatch({
  37. type: TIMELINE_UPDATE,
  38. timeline,
  39. status,
  40. references,
  41. });
  42. if (parents.length > 0) {
  43. dispatch({
  44. type: TIMELINE_CONTEXT_UPDATE,
  45. status,
  46. references: parents,
  47. });
  48. }
  49. };
  50. };
  51. export function deleteFromTimelines(id) {
  52. return (dispatch, getState) => {
  53. const accountId = getState().getIn(['statuses', id, 'account']);
  54. const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => [status.get('id'), status.get('account')]);
  55. const reblogOf = getState().getIn(['statuses', id, 'reblog'], null);
  56. dispatch({
  57. type: TIMELINE_DELETE,
  58. id,
  59. accountId,
  60. references,
  61. reblogOf,
  62. });
  63. };
  64. };
  65. export function refreshTimelineRequest(timeline, skipLoading) {
  66. return {
  67. type: TIMELINE_REFRESH_REQUEST,
  68. timeline,
  69. skipLoading,
  70. };
  71. };
  72. export function refreshTimeline(timelineId, path, params = {}) {
  73. return function (dispatch, getState) {
  74. const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
  75. if (timeline.get('isLoading') || (timeline.get('online') && !timeline.get('isPartial'))) {
  76. return;
  77. }
  78. const ids = timeline.get('items', ImmutableList());
  79. const newestId = ids.size > 0 ? ids.first() : null;
  80. let skipLoading = timeline.get('loaded');
  81. if (newestId !== null) {
  82. params.since_id = newestId;
  83. }
  84. dispatch(refreshTimelineRequest(timelineId, skipLoading));
  85. api(getState).get(path, { params }).then(response => {
  86. if (response.status === 206) {
  87. dispatch(refreshTimelineSuccess(timelineId, [], skipLoading, null, true));
  88. } else {
  89. const next = getLinks(response).refs.find(link => link.rel === 'next');
  90. dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null, false));
  91. }
  92. }).catch(error => {
  93. dispatch(refreshTimelineFail(timelineId, error, skipLoading));
  94. });
  95. };
  96. };
  97. export const refreshHomeTimeline = () => refreshTimeline('home', '/api/v1/timelines/home');
  98. export const refreshPublicTimeline = () => refreshTimeline('public', '/api/v1/timelines/public');
  99. export const refreshCommunityTimeline = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true });
  100. export const refreshAccountTimeline = (accountId, withReplies) => refreshTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies });
  101. export const refreshAccountFeaturedTimeline = accountId => refreshTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });
  102. export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
  103. export const refreshHashtagTimeline = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
  104. export const refreshListTimeline = id => refreshTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`);
  105. export function refreshTimelineFail(timeline, error, skipLoading) {
  106. return {
  107. type: TIMELINE_REFRESH_FAIL,
  108. timeline,
  109. error,
  110. skipLoading,
  111. skipAlert: error.response && error.response.status === 404,
  112. };
  113. };
  114. export function expandTimeline(timelineId, path, params = {}) {
  115. return (dispatch, getState) => {
  116. const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
  117. const ids = timeline.get('items', ImmutableList());
  118. if (timeline.get('isLoading') || ids.size === 0) {
  119. return;
  120. }
  121. params.max_id = ids.last();
  122. params.limit = 10;
  123. dispatch(expandTimelineRequest(timelineId));
  124. api(getState).get(path, { params }).then(response => {
  125. const next = getLinks(response).refs.find(link => link.rel === 'next');
  126. dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null));
  127. }).catch(error => {
  128. dispatch(expandTimelineFail(timelineId, error));
  129. });
  130. };
  131. };
  132. export const expandHomeTimeline = () => expandTimeline('home', '/api/v1/timelines/home');
  133. export const expandPublicTimeline = () => expandTimeline('public', '/api/v1/timelines/public');
  134. export const expandCommunityTimeline = () => expandTimeline('community', '/api/v1/timelines/public', { local: true });
  135. export const expandAccountTimeline = (accountId, withReplies) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies });
  136. export const expandAccountMediaTimeline = accountId => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
  137. export const expandHashtagTimeline = hashtag => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
  138. export const expandListTimeline = id => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`);
  139. export function expandTimelineRequest(timeline) {
  140. return {
  141. type: TIMELINE_EXPAND_REQUEST,
  142. timeline,
  143. };
  144. };
  145. export function expandTimelineSuccess(timeline, statuses, next) {
  146. return {
  147. type: TIMELINE_EXPAND_SUCCESS,
  148. timeline,
  149. statuses,
  150. next,
  151. };
  152. };
  153. export function expandTimelineFail(timeline, error) {
  154. return {
  155. type: TIMELINE_EXPAND_FAIL,
  156. timeline,
  157. error,
  158. };
  159. };
  160. export function scrollTopTimeline(timeline, top) {
  161. return {
  162. type: TIMELINE_SCROLL_TOP,
  163. timeline,
  164. top,
  165. };
  166. };
  167. export function connectTimeline(timeline) {
  168. return {
  169. type: TIMELINE_CONNECT,
  170. timeline,
  171. };
  172. };
  173. export function disconnectTimeline(timeline) {
  174. return {
  175. type: TIMELINE_DISCONNECT,
  176. timeline,
  177. };
  178. };