settings.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import { pluck, distinctUntilChanged } from "rxjs/operators"
  2. import has from "lodash/has"
  3. import { Observable } from "rxjs"
  4. import { Ref } from "@nuxtjs/composition-api"
  5. import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
  6. import type { KeysMatching } from "~/types/ts-utils"
  7. import { useStream } from "~/helpers/utils/composables"
  8. export const HoppBgColors = ["system", "light", "dark", "black"] as const
  9. export type HoppBgColor = typeof HoppBgColors[number]
  10. export const HoppAccentColors = [
  11. "green",
  12. "teal",
  13. "blue",
  14. "indigo",
  15. "purple",
  16. "yellow",
  17. "orange",
  18. "red",
  19. "pink",
  20. ] as const
  21. export type HoppAccentColor = typeof HoppAccentColors[number]
  22. export const HoppFontSizes = ["small", "medium", "large"] as const
  23. export type HoppFontSize = typeof HoppFontSizes[number]
  24. export type SettingsType = {
  25. syncCollections: boolean
  26. syncHistory: boolean
  27. syncEnvironments: boolean
  28. PROXY_ENABLED: boolean
  29. PROXY_URL: string
  30. PROXY_KEY: string
  31. EXTENSIONS_ENABLED: boolean
  32. EXPERIMENTAL_URL_BAR_ENABLED: boolean
  33. URL_EXCLUDES: {
  34. auth: boolean
  35. httpUser: boolean
  36. httpPassword: boolean
  37. bearerToken: boolean
  38. oauth2Token: boolean
  39. }
  40. THEME_COLOR: HoppAccentColor
  41. BG_COLOR: HoppBgColor
  42. TELEMETRY_ENABLED: boolean
  43. LEFT_SIDEBAR: boolean
  44. RIGHT_SIDEBAR: boolean
  45. ZEN_MODE: boolean
  46. FONT_SIZE: HoppFontSize
  47. COLUMN_LAYOUT: boolean
  48. }
  49. export const defaultSettings: SettingsType = {
  50. syncCollections: true,
  51. syncHistory: true,
  52. syncEnvironments: true,
  53. PROXY_ENABLED: false,
  54. PROXY_URL: "https://proxy.hoppscotch.io/",
  55. PROXY_KEY: "",
  56. EXTENSIONS_ENABLED: true,
  57. EXPERIMENTAL_URL_BAR_ENABLED: true,
  58. URL_EXCLUDES: {
  59. auth: true,
  60. httpUser: true,
  61. httpPassword: true,
  62. bearerToken: true,
  63. oauth2Token: true,
  64. },
  65. THEME_COLOR: "indigo",
  66. BG_COLOR: "system",
  67. TELEMETRY_ENABLED: true,
  68. LEFT_SIDEBAR: true,
  69. RIGHT_SIDEBAR: true,
  70. ZEN_MODE: false,
  71. FONT_SIZE: "small",
  72. COLUMN_LAYOUT: true,
  73. }
  74. const validKeys = Object.keys(defaultSettings)
  75. const dispatchers = defineDispatchers({
  76. bulkApplySettings(
  77. _currentState: SettingsType,
  78. payload: Partial<SettingsType>
  79. ) {
  80. return payload
  81. },
  82. toggleSetting(
  83. currentState: SettingsType,
  84. { settingKey }: { settingKey: KeysMatching<SettingsType, boolean> }
  85. ) {
  86. if (!has(currentState, settingKey)) {
  87. console.log(
  88. `Toggling of a non-existent setting key '${settingKey}' ignored.`
  89. )
  90. return {}
  91. }
  92. const result: Partial<SettingsType> = {}
  93. result[settingKey] = !currentState[settingKey]
  94. return result
  95. },
  96. applySetting<K extends keyof SettingsType>(
  97. _currentState: SettingsType,
  98. { settingKey, value }: { settingKey: K; value: SettingsType[K] }
  99. ) {
  100. if (!validKeys.includes(settingKey)) {
  101. console.log(
  102. `Ignoring non-existent setting key '${settingKey}' assignment`
  103. )
  104. return {}
  105. }
  106. const result: Partial<SettingsType> = {}
  107. result[settingKey] = value
  108. return result
  109. },
  110. })
  111. export const settingsStore = new DispatchingStore(defaultSettings, dispatchers)
  112. /**
  113. * An observable value to make avail all the state information at once
  114. */
  115. export const settings$ = settingsStore.subject$.asObservable()
  116. export function getSettingSubject<K extends keyof SettingsType>(
  117. settingKey: K
  118. ): Observable<SettingsType[K]> {
  119. return settingsStore.subject$.pipe(pluck(settingKey), distinctUntilChanged())
  120. }
  121. export function bulkApplySettings(settingsObj: Partial<SettingsType>) {
  122. settingsStore.dispatch({
  123. dispatcher: "bulkApplySettings",
  124. payload: settingsObj,
  125. })
  126. }
  127. export function toggleSetting(settingKey: KeysMatching<SettingsType, boolean>) {
  128. settingsStore.dispatch({
  129. dispatcher: "toggleSetting",
  130. payload: {
  131. settingKey,
  132. },
  133. })
  134. }
  135. export function applySetting<K extends keyof SettingsType>(
  136. settingKey: K,
  137. value: SettingsType[K]
  138. ) {
  139. settingsStore.dispatch({
  140. dispatcher: "applySetting",
  141. payload: {
  142. settingKey,
  143. value,
  144. },
  145. })
  146. }
  147. export function useSetting<K extends keyof SettingsType>(
  148. settingKey: K
  149. ): Ref<SettingsType[K]> {
  150. return useStream(
  151. settingsStore.subject$.pipe(pluck(settingKey), distinctUntilChanged()),
  152. settingsStore.value[settingKey],
  153. (value: SettingsType[K]) => {
  154. settingsStore.dispatch({
  155. dispatcher: "applySetting",
  156. payload: {
  157. settingKey,
  158. value,
  159. },
  160. })
  161. }
  162. )
  163. }