Browse Source

Fix all the bugs and hide all the Bois.

master
Stian Aune 5 years ago
parent
commit
3d92e63f51
  1. 1
      install-and-build.sh
  2. 14
      my-bois/src/components/Bois.css
  3. 91
      my-bois/src/components/Bois.jsx
  4. 39
      my-bois/src/components/Contexts.jsx
  5. 10
      my-bois/src/components/Milestones.jsx
  6. 13
      my-bois/src/components/Misc.css
  7. 35
      my-bois/src/components/Misc.jsx
  8. 2
      my-bois/src/hooks/milestones.js
  9. 4
      my-bois/src/hooks/useKey.js

1
install-and-build.sh

@ -2,4 +2,3 @@ cd ./my-bois
npm install npm install
sh build.sh sh build.sh

14
my-bois/src/components/Bois.css

@ -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;

91
my-bois/src/components/Bois.jsx

@ -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);
if (workoutStatus === null || program === null) {
const {prevLongDiff, workoutStatus, program, hidden} = useContext(StatusContext);
if (workoutStatus === null || program === null || hidden) {
return null; return null;
} }
@ -113,8 +113,7 @@ export const CentreBoi = () => {
} }
}); });
useKey("H", () => showHide());
useKey("h", () => showHide());
useKey(["H", "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}}>
{diff}
</span>
<Warning>{diff}</Warning>
</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" && (
<div className="Boi-centre-info">Inaktiv</div>
)}
{state === "bike" && (
<div className="Boi-centre-info">
<StateFilter current={state} required="stopped">
<Info>Inaktiv</Info>
</StateFilter>
<StateFilter current={state} required="bike">
<Info>
Velg sykkel (+/-): Velg sykkel (+/-):
<br/> <br/>
<b>{options[current].name}</b>
</div>
)}
{state === "program" && (
<div className="Boi-centre-info">
<b>{currentOptionName()}</b>
</Info>
</StateFilter>
<StateFilter current={state} required="program">
<Info>
Velg program (+/-): Velg program (+/-):
<br/> <br/>
<b>{options[current].name}</b>
</div>
)}
{state === "connected" && (
<table className="Boi-centre-info">
<tr>
<td>Enter:</td>
<td><b>Start</b></td>
</tr>
<tr>
<td>Esc:</td>
<td><b>Avslutt</b></td>
</tr>
</table>
)}
{state === "unknown" && (
<div className="Boi-centre-info">Noe gikk galt</div>
)}
<b>{currentOptionName()}</b>
</Info>
</StateFilter>
<StateFilter current={state} required="connected">
<InfoTable keyValuePairs={[
{key: "Enter", value: "Start"},
{key: "Escape", value: "Avslutt"},
]}/>
</StateFilter>
<StateFilter current={state} required="disconnected">
<Info>Kobler til...</Info>
</StateFilter>
<StateFilter current={state} required="started">
<Info>Abonnerer WS...</Info>
</StateFilter>
<StateFilter current={state} required="unknown">
<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;
} }

39
my-bois/src/components/Contexts.jsx

@ -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]);
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}});
}
}
}, [socket, workout, program, msDispatch]);
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}

10
my-bois/src/components/Milestones.jsx

@ -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-calories">{calories}</td>
<td className="Milestone-diff">{minutes % 5 === 0 ? diffString(diff) : ""}</td>
<td className="Milestone-minutes">&nbsp;{minutes}</td>
<td className="Milestone-calories">&nbsp;{calories}</td>
<td className="Milestone-diff">&nbsp;{minutes % 5 === 0 ? diffString(diff) : ""}</td>
</tr> </tr>
); );

13
my-bois/src/components/Misc.css

@ -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;
}

35
my-bois/src/components/Misc.jsx

@ -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>
);

2
my-bois/src/hooks/milestones.js

@ -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) {

4
my-bois/src/hooks/useKey.js

@ -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();
} }

Loading…
Cancel
Save