~/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 @@