diff --git a/package.json b/package.json index c65d0e3c..a60b6c47 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,14 @@ "@tauri-apps/plugin-shell": "2.0.0-beta.2", "@untitled-theme/icons-solid": "^0.6.0", "solid-js": "^1.7.8", - "solid-transition-group": "^0.2.3" + "solid-transition-group": "^0.2.3", + "uuid": "^9.0.1" }, "devDependencies": { "@solid/eslint-config-base": "^0.6.0", "@stylistic/eslint-plugin-ts": "^1.7.0", "@tauri-apps/cli": "2.0.0-beta.9", + "@types/uuid": "^9.0.8", "@typescript-eslint/parser": "^7.2.0", "autoprefixer": "^10.4.18", "eslint": "^8.57.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4685b688..2dee707c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: solid-transition-group: specifier: ^0.2.3 version: 0.2.3(solid-js@1.8.15) + uuid: + specifier: ^9.0.1 + version: 9.0.1 devDependencies: '@solid/eslint-config-base': @@ -34,6 +37,9 @@ devDependencies: '@tauri-apps/cli': specifier: 2.0.0-beta.9 version: 2.0.0-beta.9 + '@types/uuid': + specifier: ^9.0.8 + version: 9.0.8 '@typescript-eslint/parser': specifier: ^7.2.0 version: 7.2.0(eslint@8.57.0)(typescript@5.4.2) @@ -1009,6 +1015,10 @@ packages: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + dev: true + /@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -3591,6 +3601,11 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: false + /validate-html-nesting@1.2.2: resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} dev: true diff --git a/src/assets/images/default_instance_cover.jpg b/src/assets/images/default_instance_cover.jpg new file mode 100644 index 00000000..6de5d7af Binary files /dev/null and b/src/assets/images/default_instance_cover.jpg differ diff --git a/src/globals.css b/src/globals.css index b2a63d25..49b43c4f 100644 --- a/src/globals.css +++ b/src/globals.css @@ -15,16 +15,4 @@ img { -webkit-user-drag: none; } h1 { @apply text-2xl font-semibold; } h2 { @apply text-xxl font-semibold; } h3 { @apply text-xl font-medium; } - -.slide-fade-enter-active, -.slide-fade-exit-active { - transition: opacity 0.3s, transform 0.3s; -} -.slide-fade-enter, -.slide-fade-exit-to { - transform: translateX(10px); - opacity: 0; -} -.slide-fade-enter { - transform: translateX(-10px); -} +h4 { @apply text-lg font-medium; } diff --git a/src/types/game.d.ts b/src/types/game.d.ts new file mode 100644 index 00000000..b5c7fc9c --- /dev/null +++ b/src/types/game.d.ts @@ -0,0 +1,3 @@ +declare namespace game { + export type Client = 'fabric' | 'forge' | 'quilt' | 'vanilla' | 'other'; +} diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 9d4410de..8af075b1 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -12,14 +12,18 @@ function App(props: ParentProps) { } return ( -
+
-
+
- { /* eslint-disable-next-line @typescript-eslint/no-use-before-define */ } - - {props.children} - + + {/* // TODO fix overflow */} +
+ { /* eslint-disable-next-line @typescript-eslint/no-use-before-define */ } + + {props.children} + +
); diff --git a/src/ui/components/Navbar.tsx b/src/ui/components/Navbar.tsx index b8970c72..9f886027 100644 --- a/src/ui/components/Navbar.tsx +++ b/src/ui/components/Navbar.tsx @@ -1,5 +1,5 @@ import { A } from '@solidjs/router'; -import { ParentProps, createSignal } from 'solid-js'; +import { createSignal } from 'solid-js'; import PolyfrostFull from './logos/PolyfrostFull'; import AccountPopup from './overlay/AccountPopup'; diff --git a/src/ui/components/base/TextField.module.scss b/src/ui/components/base/TextField.module.scss index f90ad672..9dfa5f48 100644 --- a/src/ui/components/base/TextField.module.scss +++ b/src/ui/components/base/TextField.module.scss @@ -1,7 +1,7 @@ .textfield { @apply bg-component-bg [&:not(:focus-within)]:hover:bg-component-bg-hover focus-within:bg-component-bg-pressed disabled:bg-component-bg-disabled; @apply border border-gray-.5 text-fg-primary fill-fg-primary; - @apply rounded-lg px-2.5 py-1; + @apply rounded-lg px-2.5 py-1.5; @apply flex flex-row gap-x-1.5; diff --git a/src/ui/components/base/TextField.tsx b/src/ui/components/base/TextField.tsx index 0d7d89ac..254eb7ae 100644 --- a/src/ui/components/base/TextField.tsx +++ b/src/ui/components/base/TextField.tsx @@ -1,4 +1,4 @@ -import { JSX, splitProps } from 'solid-js'; +import { JSX, createUniqueId, splitProps } from 'solid-js'; import styles from './TextField.module.scss'; type TextFieldProps = { @@ -8,13 +8,14 @@ type TextFieldProps = { function TextField(props: TextFieldProps) { const [fieldProps, rest] = splitProps(props, ['iconLeft', 'iconRight']); + const id = createUniqueId(); return ( -
+
+ ); } diff --git a/src/ui/pages/Home.tsx b/src/ui/pages/Home.tsx index 07dd1859..32872784 100644 --- a/src/ui/pages/Home.tsx +++ b/src/ui/pages/Home.tsx @@ -1,10 +1,13 @@ import { - CheckIcon, DotsVerticalIcon, Download01Icon, PlayIcon, PlusIcon, SearchMdIcon, + CheckIcon, DotsVerticalIcon, Download01Icon, HeartRoundedIcon, PlayIcon, PlusIcon, SearchMdIcon, } from '@untitled-theme/icons-solid'; +import { createEffect, createSignal, For } from 'solid-js'; import image from '../../assets/images/header.png'; import Button from '../components/base/Button'; import Tag from '../components/base/Tag'; import TextField from '../components/base/TextField'; +import defaultCover from '../../assets/images/default_instance_cover.jpg'; +import { upperFirst } from '../../utils/string'; // TODO: Replace this into it's own component function OneConfigLogo() { @@ -49,10 +52,118 @@ function Banner() { ); } -function HomePage() { +type InstanceCardProps = { + name: string, + version: string, + client: game.Client, + mods?: number, + cover?: string, + lastPlayed?: number, +}; + +function InstanceCard(props: InstanceCardProps) { return ( -
+
+
+
+ +
+
+
+
+

{props.name}

+

+ {upperFirst(props.client)} {props.version} {props.mods && `• ${props.mods} mods`} +

+
+ +
+
+ ); +} + +type InstanceGroupProps = { + title: string, + instances: InstanceCardProps[], +}; + +function InstanceGroup(props: InstanceGroupProps) { + const [sorted, setSorted] = createSignal([]); + + createEffect(() => { + setSorted(props.instances.sort((a, b) => { + if (a.lastPlayed && b.lastPlayed) { + return b.lastPlayed - a.lastPlayed; + } + + return 0; + })); + }); + + return ( +
+

{props.title}

+
+ {(instance) => ( + + )} +
+
+ ); +} + +function HomePage() { + const myInstances: InstanceCardProps[] = [ + { + name: 'Hypixel', + client: 'vanilla', + version: '1.8.9', + }, + { + name: 'OneConfig ??', + client: 'forge', + version: '1.8.9', + mods: 12, + }, + { + name: 'Fabulously Optimised', + client: 'fabric', + version: '1.20.4', + mods: 48, + }, + { + name: 'sus client', + client: 'other', + version: '1.8.9', + }, + { + name: 'OneConfig ??', + client: 'forge', + version: '1.8.9', + mods: 12, + }, + { + name: 'Fabulously Optimised', + client: 'fabric', + version: '1.20.4', + mods: 48, + }, + { + name: 'sus client', + client: 'other', + version: '1.8.9', + }, + ]; + + return ( +
+
} placeholder="Search for something..." /> @@ -62,6 +173,9 @@ function HomePage() {
+ + +
); } diff --git a/src/utils/environment.ts b/src/utils/environment.ts index 91f49ff8..1267b2bc 100644 --- a/src/utils/environment.ts +++ b/src/utils/environment.ts @@ -1,4 +1,4 @@ -function isDev() { +export function isDev() { return window.location.host.startsWith('localhost:'); } diff --git a/src/utils/string.ts b/src/utils/string.ts new file mode 100644 index 00000000..019eaf7f --- /dev/null +++ b/src/utils/string.ts @@ -0,0 +1,7 @@ +export function upperFirst(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +export default { + upperFirst, +};