From a17bcbb471ff0a232fe0c578df565b8a429a8c6c Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Sun, 16 Jun 2024 12:47:51 +0200 Subject: [PATCH] feat: Dropdown + Text Field modifications. Started work on Browser --- desktop/src/index.tsx | 12 +-- desktop/src/ui/App.tsx | 3 +- .../SettingsRow.tsx} | 0 .../ui/components/base/Dropdown.module.scss | 19 +++++ desktop/src/ui/components/base/Dropdown.tsx | 80 +++++++++++++++++++ .../ui/components/base/TextField.module.scss | 7 +- desktop/src/ui/pages/browser/BrowserMain.tsx | 65 +++++++++++++++ desktop/src/ui/pages/browser/BrowserRoot.tsx | 19 +++++ desktop/src/ui/pages/cluster/ClusterRoot.tsx | 66 +++++++-------- .../settings/launcher/SettingsAppearance.tsx | 2 +- .../settings/launcher/SettingsGeneral.tsx | 2 +- desktop/src/utils/sorting.ts | 26 ++++++ 12 files changed, 251 insertions(+), 50 deletions(-) rename desktop/src/ui/{pages/settings/components.tsx => components/SettingsRow.tsx} (100%) create mode 100644 desktop/src/ui/components/base/Dropdown.module.scss create mode 100644 desktop/src/ui/components/base/Dropdown.tsx create mode 100644 desktop/src/ui/pages/browser/BrowserMain.tsx create mode 100644 desktop/src/ui/pages/browser/BrowserRoot.tsx create mode 100644 desktop/src/utils/sorting.ts diff --git a/desktop/src/index.tsx b/desktop/src/index.tsx index a8f7c13b..765ccd83 100644 --- a/desktop/src/index.tsx +++ b/desktop/src/index.tsx @@ -6,23 +6,19 @@ import './imports'; import { Route, Router } from '@solidjs/router'; import App from './ui/App'; import HomePage from './ui/pages/Home'; -import BrowserPage from './ui/pages/Browser'; import UpdatesPage from './ui/pages/Updates'; import ClusterRoot from '~ui/pages/cluster/ClusterRoot'; import SettingsRoot from '~ui/pages/settings/SettingsRoot'; +import BrowserRoot from '~ui/pages/browser/BrowserRoot'; export * as bridge from './bindings'; render(() => ( - - - - - - - + } /> + } /> + } /> ), document.getElementById('root') as HTMLElement); diff --git a/desktop/src/ui/App.tsx b/desktop/src/ui/App.tsx index 17e03bbf..cbf0b623 100644 --- a/desktop/src/ui/App.tsx +++ b/desktop/src/ui/App.tsx @@ -8,10 +8,11 @@ import NotificationOverlay from './components/overlay/notifications/Notification import { bridge } from '~index'; function App(props: ParentProps) { - if (!bridge.commands.isDev()) + if (!bridge.commands.isDev()) { document.addEventListener('contextmenu', (event) => { event.preventDefault(); }); + } return (
diff --git a/desktop/src/ui/pages/settings/components.tsx b/desktop/src/ui/components/SettingsRow.tsx similarity index 100% rename from desktop/src/ui/pages/settings/components.tsx rename to desktop/src/ui/components/SettingsRow.tsx diff --git a/desktop/src/ui/components/base/Dropdown.module.scss b/desktop/src/ui/components/base/Dropdown.module.scss new file mode 100644 index 00000000..20ffb27d --- /dev/null +++ b/desktop/src/ui/components/base/Dropdown.module.scss @@ -0,0 +1,19 @@ +.dropdown { + @apply relative; + + .row { + @apply flex flex-row justify-start items-center gap-1.5 h-4; + + > svg { + @apply w-4 h-4; + } + } + + .selected { + @apply w-1 h-1 bg-white rounded-full opacity-0; + &.visible { + @apply opacity-100; + } + } + +} \ No newline at end of file diff --git a/desktop/src/ui/components/base/Dropdown.tsx b/desktop/src/ui/components/base/Dropdown.tsx new file mode 100644 index 00000000..a4800944 --- /dev/null +++ b/desktop/src/ui/components/base/Dropdown.tsx @@ -0,0 +1,80 @@ +import { Index, type JSX, type ParentProps, children, createSignal } from 'solid-js'; +import { ChevronDownIcon } from '@untitled-theme/icons-solid'; +import Popup from '../overlay/Popup'; +import Button from './Button'; +import styles from './Dropdown.module.scss'; + +export type DropdownProps = ParentProps; + +function Dropdown(props: DropdownProps) { + const [visible, setVisible] = createSignal(false); + const [selected, setSelected] = createSignal(0); + let ref!: HTMLDivElement; + + const items = () => children(() => props.children).toArray(); + + function select(index: number) { + setSelected(index); + setVisible(false); + } + + return ( +
+ + + ref.classList.add('mt-1', 'left-0', 'right-0')} + > +
+
+ + {(item, index) => ( +
select(index)}> +
+ {item()} +
+
+
+ )} + +
+
+ +
+ ); +} + +interface DropdownRowProps { + iconLeft?: JSX.Element; +}; + +Dropdown.Row = function (props: ParentProps) { + return ( +
+ {props.children} +
+ ); +}; + +export default Dropdown; diff --git a/desktop/src/ui/components/base/TextField.module.scss b/desktop/src/ui/components/base/TextField.module.scss index a8d1de10..dab71de7 100644 --- a/desktop/src/ui/components/base/TextField.module.scss +++ b/desktop/src/ui/components/base/TextField.module.scss @@ -1,9 +1,8 @@ .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-05 text-fg-primary fill-fg-primary; - @apply rounded-lg px-2.5 py-1.5; - @apply flex flex-row gap-x-1.5; - + @apply rounded-lg px-2 py-1 max-h-8; + @apply flex flex-row items-center justify-start gap-x-1.5; & input { &::selection { @@ -15,7 +14,7 @@ & span { & * { - @apply w-4; + @apply w-4 h-4; } } } diff --git a/desktop/src/ui/pages/browser/BrowserMain.tsx b/desktop/src/ui/pages/browser/BrowserMain.tsx new file mode 100644 index 00000000..45bc6caa --- /dev/null +++ b/desktop/src/ui/pages/browser/BrowserMain.tsx @@ -0,0 +1,65 @@ +import { HeartIcon, SearchMdIcon } from '@untitled-theme/icons-solid'; +import { createSignal } from 'solid-js'; +import Dropdown from '~ui/components/base/Dropdown'; +import TextField from '~ui/components/base/TextField'; +import createSortable from '~utils/sorting'; + +interface CardProps { + id: string; + name: string; + date_added: number; + date_updated: number; + provider: Provider; +}; + +enum Provider { + Curseforge, + Modrinth, + Polyfrost, + Skyclient, +} + +interface BrowserFilters { + provider: Provider[]; // TODO: Change with Provider types from Rust +} + +function BrowserMain() { + const [filters, setFilters] = createSignal({ + provider: [Provider.Curseforge], + }); + + const [list, key, setList, setKey] = createSortable([], { + 'A-Z': (a, b) => a.name.localeCompare(b.name), + 'Z-A': (a, b) => b.name.localeCompare(a.name), + 'Last Updated': (a, b) => a.date_updated - b.date_updated, + 'New': (a, b) => b.date_added - a.date_added, + // 'Provider': (a, b) => a.provider + }); + + return ( +
+
+ } /> + + + +

Test

+
+ + +

Test 2

+
+ +

Test 333333333

+
+ + +

Lorem Ipsum dolor

+
+
+
+
+ ); +} + +export default BrowserMain; diff --git a/desktop/src/ui/pages/browser/BrowserRoot.tsx b/desktop/src/ui/pages/browser/BrowserRoot.tsx new file mode 100644 index 00000000..c8cdde62 --- /dev/null +++ b/desktop/src/ui/pages/browser/BrowserRoot.tsx @@ -0,0 +1,19 @@ +import { Route } from '@solidjs/router'; +import type { ParentProps } from 'solid-js'; +import BrowserMain from './BrowserMain'; + +function BrowserRoutes() { + return ( + <> + + + ); +} + +function BrowserRoot(props: ParentProps) { + return <>{props.children}; +} + +BrowserRoot.Routes = BrowserRoutes; + +export default BrowserRoot; diff --git a/desktop/src/ui/pages/cluster/ClusterRoot.tsx b/desktop/src/ui/pages/cluster/ClusterRoot.tsx index 39ba267c..69ed4a12 100644 --- a/desktop/src/ui/pages/cluster/ClusterRoot.tsx +++ b/desktop/src/ui/pages/cluster/ClusterRoot.tsx @@ -1,5 +1,5 @@ import { Route, useSearchParams } from '@solidjs/router'; -import type { ParentProps } from 'solid-js'; +import { type ParentProps, Show } from 'solid-js'; import { EyeIcon, File06Icon, Globe04Icon, Image03Icon, PackagePlusIcon, Settings04Icon, Tool02Icon } from '@untitled-theme/icons-solid'; import Sidebar from '../../components/Sidebar'; import AnimatedRoutes from '../../components/AnimatedRoutes'; @@ -25,43 +25,39 @@ function ClusterRoot(props: ParentProps) { const [searchParams] = useSearchParams(); const cluster = useCluster(searchParams.id); - if (!cluster) { - location.href = '/'; - return; - } - return ( -
-
- , 'Overview', '/'], - // [, 'Accounts', '/users'], - // TODO: Better way of checking mods - (cluster()?.meta.loader !== 'vanilla' ? [, 'Mods', '/mods'] : undefined), - [, 'Screenshots', '/screenshots'], - [, 'Worlds', '/worlds'], - [, 'Logs', '/logs'], - ], - Settings: [ - [, 'Java', '/java'], - [, 'Miscellaneous', '/misc'], - ], - }} - /> -
+ +
+
+ , 'Overview', '/'], + // TODO: Better way of checking mods + (cluster!()!.meta.loader === 'vanilla' ? [, 'Mods', '/mods'] : undefined), + [, 'Screenshots', '/screenshots'], + [, 'Worlds', '/worlds'], + [, 'Logs', '/logs'], + ], + Settings: [ + [, 'Java', '/java'], + [, 'Miscellaneous', '/misc'], + ], + }} + /> +
-
- - - {props.children} - - +
+ + + {props.children} + + +
-
+
); } diff --git a/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx b/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx index 800ae98f..2c7270b5 100644 --- a/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx +++ b/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx @@ -1,5 +1,5 @@ import { ColorsIcon, PaintPourIcon, Speedometer04Icon } from '@untitled-theme/icons-solid'; -import SettingsRow from '../components'; +import SettingsRow from '../../../components/SettingsRow'; import ScrollableContainer from '~ui/components/ScrollableContainer'; import Button from '~ui/components/base/Button'; import Toggle from '~ui/components/base/Toggle'; diff --git a/desktop/src/ui/pages/settings/launcher/SettingsGeneral.tsx b/desktop/src/ui/pages/settings/launcher/SettingsGeneral.tsx index 16539bcb..e784389c 100644 --- a/desktop/src/ui/pages/settings/launcher/SettingsGeneral.tsx +++ b/desktop/src/ui/pages/settings/launcher/SettingsGeneral.tsx @@ -1,5 +1,5 @@ import { XIcon } from '@untitled-theme/icons-solid'; -import SettingsRow from '../components'; +import SettingsRow from '../../../components/SettingsRow'; import ScrollableContainer from '~ui/components/ScrollableContainer'; import Toggle from '~ui/components/base/Toggle'; import appSettings from '~ui/state/appSettings'; diff --git a/desktop/src/utils/sorting.ts b/desktop/src/utils/sorting.ts new file mode 100644 index 00000000..04a268d1 --- /dev/null +++ b/desktop/src/utils/sorting.ts @@ -0,0 +1,26 @@ +import { type Accessor, type Setter, createSignal } from 'solid-js'; + +export type SortingFunction = (a: T, b: T) => number; +export interface Sortables { [key: string]: SortingFunction } + +type CreateSortable = Sortables> = [ + list: Accessor, + key: Accessor, + setList: Setter, + setKey: Setter, +]; + +export function createSortable = Sortables>(initList: T[], initSortables: S): CreateSortable { + const sortables = initSortables; + const [list, setList] = createSignal(initList); + const [key, setKey] = createSignal(Object.keys(sortables)[0]!); + + return [ + list, + key, + setList, + setKey, + ]; +} + +export default createSortable;