collections.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import {
  2. collection,
  3. doc,
  4. getFirestore,
  5. onSnapshot,
  6. setDoc,
  7. } from "firebase/firestore"
  8. import {
  9. translateToNewRESTCollection,
  10. translateToNewGQLCollection,
  11. } from "@hoppscotch/data"
  12. import { currentUser$ } from "./auth"
  13. import {
  14. restCollections$,
  15. graphqlCollections$,
  16. setRESTCollections,
  17. setGraphqlCollections,
  18. } from "~/newstore/collections"
  19. import { settingsStore } from "~/newstore/settings"
  20. type CollectionFlags = "collectionsGraphql" | "collections"
  21. /**
  22. * Whether the collections are loaded. If this is set to true
  23. * Updates to the collections store are written into firebase.
  24. *
  25. * If you have want to update the store and not fire the store update
  26. * subscription, set this variable to false, do the update and then
  27. * set it to true
  28. */
  29. let loadedRESTCollections = false
  30. /**
  31. * Whether the collections are loaded. If this is set to true
  32. * Updates to the collections store are written into firebase.
  33. *
  34. * If you have want to update the store and not fire the store update
  35. * subscription, set this variable to false, do the update and then
  36. * set it to true
  37. */
  38. let loadedGraphqlCollections = false
  39. export async function writeCollections(
  40. collection: any[],
  41. flag: CollectionFlags
  42. ) {
  43. if (currentUser$.value === null)
  44. throw new Error("User not logged in to write collections")
  45. const cl = {
  46. updatedOn: new Date(),
  47. author: currentUser$.value.uid,
  48. author_name: currentUser$.value.displayName,
  49. author_image: currentUser$.value.photoURL,
  50. collection,
  51. }
  52. try {
  53. await setDoc(
  54. doc(getFirestore(), "users", currentUser$.value.uid, flag, "sync"),
  55. cl
  56. )
  57. } catch (e) {
  58. console.error("error updating", cl, e)
  59. throw e
  60. }
  61. }
  62. export function initCollections() {
  63. restCollections$.subscribe((collections) => {
  64. if (
  65. loadedRESTCollections &&
  66. currentUser$.value &&
  67. settingsStore.value.syncCollections
  68. ) {
  69. writeCollections(collections, "collections")
  70. }
  71. })
  72. graphqlCollections$.subscribe((collections) => {
  73. if (
  74. loadedGraphqlCollections &&
  75. currentUser$.value &&
  76. settingsStore.value.syncCollections
  77. ) {
  78. writeCollections(collections, "collectionsGraphql")
  79. }
  80. })
  81. let restSnapshotStop: (() => void) | null = null
  82. let graphqlSnapshotStop: (() => void) | null = null
  83. currentUser$.subscribe((user) => {
  84. if (!user) {
  85. if (restSnapshotStop) {
  86. restSnapshotStop()
  87. restSnapshotStop = null
  88. }
  89. if (graphqlSnapshotStop) {
  90. graphqlSnapshotStop()
  91. graphqlSnapshotStop = null
  92. }
  93. } else {
  94. restSnapshotStop = onSnapshot(
  95. collection(getFirestore(), "users", user.uid, "collections"),
  96. (collectionsRef) => {
  97. const collections: any[] = []
  98. collectionsRef.forEach((doc) => {
  99. const collection = doc.data()
  100. collection.id = doc.id
  101. collections.push(collection)
  102. })
  103. // Prevent infinite ping-pong of updates
  104. loadedRESTCollections = false
  105. // TODO: Wth is with collections[0]
  106. if (collections.length > 0) {
  107. setRESTCollections(
  108. (collections[0].collection ?? []).map(
  109. translateToNewRESTCollection
  110. )
  111. )
  112. }
  113. loadedRESTCollections = true
  114. }
  115. )
  116. graphqlSnapshotStop = onSnapshot(
  117. collection(getFirestore(), "users", user.uid, "collectionsGraphql"),
  118. (collectionsRef) => {
  119. const collections: any[] = []
  120. collectionsRef.forEach((doc) => {
  121. const collection = doc.data()
  122. collection.id = doc.id
  123. collections.push(collection)
  124. })
  125. // Prevent infinite ping-pong of updates
  126. loadedGraphqlCollections = false
  127. // TODO: Wth is with collections[0]
  128. if (collections.length > 0) {
  129. setGraphqlCollections(
  130. (collections[0].collection ?? []).map(translateToNewGQLCollection)
  131. )
  132. }
  133. loadedGraphqlCollections = true
  134. }
  135. )
  136. }
  137. })
  138. }