Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat (ui): implement speed controls #1206

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions apps/client/src/features/control/playback/PlaybackControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import AddTime from './add-time/AddTime';
import { AuxTimer } from './aux-timer/AuxTimer';
import PlaybackButtons from './playback-buttons/PlaybackButtons';
import PlaybackTimer from './playback-timer/PlaybackTimer';
import TimerSpeed from './timer-speed/TimerSpeed';

import style from './PlaybackControl.module.scss';

Expand All @@ -23,6 +24,7 @@ export default function PlaybackControl() {
selectedEventIndex={data.selectedEventIndex}
timerPhase={data.timerPhase}
/>
<TimerSpeed />
<AuxTimer />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
.panelContainer {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-top: 2rem;
}

// TODO: unify panel label
.label {
display: block;
font-size: $inner-section-text-size;
color: $label-gray;
}

.highlight {
color: $orange-600;
}

.speedContainer {
background-color: $gray-1100;
width: 100%;
height: 4px;
border-radius: 1px;
position: relative;
overflow: hidden;
}

.speedRegular {
position: absolute;
left: 0;
height: 100%;
width: 33.33%;
background-color: $ui-white;
}

.speedOverride {
position: absolute;
background-color: $orange-700;
left: 0;
height: 100%;
width: calc(var(--override, 0) * 1%);
}

.labels {
margin-top: 0.25rem;
font-size: calc(1rem - 3px);
color: $label-gray;
position: relative;

> span {
position: absolute;
transform: translateX(-50%);

&:first-child {
transform: translateX(0);
}

&:last-child {
transform: translateX(-100%);
}
}

.override {
color: $gray-1100;
background-color: $orange-600;
padding: 0 0.25rem;
border-radius: 2px;
top: calc(-4px - 0.5rem); // speed + gap * 2
transform: translate(-50%, -100%);
// TODO: account for case where we translate all the way left
font-weight: 600;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Button } from '@chakra-ui/react';

import style from './TimerSpeed.module.scss';

// TODO: extract and test
function mapRange(value: number, fromA_start: number, fromA_end: number, toB_start: number, toB_end: number): number {
return ((value - fromA_start) * (toB_end - toB_start)) / (fromA_end - fromA_start) + toB_start;
}
Comment on lines +8 to +11
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address TODO: Extract and test mapRange function.

The mapRange function should be moved to a separate utility file and unit tested.

Would you like me to create a new utility file for this function and generate unit tests? I can also open a GitHub issue to track this task if you prefer.


export default function TimerSpeed() {
const newSpeed = 1.23;
const newSpeedIndicator = mapRange(newSpeed, 0.5, 2.0, 0, 100);

console.log('newSpeedIndicator', newSpeedIndicator);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace hardcoded values with state management.

The newSpeed value is hardcoded, and newSpeedIndicator is calculated based on it. Consider using React state to manage these values dynamically.

-  const newSpeed = 1.23;
-  const newSpeedIndicator = mapRange(newSpeed, 0.5, 2.0, 0, 100);
+  const [newSpeed, setNewSpeed] = useState(1.0);
+  const newSpeedIndicator = useMemo(() => mapRange(newSpeed, 0.5, 2.0, 0, 100), [newSpeed]);

Also, remove the console.log statement or replace it with proper error logging.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default function TimerSpeed() {
const newSpeed = 1.23;
const newSpeedIndicator = mapRange(newSpeed, 0.5, 2.0, 0, 100);
console.log('newSpeedIndicator', newSpeedIndicator);
export default function TimerSpeed() {
const [newSpeed, setNewSpeed] = useState(1.0);
const newSpeedIndicator = useMemo(() => mapRange(newSpeed, 0.5, 2.0, 0, 100), [newSpeed]);

const handleApply = () => {
console.log('timerSpeedControl.apply');
};

const handleReset = () => {
console.log('timerSpeedControl.apply');
};

const handleMeetSchedule = () => {
console.log('timerSpeedControl.apply');
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement handler functions.

The handler functions currently only log to the console. Implement the actual functionality for applying speed changes, resetting, and meeting the schedule.

Example for handleApply:

   const handleApply = () => {
-    console.log('timerSpeedControl.apply');
+    // TODO: Implement logic to apply the new speed
+    // For example:
+    // applyNewSpeed(newSpeed);
   };

Make similar changes for handleReset and handleMeetSchedule.

Committable suggestion was skipped due to low confidence.


return (
<div className={style.panelContainer}>
<div className={style.label}>Timer speed</div>
<div style={{ display: 'flex', gap: '1rem' }}>
<Button size='sm' variant='ontime-subtle-white' onClick={handleApply}>
Apply
</Button>
<Button size='sm' variant='ontime-subtle-white' onClick={handleReset}>
Reset
</Button>
<Button size='sm' variant='ontime-subtle-white' onClick={handleMeetSchedule}>
Meet schedule
</Button>
</div>
<div>
<span>1.0x</span>
<span>{'->'}</span>
<span className={style.highlight}>{`${newSpeed}x`}</span>
</div>
<div>
<div className={style.speedContainer}>
<div className={style.speedOverride} style={{ '--override': newSpeedIndicator }} />
<div className={style.speedRegular} />
</div>
<div className={style.labels}>
<span>0.5x</span>
<span className={style.override} style={{ left: `${newSpeedIndicator}%` }}>{`${newSpeed}x`}</span>
<span style={{ left: '33.33%' }}>1.0x</span>
<span style={{ left: '66.66%' }}>1.5x</span>
<span style={{ left: '100%' }}>2.0x</span>
</div>
</div>
</div>
);
}
1 change: 0 additions & 1 deletion apps/client/src/theme/ontimeButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,4 @@ export const ontimeButtonGhosted = {
export const ontimeButtonSubtleWhite = {
...ontimeButtonSubtle,
color: '#f6f6f6', // $gray-50
fontWeight: 600,
};