fix: Fix Cluster java selection modal

This commit is contained in:
LynithDev 2024-12-14 13:31:00 +01:00
parent f696419884
commit 8f08812216
6 changed files with 166 additions and 41 deletions

View file

@ -7,6 +7,7 @@ use onelauncher::cluster::{self};
use onelauncher::data::{Loader, PackageData};
use onelauncher::processor::DetailedProcess;
use onelauncher::store::{Cluster, ClusterPath};
use onelauncher::utils::java::JavaVersion;
use onelauncher::State;
use serde::{Deserialize, Serialize};
use specta::Type;
@ -195,3 +196,10 @@ pub async fn get_worlds(uuid: Uuid) -> Result<Vec<String>, String> {
Ok(screenshots)
}
#[specta::specta]
#[tauri::command]
pub async fn get_optimal_java_version(cluster_id: Uuid) -> Result<JavaVersion, String> {
let cluster_path = cluster::get_by_uuid(cluster_id).await?.ok_or("Cluster not found")?.cluster_path();
Ok(cluster::get_optimal_java_version(&cluster_path).await?.ok_or("No Java version found")?)
}

View file

@ -1,5 +1,6 @@
use interpulse::api::minecraft::Version;
use onelauncher::data::Settings;
use onelauncher::game::metadata;
use onelauncher::settings;
use tauri::{AppHandle, Manager};
@ -42,6 +43,7 @@ macro_rules! collect_commands {
upload_log,
get_screenshots,
get_worlds,
get_optimal_java_version,
// Processor
get_running_clusters,
get_processes_by_path,

View file

@ -44,7 +44,7 @@ function ClusterRoutes() {
}
function ClusterRoot(props: ParentProps) {
const [searchParams] = useSearchParams();
const [searchParams] = useSearchParams<{ id: string }>();
return (
<ClusterProvider uuid={searchParams.id}>

View file

@ -40,7 +40,8 @@ function PageSettings(cluster: Accessor<Cluster>) {
const postCommand = createSetting(cluster().init_hooks?.post, settings().init_hooks.post ?? '');
// JVM
const javaVersion = createSetting(cluster().java?.custom_version || null);
const javaVersion = createSetting<bridge.JavaVersion | null>(cluster().java?.custom_version || null);
const javaVersions = settings().java_versions;
const javaArgs = createSetting(cluster().java?.custom_arguments, settings().custom_java_args);
const envVars = createSetting(cluster().java?.custom_env_arguments, settings().custom_env_args);
@ -96,8 +97,9 @@ function PageSettings(cluster: Accessor<Cluster>) {
<JvmSettings
{...{
clusterId: cluster().uuid,
javaVersion,
javaVersions: undefined,
javaVersions,
javaArgs,
envVars,
}}

View file

@ -296,12 +296,33 @@ export function ProcessSettings(props: {
}
export function JvmSettings(props: {
javaVersion: CreateSetting<JavaVersion> | undefined;
javaVersions: CreateSetting<JavaVersions> | undefined;
javaArgs: CreateSetting<string[]>;
envVars: CreateSetting<[string, string][]>;
}) {
const modal = createModal(controller => <JavaVersionModal {...controller} javaVersions={props.javaVersions} />);
} & ({
clusterId: string;
javaVersion: CreateSetting<JavaVersion | null>;
javaVersions: JavaVersions;
} | {
javaVersion: undefined;
javaVersions: CreateSetting<JavaVersions>;
})) {
const modal = createModal((controller) => {
if (props.javaVersion)
return (
<ClusterJavaVersionModal
{...controller}
clusterId={props.clusterId}
javaVersion={props.javaVersion}
javaVersions={props.javaVersions}
/>
);
else return (
<GlobalJavaVersionModal
{...controller}
javaVersions={props.javaVersions}
/>
);
});
return (
<>
@ -442,8 +463,119 @@ function PageSettings() {
export default SettingsMinecraft;
function JavaVersionModal(props: ModalProps & {
javaVersions: CreateSetting<JavaVersions> | undefined;
function ClusterJavaVersionModal(props: ModalProps & {
clusterId: string;
javaVersion: CreateSetting<JavaVersion | null>;
javaVersions: JavaVersions;
}) {
const [_, modalProps] = splitProps(props, ['javaVersion', 'javaVersions']);
const javaVersions = createMemo(() => Object.entries(props.javaVersions).sort((a, b) => Number.parseFloat(b[1].version) - Number.parseFloat(a[1].version)));
const [selected, setSelected] = createSignal<number>(0);
onMount(async () => {
const javaVersion = props.javaVersion.get();
if (!javaVersion) {
const clusterId = props.clusterId;
const optimal = await tryResult(() => bridge.commands.getOptimalJavaVersion(clusterId));
setSelected(javaVersions().findIndex(([_, meta]) => meta.path === optimal.path));
}
else {
const found = javaVersions().findIndex(([_, meta]) => meta.path === javaVersion.path);
setSelected(found);
}
});
const setPackage = (pkg: JavaVersion) => {
props.javaVersion.set(pkg);
};
const onChange = (selected: number) => {
const version = javaVersions()[selected]?.[0];
if (!version)
return;
const meta = props.javaVersions[version];
if (!meta)
return;
setPackage(meta);
};
return (
<BaseJavaVersionModal
{...modalProps}
setPackage={setPackage}
>
<h4>Java Path</h4>
<div class="flex flex-col items-stretch gap-y-2">
<Dropdown onChange={onChange} selected={selected}>
<For each={javaVersions()}>
{([version]) => {
const major = version.toLowerCase().replaceAll('_', ' ').replaceAll('java', '');
return (
<Dropdown.Row>
<span class="capitalize">
Java
{major}
</span>
</Dropdown.Row>
);
}}
</For>
</Dropdown>
</div>
</BaseJavaVersionModal>
);
}
function GlobalJavaVersionModal(props: ModalProps & {
javaVersions: CreateSetting<JavaVersions>;
}) {
const [_, modalProps] = splitProps(props, ['javaVersions']);
const setPackage = (pkg: JavaVersion, version?: number) => {
props.javaVersions?.set({
...props.javaVersions?.get(),
[`JAVA_${version}`]: pkg,
});
};
return (
<BaseJavaVersionModal
{...modalProps}
setPackage={setPackage}
>
<h4>Default Java Paths</h4>
<div class="grid grid-cols-[80px_1fr] items-center gap-y-2">
<For each={Object.entries(props.javaVersions?.get() ?? {}).sort((a, b) => Number.parseFloat(b[1].version) - Number.parseFloat(a[1].version))}>
{([version, meta]) => {
const major = version.toLowerCase().replaceAll('_', ' ').replaceAll('java', '');
return (
<>
<span class="capitalize">
Java
{major}
</span>
<TextField
onValidSubmit={(value) => {
setPackage({ ...meta, path: value }, Number.parseInt(major));
}}
value={meta.path}
/>
</>
);
}}
</For>
</div>
</BaseJavaVersionModal>
);
}
function BaseJavaVersionModal(props: ModalProps & {
setPackage: (pkg: JavaVersion, version?: number) => void;
}) {
const [selectedPackageIndex, setSelectedPackageIndex] = createSignal<number>(-1);
@ -461,21 +593,14 @@ function JavaVersionModal(props: ModalProps & {
return zuluPackages()?.map(pkg => pkg.java_version.join('.')) ?? [];
});
const setPackage = (version: number, pkg: JavaVersion) => {
props.javaVersions?.set({
...props.javaVersions?.get(),
[`JAVA_${version}`]: pkg,
});
};
const download = async (pkg: JavaZuluPackage) => {
const path = await tryResult(() => bridge.commands.installJavaFromPackage(pkg));
if (path)
setPackage(pkg.java_version[0]!, {
props.setPackage({
version: pkg.java_version.join('.'),
path,
arch: '',
});
}, pkg.java_version[0]!);
};
return (
@ -492,29 +617,7 @@ function JavaVersionModal(props: ModalProps & {
>
<div class="flex flex-col gap-6">
<div class="flex flex-col gap-2">
<h4>Default Java Paths</h4>
<div class="grid grid-cols-[80px_1fr] items-center gap-y-2">
<For each={Object.entries(props.javaVersions?.get() ?? {}).sort((a, b) => Number.parseFloat(b[1].version) - Number.parseFloat(a[1].version))}>
{([version, meta]) => {
const major = version.toLowerCase().replaceAll('_', ' ').replaceAll('java', '');
return (
<>
<span class="capitalize">
Java
{major}
</span>
<TextField
onValidSubmit={(value) => {
setPackage(Number.parseInt(major), { ...meta, path: value });
}}
value={meta.path}
/>
</>
);
}}
</For>
</div>
{props.children}
</div>
<div class="flex flex-col gap-2">

View file

@ -204,6 +204,16 @@ export const commands = {
else return { status: 'error', error: e as any };
}
},
async getOptimalJavaVersion(clusterId: string): Promise<Result<JavaVersion, string>> {
try {
return { status: 'ok', data: await TAURI_INVOKE('get_optimal_java_version', { clusterId }) };
}
catch (e) {
if (e instanceof Error)
throw e;
else return { status: 'error', error: e as any };
}
},
async getRunningClusters(): Promise<Result<Cluster[], string>> {
try {
return { status: 'ok', data: await TAURI_INVOKE('get_running_clusters') };