index.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import Vuex from 'vuex'
  2. import md5 from 'md5'
  3. import slugify from 'slugify'
  4. import db from '~/plugins/firestore'
  5. import { saveUserData, clearUserData } from '~/utils'
  6. import defaultImage from '~/assets/default-image.jpg'
  7. const createStore = () => {
  8. return new Vuex.Store({
  9. state: {
  10. headlines: [],
  11. headline: null,
  12. feed: [],
  13. loading: false,
  14. category: '',
  15. token: null,
  16. country: 'us',
  17. user: null,
  18. source: ''
  19. },
  20. mutations: {
  21. setHeadLines (state, headlines) {
  22. state.headlines = headlines
  23. },
  24. setHeadline (state, headline) {
  25. state.headline = headline
  26. },
  27. setLoading (state, loading) {
  28. state.loading = loading
  29. },
  30. setCategory (state, category) {
  31. state.category = category
  32. },
  33. setCountry (state, country) {
  34. state.country = country
  35. },
  36. setToken (state, token) {
  37. state.token = token
  38. },
  39. setUser (state, user) {
  40. state.user = user
  41. },
  42. setFeed (state, headlines) {
  43. state.feed = headlines
  44. },
  45. setSource (state, source) {
  46. state.source = source
  47. },
  48. clearToken: state => (state.token = null),
  49. clearUser: state => (state.user = null),
  50. clearFeed: state => (state.feed = [])
  51. },
  52. actions: {
  53. async loadHeadLines ({ commit }, apiUrl) {
  54. commit('setLoading', true)
  55. const { articles } = await this.$axios.$get(apiUrl)
  56. const headlines = articles.map((article) => {
  57. const slug = slugify(article.title, {
  58. replacement: '-',
  59. remove: /[^a-zA-Z0-9 -]/g
  60. })
  61. if (!article.urlToImage) {
  62. article.urlToImage = defaultImage
  63. }
  64. const headline = { ...article, slug }
  65. return headline
  66. })
  67. commit('setLoading', false)
  68. commit('setHeadLines', headlines)
  69. },
  70. async authenticateUser ({ commit }, userPayload) {
  71. try {
  72. commit('setLoading', true)
  73. const autuUserData = await this.$axios.$post(
  74. `/${userPayload.action}/`,
  75. {
  76. email: userPayload.email,
  77. password: userPayload.password,
  78. resturnSecureToken: userPayload.resturnSecureToken
  79. }
  80. )
  81. let user
  82. if (userPayload.action === 'register') {
  83. const avatar = `http://gravatar.com/avatar/${md5(autuUserData.email)}?d=identicon`
  84. user = { email: autuUserData.email, avatar }
  85. await db
  86. .collection('users')
  87. .doc(userPayload.email)
  88. .set(user)
  89. } else {
  90. const loginRef = db.collection('users').doc(userPayload.email)
  91. const loggedInUser = await loginRef.get()
  92. user = loggedInUser.data()
  93. }
  94. // console.log(autuUserData)
  95. commit('setUser', user)
  96. commit('setToken', autuUserData.idToken)
  97. commit('setLoading', false)
  98. saveUserData(autuUserData, user)
  99. } catch (error) {
  100. // console.log(error)
  101. }
  102. },
  103. async loadHeadline ({ commit }, headlineSlug) {
  104. const headlineRef = db.collection('headlines').doc(headlineSlug)
  105. const commentsRef = db.collection(`headlines/${headlineSlug}/comments`).orderBy('likes', 'desc')
  106. let loadedHeadline = {}
  107. await headlineRef.get().then(async (doc) => {
  108. if (doc.exists) {
  109. loadedHeadline = doc.data()
  110. await commentsRef.get().then((querySnapshot) => {
  111. if (querySnapshot.empty) {
  112. commit('setHeadline', loadedHeadline)
  113. }
  114. // eslint-disable-next-line prefer-const
  115. let loadedComments = []
  116. querySnapshot.forEach((doc) => {
  117. loadedComments.push(doc.data())
  118. loadedHeadline.comments = loadedComments
  119. commit('setHeadline', loadedHeadline)
  120. })
  121. })
  122. // const headline = doc.data()
  123. // this.commit('setHeadline', headline)
  124. }
  125. })
  126. },
  127. async sendComment ({ commit, state }, comment) {
  128. const commentRef = db.collection(`headlines/${state.headline.slug}/comments`)
  129. commit('setLoading', true)
  130. await commentRef.doc(comment.id).set(comment)
  131. await commentRef.orderBy('likes', 'desc').get().then((querySnapshot) => {
  132. // eslint-disable-next-line prefer-const
  133. let comments = []
  134. querySnapshot.forEach((doc) => {
  135. comments.push(doc.data())
  136. const updateHeadline = { ...state.headline, comments }
  137. commit('setHeadline', updateHeadline)
  138. })
  139. })
  140. commit('setLoading', false)
  141. },
  142. async likeComment ({ state, commit }, commentId) {
  143. const commentsRef = db.collection(`headlines/${state.headline.slug}/comments`).orderBy('likes', 'desc')
  144. const likedCommentRef = db.collection('headlines').doc(state.headline.slug).collection('comments').doc(commentId)
  145. await likedCommentRef.get().then((doc) => {
  146. if (doc.exists) {
  147. const prevLikes = doc.data().likes
  148. const currentLikes = prevLikes + 1
  149. likedCommentRef.update({
  150. likes: currentLikes
  151. })
  152. }
  153. })
  154. await commentsRef.onSnapshot((querySnapshot) => {
  155. // eslint-disable-next-line prefer-const
  156. let loadedComments = []
  157. querySnapshot.forEach((doc) => {
  158. loadedComments.push(doc.data())
  159. const updateHeadline = {
  160. ...state.headline,
  161. comments: loadedComments
  162. }
  163. commit('setHeadline', updateHeadline)
  164. })
  165. })
  166. },
  167. async saveHeadline (context, headline) {
  168. const headlineRef = db.collection('headlines').doc(headline.slug)
  169. // eslint-disable-next-line no-unused-vars
  170. let headlineId
  171. await headlineRef.get().then((doc) => {
  172. if (doc.exists) {
  173. headlineId = doc.id
  174. }
  175. })
  176. if (!headlineId) {
  177. await headlineRef.set(headline)
  178. }
  179. },
  180. async removeHeadlineFromFeed ({ state }, headline) {
  181. const headlineRef = db.collection(`users/${state.user.email}/feed`).doc(headline.title)
  182. await headlineRef.delete()
  183. },
  184. async addHeadlineToFeed ({ state }, headline) {
  185. const feedRef = db.collection(`users/${state.user.email}/feed`).doc(headline.title)
  186. await feedRef.set(headline)
  187. },
  188. async loadUserFeed ({ state, commit }) {
  189. if (state.user) {
  190. const feedRef = db.collection(`users/${state.user.email}/feed`)
  191. await feedRef.onSnapshot((querySnapshot) => {
  192. // eslint-disable-next-line prefer-const
  193. let headlines = []
  194. querySnapshot.forEach((doc) => {
  195. headlines.push(doc.data())
  196. commit('setFeed', headlines)
  197. })
  198. if (querySnapshot.empty) {
  199. headlines = []
  200. commit('setFeed', headlines)
  201. }
  202. })
  203. }
  204. },
  205. setLogoutTimer ({ dispatch }, interval) {
  206. setTimeout(() => dispatch('logoutUser'), interval)
  207. },
  208. logoutUser ({ commit }) {
  209. commit('clearToken')
  210. commit('clearUser')
  211. commit('clearFeed')
  212. clearUserData()
  213. }
  214. },
  215. getters: {
  216. headlines: state => state.headlines,
  217. headline: state => state.headline,
  218. feed: state => state.feed,
  219. loading: state => state.loading,
  220. category: state => state.category,
  221. country: state => state.country,
  222. isAuthenticated: state => !!state.token,
  223. user: state => state.user,
  224. source: state => state.source
  225. }
  226. })
  227. }
  228. export default createStore