Merge remote-tracking branch 'origin/main' into refactor/ui
This commit is contained in:
@@ -13,6 +13,7 @@ STORAGE_BUCKET=postwoman-api.appspot.com
|
|||||||
MESSAGING_SENDER_ID=421993993223
|
MESSAGING_SENDER_ID=421993993223
|
||||||
APP_ID=1:421993993223:web:ec0baa8ee8c02ffa1fc6a2
|
APP_ID=1:421993993223:web:ec0baa8ee8c02ffa1fc6a2
|
||||||
MEASUREMENT_ID=G-ERJ6025CEB
|
MEASUREMENT_ID=G-ERJ6025CEB
|
||||||
|
FB_MEASUREMENT_ID=G-BBJ3R80PJT
|
||||||
|
|
||||||
# Base URL
|
# Base URL
|
||||||
BASE_URL=https://hoppscotch.io
|
BASE_URL=https://hoppscotch.io
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
import { Splitpanes, Pane } from "splitpanes"
|
import { Splitpanes, Pane } from "splitpanes"
|
||||||
import Paho from "paho-mqtt"
|
import Paho from "paho-mqtt"
|
||||||
import debounce from "~/helpers/utils/debounce"
|
import debounce from "~/helpers/utils/debounce"
|
||||||
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Splitpanes, Pane },
|
components: { Splitpanes, Pane },
|
||||||
@@ -202,6 +203,10 @@ export default {
|
|||||||
})
|
})
|
||||||
this.client.onConnectionLost = this.onConnectionLost
|
this.client.onConnectionLost = this.onConnectionLost
|
||||||
this.client.onMessageArrived = this.onMessageArrived
|
this.client.onMessageArrived = this.onMessageArrived
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "mqtt",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
onConnectionFailure() {
|
onConnectionFailure() {
|
||||||
this.connectionState = false
|
this.connectionState = false
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ import { Splitpanes, Pane } from "splitpanes"
|
|||||||
import { io as Client } from "socket.io-client"
|
import { io as Client } from "socket.io-client"
|
||||||
import wildcard from "socketio-wildcard"
|
import wildcard from "socketio-wildcard"
|
||||||
import debounce from "~/helpers/utils/debounce"
|
import debounce from "~/helpers/utils/debounce"
|
||||||
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Splitpanes, Pane },
|
components: { Splitpanes, Pane },
|
||||||
@@ -275,6 +276,10 @@ export default {
|
|||||||
icon: "error",
|
icon: "error",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "socketio",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
disconnect() {
|
disconnect() {
|
||||||
this.io.close()
|
this.io.close()
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Splitpanes, Pane } from "splitpanes"
|
import { Splitpanes, Pane } from "splitpanes"
|
||||||
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
import debounce from "~/helpers/utils/debounce"
|
import debounce from "~/helpers/utils/debounce"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -164,6 +165,10 @@ export default {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "mqtt",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleSSEError(error) {
|
handleSSEError(error) {
|
||||||
this.stop()
|
this.stop()
|
||||||
|
|||||||
@@ -169,6 +169,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Splitpanes, Pane } from "splitpanes"
|
import { Splitpanes, Pane } from "splitpanes"
|
||||||
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
import debounce from "~/helpers/utils/debounce"
|
import debounce from "~/helpers/utils/debounce"
|
||||||
import "splitpanes/dist/splitpanes.css"
|
import "splitpanes/dist/splitpanes.css"
|
||||||
|
|
||||||
@@ -285,6 +286,10 @@ export default {
|
|||||||
icon: "error",
|
icon: "error",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "wss",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
disconnect() {
|
disconnect() {
|
||||||
if (this.socket) {
|
if (this.socket) {
|
||||||
|
|||||||
@@ -21,36 +21,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { getLocalConfig, setLocalConfig } from "~/newstore/localpersistence"
|
import Vue from "vue"
|
||||||
|
import {
|
||||||
|
HoppAccentColors,
|
||||||
|
HoppAccentColor,
|
||||||
|
getSettingSubject,
|
||||||
|
settingsStore,
|
||||||
|
applySetting,
|
||||||
|
} from "~/newstore/settings"
|
||||||
|
|
||||||
export default {
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: getLocalConfig("THEME_COLOR") || "green",
|
accentColors: HoppAccentColors,
|
||||||
accentColors: [
|
active: settingsStore.value.THEME_COLOR,
|
||||||
"blue",
|
|
||||||
"green",
|
|
||||||
"teal",
|
|
||||||
"indigo",
|
|
||||||
"purple",
|
|
||||||
"orange",
|
|
||||||
"pink",
|
|
||||||
"red",
|
|
||||||
"yellow",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
subscriptions() {
|
||||||
active(color) {
|
return {
|
||||||
setLocalConfig("THEME_COLOR", color)
|
active: getSettingSubject("THEME_COLOR"),
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setActiveColor(color) {
|
setActiveColor(color: HoppAccentColor) {
|
||||||
document.documentElement.setAttribute("data-accent", color)
|
document.documentElement.setAttribute("data-accent", color)
|
||||||
this.active = color
|
|
||||||
|
applySetting("THEME_COLOR", color)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,15 +15,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
export default {
|
import Vue from "vue"
|
||||||
|
import {
|
||||||
|
applySetting,
|
||||||
|
getSettingSubject,
|
||||||
|
HoppBgColor,
|
||||||
|
HoppBgColors,
|
||||||
|
} from "~/newstore/settings"
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
colors: ["system", "light", "dark", "black"],
|
colors: HoppBgColors,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subscriptions() {
|
||||||
|
return {
|
||||||
|
activeColor: getSettingSubject("BG_COLOR"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getIcon(color) {
|
setBGMode(color: HoppBgColor) {
|
||||||
|
applySetting("BG_COLOR", color)
|
||||||
|
},
|
||||||
|
getIcon(color: HoppBgColor) {
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case "system":
|
case "system":
|
||||||
return "desktop_windows"
|
return "desktop_windows"
|
||||||
@@ -38,5 +54,5 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
93
helpers/fb/analytics.ts
Normal file
93
helpers/fb/analytics.ts
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import firebase from "firebase"
|
||||||
|
import { authEvents$ } from "./auth"
|
||||||
|
import {
|
||||||
|
HoppAccentColor,
|
||||||
|
HoppBgColor,
|
||||||
|
settings$,
|
||||||
|
settingsStore,
|
||||||
|
} from "~/newstore/settings"
|
||||||
|
|
||||||
|
let analytics: firebase.analytics.Analytics
|
||||||
|
|
||||||
|
type SettingsCustomDimensions = {
|
||||||
|
usesProxy: boolean
|
||||||
|
usesExtension: boolean
|
||||||
|
usesScrollInto: boolean
|
||||||
|
syncCollections: boolean
|
||||||
|
syncEnvironments: boolean
|
||||||
|
syncHistory: boolean
|
||||||
|
usesBg: HoppBgColor
|
||||||
|
usesAccent: HoppAccentColor
|
||||||
|
usesTelemetry: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type HoppRequestEvent =
|
||||||
|
| {
|
||||||
|
platform: "rest" | "graphql-query" | "graphql-schema"
|
||||||
|
strategy: "normal" | "proxy" | "extension"
|
||||||
|
}
|
||||||
|
| { platform: "wss" | "sse" | "socketio" | "mqtt" }
|
||||||
|
|
||||||
|
export function initAnalytics() {
|
||||||
|
analytics = firebase.app().analytics()
|
||||||
|
|
||||||
|
initLoginListeners()
|
||||||
|
initSettingsListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
function initLoginListeners() {
|
||||||
|
authEvents$.subscribe((ev) => {
|
||||||
|
if (ev.event === "login") {
|
||||||
|
if (settingsStore.value.TELEMETRY_ENABLED) {
|
||||||
|
analytics.setUserId(ev.user.uid)
|
||||||
|
|
||||||
|
analytics.logEvent("login", {
|
||||||
|
method: ev.user.providerData[0]?.providerId, // Assume the first provider is the login provider
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (ev.event === "logout") {
|
||||||
|
if (settingsStore.value.TELEMETRY_ENABLED) {
|
||||||
|
analytics.logEvent("logout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSettingsListeners() {
|
||||||
|
// Keep track of the telemetry status
|
||||||
|
let telemetryStatus = settingsStore.value.TELEMETRY_ENABLED
|
||||||
|
|
||||||
|
settings$.subscribe((settings) => {
|
||||||
|
const conf: SettingsCustomDimensions = {
|
||||||
|
usesProxy: settings.PROXY_ENABLED,
|
||||||
|
usesExtension: settings.EXTENSIONS_ENABLED,
|
||||||
|
usesScrollInto: settings.SCROLL_INTO_ENABLED,
|
||||||
|
syncCollections: settings.syncCollections,
|
||||||
|
syncEnvironments: settings.syncEnvironments,
|
||||||
|
syncHistory: settings.syncHistory,
|
||||||
|
usesAccent: settings.THEME_COLOR,
|
||||||
|
usesBg: settings.BG_COLOR,
|
||||||
|
usesTelemetry: settings.TELEMETRY_ENABLED,
|
||||||
|
}
|
||||||
|
|
||||||
|
// User toggled telemetry mode to off or to on
|
||||||
|
if (
|
||||||
|
(telemetryStatus && !settings.TELEMETRY_ENABLED) ||
|
||||||
|
settings.TELEMETRY_ENABLED
|
||||||
|
) {
|
||||||
|
analytics.setUserProperties(conf)
|
||||||
|
}
|
||||||
|
|
||||||
|
telemetryStatus = settings.TELEMETRY_ENABLED
|
||||||
|
|
||||||
|
analytics.setAnalyticsCollectionEnabled(telemetryStatus)
|
||||||
|
})
|
||||||
|
|
||||||
|
analytics.setAnalyticsCollectionEnabled(telemetryStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logHoppRequestRunToAnalytics(ev: HoppRequestEvent) {
|
||||||
|
if (settingsStore.value.TELEMETRY_ENABLED) {
|
||||||
|
analytics.logEvent("hopp-request", ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,16 @@
|
|||||||
import firebase from "firebase"
|
import firebase from "firebase"
|
||||||
import { BehaviorSubject } from "rxjs"
|
import { BehaviorSubject, Subject } from "rxjs"
|
||||||
|
|
||||||
export type HoppUser = firebase.User & {
|
export type HoppUser = firebase.User & {
|
||||||
provider?: string
|
provider?: string
|
||||||
accessToken?: string
|
accessToken?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AuthEvents =
|
||||||
|
| { event: "login"; user: HoppUser }
|
||||||
|
| { event: "logout" }
|
||||||
|
| { event: "authTokenUpdate"; user: HoppUser; newToken: string | null }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A BehaviorSubject emitting the currently logged in user (or null if not logged in)
|
* A BehaviorSubject emitting the currently logged in user (or null if not logged in)
|
||||||
*/
|
*/
|
||||||
@@ -15,6 +20,11 @@ export const currentUser$ = new BehaviorSubject<HoppUser | null>(null)
|
|||||||
*/
|
*/
|
||||||
export const authIdToken$ = new BehaviorSubject<string | null>(null)
|
export const authIdToken$ = new BehaviorSubject<string | null>(null)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subject that emits events related to authentication flows
|
||||||
|
*/
|
||||||
|
export const authEvents$ = new Subject<AuthEvents>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the firebase authentication related subjects
|
* Initializes the firebase authentication related subjects
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +32,9 @@ export function initAuth() {
|
|||||||
let extraSnapshotStop: (() => void) | null = null
|
let extraSnapshotStop: (() => void) | null = null
|
||||||
|
|
||||||
firebase.auth().onAuthStateChanged((user) => {
|
firebase.auth().onAuthStateChanged((user) => {
|
||||||
|
/** Whether the user was logged in before */
|
||||||
|
const wasLoggedIn = currentUser$.value !== null
|
||||||
|
|
||||||
if (!user && extraSnapshotStop) {
|
if (!user && extraSnapshotStop) {
|
||||||
extraSnapshotStop()
|
extraSnapshotStop()
|
||||||
extraSnapshotStop = null
|
extraSnapshotStop = null
|
||||||
@@ -61,14 +74,35 @@ export function initAuth() {
|
|||||||
userUpdate.provider = data.provider
|
userUpdate.provider = data.provider
|
||||||
userUpdate.accessToken = data.accessToken
|
userUpdate.accessToken = data.accessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentUser$.next(userUpdate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
currentUser$.next(user)
|
currentUser$.next(user)
|
||||||
|
|
||||||
|
// User wasn't found before, but now is there (login happened)
|
||||||
|
if (!wasLoggedIn && user) {
|
||||||
|
authEvents$.next({
|
||||||
|
event: "login",
|
||||||
|
user: currentUser$.value!!,
|
||||||
|
})
|
||||||
|
} else if (wasLoggedIn && !user) {
|
||||||
|
// User was found before, but now is not there (logout happened)
|
||||||
|
authEvents$.next({
|
||||||
|
event: "logout",
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
firebase.auth().onIdTokenChanged(async (user) => {
|
firebase.auth().onIdTokenChanged(async (user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
authIdToken$.next(await user.getIdToken())
|
authIdToken$.next(await user.getIdToken())
|
||||||
|
|
||||||
|
authEvents$.next({
|
||||||
|
event: "authTokenUpdate",
|
||||||
|
newToken: authIdToken$.value,
|
||||||
|
user: currentUser$.value!!, // Force not-null because user is defined
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
authIdToken$.next(null)
|
authIdToken$.next(null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import firebase from "firebase"
|
import firebase from "firebase"
|
||||||
|
import { initAnalytics } from "./analytics"
|
||||||
import { initAuth } from "./auth"
|
import { initAuth } from "./auth"
|
||||||
import { initCollections } from "./collections"
|
import { initCollections } from "./collections"
|
||||||
import { initEnvironments } from "./environments"
|
import { initEnvironments } from "./environments"
|
||||||
@@ -13,13 +14,14 @@ const firebaseConfig = {
|
|||||||
storageBucket: process.env.STORAGE_BUCKET,
|
storageBucket: process.env.STORAGE_BUCKET,
|
||||||
messagingSenderId: process.env.MESSAGING_SENDER_ID,
|
messagingSenderId: process.env.MESSAGING_SENDER_ID,
|
||||||
appId: process.env.APP_ID,
|
appId: process.env.APP_ID,
|
||||||
measurementId: process.env.MEASUREMENT_ID,
|
measurementId: process.env.FB_MEASUREMENT_ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
let initialized = false
|
let initialized = false
|
||||||
|
|
||||||
export function initializeFirebase() {
|
export function initializeFirebase() {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
try {
|
||||||
firebase.initializeApp(firebaseConfig)
|
firebase.initializeApp(firebaseConfig)
|
||||||
|
|
||||||
initAuth()
|
initAuth()
|
||||||
@@ -27,7 +29,12 @@ export function initializeFirebase() {
|
|||||||
initCollections()
|
initCollections()
|
||||||
initHistory()
|
initHistory()
|
||||||
initEnvironments()
|
initEnvironments()
|
||||||
|
initAnalytics()
|
||||||
|
|
||||||
initialized = true
|
initialized = true
|
||||||
|
} catch (e) {
|
||||||
|
// initializeApp throws exception if we reinitialize
|
||||||
|
initialized = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,5 +25,21 @@ const runAppropriateStrategy = (req) => {
|
|||||||
return AxiosStrategy(req)
|
return AxiosStrategy(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an identifier for how a request will be ran
|
||||||
|
* if the system is asked to fire a request
|
||||||
|
*
|
||||||
|
* @returns {"normal" | "extension" | "proxy"}
|
||||||
|
*/
|
||||||
|
export function getCurrentStrategyID() {
|
||||||
|
if (isExtensionsAllowed() && hasExtensionInstalled()) {
|
||||||
|
return "extension"
|
||||||
|
} else if (settingsStore.value.PROXY_ENABLED) {
|
||||||
|
return "proxy"
|
||||||
|
} else {
|
||||||
|
return "normal"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const sendNetworkRequest = (req) =>
|
export const sendNetworkRequest = (req) =>
|
||||||
runAppropriateStrategy(req).finally(() => window.$nuxt.$loading.finish())
|
runAppropriateStrategy(req).finally(() => window.$nuxt.$loading.finish())
|
||||||
|
|||||||
@@ -286,6 +286,8 @@
|
|||||||
"are_you_sure_remove_folder": "Are you sure you want to remove this folder?",
|
"are_you_sure_remove_folder": "Are you sure you want to remove this folder?",
|
||||||
"are_you_sure_remove_request": "Are you sure you want to remove this request?",
|
"are_you_sure_remove_request": "Are you sure you want to remove this request?",
|
||||||
"are_you_sure_remove_environment": "Are you sure you want to remove this environment?",
|
"are_you_sure_remove_environment": "Are you sure you want to remove this environment?",
|
||||||
|
"are_you_sure_remove_telemetry": "Are you sure you want to opt-out of Telemetry?",
|
||||||
|
"telemetry_helps_us": "Telemetry helps us to personalize our operations and deliver the best experience to you.",
|
||||||
"select_next_method": "Select Next method",
|
"select_next_method": "Select Next method",
|
||||||
"select_previous_method": "Select Previous method",
|
"select_previous_method": "Select Previous method",
|
||||||
"select_get_method": "Select GET method",
|
"select_get_method": "Select GET method",
|
||||||
@@ -345,5 +347,6 @@
|
|||||||
"share": "Share",
|
"share": "Share",
|
||||||
"interceptor": "Interceptor",
|
"interceptor": "Interceptor",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
"are_you_sure_logout": "Are you sure you want to logout?"
|
"are_you_sure_logout": "Are you sure you want to logout?",
|
||||||
|
"telemetry": "Telemetry"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,15 +66,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { Splitpanes, Pane } from "splitpanes"
|
import { Splitpanes, Pane } from "splitpanes"
|
||||||
import "splitpanes/dist/splitpanes.css"
|
import "splitpanes/dist/splitpanes.css"
|
||||||
|
import { setupLocalPersistence } from "~/newstore/localpersistence"
|
||||||
import {
|
|
||||||
setupLocalPersistence,
|
|
||||||
getLocalConfig,
|
|
||||||
} from "~/newstore/localpersistence"
|
|
||||||
import { performMigrations } from "~/helpers/migrations"
|
import { performMigrations } from "~/helpers/migrations"
|
||||||
import { initUserInfo } from "~/helpers/teams/BackendUserInfo"
|
import { initUserInfo } from "~/helpers/teams/BackendUserInfo"
|
||||||
import { registerApolloAuthUpdate } from "~/helpers/apollo"
|
import { registerApolloAuthUpdate } from "~/helpers/apollo"
|
||||||
import { initializeFirebase } from "~/helpers/fb"
|
import { initializeFirebase } from "~/helpers/fb"
|
||||||
|
import { getSettingSubject } from "~/newstore/settings"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Splitpanes, Pane },
|
components: { Splitpanes, Pane },
|
||||||
@@ -93,8 +90,13 @@ export default {
|
|||||||
beforeMount() {
|
beforeMount() {
|
||||||
registerApolloAuthUpdate()
|
registerApolloAuthUpdate()
|
||||||
|
|
||||||
const color = getLocalConfig("THEME_COLOR") || "green"
|
this.$subscribeTo(getSettingSubject("THEME_COLOR"), (color) => {
|
||||||
document.documentElement.setAttribute("data-accent", color)
|
document.documentElement.setAttribute("data-accent", color)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$subscribeTo(getSettingSubject("BG_COLOR"), (color) => {
|
||||||
|
this.$colorMode.preference = color
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
performMigrations()
|
performMigrations()
|
||||||
@@ -112,13 +114,13 @@ export default {
|
|||||||
if (workbox) {
|
if (workbox) {
|
||||||
workbox.addEventListener("installed", (event) => {
|
workbox.addEventListener("installed", (event) => {
|
||||||
if (event.isUpdate) {
|
if (event.isUpdate) {
|
||||||
this.$toast.show(this.$t("new_version_found"), {
|
this.$toast.show(this.$t("new_version_found").toString(), {
|
||||||
icon: "info",
|
icon: "info",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
theme: "toasted-primary",
|
theme: "toasted-primary",
|
||||||
action: [
|
action: [
|
||||||
{
|
{
|
||||||
text: this.$t("reload"),
|
text: this.$t("reload").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
toastObject.goAway(0)
|
toastObject.goAway(0)
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
|
|||||||
@@ -3,7 +3,14 @@
|
|||||||
import clone from "lodash/clone"
|
import clone from "lodash/clone"
|
||||||
import assign from "lodash/assign"
|
import assign from "lodash/assign"
|
||||||
import eq from "lodash/eq"
|
import eq from "lodash/eq"
|
||||||
import { settingsStore, bulkApplySettings, defaultSettings } from "./settings"
|
import {
|
||||||
|
settingsStore,
|
||||||
|
bulkApplySettings,
|
||||||
|
defaultSettings,
|
||||||
|
applySetting,
|
||||||
|
HoppAccentColor,
|
||||||
|
HoppBgColor,
|
||||||
|
} from "./settings"
|
||||||
import {
|
import {
|
||||||
restHistoryStore,
|
restHistoryStore,
|
||||||
graphqlHistoryStore,
|
graphqlHistoryStore,
|
||||||
@@ -55,6 +62,20 @@ function checkAndMigrateOldSettings() {
|
|||||||
delete vuexData.postwoman.environments
|
delete vuexData.postwoman.environments
|
||||||
window.localStorage.setItem("vuex", JSON.stringify(vuexData))
|
window.localStorage.setItem("vuex", JSON.stringify(vuexData))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window.localStorage.getItem("THEME_COLOR")) {
|
||||||
|
const themeColor = window.localStorage.getItem("THEME_COLOR")
|
||||||
|
applySetting("THEME_COLOR", themeColor as HoppAccentColor)
|
||||||
|
|
||||||
|
window.localStorage.removeItem("THEME_COLOR")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.localStorage.getItem("nuxt-color-mode")) {
|
||||||
|
const color = window.localStorage.getItem("nuxt-color-mode") as HoppBgColor
|
||||||
|
applySetting("BG_COLOR", color)
|
||||||
|
|
||||||
|
window.localStorage.removeItem("BG_COLOR")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupSettingsPersistence() {
|
function setupSettingsPersistence() {
|
||||||
|
|||||||
@@ -4,7 +4,47 @@ import { Observable } from "rxjs"
|
|||||||
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
||||||
import type { KeysMatching } from "~/types/ts-utils"
|
import type { KeysMatching } from "~/types/ts-utils"
|
||||||
|
|
||||||
export const defaultSettings = {
|
export const HoppBgColors = ["system", "light", "dark", "black"] as const
|
||||||
|
|
||||||
|
export type HoppBgColor = typeof HoppBgColors[number]
|
||||||
|
|
||||||
|
export const HoppAccentColors = [
|
||||||
|
"blue",
|
||||||
|
"green",
|
||||||
|
"teal",
|
||||||
|
"indigo",
|
||||||
|
"purple",
|
||||||
|
"orange",
|
||||||
|
"pink",
|
||||||
|
"red",
|
||||||
|
"yellow",
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export type HoppAccentColor = typeof HoppAccentColors[number]
|
||||||
|
|
||||||
|
export type SettingsType = {
|
||||||
|
syncCollections: boolean
|
||||||
|
syncHistory: boolean
|
||||||
|
syncEnvironments: boolean
|
||||||
|
|
||||||
|
SCROLL_INTO_ENABLED: boolean
|
||||||
|
PROXY_ENABLED: boolean
|
||||||
|
PROXY_URL: string
|
||||||
|
PROXY_KEY: string
|
||||||
|
EXTENSIONS_ENABLED: boolean
|
||||||
|
EXPERIMENTAL_URL_BAR_ENABLED: boolean
|
||||||
|
URL_EXCLUDES: {
|
||||||
|
auth: boolean
|
||||||
|
httpUser: boolean
|
||||||
|
httpPassword: boolean
|
||||||
|
bearerToken: boolean
|
||||||
|
}
|
||||||
|
THEME_COLOR: HoppAccentColor
|
||||||
|
BG_COLOR: HoppBgColor
|
||||||
|
TELEMETRY_ENABLED: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultSettings: SettingsType = {
|
||||||
syncCollections: true,
|
syncCollections: true,
|
||||||
syncHistory: true,
|
syncHistory: true,
|
||||||
syncEnvironments: true,
|
syncEnvironments: true,
|
||||||
@@ -21,10 +61,11 @@ export const defaultSettings = {
|
|||||||
httpPassword: true,
|
httpPassword: true,
|
||||||
bearerToken: true,
|
bearerToken: true,
|
||||||
},
|
},
|
||||||
|
THEME_COLOR: "green",
|
||||||
|
BG_COLOR: "system",
|
||||||
|
TELEMETRY_ENABLED: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SettingsType = typeof defaultSettings
|
|
||||||
|
|
||||||
const validKeys = Object.keys(defaultSettings)
|
const validKeys = Object.keys(defaultSettings)
|
||||||
|
|
||||||
const dispatchers = defineDispatchers({
|
const dispatchers = defineDispatchers({
|
||||||
|
|||||||
@@ -455,9 +455,10 @@ import { Splitpanes, Pane } from "splitpanes"
|
|||||||
import * as gql from "graphql"
|
import * as gql from "graphql"
|
||||||
import { commonHeaders } from "~/helpers/headers"
|
import { commonHeaders } from "~/helpers/headers"
|
||||||
import { getPlatformSpecialKey } from "~/helpers/platformutils"
|
import { getPlatformSpecialKey } from "~/helpers/platformutils"
|
||||||
import { sendNetworkRequest } from "~/helpers/network"
|
import { getCurrentStrategyID, sendNetworkRequest } from "~/helpers/network"
|
||||||
import { getSettingSubject } from "~/newstore/settings"
|
import { getSettingSubject } from "~/newstore/settings"
|
||||||
import { addGraphqlHistoryEntry } from "~/newstore/history"
|
import { addGraphqlHistoryEntry } from "~/newstore/history"
|
||||||
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Splitpanes, Pane },
|
components: { Splitpanes, Pane },
|
||||||
@@ -818,6 +819,11 @@ export default {
|
|||||||
})
|
})
|
||||||
console.log("Error", error)
|
console.log("Error", error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "graphql-query",
|
||||||
|
strategy: getCurrentStrategyID(),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// NOTE : schema required here is the GQL Schema document object, not the schema string
|
// NOTE : schema required here is the GQL Schema document object, not the schema string
|
||||||
@@ -887,6 +893,11 @@ export default {
|
|||||||
await this.getSchema()
|
await this.getSchema()
|
||||||
|
|
||||||
this.pollSchema()
|
this.pollSchema()
|
||||||
|
|
||||||
|
logHoppRequestRunToAnalytics({
|
||||||
|
platform: "graphql-schema",
|
||||||
|
strategy: getCurrentStrategyID(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async pollSchema() {
|
async pollSchema() {
|
||||||
|
|||||||
@@ -167,6 +167,12 @@
|
|||||||
{{ $t("use_experimental_url_bar") }}
|
{{ $t("use_experimental_url_bar") }}
|
||||||
</SmartToggle>
|
</SmartToggle>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<SmartToggle :on="TELEMETRY_ENABLED" @change="showConfirmModal">
|
||||||
|
{{ $t("telemetry") }}
|
||||||
|
{{ TELEMETRY_ENABLED ? $t("enabled") : $t("disabled") }}
|
||||||
|
</SmartToggle>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
@@ -275,8 +281,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
<FirebaseLogin :show="showLogin" @hide-modal="showLogin = false" />
|
||||||
|
<FirebaseEmail :show="showEmail" @hide-modal="showEmail = false" />
|
||||||
|
<SmartConfirmModal
|
||||||
|
:show="confirmRemove"
|
||||||
|
:title="`${$t('are_you_sure_remove_telemetry')} ${$t(
|
||||||
|
'telemetry_helps_us'
|
||||||
|
)}`"
|
||||||
|
@hide-modal="confirmRemove = false"
|
||||||
|
@resolve="
|
||||||
|
toggleSetting('TELEMETRY_ENABLED')
|
||||||
|
confirmRemove = false
|
||||||
|
"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -319,6 +336,9 @@ export default Vue.extend({
|
|||||||
showLogin: false,
|
showLogin: false,
|
||||||
|
|
||||||
active: getLocalConfig("THEME_COLOR") || "green",
|
active: getLocalConfig("THEME_COLOR") || "green",
|
||||||
|
confirmRemove: false,
|
||||||
|
|
||||||
|
TELEMETRY_ENABLED: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
subscriptions() {
|
subscriptions() {
|
||||||
@@ -339,6 +359,8 @@ export default Vue.extend({
|
|||||||
SYNC_ENVIRONMENTS: getSettingSubject("syncEnvironments"),
|
SYNC_ENVIRONMENTS: getSettingSubject("syncEnvironments"),
|
||||||
SYNC_HISTORY: getSettingSubject("syncHistory"),
|
SYNC_HISTORY: getSettingSubject("syncHistory"),
|
||||||
|
|
||||||
|
TELEMETRY_ENABLED: getSettingSubject("TELEMETRY_ENABLED"),
|
||||||
|
|
||||||
currentUser: currentUser$,
|
currentUser: currentUser$,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -365,6 +387,10 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showConfirmModal() {
|
||||||
|
if (this.TELEMETRY_ENABLED) this.confirmRemove = true
|
||||||
|
else toggleSetting("TELEMETRY_ENABLED")
|
||||||
|
},
|
||||||
applySetting<K extends keyof SettingsType>(key: K, value: SettingsType[K]) {
|
applySetting<K extends keyof SettingsType>(key: K, value: SettingsType[K]) {
|
||||||
applySetting(key, value)
|
applySetting(key, value)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ export const SETTINGS_KEYS = [
|
|||||||
*/
|
*/
|
||||||
"EXTENSIONS_ENABLED",
|
"EXTENSIONS_ENABLED",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean value indicating whether Telemetry is enabled.
|
||||||
|
*/
|
||||||
|
"TELEMETRY_ENABLED",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean value indicating whether to use the URL bar experiments
|
* A boolean value indicating whether to use the URL bar experiments
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user