diff --git a/apps/onelauncher/desktop/src/api/commands.rs b/apps/onelauncher/desktop/src/api/commands.rs index 0f4b4e1e..4057c433 100644 --- a/apps/onelauncher/desktop/src/api/commands.rs +++ b/apps/onelauncher/desktop/src/api/commands.rs @@ -3,6 +3,7 @@ pub mod users; pub mod processor; pub mod package; pub mod other; +pub mod settings; #[macro_export(local_inner_macros)] macro_rules! collect_commands { @@ -19,6 +20,8 @@ macro_rules! collect_commands { cluster::create_cluster, cluster::get_clusters, + settings::get_global_profile, + other::open_dev_tools, ] }}; diff --git a/apps/onelauncher/desktop/src/api/commands/settings.rs b/apps/onelauncher/desktop/src/api/commands/settings.rs new file mode 100644 index 00000000..7edbc6b7 --- /dev/null +++ b/apps/onelauncher/desktop/src/api/commands/settings.rs @@ -0,0 +1,10 @@ +use onelauncher_core::entity::setting_profiles::Model; +use onelauncher_core::api::setting_profiles; + +use crate::api::error::SerializableResult; + +#[specta::specta] +#[tauri::command] +pub async fn get_global_profile() -> SerializableResult { + Ok(setting_profiles::get_global_profile().await) +} \ No newline at end of file diff --git a/apps/onelauncher/frontend/src/components/Navbar.tsx b/apps/onelauncher/frontend/src/components/Navbar.tsx index dc7401ad..645b58fe 100644 --- a/apps/onelauncher/frontend/src/components/Navbar.tsx +++ b/apps/onelauncher/frontend/src/components/Navbar.tsx @@ -22,7 +22,7 @@ function Navbar() {
- +
- - - -
- Sign up - - - - - - - - - -
-
-
-
- - - ) -} \ No newline at end of file +interface ModalProps extends DialogProps, ClassNameString { } + +function Modal({ className, ...props }: ModalProps) { + return ( + + + + ); +} + +Modal.Trigger = DialogTrigger; + +export default Modal; diff --git a/apps/onelauncher/frontend/src/routes/app/browser/index.tsx b/apps/onelauncher/frontend/src/routes/app/browser/index.tsx index 9c814974..c58edf9a 100644 --- a/apps/onelauncher/frontend/src/routes/app/browser/index.tsx +++ b/apps/onelauncher/frontend/src/routes/app/browser/index.tsx @@ -1,5 +1,6 @@ +import Button from '@/components/base/Button'; import { TextField } from '@/components/base/TextField'; -import { Modal } from '@/components/overlay/Modal'; +import Modal from '@/components/overlay/Modal'; import { createFileRoute } from '@tanstack/react-router'; export const Route = createFileRoute('/app/browser/')({ @@ -13,7 +14,14 @@ function RouteComponent() { - + {/* we can open the modal but we cant close it for some reason */} + + + + +

sadsadsad

+
+
); } diff --git a/apps/onelauncher/frontend/src/routes/app/index.tsx b/apps/onelauncher/frontend/src/routes/app/index.tsx index 85639bde..e033708f 100644 --- a/apps/onelauncher/frontend/src/routes/app/index.tsx +++ b/apps/onelauncher/frontend/src/routes/app/index.tsx @@ -3,13 +3,19 @@ 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 { useIsFetching, useQueryClient } from '@tanstack/react-query'; import { createFileRoute, useNavigate } from '@tanstack/react-router'; +import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; +import DefaultInstancePhoto from "@/assets/images/default_instance_cover.jpg" export const Route = createFileRoute('/app/')({ component: RouteComponent, }); +/* +Please note this route has a very big issue related to scrolling +and i am very angry rn so i will not be fixing it rn +*/ function RouteComponent() { const result = useCommand("getClusters", bindings.commands.getClusters) @@ -23,7 +29,7 @@ function RouteComponent() { -
+
@@ -102,6 +108,8 @@ function Banner() { } function ClusterCreate() { + const queryClient = useQueryClient(); + const result = useCommand("createCluster", () => bindings.commands.createCluster({ icon_url: "asd", mc_loader: "vanilla", @@ -121,7 +129,9 @@ function ClusterCreate() { return; } - return; + queryClient.invalidateQueries({ + queryKey: ["getClusters"], + }) } return ( @@ -143,54 +153,56 @@ function ClusterGroup(props: ClusterGroupProps) { if (isFetching) { return ( -
-
+
+
) } return ( - <> -
- {props.clusters?.map((data) => ( - - ))} -
- +
+ +
+ {props.clusters?.map((data) => ( + + ))} +
+
+
) } function ClusterCard(props: Model) { return ( - <> -
-
-
- -
-
-
-
-

{props.name}

-

- {props.mc_loader} - {' '} - {props.mc_version} - {/* {' '} - {props.packages.mods && `• ${props.mods} mods`} */} -

-
- - {/* */} +
+
+
+
- +
+
+

{props.name}

+

+ {props.mc_loader} + {' '} + {props.mc_version} + {/* {' '} + {props.packages.mods && `• ${props.mods} mods`} */} +

+
+ + {/* */} +
+
); } \ No newline at end of file diff --git a/apps/onelauncher/frontend/src/routes/app/settings/index.tsx b/apps/onelauncher/frontend/src/routes/app/settings/index.tsx new file mode 100644 index 00000000..022fc241 --- /dev/null +++ b/apps/onelauncher/frontend/src/routes/app/settings/index.tsx @@ -0,0 +1,34 @@ +import { createFileRoute } from '@tanstack/react-router' +import Sidebar from './route' +import useCommand from '@/hooks/useCommand' +import { bindings } from '@/main' +import SettingsRow from '@/components/SettingsRow' +import DiscordIcon from "@/assets/logos/discord.svg" +import ToggleButton from '@/components/base/ToggleButton' +import Switch from '@/components/base/Switch' + +export const Route = createFileRoute('/app/settings/')({ + component: RouteComponent, +}) + +function RouteComponent() { + const result = useCommand("getGlobalProfile", bindings.commands.getGlobalProfile) + + return ( + +
+

General Settings

+ + } + title="Discord RPC" + > + Thing + + +
{JSON.stringify(result.data, null, 2)}
+
+
+ ) +} diff --git a/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx b/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx new file mode 100644 index 00000000..3575a1b4 --- /dev/null +++ b/apps/onelauncher/frontend/src/routes/app/settings/minecraft.tsx @@ -0,0 +1,29 @@ +import { createFileRoute } from '@tanstack/react-router' +import Sidebar from './route' +import SettingsRow from '@/components/SettingsRow' +import { Maximize01Icon } from '@untitled-theme/icons-react' +import Button from '@/components/base/Button' + +export const Route = createFileRoute('/app/settings/minecraft')({ + component: RouteComponent, +}) + +function RouteComponent() { + return ( + +
+

Minecraft Settings

+ + Game + + } + title="Force Fullscreen" + > + + +
+
+ ) +} diff --git a/apps/onelauncher/frontend/src/routes/app/settings/route.tsx b/apps/onelauncher/frontend/src/routes/app/settings/route.tsx new file mode 100644 index 00000000..f54dac05 --- /dev/null +++ b/apps/onelauncher/frontend/src/routes/app/settings/route.tsx @@ -0,0 +1,123 @@ +import { createFileRoute, Outlet, useNavigate, useRouterState } from '@tanstack/react-router' +import { Brush01Icon, CodeSnippet02Icon, MessageTextSquare01Icon, RefreshCcw02Icon, Rocket02Icon, Sliders04Icon, Users01Icon } from '@untitled-theme/icons-react'; +import { useEffect, type JSX } from 'react'; + +export const Route = createFileRoute('/app/settings')({ + component: RouteComponent, +}) + +function RouteComponent() { + return ( +
+
+ , 'General', '/'], + [, 'Appearance', '/appearance'], + // [, 'APIs', '/apis'], + // [, 'Language', '/language'], + ], + 'Game Settings': [ + [, 'Minecraft settings', '/minecraft'], + [, 'Accounts', '/accounts'], + ], + 'About': [ + [, 'Changelog', '/changelog'], + [, 'Feedback', '/feedback'], + [, 'Developer Options', '/developer'], + ], + }} + /> + {/* */} +
+ +
+ +
+
+ ) +} + +type SidebarProps = { + base: string; + links: Record; +}; + +function Sidebar(props: SidebarProps) { + const navigate = useNavigate(); + const routerState = useRouterState(); + + const location = routerState.location.pathname + + useEffect(() => { + if (props.base.endsWith('/')) + throw new Error('Base should not end with a slash'); + }); + + function goto(href: string, params?: URLSearchParams) { + const currParams = new URLSearchParams(location); + if (params) + for (const [key, value] of params) + currParams.set(key, value); + + const url = `${props.base}${href}`; + navigate({ to: url }) + } + + function isActive(link: string, params: URLSearchParams | undefined) { + const pathnameMatch = location === `${props.base}${link}` || `${location}/` === `${props.base}${link}`; + const paramsMatch = params ? location.endsWith(params.toString()) : true; + return pathnameMatch && paramsMatch; + } + + return ( +
+ {Object.keys(props.links).map((section, i) => ( +
+
+

{section.toUpperCase()}

+
+ {props.links[section].map((link) => { + if (!link) + return; + + return ( + goto(link[2], link[3])} + > + + {link[0]} + {link[1]} + + + ) + })} +
+
+
+ ) + )} +
+ ); +} + +interface SidebarPageProps { + className?: string; + children: JSX.Element; +} + +Sidebar.Page = function (props: SidebarPageProps) { + return ( +
+ {props.children} +
+ ); +}; + +export default Sidebar; +