From 67488594bb033067df7d979398d7c92a5c0d8129 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:07:42 +0200 Subject: [PATCH 01/11] feat: settings page --- apps/oneclient/frontend/src/bindings.gen.ts | 2 +- .../frontend/src/components/Navbar.tsx | 9 +- .../frontend/src/components/PackageItem.tsx | 1 + .../frontend/src/components/SettingSwitch.tsx | 16 ++ .../frontend/src/components/SettingsRow.tsx | 45 ++++ .../frontend/src/hooks/usePopState.ts | 20 ++ .../frontend/src/hooks/useSettings.ts | 25 ++ .../src/routes/app/settings/appearance.tsx | 224 ++++++++++++++++++ .../src/routes/app/settings/index.tsx | 81 +++++++ .../src/routes/app/settings/minecraft.tsx | 191 +++++++++++++++ .../src/routes/app/settings/route.tsx | 135 +++++++++++ 11 files changed, 746 insertions(+), 3 deletions(-) create mode 100644 apps/oneclient/frontend/src/components/SettingSwitch.tsx create mode 100644 apps/oneclient/frontend/src/components/SettingsRow.tsx create mode 100644 apps/oneclient/frontend/src/hooks/usePopState.ts create mode 100644 apps/oneclient/frontend/src/hooks/useSettings.ts create mode 100644 apps/oneclient/frontend/src/routes/app/settings/appearance.tsx create mode 100644 apps/oneclient/frontend/src/routes/app/settings/index.tsx create mode 100644 apps/oneclient/frontend/src/routes/app/settings/minecraft.tsx create mode 100644 apps/oneclient/frontend/src/routes/app/settings/route.tsx diff --git a/apps/oneclient/frontend/src/bindings.gen.ts b/apps/oneclient/frontend/src/bindings.gen.ts index 4692aaac..35fb9148 100644 --- a/apps/oneclient/frontend/src/bindings.gen.ts +++ b/apps/oneclient/frontend/src/bindings.gen.ts @@ -230,7 +230,7 @@ export type VersionType = */ "old_beta" -const ARGS_MAP = { 'core':'{"getClusterById":["id"],"getLogByName":["id","name"],"getLogs":["id"],"openMsaLogin":[],"writeSettings":["setting"],"removeUser":["uuid"],"searchPackages":["provider","query"],"getClusters":[],"updateClusterById":["id","request"],"getUser":["uuid"],"getPackage":["provider","slug"],"getLoadersForVersion":["mc_version"],"getUsers":[],"getScreenshots":["id"],"getPackageBody":["provider","body"],"launchCluster":["id","uuid"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"updateClusterProfile":["name","profile"],"getMultiplePackages":["provider","slugs"],"setDefaultUser":["uuid"],"getWorlds":["id"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"getUsersFromAuthor":["provider","author"],"fetchMinecraftProfile":["uuid"],"removeCluster":["id"],"readSettings":[],"getGlobalProfile":[],"getDefaultUser":["fallback"],"getGameVersions":[],"createCluster":["options"],"getProfileOrDefault":["name"]}', 'events':'{"process":["event"],"ingress":["event"],"message":["event"]}', 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}', 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}' } +const ARGS_MAP = { 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}', 'events':'{"message":["event"],"process":["event"],"ingress":["event"]}', 'core':'{"readSettings":[],"getLogs":["id"],"getGameVersions":[],"getClusters":[],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid"],"getClusterById":["id"],"getUsersFromAuthor":["provider","author"],"setDefaultUser":["uuid"],"removeUser":["uuid"],"updateClusterProfile":["name","profile"],"openMsaLogin":[],"getDefaultUser":["fallback"],"getScreenshots":["id"],"removeCluster":["id"],"getMultiplePackages":["provider","slugs"],"writeSettings":["setting"],"getUsers":[],"createCluster":["options"],"getWorlds":["id"],"updateClusterById":["id","request"],"getGlobalProfile":[],"getUser":["uuid"],"getLogByName":["id","name"],"searchPackages":["provider","query"],"getProfileOrDefault":["name"],"getLoadersForVersion":["mc_version"],"getPackage":["provider","slug"],"getPackageBody":["provider","body"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"fetchMinecraftProfile":["uuid"]}', 'oneclient':'{"openDevTools":[],"getClustersGroupedByMajor":[]}' } export type Router = { 'oneclient': { openDevTools: () => Promise, getClustersGroupedByMajor: () => Promise> }, 'core': { getClusters: () => Promise, diff --git a/apps/oneclient/frontend/src/components/Navbar.tsx b/apps/oneclient/frontend/src/components/Navbar.tsx index de0d3734..f09af13c 100644 --- a/apps/oneclient/frontend/src/components/Navbar.tsx +++ b/apps/oneclient/frontend/src/components/Navbar.tsx @@ -4,15 +4,16 @@ import LauncherLogo from '@/assets/logos/oneclient.svg?react'; import { bindings } from '@/main'; import { useCommand } from '@onelauncher/common'; import { Button, Popup } from '@onelauncher/common/components'; -import { Link } from '@tanstack/react-router'; +import { Link, useNavigate } from '@tanstack/react-router'; import { Window } from '@tauri-apps/api/window'; -import { MinusIcon, SquareIcon, XCloseIcon } from '@untitled-theme/icons-react'; +import { MinusIcon, Settings01Icon, Settings02Icon, SquareIcon, XCloseIcon } from '@untitled-theme/icons-react'; import { twMerge } from 'tailwind-merge'; import { AccountAvatar } from './AccountAvatar'; import { AccountPopup } from './overlay/AccountPopup'; export function Navbar() { const { data: currentAccount } = useCommand(['getDefaultUser'], () => bindings.core.getDefaultUser(true)); + const navigate = useNavigate(); const onMinimize = () => Window.getCurrent().minimize(); const onMaximize = () => Window.getCurrent().toggleMaximize(); @@ -31,6 +32,10 @@ export function Navbar() {
+ } + onClick={() => navigate({ to: '/app/settings' })} + /> diff --git a/apps/oneclient/frontend/src/components/PackageItem.tsx b/apps/oneclient/frontend/src/components/PackageItem.tsx index 0ff0fe49..cf8b1b5d 100644 --- a/apps/oneclient/frontend/src/components/PackageItem.tsx +++ b/apps/oneclient/frontend/src/components/PackageItem.tsx @@ -21,6 +21,7 @@ export function PackageItem({ provider, clusterId, ...item }: SearchResult & { p return ( void, +]; + +export default function SettingsSwitch({ setting }: { setting: BooleanSetting }) { + return ( + setting[1](val)} + /> + ); +} diff --git a/apps/oneclient/frontend/src/components/SettingsRow.tsx b/apps/oneclient/frontend/src/components/SettingsRow.tsx new file mode 100644 index 00000000..4bfe7435 --- /dev/null +++ b/apps/oneclient/frontend/src/components/SettingsRow.tsx @@ -0,0 +1,45 @@ +import type { JSX } from 'react'; + +export interface SettingsRowProps { + title: JSX.Element | string; + description: JSX.Element | string; + icon: JSX.Element; + disabled?: boolean; + children?: JSX.Element; +} + +function SettingsRow({ disabled, description, icon, title, children }: SettingsRowProps) { + return ( +
+
+ {icon} +
+ +
+

{title}

+

{description}

+
+ +
+ {children} +
+
+ ); +} + +interface SettingsRowHeaderProps { + className?: string; + children?: React.ReactNode; +} + +SettingsRow.Header = ({ className, children }: SettingsRowHeaderProps) => { + const headerClasses = `mt-4 mb-1 ml-2 text-md text-fg-secondary uppercase ${className || ''}`; + return

{children}

; +}; + +export default SettingsRow; diff --git a/apps/oneclient/frontend/src/hooks/usePopState.ts b/apps/oneclient/frontend/src/hooks/usePopState.ts new file mode 100644 index 00000000..5714b47c --- /dev/null +++ b/apps/oneclient/frontend/src/hooks/usePopState.ts @@ -0,0 +1,20 @@ +import { useLocation } from '@tanstack/react-router'; +import { useEffect, useRef } from 'react'; + +export default function usePopState(onRouteChange: void | any) { + const location = useLocation(); + const prevLocationRef = useRef(location); + + useEffect(() => { + const prevLocation = prevLocationRef.current; + + // Only run if the pathname actually changed + if (prevLocation.pathname !== location.pathname) + onRouteChange?.({ + from: prevLocation, + to: location, + }); + + prevLocationRef.current = location; + }, [location, onRouteChange]); +} diff --git a/apps/oneclient/frontend/src/hooks/useSettings.ts b/apps/oneclient/frontend/src/hooks/useSettings.ts new file mode 100644 index 00000000..a8a2d315 --- /dev/null +++ b/apps/oneclient/frontend/src/hooks/useSettings.ts @@ -0,0 +1,25 @@ +import type { Settings } from '@/bindings.gen'; +import { bindings } from '@/main'; +import { useCommandSuspense } from '@onelauncher/common'; +import { useMemo } from 'react'; + +export function useSettings() { + const settings = useCommandSuspense(['readSettings'], bindings.core.readSettings); + const setting = useMemo(() => (key: TKey) => settings.data[key], [settings]); + + const setSetting = useMemo(() => (key: TKey, value: Settings[TKey]) => { + bindings.core.writeSettings({ + ...settings.data, + [key]: value, + }); + settings.refetch(); + }, [settings]); + + type Setter = (value: Settings[TKey]) => void; + + const createSetting = useMemo(() => (key: TKey): [Settings[TKey], Setter] => { + return [setting(key), value => setSetting(key, value)]; + }, [setting]); + + return { setting, setSetting, createSetting }; +} diff --git a/apps/oneclient/frontend/src/routes/app/settings/appearance.tsx b/apps/oneclient/frontend/src/routes/app/settings/appearance.tsx new file mode 100644 index 00000000..6b83f19e --- /dev/null +++ b/apps/oneclient/frontend/src/routes/app/settings/appearance.tsx @@ -0,0 +1,224 @@ +// import ScrollableContainer from '@/components/ScrollableContainer'; +import SettingsRow from '@/components/SettingsRow'; +import SettingsSwitch from '@/components/SettingSwitch'; +import { useSettings } from '@/hooks/useSettings'; +import { bindings } from '@/main'; +import { THEMES } from '@/utils/theming'; +import { Switch } from '@onelauncher/common/components'; +import { createFileRoute } from '@tanstack/react-router'; +import { Monitor01Icon, PackageIcon, Speedometer04Icon } from '@untitled-theme/icons-react'; +import Sidebar from './route'; + +export const Route = createFileRoute('/app/settings/appearance')({ + component: RouteComponent, +}); + +function RouteComponent() { + const { createSetting } = useSettings(); + + return ( + + {/* */} +
+

Appearance

+ +
+ +
+ {/* + {theme => ( + + {variant => ( + + )} + + )} + */} + + {Object.keys(THEMES).map((theme) => { + return THEMES[theme as keyof typeof THEMES].variants.map((variant) => { + return ( + { }} themeSelector={`${theme}-${variant.name}`} /> + ); + }); + })} +
+
+ + } + title="Package List Style" + > +

i hope i'll fix this

+
+ + } + title="Custom Window Frame" + > + + + + } + title="Disable Animations" + > + {/* */} + +
+ {/*
*/} +
+ ); +} + +interface ThemeCardProps { + themeSelector: string; + setTheme: (merged: string) => void; +}; + +function ThemeCard({ + themeSelector, + setTheme, +}: ThemeCardProps) { + return ( +
setTheme(themeSelector)}> + + + + + + + + + +
+ ); +} + +function PrimaryThemeCard() { + return ( +
+ + + + + + + + + + + + + +
+ ); +} diff --git a/apps/oneclient/frontend/src/routes/app/settings/index.tsx b/apps/oneclient/frontend/src/routes/app/settings/index.tsx new file mode 100644 index 00000000..364cebfe --- /dev/null +++ b/apps/oneclient/frontend/src/routes/app/settings/index.tsx @@ -0,0 +1,81 @@ +// import DiscordIcon from '@/assets/logos/discord.svg'; +import SettingsRow from '@/components/SettingsRow'; +import { useSettings } from '@/hooks/useSettings'; +// import useSettings from '@/hooks/useSettings'; +import { Button, Switch } from '@onelauncher/common/components'; +import { createFileRoute } from '@tanstack/react-router'; +import { dataDir, join } from '@tauri-apps/api/path'; +import { openPath } from '@tauri-apps/plugin-opener'; +import { FolderIcon, Link03Icon, LinkExternal01Icon } from '@untitled-theme/icons-react'; +import { useEffect, useState } from 'react'; +import Sidebar from './route'; + +export const Route = createFileRoute('/app/settings/')({ + component: RouteComponent, +}); + +function RouteComponent() { + const { setting, setSetting } = useSettings(); + const [launcherDir, setLauncherDir] = useState(''); + + useEffect(() => { + (async () => { + setLauncherDir(await join(await dataDir(), 'OneLauncher')); + })(); + }, []); + + const openLauncherDir = () => openPath(launcherDir); + + // const [discordRpc, setDiscordRpc] = createSetting('discord_enabled', settings?.discord_enabled); + + return ( + +
+

