thread.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import AjaxErrorHandler from '../../assets/js/errorHandler'
  2. const state = {
  3. thread: '',
  4. threadId: undefined,
  5. posts: [],
  6. reply: {
  7. username: '',
  8. id: null
  9. },
  10. editor: {
  11. show: false,
  12. value: ''
  13. },
  14. loadingPosts: false,
  15. nextURL: '',
  16. previousURL: '',
  17. nextPostsCount: 10,
  18. previousPostsCount: 0
  19. }
  20. const getters = {
  21. sortedPosts (state) {
  22. return state.posts.sort((a, b) => {
  23. return new Date(a.createdAt) - new Date(b.createdAt)
  24. })
  25. }
  26. }
  27. const actions = {
  28. addPostAsync ({ state, commit, rootState }, vue) {
  29. var post = {
  30. content: state.editor.value,
  31. threadId: +vue.$route.params.id
  32. };
  33. if(state.reply.id) {
  34. post.replyingToId = state.reply.id;
  35. }
  36. vue.axios
  37. .post('/api/v1/post', post)
  38. .then(res => {
  39. commit('addPost', res.data);
  40. commit('addReplyBubble', res.data)
  41. commit('setThreadEditorValue', '');
  42. commit('setThreadEditorState', false);
  43. commit({
  44. type: 'setReply',
  45. username: '',
  46. id: ''
  47. });
  48. })
  49. .catch(AjaxErrorHandler(vue.$store))
  50. },
  51. loadInitialPostsAsync ({ state, commit, rootState }, vue) {
  52. let postNumber = vue.$route.params.post_number
  53. let apiURL = '/api/v1/thread/' + vue.$route.params.id
  54. if(postNumber !== undefined) {
  55. apiURL += '?postNumber=' + postNumber
  56. }
  57. vue.axios
  58. .get(apiURL)
  59. .then(res => {
  60. commit('setThread', res.data)
  61. commit('setNextURL', res.data.meta.nextURL)
  62. commit('setPreviousURL', res.data.meta.previousURL)
  63. commit('setNextURL', res.data.meta.nextURL)
  64. commit('setPreviousURL', res.data.meta.previousURL)
  65. commit('setPostCounts', res.data.meta)
  66. commit('setPosts', res.data.Posts)
  67. if(postNumber !== undefined) {
  68. vue.highlightPost(+postNumber)
  69. }
  70. }).catch(AjaxErrorHandler(vue.$store))
  71. },
  72. loadPostsAsync ({ state, commit, rootState }, { vue, previous }) {
  73. let URL
  74. if(previous) {
  75. commit('setLoadingPostsState', 'previous')
  76. URL = state.previousURL
  77. } else {
  78. commit('setLoadingPostsState', 'next')
  79. URL = state.nextURL
  80. }
  81. if(URL === null) {
  82. commit('setLoadingPostsState', false)
  83. } else {
  84. vue.axios
  85. .get(URL)
  86. .then(res => {
  87. let currentPostsIds = state.posts.map(p => p.id)
  88. let filteredPosts =
  89. res.data.Posts.filter(p => !currentPostsIds.includes(p.id))
  90. commit('setLoadingPostsState', false)
  91. if(previous) {
  92. let last = filteredPosts.slice(-1)[0]
  93. commit('prependPosts', filteredPosts)
  94. commit('setPreviousURL', res.data.meta.previousURL)
  95. if(last) {
  96. vue.scrollTo(last.postNumber)
  97. }
  98. } else {
  99. commit('addPost', filteredPosts)
  100. commit('setNextURL', res.data.meta.nextURL)
  101. }
  102. commit('setPostCounts', res.data.meta)
  103. })
  104. .catch((e) => {
  105. console.log(e)
  106. AjaxErrorHandler(vue.$store)
  107. })
  108. }
  109. },
  110. loadNewPostsSinceLoad ({ state, commit }, post) {
  111. if(state.nextPostsCount < 10) {
  112. let nextURL = state.nextURL
  113. let baseURL = '/api/v1/thread/' + state.threadId + '?limit=10&from='
  114. commit('incrementNextPostsCount')
  115. if(nextURL === null) {
  116. commit('setNextURL', baseURL + (post.postNumber-1))
  117. }
  118. }
  119. }
  120. }
  121. const mutations = {
  122. setReply (state, payload) {
  123. state.reply.username = payload.username;
  124. state.reply.id = payload.id;
  125. },
  126. addPost (state, post) {
  127. if(Array.isArray(post)) {
  128. state.posts.push(...post)
  129. } else {
  130. state.posts.push(post)
  131. }
  132. },
  133. prependPosts (state, posts) {
  134. state.posts.unshift(...posts)
  135. },
  136. addReplyBubble (state, post) {
  137. let repliedToPost = {}, index
  138. if(post.replyId) {
  139. state.posts.forEach((p, i) => {
  140. if(p.id === post.replyId) {
  141. index = i
  142. repliedToPost = p
  143. }
  144. })
  145. repliedToPost.Replies.push(post)
  146. state.posts.splice(index, 1, repliedToPost)
  147. }
  148. },
  149. setThreadEditorValue (state, value) {
  150. state.editor.value = value
  151. },
  152. setThreadEditorState (state, value) {
  153. state.editor.show = value
  154. },
  155. setLoadingPostsState (state, value) {
  156. state.loadingPosts = value
  157. },
  158. setPosts (state, value) {
  159. state.posts = value
  160. },
  161. setThread (state, obj) {
  162. state.thread = obj.name
  163. state.threadId = obj.id
  164. },
  165. setNextURL (state, URL) {
  166. state.nextURL = URL
  167. },
  168. setPreviousURL (state, URL) {
  169. state.previousURL = URL
  170. },
  171. setPostCounts (state, meta) {
  172. state.previousPostsCount = meta.previousPostsCount
  173. state.nextPostsCount = meta.nextPostsCount
  174. },
  175. incrementNextPostsCount (state) {
  176. state.nextPostsCount++
  177. }
  178. }
  179. export default {
  180. state,
  181. getters,
  182. actions,
  183. mutations
  184. }