You've already forked AstralRinth
forked from didirus/AstralRinth
Switch to PostHog for app analytics (#2316)
This commit is contained in:
@@ -21,14 +21,15 @@
|
||||
"@vintl/vintl": "^4.4.1",
|
||||
"dayjs": "^1.11.10",
|
||||
"floating-vue": "^5.2.2",
|
||||
"mixpanel-browser": "^2.49.0",
|
||||
"ofetch": "^1.3.4",
|
||||
"pinia": "^2.1.7",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
"vue": "^3.4.21",
|
||||
"vue-multiselect": "3.0.0",
|
||||
"vue-router": "4.3.0",
|
||||
"vue-virtual-scroller": "v2.0.0-beta.8"
|
||||
"vue-virtual-scroller": "v2.0.0-beta.8",
|
||||
"posthog-js": "^1.158.2",
|
||||
"@sentry/vue": "^8.27.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^2.0.0-rc",
|
||||
|
||||
@@ -17,16 +17,9 @@ import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||
import { MinimizeIcon, MaximizeIcon } from '@/assets/icons'
|
||||
import { type } from '@tauri-apps/plugin-os'
|
||||
import { isDev, getOS } from '@/helpers/utils.js'
|
||||
import {
|
||||
mixpanel_track,
|
||||
mixpanel_init,
|
||||
mixpanel_opt_out_tracking,
|
||||
mixpanel_is_loaded,
|
||||
} from '@/helpers/mixpanel'
|
||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||
import { initAnalytics, debugAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
import { TauriEvent } from '@tauri-apps/api/event'
|
||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||
import { install_from_file } from './helpers/pack'
|
||||
import { useError } from '@/store/error.js'
|
||||
@@ -90,11 +83,12 @@ async function setupApp() {
|
||||
themeStore.collapsedNavigation = collapsed_navigation
|
||||
themeStore.advancedRendering = advanced_rendering
|
||||
|
||||
mixpanel_init('014c7d6a336d0efaefe3aca91063748d', { debug: dev, persistence: 'localStorage' })
|
||||
initAnalytics()
|
||||
if (!telemetry) {
|
||||
mixpanel_opt_out_tracking()
|
||||
optOutAnalytics()
|
||||
}
|
||||
mixpanel_track('Launched', { version, dev, onboarded })
|
||||
if (dev) debugAnalytics()
|
||||
trackEvent('Launched', { version, dev, onboarded })
|
||||
|
||||
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
|
||||
|
||||
@@ -137,9 +131,7 @@ const handleClose = async () => {
|
||||
|
||||
const router = useRouter()
|
||||
router.afterEach((to, from, failure) => {
|
||||
if (mixpanel_is_loaded()) {
|
||||
mixpanel_track('PageView', { path: to.path, fromPath: from.path, failed: failure })
|
||||
}
|
||||
trackEvent('PageView', { path: to.path, fromPath: from.path, failed: failure })
|
||||
})
|
||||
const route = useRoute()
|
||||
const isOnBrowse = computed(() => route.path.startsWith('/browse'))
|
||||
@@ -214,7 +206,7 @@ async function handleCommand(e) {
|
||||
// RunMRPack should directly install a local mrpack given a path
|
||||
if (e.path.endsWith('.mrpack')) {
|
||||
await install_from_file(e.path).catch(handleError)
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileDrop',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
|
||||
@@ -125,14 +125,14 @@ const handleOptionsClick = async (args) => {
|
||||
await run(args.item.path).catch((err) =>
|
||||
handleSevereError(err, { profilePath: args.item.path }),
|
||||
)
|
||||
mixpanel_track('InstanceStart', {
|
||||
trackEvent('InstanceStart', {
|
||||
loader: args.item.loader,
|
||||
game_version: args.item.game_version,
|
||||
})
|
||||
break
|
||||
case 'stop':
|
||||
await kill(args.item.path).catch(handleError)
|
||||
mixpanel_track('InstanceStop', {
|
||||
trackEvent('InstanceStop', {
|
||||
loader: args.item.loader,
|
||||
game_version: args.item.game_version,
|
||||
})
|
||||
|
||||
@@ -70,7 +70,7 @@ import {
|
||||
get_default_user,
|
||||
} from '@/helpers/auth'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
|
||||
@@ -118,7 +118,7 @@ async function login() {
|
||||
await refreshValues()
|
||||
}
|
||||
|
||||
mixpanel_track('AccountLogIn')
|
||||
trackEvent('AccountLogIn')
|
||||
}
|
||||
|
||||
const logout = async (id) => {
|
||||
@@ -130,7 +130,7 @@ const logout = async (id) => {
|
||||
} else {
|
||||
emit('change')
|
||||
}
|
||||
mixpanel_track('AccountLogOut')
|
||||
trackEvent('AccountLogOut')
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
|
||||
@@ -5,10 +5,10 @@ import { ChatIcon } from '@/assets/icons'
|
||||
import { ref } from 'vue'
|
||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { cancel_directory_change } from '@/helpers/settings.js'
|
||||
import { install } from '@/helpers/profile.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const errorModal = ref()
|
||||
const error = ref()
|
||||
@@ -85,7 +85,7 @@ async function loginMinecraft() {
|
||||
await set_default_user(loggedIn.id).catch(handleError)
|
||||
}
|
||||
|
||||
await mixpanel.track('AccountLogIn')
|
||||
await trackEvent('AccountLogIn', { source: 'ErrorModal' })
|
||||
loadingMinecraft.value = false
|
||||
errorModal.value.hide()
|
||||
} catch (err) {
|
||||
|
||||
@@ -9,8 +9,8 @@ import { get_by_profile_path } from '@/helpers/process'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
@@ -45,7 +45,7 @@ const play = async (e, context) => {
|
||||
)
|
||||
modLoading.value = false
|
||||
|
||||
mixpanel_track('InstancePlay', {
|
||||
trackEvent('InstancePlay', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
source: context,
|
||||
@@ -58,7 +58,7 @@ const stop = async (e, context) => {
|
||||
|
||||
await kill(props.instance.path).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceStop', {
|
||||
trackEvent('InstanceStop', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
source: context,
|
||||
|
||||
@@ -216,7 +216,7 @@ import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { install_from_file } from '@/helpers/pack.js'
|
||||
@@ -264,13 +264,13 @@ defineExpose({
|
||||
hide()
|
||||
if (event.payload && event.payload.length > 0 && event.payload[0].endsWith('.mrpack')) {
|
||||
await install_from_file(event.payload[0]).catch(handleError)
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileDrop',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
mixpanel_track('InstanceCreateStart', { source: 'CreationModal' })
|
||||
trackEvent('InstanceCreateStart', { source: 'CreationModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -360,7 +360,7 @@ const create_instance = async () => {
|
||||
icon.value,
|
||||
).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
profile_name: profile_name.value,
|
||||
game_version: game_version.value,
|
||||
loader: loader.value,
|
||||
@@ -419,7 +419,7 @@ const openFile = async () => {
|
||||
hide()
|
||||
await install_from_file(newProject).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileOpen',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ import { Modal, Button } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
@@ -67,7 +67,7 @@ const emit = defineEmits(['submit'])
|
||||
function setJavaInstall(javaInstall) {
|
||||
emit('submit', javaInstall)
|
||||
detectJavaModal.value.hide()
|
||||
mixpanel_track('JavaAutoDetect', {
|
||||
trackEvent('JavaAutoDetect', {
|
||||
path: javaInstall.path,
|
||||
version: javaInstall.version,
|
||||
})
|
||||
|
||||
@@ -65,8 +65,8 @@ import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/help
|
||||
import { ref } from 'vue'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const props = defineProps({
|
||||
version: {
|
||||
@@ -113,7 +113,7 @@ async function testJava() {
|
||||
)
|
||||
testingJava.value = false
|
||||
|
||||
mixpanel_track('JavaTest', {
|
||||
trackEvent('JavaTest', {
|
||||
path: props.modelValue ? props.modelValue.path : '',
|
||||
success: testingJavaSuccess.value,
|
||||
})
|
||||
@@ -136,7 +136,7 @@ async function handleJavaFileInput() {
|
||||
}
|
||||
}
|
||||
|
||||
mixpanel_track('JavaManualSelect', {
|
||||
trackEvent('JavaManualSelect', {
|
||||
path: filePath,
|
||||
version: props.version,
|
||||
})
|
||||
@@ -170,7 +170,7 @@ async function reinstallJava() {
|
||||
}
|
||||
}
|
||||
|
||||
mixpanel_track('JavaReInstall', {
|
||||
trackEvent('JavaReInstall', {
|
||||
path: path,
|
||||
version: props.version,
|
||||
})
|
||||
|
||||
@@ -117,9 +117,9 @@ import { useRouter } from 'vue-router'
|
||||
import { progress_bars_list } from '@/helpers/state.js'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { ChatIcon } from '@/assets/icons'
|
||||
import { get_many } from '@/helpers/profile.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const router = useRouter()
|
||||
const card = ref(null)
|
||||
@@ -164,7 +164,7 @@ const stop = async (process) => {
|
||||
try {
|
||||
await killProcess(process.uuid).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceStop', {
|
||||
trackEvent('InstanceStop', {
|
||||
loader: process.profile.loader,
|
||||
game_version: process.profile.game_version,
|
||||
source: 'AppBar',
|
||||
|
||||
@@ -61,7 +61,7 @@ import { formatCategory } from '@modrinth/utils'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { ref } from 'vue'
|
||||
import { handleError, useTheming } from '@/store/state.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
@@ -87,7 +87,7 @@ defineExpose({
|
||||
|
||||
incompatibleModal.value.show()
|
||||
|
||||
mixpanel_track('ProjectInstallStart', { source: 'ProjectIncompatibilityWarningModal' })
|
||||
trackEvent('ProjectInstallStart', { source: 'ProjectIncompatibilityWarningModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -98,7 +98,7 @@ const install = async () => {
|
||||
onInstall.value(selectedVersion.value.id)
|
||||
incompatibleModal.value.hide()
|
||||
|
||||
mixpanel_track('ProjectInstall', {
|
||||
trackEvent('ProjectInstall', {
|
||||
loader: instance.value.loader,
|
||||
game_version: instance.value.game_version,
|
||||
id: project.value,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||
import { Button, Modal } from '@modrinth/ui'
|
||||
import { install as pack_install } from '@/helpers/pack'
|
||||
import { ref } from 'vue'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { handleError } from '@/store/state.js'
|
||||
|
||||
@@ -25,7 +25,7 @@ defineExpose({
|
||||
|
||||
onInstall.value = callback
|
||||
|
||||
mixpanel_track('PackInstallStart')
|
||||
trackEvent('PackInstallStart')
|
||||
},
|
||||
})
|
||||
|
||||
@@ -39,7 +39,7 @@ async function install() {
|
||||
project.value.title,
|
||||
project.value.icon_url,
|
||||
).catch(handleError)
|
||||
mixpanel_track('PackInstall', {
|
||||
trackEvent('PackInstall', {
|
||||
id: project.value.id,
|
||||
version_id: versionId.value,
|
||||
title: project.value.title,
|
||||
|
||||
@@ -19,10 +19,10 @@ import {
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { installVersionDependencies } from '@/store/install.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const themeStore = useTheming()
|
||||
const router = useRouter()
|
||||
@@ -88,7 +88,7 @@ defineExpose({
|
||||
|
||||
installModal.value.show()
|
||||
|
||||
mixpanel_track('ProjectInstallStart', { source: 'ProjectInstallModal' })
|
||||
trackEvent('ProjectInstallStart', { source: 'ProjectInstallModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -115,7 +115,7 @@ async function install(instance) {
|
||||
instance.installedMod = true
|
||||
instance.installing = false
|
||||
|
||||
mixpanel_track('ProjectInstall', {
|
||||
trackEvent('ProjectInstall', {
|
||||
loader: instance.loader,
|
||||
game_version: instance.game_version,
|
||||
id: project.value.id,
|
||||
@@ -137,7 +137,7 @@ const toggleCreation = () => {
|
||||
loader.value = null
|
||||
|
||||
if (showCreation.value) {
|
||||
mixpanel_track('InstanceCreateStart', { source: 'ProjectInstallModal' })
|
||||
trackEvent('InstanceCreateStart', { source: 'ProjectInstallModal' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ const createInstance = async () => {
|
||||
const instance = await get(id, true)
|
||||
await installVersionDependencies(instance, versions.value[0])
|
||||
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
profile_name: name.value,
|
||||
game_version: versions.value[0].game_versions[0],
|
||||
loader: loader,
|
||||
@@ -195,7 +195,7 @@ const createInstance = async () => {
|
||||
source: 'ProjectInstallModal',
|
||||
})
|
||||
|
||||
mixpanel_track('ProjectInstall', {
|
||||
trackEvent('ProjectInstall', {
|
||||
loader: loader,
|
||||
game_version: versions.value[0].game_versions[0],
|
||||
id: project.value,
|
||||
|
||||
23
apps/app-frontend/src/helpers/analytics.js
Normal file
23
apps/app-frontend/src/helpers/analytics.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { posthog } from 'posthog-js'
|
||||
|
||||
export const initAnalytics = () => {
|
||||
posthog.init('phc_hm2ihMpTAoE86xIm7XzsCB8RPiTRKivViK5biiHedm', {
|
||||
persistence: 'localStorage',
|
||||
})
|
||||
}
|
||||
|
||||
export const debugAnalytics = () => {
|
||||
posthog.debug()
|
||||
}
|
||||
|
||||
export const optOutAnalytics = () => {
|
||||
posthog.opt_out_capturing()
|
||||
}
|
||||
|
||||
export const optInAnalytics = () => {
|
||||
posthog.opt_in_capturing()
|
||||
}
|
||||
|
||||
export const trackEvent = (eventName, properties) => {
|
||||
posthog.capture(eventName, properties)
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
// mixpanel_track
|
||||
function trackWrapper(originalTrack) {
|
||||
return function (event_name, properties = {}) {
|
||||
try {
|
||||
originalTrack(event_name, properties)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
export const mixpanel_track = trackWrapper(mixpanel.track.bind(mixpanel))
|
||||
|
||||
// mixpanel_opt_out_tracking()
|
||||
function optOutTrackingWrapper(originalOptOutTracking) {
|
||||
return function () {
|
||||
try {
|
||||
originalOptOutTracking()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
export const mixpanel_opt_out_tracking = optOutTrackingWrapper(
|
||||
mixpanel.opt_out_tracking.bind(mixpanel),
|
||||
)
|
||||
|
||||
// mixpanel_opt_in_tracking()
|
||||
function optInTrackingWrapper(originalOptInTracking) {
|
||||
return function () {
|
||||
try {
|
||||
originalOptInTracking()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
export const mixpanel_opt_in_tracking = optInTrackingWrapper(
|
||||
mixpanel.opt_in_tracking.bind(mixpanel),
|
||||
)
|
||||
|
||||
// mixpanel_init
|
||||
function initWrapper(originalInit) {
|
||||
return function (token, config = {}) {
|
||||
try {
|
||||
originalInit(token, config)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
export const mixpanel_init = initWrapper(mixpanel.init.bind(mixpanel))
|
||||
|
||||
export const mixpanel_is_loaded = () => {
|
||||
return mixpanel.__loaded
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { createPinia } from 'pinia'
|
||||
import FloatingVue from 'floating-vue'
|
||||
import 'floating-vue/dist/style.css'
|
||||
import { createPlugin } from '@vintl/vintl/plugin'
|
||||
import * as Sentry from '@sentry/vue'
|
||||
|
||||
const VIntlPlugin = createPlugin({
|
||||
controllerOpts: {
|
||||
@@ -26,6 +27,14 @@ const VIntlPlugin = createPlugin({
|
||||
const pinia = createPinia()
|
||||
|
||||
let app = createApp(App)
|
||||
|
||||
Sentry.init({
|
||||
app,
|
||||
dsn: 'https://9508775ee5034536bc70433f5f531dd4@o485889.ingest.us.sentry.io/4504579615227904',
|
||||
integrations: [Sentry.browserTracingIntegration({ router })],
|
||||
tracesSampleRate: 0.1,
|
||||
})
|
||||
|
||||
app.use(router)
|
||||
app.use(pinia)
|
||||
app.use(FloatingVue)
|
||||
|
||||
@@ -8,7 +8,7 @@ import { get_java_versions, get_max_memory, set_java_version } from '@/helpers/j
|
||||
import { get as getCreds, logout } from '@/helpers/mr_auth.js'
|
||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
import ModrinthLoginScreen from '@/components/ui/tutorial/ModrinthLoginScreen.vue'
|
||||
import { mixpanel_opt_out_tracking, mixpanel_opt_in_tracking } from '@/helpers/mixpanel'
|
||||
import { optOutAnalytics, optInAnalytics } from '@/helpers/analytics'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { getOS } from '@/helpers/utils.js'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
@@ -45,9 +45,9 @@ watch(
|
||||
const setSettings = JSON.parse(JSON.stringify(newSettings))
|
||||
|
||||
if (setSettings.telemetry) {
|
||||
mixpanel_opt_out_tracking()
|
||||
optInAnalytics()
|
||||
} else {
|
||||
mixpanel_opt_in_tracking()
|
||||
optOutAnalytics()
|
||||
}
|
||||
|
||||
setSettings.extra_launch_args = setSettings.launchArgs.trim().split(/\s+/).filter(Boolean)
|
||||
|
||||
@@ -131,9 +131,8 @@ import { ref, onUnmounted } from 'vue'
|
||||
import { handleError, useBreadcrumbs, useLoading } from '@/store/state'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { useFetch } from '@/helpers/fetch'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -183,7 +182,7 @@ const startInstance = async (context) => {
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
mixpanel_track('InstanceStart', {
|
||||
trackEvent('InstanceStart', {
|
||||
loader: instance.value.loader,
|
||||
game_version: instance.value.game_version,
|
||||
source: context,
|
||||
@@ -220,7 +219,7 @@ const stopInstance = async (context) => {
|
||||
playing.value = false
|
||||
await kill(route.params.id).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceStop', {
|
||||
trackEvent('InstanceStop', {
|
||||
loader: instance.value.loader,
|
||||
game_version: instance.value.game_version,
|
||||
source: context,
|
||||
|
||||
@@ -379,7 +379,7 @@ import {
|
||||
update_project,
|
||||
} from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { highlightModInProfile } from '@/helpers/utils.js'
|
||||
import { MenuIcon, ToggleIcon, TextInputIcon, AddProjectImage, PackageIcon } from '@/assets/icons'
|
||||
@@ -682,7 +682,7 @@ const updateAll = async () => {
|
||||
projects.value[project].updating = false
|
||||
}
|
||||
|
||||
mixpanel_track('InstanceUpdateAll', {
|
||||
trackEvent('InstanceUpdateAll', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
count: setProjects.length,
|
||||
@@ -708,7 +708,7 @@ const updateProject = async (mod) => {
|
||||
mod.version = mod.updateVersion.version_number
|
||||
mod.updateVersion = null
|
||||
|
||||
mixpanel_track('InstanceProjectUpdate', {
|
||||
trackEvent('InstanceProjectUpdate', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
id: mod.id,
|
||||
@@ -735,7 +735,7 @@ const toggleDisableMod = async (mod) => {
|
||||
.then((newPath) => {
|
||||
mod.path = newPath
|
||||
mod.disabled = !mod.disabled
|
||||
mixpanel_track('InstanceProjectDisable', {
|
||||
trackEvent('InstanceProjectDisable', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
id: mod.id,
|
||||
@@ -756,7 +756,7 @@ const removeMod = async (mod) => {
|
||||
await remove_project(props.instance.path, mod.path).catch(handleError)
|
||||
projects.value = projects.value.filter((x) => mod.path !== x.path)
|
||||
|
||||
mixpanel_track('InstanceProjectRemove', {
|
||||
trackEvent('InstanceProjectRemove', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
id: mod.id,
|
||||
|
||||
@@ -546,10 +546,10 @@ import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { get_loader_versions } from '@/helpers/metadata.js'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const breadcrumbs = useBreadcrumbs()
|
||||
|
||||
@@ -590,7 +590,7 @@ const availableGroups = ref([
|
||||
async function resetIcon() {
|
||||
icon.value = null
|
||||
await edit_icon(props.instance.path, null).catch(handleError)
|
||||
mixpanel_track('InstanceRemoveIcon')
|
||||
trackEvent('InstanceRemoveIcon')
|
||||
}
|
||||
|
||||
async function setIcon() {
|
||||
@@ -609,7 +609,7 @@ async function setIcon() {
|
||||
icon.value = value
|
||||
await edit_icon(props.instance.path, icon.value).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceSetIcon')
|
||||
trackEvent('InstanceSetIcon')
|
||||
}
|
||||
|
||||
const globalSettings = await get().catch(handleError)
|
||||
@@ -754,7 +754,7 @@ const repairing = ref(false)
|
||||
|
||||
async function duplicateProfile() {
|
||||
await duplicate(props.instance.path).catch(handleError)
|
||||
mixpanel_track('InstanceDuplicate', {
|
||||
trackEvent('InstanceDuplicate', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
})
|
||||
@@ -765,7 +765,7 @@ async function repairProfile(force) {
|
||||
await install(props.instance.path, force).catch(handleError)
|
||||
repairing.value = false
|
||||
|
||||
mixpanel_track('InstanceRepair', {
|
||||
trackEvent('InstanceRepair', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
})
|
||||
@@ -796,7 +796,7 @@ async function repairModpack() {
|
||||
await update_repair_modrinth(props.instance.path).catch(handleError)
|
||||
inProgress.value = false
|
||||
|
||||
mixpanel_track('InstanceRepair', {
|
||||
trackEvent('InstanceRepair', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
})
|
||||
@@ -808,7 +808,7 @@ async function removeProfile() {
|
||||
await remove(props.instance.path).catch(handleError)
|
||||
removing.value = false
|
||||
|
||||
mixpanel_track('InstanceRemove', {
|
||||
trackEvent('InstanceRemove', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
})
|
||||
|
||||
@@ -93,7 +93,7 @@ import {
|
||||
} from '@modrinth/assets'
|
||||
import { Button, Card } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const props = defineProps({
|
||||
project: {
|
||||
@@ -112,7 +112,7 @@ const nextImage = () => {
|
||||
expandedGalleryIndex.value = 0
|
||||
}
|
||||
expandedGalleryItem.value = props.project.gallery[expandedGalleryIndex.value]
|
||||
mixpanel_track('GalleryImageNext', {
|
||||
trackEvent('GalleryImageNext', {
|
||||
project_id: props.project.id,
|
||||
url: expandedGalleryItem.value.url,
|
||||
})
|
||||
@@ -124,7 +124,7 @@ const previousImage = () => {
|
||||
expandedGalleryIndex.value = props.project.gallery.length - 1
|
||||
}
|
||||
expandedGalleryItem.value = props.project.gallery[expandedGalleryIndex.value]
|
||||
mixpanel_track('GalleryImagePrevious', {
|
||||
trackEvent('GalleryImagePrevious', {
|
||||
project_id: props.project.id,
|
||||
url: expandedGalleryItem.value,
|
||||
})
|
||||
@@ -135,7 +135,7 @@ const expandImage = (item, index) => {
|
||||
expandedGalleryIndex.value = index
|
||||
zoomedIn.value = false
|
||||
|
||||
mixpanel_track('GalleryImageExpand', {
|
||||
trackEvent('GalleryImageExpand', {
|
||||
project_id: props.project.id,
|
||||
url: item.url,
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import { install as packInstall } from '@/helpers/pack.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel.js'
|
||||
import { trackEvent } from '@/helpers/analytics.js'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export const useInstall = defineStore('installStore', {
|
||||
@@ -51,7 +51,7 @@ export const install = async (projectId, versionId, instancePath, source, callba
|
||||
if (packs.length === 0 || !packs.find((pack) => pack.linked_data?.project_id === project.id)) {
|
||||
await packInstall(project.id, version, project.title, project.icon_url).catch(handleError)
|
||||
|
||||
mixpanel_track('PackInstall', {
|
||||
trackEvent('PackInstall', {
|
||||
id: project.id,
|
||||
version_id: version,
|
||||
title: project.title,
|
||||
@@ -107,7 +107,7 @@ export const install = async (projectId, versionId, instancePath, source, callba
|
||||
await add_project_from_version(instance.path, version.id).catch(handleError)
|
||||
await installVersionDependencies(instance, version)
|
||||
|
||||
mixpanel_track('ProjectInstall', {
|
||||
trackEvent('ProjectInstall', {
|
||||
loader: instance.loader,
|
||||
game_version: instance.game_version,
|
||||
id: project.id,
|
||||
|
||||
@@ -23,7 +23,3 @@ export const handleError = (err) => {
|
||||
})
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
export const handleMixpanelError = (err) => {
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
],
|
||||
"enable": true
|
||||
},
|
||||
"csp": "default-src 'self'; connect-src ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://mixpanel.com https://*.mixpanel.com https://*.cloudflare.com https://api.mclo.gs; font-src https://cdn-raw.modrinth.com/fonts/inter/; img-src tauri: https: data: blob: 'unsafe-inline' asset: https://asset.localhost; script-src https://*.cloudflare.com 'self'; frame-src https://*.cloudflare.com https://www.youtube.com https://www.youtube-nocookie.com https://discord.com 'self'; style-src unsafe-inline 'self'"
|
||||
"csp": "default-src 'self'; connect-src ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://*.cloudflare.com https://api.mclo.gs; font-src https://cdn-raw.modrinth.com/fonts/inter/; img-src tauri: https: data: blob: 'unsafe-inline' asset: https://asset.localhost; script-src https://*.cloudflare.com 'self'; frame-src https://*.cloudflare.com https://www.youtube.com https://www.youtube-nocookie.com https://discord.com 'self'; style-src unsafe-inline 'self'"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
<p>This data is used to deliver statistics.</p>
|
||||
|
||||
<h3>Usage data</h3>
|
||||
<p>When you interact with the Modrinth App or the Website, we collect through MixPanel:</p>
|
||||
<p>When you interact with the Modrinth App or the Website, we collect through PostHog:</p>
|
||||
<ul>
|
||||
<li>Your IP address</li>
|
||||
<li>Your anonymized user ID</li>
|
||||
@@ -150,9 +150,10 @@
|
||||
<a href="https://www.cloudflare.com/en-gb/gdpr/introduction/"> Cloudflare </a>
|
||||
</li>
|
||||
<li><a href="https://sentry.io/trust/privacy/">Sentry</a></li>
|
||||
<li><a href="https://mixpanel.com/legal/privacy-policy">MixPanel</a></li>
|
||||
<li><a href="https://posthog.com/privacy">PostHog</a></li>
|
||||
<li><a href="https://www.beehiiv.com/privacy">BeeHiiv</a></li>
|
||||
<li><a href="https://www.paypal.com/us/legalhub/privacy-full">PayPal</a></li>
|
||||
<li><a href="https://stripe.com/privacy">Stripe</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
Data that we specifically collect isn't shared with any other third party. We do not sell any
|
||||
|
||||
Reference in New Issue
Block a user