General

+ + } + title="Discord RPC" + > + setSetting('discord_enabled', val)} + /> + + + {/* } + title="Hide Close Dialog" + > + + + + } + title="Error Analytics" + > + !(settings().disable_analytics ?? false)} + onChecked={value => settings().disable_analytics = !value} + /> + */} + + Folders and Files + } + title="Launcher Folder" + > + + +
+
+ ); +} diff --git a/apps/oneclient/frontend/src/routes/app/settings/minecraft.tsx b/apps/oneclient/frontend/src/routes/app/settings/minecraft.tsx new file mode 100644 index 00000000..fc0358ca --- /dev/null +++ b/apps/oneclient/frontend/src/routes/app/settings/minecraft.tsx @@ -0,0 +1,191 @@ +import type { SettingProfileModel } from '@/bindings.gen'; +// import ScrollableContainer from '@/components/ScrollableContainer'; +import SettingsRow from '@/components/SettingsRow'; +import usePopState from '@/hooks/usePopState'; +import { useSettings } from '@/hooks/useSettings'; +import { bindings } from '@/main'; +import { useCommandMut, useCommandSuspense } from '@onelauncher/common'; +import { Switch, TextField } from '@onelauncher/common/components'; +import { createFileRoute } from '@tanstack/react-router'; +import { Database01Icon, FilePlus02Icon, FileX02Icon, LayoutTopIcon, Maximize01Icon, ParagraphWrapIcon, XIcon } from '@untitled-theme/icons-react'; +import { useMemo } from 'react'; +import Sidebar from './route'; + +export const Route = createFileRoute('/app/settings/minecraft')({ + component: RouteComponent, +}); + +function RouteComponent() { + const result = useCommandSuspense(['readSettings'], bindings.core.readSettings); + + const save = useCommandMut(() => bindings.core.writeSettings(result.data)); + + usePopState(() => { + save.mutate(); + }); + + return ( + + {/* */} +
+

