You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
4.2 KiB

5 years ago
  1. import React, {useContext, useEffect, useMemo, useState} from 'react';
  2. import "./Bois.css";
  3. import {StatusContext} from "./Contexts";
  4. import {CalorieScore, CpmScore, DistanceScore, RpmScore, Timer} from "./Score";
  5. import calculateDiff from "../helpers/diff";
  6. import useKey from "../hooks/useKey";
  7. import {COLOR_VERY_BAD} from "../helpers/color";
  8. import {Milestones} from "./Milestones";
  9. const Boi = ({type, children}) => {
  10. return (
  11. <div className={`Boi Boi-${type}`}>
  12. {children}
  13. </div>
  14. )
  15. };
  16. export const LeftBoi = () => {
  17. const {prevLongDiff, workoutStatus, program} = useContext(StatusContext);
  18. if (workoutStatus === null || program === null) {
  19. return null;
  20. }
  21. const {minutes, seconds, calories, distance, rpm} = workoutStatus;
  22. const diff = calculateDiff(program, minutes, seconds, calories);
  23. const cpm = calories / (minutes + (seconds / 60));
  24. return (
  25. <Boi type="left">
  26. <Timer minutes={minutes} seconds={seconds}/>
  27. <CalorieScore calories={calories} diff={diff} prevDiff={prevLongDiff}/>
  28. <DistanceScore distance={distance}/>
  29. <RpmScore rpm={rpm}/>
  30. <CpmScore cpm={cpm}/>
  31. </Boi>
  32. );
  33. };
  34. export const CentreBoi = () => {
  35. const {
  36. state, program, setProgram, bike, setBike, bikes, programs,
  37. start, pause, stop, create, workoutStatus,
  38. } = useContext(StatusContext);
  39. const [options, setOptions] = useState(null);
  40. const [current, setCurrent] = useState(0);
  41. useEffect(() => {
  42. if (bikes === null && programs === null) {
  43. return;
  44. }
  45. setOptions(state === "bike" ? bikes : programs);
  46. }, [state, bike, program, bikes, programs]);
  47. useKey("-", () => {
  48. if (options === null) {
  49. return false;
  50. }
  51. if (current > 0) {
  52. setCurrent(current - 1);
  53. } else {
  54. setCurrent(options.length - 1);
  55. }
  56. return true;
  57. });
  58. useKey("+", () => {
  59. if (options === null) {
  60. return false;
  61. }
  62. if (current < options.length - 1) {
  63. setCurrent(current + 1);
  64. } else {
  65. setCurrent(0);
  66. }
  67. return true;
  68. });
  69. useKey("Enter", () => {
  70. if (state === "bike") {
  71. setBike(options[current]);
  72. return true;
  73. } else if (state === "program") {
  74. setProgram(options[current]);
  75. create(options[current]);
  76. return true;
  77. } else if (state === "connected") {
  78. start();
  79. return true;
  80. } else if (state === "started") {
  81. pause();
  82. return true;
  83. }
  84. return false;
  85. });
  86. useKey("Escape", () => {
  87. if (state === "connected") {
  88. stop();
  89. return true;
  90. }
  91. });
  92. if (state === "started" && workoutStatus !== null) {
  93. const {minutes, seconds, calories} = workoutStatus;
  94. const diff = calculateDiff(program, minutes, seconds, calories);
  95. if (diff < 0) {
  96. return (
  97. <Boi type="centre">
  98. <span className="Boi-centre-warning" style={{color: COLOR_VERY_BAD}}>
  99. {diff}
  100. </span>
  101. </Boi>
  102. );
  103. } else {
  104. return null;
  105. }
  106. }
  107. if (bikes === null || programs === null) {
  108. return <Boi type="centre">Laster inn...</Boi>;
  109. }
  110. return (
  111. <Boi type="centre">
  112. {state === "stopped" && (
  113. <div className="Boi-centre-info">Inaktiv</div>
  114. )}
  115. {state === "bike" && (
  116. <div className="Boi-centre-info">
  117. Velg sykkel (+/-):
  118. <br/>
  119. <b>{options[current].name}</b>
  120. </div>
  121. )}
  122. {state === "program" && (
  123. <div className="Boi-centre-info">
  124. Velg program (+/-):
  125. <br/>
  126. <b>{options[current].name}</b>
  127. </div>
  128. )}
  129. {state === "connected" && (
  130. <table className="Boi-centre-info">
  131. <tr>
  132. <td>Enter:</td>
  133. <td><b>Start</b></td>
  134. </tr>
  135. <tr>
  136. <td>Esc:</td>
  137. <td><b>Avslutt</b></td>
  138. </tr>
  139. </table>
  140. )}
  141. {state === "unknown" && (
  142. <div className="Boi-centre-info">Noe gikk galt</div>
  143. )}
  144. </Boi>
  145. );
  146. };
  147. export const RightBoi = () => {
  148. const {milestones} = useContext(StatusContext);
  149. if ((milestones || []).length === 0) {
  150. return null;
  151. }
  152. return (
  153. <Boi type="right">
  154. <Milestones milestones={milestones.sort((i, j) => j.minutes - i.minutes)}/>
  155. </Boi>
  156. );
  157. };