chore: move collections sync system to platform (#2940)
This commit is contained in:
193
packages/hoppscotch-web/src/collections.ts
Normal file
193
packages/hoppscotch-web/src/collections.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
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,
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { createHoppApp } from "@hoppscotch/common"
|
||||
import { def as authDef } from "./firebase/auth"
|
||||
import { def as envDef } from "./environments"
|
||||
import { def as collectionsDef } from "./collections"
|
||||
|
||||
createHoppApp("#app", {
|
||||
auth: authDef,
|
||||
sync: {
|
||||
environments: envDef,
|
||||
collections: collectionsDef,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user