Liu Song’s Projects


~/Projects/hoppscotch

git clone https://code.lsong.org/hoppscotch

Commit

Commit
7acde1c1747459515a377ca8742bef70abf9b5ab
Author
Andrew Bastin <[email protected]>
Date
2021-08-15 10:45:26 +0530 +0530
Diffstat
 helpers/fb/auth.ts | 36 +++++++++++++++++++
 helpers/fb/request.ts | 83 +++++++++++++++++++++++++++++++++++++++++++++
 pages/index.vue | 29 +++++++++++++++

feat: rest request sync with firestore


diff --git a/helpers/fb/auth.ts b/helpers/fb/auth.ts
index 6851d2dea76ef1470556368d5857568e74a5cbee..de51c5f365b77a1a3883594f87b5afc2363e290f 100644
--- a/helpers/fb/auth.ts
+++ b/helpers/fb/auth.ts
@@ -1,7 +1,17 @@
 import firebase from "firebase/app"
 import "firebase/firestore"
 import "firebase/auth"
+import firebase from "firebase/app"
 import { BehaviorSubject, Subject } from "rxjs"
+import "firebase/firestore"
+  BehaviorSubject,
+  distinctUntilChanged,
+  filter,
+  map,
+  Subject,
+  Subscription,
+} from "rxjs"
+import { onBeforeUnmount, onMounted } from "@nuxtjs/composition-api"
 
 export type HoppUser = firebase.User & {
   provider?: string
@@ -219,3 +229,29 @@     console.error("error updating", e)
     throw e
   }
 }
+
+/**
+ * A Vue composable function that is called when the auth status
+ * is being updated to being logged in (fired multiple times),
+ * this is also called on component mount if the login
+ * was already resolved before mount.
+ */
+export function onLoggedIn(exec: (user: HoppUser) => void) {
+  let sub: Subscription | null = null
+
+  onMounted(() => {
+    sub = currentUser$
+      .pipe(
+        map((user) => !!user), // Get a logged in status (true or false)
+        distinctUntilChanged(), // Don't propagate unless the status updates
+        filter((x) => x) // Don't propagate unless it is logged in
+      )
+      .subscribe(() => {
+        exec(currentUser$.value!)
+      })
+  })
+
+  onBeforeUnmount(() => {
+    sub?.unsubscribe()
+  })
+}




diff --git a/helpers/fb/request.ts b/helpers/fb/request.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f56996e8a075dbdd31fe5a17c1314a8dd073c214
--- /dev/null
+++ b/helpers/fb/request.ts
@@ -0,0 +1,83 @@
+import firebase from "firebase/app"
+import "firebase/firestore"
+import {
+  audit,
+  combineLatest,
+  distinctUntilChanged,
+  EMPTY,
+  from,
+  map,
+  Subscription,
+} from "rxjs"
+import {
+  HoppRESTRequest,
+  translateToNewRequest,
+} from "../types/HoppRESTRequest"
+import { currentUser$, HoppUser } from "./auth"
+import { restRequest$ } from "~/newstore/RESTSession"
+
+/**
+ * Writes a request to a user's firestore sync
+ *
+ * @param user The user to write to
+ * @param request The request to write to the request sync
+ */
+function writeCurrentRequest(user: HoppUser, request: HoppRESTRequest) {
+  return firebase
+    .firestore()
+    .collection("users")
+    .doc(user.uid)
+    .collection("requests")
+    .doc("rest")
+    .set(request)
+}
+
+/**
+ * Loads the synced request from the firestore sync
+ *
+ * @returns Fetched request object if exists else null
+ */
+export async function loadRequestFromSync(): Promise<HoppRESTRequest | null> {
+  const currentUser = currentUser$.value
+
+  if (!currentUser)
+    throw new Error("Cannot load request from sync without login")
+
+  const doc = await firebase
+    .firestore()
+    .collection("users")
+    .doc(currentUser.uid)
+    .collection("requests")
+    .doc("rest")
+    .get()
+
+  const data = doc.data()
+
+  if (!data) return null
+  else return translateToNewRequest(data)
+}
+
+/**
+ * Performs sync of the REST Request session with Firestore.
+ *
+ * @returns A subscription to the sync observable stream.
+ * Unsubscribe to stop syncing.
+ */
+export function startRequestSync(): Subscription {
+  const sub = combineLatest([
+    currentUser$,
+    restRequest$.pipe(distinctUntilChanged()),
+  ])
+    .pipe(
+      map(([user, request]) =>
+        user ? from(writeCurrentRequest(user, request)) : EMPTY
+      ),
+      audit((x) => x)
+    )
+    .subscribe(() => {
+      // NOTE: This subscription should be kept
+      console.log("synced request")
+    })
+
+  return sub
+}




diff --git a/pages/index.vue b/pages/index.vue
index 9f44dd8c83036547d7318724c88ff32c26a0723e..13dead1f68b89b959db6e7181b7c351243b20a65 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -77,6 +77,7 @@