settings.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {
  2. collection,
  3. doc,
  4. getFirestore,
  5. onSnapshot,
  6. setDoc,
  7. } from "@firebase/firestore"
  8. import { currentUser$ } from "./auth"
  9. import { applySetting, settingsStore, SettingsType } from "~/newstore/settings"
  10. /**
  11. * Used locally to prevent infinite loop when settings sync update
  12. * is applied to the store which then fires the store sync listener.
  13. * When you want to update settings and not want to fire the update listener,
  14. * set this to true and then set it back to false once it is done
  15. */
  16. let loadedSettings = false
  17. /**
  18. * Write Transform
  19. */
  20. async function writeSettings(setting: string, value: any) {
  21. if (currentUser$.value === null)
  22. throw new Error("Cannot write setting, user not signed in")
  23. const st = {
  24. updatedOn: new Date(),
  25. author: currentUser$.value.uid,
  26. author_name: currentUser$.value.displayName,
  27. author_image: currentUser$.value.photoURL,
  28. name: setting,
  29. value,
  30. }
  31. try {
  32. await setDoc(
  33. doc(getFirestore(), "users", currentUser$.value.uid, "settings", setting),
  34. st
  35. )
  36. } catch (e) {
  37. console.error("error updating", st, e)
  38. throw e
  39. }
  40. }
  41. export function initSettings() {
  42. settingsStore.dispatches$.subscribe((dispatch) => {
  43. if (currentUser$.value && loadedSettings) {
  44. if (dispatch.dispatcher === "bulkApplySettings") {
  45. Object.keys(dispatch.payload).forEach((key) => {
  46. writeSettings(key, dispatch.payload[key])
  47. })
  48. } else {
  49. writeSettings(
  50. dispatch.payload.settingKey,
  51. settingsStore.value[dispatch.payload.settingKey as keyof SettingsType]
  52. )
  53. }
  54. }
  55. })
  56. let snapshotStop: (() => void) | null = null
  57. // Subscribe and unsubscribe event listeners
  58. currentUser$.subscribe((user) => {
  59. if (!user && snapshotStop) {
  60. // User logged out
  61. snapshotStop()
  62. snapshotStop = null
  63. } else if (user) {
  64. snapshotStop = onSnapshot(
  65. collection(getFirestore(), "users", user.uid, "settings"),
  66. (settingsRef) => {
  67. const settings: any[] = []
  68. settingsRef.forEach((doc) => {
  69. const setting = doc.data()
  70. setting.id = doc.id
  71. settings.push(setting)
  72. })
  73. loadedSettings = false
  74. settings.forEach((e) => {
  75. if (e && e.name && e.value != null) {
  76. applySetting(e.name, e.value)
  77. }
  78. })
  79. loadedSettings = true
  80. }
  81. )
  82. }
  83. })
  84. }