Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/app/storage/defaultDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export const defaultDashboard: DashboardLayout = {
enabled: true,
unit: 'auto',
},
steer: {
enabled: true,
},
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const RandomTraces = () => {
const [clutch, setClutch] = useState(0);
const [gear] = useState(2);
const [speed] = useState(122);
const [steer, setSteer] = useState(0);

useEffect(() => {
const interval = setInterval(() => {
Expand All @@ -29,6 +30,13 @@ const RandomTraces = () => {
setClutch((value) =>
Math.max(0, Math.min(1, value + Math.random() * 0.1 - 0.05))
);

setSteer((value) =>
Math.max(
-Math.PI,
Math.min(Math.PI, value + Math.random() * 0.2 - 0.1),
)
);
}, 1000 / 60);
return () => clearInterval(interval);
}, []);
Expand All @@ -39,6 +47,7 @@ const RandomTraces = () => {
clutch={clutch}
gear={gear}
speed={speed}
steer={steer}
settings={{
trace: {
enabled: true,
Expand All @@ -55,6 +64,9 @@ const RandomTraces = () => {
enabled: true,
unit: 'auto',
},
steer: {
enabled: true,
},
}}
/>
);
Expand Down
26 changes: 6 additions & 20 deletions src/frontend/components/Input/InputContainer/InputContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { InputWidgetSettings } from '../../Settings/types';
import { InputBar } from '../InputBar/InputBar';
import { InputGear } from '../InputGear/InputGear';
import { InputSteer } from '../InputSteer/InputSteer';
import { InputTrace } from '../InputTrace/InputTrace';

export interface InputProps {
Expand All @@ -9,25 +11,8 @@ export interface InputProps {
gear?: number;
speed?: number;
unit?: number;
settings?: InputSettings;
}

export interface InputSettings {
trace: {
enabled: boolean;
includeThrottle: boolean;
includeBrake: boolean;
};
bar: {
enabled: boolean;
includeClutch: boolean;
includeBrake: boolean;
includeThrottle: boolean;
};
gear: {
enabled: boolean;
unit: 'mph' | 'km/h' | 'auto';
};
steer?: number;
settings?: InputWidgetSettings['config'];
}

export const InputContainer = ({
Expand All @@ -36,6 +21,7 @@ export const InputContainer = ({
clutch,
gear,
speed,
steer,
unit,
settings,
}: InputProps) => {
Expand All @@ -44,7 +30,7 @@ export const InputContainer = ({
{settings?.trace.enabled && <InputTrace input={{ brake, throttle }} settings={settings.trace} />}
{settings?.bar.enabled && <InputBar brake={brake} throttle={throttle} clutch={clutch} settings={settings.bar} />}
{settings?.gear.enabled && <InputGear gear={gear} speedMs={speed} unit={unit} settings={settings.gear} />}
{/* <InputSteer /> */} {/* WIP */}
{settings?.steer?.enabled && <InputSteer angleRad={steer} />}
</div>
);
};
14 changes: 13 additions & 1 deletion src/frontend/components/Input/InputSteer/InputSteer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ import { InputSteer } from './InputSteer';

export default {
component: InputSteer,
argTypes: {
angleRad: {
control: {
type: 'range',
min: -3.14,
max: 3.14,
step: 0.01,
},
},
},
} as Meta;

type Story = StoryObj<typeof InputSteer>;

export const Primary: Story = {
args: {},
args: {
angleRad: 0,
},
};
32 changes: 26 additions & 6 deletions src/frontend/components/Input/InputSteer/InputSteer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
import { SteeringWheelIcon } from '@phosphor-icons/react';
export interface InputSteerProps {
angleRad?: number;
}

export type InputSteerProps = object; // TODO

export const InputSteer = () => {
export const InputSteer = ({ angleRad = 0 }: InputSteerProps) => {
return (
<div className="w-[120px]">
<SteeringWheelIcon width="100%" height="100%" />
<div className="w-[120px] fill-white">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
width="100%"
height="100%"
viewBox="-66 33 145 145"
>
<g
style={{
transform: `rotate(${angleRad}rad)`,
transformBox: 'fill-box',
transformOrigin: 'center',
}}
>
<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" />
<path
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"
className='fill-yellow-500'
/>
</g>
</svg>
</div>
);
};
4 changes: 2 additions & 2 deletions src/frontend/components/Input/hooks/useInputSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useDashboard } from '@irdashies/context'
import { InputSettings } from '../InputContainer/InputContainer';
import { InputWidgetSettings } from '../../Settings/types';

export const useInputSettings = () => {
const { currentDashboard } = useDashboard();
Expand All @@ -18,7 +18,7 @@ export const useInputSettings = () => {
typeof inputSettings.bar === 'object' &&
typeof inputSettings.gear === 'object'
) {
return inputSettings as unknown as InputSettings;
return inputSettings as unknown as InputWidgetSettings['config'];
}

return undefined;
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/components/Input/hooks/useInputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const useInputs = () => {
const gear = useTelemetryValue('Gear');
const speed = useTelemetryValue('Speed');
const unit = useTelemetryValue('DisplayUnits');
const steer = useTelemetryValue('SteeringWheelAngle');

return { brake, throttle, clutch, gear, speed, unit };
return { brake, throttle, clutch, gear, speed, unit, steer };
};
104 changes: 98 additions & 6 deletions src/frontend/components/Settings/sections/InputSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,87 @@ import { BaseSettingsSection } from '../components/BaseSettingsSection';
import { InputWidgetSettings } from '../types';
import { useDashboard } from '@irdashies/context';
import { ToggleSwitch } from '../components/ToggleSwitch';
import { InputSettings as InputSettingsType } from '../../Input/InputContainer/InputContainer';

const SETTING_ID = 'input';

const defaultConfig: InputWidgetSettings['config'] = {
trace: {
enabled: true,
includeThrottle: true,
includeBrake: true,
},
bar: {
enabled: true,
includeClutch: true,
includeBrake: true,
includeThrottle: true,
},
gear: {
enabled: true,
unit: 'auto',
},
steer: {
enabled: true,
},
};

// Migration function to handle missing properties in the new config format
const migrateConfig = (
savedConfig: unknown,
): InputWidgetSettings['config'] => {
if (!savedConfig || typeof savedConfig !== 'object') return defaultConfig;

const config = savedConfig as Record<string, unknown>;

return {
trace: {
enabled:
(config.trace as { enabled?: boolean })?.enabled ??
defaultConfig.trace.enabled,
includeThrottle:
(config.trace as { includeThrottle?: boolean })?.includeThrottle ??
defaultConfig.trace.includeThrottle,
includeBrake:
(config.trace as { includeBrake?: boolean })?.includeBrake ??
defaultConfig.trace.includeBrake,
},
bar: {
enabled:
(config.bar as { enabled?: boolean })?.enabled ?? defaultConfig.bar.enabled,
includeClutch:
(config.bar as { includeClutch?: boolean })?.includeClutch ??
defaultConfig.bar.includeClutch,
includeBrake:
(config.bar as { includeBrake?: boolean })?.includeBrake ??
defaultConfig.bar.includeBrake,
includeThrottle:
(config.bar as { includeThrottle?: boolean })?.includeThrottle ??
defaultConfig.bar.includeThrottle,
},
gear: {
enabled:
(config.gear as { enabled?: boolean })?.enabled ??
defaultConfig.gear.enabled,
unit:
(config.gear as { unit?: 'mph' | 'km/h' | 'auto' })?.unit ??
defaultConfig.gear.unit,
},
steer: {
enabled:
(config.steer as { enabled?: boolean })?.enabled ??
defaultConfig.steer.enabled,
},
};
};

export const InputSettings = () => {
const { currentDashboard } = useDashboard();
const savedSettings = currentDashboard?.widgets.find(
(w) => w.id === SETTING_ID,
);
const [settings, setSettings] = useState<InputWidgetSettings>({
enabled:
currentDashboard?.widgets.find((w) => w.id === 'input')?.enabled ?? false,
config: ((currentDashboard?.widgets.find((w) => w.id === 'input')
?.config as unknown) as InputSettingsType),
enabled: savedSettings?.enabled ?? false,
config: migrateConfig(savedSettings?.config),
});

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

return (
<BaseSettingsSection<InputSettingsType>
<BaseSettingsSection
title="Input Traces Settings"
description="Configure the input traces display settings for throttle, brake, and clutch."
settings={settings}
Expand Down Expand Up @@ -135,6 +207,26 @@ export const InputSettings = () => {
)}
</div>

{/* Steer Settings */}
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-slate-200">
Steer Settings
</h3>
<div className="flex items-center gap-3">
<span className="text-sm text-slate-300">
Enable Steer Display
</span>
<ToggleSwitch
enabled={config.steer.enabled}
onToggle={(enabled) =>
handleConfigChange({ steer: { ...config.steer, enabled } })
}
/>
</div>
</div>
</div>

{/* Gear Settings */}
<div className="space-y-4">
<div className="flex items-center justify-between">
Expand Down
27 changes: 23 additions & 4 deletions src/frontend/components/Settings/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { InputSettings } from '../Input/InputContainer/InputContainer';

/* eslint-disable @typescript-eslint/no-empty-object-type */
export interface BaseWidgetSettings<T = Record<string, unknown>> {
enabled: boolean;
config: T;
Expand Down Expand Up @@ -42,8 +39,30 @@ export interface TrackMapWidgetSettings extends BaseWidgetSettings {
};
}

export type InputWidgetSettings = BaseWidgetSettings<InputSettings>;
export interface InputWidgetSettings extends BaseWidgetSettings {
config: {
trace: {
enabled: boolean;
includeThrottle: boolean;
includeBrake: boolean;
};
bar: {
enabled: boolean;
includeClutch: boolean;
includeBrake: boolean;
includeThrottle: boolean;
};
gear: {
enabled: boolean;
unit: 'mph' | 'km/h' | 'auto';
};
steer: {
enabled: boolean;
};
};
}

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