From 46a5606ade72f7092a64db90cf5c23d48adaa7ff Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Fri, 17 May 2024 21:20:15 +0200 Subject: [PATCH] feat: Launcher reduced motion --- desktop/src/globals.css | 5 ++++ desktop/src/ui/components/base/Toggle.tsx | 30 +++++++++++++++++++ .../src/ui/components/overlay/ContextMenu.tsx | 2 +- desktop/src/ui/pages/cluster/ClusterRoot.tsx | 8 ++--- .../cluster/{ => cluster}/ClusterLogs.tsx | 2 +- .../cluster/{ => cluster}/ClusterMods.tsx | 4 +-- .../cluster/{ => cluster}/ClusterOverview.tsx | 10 +++---- .../{ => cluster}/ClusterScreenshots.tsx | 0 desktop/src/ui/pages/settings/components.tsx | 6 ++-- .../settings/launcher/SettingsAppearance.tsx | 22 ++++++++++++-- desktop/src/ui/state/reducedMotionTracker.ts | 20 +++++++++++++ 11 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 desktop/src/ui/components/base/Toggle.tsx rename desktop/src/ui/pages/cluster/{ => cluster}/ClusterLogs.tsx (96%) rename desktop/src/ui/pages/cluster/{ => cluster}/ClusterMods.tsx (96%) rename desktop/src/ui/pages/cluster/{ => cluster}/ClusterOverview.tsx (85%) rename desktop/src/ui/pages/cluster/{ => cluster}/ClusterScreenshots.tsx (100%) create mode 100644 desktop/src/ui/state/reducedMotionTracker.ts diff --git a/desktop/src/globals.css b/desktop/src/globals.css index 77657ac3..9589b4ea 100644 --- a/desktop/src/globals.css +++ b/desktop/src/globals.css @@ -57,3 +57,8 @@ h4 { @apply text-lg font-medium; } opacity: 1; transform: translateX(0); } + +body.reduce-motion * { + transition-duration: 0.0001ms !important; + animation-duration: 0.0001ms !important; +} diff --git a/desktop/src/ui/components/base/Toggle.tsx b/desktop/src/ui/components/base/Toggle.tsx new file mode 100644 index 00000000..c4cbe762 --- /dev/null +++ b/desktop/src/ui/components/base/Toggle.tsx @@ -0,0 +1,30 @@ +import { type JSX, createSignal, splitProps } from 'solid-js'; + +type ToggleProps = JSX.HTMLAttributes & { + defaultChecked?: boolean; + onChecked?: (checked: boolean) => void; + showText?: 'left' | 'right'; +}; + +function Toggle(props: ToggleProps) { + const [checked, setChecked] = createSignal(props.defaultChecked || false); + const [split, rest] = splitProps(props, ['class', 'defaultChecked', 'onChecked', 'text']); + + function toggle() { + const newValue = !checked(); + setChecked(newValue); + props.onChecked?.(newValue); + } + + return ( +
toggle()} + class={`w-[40px] h-[22px] p-3 flex flex-row relative rounded-full transition-colors overflow-hidden ${checked() ? 'bg-brand' : 'bg-gray-10'}${` ${split.class}` ?? ''}`} + {...rest} + > +
+
+ ); +} + +export default Toggle; diff --git a/desktop/src/ui/components/overlay/ContextMenu.tsx b/desktop/src/ui/components/overlay/ContextMenu.tsx index 610ce235..b67ca27b 100644 --- a/desktop/src/ui/components/overlay/ContextMenu.tsx +++ b/desktop/src/ui/components/overlay/ContextMenu.tsx @@ -36,7 +36,7 @@ function ContextMenu(props: ContextMenuProps) { visible={props.visible} setVisible={props.setVisible} > -
+
{props.children}
diff --git a/desktop/src/ui/pages/cluster/ClusterRoot.tsx b/desktop/src/ui/pages/cluster/ClusterRoot.tsx index f10619bf..fb10608e 100644 --- a/desktop/src/ui/pages/cluster/ClusterRoot.tsx +++ b/desktop/src/ui/pages/cluster/ClusterRoot.tsx @@ -4,10 +4,10 @@ import { EyeIcon, File06Icon, Globe04Icon, Image03Icon, PackagePlusIcon, Setting import Sidebar from '../../components/Sidebar'; import AnimatedRoutes from '../../components/AnimatedRoutes'; import ErrorBoundary from '../../components/ErrorBoundary'; -import ClusterOverview from './ClusterOverview'; -import ClusterLogs from './ClusterLogs'; -import ClusterMods from './ClusterMods'; -import ClusterScreenshots from './ClusterScreenshots'; +import ClusterOverview from './cluster/ClusterOverview'; +import ClusterLogs from './cluster/ClusterLogs'; +import ClusterMods from './cluster/ClusterMods'; +import ClusterScreenshots from './cluster/ClusterScreenshots'; function ClusterRoutes() { return ( diff --git a/desktop/src/ui/pages/cluster/ClusterLogs.tsx b/desktop/src/ui/pages/cluster/cluster/ClusterLogs.tsx similarity index 96% rename from desktop/src/ui/pages/cluster/ClusterLogs.tsx rename to desktop/src/ui/pages/cluster/cluster/ClusterLogs.tsx index eb4692f4..63004c7b 100644 --- a/desktop/src/ui/pages/cluster/ClusterLogs.tsx +++ b/desktop/src/ui/pages/cluster/cluster/ClusterLogs.tsx @@ -1,7 +1,7 @@ import { useSearchParams } from '@solidjs/router'; import { For, Show, createEffect, createResource, createSignal } from 'solid-js'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-solid'; -import { getClusterLog, getClusterLogs } from '../../../bridge/game'; +import { getClusterLog, getClusterLogs } from '../../../../bridge/game'; function ClusterLogs() { const [params] = useSearchParams(); diff --git a/desktop/src/ui/pages/cluster/ClusterMods.tsx b/desktop/src/ui/pages/cluster/cluster/ClusterMods.tsx similarity index 96% rename from desktop/src/ui/pages/cluster/ClusterMods.tsx rename to desktop/src/ui/pages/cluster/cluster/ClusterMods.tsx index 5e65e5bb..e6188856 100644 --- a/desktop/src/ui/pages/cluster/ClusterMods.tsx +++ b/desktop/src/ui/pages/cluster/cluster/ClusterMods.tsx @@ -50,8 +50,8 @@ function ModEntry(props: ModEntryProps) {
-

{props.name}

- +

{props.name}

+ {props.version} {/* TODO: Add version checker */} {/* */} diff --git a/desktop/src/ui/pages/cluster/ClusterOverview.tsx b/desktop/src/ui/pages/cluster/cluster/ClusterOverview.tsx similarity index 85% rename from desktop/src/ui/pages/cluster/ClusterOverview.tsx rename to desktop/src/ui/pages/cluster/cluster/ClusterOverview.tsx index d6e56887..057170f7 100644 --- a/desktop/src/ui/pages/cluster/ClusterOverview.tsx +++ b/desktop/src/ui/pages/cluster/cluster/ClusterOverview.tsx @@ -1,11 +1,11 @@ import { useSearchParams } from '@solidjs/router'; import { Show } from 'solid-js'; import { PlayIcon, Share07Icon } from '@untitled-theme/icons-solid'; -import useCluster from '../../hooks/useCluster'; -import ClusterCover from '../../components/game/ClusterCover'; -import LoaderIcon from '../../components/game/LoaderIcon'; -import Button from '../../components/base/Button'; -import { launchCluster } from '../../../bridge/game'; +import useCluster from '../../../hooks/useCluster'; +import ClusterCover from '../../../components/game/ClusterCover'; +import LoaderIcon from '../../../components/game/LoaderIcon'; +import Button from '../../../components/base/Button'; +import { launchCluster } from '../../../../bridge/game'; import ScrollableContainer from '~ui/components/ScrollableContainer'; function ClusterOverview() { diff --git a/desktop/src/ui/pages/cluster/ClusterScreenshots.tsx b/desktop/src/ui/pages/cluster/cluster/ClusterScreenshots.tsx similarity index 100% rename from desktop/src/ui/pages/cluster/ClusterScreenshots.tsx rename to desktop/src/ui/pages/cluster/cluster/ClusterScreenshots.tsx diff --git a/desktop/src/ui/pages/settings/components.tsx b/desktop/src/ui/pages/settings/components.tsx index 5485af30..d71f430b 100644 --- a/desktop/src/ui/pages/settings/components.tsx +++ b/desktop/src/ui/pages/settings/components.tsx @@ -11,14 +11,14 @@ function SettingsRow(props: SettingsRowProps) { const interactableClass = createEffect(() => props.clickable ? 'hover:bg-component-bg-hover active:bg-component-bg-pressed' : ''); return ( -
+
{props.icon}
-

{props.title}

-

{props.description}

+

{props.title}

+

{props.description}

diff --git a/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx b/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx index ce250042..14b605a2 100644 --- a/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx +++ b/desktop/src/ui/pages/settings/launcher/SettingsAppearance.tsx @@ -1,21 +1,39 @@ -import { ColorsIcon, PaintPourIcon } from '@untitled-theme/icons-solid'; +import { ColorsIcon, PaintPourIcon, Speedometer04Icon } from '@untitled-theme/icons-solid'; import SettingsRow from '../components'; import ScrollableContainer from '~ui/components/ScrollableContainer'; import Button from '~ui/components/base/Button'; +import Toggle from '~ui/components/base/Toggle'; +import reducedMotionTracker from '~ui/state/reducedMotionTracker'; function SettingsAppearance() { + const { reducedMotion, setReducedMotion } = reducedMotionTracker; + return (

theme placeholder

+ } > + + } + > + { + setReducedMotion(checked); + }} + /> +
); } diff --git a/desktop/src/ui/state/reducedMotionTracker.ts b/desktop/src/ui/state/reducedMotionTracker.ts new file mode 100644 index 00000000..6aa16cf7 --- /dev/null +++ b/desktop/src/ui/state/reducedMotionTracker.ts @@ -0,0 +1,20 @@ +import { createEffect, createRoot, createSignal, onMount } from 'solid-js'; + +function createReducedMotionTracker() { + const [reducedMotion, setReducedMotion] = createSignal(false); + + onMount(() => { + const enabled = window.localStorage.getItem('reduced-motion') === 'true'; + setReducedMotion(enabled); + }); + + createEffect(() => { + const enabled = reducedMotion(); + document.body.classList.toggle('reduce-motion', enabled); + window.localStorage.setItem('reduced-motion', enabled.toString()); + }); + + return { reducedMotion, setReducedMotion }; +} + +export default createRoot(createReducedMotionTracker);