Skip to content

Commit 9367011

Browse files
committed
feat: add steering input
1 parent aa0252c commit 9367011

File tree

9 files changed

+185
-40
lines changed

9 files changed

+185
-40
lines changed

src/app/storage/defaultDashboard.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ export const defaultDashboard: DashboardLayout = {
4545
enabled: true,
4646
unit: 'auto',
4747
},
48+
steer: {
49+
enabled: true,
50+
},
4851
},
4952
},
5053
{

src/frontend/components/Input/InputContainer/InputContainer.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const RandomTraces = () => {
1515
const [clutch, setClutch] = useState(0);
1616
const [gear] = useState(2);
1717
const [speed] = useState(122);
18+
const [steer, setSteer] = useState(0);
1819

1920
useEffect(() => {
2021
const interval = setInterval(() => {
@@ -29,6 +30,13 @@ const RandomTraces = () => {
2930
setClutch((value) =>
3031
Math.max(0, Math.min(1, value + Math.random() * 0.1 - 0.05))
3132
);
33+
34+
setSteer((value) =>
35+
Math.max(
36+
-Math.PI,
37+
Math.min(Math.PI, value + Math.random() * 0.2 - 0.1),
38+
)
39+
);
3240
}, 1000 / 60);
3341
return () => clearInterval(interval);
3442
}, []);
@@ -39,6 +47,7 @@ const RandomTraces = () => {
3947
clutch={clutch}
4048
gear={gear}
4149
speed={speed}
50+
steer={steer}
4251
settings={{
4352
trace: {
4453
enabled: true,
@@ -55,6 +64,9 @@ const RandomTraces = () => {
5564
enabled: true,
5665
unit: 'auto',
5766
},
67+
steer: {
68+
enabled: true,
69+
},
5870
}}
5971
/>
6072
);
Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { InputWidgetSettings } from '../../Settings/types';
12
import { InputBar } from '../InputBar/InputBar';
23
import { InputGear } from '../InputGear/InputGear';
4+
import { InputSteer } from '../InputSteer/InputSteer';
35
import { InputTrace } from '../InputTrace/InputTrace';
46

57
export interface InputProps {
@@ -9,25 +11,8 @@ export interface InputProps {
911
gear?: number;
1012
speed?: number;
1113
unit?: number;
12-
settings?: InputSettings;
13-
}
14-
15-
export interface InputSettings {
16-
trace: {
17-
enabled: boolean;
18-
includeThrottle: boolean;
19-
includeBrake: boolean;
20-
};
21-
bar: {
22-
enabled: boolean;
23-
includeClutch: boolean;
24-
includeBrake: boolean;
25-
includeThrottle: boolean;
26-
};
27-
gear: {
28-
enabled: boolean;
29-
unit: 'mph' | 'km/h' | 'auto';
30-
};
14+
steer?: number;
15+
settings?: InputWidgetSettings['config'];
3116
}
3217

3318
export const InputContainer = ({
@@ -36,6 +21,7 @@ export const InputContainer = ({
3621
clutch,
3722
gear,
3823
speed,
24+
steer,
3925
unit,
4026
settings,
4127
}: InputProps) => {
@@ -44,7 +30,7 @@ export const InputContainer = ({
4430
{settings?.trace.enabled && <InputTrace input={{ brake, throttle }} settings={settings.trace} />}
4531
{settings?.bar.enabled && <InputBar brake={brake} throttle={throttle} clutch={clutch} settings={settings.bar} />}
4632
{settings?.gear.enabled && <InputGear gear={gear} speedMs={speed} unit={unit} settings={settings.gear} />}
47-
{/* <InputSteer /> */} {/* WIP */}
33+
{settings?.steer?.enabled && <InputSteer angleRad={steer} />}
4834
</div>
4935
);
5036
};

src/frontend/components/Input/InputSteer/InputSteer.stories.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,22 @@ import { InputSteer } from './InputSteer';
33

44
export default {
55
component: InputSteer,
6+
argTypes: {
7+
angleRad: {
8+
control: {
9+
type: 'range',
10+
min: -3.14,
11+
max: 3.14,
12+
step: 0.01,
13+
},
14+
},
15+
},
616
} as Meta;
717

818
type Story = StoryObj<typeof InputSteer>;
919

1020
export const Primary: Story = {
11-
args: {},
21+
args: {
22+
angleRad: 0,
23+
},
1224
};
Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
1-
import { SteeringWheelIcon } from '@phosphor-icons/react';
1+
export interface InputSteerProps {
2+
angleRad?: number;
3+
}
24

3-
export type InputSteerProps = object; // TODO
4-
5-
export const InputSteer = () => {
5+
export const InputSteer = ({ angleRad = 0 }: InputSteerProps) => {
66
return (
7-
<div className="w-[120px]">
8-
<SteeringWheelIcon width="100%" height="100%" />
7+
<div className="w-[120px] fill-white">
8+
<svg
9+
xmlns="http://www.w3.org/2000/svg"
10+
xmlSpace="preserve"
11+
width="100%"
12+
height="100%"
13+
viewBox="-66 33 145 145"
14+
>
15+
<g
16+
style={{
17+
transform: `rotate(${angleRad}rad)`,
18+
transformBox: 'fill-box',
19+
transformOrigin: 'center',
20+
}}
21+
>
22+
<path d="M6.033 32.908a72.196 72.196 0 0 0-72.196 72.196A72.196 72.196 0 0 0 6.033 177.3a72.196 72.196 0 0 0 72.196-72.196A72.196 72.196 0 0 0 6.033 32.908Zm0 12.657A59.538 59.538 0 0 1 64.298 93.54C48.864 89.147 33.41 84.76 6.42 84.51v-.013c-.133 0-.256.005-.388.006-.133 0-.255-.005-.388-.006v.013c-26.99.25-42.444 4.637-57.877 9.03A59.538 59.538 0 0 1 6.033 45.565Zm-28.908 58.126c9.141 2.38 16.78 12.14 22.875 29.501-.808 17.98-1.985 28.342-3.55 30.653a59.538 59.538 0 0 1-49.561-53.73c8.89-2.973 16.97-6.514 30.236-6.424zm57.816 0c13.345-.09 21.44 3.494 30.393 6.477a59.538 59.538 0 0 1-49.708 53.695c-1.57-2.281-2.75-12.651-3.56-30.671 6.093-17.36 13.733-27.122 22.875-29.501z" />
23+
<path
24+
d="M 0 33.25 A 72 72 0 0 1 12 33.25 L 12 45.8 A 60 60 0 0 0 0 45.8 Z"
25+
fill="#ffc800"
26+
/>
27+
</g>
28+
</svg>
929
</div>
1030
);
1131
};

src/frontend/components/Input/hooks/useInputSettings.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useDashboard } from '@irdashies/context'
2-
import { InputSettings } from '../InputContainer/InputContainer';
2+
import { InputWidgetSettings } from '../../Settings/types';
33

44
export const useInputSettings = () => {
55
const { currentDashboard } = useDashboard();
@@ -18,7 +18,7 @@ export const useInputSettings = () => {
1818
typeof inputSettings.bar === 'object' &&
1919
typeof inputSettings.gear === 'object'
2020
) {
21-
return inputSettings as unknown as InputSettings;
21+
return inputSettings as unknown as InputWidgetSettings['config'];
2222
}
2323

2424
return undefined;

src/frontend/components/Input/hooks/useInputs.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const useInputs = () => {
77
const gear = useTelemetryValue('Gear');
88
const speed = useTelemetryValue('Speed');
99
const unit = useTelemetryValue('DisplayUnits');
10+
const steer = useTelemetryValue('SteeringWheelAngle');
1011

11-
return { brake, throttle, clutch, gear, speed, unit };
12+
return { brake, throttle, clutch, gear, speed, unit, steer };
1213
};

src/frontend/components/Settings/sections/InputSettings.tsx

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,87 @@ import { BaseSettingsSection } from '../components/BaseSettingsSection';
33
import { InputWidgetSettings } from '../types';
44
import { useDashboard } from '@irdashies/context';
55
import { ToggleSwitch } from '../components/ToggleSwitch';
6-
import { InputSettings as InputSettingsType } from '../../Input/InputContainer/InputContainer';
6+
7+
const SETTING_ID = 'input';
8+
9+
const defaultConfig: InputWidgetSettings['config'] = {
10+
trace: {
11+
enabled: true,
12+
includeThrottle: true,
13+
includeBrake: true,
14+
},
15+
bar: {
16+
enabled: true,
17+
includeClutch: true,
18+
includeBrake: true,
19+
includeThrottle: true,
20+
},
21+
gear: {
22+
enabled: true,
23+
unit: 'auto',
24+
},
25+
steer: {
26+
enabled: true,
27+
},
28+
};
29+
30+
// Migration function to handle missing properties in the new config format
31+
const migrateConfig = (
32+
savedConfig: unknown,
33+
): InputWidgetSettings['config'] => {
34+
if (!savedConfig || typeof savedConfig !== 'object') return defaultConfig;
35+
36+
const config = savedConfig as Record<string, unknown>;
37+
38+
return {
39+
trace: {
40+
enabled:
41+
(config.trace as { enabled?: boolean })?.enabled ??
42+
defaultConfig.trace.enabled,
43+
includeThrottle:
44+
(config.trace as { includeThrottle?: boolean })?.includeThrottle ??
45+
defaultConfig.trace.includeThrottle,
46+
includeBrake:
47+
(config.trace as { includeBrake?: boolean })?.includeBrake ??
48+
defaultConfig.trace.includeBrake,
49+
},
50+
bar: {
51+
enabled:
52+
(config.bar as { enabled?: boolean })?.enabled ?? defaultConfig.bar.enabled,
53+
includeClutch:
54+
(config.bar as { includeClutch?: boolean })?.includeClutch ??
55+
defaultConfig.bar.includeClutch,
56+
includeBrake:
57+
(config.bar as { includeBrake?: boolean })?.includeBrake ??
58+
defaultConfig.bar.includeBrake,
59+
includeThrottle:
60+
(config.bar as { includeThrottle?: boolean })?.includeThrottle ??
61+
defaultConfig.bar.includeThrottle,
62+
},
63+
gear: {
64+
enabled:
65+
(config.gear as { enabled?: boolean })?.enabled ??
66+
defaultConfig.gear.enabled,
67+
unit:
68+
(config.gear as { unit?: 'mph' | 'km/h' | 'auto' })?.unit ??
69+
defaultConfig.gear.unit,
70+
},
71+
steer: {
72+
enabled:
73+
(config.steer as { enabled?: boolean })?.enabled ??
74+
defaultConfig.steer.enabled,
75+
},
76+
};
77+
};
778

879
export const InputSettings = () => {
980
const { currentDashboard } = useDashboard();
81+
const savedSettings = currentDashboard?.widgets.find(
82+
(w) => w.id === SETTING_ID,
83+
);
1084
const [settings, setSettings] = useState<InputWidgetSettings>({
11-
enabled:
12-
currentDashboard?.widgets.find((w) => w.id === 'input')?.enabled ?? false,
13-
config: ((currentDashboard?.widgets.find((w) => w.id === 'input')
14-
?.config as unknown) as InputSettingsType),
85+
enabled: savedSettings?.enabled ?? false,
86+
config: migrateConfig(savedSettings?.config),
1587
});
1688

1789
if (!currentDashboard) {
@@ -21,7 +93,7 @@ export const InputSettings = () => {
2193
const config = settings.config;
2294

2395
return (
24-
<BaseSettingsSection<InputSettingsType>
96+
<BaseSettingsSection
2597
title="Input Traces Settings"
2698
description="Configure the input traces display settings for throttle, brake, and clutch."
2799
settings={settings}
@@ -135,6 +207,26 @@ export const InputSettings = () => {
135207
)}
136208
</div>
137209

210+
{/* Steer Settings */}
211+
<div className="space-y-4">
212+
<div className="flex items-center justify-between">
213+
<h3 className="text-lg font-medium text-slate-200">
214+
Steer Settings
215+
</h3>
216+
<div className="flex items-center gap-3">
217+
<span className="text-sm text-slate-300">
218+
Enable Steer Display
219+
</span>
220+
<ToggleSwitch
221+
enabled={config.steer.enabled}
222+
onToggle={(enabled) =>
223+
handleConfigChange({ steer: { ...config.steer, enabled } })
224+
}
225+
/>
226+
</div>
227+
</div>
228+
</div>
229+
138230
{/* Gear Settings */}
139231
<div className="space-y-4">
140232
<div className="flex items-center justify-between">

src/frontend/components/Settings/types.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { InputSettings } from '../Input/InputContainer/InputContainer';
2-
3-
/* eslint-disable @typescript-eslint/no-empty-object-type */
41
export interface BaseWidgetSettings<T = Record<string, unknown>> {
52
enabled: boolean;
63
config: T;
@@ -42,8 +39,30 @@ export interface TrackMapWidgetSettings extends BaseWidgetSettings {
4239
};
4340
}
4441

45-
export type InputWidgetSettings = BaseWidgetSettings<InputSettings>;
42+
export interface InputWidgetSettings extends BaseWidgetSettings {
43+
config: {
44+
trace: {
45+
enabled: boolean;
46+
includeThrottle: boolean;
47+
includeBrake: boolean;
48+
};
49+
bar: {
50+
enabled: boolean;
51+
includeClutch: boolean;
52+
includeBrake: boolean;
53+
includeThrottle: boolean;
54+
};
55+
gear: {
56+
enabled: boolean;
57+
unit: 'mph' | 'km/h' | 'auto';
58+
};
59+
steer: {
60+
enabled: boolean;
61+
};
62+
};
63+
}
4664

65+
/* eslint-disable @typescript-eslint/no-empty-object-type */
4766
export interface AdvancedSettings extends BaseWidgetSettings {
4867
// Add specific advanced settings here
4968
}

0 commit comments

Comments
 (0)