194 lines
5.1 KiB
TypeScript
194 lines
5.1 KiB
TypeScript
import {
|
|
collection,
|
|
doc,
|
|
getFirestore,
|
|
onSnapshot,
|
|
setDoc,
|
|
} from "firebase/firestore"
|
|
import {
|
|
translateToNewRESTCollection,
|
|
translateToNewGQLCollection,
|
|
} from "@hoppscotch/data"
|
|
|
|
import { def as platformAuth } from "./firebase/auth"
|
|
|
|
import {
|
|
restCollections$,
|
|
graphqlCollections$,
|
|
setRESTCollections,
|
|
setGraphqlCollections,
|
|
} from "@hoppscotch/common/newstore/collections"
|
|
|
|
import {
|
|
getSettingSubject,
|
|
settingsStore,
|
|
} from "@hoppscotch/common/newstore/settings"
|
|
|
|
import { CollectionsPlatformDef } from "@hoppscotch/common/platform/collections"
|
|
|
|
type CollectionFlags = "collectionsGraphql" | "collections"
|
|
|
|
/**
|
|
* Whether the collections are loaded. If this is set to true
|
|
* Updates to the collections store are written into firebase.
|
|
*
|
|
* If you have want to update the store and not fire the store update
|
|
* subscription, set this variable to false, do the update and then
|
|
* set it to true
|
|
*/
|
|
let loadedRESTCollections = false
|
|
|
|
/**
|
|
* Whether the collections are loaded. If this is set to true
|
|
* Updates to the collections store are written into firebase.
|
|
*
|
|
* If you have want to update the store and not fire the store update
|
|
* subscription, set this variable to false, do the update and then
|
|
* set it to true
|
|
*/
|
|
let loadedGraphqlCollections = false
|
|
|
|
async function writeCollections(collection: any[], flag: CollectionFlags) {
|
|
const currentUser = platformAuth.getCurrentUser()
|
|
|
|
if (currentUser === null)
|
|
throw new Error("User not logged in to write collections")
|
|
|
|
const cl = {
|
|
updatedOn: new Date(),
|
|
author: currentUser.uid,
|
|
author_name: currentUser.displayName,
|
|
author_image: currentUser.photoURL,
|
|
collection,
|
|
}
|
|
|
|
try {
|
|
await setDoc(
|
|
doc(getFirestore(), "users", currentUser.uid, flag, "sync"),
|
|
cl
|
|
)
|
|
} catch (e) {
|
|
console.error("error updating", cl, e)
|
|
throw e
|
|
}
|
|
}
|
|
|
|
function initCollectionsSync() {
|
|
const currentUser$ = platformAuth.getCurrentUserStream()
|
|
|
|
const restCollSub = restCollections$.subscribe((collections) => {
|
|
const currentUser = platformAuth.getCurrentUser()
|
|
|
|
if (
|
|
loadedRESTCollections &&
|
|
currentUser &&
|
|
settingsStore.value.syncCollections
|
|
) {
|
|
writeCollections(collections, "collections")
|
|
}
|
|
})
|
|
|
|
const gqlCollSub = graphqlCollections$.subscribe((collections) => {
|
|
const currentUser = platformAuth.getCurrentUser()
|
|
|
|
if (
|
|
loadedGraphqlCollections &&
|
|
currentUser &&
|
|
settingsStore.value.syncCollections
|
|
) {
|
|
writeCollections(collections, "collectionsGraphql")
|
|
}
|
|
})
|
|
|
|
let restSnapshotStop: (() => void) | null = null
|
|
let graphqlSnapshotStop: (() => void) | null = null
|
|
|
|
const currentUserSub = currentUser$.subscribe((user) => {
|
|
if (!user) {
|
|
if (restSnapshotStop) {
|
|
restSnapshotStop()
|
|
restSnapshotStop = null
|
|
}
|
|
|
|
if (graphqlSnapshotStop) {
|
|
graphqlSnapshotStop()
|
|
graphqlSnapshotStop = null
|
|
}
|
|
} else {
|
|
restSnapshotStop = onSnapshot(
|
|
collection(getFirestore(), "users", user.uid, "collections"),
|
|
(collectionsRef) => {
|
|
const collections: any[] = []
|
|
collectionsRef.forEach((doc) => {
|
|
const collection = doc.data()
|
|
collection.id = doc.id
|
|
collections.push(collection)
|
|
})
|
|
|
|
// Prevent infinite ping-pong of updates
|
|
loadedRESTCollections = false
|
|
|
|
// TODO: Wth is with collections[0]
|
|
if (collections.length > 0 && settingsStore.value.syncCollections) {
|
|
setRESTCollections(
|
|
(collections[0].collection ?? []).map(
|
|
translateToNewRESTCollection
|
|
)
|
|
)
|
|
}
|
|
|
|
loadedRESTCollections = true
|
|
}
|
|
)
|
|
|
|
graphqlSnapshotStop = onSnapshot(
|
|
collection(getFirestore(), "users", user.uid, "collectionsGraphql"),
|
|
(collectionsRef) => {
|
|
const collections: any[] = []
|
|
collectionsRef.forEach((doc) => {
|
|
const collection = doc.data()
|
|
collection.id = doc.id
|
|
collections.push(collection)
|
|
})
|
|
|
|
// Prevent infinite ping-pong of updates
|
|
loadedGraphqlCollections = false
|
|
|
|
// TODO: Wth is with collections[0]
|
|
if (collections.length > 0 && settingsStore.value.syncCollections) {
|
|
setGraphqlCollections(
|
|
(collections[0].collection ?? []).map(translateToNewGQLCollection)
|
|
)
|
|
}
|
|
|
|
loadedGraphqlCollections = true
|
|
}
|
|
)
|
|
}
|
|
})
|
|
|
|
let oldSyncStatus = settingsStore.value.syncCollections
|
|
|
|
const syncStop = getSettingSubject("syncCollections").subscribe(
|
|
(newStatus) => {
|
|
if (oldSyncStatus === true && newStatus === false) {
|
|
restSnapshotStop?.()
|
|
graphqlSnapshotStop?.()
|
|
|
|
oldSyncStatus = newStatus
|
|
} else if (oldSyncStatus === false && newStatus === true) {
|
|
syncStop.unsubscribe()
|
|
restCollSub.unsubscribe()
|
|
gqlCollSub.unsubscribe()
|
|
currentUserSub.unsubscribe()
|
|
|
|
initCollectionsSync()
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
export const def: CollectionsPlatformDef = {
|
|
initCollectionsSync,
|
|
}
|