Merge branch 'oneclient/main' of https://github.com/Polyfrost/OneLauncher into refactor/frontend
This commit is contained in:
commit
7a25c017e6
39 changed files with 1623 additions and 553 deletions
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
// updated 2024-08-26 15:46
|
||||
// https://github.com/antfu/vscode-file-nesting-config
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.enabled": false,
|
||||
"explorer.fileNesting.expand": false,
|
||||
"explorer.fileNesting.patterns": {
|
||||
".clang-tidy": ".clang-format, .clangd, compile_commands.json",
|
||||
|
|
|
|||
2
apps/oneclient/frontend/.gitignore
vendored
2
apps/oneclient/frontend/.gitignore
vendored
|
|
@ -4,4 +4,4 @@ dist
|
|||
dist-ssr
|
||||
*.local
|
||||
|
||||
*.gen.ts
|
||||
**/*.gen.ts
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
"tailwindcss": "^4.0.6",
|
||||
"tailwindcss-animated": "^2.0.0",
|
||||
"tailwindcss-react-aria-components": "^2.0.0",
|
||||
"taurpc": "^1.8.1"
|
||||
"taurpc": "^1.8.1",
|
||||
"zustand": "^5.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tanstack/eslint-config": "^0.1.0",
|
||||
|
|
@ -47,6 +48,7 @@
|
|||
"@types/react-dom": "^19.0.3",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"typescript": "^5.7.2",
|
||||
"vite": "^6.1.0"
|
||||
"vite": "^6.1.0",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
4
apps/oneclient/frontend/src/assets/logos/oneclient.svg
Normal file
4
apps/oneclient/frontend/src/assets/logos/oneclient.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="156" height="32" viewBox="0 0 156 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.9398 25.6841C9.60192 25.6841 8.3644 25.447 7.22718 24.9728C6.10671 24.4986 5.12003 23.8381 4.26712 22.9913C3.41424 22.1446 2.75365 21.1623 2.28539 20.0446C1.81714 18.9099 1.58301 17.6905 1.58301 16.3865C1.58301 15.0655 1.81714 13.8461 2.28539 12.7284C2.75365 11.6107 3.40587 10.6368 4.24206 9.80701C5.07821 8.96023 6.05654 8.3082 7.17703 7.85093C8.31422 7.37675 9.55174 7.13965 10.8896 7.13965C12.2108 7.13965 13.4316 7.37675 14.5521 7.85093C15.6893 8.3082 16.676 8.96023 17.5122 9.80701C18.365 10.6368 19.0256 11.6191 19.4939 12.7538C19.9621 13.8715 20.1963 15.0909 20.1963 16.4119C20.1963 17.7159 19.9621 18.9353 19.4939 20.07C19.0256 21.1877 18.3734 22.17 17.5372 23.0168C16.7011 23.8466 15.7144 24.4986 14.5772 24.9728C13.4567 25.447 12.2443 25.6841 10.9398 25.6841ZM10.8896 22.0514C11.9432 22.0514 12.863 21.8143 13.649 21.3401C14.4517 20.8659 15.0705 20.2054 15.5053 19.3587C15.9401 18.495 16.1576 17.5042 16.1576 16.3865C16.1576 15.5397 16.0321 14.7776 15.7813 14.1002C15.5304 13.4058 15.1709 12.8131 14.7026 12.3219C14.2344 11.8139 13.6741 11.4328 13.0219 11.1788C12.3864 10.9078 11.6757 10.7723 10.8896 10.7723C9.83606 10.7723 8.90791 11.0094 8.10518 11.4836C7.31917 11.9409 6.70876 12.5929 6.27395 13.4397C5.83913 14.2695 5.62175 15.2518 5.62175 16.3865C5.62175 17.2332 5.74716 18.0038 5.99802 18.6982C6.24886 19.3925 6.60007 19.9937 7.05159 20.5018C7.51986 20.9929 8.08009 21.374 8.73232 21.645C9.38451 21.9159 10.1036 22.0514 10.8896 22.0514ZM24.2015 25.3793V7.4445H26.9609L28.1399 11.0264V25.3793H24.2015ZM36.4181 25.3793L25.9825 11.8393L26.9609 7.4445L37.3963 20.9845L36.4181 25.3793ZM36.4181 25.3793L35.3644 21.7974V7.4445H39.3029V25.3793H36.4181ZM44.2267 25.3793V7.4445H48.1649V25.3793H44.2267ZM47.2368 25.3793V21.9244H56.9448V25.3793H47.2368ZM47.2368 17.8853V14.5574H56.0669V17.8853H47.2368ZM47.2368 10.8739V7.4445H56.8192V10.8739H47.2368Z" fill="currentColor" fill-opacity="0.85"/>
|
||||
<path d="M69.2499 25.6588C67.9287 25.6588 66.6996 25.4302 65.5623 24.9729C64.4419 24.4987 63.4552 23.8382 62.6023 22.9915C61.7663 22.1447 61.1139 21.1624 60.6456 20.0447C60.1774 18.91 59.9434 17.6906 59.9434 16.3866C59.9434 15.0825 60.1774 13.8716 60.6456 12.7539C61.1139 11.6192 61.7663 10.6369 62.6023 9.80712C63.4386 8.97727 64.4168 8.33371 65.5373 7.87644C66.6746 7.40227 67.9037 7.16516 69.2248 7.16516C70.6296 7.16516 71.8756 7.3938 72.9625 7.85104C74.0663 8.30831 75.0279 8.93493 75.8473 9.7309L73.2134 12.4236C72.7452 11.9156 72.1766 11.5176 71.5076 11.2297C70.8555 10.9418 70.0946 10.7979 69.2248 10.7979C68.4556 10.7979 67.7448 10.9333 67.0927 11.2043C66.4572 11.4583 65.9053 11.8309 65.437 12.322C64.9854 12.8132 64.626 13.4059 64.3583 14.1003C64.1074 14.7946 63.9821 15.5567 63.9821 16.3866C63.9821 17.2334 64.1074 18.0039 64.3583 18.6983C64.626 19.3926 64.9854 19.9854 65.437 20.4765C65.9053 20.9676 66.4572 21.3487 67.0927 21.6197C67.7448 21.8907 68.4556 22.0261 69.2248 22.0261C70.1279 22.0261 70.914 21.8822 71.5828 21.5943C72.2518 21.3064 72.8288 20.9084 73.3137 20.4003L75.9729 23.0931C75.12 23.8891 74.1415 24.5156 73.0377 24.9729C71.9508 25.4302 70.6882 25.6588 69.2499 25.6588ZM79.6466 25.3794V7.44461H83.5851V25.3794H79.6466ZM82.6821 25.3794V21.8737H91.4367V25.3794H82.6821ZM95.2131 25.3794V7.44461H99.1515V25.3794H95.2131ZM104.067 25.3794V7.44461H108.006V25.3794H104.067ZM107.078 25.3794V21.9245H116.786V25.3794H107.078ZM107.078 17.8854V14.5575H115.908V17.8854H107.078ZM107.078 10.874V7.44461H116.66V10.874H107.078ZM121.006 25.3794V7.44461H123.765L124.944 11.0265V25.3794H121.006ZM133.222 25.3794L122.787 11.8394L123.765 7.44461L134.201 20.9846L133.222 25.3794ZM133.222 25.3794L132.169 21.7975V7.44461H136.107V25.3794H133.222ZM145.371 25.3794V7.69862H149.309V25.3794H145.371ZM139.827 10.9249V7.44461H154.853V10.9249H139.827Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
24
apps/oneclient/frontend/src/components/GameBackground.tsx
Normal file
24
apps/oneclient/frontend/src/components/GameBackground.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { twMerge } from 'tailwind-merge';
|
||||
import HypixelSkyblockHub from '../assets/backgrounds/HypixelSkyblockHub.png';
|
||||
|
||||
const GameBackgrounds = {
|
||||
HypixelSkyblockHub,
|
||||
};
|
||||
|
||||
type GameBackgroundName = keyof typeof GameBackgrounds;
|
||||
|
||||
interface GameBackgroundProps {
|
||||
name: GameBackgroundName;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function GameBackground({ name, className = '' }: GameBackgroundProps) {
|
||||
const BackgroundImage = GameBackgrounds[name];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={twMerge(`absolute -z-50 pointer-events-none inset-0 bg-cover bg-center`, className)}
|
||||
style={{ backgroundImage: `url(${BackgroundImage})` }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import type { Context } from 'react';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
const myContext = createContext(null) as Context<
|
||||
{
|
||||
text: string;
|
||||
} | null
|
||||
>;
|
||||
|
||||
export function MyContextProvider({ children, value }: {
|
||||
children: React.ReactNode;
|
||||
value: {
|
||||
text: string;
|
||||
} | null;
|
||||
}) {
|
||||
// eslint-disable-next-line react/no-context-provider -- ok
|
||||
return <myContext.Provider value={value}>{children}</myContext.Provider>;
|
||||
}
|
||||
|
||||
export default function useMyContext() {
|
||||
const context = useContext(myContext);
|
||||
|
||||
if (!context)
|
||||
throw new Error('useMyContext must be used within a MyContextProvider');
|
||||
|
||||
return context;
|
||||
}
|
||||
98
apps/oneclient/frontend/src/components/Navbar.tsx
Normal file
98
apps/oneclient/frontend/src/components/Navbar.tsx
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import type { ButtonProps } from '@onelauncher/common/components';
|
||||
import type { LinkProps } from '@tanstack/react-router';
|
||||
import LauncherLogo from '@/assets/logos/oneclient.svg?react';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { Window } from '@tauri-apps/api/window';
|
||||
import { MinusIcon, SquareIcon, XCloseIcon } from '@untitled-theme/icons-react';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function Navbar() {
|
||||
const onMinimize = () => Window.getCurrent().minimize();
|
||||
const onMaximize = () => Window.getCurrent().toggleMaximize();
|
||||
const onClose = () => Window.getCurrent().close();
|
||||
|
||||
return (
|
||||
<nav className="flex flex-row items-center justify-between h-20" data-tauri-drag-region="true">
|
||||
<div className="flex flex-1 pointer-events-none">
|
||||
<LauncherLogo height={47} width={230} />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 items-center justify-center pointer-events-none gap-6">
|
||||
<NavbarLink to="/app">Home</NavbarLink>
|
||||
<NavbarLink to="/app/test">Clusters</NavbarLink>
|
||||
<NavbarLink to="/">Accounts</NavbarLink>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 items-center justify-end gap-2">
|
||||
<NavbarButton
|
||||
children={<MinusIcon />}
|
||||
onClick={onMinimize}
|
||||
/>
|
||||
<NavbarButton
|
||||
children={<SquareIcon />}
|
||||
onClick={onMaximize}
|
||||
/>
|
||||
<NavbarButton
|
||||
children={(
|
||||
<XCloseIcon
|
||||
height={28}
|
||||
strokeWidth={1.5}
|
||||
width={28}
|
||||
/>
|
||||
)}
|
||||
className="bg-transparent"
|
||||
color="danger"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
function NavbarLink({
|
||||
to,
|
||||
children,
|
||||
}: LinkProps) {
|
||||
return (
|
||||
<div className="flex-1 flex justify-center items-center">
|
||||
<Link
|
||||
activeOptions={{
|
||||
exact: true,
|
||||
}}
|
||||
activeProps={{
|
||||
className: 'text-fg-primary font-semibold partial-underline-75% pointer-events-none',
|
||||
}}
|
||||
className="text-center text-2lg transition-all duration-100 after:duration-100 after:transition-all"
|
||||
inactiveProps={{
|
||||
className: 'text-fg-secondary font-normal partial-underline-0% hover:partial-underline-50% hover:font-medium hover:text-fg-secondary-hover after:text-fg-secondary-hover pointer-events-auto',
|
||||
}}
|
||||
to={to}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function NavbarButton({
|
||||
children,
|
||||
color = 'ghost',
|
||||
size = 'iconLarge',
|
||||
onClick,
|
||||
className = '',
|
||||
...rest
|
||||
}: ButtonProps) {
|
||||
return (
|
||||
<Button
|
||||
className={twMerge('flex items-center justify-center w-12 h-12 pointer-events-auto', className)}
|
||||
color={color}
|
||||
onClick={onClick}
|
||||
size={size}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
2
apps/oneclient/frontend/src/components/index.ts
Normal file
2
apps/oneclient/frontend/src/components/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from './GameBackground';
|
||||
export * from './Navbar';
|
||||
|
|
@ -1,20 +1,42 @@
|
|||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import { createRootRouteWithContext, Outlet } from '@tanstack/react-router';
|
||||
import type { NavigateOptions, ToOptions } from '@tanstack/react-router';
|
||||
import { Navbar } from '@/components';
|
||||
import { AnimatedOutletProvider } from '@onelauncher/common/components';
|
||||
import { createRootRouteWithContext, Outlet, useRouter } from '@tanstack/react-router';
|
||||
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
|
||||
import { RouterProvider } from 'react-aria-components';
|
||||
|
||||
interface MyRouterContext {
|
||||
queryClient: QueryClient;
|
||||
}
|
||||
|
||||
declare module 'react-aria-components' {
|
||||
interface RouterConfig {
|
||||
href: ToOptions['to'];
|
||||
routerOptions: Omit<NavigateOptions, keyof ToOptions>;
|
||||
}
|
||||
}
|
||||
|
||||
export const Route = createRootRouteWithContext<MyRouterContext>()({
|
||||
component: RootLayout,
|
||||
component: RootRoute,
|
||||
});
|
||||
|
||||
function RootLayout() {
|
||||
function RootRoute() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<Outlet />
|
||||
<TanStackRouterDevtools />
|
||||
</>
|
||||
<AnimatedOutletProvider>
|
||||
<RouterProvider
|
||||
navigate={(to, options) => router.navigate({ to, ...options })}
|
||||
useHref={to => router.buildLocation({ to }).href}
|
||||
>
|
||||
<div className="h-screen flex flex-col overflow-hidden text-fg-primary px-12">
|
||||
<Navbar />
|
||||
|
||||
<Outlet />
|
||||
|
||||
<TanStackRouterDevtools />
|
||||
</div>
|
||||
</RouterProvider>
|
||||
</AnimatedOutletProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
21
apps/oneclient/frontend/src/routes/app/index.tsx
Normal file
21
apps/oneclient/frontend/src/routes/app/index.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/app/')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col justify-center">
|
||||
<div className="flex flex-1 flex-col justify-center">
|
||||
<h1 className="text-5xl font-semibold text-fg-primary">1.8.9</h1>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row h-56">
|
||||
<div className="flex-1 rounded-xl border border-solid border-component-border bg-page-overlay">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
63
apps/oneclient/frontend/src/routes/app/route.tsx
Normal file
63
apps/oneclient/frontend/src/routes/app/route.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { GameBackground } from '@/components/GameBackground';
|
||||
import { AnimatedOutlet } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/app')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div className="h-full w-full">
|
||||
<Background />
|
||||
|
||||
<div className="h-full w-full">
|
||||
<AnimatedOutlet
|
||||
enter={{
|
||||
initial: { opacity: 0, transform: 'translateX(-20%)' },
|
||||
animate: { opacity: 1, transform: 'translateX(0)' },
|
||||
}}
|
||||
exit={{
|
||||
initial: { opacity: 1, transform: 'translateX(0)' },
|
||||
animate: { opacity: 0, transform: 'translateX(-20%)' },
|
||||
}}
|
||||
from={Route.id}
|
||||
transition={{ duration: 0.3, bounce: 0.1, power: 0.2, type: 'spring' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Background() {
|
||||
return (
|
||||
<div>
|
||||
{/* Linear gradient: left -> right */}
|
||||
<div
|
||||
className="absolute top-0 left-0 w-screen h-screen -z-10"
|
||||
style={{
|
||||
background: 'linear-gradient(270deg, rgba(0, 0, 0, 0.00) 35%, rgba(0, 0, 0, 0.60) 87.5%)',
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
|
||||
{/* Radial Gradient */}
|
||||
<div
|
||||
className="absolute top-0 left-0 w-screen h-screen -z-10" style={{
|
||||
background: 'radial-gradient(48.29% 48.29% at 77.29% 50%, rgba(0, 0, 0, 0.00) 0%, rgba(0, 0, 0, 0.64) 100%)',
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
|
||||
{/* Linear gradient: bottom -> 200 px up */}
|
||||
<div
|
||||
className="absolute bottom-0 left-0 w-screen h-50 -z-10" style={{
|
||||
background: 'linear-gradient(180deg, rgba(17, 23, 28, 0.00) 0%, rgba(0, 0, 0, 0.68) 60%)',
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
|
||||
<GameBackground name="HypixelSkyblockHub" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
9
apps/oneclient/frontend/src/routes/app/test.tsx
Normal file
9
apps/oneclient/frontend/src/routes/app/test.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/app/test')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return <div>Hello "/app/test"!</div>;
|
||||
}
|
||||
|
|
@ -1,55 +1,9 @@
|
|||
import type { LauncherError } from '@/bindings.gen';
|
||||
import { bindings } from '@/main';
|
||||
import { Button } from '@onelauncher/common/components';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { createFileRoute, Navigate } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/')({
|
||||
component: App,
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function App() {
|
||||
const onClick = async () => {
|
||||
// const result = await bindings.core.createCluster({
|
||||
// name: 'Test 1.8.9 Forge',
|
||||
// mc_loader: 'forge',
|
||||
// mc_version: '1.8.9',
|
||||
// icon: null,
|
||||
// mc_loader_version: '11.15.1.2318',
|
||||
// });
|
||||
|
||||
try {
|
||||
// await bindings.core.launchCluster(9 as unknown as bigint, null);
|
||||
await bindings.core.removeCluster(9 as unknown as bigint);
|
||||
|
||||
const unlisten = await bindings.events.process.on((e) => {
|
||||
if (e.type === 'Output') { console.log(e.output); }
|
||||
else if (e.type === 'Stopped') {
|
||||
console.log(e.exit_code);
|
||||
unlisten();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (err: unknown) {
|
||||
let error = err as LauncherError;
|
||||
// console.log(error);
|
||||
// if (error.type === 'DaoError')
|
||||
// if (error.data.type === 'NotFound')
|
||||
// console.log(error.data.data);
|
||||
if (error.type === 'TauriError')
|
||||
console.error(error.data);
|
||||
else if (error.type === 'IOError')
|
||||
console.error(error.data.data);
|
||||
else if (error.type === 'DaoError')
|
||||
console.error(error.data);
|
||||
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="text-center">
|
||||
<h1>test</h1>
|
||||
<Button onClick={onClick}>Click Me!</Button>
|
||||
</div>
|
||||
);
|
||||
function RouteComponent() {
|
||||
return <Navigate to="/app" />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
import useMyContext from '@/components/MyContext';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/test/app')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const myContext = useMyContext();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Hello "/test/app"!</div>
|
||||
<div>
|
||||
Value from MyContext:
|
||||
{' '}
|
||||
{myContext.text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
import { MyContextProvider } from '@/components/MyContext';
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/test')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<MyContextProvider value={{ text: 'Hello from cool!' }}>
|
||||
<div>Hello "/test"!</div>
|
||||
<Outlet />
|
||||
</MyContextProvider>
|
||||
);
|
||||
}
|
||||
18
apps/oneclient/frontend/src/stores/appFrameStore.ts
Normal file
18
apps/oneclient/frontend/src/stores/appFrameStore.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import type { ClusterModel } from '@/bindings.gen';
|
||||
import type { FileRoutesByFullPath } from '@/routeTree.gen';
|
||||
import { create } from 'zustand';
|
||||
|
||||
interface AppFrameStore {
|
||||
previousPage: FileRoutesByFullPath | null;
|
||||
activeCluster: ClusterModel | null;
|
||||
}
|
||||
|
||||
const useAppFrameStore = create<AppFrameStore>()(set => ({
|
||||
activeCluster: null,
|
||||
previousPage: null,
|
||||
|
||||
setPreviousPage: (page: FileRoutesByFullPath) => set({ previousPage: page }),
|
||||
setActiveCluster: (cluster: ClusterModel | null) => set({ activeCluster: cluster }),
|
||||
}));
|
||||
|
||||
export default useAppFrameStore;
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
@import "tailwindcss";
|
||||
|
||||
body {
|
||||
@apply m-0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
||||
|
|
@ -1,108 +1,20 @@
|
|||
@import "tailwindcss";
|
||||
@plugin "tailwindcss-react-aria-components";
|
||||
@plugin "tailwindcss-animated";
|
||||
@source "../../node_modules/@onelauncher/common";
|
||||
@import "../../node_modules/@onelauncher/common/dist/theme.css";
|
||||
|
||||
@theme {
|
||||
/* foreground colors */
|
||||
--color-fg-primary: #d5dbff;
|
||||
--color-fg-primary-hover: #dae0ff;
|
||||
--color-fg-primary-pressed: #e1e5ff;
|
||||
--color-fg-primary-disabled: #cdd1eb;
|
||||
@utility partial-underline-* {
|
||||
position: relative;
|
||||
|
||||
--color-fg-secondary: #78818d;
|
||||
--color-fg-secondary-hover: #5f6874;
|
||||
--color-fg-secondary-pressed: #828d9b;
|
||||
--color-fg-secondary-disabled: #646d79;
|
||||
|
||||
--color-link: #61afef;
|
||||
--color-link-hover: #5f87ff;
|
||||
--color-link-pressed: #72afff;
|
||||
--color-link-disabled: #7597b3;
|
||||
|
||||
/* background colors */
|
||||
--color-brand: #2b4bff;
|
||||
--color-brand-hover: #2843dd;
|
||||
--color-brand-pressed: #3957ff;
|
||||
--color-brand-disabled: #2543eb;
|
||||
|
||||
--color-component-bg: #1a2228;
|
||||
--color-component-bg-hover: #1d242b;
|
||||
--color-component-bg-pressed: #222c35;
|
||||
--color-component-bg-disabled: #10181f;
|
||||
|
||||
--color-page: #11171c;
|
||||
--color-page-elevated: #151c22;
|
||||
--color-window-frame: #151b20;
|
||||
|
||||
/* general colors */
|
||||
--color-danger: #ff4444;
|
||||
--color-danger-hover: #d63434;
|
||||
--color-danger-pressed: #ff5656;
|
||||
--color-danger-disabled: #eb3030;
|
||||
|
||||
--color-success: #239a60;
|
||||
--color-success-hover: #1a8752;
|
||||
--color-success-pressed: #2cac6e;
|
||||
--color-success-disabled: #0f864c;
|
||||
|
||||
--color-code-info: #61afef;
|
||||
--color-code-warn: #e5c07b;
|
||||
--color-code-error: #be5046;
|
||||
--color-code-debug: #2b4bff;
|
||||
--color-code-trace: #fdfdfd;
|
||||
|
||||
/* border */
|
||||
--color-component-border: rgba(255, 255, 255, 0.05);
|
||||
--color-component-border-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-component-border-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* overlay */
|
||||
--color-ghost-overlay: rgba(255, 255, 255, 0.05);
|
||||
--color-ghost-overlay-hover: rgba(255, 255, 255, 0.10);
|
||||
|
||||
--color-scrollbar-bg: rgba(255, 255, 255, 0.05);
|
||||
--color-scrollbar-bg-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-scrollbar-bg-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* other */
|
||||
--font-sans: "Poppins", sans-serif;
|
||||
--text-xs: 0.688rem;
|
||||
--text-sm: 0.75rem;
|
||||
--text-base: 0.875rem;
|
||||
--text-lg: 1rem;
|
||||
--text-2lg: 1.125rem;
|
||||
--text-xl: 1.25rem;
|
||||
--text-xxl: 1.5rem;
|
||||
--text-2xl: 2rem;
|
||||
--text-3xl: 2.5rem;
|
||||
--text-4xl: 3rem;
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none !important;
|
||||
-webkit-user-select: none !important;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-page text-fg-primary text-base;
|
||||
}
|
||||
|
||||
.os-scrollbar {
|
||||
--os-size: 10px;
|
||||
--os-track-border-radius: var(--border-radius-lg);
|
||||
--os-handle-bg: var(--color-scrollbar-bg);
|
||||
--os-handle-bg-hover: var(--color-scrollbar-bg-hover);
|
||||
--os-handle-bg-active: var(--color-scrollbar-bg-pressed);
|
||||
--os-handle-perpendicular-size-hover: 140%;
|
||||
--os-handle-perpendicular-size-active: 140%;
|
||||
--os-handle-interactive-area-offset: 4px;
|
||||
}
|
||||
|
||||
.os-scrollbar-offset-right {
|
||||
--os-padding-axis: 10;
|
||||
}
|
||||
|
||||
.os-hide-horizontal-scrollbar > .os-scrollbar-horizontal {
|
||||
display: none;
|
||||
&::after {
|
||||
content: "";
|
||||
background: none repeat scroll 0 0 currentColor;
|
||||
bottom: 1px;
|
||||
display: block;
|
||||
height: 3px;
|
||||
position: absolute;
|
||||
width: --spacing(--value(integer));
|
||||
width: --value(percentage, [percentage]);
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
apps/oneclient/frontend/src/vite-env.d.ts
vendored
Normal file
2
apps/oneclient/frontend/src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/// <reference types="vite-plugin-svgr/client" />
|
||||
/// <reference types="vite/client" />
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
import { resolve } from 'node:path';
|
||||
|
||||
import process from 'node:process';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
|
||||
import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
|
||||
import viteReact from '@vitejs/plugin-react';
|
||||
|
||||
import { defineConfig } from 'vite';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
svgr(),
|
||||
TanStackRouterVite({ autoCodeSplitting: true }),
|
||||
viteReact(),
|
||||
tailwindcss(),
|
||||
|
|
|
|||
2
apps/onelauncher/frontend/.gitignore
vendored
2
apps/onelauncher/frontend/.gitignore
vendored
|
|
@ -4,4 +4,4 @@ dist
|
|||
dist-ssr
|
||||
*.local
|
||||
|
||||
*.gen.ts
|
||||
**/*.gen.ts
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ function AccountPopup() {
|
|||
const defaultUser = useCommand('getDefaultUser', () => bindings.core.getDefaultUser(false));
|
||||
|
||||
const setDefaultUser = (user: MinecraftCredentials) => {
|
||||
bindings.core.setDefaultUser(user.id);
|
||||
bindings.commands.setDefaultUser(user.id);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function RouteComponent() {
|
|||
|
||||
const cluster = useCommand('getClusterById', () => bindings.core.getClusterById(Number(id.toString()) as unknown as bigint));
|
||||
|
||||
const isModded = cluster.data?.mc_loader != 'vanilla';
|
||||
const isModded = cluster.data?.mc_loader !== 'vanilla';
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-row overflow-hidden">
|
||||
|
|
@ -32,12 +32,12 @@ function RouteComponent() {
|
|||
links={{
|
||||
'Cluster Settings': [
|
||||
// if someone has a better way to do this, please let me know
|
||||
[<EyeIcon />, 'Overview', `/?id=${id}`],
|
||||
(isModded ? [<PackagePlusIcon />, 'Mods', `/mods?id=${id}`] : undefined),
|
||||
[<Image03Icon />, 'Screenshots', `/screenshots?id=${id}`],
|
||||
[<Globe04Icon />, 'Worlds', `/worlds?id=${id}`],
|
||||
[<File06Icon />, 'Logs', `/logs?id=${id}`],
|
||||
[<Settings04Icon />, 'Game Settings', `/settings?id=${id}`],
|
||||
[<EyeIcon key="overview" />, 'Overview', `/?id=${id}`],
|
||||
(isModded ? [<PackagePlusIcon key="mods" />, 'Mods', `/mods?id=${id}`] : undefined),
|
||||
[<Image03Icon key="screenshots" />, 'Screenshots', `/screenshots?id=${id}`],
|
||||
[<Globe04Icon key="worlds" />, 'Worlds', `/worlds?id=${id}`],
|
||||
[<File06Icon key="logs" />, 'Logs', `/logs?id=${id}`],
|
||||
[<Settings04Icon key="gamesettings" />, 'Game Settings', `/settings?id=${id}`],
|
||||
],
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import type { Model } from '@/bindings.gen';
|
|||
import DefaultBanner from '@/assets/images/default_banner.png';
|
||||
import DefaultInstancePhoto from '@/assets/images/default_instance_cover.jpg';
|
||||
import { NewClusterCreate } from '@/components/launcher/cluster/ClusterCreation';
|
||||
import { NewClusterCreate } from '@/components/launcher/cluster/ClusterCreation';
|
||||
import Modal from '@/components/overlay/Modal';
|
||||
import useRecentCluster from '@/hooks/useCluster';
|
||||
import { bindings } from '@/main';
|
||||
|
|
@ -10,6 +11,7 @@ import { useCommand } from '@onelauncher/common';
|
|||
import { Button, Show, TextField } from '@onelauncher/common/components';
|
||||
import { createFileRoute, Link } from '@tanstack/react-router';
|
||||
import { PlayIcon, Server01Icon } from '@untitled-theme/icons-react';
|
||||
import { PlayIcon, Server01Icon } from '@untitled-theme/icons-react';
|
||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||
|
||||
export const Route = createFileRoute('/app/')({
|
||||
|
|
@ -20,6 +22,8 @@ export const Route = createFileRoute('/app/')({
|
|||
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
|
||||
|
||||
hey future sassan here i guess the issue is solved idk
|
||||
|
||||
hey future sassan here i guess the issue is solved idk
|
||||
*/
|
||||
function RouteComponent() {
|
||||
|
|
@ -161,7 +165,46 @@ function ClusterCard({
|
|||
console.error(launch.error.message);
|
||||
};
|
||||
|
||||
const launch = useCommand('launchCluster', () => bindings.core.launchCluster(id, null), {
|
||||
enabled: false,
|
||||
subscribed: false,
|
||||
});
|
||||
|
||||
const handleLaunch = () => {
|
||||
launch.refetch();
|
||||
|
||||
if (launch.error)
|
||||
console.error(launch.error.message);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link
|
||||
search={{
|
||||
id,
|
||||
}} to="/app/cluster"
|
||||
>
|
||||
<div
|
||||
className="group relative h-[152px] flex flex-col rounded-xl border border-component-border/5 bg-component-bg active:bg-component-bg-pressed hover:bg-component-bg-hover"
|
||||
>
|
||||
<div className="relative flex-1 overflow-hidden rounded-t-xl">
|
||||
<div
|
||||
className="absolute h-full w-full transition-transform group-hover:!scale-110"
|
||||
>
|
||||
<img
|
||||
className="h-full w-full object-cover"
|
||||
src={DefaultInstancePhoto}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="z-10 flex flex-row items-center justify-between gap-x-3 p-3">
|
||||
<div className="h-full flex flex-col gap-1.5 overflow-hidden">
|
||||
<p className="h-4 text-ellipsis whitespace-nowrap font-medium">{name}</p>
|
||||
<p className="h-4 text-xs">
|
||||
{mc_loader}
|
||||
{' '}
|
||||
{mc_version}
|
||||
{/* {' '}
|
||||
<>
|
||||
<Link
|
||||
search={{
|
||||
|
|
@ -192,6 +235,8 @@ function ClusterCard({
|
|||
{props.packages.mods && `• ${props.mods} mods`} */}
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* <LaunchButton cluster={props} iconOnly /> */}
|
||||
<Button onClick={handleLaunch} size="icon"><PlayIcon /></Button>
|
||||
|
|
|
|||
|
|
@ -1,108 +1,4 @@
|
|||
@import "tailwindcss";
|
||||
@plugin "tailwindcss-react-aria-components";
|
||||
@plugin "tailwindcss-animated";
|
||||
@source "../../node_modules/@onelauncher/common";
|
||||
|
||||
@theme {
|
||||
/* foreground colors */
|
||||
--color-fg-primary: #d5dbff;
|
||||
--color-fg-primary-hover: #dae0ff;
|
||||
--color-fg-primary-pressed: #e1e5ff;
|
||||
--color-fg-primary-disabled: #cdd1eb;
|
||||
|
||||
--color-fg-secondary: #78818d;
|
||||
--color-fg-secondary-hover: #5f6874;
|
||||
--color-fg-secondary-pressed: #828d9b;
|
||||
--color-fg-secondary-disabled: #646d79;
|
||||
|
||||
--color-link: #61afef;
|
||||
--color-link-hover: #5f87ff;
|
||||
--color-link-pressed: #72afff;
|
||||
--color-link-disabled: #7597b3;
|
||||
|
||||
/* background colors */
|
||||
--color-brand: #2b4bff;
|
||||
--color-brand-hover: #2843dd;
|
||||
--color-brand-pressed: #3957ff;
|
||||
--color-brand-disabled: #2543eb;
|
||||
|
||||
--color-component-bg: #1a2228;
|
||||
--color-component-bg-hover: #1d242b;
|
||||
--color-component-bg-pressed: #222c35;
|
||||
--color-component-bg-disabled: #10181f;
|
||||
|
||||
--color-page: #11171c;
|
||||
--color-page-elevated: #151c22;
|
||||
--color-window-frame: #151b20;
|
||||
|
||||
/* general colors */
|
||||
--color-danger: #ff4444;
|
||||
--color-danger-hover: #d63434;
|
||||
--color-danger-pressed: #ff5656;
|
||||
--color-danger-disabled: #eb3030;
|
||||
|
||||
--color-success: #239a60;
|
||||
--color-success-hover: #1a8752;
|
||||
--color-success-pressed: #2cac6e;
|
||||
--color-success-disabled: #0f864c;
|
||||
|
||||
--color-code-info: #61afef;
|
||||
--color-code-warn: #e5c07b;
|
||||
--color-code-error: #be5046;
|
||||
--color-code-debug: #2b4bff;
|
||||
--color-code-trace: #fdfdfd;
|
||||
|
||||
/* border */
|
||||
--color-component-border: rgba(255, 255, 255, 0.05);
|
||||
--color-component-border-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-component-border-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* overlay */
|
||||
--color-ghost-overlay: rgba(255, 255, 255, 0.05);
|
||||
--color-ghost-overlay-hover: rgba(255, 255, 255, 0.10);
|
||||
|
||||
--color-scrollbar-bg: rgba(255, 255, 255, 0.05);
|
||||
--color-scrollbar-bg-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-scrollbar-bg-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* other */
|
||||
--font-sans: "Poppins", sans-serif;
|
||||
--text-xs: 0.688rem;
|
||||
--text-sm: 0.75rem;
|
||||
--text-base: 0.875rem;
|
||||
--text-lg: 1rem;
|
||||
--text-2lg: 1.125rem;
|
||||
--text-xl: 1.25rem;
|
||||
--text-xxl: 1.5rem;
|
||||
--text-2xl: 2rem;
|
||||
--text-3xl: 2.5rem;
|
||||
--text-4xl: 3rem;
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none !important;
|
||||
-webkit-user-select: none !important;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-page text-fg-primary text-base;
|
||||
}
|
||||
|
||||
.os-scrollbar {
|
||||
--os-size: 10px;
|
||||
--os-track-border-radius: var(--border-radius-lg);
|
||||
--os-handle-bg: var(--color-scrollbar-bg);
|
||||
--os-handle-bg-hover: var(--color-scrollbar-bg-hover);
|
||||
--os-handle-bg-active: var(--color-scrollbar-bg-pressed);
|
||||
--os-handle-perpendicular-size-hover: 140%;
|
||||
--os-handle-perpendicular-size-active: 140%;
|
||||
--os-handle-interactive-area-offset: 4px;
|
||||
}
|
||||
|
||||
.os-scrollbar-offset-right {
|
||||
--os-padding-axis: 10;
|
||||
}
|
||||
|
||||
.os-hide-horizontal-scrollbar > .os-scrollbar-horizontal {
|
||||
display: none;
|
||||
}
|
||||
@import "../../node_modules/@onelauncher/common/dist/theme.css";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "cluster_groups")]
|
||||
#[serde(rename = "ClusterGroupModel")]
|
||||
#[onelauncher_macro::specta]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "cluster_packages")]
|
||||
#[serde(rename = "ClusterPackageModel")]
|
||||
#[onelauncher_macro::specta]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use crate::{cluster_stage::ClusterStage, icon::Icon, loader::GameLoader};
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "clusters")]
|
||||
#[serde(rename = "ClusterModel")]
|
||||
#[onelauncher_macro::specta]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "java_versions")]
|
||||
#[serde(rename = "JavaModel")]
|
||||
#[serde(rename = "JavaVersionModel")]
|
||||
#[onelauncher_macro::specta]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use crate::{icon::Icon, loader::GameLoader, package::{PackageType, Provider}, ut
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "packages")]
|
||||
#[serde(rename = "PackageModel")]
|
||||
#[onelauncher_macro::specta]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
|
|
|
|||
|
|
@ -6,18 +6,20 @@
|
|||
"authors": "Polyfrost",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/index.d.ts",
|
||||
"import": "./lib/index.js"
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./components": {
|
||||
"types": "./lib/components.d.ts",
|
||||
"import": "./lib/components.js"
|
||||
"types": "./dist/components.d.ts",
|
||||
"import": "./dist/components.js"
|
||||
}
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"typings": "./lib/index.d.ts",
|
||||
"main": "./dist/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"style": "./dist/theme.css",
|
||||
"scripts": {
|
||||
"build": "rollup -c"
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tanstack/react-query": "^5.66.5",
|
||||
|
|
@ -32,14 +34,12 @@
|
|||
"tailwindcss-react-aria-components": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/vite": "^4.0.6",
|
||||
"@types/react": "^19.0.8",
|
||||
"esbuild": "^0.25.5",
|
||||
"rollup": "^4.41.1",
|
||||
"rollup-plugin-dts": "^6.2.1",
|
||||
"rollup-plugin-esbuild": "^6.2.1",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@untitled-theme/icons-react": "^0.14.0"
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.1.0",
|
||||
"vite-plugin-dts": "^4.5.4",
|
||||
"vite-plugin-static-copy": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
import process from 'node:process';
|
||||
import dts from 'rollup-plugin-dts';
|
||||
import esbuild from 'rollup-plugin-esbuild';
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @returns {boolean} true if the id is an external module
|
||||
*/
|
||||
const isExternal
|
||||
= process.platform === 'win32'
|
||||
? (/** @type {string} */ id) => !/^(?:[a-z]:\\|[.\\])/i.test(id)
|
||||
: (/** @type {string} */ id) => !/^[./]/.test(id);
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {import('rollup').RollupOptions} config
|
||||
* @returns {import('rollup').RollupOptions} bundle options
|
||||
*/
|
||||
function bundle(input, config) {
|
||||
return {
|
||||
...config,
|
||||
input,
|
||||
external: isExternal,
|
||||
};
|
||||
}
|
||||
|
||||
export default [
|
||||
// Output for NodeJS
|
||||
bundle('./src/index.ts', {
|
||||
plugins: [esbuild({ target: 'es2020' })],
|
||||
output: {
|
||||
file: `./lib/index.js`,
|
||||
format: 'esm',
|
||||
sourcemap: false,
|
||||
compact: false,
|
||||
},
|
||||
}),
|
||||
|
||||
// Output for Typescript's .d.ts
|
||||
bundle('./src/index.ts', {
|
||||
plugins: [dts()],
|
||||
output: {
|
||||
file: `./lib/index.d.ts`,
|
||||
format: 'esm',
|
||||
},
|
||||
}),
|
||||
|
||||
// Output for React components
|
||||
bundle('./src/components/index.ts', {
|
||||
plugins: [esbuild({ target: 'es2020' })],
|
||||
output: {
|
||||
file: `./lib/components.js`,
|
||||
format: 'esm',
|
||||
sourcemap: false,
|
||||
compact: false,
|
||||
},
|
||||
jsx: 'react-jsx',
|
||||
}),
|
||||
|
||||
// Output for React components .d.ts
|
||||
bundle('./src/components/index.ts', {
|
||||
plugins: [dts()],
|
||||
output: {
|
||||
file: `./lib/components.d.ts`,
|
||||
format: 'esm',
|
||||
},
|
||||
jsx: 'react-jsx',
|
||||
}),
|
||||
|
||||
// Output for browser
|
||||
// bundle({
|
||||
// plugins: [esbuild({ target: 'es2020', minify: true })],
|
||||
// output: {
|
||||
// file: `./dist/${name}-v${version}.js`,
|
||||
// format: 'esm',
|
||||
// name: camelCaseName,
|
||||
// sourcemap: true,
|
||||
// compact: true,
|
||||
// },
|
||||
// jsx: 'react-jsx',
|
||||
// }),
|
||||
];
|
||||
|
|
@ -24,7 +24,7 @@ export const buttonVariants = tv({
|
|||
'bg-danger hover:bg-danger-hover pressed:bg-danger-pressed disabled:bg-danger-disabled',
|
||||
],
|
||||
ghost: [
|
||||
'hover:bg-component-bg-hover pressed:bg-component-bg-pressed checked:selected:bg-component-bg-hover',
|
||||
'hover:bg-ghost-overlay-hover pressed:bg-ghost-overlay-pressed checked:selected:bg-ghost-overlay-pressed',
|
||||
],
|
||||
},
|
||||
size: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type {
|
||||
ListBoxItemProps as AriaListBoxItemProps,
|
||||
SelectProps as AriaSelectProps,
|
||||
|
||||
} from 'react-aria-components';
|
||||
import type { VariantProps } from 'tailwind-variants';
|
||||
import type { ClassNameString } from '../types/global';
|
||||
|
|
|
|||
110
packages/web_common/src/theme.css
Normal file
110
packages/web_common/src/theme.css
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
@source "./**/*.{js,jsx,ts,tsx}";
|
||||
@plugin "tailwindcss-react-aria-components";
|
||||
@plugin "tailwindcss-animated";
|
||||
|
||||
@theme {
|
||||
/* foreground colors */
|
||||
--color-fg-primary: #d5dbff;
|
||||
--color-fg-primary-hover: #dae0ff;
|
||||
--color-fg-primary-pressed: #e1e5ff;
|
||||
--color-fg-primary-disabled: #cdd1eb;
|
||||
|
||||
--color-fg-secondary: #78818d;
|
||||
--color-fg-secondary-hover: #5f6874;
|
||||
--color-fg-secondary-pressed: #828d9b;
|
||||
--color-fg-secondary-disabled: #646d79;
|
||||
|
||||
--color-link: #61afef;
|
||||
--color-link-hover: #5f87ff;
|
||||
--color-link-pressed: #72afff;
|
||||
--color-link-disabled: #7597b3;
|
||||
|
||||
/* background colors */
|
||||
--color-brand: #2b4bff;
|
||||
--color-brand-hover: #2843dd;
|
||||
--color-brand-pressed: #3957ff;
|
||||
--color-brand-disabled: #2543eb;
|
||||
|
||||
--color-component-bg: #1a2228;
|
||||
--color-component-bg-hover: #1d242b;
|
||||
--color-component-bg-pressed: #222c35;
|
||||
--color-component-bg-disabled: #10181f;
|
||||
|
||||
--color-page: #11171c;
|
||||
--color-page-elevated: #151c22;
|
||||
--color-page-overlay: #ffffff1a;
|
||||
--color-window-frame: #151b20;
|
||||
|
||||
/* general colors */
|
||||
--color-danger: #ff4444;
|
||||
--color-danger-hover: #d63434;
|
||||
--color-danger-pressed: #ff5656;
|
||||
--color-danger-disabled: #eb3030;
|
||||
|
||||
--color-success: #239a60;
|
||||
--color-success-hover: #1a8752;
|
||||
--color-success-pressed: #2cac6e;
|
||||
--color-success-disabled: #0f864c;
|
||||
|
||||
--color-code-info: #61afef;
|
||||
--color-code-warn: #e5c07b;
|
||||
--color-code-error: #be5046;
|
||||
--color-code-debug: #2b4bff;
|
||||
--color-code-trace: #fdfdfd;
|
||||
|
||||
/* border */
|
||||
--color-component-border: rgba(255, 255, 255, 0.05);
|
||||
--color-component-border-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-component-border-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* overlay */
|
||||
--color-ghost-overlay: rgba(255, 255, 255, 0.05);
|
||||
--color-ghost-overlay-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-ghost-overlay-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
--color-scrollbar-bg: rgba(255, 255, 255, 0.05);
|
||||
--color-scrollbar-bg-hover: rgba(255, 255, 255, 0.10);
|
||||
--color-scrollbar-bg-pressed: rgba(255, 255, 255, 0.15);
|
||||
|
||||
/* other */
|
||||
--font-sans: "Poppins", sans-serif;
|
||||
--text-xs: 0.688rem;
|
||||
--text-sm: 0.75rem;
|
||||
--text-base: 0.875rem;
|
||||
--text-lg: 1rem;
|
||||
--text-2lg: 1.125rem;
|
||||
--text-xl: 1.25rem;
|
||||
--text-xxl: 1.5rem;
|
||||
--text-2xl: 2rem;
|
||||
--text-3xl: 2.5rem;
|
||||
--text-4xl: 3rem;
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none !important;
|
||||
-webkit-user-select: none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-page text-fg-primary text-base;
|
||||
}
|
||||
|
||||
.os-scrollbar {
|
||||
--os-size: 10px;
|
||||
--os-track-border-radius: var(--border-radius-lg);
|
||||
--os-handle-bg: var(--color-scrollbar-bg);
|
||||
--os-handle-bg-hover: var(--color-scrollbar-bg-hover);
|
||||
--os-handle-bg-active: var(--color-scrollbar-bg-pressed);
|
||||
--os-handle-perpendicular-size-hover: 140%;
|
||||
--os-handle-perpendicular-size-active: 140%;
|
||||
--os-handle-interactive-area-offset: 4px;
|
||||
}
|
||||
|
||||
.os-scrollbar-offset-right {
|
||||
--os-padding-axis: 10;
|
||||
}
|
||||
|
||||
.os-hide-horizontal-scrollbar > .os-scrollbar-horizontal {
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -11,5 +11,5 @@
|
|||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": ["src/**/*", "rollup.config.mjs"]
|
||||
"include": ["src/**/*", "vite.config.ts"]
|
||||
}
|
||||
|
|
|
|||
60
packages/web_common/vite.config.ts
Normal file
60
packages/web_common/vite.config.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import path from 'node:path';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vite';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tailwindcss(),
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: path.resolve(__dirname, 'src/theme.css'),
|
||||
dest: './',
|
||||
},
|
||||
],
|
||||
}),
|
||||
dts({
|
||||
insertTypesEntry: true,
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
minify: false,
|
||||
lib: {
|
||||
entry: {
|
||||
'index': path.resolve(__dirname, 'src/index.ts'),
|
||||
'components': path.resolve(__dirname, 'src/components/index.ts'),
|
||||
},
|
||||
formats: ['es'],
|
||||
fileName: (_, entryName) => `${entryName}.js`,
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [
|
||||
'react',
|
||||
'react/jsx-runtime',
|
||||
'react-dom',
|
||||
'react-aria-components',
|
||||
'motion',
|
||||
'motion/react',
|
||||
'@tanstack/react-query',
|
||||
'@tanstack/react-router',
|
||||
'tailwindcss',
|
||||
'tailwind-merge',
|
||||
'tailwind-variants',
|
||||
// 'tailwindcss-animated',
|
||||
// 'tailwindcss-react-aria-components',
|
||||
],
|
||||
output: {
|
||||
globals: {
|
||||
'react': 'React',
|
||||
'react/jsx-runtime': 'react/jsx-runtime',
|
||||
'react-dom': 'ReactDOM',
|
||||
'tailwindcss': 'tailwindcss',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
1175
pnpm-lock.yaml
generated
1175
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue