diff --git a/apps/onelauncher/desktop/src/api/commands.rs b/apps/onelauncher/desktop/src/api/commands.rs index a4542ee9..0f4b4e1e 100644 --- a/apps/onelauncher/desktop/src/api/commands.rs +++ b/apps/onelauncher/desktop/src/api/commands.rs @@ -16,6 +16,9 @@ macro_rules! collect_commands { users::set_default_user, users::begin_ms_flow, + cluster::create_cluster, + cluster::get_clusters, + other::open_dev_tools, ] }}; diff --git a/apps/onelauncher/desktop/src/api/commands/cluster.rs b/apps/onelauncher/desktop/src/api/commands/cluster.rs index 84e23d44..0f3c80bd 100644 --- a/apps/onelauncher/desktop/src/api/commands/cluster.rs +++ b/apps/onelauncher/desktop/src/api/commands/cluster.rs @@ -214,4 +214,32 @@ // cluster::repair_cluster(&cluster.cluster_path()).await?; // Ok(()) -// } \ No newline at end of file +// } + +use onelauncher_core::{api::cluster, entity::{clusters::Model, icon::Icon, loader::GameLoader}}; +use serde::{Deserialize, Serialize}; +use specta::Type; +use crate::api::error::SerializableResult; + +#[derive(Serialize, Deserialize, Type)] +pub struct CreateCluster { + name: String, + mc_version: String, + mc_loader: GameLoader, + mc_loader_version: Option, + icon_url: Option +} + +#[specta::specta] +#[tauri::command] +pub async fn create_cluster(options: CreateCluster) -> SerializableResult { + let thing = cluster::create_cluster(&options.name, &options.mc_version, options.mc_loader, options.mc_loader_version.as_deref(), options.icon_url).await?; + + Ok(thing) +} + +#[specta::specta] +#[tauri::command] +pub async fn get_clusters() -> SerializableResult> { + Ok(cluster::dao::get_all_clusters().await?) +} \ No newline at end of file diff --git a/apps/onelauncher/frontend/src/components/base/TextField.tsx b/apps/onelauncher/frontend/src/components/base/TextField.tsx new file mode 100644 index 00000000..f245a318 --- /dev/null +++ b/apps/onelauncher/frontend/src/components/base/TextField.tsx @@ -0,0 +1,45 @@ +import { Input } from 'react-aria-components'; +import type { RefAttributes } from 'react'; +import type { InputProps as AriaInputProps } from 'react-aria-components'; +import type { VariantProps } from 'tailwind-variants'; +import { tv } from 'tailwind-variants'; + +export const textFieldVariants = tv({ + base: [ + 'bg-component-bg', + '[&:not(:focus-within)]:hover:bg-component-bg-hover', + 'focus-within:bg-component-bg-pressed', + 'disabled:bg-component-bg-disabled', + 'border-component-border border fill-fg-primary', + 'rounded-lg px-2.5 py-1.5 min-h-8', + 'flex flex-row items-center justify-start gap-x-1.5', + 'text-sm text-fg-primary font-medium', + 'bg-transparent outline-none appearance-none p-0 m-0 box-border w-full font-medium', + '[&::selection]:bg-brand/30', + 'placeholder:text-fg-secondary/40 placeholder:font-normal' + ], + variants: { + invalid: { + true: { + base: 'border-danger' + } + } + } +}) + +export type TextFieldVariants = VariantProps; + +export type TextFieldProps = AriaInputProps & RefAttributes & { + className?: string; +}; + +export function TextField({ + className, + ...props +}: TextFieldProps) { + return ( + <> + + + ) +} \ No newline at end of file diff --git a/apps/onelauncher/frontend/src/components/content/PlayerHead.tsx b/apps/onelauncher/frontend/src/components/content/PlayerHead.tsx index f9d90ae4..bd895519 100644 --- a/apps/onelauncher/frontend/src/components/content/PlayerHead.tsx +++ b/apps/onelauncher/frontend/src/components/content/PlayerHead.tsx @@ -13,7 +13,7 @@ function PlayerHead({ }: PlayerHeadProps & ImgHTMLAttributes) { const src = useMemo(() => { return uuid - ? `https://crafatar.com/avatars/${uuid}?overlay&size=8` + ? `https://crafatar.com/avatars/${uuid}?overlay&size=64` : SteveHead; }, [uuid]); diff --git a/apps/onelauncher/frontend/src/components/overlay/Modal.tsx b/apps/onelauncher/frontend/src/components/overlay/Modal.tsx new file mode 100644 index 00000000..42efcfa6 --- /dev/null +++ b/apps/onelauncher/frontend/src/components/overlay/Modal.tsx @@ -0,0 +1,33 @@ +import { Dialog, DialogTrigger, Heading, Input, Label, Modal as AriaModal, TextField, ModalOverlay } from 'react-aria-components'; +import Button from '../base/Button'; + +// just testing stuff +export function Modal() { + return ( + <> + + + + + +
+ Sign up + + + + + + + + + +
+
+
+
+
+ + ) +} \ No newline at end of file diff --git a/apps/onelauncher/frontend/src/routes/__root.tsx b/apps/onelauncher/frontend/src/routes/__root.tsx index 4fa5efba..28af9009 100644 --- a/apps/onelauncher/frontend/src/routes/__root.tsx +++ b/apps/onelauncher/frontend/src/routes/__root.tsx @@ -29,7 +29,6 @@ function RootRoute() { navigate={(to, options) => router.navigate({ to, ...options })} useHref={to => router.buildLocation({ to }).href} > - {/* questionable fix copied from old frontend but it works */}
diff --git a/apps/onelauncher/frontend/src/routes/app/browser/index.tsx b/apps/onelauncher/frontend/src/routes/app/browser/index.tsx index ed21d7b5..9c814974 100644 --- a/apps/onelauncher/frontend/src/routes/app/browser/index.tsx +++ b/apps/onelauncher/frontend/src/routes/app/browser/index.tsx @@ -1,3 +1,5 @@ +import { TextField } from '@/components/base/TextField'; +import { Modal } from '@/components/overlay/Modal'; import { createFileRoute } from '@tanstack/react-router'; export const Route = createFileRoute('/app/browser/')({ @@ -5,5 +7,13 @@ export const Route = createFileRoute('/app/browser/')({ }); function RouteComponent() { - return
Hello "/app/browser/"!
; + return ( +
+

asdasdas

+ + + + +
+ ); } diff --git a/apps/onelauncher/frontend/src/routes/app/index.tsx b/apps/onelauncher/frontend/src/routes/app/index.tsx index fc3cd082..85639bde 100644 --- a/apps/onelauncher/frontend/src/routes/app/index.tsx +++ b/apps/onelauncher/frontend/src/routes/app/index.tsx @@ -1,4 +1,9 @@ import DefaultBanner from '@/assets/images/default_banner.png'; +import type { Model } from '@/bindings.gen'; +import Button from '@/components/base/Button'; +import useCommand from '@/hooks/useCommand'; +import { bindings } from '@/main'; +import { useIsFetching } from '@tanstack/react-query'; import { createFileRoute, useNavigate } from '@tanstack/react-router'; export const Route = createFileRoute('/app/')({ @@ -6,9 +11,21 @@ export const Route = createFileRoute('/app/')({ }); function RouteComponent() { + const result = useCommand("getClusters", bindings.commands.getClusters) + return (
+ +
+
+ +
+
+ +
+ +
); } @@ -83,3 +100,97 @@ function Banner() { ); } + +function ClusterCreate() { + const result = useCommand("createCluster", () => bindings.commands.createCluster({ + icon_url: "asd", + mc_loader: "vanilla", + mc_version: "1.20.1", + name: "Test Cluster", + mc_loader_version: "0.13.5", + }), { + enabled: false, + subscribed: false + }) + + const testThingy = () => { + result.refetch() + + if (result.isError) { + alert(result.error.message) + return; + } + + return; + } + + return ( + <> +