index.js 7.6 KB

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