Fix all the bugs and hide all the Bois.
This commit is contained in:
@@ -2,4 +2,3 @@ cd ./my-bois
|
|||||||
|
|
||||||
npm install
|
npm install
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
|
|||||||
@@ -23,20 +23,6 @@
|
|||||||
font-size: 5vmax;
|
font-size: 5vmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Boi-centre-warning {
|
|
||||||
margin-top: 1em;
|
|
||||||
font-weight: 800;
|
|
||||||
font-size: 150%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Boi-centre-info {
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Boi-centre-info td:first-child {
|
|
||||||
padding-right: 1ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Boi-right {
|
.Boi-right {
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React, {useContext, useEffect, useMemo, useState} from 'react';
|
import React, {useContext, useEffect, useState} from 'react';
|
||||||
|
|
||||||
import "./Bois.css";
|
import "./Bois.css";
|
||||||
import {StatusContext} from "./Contexts";
|
import {StatusContext} from "./Contexts";
|
||||||
import {CalorieScore, CpmScore, DistanceScore, RpmScore, Timer} from "./Score";
|
import {CalorieScore, CpmScore, DistanceScore, RpmScore, Timer} from "./Score";
|
||||||
import calculateDiff from "../helpers/diff";
|
import calculateDiff from "../helpers/diff";
|
||||||
import useKey from "../hooks/useKey";
|
import useKey from "../hooks/useKey";
|
||||||
import {COLOR_VERY_BAD} from "../helpers/color";
|
|
||||||
import {Milestones} from "./Milestones";
|
import {Milestones} from "./Milestones";
|
||||||
|
import {Info, InfoTable, StateFilter, Warning} from "./Misc";
|
||||||
|
|
||||||
const Boi = ({type, children}) => {
|
const Boi = ({type, children}) => {
|
||||||
return (
|
return (
|
||||||
@@ -17,8 +17,8 @@ const Boi = ({type, children}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const LeftBoi = () => {
|
export const LeftBoi = () => {
|
||||||
const {prevLongDiff, workoutStatus, program} = useContext(StatusContext);
|
const {prevLongDiff, workoutStatus, program, hidden} = useContext(StatusContext);
|
||||||
if (workoutStatus === null || program === null) {
|
if (workoutStatus === null || program === null || hidden) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,8 +113,7 @@ export const CentreBoi = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useKey("H", () => showHide());
|
useKey(["H", "h"], () => showHide());
|
||||||
useKey("h", () => showHide());
|
|
||||||
|
|
||||||
function showHide() {
|
function showHide() {
|
||||||
setHidden(!hidden);
|
setHidden(!hidden);
|
||||||
@@ -131,9 +130,7 @@ export const CentreBoi = () => {
|
|||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
return (
|
return (
|
||||||
<Boi type="centre">
|
<Boi type="centre">
|
||||||
<span className="Boi-centre-warning" style={{color: COLOR_VERY_BAD}}>
|
<Warning>{diff}</Warning>
|
||||||
{diff}
|
|
||||||
</span>
|
|
||||||
</Boi>
|
</Boi>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -142,51 +139,65 @@ export const CentreBoi = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bikes === null || programs === null) {
|
if (bikes === null || programs === null) {
|
||||||
return <Boi type="centre">Laster inn...</Boi>;
|
return <Boi type="centre"><Info>Laster inn...</Info></Boi>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function currentOptionName() {
|
||||||
|
if (options === null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options[current] === void(0)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return options[current].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(state);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Boi type="centre">
|
<Boi type="centre">
|
||||||
{state === "stopped" && (
|
<StateFilter current={state} required="stopped">
|
||||||
<div className="Boi-centre-info">Inaktiv</div>
|
<Info>Inaktiv</Info>
|
||||||
)}
|
</StateFilter>
|
||||||
{state === "bike" && (
|
<StateFilter current={state} required="bike">
|
||||||
<div className="Boi-centre-info">
|
<Info>
|
||||||
Velg sykkel (+/-):
|
Velg sykkel (+/-):
|
||||||
<br/>
|
<br/>
|
||||||
<b>{options[current].name}</b>
|
<b>{currentOptionName()}</b>
|
||||||
</div>
|
</Info>
|
||||||
)}
|
</StateFilter>
|
||||||
{state === "program" && (
|
<StateFilter current={state} required="program">
|
||||||
<div className="Boi-centre-info">
|
<Info>
|
||||||
Velg program (+/-):
|
Velg program (+/-):
|
||||||
<br/>
|
<br/>
|
||||||
<b>{options[current].name}</b>
|
<b>{currentOptionName()}</b>
|
||||||
</div>
|
</Info>
|
||||||
)}
|
</StateFilter>
|
||||||
{state === "connected" && (
|
<StateFilter current={state} required="connected">
|
||||||
<table className="Boi-centre-info">
|
<InfoTable keyValuePairs={[
|
||||||
<tr>
|
{key: "Enter", value: "Start"},
|
||||||
<td>Enter:</td>
|
{key: "Escape", value: "Avslutt"},
|
||||||
<td><b>Start</b></td>
|
]}/>
|
||||||
</tr>
|
</StateFilter>
|
||||||
<tr>
|
<StateFilter current={state} required="disconnected">
|
||||||
<td>Esc:</td>
|
<Info>Kobler til...</Info>
|
||||||
<td><b>Avslutt</b></td>
|
</StateFilter>
|
||||||
</tr>
|
<StateFilter current={state} required="started">
|
||||||
</table>
|
<Info>Abonnerer på WS...</Info>
|
||||||
)}
|
</StateFilter>
|
||||||
{state === "unknown" && (
|
<StateFilter current={state} required="unknown">
|
||||||
<div className="Boi-centre-info">Noe gikk galt</div>
|
<Info>Noe gikk galt!</Info>
|
||||||
)}
|
</StateFilter>
|
||||||
</Boi>
|
</Boi>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RightBoi = () => {
|
export const RightBoi = () => {
|
||||||
const {milestones} = useContext(StatusContext);
|
const {milestones, hidden} = useContext(StatusContext);
|
||||||
|
|
||||||
if ((milestones || []).length === 0) {
|
if (hidden || (milestones || []).length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,31 +87,29 @@ export const StatusContextProvider = ({children}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
socket.onmessage = ({data}) => {
|
socket.onmessage = ({data}) => {
|
||||||
onSocketMessage(workout, program, JSON.parse(data));
|
const body = JSON.parse(data);
|
||||||
|
|
||||||
|
if (typeof body.workout !== "undefined") {
|
||||||
|
setWorkout({...body.workout, ...workout});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof body.workoutStatusBackfill !== "undefined") {
|
||||||
|
body.workoutStatusBackfill.forEach(wsbf => {
|
||||||
|
setWorkoutStatus(wsbf);
|
||||||
|
msDispatch({type: "measure", payload: {...wsbf, program}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof body.workoutStatus !== "undefined") {
|
||||||
|
setWorkoutStatus(body.workoutStatus);
|
||||||
|
msDispatch({type: "measure", payload: {...body.workoutStatus, program}});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.onmessage = null;
|
socket.onmessage = null;
|
||||||
}
|
}
|
||||||
}, [socket, workout, program]);
|
}, [socket, workout, program, msDispatch]);
|
||||||
|
|
||||||
function onSocketMessage(myWorkout, program, body) {
|
|
||||||
if (typeof body.workout !== "undefined") {
|
|
||||||
setWorkout({...body.workout, ...myWorkout});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof body.workoutStatusBackfill !== "undefined") {
|
|
||||||
body.workoutStatusBackfill.forEach(wsbf => {
|
|
||||||
setWorkoutStatus(wsbf);
|
|
||||||
msDispatch({type: "measure", payload: {...wsbf, program}});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof body.workoutStatus !== "undefined") {
|
|
||||||
setWorkoutStatus(body.workoutStatus);
|
|
||||||
msDispatch({type: "measure", payload: {...body.workoutStatus, program}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create(myProgram = null) {
|
async function create(myProgram = null) {
|
||||||
setWorkoutStatus(null);
|
setWorkoutStatus(null);
|
||||||
@@ -162,6 +160,7 @@ export const StatusContextProvider = ({children}) => {
|
|||||||
setBike, setProgram,
|
setBike, setProgram,
|
||||||
create, resume, start, pause, stop,
|
create, resume, start, pause, stop,
|
||||||
programs, bikes,
|
programs, bikes,
|
||||||
|
prevDiff, prevLongDiff,
|
||||||
hidden, setHidden,
|
hidden, setHidden,
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -6,14 +6,16 @@ import {colorByDiff} from "../helpers/color";
|
|||||||
|
|
||||||
export const Milestones = ({milestones}) => (
|
export const Milestones = ({milestones}) => (
|
||||||
<table className="Milestone">
|
<table className="Milestone">
|
||||||
{milestones.map(milestone => <Milestone {...milestone} />)}
|
<tbody>
|
||||||
|
{milestones.map(milestone => <Milestone key={milestone.minutes} {...milestone} />)}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Milestone = ({minutes, calories, diff, prevDiff}) => (
|
const Milestone = ({minutes, calories, diff, prevDiff}) => (
|
||||||
<tr style={{color: colorByDiff(diff, prevDiff)}}>
|
<tr style={{color: colorByDiff(diff, prevDiff)}}>
|
||||||
<td className="Milestone-minutes">{minutes}</td>
|
<td className="Milestone-minutes"> {minutes}</td>
|
||||||
<td className="Milestone-calories">{calories}</td>
|
<td className="Milestone-calories"> {calories}</td>
|
||||||
<td className="Milestone-diff">{minutes % 5 === 0 ? diffString(diff) : ""}</td>
|
<td className="Milestone-diff"> {minutes % 5 === 0 ? diffString(diff) : ""}</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
.Warning {
|
||||||
|
margin-top: 1em;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Info {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Info table td:first-child {
|
||||||
|
padding-right: 1ch;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {COLOR_VERY_BAD} from "../helpers/color";
|
||||||
|
|
||||||
|
import "./Misc.css";
|
||||||
|
|
||||||
|
const Filter = ({bool, children}) => bool ? <>{children}</> : null;
|
||||||
|
|
||||||
|
export const StateFilter = ({current, required, children}) => (
|
||||||
|
<Filter bool={current === required}>{children}</Filter>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Warning = ({children}) => (
|
||||||
|
<div className="Warning" style={{color: COLOR_VERY_BAD}}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Info = ({children}) => (
|
||||||
|
<div className="Info">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const InfoTable = ({keyValuePairs}) => (
|
||||||
|
<Info>
|
||||||
|
<table>
|
||||||
|
{keyValuePairs.map(({key, value}) => (
|
||||||
|
<tr key={key}>
|
||||||
|
<td>{key}:</td>
|
||||||
|
<td><b>{value}</b></td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</table>
|
||||||
|
</Info>
|
||||||
|
);
|
||||||
@@ -22,7 +22,7 @@ function reducer(state, {type, payload}) {
|
|||||||
let newMilestones = milestones.filter(m => m.minutes !== minutes);
|
let newMilestones = milestones.filter(m => m.minutes !== minutes);
|
||||||
newMilestones.push({
|
newMilestones.push({
|
||||||
minutes, seconds, calories, diff,
|
minutes, seconds, calories, diff,
|
||||||
prevDiff: isFive ? prevDiff : prevLongDiff
|
prevDiff: isFive ? prevLongDiff : prevDiff
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFive) {
|
if (isFive) {
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import {useEffect} from "react";
|
|||||||
|
|
||||||
export default function useKey(keyName, callback) {
|
export default function useKey(keyName, callback) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const keys = Array.isArray(keyName) ? keyName : [keyName];
|
||||||
|
|
||||||
const handler = function (ev) {
|
const handler = function (ev) {
|
||||||
if (ev.key === keyName) {
|
if (keys.includes(ev.key)) {
|
||||||
if (callback()) {
|
if (callback()) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user