Minecraft Settings

+ + + + {/* */} + + +
+ {/*
*/} +
+ ); +} + +export function GameSettings() { + const { createSetting } = useSettings(); + + const [gameSettings, setGameSettings] = createSetting('global_game_settings'); + + // const getSetting = useMemo(()=>(key: TKey)=>gameSettings[key], [gameSettings]) + + const setSetting = useMemo(() => (key: TKey, value: SettingProfileModel[TKey]) => { + setGameSettings({ + ...gameSettings, + [key]: value, + }); + }, [gameSettings, setGameSettings]); + + return ( + <> + Game + + } + title="Force Fullscreen" + > + setSetting('force_fullscreen', val)} + /> + + + } + title="Resolution" + > +
+ { + setSetting('res', { height: gameSettings.res?.height ?? 720, width: Number(e.currentTarget.value) }); + }} + type="number" + value={gameSettings.res?.width} + /> + + { + setSetting('res', { width: gameSettings.res?.height ?? 1280, height: Number(e.currentTarget.value) }); + }} + type="number" + value={gameSettings.res?.height} + /> +
+
+ + } + title="Memory" + > +
+
+ { + setSetting('mem_max', Number(e.currentTarget.value)); + }} + type="number" + value={gameSettings.mem_max ?? undefined} + /> +
+
+
+ + ); +} + +// function LauncherSettings() { +// return ( +// <> +// Launcher +// } +// title="Hide On Launch" +// > +// +// +// +// ); +// } + +export function ProcessSettings() { + const { createSetting } = useSettings(); + + const [gameSettings, setGameSettings] = createSetting('global_game_settings'); + + // const getSetting = useMemo(()=>(key: TKey)=>gameSettings[key], [gameSettings]) + + const setSetting = useMemo(() => (key: TKey, value: SettingProfileModel[TKey]) => { + setGameSettings({ + ...gameSettings, + [key]: value, + }); + }, [gameSettings, setGameSettings]); + + return ( + <> + Process + + } + title="Pre-Launch Command" + > + setSetting('hook_pre', e.currentTarget.value)} + placeholder="echo 'Game started'" + value={gameSettings.hook_pre ?? undefined} + /> + + + } + title="Wrapper Command" + > + setSetting('hook_wrapper', e.currentTarget.value)} + placeholder="gamescope" + value={gameSettings.hook_wrapper ?? undefined} + /> + + + } + title="Post-Exit Command" + > + setSetting('hook_post', e.currentTarget.value)} + placeholder="echo 'Game exited'" + value={gameSettings.hook_post ?? undefined} + /> + + + ); +} diff --git a/apps/oneclient/frontend/src/routes/app/settings/route.tsx b/apps/oneclient/frontend/src/routes/app/settings/route.tsx new file mode 100644 index 00000000..b51ab5ba --- /dev/null +++ b/apps/oneclient/frontend/src/routes/app/settings/route.tsx @@ -0,0 +1,135 @@ +import type { JSX } from 'react'; +import { createFileRoute, Outlet, useNavigate, useRouterState } from '@tanstack/react-router'; +import { Brush01Icon, CodeSnippet02Icon, MessageTextSquare01Icon, RefreshCcw02Icon, Rocket02Icon, Sliders04Icon, Users01Icon } from '@untitled-theme/icons-react'; +import { useEffect } 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'], + ], + 'About': [ + [, 'Changelog', '/changelog'], + [, 'Feedback', '/feedback'], + [, 'Developer Options', '/developer'], + ], + }} + /> + {/* */} +
+ +
+ +
+
+ ); +} + +interface SidebarProps { + base: string; + links: Record>; +} + +function Sidebar(props: SidebarProps) { + const { base, links } = props; + + const navigate = useNavigate(); + const routerState = useRouterState(); + + const location = routerState.location.pathname; + + useEffect(() => { + if (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 = `${base}${href}`; + navigate({ to: url }); + } + + function isActive(link: string, params: URLSearchParams | undefined) { + const fullBasePath = `${base}${link}`; + const pathnameMatch = location.startsWith(fullBasePath) || `${location}/`.startsWith(fullBasePath); + + if (!params) + return pathnameMatch; + + const searchParams = new URLSearchParams(routerState.location.searchStr); + for (const [key, value] of params) + if (searchParams.get(key) !== value) + return false; + + return pathnameMatch; + } + + return ( +
+ {Object.keys(links).map(section => ( +
+
+

{section.toUpperCase()}

+
+ {links[section].map((entry) => { + if (!entry) + return ''; + + const [Component, label, link, params] = entry; + + return ( + goto(link, params)} + > + + {Component} + {label} + + + ); + })} +
+
+
+ ))} +
+ ); +} + +interface SidebarPageProps { + className?: string; + children: JSX.Element | Array; +} + +Sidebar.Page = function (props: SidebarPageProps) { + return ( +
+ {props.children} +
+ ); +}; + +export default Sidebar; From 48373d193b6dc0c7bc842d51195366c11d9a07e5 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:53:22 +0200 Subject: [PATCH 02/11] fix: pagination imports --- packages/web_common/src/hooks/usePagination.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web_common/src/hooks/usePagination.tsx b/packages/web_common/src/hooks/usePagination.tsx index 332982b1..cac8922b 100644 --- a/packages/web_common/src/hooks/usePagination.tsx +++ b/packages/web_common/src/hooks/usePagination.tsx @@ -1,6 +1,6 @@ -import { Button, Show } from '@onelauncher/common/components'; import { ChevronLeftIcon, ChevronRightIcon } from '@untitled-theme/icons-react'; import { useState } from 'react'; +import { Button, Show } from '../components'; export interface PaginationOptions { itemsCount: number; From 5b9ff1056465e929706b0e00c75b473a6134bba5 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Sun, 31 Aug 2025 19:49:00 +0200 Subject: [PATCH 03/11] fix: correct file opener --- apps/oneclient/frontend/src/bindings.gen.ts | 10 +++++----- .../frontend/src/routes/app/settings/index.tsx | 14 +++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/apps/oneclient/frontend/src/bindings.gen.ts b/apps/oneclient/frontend/src/bindings.gen.ts index 9557b5bf..6c32f842 100644 --- a/apps/oneclient/frontend/src/bindings.gen.ts +++ b/apps/oneclient/frontend/src/bindings.gen.ts @@ -232,8 +232,10 @@ export type VersionType = */ "old_beta" -const ARGS_MAP = { 'core':'{"writeSettings":["setting"],"getWorlds":["id"],"getRunningProcessesByClusterId":["cluster_id"],"updateClusterProfile":["name","profile"],"getClusterById":["id"],"openMsaLogin":[],"getScreenshots":["id"],"getUsers":[],"getProfileOrDefault":["name"],"updateClusterById":["id","request"],"getDefaultUser":["fallback"],"removeCluster":["id"],"createCluster":["options"],"getPackage":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"open":["input"],"getMultiplePackages":["provider","slugs"],"getLogByName":["id","name"],"getLoadersForVersion":["mc_version"],"isClusterRunning":["cluster_id"],"searchPackages":["provider","query"],"setDefaultUser":["uuid"],"getUser":["uuid"],"killProcess":["pid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid"],"getClusters":[],"getRunningProcesses":[],"getGameVersions":[],"getGlobalProfile":[],"getPackageBody":["provider","body"],"removeUser":["uuid"],"fetchMinecraftProfile":["uuid"],"readSettings":[],"getLogs":["id"]}', 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}', 'events':'{"message":["event"],"ingress":["event"],"process":["event"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}' } -export type Router = { 'events': { ingress: (event: IngressPayload) => Promise, +const ARGS_MAP = { 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}', 'core':'{"writeSettings":["setting"],"getWorlds":["id"],"getRunningProcessesByClusterId":["cluster_id"],"updateClusterProfile":["name","profile"],"getClusterById":["id"],"openMsaLogin":[],"getScreenshots":["id"],"getUsers":[],"getProfileOrDefault":["name"],"updateClusterById":["id","request"],"getDefaultUser":["fallback"],"removeCluster":["id"],"createCluster":["options"],"getPackage":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"open":["input"],"getMultiplePackages":["provider","slugs"],"getLogByName":["id","name"],"getLoadersForVersion":["mc_version"],"isClusterRunning":["cluster_id"],"searchPackages":["provider","query"],"setDefaultUser":["uuid"],"getUser":["uuid"],"killProcess":["pid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid"],"getClusters":[],"getRunningProcesses":[],"getGameVersions":[],"getGlobalProfile":[],"getPackageBody":["provider","body"],"removeUser":["uuid"],"fetchMinecraftProfile":["uuid"],"readSettings":[],"getLogs":["id"]}', 'events':'{"message":["event"],"ingress":["event"],"process":["event"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}' } +export type Router = { 'folders': { fromCluster: (folderName: string) => Promise, +openCluster: (folderName: string) => Promise }, +'events': { ingress: (event: IngressPayload) => Promise, message: (event: MessagePayload) => Promise, process: (event: ProcessPayload) => Promise }, 'core': { getClusters: () => Promise, @@ -273,9 +275,7 @@ getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise Promise, open: (input: string) => Promise }, 'oneclient': { openDevTools: () => Promise, -getClustersGroupedByMajor: () => Promise> }, -'folders': { fromCluster: (folderName: string) => Promise, -openCluster: (folderName: string) => Promise } }; +getClustersGroupedByMajor: () => Promise> } }; export type { InferCommandOutput } diff --git a/apps/oneclient/frontend/src/routes/app/settings/index.tsx b/apps/oneclient/frontend/src/routes/app/settings/index.tsx index 364cebfe..ba53b6f0 100644 --- a/apps/oneclient/frontend/src/routes/app/settings/index.tsx +++ b/apps/oneclient/frontend/src/routes/app/settings/index.tsx @@ -1,11 +1,12 @@ // import DiscordIcon from '@/assets/logos/discord.svg'; import SettingsRow from '@/components/SettingsRow'; +import SettingsSwitch from '@/components/SettingSwitch'; import { useSettings } from '@/hooks/useSettings'; +import { bindings } from '@/main'; // import useSettings from '@/hooks/useSettings'; import { Button, Switch } from '@onelauncher/common/components'; import { createFileRoute } from '@tanstack/react-router'; import { dataDir, join } from '@tauri-apps/api/path'; -import { openPath } from '@tauri-apps/plugin-opener'; import { FolderIcon, Link03Icon, LinkExternal01Icon } from '@untitled-theme/icons-react'; import { useEffect, useState } from 'react'; import Sidebar from './route'; @@ -15,7 +16,7 @@ export const Route = createFileRoute('/app/settings/')({ }); function RouteComponent() { - const { setting, setSetting } = useSettings(); + const { setting, setSetting, createSetting } = useSettings(); const [launcherDir, setLauncherDir] = useState(''); useEffect(() => { @@ -24,9 +25,7 @@ function RouteComponent() { })(); }, []); - const openLauncherDir = () => openPath(launcherDir); - - // const [discordRpc, setDiscordRpc] = createSetting('discord_enabled', settings?.discord_enabled); + const openLauncherDir = () => bindings.core.open(launcherDir); return ( @@ -38,10 +37,7 @@ function RouteComponent() { icon={} title="Discord RPC" > - setSetting('discord_enabled', val)} - /> + {/* Date: Sun, 31 Aug 2025 19:49:33 +0200 Subject: [PATCH 04/11] refactor: remove unused variables --- apps/oneclient/frontend/src/routes/app/settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/oneclient/frontend/src/routes/app/settings/index.tsx b/apps/oneclient/frontend/src/routes/app/settings/index.tsx index ba53b6f0..ad6f400a 100644 --- a/apps/oneclient/frontend/src/routes/app/settings/index.tsx +++ b/apps/oneclient/frontend/src/routes/app/settings/index.tsx @@ -16,7 +16,7 @@ export const Route = createFileRoute('/app/settings/')({ }); function RouteComponent() { - const { setting, setSetting, createSetting } = useSettings(); + const { createSetting } = useSettings(); const [launcherDir, setLauncherDir] = useState(''); useEffect(() => { From 88ba7a9a00294a438da076c3e8324b22c48793f8 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Tue, 2 Sep 2025 19:53:35 +0200 Subject: [PATCH 05/11] feat: download button visual indication --- apps/oneclient/frontend/src/bindings.gen.ts | 12 +++++----- .../routes/app/cluster/browser/package.tsx | 23 +++++++++++-------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/apps/oneclient/frontend/src/bindings.gen.ts b/apps/oneclient/frontend/src/bindings.gen.ts index 6c32f842..fbcec9da 100644 --- a/apps/oneclient/frontend/src/bindings.gen.ts +++ b/apps/oneclient/frontend/src/bindings.gen.ts @@ -232,12 +232,14 @@ export type VersionType = */ "old_beta" -const ARGS_MAP = { 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}', 'core':'{"writeSettings":["setting"],"getWorlds":["id"],"getRunningProcessesByClusterId":["cluster_id"],"updateClusterProfile":["name","profile"],"getClusterById":["id"],"openMsaLogin":[],"getScreenshots":["id"],"getUsers":[],"getProfileOrDefault":["name"],"updateClusterById":["id","request"],"getDefaultUser":["fallback"],"removeCluster":["id"],"createCluster":["options"],"getPackage":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"open":["input"],"getMultiplePackages":["provider","slugs"],"getLogByName":["id","name"],"getLoadersForVersion":["mc_version"],"isClusterRunning":["cluster_id"],"searchPackages":["provider","query"],"setDefaultUser":["uuid"],"getUser":["uuid"],"killProcess":["pid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid"],"getClusters":[],"getRunningProcesses":[],"getGameVersions":[],"getGlobalProfile":[],"getPackageBody":["provider","body"],"removeUser":["uuid"],"fetchMinecraftProfile":["uuid"],"readSettings":[],"getLogs":["id"]}', 'events':'{"message":["event"],"ingress":["event"],"process":["event"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}' } -export type Router = { 'folders': { fromCluster: (folderName: string) => Promise, -openCluster: (folderName: string) => Promise }, +const ARGS_MAP = { 'events':'{"message":["event"],"ingress":["event"],"process":["event"]}', 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}', 'core':'{"writeSettings":["setting"],"getWorlds":["id"],"getRunningProcessesByClusterId":["cluster_id"],"updateClusterProfile":["name","profile"],"getClusterById":["id"],"openMsaLogin":[],"getScreenshots":["id"],"getUsers":[],"getProfileOrDefault":["name"],"updateClusterById":["id","request"],"getDefaultUser":["fallback"],"removeCluster":["id"],"createCluster":["options"],"getPackage":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"open":["input"],"getMultiplePackages":["provider","slugs"],"getLogByName":["id","name"],"getLoadersForVersion":["mc_version"],"isClusterRunning":["cluster_id"],"searchPackages":["provider","query"],"setDefaultUser":["uuid"],"getUser":["uuid"],"killProcess":["pid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"launchCluster":["id","uuid"],"getClusters":[],"getRunningProcesses":[],"getGameVersions":[],"getGlobalProfile":[],"getPackageBody":["provider","body"],"removeUser":["uuid"],"fetchMinecraftProfile":["uuid"],"readSettings":[],"getLogs":["id"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}' } +export type Router = { 'oneclient': { openDevTools: () => Promise, +getClustersGroupedByMajor: () => Promise> }, 'events': { ingress: (event: IngressPayload) => Promise, message: (event: MessagePayload) => Promise, process: (event: ProcessPayload) => Promise }, +'folders': { fromCluster: (folderName: string) => Promise, +openCluster: (folderName: string) => Promise }, 'core': { getClusters: () => Promise, getClusterById: (id: number) => Promise, removeCluster: (id: number) => Promise, @@ -273,9 +275,7 @@ getPackageVersions: (provider: Provider, slug: string, mcVersion: string | null, downloadPackage: (provider: Provider, packageId: string, versionId: string, clusterId: number, skipCompatibility: boolean | null) => Promise, getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise, fetchMinecraftProfile: (uuid: string) => Promise, -open: (input: string) => Promise }, -'oneclient': { openDevTools: () => Promise, -getClustersGroupedByMajor: () => Promise> } }; +open: (input: string) => Promise } }; export type { InferCommandOutput } diff --git a/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx b/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx index f325a871..dfeec2bf 100644 --- a/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx +++ b/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx @@ -1,12 +1,12 @@ import type { ClusterModel, ManagedPackage, ManagedUser, ManagedVersion, PackageDonationUrl, Provider } from '@/bindings.gen'; -import { LoaderSuspense } from '@/components'; +import { LoaderSuspense, Spinner } from '@/components'; import { ExternalLink } from '@/components/ExternalLink'; import { Markdown } from '@/components/Markdown'; import { bindings } from '@/main'; import { abbreviateNumber, formatAsRelative, upperFirst, useCommand, useCommandMut, useCommandSuspense } from '@onelauncher/common'; -import { Button, Tooltip } from '@onelauncher/common/components'; +import { Button, Show, Tooltip } from '@onelauncher/common/components'; import { createFileRoute, redirect } from '@tanstack/react-router'; -import { CalendarIcon, ClockRewindIcon, Download01Icon, File02Icon } from '@untitled-theme/icons-react'; +import { CalendarIcon, CheckIcon, ClockRewindIcon, Download01Icon, File02Icon, Loading01Icon, Loading02Icon, XIcon } from '@untitled-theme/icons-react'; import { useMemo } from 'react'; import { Cell, Column, Row, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs } from 'react-aria-components'; @@ -349,6 +349,7 @@ function Versions() { function VersionRow({ version }: { version: ManagedVersion }) { const { cluster } = Route.useRouteContext(); const { provider } = Route.useSearch(); + const download = useCommandMut(() => bindings.core.downloadPackage(provider, version.project_id, version.version_id, cluster.id, true)); return ( @@ -365,17 +366,19 @@ function VersionRow({ version }: { version: ManagedVersion }) { {version.downloads} ); } - -function downloadPackage(cluster: ClusterModel, provider: Provider, version: ManagedVersion, skipCompatibility = false) { - return bindings.core.downloadPackage(provider, version.project_id, version.version_id, cluster.id, skipCompatibility); -} From 633fbcddeaca5f47888b0e30a22de9b35752a8a1 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Tue, 2 Sep 2025 19:55:07 +0200 Subject: [PATCH 06/11] refactor: remove unused imports --- .../frontend/src/routes/app/cluster/browser/package.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx b/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx index dfeec2bf..3a1957e6 100644 --- a/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx +++ b/apps/oneclient/frontend/src/routes/app/cluster/browser/package.tsx @@ -1,12 +1,12 @@ -import type { ClusterModel, ManagedPackage, ManagedUser, ManagedVersion, PackageDonationUrl, Provider } from '@/bindings.gen'; -import { LoaderSuspense, Spinner } from '@/components'; +import type { ManagedPackage, ManagedUser, ManagedVersion, PackageDonationUrl } from '@/bindings.gen'; +import { LoaderSuspense } from '@/components'; import { ExternalLink } from '@/components/ExternalLink'; import { Markdown } from '@/components/Markdown'; import { bindings } from '@/main'; import { abbreviateNumber, formatAsRelative, upperFirst, useCommand, useCommandMut, useCommandSuspense } from '@onelauncher/common'; import { Button, Show, Tooltip } from '@onelauncher/common/components'; import { createFileRoute, redirect } from '@tanstack/react-router'; -import { CalendarIcon, CheckIcon, ClockRewindIcon, Download01Icon, File02Icon, Loading01Icon, Loading02Icon, XIcon } from '@untitled-theme/icons-react'; +import { CalendarIcon, CheckIcon, ClockRewindIcon, Download01Icon, File02Icon, Loading02Icon, XIcon } from '@untitled-theme/icons-react'; import { useMemo } from 'react'; import { Cell, Column, Row, Tab, Table, TableBody, TableHeader, TabList, TabPanel, Tabs } from 'react-aria-components'; From c975f3b25fe0562d32c06b3ea8bcd4f3d2694d25 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:50:06 +0200 Subject: [PATCH 07/11] fix License info in mod browser looks weird Fixes #360 --- apps/oneclient/frontend/src/components/ExternalLink.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/oneclient/frontend/src/components/ExternalLink.tsx b/apps/oneclient/frontend/src/components/ExternalLink.tsx index 0dd9dad5..ab64843f 100644 --- a/apps/oneclient/frontend/src/components/ExternalLink.tsx +++ b/apps/oneclient/frontend/src/components/ExternalLink.tsx @@ -45,7 +45,7 @@ export function ExternalLink({ {...rest} > {children} - {withIcon && } + {withIcon && } From 4ab3ef7d408adfeaf44b5cb87715ab6ec5173e9b Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:51:20 +0200 Subject: [PATCH 08/11] fix: get_body invalid body type --- packages/core/src/api/packages/provider/curseforge/mod.rs | 2 +- packages/core/src/api/packages/provider/mod.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/api/packages/provider/curseforge/mod.rs b/packages/core/src/api/packages/provider/curseforge/mod.rs index ac77a80e..ad4d7574 100644 --- a/packages/core/src/api/packages/provider/curseforge/mod.rs +++ b/packages/core/src/api/packages/provider/curseforge/mod.rs @@ -462,7 +462,7 @@ impl From for ManagedPackage { slug: value.slug, name: value.name, short_desc: value.summary, - body: ManagedPackageBody::Url(format!("/v1/mods/{}/description", value.id)), + body: ManagedPackageBody::Url(format!("/mods/{}/description", value.id)), version_ids: latest_version_ids, mc_versions, loaders, diff --git a/packages/core/src/api/packages/provider/mod.rs b/packages/core/src/api/packages/provider/mod.rs index 825c8c8a..20b6876f 100644 --- a/packages/core/src/api/packages/provider/mod.rs +++ b/packages/core/src/api/packages/provider/mod.rs @@ -130,4 +130,8 @@ impl ProviderExt for Provider { async fn get_versions(&self, slugs: &[String]) -> LauncherResult> { delegate!(self, get_versions(slugs)) } + + async fn get_body(&self, body: &ManagedPackageBody) -> LauncherResult { + delegate!(self, get_body(body)) + } } From 75379a917dc1408c9b5a1ede39270295aa0b50b0 Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:24:14 +0200 Subject: [PATCH 09/11] fix: cluster browser style consistency --- .../src/routes/app/cluster/browser/index.tsx | 16 +++++++++------- .../src/routes/app/cluster/browser/route.tsx | 5 ++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/oneclient/frontend/src/routes/app/cluster/browser/index.tsx b/apps/oneclient/frontend/src/routes/app/cluster/browser/index.tsx index 01e8f954..fc66e0b5 100644 --- a/apps/oneclient/frontend/src/routes/app/cluster/browser/index.tsx +++ b/apps/oneclient/frontend/src/routes/app/cluster/browser/index.tsx @@ -1,5 +1,5 @@ import type { Filters, PackageCategories, PackageType, Provider, Sort } from '@/bindings.gen'; -import { LoaderSuspense } from '@/components'; +import { LoaderSuspense, SheetPage } from '@/components'; import { PackageGrid } from '@/components/PackageItem'; import { bindings } from '@/main'; import { browserCategories, categoryNameFromId } from '@/utils/browser'; @@ -33,15 +33,16 @@ const PROVIDERS: Array = ['Modrinth', 'CurseForge', 'SkyClient']; function RouteComponent() { return ( + //
-
-
+
+

