Skip to content

Commit b432a69

Browse files
feat: add settings dialog
1 parent eb75f1c commit b432a69

12 files changed

+324
-12
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"devDependencies": {
6666
"@arianrhodsandlot/eslint-config": "0.18.4",
6767
"@eslint/config-inspector": "1.0.2",
68-
"@iconify/json": "2.2.316",
68+
"@iconify/json": "2.2.317",
6969
"@iconify/tailwind4": "1.0.6",
7070
"@tailwindcss/vite": "4.0.14",
7171
"@tsconfig/vite-react": "3.4.0",

pnpm-lock.yaml

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constants/platform.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ interface Platform {
3434

3535
// This link can be used as a reference for the array, but they may be not identical.
3636
// https://github.com/RetroPie/RetroPie-Setup/blob/master/platforms.cfg
37-
const platforms: Platform[] = [
37+
export const platforms: Platform[] = [
3838
{
3939
cores: [
4040
'mame2000',

src/constants/preference.ts

-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export const defaultPreference: Preference = {
6565
'megadrive',
6666
'nes',
6767
'snes',
68-
6968
'vb',
7069
'wonderswan',
7170
'wonderswancolor',

src/pages/library/components/app-layout.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type ReactNode, type UIEventHandler, useMemo } from 'react'
22
import { getContext, getContextData } from 'waku/middleware/context'
33
import { ScrollArea } from '@/pages/components/radix-themes.ts'
44
import { ServerDataContextProvider } from './server-data-context-provider.tsx'
5+
import { SidebarFooter } from './sidebar-footer.tsx'
56
import { SidebarLinks } from './sidebar-links.tsx'
67

78
interface AppLayoutProps {
@@ -28,14 +29,15 @@ export default function AppLayout({
2829
return (
2930
<ServerDataContextProvider value={value}>
3031
<div className='flex h-screen bg-[var(--accent-9)]'>
31-
<aside className='ml-4 flex w-64 shrink-0 flex-col'>
32-
<div className='flex items-center justify-center gap-2 pb-4 pt-2 font-bold text-white'>
32+
<aside className='ml-4 flex w-64 shrink-0 flex-col py-4 text-white'>
33+
<div className='flex items-center justify-center gap-2 pb-4 pt-2 font-bold'>
3334
<img alt='logo' height='32' src='/assets/logo/logo-192x192.png' width='32' />
3435
RetroAssembly
3536
</div>
3637
<ScrollArea className='flex-1' size='2'>
3738
{sidebar}
3839
</ScrollArea>
40+
<SidebarFooter />
3941
</aside>
4042

4143
<div className='m-4 flex min-w-0 flex-1'>

src/pages/library/components/device-notes.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export function DeviceNotes({ notes }: { notes: string }) {
2525
>
2626
{notes}
2727
</div>
28-
<div className=' mt-1 flex justify-end px-6'>
29-
<div className='absolute -mt-2'>
28+
<div className='relative mt-1 flex justify-end px-6'>
29+
<div className='absolute -mt-1.5'>
3030
{showExpandButton ? (
3131
<Button onClick={() => toggleExpanded()} size='1' type='button' variant='ghost'>
3232
<span className='motion-duration-1000 icon-[mdi--menu-down] motion-preset-blink size-5' />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Select } from '@radix-ui/themes'
2+
import { platforms } from '@/constants/platform.ts'
3+
import { getPlatformIcon } from '@/utils/rom.ts'
4+
5+
export function EmulatingSettings() {
6+
return (
7+
<div className='mt-4'>
8+
<h3 className='flex items-center gap-2 py-2 text-lg font-semibold'>
9+
<span className='icon-[mdi--computer-classic]' /> Platform
10+
</h3>
11+
<Select.Root defaultValue='arcade' size='3'>
12+
<Select.Trigger variant='ghost' />
13+
<Select.Content>
14+
{platforms.map((platform) => (
15+
<Select.Item key={platform.name} value={platform.name}>
16+
<div className='flex items-center gap-2'>
17+
<img
18+
alt={platform.displayName}
19+
className='size-6 object-contain object-center'
20+
src={getPlatformIcon(platform.name, '')}
21+
/>
22+
{platform.displayName}
23+
</div>
24+
</Select.Item>
25+
))}
26+
</Select.Content>
27+
</Select.Root>
28+
29+
<h3 className='flex items-center gap-2 py-2 text-lg font-semibold'>
30+
<span className='icon-[mdi--monitor-screenshot]' /> Emulator
31+
</h3>
32+
<Select.Root defaultValue='arcade' size='3'>
33+
<Select.Trigger variant='ghost' />
34+
<Select.Content>
35+
{platforms
36+
.find(({ name }) => name === 'nes')
37+
.cores.map((core) => (
38+
<Select.Item key={core} value={core}>
39+
<div className='flex items-center gap-2'>
40+
<span className='icon-[mdi--jigsaw]' />
41+
{core}
42+
</div>
43+
</Select.Item>
44+
))}
45+
</Select.Content>
46+
</Select.Root>
47+
48+
<h3 className='flex items-center gap-2 py-2 text-lg font-semibold'>
49+
<span className='icon-[mdi--wrench]' /> Emulator Options
50+
</h3>
51+
</div>
52+
)
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { Kbd, TextField } from '@radix-ui/themes'
2+
3+
const select = <TextField.Root className='w-10' />
4+
5+
export function KeyboardInputs() {
6+
return (
7+
<div>
8+
<div className='flex gap-4'>
9+
<label className='flex items-center gap-2'>
10+
<span className='icon-[mdi--gamepad-left] size-8' />
11+
{select}
12+
</label>
13+
<label className='flex items-center gap-2'>
14+
<span className='icon-[mdi--gamepad-right] size-8' />
15+
{select}
16+
</label>
17+
<label className='flex items-center gap-2'>
18+
<span className='icon-[mdi--gamepad-up] size-8' />
19+
{select}
20+
</label>
21+
<label className='flex items-center gap-2'>
22+
<span className='icon-[mdi--gamepad-down] size-8' />
23+
{select}
24+
</label>
25+
</div>
26+
<div className='mt-2 flex gap-4'>
27+
<label className='flex items-center gap-2'>
28+
<span className='icon-[mdi--gamepad-circle-down] size-8' />
29+
{select}
30+
</label>
31+
<label className='flex items-center gap-2'>
32+
<span className='icon-[mdi--gamepad-circle-left] size-8' />
33+
{select}
34+
</label>
35+
<label className='flex items-center gap-2'>
36+
<span className='icon-[mdi--gamepad-circle-right] size-8' />
37+
{select}
38+
</label>
39+
<label className='flex items-center gap-2'>
40+
<span className='icon-[mdi--gamepad-circle-up] size-8' />
41+
{select}
42+
</label>
43+
</div>
44+
45+
<div className='mt-2 flex gap-4'>
46+
<label className='flex items-center gap-2'>
47+
<Kbd>L1</Kbd>
48+
{select}
49+
</label>
50+
<label className='flex items-center gap-2'>
51+
<Kbd>L2</Kbd>
52+
{select}
53+
</label>
54+
<label className='flex items-center gap-2'>
55+
<Kbd>R1</Kbd>
56+
{select}
57+
</label>
58+
<label className='flex items-center gap-2'>
59+
<Kbd>R2</Kbd>
60+
{select}
61+
</label>
62+
<label className='flex items-center gap-2'>
63+
<Kbd>L3</Kbd>
64+
{select}
65+
</label>
66+
<label className='flex items-center gap-2'>
67+
<Kbd>R3</Kbd>
68+
{select}
69+
</label>
70+
</div>
71+
72+
<div className='mt-2 flex gap-4'>
73+
<label className='flex items-center gap-2'>
74+
<Kbd>Select</Kbd>
75+
{select}
76+
</label>
77+
<label className='flex items-center gap-2'>
78+
<Kbd>Start</Kbd>
79+
{select}
80+
</label>
81+
</div>
82+
</div>
83+
)
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { AlertDialog, Button } from '@radix-ui/themes'
2+
import { useRouter_UNSTABLE } from 'waku'
3+
4+
export function LogoutDialog(props: AlertDialog.RootProps) {
5+
const router = useRouter_UNSTABLE()
6+
7+
function handleClickLogout() {
8+
console.info('Logout')
9+
router.push('/')
10+
}
11+
12+
return (
13+
<AlertDialog.Root {...props}>
14+
<AlertDialog.Content>
15+
<AlertDialog.Title>Log out of RetroAssembly?</AlertDialog.Title>
16+
<AlertDialog.Description>You can always log back in at any time.</AlertDialog.Description>
17+
<div className='flex justify-end gap-4'>
18+
<AlertDialog.Cancel>
19+
<Button variant='soft'>
20+
<span className='icon-[mdi--close]' />
21+
Cancel
22+
</Button>
23+
</AlertDialog.Cancel>
24+
<Button onClick={handleClickLogout}>
25+
<span className='icon-[mdi--logout]' />
26+
Logout
27+
</Button>
28+
</div>
29+
</AlertDialog.Content>
30+
</AlertDialog.Root>
31+
)
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { CheckboxCards } from '@radix-ui/themes'
2+
import { platforms } from '@/constants/platform.ts'
3+
import { getPlatformIcon } from '@/utils/rom.ts'
4+
5+
export function PlatformCheckbox() {
6+
return (
7+
<CheckboxCards.Root columns='4' size='1'>
8+
{platforms.map((platform) => (
9+
<CheckboxCards.Item key={platform.name} value={platform.name}>
10+
<div className='flex items-center gap-2'>
11+
<img
12+
alt={platform.displayName}
13+
className='size-6 object-contain object-center'
14+
src={getPlatformIcon(platform.name, '')}
15+
/>
16+
{platform.displayName}
17+
</div>
18+
</CheckboxCards.Item>
19+
))}
20+
</CheckboxCards.Root>
21+
)
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Button, Dialog, ScrollArea, Tabs } from '@radix-ui/themes'
2+
import { EmulatingSettings } from './emulating-settings.tsx'
3+
import { KeyboardInputs } from './keyboard-inputs.tsx'
4+
import { PlatformCheckbox } from './platform-checkbox.tsx'
5+
6+
export function SettingsDialog(props: Dialog.RootProps) {
7+
return (
8+
<Dialog.Root {...props}>
9+
<Dialog.Content aria-describedby={undefined} className='!w-7xl !max-w-screen'>
10+
<Dialog.Title>
11+
<div className='flex items-center gap-2'>
12+
<span className='icon-[mdi--cog] ' />
13+
Settings
14+
</div>
15+
</Dialog.Title>
16+
17+
<div className='py-4'>
18+
<Tabs.Root defaultValue='account'>
19+
<Tabs.List>
20+
<Tabs.Trigger value='library'>
21+
<span className='icon-[mdi--library-shelves] mr-2 size-5' />
22+
<span className='text-lg'>Library</span>
23+
</Tabs.Trigger>
24+
<Tabs.Trigger value='inputs'>
25+
<span className='icon-[mdi--controller] mr-2 size-5' />
26+
<span className='text-lg'>Inputs</span>
27+
</Tabs.Trigger>
28+
<Tabs.Trigger value='emulating'>
29+
<span className='icon-[simple-icons--retroarch] mr-2 size-5' />
30+
<span className='text-lg'>Emulating</span>
31+
</Tabs.Trigger>
32+
</Tabs.List>
33+
34+
<div className='h-[60vh]'>
35+
<ScrollArea>
36+
<Tabs.Content value='library'>
37+
<label>
38+
<h3 className='flex items-center gap-2 py-2 text-lg font-semibold'>
39+
<span className='icon-[mdi--order-checkbox-ascending]' />
40+
Enabled Platforms
41+
</h3>
42+
<PlatformCheckbox />
43+
</label>
44+
</Tabs.Content>
45+
46+
<Tabs.Content value='inputs'>
47+
<h3 className='flex items-center gap-2 py-2 text-lg font-semibold'>
48+
<span className='icon-[mdi--keyboard]' /> Keyboard Inputs
49+
</h3>
50+
<KeyboardInputs />
51+
</Tabs.Content>
52+
53+
<Tabs.Content value='emulating'>
54+
<EmulatingSettings />
55+
</Tabs.Content>
56+
</ScrollArea>
57+
</div>
58+
</Tabs.Root>
59+
</div>
60+
61+
<div className='flex justify-between'>
62+
<div className='flex items-center gap-2 text-sm text-[var(--accent-9)]'>
63+
<span className='icon-[mdi--info]' />
64+
Your settings will be saved automatically once changed.
65+
</div>
66+
<Dialog.Close>
67+
<Button variant='soft'>
68+
<span className='icon-[mdi--check]' />
69+
Done
70+
</Button>
71+
</Dialog.Close>
72+
</div>
73+
</Dialog.Content>
74+
</Dialog.Root>
75+
)
76+
}

0 commit comments

Comments
 (0)