import { collection, doc, getFirestore, onSnapshot, setDoc, } from "firebase/firestore" import { currentUser$ } from "./auth" import { Environment, environments$, globalEnv$, replaceEnvironments, setGlobalEnvVariables, } from "~/newstore/environments" import { settingsStore } from "~/newstore/settings" /** * Used locally to prevent infinite loop when environment sync update * is applied to the store which then fires the store sync listener. * When you want to update environments and not want to fire the update listener, * set this to true and then set it back to false once it is done */ let loadedEnvironments = false /** * Used locally to prevent infinite loop when global env sync update * is applied to the store which then fires the store sync listener. * When you want to update global env and not want to fire the update listener, * set this to true and then set it back to false once it is done */ let loadedGlobals = true async function writeEnvironments(environment: Environment[]) { if (currentUser$.value == null) throw new Error("Cannot write environments when signed out") const ev = { updatedOn: new Date(), author: currentUser$.value.uid, author_name: currentUser$.value.displayName, author_image: currentUser$.value.photoURL, environment, } try { await setDoc( doc( getFirestore(), "users", currentUser$.value.uid, "envrionments", "sync" ), ev ) } catch (e) { console.error("error updating", ev, e) throw e } } async function writeGlobalEnvironment(variables: Environment["variables"]) { if (currentUser$.value == null) throw new Error("Cannot write global environment when signed out") const ev = { updatedOn: new Date(), author: currentUser$.value.uid, author_name: currentUser$.value.displayName, author_image: currentUser$.value.photoURL, variables, } try { await setDoc( doc(getFirestore(), "users", currentUser$.value.uid, "globalEnv", "sync"), ev ) } catch (e) { console.error("error updating", ev, e) throw e } } export function initEnvironments() { environments$.subscribe((envs) => { if ( currentUser$.value && settingsStore.value.syncEnvironments && loadedEnvironments ) { writeEnvironments(envs) } }) globalEnv$.subscribe((vars) => { if ( currentUser$.value && settingsStore.value.syncEnvironments && loadedGlobals ) { writeGlobalEnvironment(vars) } }) let envSnapshotStop: (() => void) | null = null let globalsSnapshotStop: (() => void) | null = null currentUser$.subscribe((user) => { if (!user) { // User logged out, clean up snapshot listener if (envSnapshotStop) { envSnapshotStop() envSnapshotStop = null } if (globalsSnapshotStop) { globalsSnapshotStop() globalsSnapshotStop = null } } else if (user) { envSnapshotStop = onSnapshot( collection(getFirestore(), "users", user.uid, "environments"), (environmentsRef) => { const environments: any[] = [] environmentsRef.forEach((doc) => { const environment = doc.data() environment.id = doc.id environments.push(environment) }) loadedEnvironments = false if (environments.length > 0) { replaceEnvironments(environments[0].environment) } loadedEnvironments = true } ) globalsSnapshotStop = onSnapshot( collection(getFirestore(), "users", user.uid, "globalEnv"), (globalsRef) => { if (globalsRef.docs.length === 0) { loadedGlobals = true return } const doc = globalsRef.docs[0].data() loadedGlobals = false setGlobalEnvVariables(doc.variables) loadedGlobals = true } ) } }) }