timeline_fetcher.service.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { camelCase } from 'lodash'
  2. import apiService from '../api/api.service.js'
  3. import { promiseInterval } from '../promise_interval/promise_interval.js'
  4. const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => {
  5. const ccTimeline = camelCase(timeline)
  6. store.dispatch('addNewStatuses', {
  7. timeline: ccTimeline,
  8. userId,
  9. statuses,
  10. showImmediately,
  11. pagination
  12. })
  13. }
  14. const fetchAndUpdate = ({
  15. store,
  16. credentials,
  17. timeline = 'friends',
  18. older = false,
  19. showImmediately = false,
  20. userId = false,
  21. tag = false,
  22. until,
  23. since
  24. }) => {
  25. const args = { timeline, credentials }
  26. const rootState = store.rootState || store.state
  27. const { getters } = store
  28. const timelineData = rootState.statuses.timelines[camelCase(timeline)]
  29. const { hideMutedPosts, replyVisibility } = getters.mergedConfig
  30. const loggedIn = !!rootState.users.currentUser
  31. if (older) {
  32. args['until'] = until || timelineData.minId
  33. } else {
  34. if (since === undefined) {
  35. args['since'] = timelineData.maxId
  36. } else if (since !== null) {
  37. args['since'] = since
  38. }
  39. }
  40. args['userId'] = userId
  41. args['tag'] = tag
  42. args['withMuted'] = !hideMutedPosts
  43. if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
  44. args['replyVisibility'] = replyVisibility
  45. }
  46. const numStatusesBeforeFetch = timelineData.statuses.length
  47. return apiService.fetchTimeline(args)
  48. .then(response => {
  49. if (response.errors) {
  50. throw new Error(`${response.status} ${response.statusText}`)
  51. }
  52. const { data: statuses, pagination } = response
  53. if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) {
  54. store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId })
  55. }
  56. update({ store, statuses, timeline, showImmediately, userId, pagination })
  57. return { statuses, pagination }
  58. })
  59. .catch((error) => {
  60. store.dispatch('pushGlobalNotice', {
  61. level: 'error',
  62. messageKey: 'timeline.error',
  63. messageArgs: [error.message],
  64. timeout: 5000
  65. })
  66. })
  67. }
  68. const startFetching = ({ timeline = 'friends', credentials, store, userId = false, tag = false }) => {
  69. const rootState = store.rootState || store.state
  70. const timelineData = rootState.statuses.timelines[camelCase(timeline)]
  71. const showImmediately = timelineData.visibleStatuses.length === 0
  72. timelineData.userId = userId
  73. fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, tag })
  74. const boundFetchAndUpdate = () =>
  75. fetchAndUpdate({ timeline, credentials, store, userId, tag })
  76. return promiseInterval(boundFetchAndUpdate, 10000)
  77. }
  78. const timelineFetcher = {
  79. fetchAndUpdate,
  80. startFetching
  81. }
  82. export default timelineFetcher