From 3ff8bea8ef48128e584e90c973dca9b6cede5678 Mon Sep 17 00:00:00 2001 From: emirsassan Date: Fri, 5 Sep 2025 14:33:22 +0300 Subject: [PATCH] feat: onboarding and a few refactor --- .vscode/settings.json | 2 +- .../frontend/src/assets/logos/Logo.svg | 9 ++ apps/oneclient/frontend/src/bindings.gen.ts | 14 +- .../routes/onboarding/preferences/mods.tsx | 107 ++++++++++++++- .../onboarding/preferences/versions.tsx | 6 +- .../frontend/src/routes/onboarding/route.tsx | 11 +- .../web_common/src/components/TabList.tsx | 127 ++++++++++++++++++ packages/web_common/src/components/index.ts | 1 + .../web_common/src/hooks/usePagination.tsx | 2 +- pnpm-lock.yaml | 9 +- 10 files changed, 261 insertions(+), 27 deletions(-) create mode 100644 apps/oneclient/frontend/src/assets/logos/Logo.svg create mode 100644 packages/web_common/src/components/TabList.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 871b4462..a5fedb36 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,7 +12,7 @@ "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" }, "[typescriptreact]": { - "editor.defaultFormatter": "dbaeumer.vscode-eslint" + "editor.defaultFormatter": "vscode.typescript-language-features" }, "files.readonlyInclude": { "**/node_modules/**": true, diff --git a/apps/oneclient/frontend/src/assets/logos/Logo.svg b/apps/oneclient/frontend/src/assets/logos/Logo.svg new file mode 100644 index 00000000..d5494599 --- /dev/null +++ b/apps/oneclient/frontend/src/assets/logos/Logo.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/oneclient/frontend/src/bindings.gen.ts b/apps/oneclient/frontend/src/bindings.gen.ts index 425e76b7..32df5ee1 100644 --- a/apps/oneclient/frontend/src/bindings.gen.ts +++ b/apps/oneclient/frontend/src/bindings.gen.ts @@ -169,7 +169,7 @@ export type SettingProfileModel = { name: string; java_id: number | null; res: R export type Settings = { global_game_settings: SettingProfileModel; allow_parallel_running_clusters: boolean; enable_gamemode: boolean; discord_enabled: boolean; max_concurrent_requests: number; settings_version: number; native_window_frame: boolean } -export type SettingsOsExtra = { enable_gamemode: boolean | null } +export type SettingsOsExtra = Record export type Sort = "Relevance" | "Downloads" | "Newest" | "Updated" @@ -232,9 +232,9 @@ export type VersionType = */ "old_beta" -const ARGS_MAP = { 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}', 'core':'{"createCluster":["options"],"getGlobalProfile":[],"getLoadersForVersion":["mc_version"],"getScreenshots":["id"],"getUsers":[],"getPackage":["provider","slug"],"getDefaultUser":["fallback"],"getPackageBody":["provider","body"],"writeSettings":["setting"],"open":["input"],"isClusterRunning":["cluster_id"],"getMultiplePackages":["provider","slugs"],"killProcess":["pid"],"updateClusterProfile":["name","profile"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getUsersFromAuthor":["provider","author"],"getLogByName":["id","name"],"removeUser":["uuid"],"fetchMinecraftProfile":["uuid"],"openMsaLogin":[],"getProfileOrDefault":["name"],"getUser":["uuid"],"getClusters":[],"getWorlds":["id"],"launchCluster":["id","uuid"],"readSettings":[],"removeCluster":["id"],"searchPackages":["provider","query"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"getGameVersions":[],"setDefaultUser":["uuid"],"getClusterById":["id"],"updateClusterById":["id","request"],"getRunningProcessesByClusterId":["cluster_id"],"getLogs":["id"],"getRunningProcesses":[]}', 'oneclient':'{"openDevTools":[],"getClustersGroupedByMajor":[]}', 'events':'{"process":["event"],"ingress":["event"],"message":["event"]}' } -export type Router = { 'folders': { fromCluster: (folderName: string) => Promise, -openCluster: (folderName: string) => Promise }, +const ARGS_MAP = { 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}', 'core':'{"getRunningProcessesByClusterId":["cluster_id"],"writeSettings":["setting"],"getPackage":["provider","slug"],"open":["input"],"updateClusterProfile":["name","profile"],"getScreenshots":["id"],"fetchMinecraftProfile":["uuid"],"launchCluster":["id","uuid"],"readSettings":[],"getMultiplePackages":["provider","slugs"],"getClusters":[],"updateClusterById":["id","request"],"getRunningProcesses":[],"getGlobalProfile":[],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"getProfileOrDefault":["name"],"getUser":["uuid"],"createCluster":["options"],"killProcess":["pid"],"setDefaultUser":["uuid"],"openMsaLogin":[],"searchPackages":["provider","query"],"isClusterRunning":["cluster_id"],"getPackageBody":["provider","body"],"getLoadersForVersion":["mc_version"],"removeUser":["uuid"],"getClusterById":["id"],"removeCluster":["id"],"getGameVersions":[],"getUsers":[],"getUsersFromAuthor":["provider","author"],"getLogByName":["id","name"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"getDefaultUser":["fallback"],"getLogs":["id"],"getWorlds":["id"]}', 'oneclient':'{"getClustersGroupedByMajor":[],"openDevTools":[]}', 'events':'{"message":["event"],"process":["event"],"ingress":["event"]}' } +export type Router = { 'oneclient': { openDevTools: () => Promise, +getClustersGroupedByMajor: () => Promise> }, 'core': { getClusters: () => Promise, getClusterById: (id: number) => Promise, removeCluster: (id: number) => Promise, @@ -271,11 +271,11 @@ downloadPackage: (provider: Provider, packageId: string, versionId: string, clus getUsersFromAuthor: (provider: Provider, author: PackageAuthor) => Promise, fetchMinecraftProfile: (uuid: string) => Promise, open: (input: string) => Promise }, +'folders': { fromCluster: (folderName: string) => Promise, +openCluster: (folderName: string) => Promise }, 'events': { ingress: (event: IngressPayload) => Promise, message: (event: MessagePayload) => Promise, -process: (event: ProcessPayload) => Promise }, -'oneclient': { openDevTools: () => Promise, -getClustersGroupedByMajor: () => Promise> } }; +process: (event: ProcessPayload) => Promise } }; export type { InferCommandOutput } diff --git a/apps/oneclient/frontend/src/routes/onboarding/preferences/mods.tsx b/apps/oneclient/frontend/src/routes/onboarding/preferences/mods.tsx index 48e17f3f..ba01587d 100644 --- a/apps/oneclient/frontend/src/routes/onboarding/preferences/mods.tsx +++ b/apps/oneclient/frontend/src/routes/onboarding/preferences/mods.tsx @@ -1,9 +1,108 @@ -import { createFileRoute } from '@tanstack/react-router' +import { Tab, TabContent, TabList, TabPanel, Tabs } from '@onelauncher/common/components'; +import { createFileRoute } from '@tanstack/react-router'; +import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; +import { twMerge } from 'tailwind-merge'; export const Route = createFileRoute('/onboarding/preferences/mods')({ - component: RouteComponent, -}) + component: RouteComponent, +}); function RouteComponent() { - return
Hello "/onboarding/preferences/mods"!
+ return ( +
+
+

Choose Mods

+

+ Something something in corporate style fashion about picking your preferred gamemodes and versions and + optionally loader so that oneclient can pick something for them +

+ +
+ + + Skyblock + Survival + Minigames + PVP + GUI + Utility + Misc + +
+
+ 31 Mods selected +
+
+
+ + + + +
+ {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].map(x => ( +
+ {x % 2 === 0 ? : } +
+ ))} +
+
+
+
+
+
+
+
+ ); +} + +interface ModCardProps { + active: boolean; +} + +function ModCard(props: ModCardProps) { + const { active } = props; + + return ( +
+
+ +
+

Chatting

+

+ by + {' '} + {' '} + Polyfrost +

+
+
+
+

Chatting is a chat mod adding utilities such as extremely customizable chat tabs, chat shortcuts, chat screenshots, and message copying.

+
+
+ ); +} + +function ModCard2(props: ModCardProps) { + const { active } = props; + + return ( +
+
+ +
+

Chatting

+

+ by + {' '} + {' '} + Polyfrost +

+
+
+
+

Chatting is a chat mod adding utilities such as extremely customizable chat tabs, chat shortcuts, chat screenshots, and message copying. Chatting is a chat mod adding utilities such as extremely customizable chat tabs, chat shortcuts, chat screenshots, and message copying Chatting is a chat mod adding utilities such as extremely customizable chat tabs, chat shortcuts, chat screenshots, and message copying

+
+
+ ); } diff --git a/apps/oneclient/frontend/src/routes/onboarding/preferences/versions.tsx b/apps/oneclient/frontend/src/routes/onboarding/preferences/versions.tsx index b02241c2..e75e7427 100644 --- a/apps/oneclient/frontend/src/routes/onboarding/preferences/versions.tsx +++ b/apps/oneclient/frontend/src/routes/onboarding/preferences/versions.tsx @@ -25,7 +25,7 @@ const versions = [ function RouteComponent() { return ( -
+

Starting Versions

@@ -42,7 +42,7 @@ function RouteComponent() { /> ))}

-
+
@@ -63,7 +63,7 @@ export function VersionCard({ version, tags }: VersionCardProps) {
{`Minecraft diff --git a/apps/oneclient/frontend/src/routes/onboarding/route.tsx b/apps/oneclient/frontend/src/routes/onboarding/route.tsx index b534dc2a..8a362461 100644 --- a/apps/oneclient/frontend/src/routes/onboarding/route.tsx +++ b/apps/oneclient/frontend/src/routes/onboarding/route.tsx @@ -1,5 +1,6 @@ import type { PropsWithChildren } from 'react'; -import Logo from '@/assets/logos/oneclient2.svg'; +import Logo from '@/assets/logos/Logo.svg'; +import LauncherLogo from '@/assets/logos/oneclient.svg?react'; import { LoaderSuspense, NavbarButton } from '@/components'; import { GameBackground } from '@/components/GameBackground'; import { Stepper } from '@/components/Stepper'; @@ -109,7 +110,7 @@ function AppShell({
- logo +
@@ -131,10 +132,10 @@ function AppShell({ } function BackgroundGradient() { - const background = useAppShellStore(state => state.background); + // const background = useAppShellStore(state => state.background); - if (background === 'none') - return undefined; + // if (background === 'none') + // return undefined; return (
diff --git a/packages/web_common/src/components/TabList.tsx b/packages/web_common/src/components/TabList.tsx new file mode 100644 index 00000000..000dc7d1 --- /dev/null +++ b/packages/web_common/src/components/TabList.tsx @@ -0,0 +1,127 @@ +import type { HTMLAttributes, ReactNode, Ref } from 'react'; +import { createContext, useContext, useState } from 'react'; +import { twMerge } from 'tailwind-merge'; + +// i thank chatgpt for this i dont want to replace current tabs component yet so this is going to be here for some time +interface TabsContextType { + activeTab: string; + setActiveTab: (value: string) => void; +} + +const TabsContext = createContext(null); + +function useTabs() { + const context = useContext(TabsContext); + if (!context) + throw new Error('useTabs must be used within a component'); + + return context; +} + +interface TabsProps { + defaultValue: string; + children: ReactNode; +} + +export function Tabs({ defaultValue, children }: TabsProps) { + const [activeTab, setActiveTab] = useState(defaultValue); + + return ( + + {children} + + ); +} + +interface TabListProps extends HTMLAttributes { + floating?: boolean; + ref?: Ref; +} + +export function TabList({ + className, + children, + floating = false, + ref, +}: TabListProps) { + return ( +
+
+ {children} +
+
+ ); +} + +interface TabProps extends Omit, 'value'> { + value: string; +} + +export function Tab({ + children, + value, + className, + ...rest +}: TabProps) { + const { activeTab, setActiveTab } = useTabs(); + const isActive = activeTab === value; + + return ( +
+ +
+ ); +} + +interface TabPanelProps extends HTMLAttributes { + value: string; +} + +export function TabPanel({ children, value, ...rest }: TabPanelProps) { + const { activeTab } = useTabs(); + + if (activeTab !== value) + return null; + + return ( +
+ {children} +
+ ); +} + +export function TabContent({ children, className, ...rest }: HTMLAttributes) { + return ( +
+ {children} +
+ ); +} diff --git a/packages/web_common/src/components/index.ts b/packages/web_common/src/components/index.ts index 1632a0ac..6445f0b5 100644 --- a/packages/web_common/src/components/index.ts +++ b/packages/web_common/src/components/index.ts @@ -7,6 +7,7 @@ export * from './Popup'; export * from './SelectList'; export * from './Show'; export * from './Switch'; +export * from './TabList'; export * from './TextField'; export * from './ToggleButton'; export * from './Tooltip'; 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; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed0eab31..c243cacb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -277,9 +277,6 @@ importers: '@tauri-apps/plugin-dialog': specifier: 'catalog:' version: 2.2.1 - '@tauri-apps/plugin-opener': - specifier: 'catalog:' - version: 2.3.0 '@untitled-theme/icons-react': specifier: 'catalog:' version: 0.14.0(@types/react@19.1.2)(react@19.1.0) @@ -304,12 +301,12 @@ importers: react-just-parallax: specifier: 'catalog:' version: 3.1.16(react@19.1.0) - react-toastify: - specifier: 'catalog:' - version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react-markdown: specifier: ^10.1.0 version: 10.1.0(@types/react@19.1.2)(react@19.1.0) + react-toastify: + specifier: 'catalog:' + version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) rehype-raw: specifier: ^7.0.0 version: 7.0.0