Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 12 additions & 3 deletions src/frontend/components/Input/InputBar/InputBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ const INPUT_CONFIG = [
{ key: 'throttle', color: getColor('green') }
] as const;

export interface InputTraceProps {
export interface InputBarProps {
brake?: number;
throttle?: number;
clutch?: number;
settings: {
settings?: {
includeClutch: boolean;
includeBrake: boolean;
includeThrottle: boolean;
};
}

export const InputBar = ({ brake, throttle, clutch, settings }: InputTraceProps) => {
export const InputBar = ({
brake,
throttle,
clutch,
settings = {
includeClutch: true,
includeBrake: true,
includeThrottle: true,
},
}: InputBarProps) => {
const svgRef = useRef<SVGSVGElement>(null);

useEffect(() => {
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
48 changes: 25 additions & 23 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,15 +21,32 @@ export const InputContainer = ({
clutch,
gear,
speed,
steer,
unit,
settings,
}: InputProps) => {
return (
<div className="w-full h-full inline-flex gap-1 p-2 flex-row bg-slate-800/50">
{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?.trace?.enabled ?? true) && (
<InputTrace input={{ brake, throttle }} settings={settings?.trace} />
)}
{(settings?.bar?.enabled ?? true) && (
<InputBar
brake={brake}
throttle={throttle}
clutch={clutch}
settings={settings?.bar}
/>
)}
{(settings?.gear?.enabled ?? true) && (
<InputGear
gear={gear}
speedMs={speed}
unit={unit}
settings={settings?.gear}
/>
)}
{(settings?.steer?.enabled ?? true) && <InputSteer angleRad={steer} />}
</div>
);
};
12 changes: 9 additions & 3 deletions src/frontend/components/Input/InputGear/InputGear.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ export interface InputGearProps {
gear?: number;
speedMs?: number;
unit?: number;
settings: {
settings?: {
unit: 'mph' | 'km/h' | 'auto';
};
}

export const InputGear = ({ gear, speedMs, unit, settings }: InputGearProps) => {
const isMetric = (unit === 1 && settings.unit === 'auto') || settings.unit === 'km/h';
export const InputGear = ({
gear,
speedMs,
unit,
settings = { unit: 'auto' },
}: InputGearProps) => {
const isMetric =
(unit === 1 && settings.unit === 'auto') || settings.unit === 'km/h';
const speed = (speedMs ?? 0) * (isMetric ? 3.6 : 2.23694);
const displayUnit = isMetric ? 'km/h' : 'mph';
let gearText = '';
Expand Down
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 * -1}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>
);
};
13 changes: 8 additions & 5 deletions src/frontend/components/Input/InputTrace/InputTrace.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import * as d3 from 'd3';
import { useEffect, useRef, useState } from 'react';
import tailwindColors from 'tailwindcss/colors';
import { getColor } from '@irdashies/utils/colors';

const BRAKE_COLOR = tailwindColors.red['500'];
const THROTTLE_COLOR = tailwindColors.green['500'];
const BRAKE_COLOR = getColor('red');
const THROTTLE_COLOR = getColor('green');

export interface InputTraceProps {
input: {
brake?: number;
throttle?: number;
};
settings: {
settings?: {
includeThrottle?: boolean;
includeBrake?: boolean;
};
}

export const InputTrace = ({ input, settings }: InputTraceProps) => {
export const InputTrace = ({
input,
settings = { includeThrottle: true, includeBrake: true },
}: InputTraceProps) => {
const { includeThrottle, includeBrake } = settings;
const svgRef = useRef<SVGSVGElement>(null);
const { width, height } = { width: 400, height: 100 };
Expand Down
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 };
};
Loading