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

188 lines
5.2 KiB

8 years ago
8 years ago
8 years ago
  1. import api, { getLinks } from '../api'
  2. import Immutable 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 function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
  15. return {
  16. type: TIMELINE_REFRESH_SUCCESS,
  17. timeline,
  18. statuses,
  19. skipLoading,
  20. next
  21. };
  22. };
  23. export function updateTimeline(timeline, status) {
  24. return (dispatch, getState) => {
  25. const references = status.reblog ? getState().get('statuses').filter((item, itemId) => (itemId === status.reblog.id || item.get('reblog') === status.reblog.id)).map((_, itemId) => itemId) : [];
  26. dispatch({
  27. type: TIMELINE_UPDATE,
  28. timeline,
  29. status,
  30. references
  31. });
  32. };
  33. };
  34. export function deleteFromTimelines(id) {
  35. return (dispatch, getState) => {
  36. const accountId = getState().getIn(['statuses', id, 'account']);
  37. const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => [status.get('id'), status.get('account')]);
  38. const reblogOf = getState().getIn(['statuses', id, 'reblog'], null);
  39. dispatch({
  40. type: TIMELINE_DELETE,
  41. id,
  42. accountId,
  43. references,
  44. reblogOf
  45. });
  46. };
  47. };
  48. export function refreshTimelineRequest(timeline, id, skipLoading) {
  49. return {
  50. type: TIMELINE_REFRESH_REQUEST,
  51. timeline,
  52. id,
  53. skipLoading
  54. };
  55. };
  56. export function refreshTimeline(timeline, id = null) {
  57. return function (dispatch, getState) {
  58. if (getState().getIn(['timelines', timeline, 'isLoading'])) {
  59. return;
  60. }
  61. const ids = getState().getIn(['timelines', timeline, 'items'], Immutable.List());
  62. const newestId = ids.size > 0 ? ids.first() : null;
  63. let params = getState().getIn(['timelines', timeline, 'params'], {});
  64. const path = getState().getIn(['timelines', timeline, 'path'])(id);
  65. let skipLoading = false;
  66. if (newestId !== null && getState().getIn(['timelines', timeline, 'loaded']) && (id === null || getState().getIn(['timelines', timeline, 'id']) === id)) {
  67. if (id === null && getState().getIn(['timelines', timeline, 'online'])) {
  68. // Skip refreshing when timeline is live anyway
  69. return;
  70. }
  71. params = { ...params, since_id: newestId };
  72. skipLoading = true;
  73. } else if (getState().getIn(['timelines', timeline, 'loaded'])) {
  74. skipLoading = true;
  75. }
  76. dispatch(refreshTimelineRequest(timeline, id, skipLoading));
  77. api(getState).get(path, { params }).then(response => {
  78. const next = getLinks(response).refs.find(link => link.rel === 'next');
  79. dispatch(refreshTimelineSuccess(timeline, response.data, skipLoading, next ? next.uri : null));
  80. }).catch(error => {
  81. dispatch(refreshTimelineFail(timeline, error, skipLoading));
  82. });
  83. };
  84. };
  85. export function refreshTimelineFail(timeline, error, skipLoading) {
  86. return {
  87. type: TIMELINE_REFRESH_FAIL,
  88. timeline,
  89. error,
  90. skipLoading
  91. };
  92. };
  93. export function expandTimeline(timeline) {
  94. return (dispatch, getState) => {
  95. if (getState().getIn(['timelines', timeline, 'isLoading'])) {
  96. return;
  97. }
  98. if (getState().getIn(['timelines', timeline, 'items']).size === 0) {
  99. return;
  100. }
  101. const path = getState().getIn(['timelines', timeline, 'path'])(getState().getIn(['timelines', timeline, 'id']));
  102. const params = getState().getIn(['timelines', timeline, 'params'], {});
  103. const lastId = getState().getIn(['timelines', timeline, 'items']).last();
  104. dispatch(expandTimelineRequest(timeline));
  105. api(getState).get(path, {
  106. params: {
  107. ...params,
  108. max_id: lastId,
  109. limit: 10
  110. }
  111. }).then(response => {
  112. const next = getLinks(response).refs.find(link => link.rel === 'next');
  113. dispatch(expandTimelineSuccess(timeline, response.data, next ? next.uri : null));
  114. }).catch(error => {
  115. dispatch(expandTimelineFail(timeline, error));
  116. });
  117. };
  118. };
  119. export function expandTimelineRequest(timeline) {
  120. return {
  121. type: TIMELINE_EXPAND_REQUEST,
  122. timeline
  123. };
  124. };
  125. export function expandTimelineSuccess(timeline, statuses, next) {
  126. return {
  127. type: TIMELINE_EXPAND_SUCCESS,
  128. timeline,
  129. statuses,
  130. next
  131. };
  132. };
  133. export function expandTimelineFail(timeline, error) {
  134. return {
  135. type: TIMELINE_EXPAND_FAIL,
  136. timeline,
  137. error
  138. };
  139. };
  140. export function scrollTopTimeline(timeline, top) {
  141. return {
  142. type: TIMELINE_SCROLL_TOP,
  143. timeline,
  144. top
  145. };
  146. };
  147. export function connectTimeline(timeline) {
  148. return {
  149. type: TIMELINE_CONNECT,
  150. timeline
  151. };
  152. };
  153. export function disconnectTimeline(timeline) {
  154. return {
  155. type: TIMELINE_DISCONNECT,
  156. timeline
  157. };
  158. };