mirror of
https://github.com/modrinth/code.git
synced 2026-07-31 13:16:38 +00:00
310 lines
6.9 KiB
Vue
310 lines
6.9 KiB
Vue
<template>
|
|
<JavaDetectionModal ref="detectJavaModal" @submit="(val) => emit('update:modelValue', val)" />
|
|
<div :id="props.id" class="toggle-setting" :class="{ compact }">
|
|
<div class="input-with-status">
|
|
<StyledInput
|
|
autocomplete="off"
|
|
:disabled="props.disabled"
|
|
:model-value="props.modelValue ? props.modelValue.path : ''"
|
|
:placeholder="placeholder ?? formatMessage(messages.pathPlaceholder)"
|
|
wrapper-class="installation-input"
|
|
@update:model-value="
|
|
(val) => {
|
|
emit('update:modelValue', {
|
|
...props.modelValue,
|
|
path: val,
|
|
})
|
|
}
|
|
"
|
|
/>
|
|
<Button
|
|
type="quiet"
|
|
:color="
|
|
!hoveringTest && !testingJava
|
|
? testingJavaSuccess === true
|
|
? 'green'
|
|
: 'red'
|
|
: undefined
|
|
"
|
|
:aria-label="formatMessage(messages.testJavaInstallation)"
|
|
class="!text-[var(--legacy-button-color,var(--color-base))] [&>svg]:!text-[var(--legacy-button-color,var(--color-primary))]"
|
|
:disabled="testingJava || props.disabled"
|
|
@click="runTest(props.modelValue?.path)"
|
|
@mouseenter="!props.disabled && (hoveringTest = true)"
|
|
@mouseleave="hoveringTest = false"
|
|
:style="{ '--legacy-button-color': (
|
|
!hoveringTest && !testingJava
|
|
? testingJavaSuccess === true
|
|
? 'green'
|
|
: 'red'
|
|
: 'standard'
|
|
) && (
|
|
!hoveringTest && !testingJava
|
|
? testingJavaSuccess === true
|
|
? 'green'
|
|
: 'red'
|
|
: 'standard'
|
|
) !== 'standard' ? `var(--color-${
|
|
!hoveringTest && !testingJava
|
|
? testingJavaSuccess === true
|
|
? 'green'
|
|
: 'red'
|
|
: 'standard'
|
|
})` : undefined }">
|
|
<SpinnerIcon v-if="testingJava" class="animate-spin h-4 w-4" />
|
|
<CheckCircleIcon
|
|
v-else-if="testingJavaSuccess === true && !hoveringTest"
|
|
class="h-4 w-4"
|
|
/>
|
|
<XCircleIcon v-else-if="testingJavaSuccess !== true && !hoveringTest" class="h-4 w-4" />
|
|
<RefreshCwIcon v-else-if="!props.disabled" class="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
<span class="installation-buttons">
|
|
<Button v-if="props.version"
|
|
v-tooltip="
|
|
testingJavaSuccess === true ? formatMessage(messages.alreadyInstalled) : undefined
|
|
"
|
|
:disabled="props.disabled || installingJava || testingJavaSuccess === true"
|
|
@click="reinstallJava"
|
|
>
|
|
<DownloadIcon />
|
|
{{
|
|
installingJava
|
|
? formatMessage(messages.installing)
|
|
: formatMessage(messages.installRecommended)
|
|
}}
|
|
</Button>
|
|
<Button :disabled="props.disabled" @click="autoDetect">
|
|
<SearchIcon />
|
|
{{ formatMessage(messages.detect) }}
|
|
</Button>
|
|
<Button :disabled="props.disabled" @click="handleJavaFileInput()">
|
|
<FolderSearchIcon />
|
|
{{ formatMessage(messages.browse) }}
|
|
</Button>
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { Button } from '@modrinth/ui'
|
|
import {
|
|
CheckCircleIcon,
|
|
DownloadIcon,
|
|
FolderSearchIcon,
|
|
RefreshCwIcon,
|
|
SearchIcon,
|
|
SpinnerIcon,
|
|
XCircleIcon,
|
|
} from '@modrinth/assets'
|
|
import {
|
|
defineMessages,
|
|
injectNotificationManager,
|
|
StyledInput,
|
|
useVIntl,
|
|
} from '@modrinth/ui'
|
|
import { open } from '@tauri-apps/plugin-dialog'
|
|
import { ref, watch } from 'vue'
|
|
|
|
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
|
import useJavaTest from '@/composables/useJavaTest'
|
|
import { trackEvent } from '@/helpers/analytics'
|
|
import { auto_install_java, find_filtered_jres, get_jre } from '@/helpers/jre.js'
|
|
|
|
const { handleError } = injectNotificationManager()
|
|
const { formatMessage } = useVIntl()
|
|
|
|
const messages = defineMessages({
|
|
pathPlaceholder: {
|
|
id: 'app.java-selector.path.placeholder',
|
|
defaultMessage: '/path/to/java',
|
|
},
|
|
testJavaInstallation: {
|
|
id: 'app.java-selector.test-installation',
|
|
defaultMessage: 'Test Java installation',
|
|
},
|
|
alreadyInstalled: {
|
|
id: 'app.java-selector.already-installed',
|
|
defaultMessage: 'Already installed',
|
|
},
|
|
installing: {
|
|
id: 'app.java-selector.installing',
|
|
defaultMessage: 'Installing...',
|
|
},
|
|
installRecommended: {
|
|
id: 'app.java-selector.install-recommended',
|
|
defaultMessage: 'Install recommended',
|
|
},
|
|
detect: {
|
|
id: 'app.java-selector.detect',
|
|
defaultMessage: 'Detect',
|
|
},
|
|
browse: {
|
|
id: 'app.java-selector.browse',
|
|
defaultMessage: 'Browse',
|
|
},
|
|
})
|
|
|
|
const props = defineProps({
|
|
id: {
|
|
type: String,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
version: {
|
|
type: Number,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
modelValue: {
|
|
type: Object,
|
|
default: () => ({
|
|
path: '',
|
|
version: '',
|
|
}),
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false,
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
compact: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits(['update:modelValue'])
|
|
|
|
const {
|
|
testingJava,
|
|
javaTestResult: testingJavaSuccess,
|
|
testJavaInstallationDebounced,
|
|
testJavaInstallation,
|
|
} = useJavaTest()
|
|
|
|
const installingJava = ref(false)
|
|
const hoveringTest = ref(false)
|
|
let hasInitialized = false
|
|
|
|
async function runTest(path) {
|
|
await testJavaInstallation(path, props.version, true)
|
|
}
|
|
|
|
watch(
|
|
() => props.modelValue?.path,
|
|
(newPath) => {
|
|
if (newPath) {
|
|
if (!hasInitialized) {
|
|
testJavaInstallation(newPath, props.version, false)
|
|
hasInitialized = true
|
|
} else {
|
|
testJavaInstallationDebounced(newPath, props.version)
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
async function handleJavaFileInput() {
|
|
const filePath = await open()
|
|
|
|
if (filePath) {
|
|
let result = await get_jre(filePath.path ?? filePath).catch(handleError)
|
|
if (!result) {
|
|
result = {
|
|
path: filePath.path ?? filePath,
|
|
version: props.version.toString(),
|
|
parsed_version: props.version,
|
|
architecture: 'x86',
|
|
}
|
|
}
|
|
|
|
trackEvent('JavaManualSelect', {
|
|
version: props.version,
|
|
})
|
|
|
|
emit('update:modelValue', result)
|
|
}
|
|
}
|
|
|
|
const detectJavaModal = ref(null)
|
|
async function autoDetect() {
|
|
if (!props.compact) {
|
|
detectJavaModal.value.show(props.version, props.modelValue)
|
|
} else {
|
|
const versions = await find_filtered_jres(props.version).catch(handleError)
|
|
if (versions.length > 0) {
|
|
emit('update:modelValue', versions[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
async function reinstallJava() {
|
|
installingJava.value = true
|
|
const path = await auto_install_java(props.version).catch(handleError)
|
|
let result = await get_jre(path)
|
|
|
|
if (!result) {
|
|
result = {
|
|
path: path,
|
|
version: props.version.toString(),
|
|
parsed_version: props.version,
|
|
architecture: 'x86',
|
|
}
|
|
}
|
|
|
|
trackEvent('JavaReInstall', {
|
|
path: path,
|
|
version: props.version,
|
|
})
|
|
|
|
emit('update:modelValue', result)
|
|
installingJava.value = false
|
|
runTest(result.path)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.input-with-status {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
width: 100%;
|
|
min-width: 0;
|
|
}
|
|
|
|
.installation-input {
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
}
|
|
|
|
.toggle-setting {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
|
|
&.compact {
|
|
flex-wrap: wrap;
|
|
}
|
|
}
|
|
|
|
.installation-buttons {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin: 0;
|
|
}
|
|
</style>
|