feat:移除了弹窗,服务器添加sls
This commit is contained in:
292
apps/app-frontend/src/components/ui/JavaSelector.vue
Normal file
292
apps/app-frontend/src/components/ui/JavaSelector.vue
Normal file
@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<JavaDetectionModal ref="detectJavaModal" @submit="commitSelection" />
|
||||
<div :id="props.id" class="flex flex-wrap justify-between items-center gap-2" :class="{ compact }">
|
||||
<div class="flex items-center gap-2 w-full min-w-0">
|
||||
<StyledInput
|
||||
autocomplete="off"
|
||||
:disabled="props.disabled"
|
||||
:model-value="props.modelValue ? props.modelValue.path : ''"
|
||||
:placeholder="placeholder ?? '/path/to/java'"
|
||||
wrapper-class="flex-1 min-w-0"
|
||||
@update:model-value="
|
||||
(val) => {
|
||||
emit('update:modelValue', {
|
||||
...props.modelValue,
|
||||
path: val,
|
||||
})
|
||||
}
|
||||
"
|
||||
@focusout="emit('commit', props.modelValue)"
|
||||
/>
|
||||
<ButtonStyled
|
||||
:color="
|
||||
!hoveringTest && !testingJava
|
||||
? testingJavaSuccess === true
|
||||
? 'green'
|
||||
: 'red'
|
||||
: 'standard'
|
||||
"
|
||||
color-fill="text"
|
||||
>
|
||||
<button
|
||||
class="!shadow-none"
|
||||
:aria-label="formatMessage(messages.testInstallation)"
|
||||
:disabled="testingJava || props.disabled"
|
||||
@click="runTest(props.modelValue?.path)"
|
||||
@mouseenter="!props.disabled && (hoveringTest = true)"
|
||||
@mouseleave="hoveringTest = false"
|
||||
>
|
||||
<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>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<span class="flex items-center gap-2 m-0">
|
||||
<ButtonStyled v-if="props.version">
|
||||
<button
|
||||
v-tooltip="recommendedInstalled ? formatMessage(messages.alreadyInstalled) : undefined"
|
||||
class="!shadow-none"
|
||||
:aria-label="formatMessage(messages.installRecommended)"
|
||||
:disabled="props.disabled || installingJava || recommendedInstalled"
|
||||
@click="reinstallJava"
|
||||
>
|
||||
<DownloadIcon />
|
||||
{{
|
||||
installingJava
|
||||
? formatMessage(commonMessages.installingLabel)
|
||||
: formatMessage(messages.installRecommended)
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button
|
||||
class="!shadow-none"
|
||||
:aria-label="formatMessage(props.selectAllVersions ? messages.select : messages.detect)"
|
||||
:disabled="props.disabled"
|
||||
@click="autoDetect"
|
||||
>
|
||||
<SearchIcon />
|
||||
{{ formatMessage(props.selectAllVersions ? messages.select : messages.detect) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button
|
||||
class="!shadow-none"
|
||||
:aria-label="formatMessage(messages.browseForExecutable)"
|
||||
:disabled="props.disabled"
|
||||
@click="handleJavaFileInput()"
|
||||
>
|
||||
<FolderSearchIcon />
|
||||
{{ formatMessage(messages.browse) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
DownloadIcon,
|
||||
FolderSearchIcon,
|
||||
RefreshCwIcon,
|
||||
SearchIcon,
|
||||
SpinnerIcon,
|
||||
XCircleIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { computed, 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({
|
||||
alreadyInstalled: { id: 'app.java.already-installed', defaultMessage: 'Already installed' },
|
||||
installRecommended: {
|
||||
id: 'app.java.install-recommended',
|
||||
defaultMessage: 'Install recommended',
|
||||
},
|
||||
detect: { id: 'app.java.detect', defaultMessage: 'Detect' },
|
||||
select: { id: 'app.java.select', defaultMessage: 'Select' },
|
||||
browse: { id: 'app.java.browse', defaultMessage: 'Browse' },
|
||||
browseForExecutable: {
|
||||
id: 'app.java.browse-for-executable',
|
||||
defaultMessage: 'Browse for Java executable',
|
||||
},
|
||||
testInstallation: {
|
||||
id: 'app.java.test-installation',
|
||||
defaultMessage: 'Test Java installation',
|
||||
},
|
||||
})
|
||||
|
||||
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,
|
||||
},
|
||||
selectAllVersions: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'commit'])
|
||||
|
||||
const {
|
||||
testingJava,
|
||||
javaTestResult: testingJavaSuccess,
|
||||
testJavaInstallationDebounced,
|
||||
testJavaInstallation,
|
||||
} = useJavaTest()
|
||||
const recommendedJavaTest = useJavaTest()
|
||||
|
||||
const installingJava = ref(false)
|
||||
const hoveringTest = ref(false)
|
||||
const testVersion = computed(() => (props.selectAllVersions ? null : props.version))
|
||||
const recommendedInstalled = computed(() => {
|
||||
if (props.version == null) return false
|
||||
if (props.selectAllVersions) return recommendedJavaTest.javaTestResult.value === true
|
||||
return testingJavaSuccess.value === true
|
||||
})
|
||||
let hasInitialized = false
|
||||
|
||||
async function runTest(path) {
|
||||
await testJavaInstallation(path, testVersion.value, true)
|
||||
if (props.version != null) {
|
||||
await recommendedJavaTest.testJavaInstallation(path, props.version, false)
|
||||
}
|
||||
}
|
||||
|
||||
function commitSelection(javaVersion) {
|
||||
emit('update:modelValue', javaVersion)
|
||||
emit('commit', javaVersion)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.modelValue?.path,
|
||||
(newPath) => {
|
||||
if (newPath) {
|
||||
if (!hasInitialized) {
|
||||
testJavaInstallation(newPath, testVersion.value, false)
|
||||
if (props.version != null) {
|
||||
recommendedJavaTest.testJavaInstallation(newPath, props.version, false)
|
||||
}
|
||||
hasInitialized = true
|
||||
} else {
|
||||
testJavaInstallationDebounced(newPath, testVersion.value)
|
||||
if (props.version != null) {
|
||||
recommendedJavaTest.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 ?? 0,
|
||||
architecture: 'x86',
|
||||
}
|
||||
}
|
||||
|
||||
trackEvent('JavaManualSelect', {
|
||||
version: props.version,
|
||||
})
|
||||
|
||||
commitSelection(result)
|
||||
}
|
||||
}
|
||||
|
||||
const detectJavaModal = ref(null)
|
||||
async function autoDetect() {
|
||||
const filterVersion = props.selectAllVersions ? null : props.version
|
||||
if (!props.compact) {
|
||||
detectJavaModal.value.show(filterVersion, props.modelValue)
|
||||
} else {
|
||||
const versions = await find_filtered_jres(filterVersion, false, false).catch(handleError)
|
||||
if (versions?.length > 0) {
|
||||
commitSelection(versions[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function reinstallJava() {
|
||||
installingJava.value = true
|
||||
try {
|
||||
const path = await auto_install_java(props.version).catch(handleError)
|
||||
if (!path) return
|
||||
|
||||
let result = await get_jre(path).catch(handleError)
|
||||
if (!result) {
|
||||
result = {
|
||||
path: path,
|
||||
version: props.version?.toString() ?? '',
|
||||
parsed_version: props.version ?? 0,
|
||||
architecture: 'x86',
|
||||
}
|
||||
}
|
||||
|
||||
trackEvent('JavaReInstall', { path: path, version: props.version })
|
||||
commitSelection(result)
|
||||
runTest(result.path)
|
||||
} finally {
|
||||
installingJava.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user