Browser

-
+ {/*
*/}
-
+
@@ -54,6 +55,7 @@ function RouteComponent() {
+ // ); } @@ -78,7 +80,7 @@ function BrowserCategories() { return (
-
+
Categories
{browserCategories[categoryNameFromId[packageType]].map(category => ( @@ -111,7 +113,7 @@ function BrowserToolbar() { const [searchBar, setSearchBar] = useState(query); return ( -
+
navigate({ search: { ...search, provider: id as Provider } })} diff --git a/apps/oneclient/frontend/src/routes/app/cluster/browser/route.tsx b/apps/oneclient/frontend/src/routes/app/cluster/browser/route.tsx index 55dbf88d..b9aa0929 100644 --- a/apps/oneclient/frontend/src/routes/app/cluster/browser/route.tsx +++ b/apps/oneclient/frontend/src/routes/app/cluster/browser/route.tsx @@ -1,4 +1,5 @@ import type { Provider } from '@/bindings.gen'; +import { SheetPage } from '@/components'; import { createFileRoute, Outlet } from '@tanstack/react-router'; export interface BrowserRouteSearchParams { @@ -16,6 +17,8 @@ export const Route = createFileRoute('/app/cluster/browser')({ function RouteComponent() { return ( - + + + ); } From 107dd69c4987b61092e2735a2eb63623d64c33fc Mon Sep 17 00:00:00 2001 From: Szedann <65607498+Szedann@users.noreply.github.com> Date: Thu, 4 Sep 2025 16:09:57 +0200 Subject: [PATCH 10/11] fix padding issues #358 --- .../frontend/src/components/Navbar.tsx | 69 ++++++++++--------- .../frontend/src/components/Tabs.tsx | 2 +- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/apps/oneclient/frontend/src/components/Navbar.tsx b/apps/oneclient/frontend/src/components/Navbar.tsx index f09af13c..1dfc6742 100644 --- a/apps/oneclient/frontend/src/components/Navbar.tsx +++ b/apps/oneclient/frontend/src/components/Navbar.tsx @@ -31,41 +31,42 @@ export function Navbar() { Accounts
-
- } - onClick={() => navigate({ to: '/app/settings' })} - /> - - - - +
+
+ } + onClick={() => navigate({ to: '/app/settings' })} + /> + + + + + + +
- - - - } - onClick={onMinimize} - /> - - } - onClick={onMaximize} - /> - - - )} - className="bg-transparent" - color="danger" - onClick={onClose} - /> +
+ } + onClick={onMinimize} + /> + } + onClick={onMaximize} + /> + + )} + className="bg-transparent" + color="danger" + onClick={onClose} + /> +
diff --git a/apps/oneclient/frontend/src/components/Tabs.tsx b/apps/oneclient/frontend/src/components/Tabs.tsx index 34f27446..081fd766 100644 --- a/apps/oneclient/frontend/src/components/Tabs.tsx +++ b/apps/oneclient/frontend/src/components/Tabs.tsx @@ -15,7 +15,7 @@ export function TabList({
Date: Thu, 4 Sep 2025 16:34:35 +0200 Subject: [PATCH 11/11] feat: account popup from onelauncher (fixes #363) --- .../src/components/overlay/AccountPopup.tsx | 129 +++++++++++------- .../frontend/src/components/overlay/Popup.tsx | 2 +- 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/apps/oneclient/frontend/src/components/overlay/AccountPopup.tsx b/apps/oneclient/frontend/src/components/overlay/AccountPopup.tsx index fef75347..d3cf6579 100644 --- a/apps/oneclient/frontend/src/components/overlay/AccountPopup.tsx +++ b/apps/oneclient/frontend/src/components/overlay/AccountPopup.tsx @@ -1,76 +1,99 @@ import type { MinecraftCredentials } from '@/bindings.gen'; -import { AccountAvatar } from '@/components/AccountAvatar'; import { bindings } from '@/main'; -import { useCommandMut, useCommandSuspense } from '@onelauncher/common'; -import { useQueryClient } from '@tanstack/react-query'; -import { Button as AriaButton } from 'react-aria-components'; +import { useCommand, useCommandMut } from '@onelauncher/common'; +import { Button } from '@onelauncher/common/components'; +import { Link } from '@tanstack/react-router'; +import { PlusIcon, Settings01Icon } from '@untitled-theme/icons-react'; +import { DialogTrigger } from 'react-aria-components'; import { twMerge } from 'tailwind-merge'; +import { AccountAvatar } from '../AccountAvatar'; +import { AddAccountModal } from './AddAccountModal'; +import { Overlay } from './Overlay'; import { Popup } from './Popup'; export function AccountPopup() { - const { data: currentAccount } = useCommandSuspense(['getDefaultUser'], () => bindings.core.getDefaultUser(true)); - const { data: accounts } = useCommandSuspense(['getUsers', 'accountPopup'], bindings.core.getUsers, { - select(data) { - data.sort((a, b) => { - if (currentAccount?.id === a.id) - return -1; - else if (currentAccount?.id === b.id) - return 1; - return a.username.localeCompare(b.username); - }); + const users = useCommand(['getUsers'], bindings.core.getUsers); + const defaultUser = useCommand(['getDefaultUser'], () => bindings.core.getDefaultUser(false)); - return data; - }, - }); - - const queryClient = useQueryClient(); - const { mutate: setDefaultUser } = useCommandMut(bindings.core.setDefaultUser, { - onSuccess() { - queryClient.invalidateQueries({ - queryKey: ['getDefaultUser'], - }); - }, - }); + const setDefaultUser = (user: MinecraftCredentials) => { + bindings.core.setDefaultUser(user.id); + }; return ( -
- {accounts.map(profile => ( - setDefaultUser(profile.id)} - profile={profile} - selected={profile.id === currentAccount?.id} - /> + +
+ {defaultUser.data && ( +
+ { }} + user={defaultUser.data} + /> +
+ )} + + {users.data?.filter(user => user.id !== defaultUser.data?.id).map(user => ( +
+ setDefaultUser(user)} + user={user} + /> +
))} + +
+
+ + + + + + + + +
+
+ + + +
+
); } -function AccountRow({ - selected = false, - profile, - onPress, +export default AccountPopup; + +function AccountEntry({ + onClick, + user, + loggedIn = false, }: { - selected?: boolean; - profile: MinecraftCredentials; - onPress: () => void; + onClick: () => void; + user: MinecraftCredentials; + loggedIn?: boolean; }) { return ( - - - -
-

{profile.username}

+
+ +
+
+

{user.username}

+ {loggedIn &&

Logged in

} +
+
- +
); } diff --git a/apps/oneclient/frontend/src/components/overlay/Popup.tsx b/apps/oneclient/frontend/src/components/overlay/Popup.tsx index 8003fe82..dd60f3ce 100644 --- a/apps/oneclient/frontend/src/components/overlay/Popup.tsx +++ b/apps/oneclient/frontend/src/components/overlay/Popup.tsx @@ -18,7 +18,7 @@ const popupVariants = tv({ ], dialog: [ 'flex flex-col items-center p-1 gap-2 relative', - 'border border-component-border-hover bg-page-elevated shadow-md rounded-lg', + 'border border-component-border-hover bg-page-elevated shadow-md rounded-xl', ], }, });