Skip to content

Commit

Permalink
Merge pull request #181 from clubcapra/add_countdown
Browse files Browse the repository at this point in the history
Add countdown timer
  • Loading branch information
amDeimos666 authored Jun 14, 2023
2 parents 02a89cc + bb83fbf commit 1c106c0
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 137 deletions.
19 changes: 19 additions & 0 deletions src/renderer/components/CountdownStatus/CountdownStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { styled } from '@/renderer/globalStyles/styled';
import { IoMdStopwatch } from 'react-icons/io';
import { Countdown } from '@/renderer/components/common/Countdown';
import React, { FC } from 'react';

export const CountdownStatus: FC = () => {
return (
<Countdown
icon={<StyledIoMdStopwatch />}
labelPopup={'scenario'}
durationDefault={35}
/>
);
};

const StyledIoMdStopwatch = styled(IoMdStopwatch)`
height: 1.25em;
width: 1.25em;
`;
155 changes: 19 additions & 136 deletions src/renderer/components/ExplorationStatus/ExplorationStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,25 @@
import { styled } from '@/renderer/globalStyles/styled';
import { ExplorationCancelNavigation } from './ExplorationCancelNavigation';
import {
StyledPopup,
StyledPopupContent,
StyledPopupContainer,
} from '@/renderer/components/styles';
import { GoTelescope } from 'react-icons/go';
import { Button } from '@/renderer/components/common/Button';
import { Countdown } from '@/renderer/components/common/Countdown';
import { rosClient } from '@/renderer/utils/ros/rosClient';
import React, { useEffect, FC, useState, ChangeEvent } from 'react';
import { LabeledInput } from '@/renderer/components/common/LabeledInput';
import React, { FC, useState } from 'react';
import { log } from '@/renderer/logger';

export const ExplorationStatus: FC = () => {
const timeDisplayDefault = '00:00';
const [isNowStopCountdownTimer, setIsNowStopCountdownTimer] = useState(false);

const [duration, setDuration] = useState(2);
const [timeRemaining, setTimeRemaining] = useState(0);
const [isTimerActive, setIsTimerActive] = useState(false);
const [timerDisplay, setTimerDisplay] = useState(timeDisplayDefault);
const [countDownDate, setCountDownDate] = useState(Date.now());

const updateDuration = (e: ChangeEvent<HTMLInputElement>) => {
setDuration(Number(e.target.value));
};

const startTimer = () => {
setIsTimerActive(false);
setCountDownDate(Date.now() + duration * 60 * 1000);
setIsTimerActive(true);
startRosExplorationTimer();
const startTimer = (duration: number) => {
setIsNowStopCountdownTimer(false);
startRosExplorationTimer(duration);
};

const stopTimer = () => {
setIsTimerActive(false);
setIsNowStopCountdownTimer(true);
stopRosExplorationTimer();
};

const isShowTimerDisplay = () => {
return timerDisplay !== '00:00';
};

useEffect(() => {
let interval: ReturnType<typeof setInterval> | undefined;
const intervalMs = 1000;
if (isTimerActive) {
interval = setInterval(() => {
setTimerDisplay(getTimeRemaining());
setTimeRemaining(timeRemaining - intervalMs);
}, intervalMs);
} else if (!isTimerActive && timeRemaining !== 0) {
if (interval !== undefined) {
clearInterval(interval);
}
setTimerDisplay(timeDisplayDefault);
setTimerDisplay(timeDisplayDefault);
setTimeRemaining(0);
}

const getTimeRemaining = () => {
const total = countDownDate - Date.now();

const minutes = Math.floor((total % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((total % (1000 * 60)) / 1000);

const minutesDiplay = minutes.toString().padStart(2, '0');
const secondsDiplay = seconds.toString().padStart(2, '0');

if (total < 0) {
setIsTimerActive(false);
}
return `${minutesDiplay}:${secondsDiplay}`;
};
return () => clearInterval(interval);
}, [isTimerActive, countDownDate, timeRemaining]);

const startRosExplorationTimer = () => {
const startRosExplorationTimer = (duration: number) => {
rosClient
.callService(
{
Expand All @@ -98,82 +42,21 @@ export const ExplorationStatus: FC = () => {
};

return (
<StyledDiv>
<ExplorationCancelNavigation isCancelNavigationProps={stopTimer} />
<StyledPopup
trigger={
<StyledPopupContainer>
{isShowTimerDisplay() && timerDisplay}
<StyledGoTelescope />
</StyledPopupContainer>
}
on="click"
position="bottom center"
arrow={false}
repositionOnResize={true}
>
<StyledPopupContent>
<StyledDivTimer>
<div>
<LabeledInput
label="Duration of exploration (min)"
value={duration.toString()}
type="number"
onChange={updateDuration}
/>
<StyledDivDuration>
<Button
onClick={startTimer}
btnType="success"
style={{ maxWidth: '185px' }}
>
Start
</Button>
<Button
onClick={stopTimer}
btnType="danger"
style={{ maxWidth: '185px' }}
>
Stop
</Button>
</StyledDivDuration>
</div>
<StyledDivInfo>
<StyledP>Time left</StyledP>
<p>{timerDisplay}</p>
<ExplorationCancelNavigation
isCancelNavigationProps={stopTimer}
/>
</StyledDivInfo>
</StyledDivTimer>
</StyledPopupContent>
</StyledPopup>
</StyledDiv>
<Countdown
icon={<StyledGoTelescope />}
labelPopup={'exploration'}
durationDefault={2}
onStartClick={startTimer}
onStopClick={stopTimer}
sideElement={
<ExplorationCancelNavigation isCancelNavigationProps={stopTimer} />
}
isNowStopCountdownTimer={isNowStopCountdownTimer}
/>
);
};

const StyledDiv = styled.div`
display: flex;
column-gap: 5px;
`;

const StyledGoTelescope = styled(GoTelescope)`
height: 1.25em;
width: 1.25em;
`;
const StyledDivTimer = styled.div`
margin: 1em;
`;

const StyledDivDuration = styled.div`
display: flex;
column-gap: 20px;
`;

const StyledP = styled.p`
margin-right: 20px;
`;

const StyledDivInfo = styled(StyledDivDuration)`
margin: 8px;
`;
4 changes: 3 additions & 1 deletion src/renderer/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSelector } from 'react-redux';
import BatteryStatus from './BatteryStatus/BatteryStatus';
import GpioPinsStatus from './GpioPinsStatus/GpioPinsStatus';
import { ExplorationStatus } from './ExplorationStatus/ExplorationStatus';
import { CountdownStatus } from './CountdownStatus/CountdownStatus';

interface NavLinkDefinition {
to: string;
Expand Down Expand Up @@ -49,6 +50,7 @@ export const Header: FC = () => {
))}
</LeftHeader>
<RightHeader>
<CountdownStatus />
<ExplorationStatus />
<GpioPinsStatus />
<BatteryStatus name="Motor" topicName="/vbus1" />
Expand All @@ -61,7 +63,7 @@ export const Header: FC = () => {

const HeaderGrid = styled.div`
display: grid;
grid-template-columns: 1fr 400px;
grid-template-columns: 1fr 500px;
box-shadow: 0 3px 2px rgba(0, 0, 0, 0.25);
`;

Expand Down
Loading

0 comments on commit 1c106c0

Please sign in to comment.