You've already forked AstralRinth
forked from didirus/AstralRinth
Analytics + more bug fixes (#144)
* Analytics + more bug fixes * debug deadlock * Fix mostly everything * merge fixes * fix rest * final fixeS
This commit is contained in:
@@ -12,10 +12,16 @@ import {
|
||||
Card,
|
||||
DropdownSelect,
|
||||
SearchIcon,
|
||||
XIcon,
|
||||
Button,
|
||||
formatCategoryHeader,
|
||||
ModalConfirm,
|
||||
} from 'omorphia'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { remove } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
|
||||
const props = defineProps({
|
||||
instances: {
|
||||
@@ -32,6 +38,19 @@ const props = defineProps({
|
||||
const instanceOptions = ref(null)
|
||||
const instanceComponents = ref(null)
|
||||
|
||||
const themeStore = useTheming()
|
||||
const currentDeleteInstance = ref(null)
|
||||
const confirmModal = ref(null)
|
||||
|
||||
async function deleteProfile() {
|
||||
if (currentDeleteInstance.value) {
|
||||
instanceComponents.value = instanceComponents.value.filter(
|
||||
(x) => x.instance.path !== currentDeleteInstance.value
|
||||
)
|
||||
await remove(currentDeleteInstance.value).catch(handleError)
|
||||
}
|
||||
}
|
||||
|
||||
const handleRightClick = (event, item) => {
|
||||
const baseOptions = [
|
||||
{ name: 'add_content' },
|
||||
@@ -68,13 +87,12 @@ const handleRightClick = (event, item) => {
|
||||
}
|
||||
|
||||
const handleOptionsClick = async (args) => {
|
||||
console.log(args)
|
||||
switch (args.option) {
|
||||
case 'play':
|
||||
args.item.play()
|
||||
args.item.play(null, 'InstanceGridContextMenu')
|
||||
break
|
||||
case 'stop':
|
||||
args.item.stop()
|
||||
args.item.stop(null, 'InstanceGridContextMenu')
|
||||
break
|
||||
case 'add_content':
|
||||
await args.item.addContent()
|
||||
@@ -82,15 +100,16 @@ const handleOptionsClick = async (args) => {
|
||||
case 'edit':
|
||||
await args.item.seeInstance()
|
||||
break
|
||||
case 'delete':
|
||||
await args.item.deleteInstance()
|
||||
break
|
||||
case 'open':
|
||||
await args.item.openFolder()
|
||||
break
|
||||
case 'copy':
|
||||
await navigator.clipboard.writeText(args.item.instance.path)
|
||||
break
|
||||
case 'delete':
|
||||
currentDeleteInstance.value = args.item.instance.path
|
||||
confirmModal.value.show()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +204,15 @@ const filteredResults = computed(() => {
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<ModalConfirm
|
||||
ref="confirmModal"
|
||||
title="Are you sure you want to delete this instance?"
|
||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||
:has-to-type="false"
|
||||
proceed-label="Delete"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
@proceed="deleteProfile"
|
||||
/>
|
||||
<Card class="header">
|
||||
<div class="iconified-input">
|
||||
<SearchIcon />
|
||||
@@ -222,7 +250,7 @@ const filteredResults = computed(() => {
|
||||
</div>
|
||||
</Card>
|
||||
<div
|
||||
v-for="(instanceSection, index) in Array.from(filteredResults, ([key, value]) => ({
|
||||
v-for="instanceSection in Array.from(filteredResults, ([key, value]) => ({
|
||||
key,
|
||||
value,
|
||||
}))"
|
||||
@@ -235,7 +263,7 @@ const filteredResults = computed(() => {
|
||||
</div>
|
||||
<section class="instances">
|
||||
<Instance
|
||||
v-for="instance in instanceSection.value"
|
||||
v-for="(instance, index) in instanceSection.value"
|
||||
ref="instanceComponents"
|
||||
:key="instance.id"
|
||||
:instance="instance"
|
||||
@@ -298,6 +326,10 @@ const filteredResults = computed(() => {
|
||||
|
||||
.iconified-input {
|
||||
flex-grow: 1;
|
||||
|
||||
input {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-dropdown {
|
||||
|
||||
@@ -12,10 +12,14 @@ import {
|
||||
StopCircleIcon,
|
||||
ExternalIcon,
|
||||
EyeIcon,
|
||||
ModalConfirm,
|
||||
} from 'omorphia'
|
||||
import Instance from '@/components/ui/Instance.vue'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { remove } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
|
||||
const props = defineProps({
|
||||
instances: {
|
||||
@@ -36,6 +40,19 @@ const modsRow = ref(null)
|
||||
const instanceOptions = ref(null)
|
||||
const instanceComponents = ref(null)
|
||||
|
||||
const themeStore = useTheming()
|
||||
const currentDeleteInstance = ref(null)
|
||||
const confirmModal = ref(null)
|
||||
|
||||
async function deleteProfile() {
|
||||
if (currentDeleteInstance.value) {
|
||||
instanceComponents.value = instanceComponents.value.filter(
|
||||
(x) => x.instance.path !== currentDeleteInstance.value
|
||||
)
|
||||
await remove(currentDeleteInstance.value).catch(handleError)
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaginationDisplay = () => {
|
||||
for (let i = 0; i < props.instances.length; i++) {
|
||||
let parentsRow = modsRow.value[i]
|
||||
@@ -114,10 +131,10 @@ const handleInstanceRightClick = (event, passedInstance) => {
|
||||
const handleOptionsClick = async (args) => {
|
||||
switch (args.option) {
|
||||
case 'play':
|
||||
await args.item.play()
|
||||
await args.item.play(null, 'InstanceRowContextMenu')
|
||||
break
|
||||
case 'stop':
|
||||
await args.item.stop()
|
||||
await args.item.stop(null, 'InstanceRowContextMenu')
|
||||
break
|
||||
case 'add_content':
|
||||
await args.item.addContent()
|
||||
@@ -126,7 +143,8 @@ const handleOptionsClick = async (args) => {
|
||||
await args.item.seeInstance()
|
||||
break
|
||||
case 'delete':
|
||||
await args.item.deleteInstance()
|
||||
currentDeleteInstance.value = args.item.instance.path
|
||||
confirmModal.value.show()
|
||||
break
|
||||
case 'open_folder':
|
||||
await args.item.openFolder()
|
||||
@@ -165,6 +183,15 @@ const getInstanceIndex = (rowIndex, index) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalConfirm
|
||||
ref="confirmModal"
|
||||
title="Are you sure you want to delete this instance?"
|
||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||
:has-to-type="false"
|
||||
proceed-label="Delete"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
@proceed="deleteProfile"
|
||||
/>
|
||||
<div class="content">
|
||||
<div v-for="(row, rowIndex) in instances" :key="row.label" class="row">
|
||||
<div class="header">
|
||||
|
||||
@@ -65,6 +65,7 @@ import {
|
||||
import { get, set } from '@/helpers/settings'
|
||||
import { WebviewWindow } from '@tauri-apps/api/window'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
defineProps({
|
||||
expanded: {
|
||||
@@ -131,6 +132,7 @@ const login = async () => {
|
||||
await setAccount(loggedIn)
|
||||
await refreshValues()
|
||||
await window.close()
|
||||
mixpanel.track('AccountLogIn')
|
||||
}
|
||||
|
||||
const logout = async (id) => {
|
||||
@@ -140,6 +142,7 @@ const logout = async (id) => {
|
||||
await setAccount(accounts.value[0])
|
||||
await refreshValues()
|
||||
}
|
||||
mixpanel.track('AccountLogOut')
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<Modal ref="incompatibleModal" header="Incompatibility warning">
|
||||
<Modal
|
||||
ref="incompatibleModal"
|
||||
header="Incompatibility warning"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
This {{ versions?.length > 0 ? 'project' : 'version' }} is not compatible with the instance
|
||||
@@ -54,9 +58,14 @@
|
||||
import { Button, Modal, XIcon, DownloadIcon, DropdownSelect, formatCategory } from 'omorphia'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { defineExpose, ref } from 'vue'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { handleError, useTheming } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const instance = ref(null)
|
||||
const project = ref(null)
|
||||
const projectType = ref(null)
|
||||
const projectTitle = ref(null)
|
||||
const versions = ref(null)
|
||||
const selectedVersion = ref(null)
|
||||
@@ -66,13 +75,26 @@ const installing = ref(false)
|
||||
let markInstalled = () => {}
|
||||
|
||||
defineExpose({
|
||||
show: (instanceVal, projectTitleVal, selectedVersions, extMarkInstalled) => {
|
||||
show: (
|
||||
instanceVal,
|
||||
projectTitleVal,
|
||||
selectedVersions,
|
||||
extMarkInstalled,
|
||||
projectIdVal,
|
||||
projectTypeVal
|
||||
) => {
|
||||
instance.value = instanceVal
|
||||
projectTitle.value = projectTitleVal
|
||||
versions.value = selectedVersions
|
||||
selectedVersion.value = selectedVersions[0]
|
||||
|
||||
project.value = projectIdVal
|
||||
projectType.value = projectTypeVal
|
||||
|
||||
incompatibleModal.value.show()
|
||||
markInstalled = extMarkInstalled
|
||||
|
||||
mixpanel.track('ProjectInstallStart', { source: 'ProjectIncompatibilityWarningModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -82,6 +104,16 @@ const install = async () => {
|
||||
installing.value = false
|
||||
markInstalled()
|
||||
incompatibleModal.value.hide()
|
||||
|
||||
mixpanel.track('ProjectInstall', {
|
||||
loader: instance.value.metadata.loader,
|
||||
game_version: instance.value.metadata.game_version,
|
||||
id: project.value,
|
||||
version_id: selectedVersion.value.id,
|
||||
project_type: projectType.value,
|
||||
title: projectTitle.value,
|
||||
source: 'ProjectIncompatibilityWarningModal',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
import { Button, Modal, XIcon, DownloadIcon } from 'omorphia'
|
||||
import { install as pack_install } from '@/helpers/pack'
|
||||
import { ref } from 'vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const version = ref('')
|
||||
const title = ref('')
|
||||
@@ -11,12 +15,14 @@ const confirmModal = ref(null)
|
||||
const installing = ref(false)
|
||||
|
||||
defineExpose({
|
||||
show: (id, projectId, projectTitle, projectIcon) => {
|
||||
show: (id, projectIdVal, projectTitle, projectIcon) => {
|
||||
version.value = id
|
||||
projectId.value = projectId
|
||||
projectId.value = projectIdVal
|
||||
title.value = projectTitle
|
||||
icon.value = projectIcon
|
||||
confirmModal.value.show()
|
||||
|
||||
mixpanel.track('PackInstallStart')
|
||||
},
|
||||
})
|
||||
|
||||
@@ -24,11 +30,18 @@ async function install() {
|
||||
installing.value = true
|
||||
await pack_install(projectId.value, version.value, title.value, icon.value ? icon.value : null)
|
||||
confirmModal.value.hide()
|
||||
|
||||
mixpanel.track('PackInstall', {
|
||||
id: projectId.value,
|
||||
version_id: version.value,
|
||||
title: title.value,
|
||||
source: 'ConfirmModal',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal ref="confirmModal" header="Are you sure?">
|
||||
<Modal ref="confirmModal" header="Are you sure?" :noblur="!themeStore.advancedRendering">
|
||||
<div class="modal-body">
|
||||
<p>You already have this modpack installed. Are you sure you want to install it again?</p>
|
||||
<div class="input-group push-right">
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Card, DownloadIcon, StopCircleIcon, Avatar, AnimatedLogo, PlayIcon } fr
|
||||
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
|
||||
import { install as pack_install } from '@/helpers/pack'
|
||||
import { list, remove, run } from '@/helpers/profile'
|
||||
import { list, run } from '@/helpers/profile'
|
||||
import {
|
||||
get_all_running_profile_paths,
|
||||
get_uuids_by_profile_path,
|
||||
@@ -16,6 +16,7 @@ import { useFetch } from '@/helpers/fetch.js'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { showInFolder } from '@/helpers/utils.js'
|
||||
import InstanceInstallModal from '@/components/ui/InstanceInstallModal.vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
@@ -91,6 +92,13 @@ const install = async (e) => {
|
||||
props.instance.icon_url
|
||||
).catch(handleError)
|
||||
modLoading.value = false
|
||||
|
||||
mixpanel.track('PackInstall', {
|
||||
id: props.instance.project_id,
|
||||
version_id: versions[0].id,
|
||||
title: props.instance.title,
|
||||
source: 'InstanceCard',
|
||||
})
|
||||
} else
|
||||
confirmModal.value.show(
|
||||
props.instance.project_id,
|
||||
@@ -99,21 +107,32 @@ const install = async (e) => {
|
||||
props.instance.icon_url
|
||||
)
|
||||
} else {
|
||||
modInstallModal.value.show(props.instance.project_id, versions)
|
||||
modInstallModal.value.show(
|
||||
props.instance.project_id,
|
||||
versions,
|
||||
props.instance.title,
|
||||
props.instance.project_type
|
||||
)
|
||||
}
|
||||
|
||||
modLoading.value = false
|
||||
}
|
||||
|
||||
const play = async (e) => {
|
||||
const play = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
modLoading.value = true
|
||||
uuid.value = await run(props.instance.path).catch(handleError)
|
||||
modLoading.value = false
|
||||
playing.value = true
|
||||
|
||||
mixpanel.track('InstancePlay', {
|
||||
loader: props.instance.metadata.loader,
|
||||
game_version: props.instance.metadata.game_version,
|
||||
source: context,
|
||||
})
|
||||
}
|
||||
|
||||
const stop = async (e) => {
|
||||
const stop = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
playing.value = false
|
||||
|
||||
@@ -126,11 +145,13 @@ const stop = async (e) => {
|
||||
uuids.forEach(async (u) => await kill_by_uuid(u).catch(handleError))
|
||||
} else await kill_by_uuid(uuid.value).catch(handleError) // If we still have the uuid, just kill it
|
||||
|
||||
uuid.value = null
|
||||
}
|
||||
mixpanel.track('InstanceStop', {
|
||||
loader: props.instance.metadata.loader,
|
||||
game_version: props.instance.metadata.game_version,
|
||||
source: context,
|
||||
})
|
||||
|
||||
const deleteInstance = async () => {
|
||||
await remove(props.instance.path).catch(handleError)
|
||||
uuid.value = null
|
||||
}
|
||||
|
||||
const openFolder = async () => {
|
||||
@@ -151,7 +172,6 @@ defineExpose({
|
||||
stop,
|
||||
seeInstance,
|
||||
openFolder,
|
||||
deleteInstance,
|
||||
addContent,
|
||||
instance: props.instance,
|
||||
})
|
||||
@@ -190,7 +210,7 @@ onUnmounted(() => unlisten())
|
||||
<div
|
||||
v-if="props.instance.metadata && playing === false && modLoading === false"
|
||||
class="install cta button-base"
|
||||
@click="play"
|
||||
@click="(e) => play(e, 'InstanceCard')"
|
||||
>
|
||||
<PlayIcon />
|
||||
</div>
|
||||
@@ -200,7 +220,7 @@ onUnmounted(() => unlisten())
|
||||
<div
|
||||
v-else-if="playing === true"
|
||||
class="stop cta button-base"
|
||||
@click="stop"
|
||||
@click="(e) => stop(e, 'InstanceCard')"
|
||||
@mousehover="checkProcess"
|
||||
>
|
||||
<StopCircleIcon />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal ref="modal" header="Create instance">
|
||||
<Modal ref="modal" header="Create instance" :noblur="!themeStore.advancedRendering">
|
||||
<div class="modal-header">
|
||||
<Chips v-model="creationType" :items="['custom', 'from file']" />
|
||||
</div>
|
||||
@@ -116,9 +116,13 @@ import {
|
||||
} from '@/helpers/metadata'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { install_from_file } from '@/helpers/pack.js'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const profile_name = ref('')
|
||||
const game_version = ref('')
|
||||
const loader = ref('vanilla')
|
||||
@@ -144,6 +148,8 @@ defineExpose({
|
||||
icon.value = null
|
||||
display_icon.value = null
|
||||
modal.value.show()
|
||||
|
||||
mixpanel.track('InstanceCreateStart', { source: 'CreationModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -195,6 +201,7 @@ const create_instance = async () => {
|
||||
creating.value = true
|
||||
const loader_version_value =
|
||||
loader_version.value === 'other' ? specified_loader_version.value : loader_version.value
|
||||
const loaderVersion = loader.value === 'vanilla' ? null : loader_version_value ?? 'stable'
|
||||
|
||||
modal.value.hide()
|
||||
creating.value = false
|
||||
@@ -206,6 +213,15 @@ const create_instance = async () => {
|
||||
loader.value === 'vanilla' ? null : loader_version_value ?? 'stable',
|
||||
icon.value
|
||||
).catch(handleError)
|
||||
|
||||
mixpanel.track('InstanceCreate', {
|
||||
profile_name: profile_name.value,
|
||||
game_version: game_version.value,
|
||||
loader: loader.value,
|
||||
loader_version: loaderVersion,
|
||||
has_icon: !!icon.value,
|
||||
source: 'CreationModal',
|
||||
})
|
||||
}
|
||||
|
||||
const upload_icon = async () => {
|
||||
@@ -253,11 +269,20 @@ const openFile = async () => {
|
||||
|
||||
modal.value.hide()
|
||||
await install_from_file(newProject).catch(handleError)
|
||||
|
||||
mixpanel.track('InstanceCreate', {
|
||||
source: 'CreationModalFileOpen',
|
||||
})
|
||||
}
|
||||
|
||||
listen('tauri://file-drop', async (event) => {
|
||||
modal.value.hide()
|
||||
await install_from_file(event.payload[0]).catch(handleError)
|
||||
if (event.payload && event.payload.length > 0 && event.payload[0].endsWith('.mrpack')) {
|
||||
await install_from_file(event.payload[0]).catch(handleError)
|
||||
mixpanel.track('InstanceCreate', {
|
||||
source: 'CreationModalFileDrop',
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -12,16 +12,28 @@ import {
|
||||
CheckIcon,
|
||||
} from 'omorphia'
|
||||
import { computed, ref } from 'vue'
|
||||
import { add_project_from_version as installMod, check_installed, list } from '@/helpers/profile'
|
||||
import {
|
||||
add_project_from_version as installMod,
|
||||
check_installed,
|
||||
get,
|
||||
list,
|
||||
} from '@/helpers/profile'
|
||||
import { tauri } from '@tauri-apps/api'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||
import { create } from '@/helpers/profile'
|
||||
import { installVersionDependencies } from '@/helpers/utils'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const versions = ref([])
|
||||
const project = ref('')
|
||||
const projectTitle = ref('')
|
||||
const projectType = ref('')
|
||||
|
||||
const installModal = ref(null)
|
||||
const searchFilter = ref('')
|
||||
const showCreation = ref(false)
|
||||
@@ -33,13 +45,18 @@ const gameVersion = ref(null)
|
||||
const creatingInstance = ref(false)
|
||||
|
||||
defineExpose({
|
||||
show: async (projectId, selectedVersions) => {
|
||||
show: async (projectId, selectedVersions, title, type) => {
|
||||
project.value = projectId
|
||||
versions.value = selectedVersions
|
||||
projectTitle.value = title
|
||||
projectType.value = type
|
||||
|
||||
installModal.value.show()
|
||||
searchFilter.value = ''
|
||||
|
||||
profiles.value = await getData()
|
||||
|
||||
mixpanel.track('ProjectInstallStart', { source: 'ProjectInstallModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -59,6 +76,16 @@ async function install(instance) {
|
||||
|
||||
instance.installedMod = true
|
||||
instance.installing = false
|
||||
|
||||
mixpanel.track('ProjectInstall', {
|
||||
loader: instance.metadata.loader,
|
||||
game_version: instance.metadata.game_version,
|
||||
id: project.value,
|
||||
version_id: version.id,
|
||||
project_type: projectType.value,
|
||||
title: projectTitle.value,
|
||||
source: 'ProjectInstallModal',
|
||||
})
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
@@ -88,6 +115,7 @@ async function getData() {
|
||||
return filtered
|
||||
}
|
||||
|
||||
const alreadySentCreation = ref(false)
|
||||
const toggleCreation = () => {
|
||||
showCreation.value = !showCreation.value
|
||||
name.value = null
|
||||
@@ -95,6 +123,11 @@ const toggleCreation = () => {
|
||||
display_icon.value = null
|
||||
gameVersion.value = null
|
||||
loader.value = null
|
||||
|
||||
if (!alreadySentCreation.value) {
|
||||
alreadySentCreation.value = false
|
||||
mixpanel.track('InstanceCreateStart', { source: 'ProjectInstallModal' })
|
||||
}
|
||||
}
|
||||
|
||||
const upload_icon = async () => {
|
||||
@@ -119,20 +152,46 @@ const reset_icon = () => {
|
||||
|
||||
const createInstance = async () => {
|
||||
creatingInstance.value = true
|
||||
|
||||
const loader =
|
||||
versions.value[0].loaders[0] !== 'forge' ||
|
||||
versions.value[0].loaders[0] !== 'fabric' ||
|
||||
versions.value[0].loaders[0] !== 'quilt'
|
||||
? versions.value[0].loaders[0]
|
||||
: 'vanilla'
|
||||
|
||||
const id = await create(
|
||||
name.value,
|
||||
versions.value[0].game_versions[0],
|
||||
versions.value[0].loaders[0] !== 'forge' ||
|
||||
versions.value[0].loaders[0] !== 'fabric' ||
|
||||
versions.value[0].loaders[0] !== 'quilt'
|
||||
? versions.value[0].loaders[0]
|
||||
: 'vanilla',
|
||||
loader,
|
||||
'latest',
|
||||
icon.value
|
||||
).catch(handleError)
|
||||
|
||||
await installMod(id, versions.value[0].id).catch(handleError)
|
||||
|
||||
const instance = await get(id, true)
|
||||
await installVersionDependencies(instance, versions.value)
|
||||
|
||||
mixpanel.track('InstanceCreate', {
|
||||
profile_name: name.value,
|
||||
game_version: versions.value[0].game_versions[0],
|
||||
loader: loader,
|
||||
loader_version: 'latest',
|
||||
has_icon: !!icon.value,
|
||||
source: 'ProjectInstallModal',
|
||||
})
|
||||
|
||||
mixpanel.track('ProjectInstall', {
|
||||
loader: loader,
|
||||
game_version: versions.value[0].game_versions[0],
|
||||
id: project.value,
|
||||
version_id: versions.value[0].id,
|
||||
project_type: projectType.value,
|
||||
title: projectTitle.value,
|
||||
source: 'ProjectInstallModal',
|
||||
})
|
||||
|
||||
installModal.value.hide()
|
||||
creatingInstance.value = false
|
||||
}
|
||||
@@ -143,7 +202,11 @@ const check_valid = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal ref="installModal" header="Install project to instance">
|
||||
<Modal
|
||||
ref="installModal"
|
||||
header="Install project to instance"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<input
|
||||
v-model="searchFilter"
|
||||
@@ -159,7 +222,15 @@ const check_valid = computed(() => {
|
||||
class="profile-button"
|
||||
@click="$router.push(`/instance/${encodeURIComponent(profile.path)}`)"
|
||||
>
|
||||
<Avatar :src="convertFileSrc(profile.metadata.icon)" class="profile-image" />
|
||||
<Avatar
|
||||
:src="
|
||||
!profile.metadata.icon ||
|
||||
(profile.metadata.icon && profile.metadata.icon.startsWith('http'))
|
||||
? profile.metadata.icon
|
||||
: convertFileSrc(profile.metadata?.icon)
|
||||
"
|
||||
class="profile-image"
|
||||
/>
|
||||
{{ profile.metadata.name }}
|
||||
</Button>
|
||||
<Button :disabled="profile.installedMod || profile.installing" @click="install(profile)">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal ref="detectJavaModal" header="Select java version">
|
||||
<Modal ref="detectJavaModal" header="Select java version" :noblur="!themeStore.advancedRendering">
|
||||
<div class="auto-detect-modal">
|
||||
<div class="table">
|
||||
<div class="table-row table-head">
|
||||
@@ -44,6 +44,10 @@ import {
|
||||
get_all_jre,
|
||||
} from '@/helpers/jre.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const chosenInstallOptions = ref([])
|
||||
const detectJavaModal = ref(null)
|
||||
@@ -75,6 +79,10 @@ const emit = defineEmits(['submit'])
|
||||
function setJavaInstall(javaInstall) {
|
||||
emit('submit', javaInstall)
|
||||
detectJavaModal.value.hide()
|
||||
mixpanel.track('JavaAutoDetect', {
|
||||
path: javaInstall.path,
|
||||
version: javaInstall.version,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@@ -83,7 +91,7 @@ function setJavaInstall(javaInstall) {
|
||||
|
||||
.table {
|
||||
.table-row {
|
||||
grid-template-columns: 1fr 4fr 1.5fr;
|
||||
grid-template-columns: 1fr 4fr min-content;
|
||||
}
|
||||
|
||||
span {
|
||||
|
||||
@@ -52,6 +52,7 @@ import { get_jre } from '@/helpers/jre.js'
|
||||
import { ref } from 'vue'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
const props = defineProps({
|
||||
version: {
|
||||
@@ -85,6 +86,11 @@ async function testJava() {
|
||||
testingJava.value = false
|
||||
testingJavaSuccess.value = !!result
|
||||
|
||||
mixpanel.track('JavaTest', {
|
||||
path: props.modelValue ? props.modelValue.path : '',
|
||||
success: !!result,
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
testingJavaSuccess.value = null
|
||||
}, 2000)
|
||||
@@ -101,6 +107,11 @@ async function handleJavaFileInput() {
|
||||
version: props.version.toString(),
|
||||
architecture: 'x86',
|
||||
}
|
||||
|
||||
mixpanel.track('JavaManualSelect', {
|
||||
path: filePath,
|
||||
version: props.version,
|
||||
})
|
||||
}
|
||||
|
||||
emit('update:modelValue', result)
|
||||
|
||||
@@ -113,6 +113,7 @@ 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 from 'mixpanel-browser'
|
||||
|
||||
const router = useRouter()
|
||||
const card = ref(null)
|
||||
@@ -140,6 +141,12 @@ const stop = async (path) => {
|
||||
try {
|
||||
const processes = await getProfileProcesses(path ?? selectedProfile.value.path)
|
||||
await killProfile(processes[0])
|
||||
|
||||
mixpanel.track('InstanceStop', {
|
||||
loader: currentProcesses.value[0].metadata.loader,
|
||||
game_version: currentProcesses.value[0].metadata.game_version,
|
||||
source: 'AppBar',
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
@@ -50,12 +50,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="install">
|
||||
<Button
|
||||
:to="`/browse/${project.slug}`"
|
||||
color="primary"
|
||||
:disabled="installed || installing"
|
||||
@click.stop="install()"
|
||||
>
|
||||
<Button color="primary" :disabled="installed || installing" @click.stop="install()">
|
||||
<DownloadIcon v-if="!installed" />
|
||||
<CheckIcon v-else />
|
||||
{{ installing ? 'Installing' : installed ? 'Installed' : 'Install' }}
|
||||
@@ -87,6 +82,7 @@ import { install as packInstall } from '@/helpers/pack.js'
|
||||
import { installVersionDependencies } from '@/helpers/utils.js'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const props = defineProps({
|
||||
@@ -159,6 +155,13 @@ async function install() {
|
||||
props.project.title,
|
||||
props.project.icon_url
|
||||
).catch(handleError)
|
||||
|
||||
mixpanel.track('PackInstall', {
|
||||
id: props.project.project_id,
|
||||
version_id: queuedVersionData.id,
|
||||
title: props.project.title,
|
||||
source: 'SearchCard',
|
||||
})
|
||||
} else {
|
||||
props.confirmModal.show(
|
||||
props.project.project_id,
|
||||
@@ -174,16 +177,33 @@ async function install() {
|
||||
props.instance,
|
||||
props.project.title,
|
||||
versions,
|
||||
() => (installed.value = true)
|
||||
() => (installed.value = true),
|
||||
props.project.project_id,
|
||||
props.project.project_type
|
||||
)
|
||||
installing.value = false
|
||||
return
|
||||
} else {
|
||||
await installMod(props.instance.path, queuedVersionData.id).catch(handleError)
|
||||
installVersionDependencies(props.instance, queuedVersionData)
|
||||
await installVersionDependencies(props.instance, queuedVersionData)
|
||||
|
||||
mixpanel.track('ProjectInstall', {
|
||||
loader: props.instance.metadata.loader,
|
||||
game_version: props.instance.metadata.game_version,
|
||||
id: props.project.project_id,
|
||||
project_type: props.project.project_type,
|
||||
version_id: queuedVersionData.id,
|
||||
title: props.project.title,
|
||||
source: 'SearchCard',
|
||||
})
|
||||
}
|
||||
} else {
|
||||
props.modInstallModal.show(props.project.project_id, versions)
|
||||
props.modInstallModal.show(
|
||||
props.project.project_id,
|
||||
versions,
|
||||
props.project.title,
|
||||
props.project.project_type
|
||||
)
|
||||
installing.value = false
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user