Skip to content

Commit

Permalink
improved BarChart, added Clock and Timer
Browse files Browse the repository at this point in the history
  • Loading branch information
modox94 committed Nov 20, 2022
1 parent 7443e71 commit b6462f7
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 69 deletions.
16 changes: 16 additions & 0 deletions renderer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react-redux": "^8.0.4",
"react-router-dom": "^6.4.3",
"react-scripts": "5.0.1",
"react-timer-hook": "^3.0.5",
"redux-logger": "^3.0.6",
"web-vitals": "^2.1.4",
"zero-fill": "^2.2.4"
Expand Down
25 changes: 13 additions & 12 deletions renderer/src/components/BarChart/BarChart.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Container, Item } from "../SquareGrid/SquareGrid";
import clsx from "clsx";
import React, { useEffect, useMemo, useRef, useState } from "react";
import styles from "./BarChart.module.css";
import { get, isNumber } from "lodash";
import PropTypes from "prop-types";
import { noop, isNumber } from "lodash";
import React, { useEffect, useMemo, useRef } from "react";
import { Item } from "../SquareGrid/SquareGrid";
import styles from "./BarChart.module.css";

const BarChart = props => {
const { currentStep, programArray } = props;
Expand Down Expand Up @@ -48,14 +48,15 @@ const BarChart = props => {
useEffect(() => {
const element = ref.current;

const targetEl = element?.children?.[currentStep + 1];

console.log("targetEl", targetEl);
// offsetLeft

// parent
// offsetLeft
// offsetWidth
if (get(element, ["children", "length"], 0) > 0) {
const barElement = get(element, ["children", 1]);
const styles = window.getComputedStyle(barElement);
const barWidth =
parseFloat(styles.marginLeft) +
parseFloat(styles.width) +
parseFloat(styles.marginRight);
element.scrollTo({ left: barWidth * currentStep, behavior: "smooth" });
}
}, [currentStep]);

return (
Expand Down
6 changes: 3 additions & 3 deletions renderer/src/components/BarChart/BarChart.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
.bar {
min-width: calc(5vh - 3.5px);
/* the width is equal to 10% of the maximum height */
background-color: darkcyan;
background-color: darkgrey;
margin: 0 2px;
}

.barActive {
background-color: blueviolet;
background-color: forestgreen;
}

.spacerBar {
min-width: 50%;
min-width: calc(50% - ((5vh - 3.5px) / 2) - 2px);
}
36 changes: 36 additions & 0 deletions renderer/src/components/Clock/Clock.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { useTime } from "react-timer-hook";
import {
TRANSLATION_KEYS,
TRANSLATION_ROOT_KEYS,
} from "../../constants/translationConst";
import { getTranslationPath } from "../../utils/translationUtils";
import { Item } from "../SquareGrid/SquareGrid";
import styles from "./Clock.module.css";
import zeroFill from "zero-fill";

const { COMMON } = TRANSLATION_ROOT_KEYS;
const { current: current_T, time: time_T } = TRANSLATION_KEYS[COMMON];

const getTPath = (...args) => getTranslationPath(COMMON, ...args);

const Clock = props => {
const { t } = useTranslation();
const { minutes, hours } = useTime({});

return (
<Item className={styles.clock}>
<p>{t(getTPath(current_T))}</p>
<p>{t(getTPath(time_T))}</p>
<p>
<b>{`${zeroFill(2, hours)}:${zeroFill(2, minutes)}`}</b>
</p>
</Item>
);
};

Clock.propTypes = {};
Clock.defaultProps = {};

export default Clock;
19 changes: 19 additions & 0 deletions renderer/src/components/Clock/Clock.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.clock {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: center;
font-size: calc((100vh - 50px) / 14);
text-align: center;
}

.clock p {
margin: 0;
}

.clock p b {
font-size: calc((100vh - 50px) / 10);
margin: 0;
}
53 changes: 10 additions & 43 deletions renderer/src/components/ProgramMode/ProgramMode.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,48 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation } from "react-router-dom";
import zeroFill from "zero-fill";
import { setMotorLevel, stopMotor, useGetProgramQuery } from "../../api/ipc";
import { PAGES, PAGES_PATHS } from "../../constants/pathConst";
import {
TRANSLATION_KEYS,
TRANSLATION_ROOT_KEYS,
} from "../../constants/translationConst";
import { getTranslationPath } from "../../utils/translationUtils";
import BarChart from "../BarChart/BarChart";
import CadenceGauge from "../CadenceGauge/CadenceGauge";
import Clock from "../Clock/Clock";
import { Container, Item } from "../SquareGrid/SquareGrid";
import Timer from "../Timer/Timer";
import styles from "./ProgramMode.module.css";

const { SELECT_PROGRAM } = PAGES;
const { COMMON } = TRANSLATION_ROOT_KEYS;
const { remainingTime: remainingTime_T, resistance: resistance_T } =
TRANSLATION_KEYS[COMMON];

const getTPath = (...args) => getTranslationPath(COMMON, ...args);

const getRemainingTime = endMills => {
const remainingDate = new Date(endMills - Date.now());
const minutes = remainingDate.getMinutes();
const seconds = remainingDate.getSeconds();
return `${zeroFill(2, minutes)}:${zeroFill(2, seconds)}`;
};

const minute = 60000;

const ProgramMode = props => {
const intervalRef = useRef();
const counterRef = useRef();
const timerRef = useRef();
const [timer, setTimer] = useState(undefined);
const [counter, setCounter] = useState(undefined);
const { t } = useTranslation();
const [endTime, setEndTime] = useState(undefined);
const location = useLocation();
const programTitle = useMemo(
() => location.pathname.slice(PAGES_PATHS[SELECT_PROGRAM].length + 1),
[location],
);

const { data: programArray } = useGetProgramQuery(programTitle) || {};
const { resistanceLevel, targetRpm } = programArray?.[counter] || {};
const { targetRpm } = programArray?.[counter] || {};

useEffect(() => {
return () => {
clearInterval(intervalRef.current);
clearInterval(timerRef.current);
intervalRef.current = undefined;
counterRef.current = undefined;
timerRef.current = undefined;
setTimer(undefined);
setCounter(undefined);
setEndTime(undefined);
stopMotor();
};
}, []);

useEffect(() => {
if (programArray && !intervalRef.current && !(counter >= 0)) {
const endTime = Date.now() + programArray.length * minute;
const now = new Date();
now.setMilliseconds(now.getMilliseconds() + programArray.length * minute);
setEndTime(now);

counterRef.current = 0;
setCounter(0);
Expand All @@ -78,31 +59,17 @@ const ProgramMode = props => {
clearInterval(intervalRef.current);
}
}, minute);

setTimer(getRemainingTime(endTime));

timerRef.current = setInterval(() => {
if (programArray[counterRef.current]) {
setTimer(getRemainingTime(endTime));
} else {
clearInterval(timerRef.current);
}
}, 1000);
}
}, [programArray, counter]);

return (
<>
<Container>
<Item>
<h1> {`${t(getTPath(remainingTime_T))}: ${timer}`}</h1>
</Item>
<Clock />
<Item className={styles.paddingReduced}>
<CadenceGauge targetRpm={targetRpm} />
</Item>
<Item>
<h1> {`${t(getTPath(resistance_T))}: ${resistanceLevel}`}</h1>
</Item>
{endTime ? <Timer expiryTimestamp={endTime} /> : <Clock />}
</Container>

<Container>
Expand Down
71 changes: 71 additions & 0 deletions renderer/src/components/Timer/Timer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import PropTypes from "prop-types";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { useStopwatch, useTimer } from "react-timer-hook";
import zeroFill from "zero-fill";
import {
TRANSLATION_KEYS,
TRANSLATION_ROOT_KEYS,
} from "../../constants/translationConst";
import { getTranslationPath } from "../../utils/translationUtils";
import { Item } from "../SquareGrid/SquareGrid";
import styles from "./Timer.module.css";

const { COMMON } = TRANSLATION_ROOT_KEYS;
const {
remaining: remaining_T,
elapsed: elapsed_T,
time: time_T,
} = TRANSLATION_KEYS[COMMON];

const getTPath = (...args) => getTranslationPath(COMMON, ...args);

const TIMER_TYPES = { REMAIN: "REMAIN", ELAPSE: "ELAPSE" };

const Timer = props => {
const { expiryTimestamp } = props;

const [type, setType] = useState(TIMER_TYPES.REMAIN);
const { t } = useTranslation();
const { seconds: seconds_E, minutes: minutes_E } = useStopwatch({
autoStart: true,
});
const { seconds: seconds_R, minutes: minutes_R } = useTimer({
expiryTimestamp,
});

const onClick = () => {
switch (type) {
case TIMER_TYPES.REMAIN:
setType(TIMER_TYPES.ELAPSE);
break;

case TIMER_TYPES.ELAPSE:
setType(TIMER_TYPES.REMAIN);
break;

default:
break;
}
};

return (
<Item className={styles.timer} onClick={onClick}>
<p>
{t(getTPath(type === TIMER_TYPES.REMAIN ? remaining_T : elapsed_T))}
</p>
<p>{t(getTPath(time_T))}</p>
<p>
<b>
{type === TIMER_TYPES.REMAIN
? `${zeroFill(2, minutes_R)}:${zeroFill(2, seconds_R)}`
: `${zeroFill(2, minutes_E)}:${zeroFill(2, seconds_E)}`}
</b>
</p>
</Item>
);
};

Timer.propTypes = { expiryTimestamp: PropTypes.instanceOf(Date) };

export default Timer;
19 changes: 19 additions & 0 deletions renderer/src/components/Timer/Timer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.timer {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: center;
justify-content: space-between;
align-items: center;
font-size: calc((100vh - 50px) / 14);
text-align: center;
}

.timer p {
margin: 0;
}

.timer p b {
font-size: calc((100vh - 50px) / 10);
margin: 0;
}
6 changes: 4 additions & 2 deletions renderer/src/constants/translationConst.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ export const TRANSLATION_KEYS = {
[PAGES.SETTINGS]: PAGES.SETTINGS,
[PAGES.SELECT_PROGRAM]: PAGES.SELECT_PROGRAM,
programMode: "programMode",
remainingTime: "remainingTime",
elapsedTime: "elapsedTime",
current: "current",
remaining: "remaining",
elapsed: "elapsed",
time: "time",
resistance: "resistance",
currentRPM: "currentRPM",
targetRPM: "targetRPM",
Expand Down
6 changes: 3 additions & 3 deletions renderer/src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
import logger from "redux-logger";
import { ipcApi } from "../api/ipc";
// import logger from "redux-logger";

const isProduction = process.env.NODE_ENV === "production";

Expand All @@ -13,8 +13,8 @@ const store = configureStore({
middleware: getDefaultMiddleware =>
isProduction
? getDefaultMiddleware().concat(ipcApi.middleware)
: getDefaultMiddleware().concat(ipcApi.middleware, logger),
// : getDefaultMiddleware().concat(ipcApi.middleware),
: getDefaultMiddleware().concat(ipcApi.middleware),
// : getDefaultMiddleware().concat(ipcApi.middleware, logger),
});

setupListeners(store.dispatch);
Expand Down
Loading

0 comments on commit b6462f7

Please sign in to comment.