diff --git a/apps/desktop/package.json b/apps/desktop/package.json index c1f75041..98a9bde8 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -29,6 +29,7 @@ "@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.5", "@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2", "@thisbeyond/solid-dnd": "^0.7.5", + "@thisbeyond/solid-select": "^0.15.0", "@unocss/reset": "^0.61.4", "@untitled-theme/icons-solid": "^0.10.4", "overlayscrollbars": "^2.9.2", diff --git a/apps/desktop/src-tauri/build.rs b/apps/desktop/src-tauri/build.rs index 4e7b8824..7b318bd1 100644 --- a/apps/desktop/src-tauri/build.rs +++ b/apps/desktop/src-tauri/build.rs @@ -18,6 +18,7 @@ fn main() { "get_settings", "set_settings", "get_program_info", + "get_minecraft_versions" ]), ), ) diff --git a/apps/desktop/src-tauri/permissions/onelauncher/default.toml b/apps/desktop/src-tauri/permissions/onelauncher/default.toml index 5baddb3e..29dee761 100644 --- a/apps/desktop/src-tauri/permissions/onelauncher/default.toml +++ b/apps/desktop/src-tauri/permissions/onelauncher/default.toml @@ -13,5 +13,6 @@ permissions = [ "allow-get-manifest", "allow-get-settings", "allow-set-settings", - "allow-get-program-info" + "allow-get-program-info", + "allow-get-minecraft-versions" ] diff --git a/apps/desktop/src-tauri/src/api/commands.rs b/apps/desktop/src-tauri/src/api/commands.rs index f9a9780e..5c97f099 100644 --- a/apps/desktop/src-tauri/src/api/commands.rs +++ b/apps/desktop/src-tauri/src/api/commands.rs @@ -2,7 +2,9 @@ use std::collections::HashMap; use std::path::PathBuf; use std::str::FromStr; +use anyhow::anyhow; use chrono::DateTime; +use interpulse::api::minecraft::Version; use onelauncher::constants::{NATIVE_ARCH, TARGET_OS, VERSION}; use onelauncher::data::{ClusterMeta, Loader, MinecraftCredentials, PackageData, Settings}; use onelauncher::store::{Cluster, ClusterPath, MinecraftLogin}; @@ -31,7 +33,8 @@ macro_rules! collect_commands { get_clusters, get_settings, set_settings, - get_program_info + get_program_info, + get_minecraft_versions ]) }}; } @@ -132,16 +135,22 @@ pub async fn get_clusters() -> Result, String> { // cluster::list(None).await.map_err(|op| op.into()) } +#[specta::specta] +#[tauri::command] +pub async fn get_minecraft_versions() -> Result, String> { + Ok(onelauncher::api::metadata::get_minecraft_versions().await?.versions) +} + #[specta::specta] #[tauri::command] pub async fn get_settings() -> Result { - settings::get().await.map_err(|err| err.into()) + Ok(settings::get().await?) } #[specta::specta] #[tauri::command] pub async fn set_settings(settings: Settings) -> Result<(), String> { - settings::set(settings).await.map_err(|err| err.into()) + Ok(settings::set(settings).await?) } #[derive(Serialize, Deserialize, Type)] @@ -174,19 +183,19 @@ pub fn get_program_info() -> ProgramInfo { #[specta::specta] #[tauri::command] pub async fn get_users() -> Result, String> { - minecraft::users().await.map_err(|err| err.into()) + Ok(minecraft::users().await?) } #[specta::specta] #[tauri::command] pub async fn get_user(uuid: Uuid) -> Result { - minecraft::get_user(uuid).await.map_err(|err| err.into()) + Ok(minecraft::get_user(uuid).await?) } #[specta::specta] #[tauri::command] pub async fn begin_msa() -> Result { - minecraft::begin().await.map_err(|err| err.into()) + Ok(minecraft::begin().await?) } #[specta::specta] @@ -195,13 +204,11 @@ pub async fn finish_msa( code: String, login: MinecraftLogin, ) -> Result { - minecraft::finish(code.as_str(), login) - .await - .map_err(|err| err.into()) + Ok(minecraft::finish(code.as_str(), login).await?) } #[specta::specta] #[tauri::command] pub async fn remove_user(uuid: Uuid) -> Result<(), String> { - minecraft::remove_user(uuid).await.map_err(|err| err.into()) + Ok(minecraft::remove_user(uuid).await?) } diff --git a/apps/desktop/src/ui/components/base/Button.module.scss b/apps/desktop/src/ui/components/base/Button.module.scss index dcca45e4..8cabc4f5 100644 --- a/apps/desktop/src/ui/components/base/Button.module.scss +++ b/apps/desktop/src/ui/components/base/Button.module.scss @@ -2,7 +2,7 @@ @apply py-1.5 px-3 rounded-lg flex flex-row justify-center items-center gap-x-2.5; &__primary { - @apply text-onbrand hover:text-onbrand-hover active:text-onbrand-pressed disabled:text-onbrand-disabled; + @apply text-onbrand hover:text-onbrand-hover active:text-onbrand-pressed disabled:text-onbrand-disabled; @apply bg-brand hover:bg-brand-hover active:bg-brand-pressed disabled:bg-brand-disabled; } @@ -17,11 +17,11 @@ } &__ghost { - @apply hover:bg-gray-05 active:bg-gray-10; + @apply hover:bg-gray-05 [&[aria-checked="true"]]:bg-gray-10 active:bg-gray-10; } &__icon, &__iconSecondary { - @apply p-1.5 hover:bg-gray-05 active:bg-gray-10 aspect-square box-border w-8 h-8; + @apply p-1.5 hover:bg-gray-05 [&[aria-checked="true"]]:bg-gray-10 active:bg-gray-10 aspect-square box-border w-8 h-8; &.large { @apply w-9 h-9; diff --git a/apps/desktop/src/ui/components/base/Button.tsx b/apps/desktop/src/ui/components/base/Button.tsx index c857415d..73c24606 100644 --- a/apps/desktop/src/ui/components/base/Button.tsx +++ b/apps/desktop/src/ui/components/base/Button.tsx @@ -1,5 +1,5 @@ import type { JSX, ParentProps } from 'solid-js'; -import { mergeProps, splitProps } from 'solid-js'; +import { createSignal, mergeProps, splitProps } from 'solid-js'; import styles from './Button.module.scss'; type ButtonProps = JSX.ButtonHTMLAttributes & ParentProps & { @@ -22,4 +22,32 @@ function Button(props: ButtonProps) { ); } +type ButtonToggleProps = ButtonProps & { + defaultChecked?: boolean; + onChecked?: (checked: boolean) => any; +}; + +Button.Toggle = (props: ButtonToggleProps) => { + const [checked, setChecked] = createSignal(props.defaultChecked || false); + const [split, rest] = splitProps(props, ['defaultChecked', 'onChecked', 'onClick', 'class']); + + function toggle() { + const newValue = !checked(); + setChecked(newValue); + props.onChecked?.(newValue); + } + + return ( +