collections.ts 4.0 KB

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