Skip to content

Commit dd13daa

Browse files
move logic to the context provider
1 parent 34c73e1 commit dd13daa

File tree

5 files changed

+70
-59
lines changed

5 files changed

+70
-59
lines changed

ui/src/components/HoldToPour.js

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import React, { useState, useEffect } from 'react';
22
import { connect } from 'react-redux';
33
import { Container, Form } from 'react-bootstrap';
44
import { useWaterPumpAPI } from '../contexts/WaterPumpAPIContext';
5-
import { startPump, stopPump } from '../store/slices/SystemStatus.js';
65

7-
export function HoldToPourComponent({ startPump, stopPump, interval }) {
6+
export function HoldToPourComponent({ interval }) {
7+
const { API }= useWaterPumpAPI();
88
const [isPouring, setIsPouring] = useState(false);
99
const [clickToPour, setClickToPour] = useState(false);
1010
// continuously pour water while the button is pressed
@@ -14,28 +14,28 @@ export function HoldToPourComponent({ startPump, stopPump, interval }) {
1414
if(Date.now() < lastPouringTime.current) return;
1515
try {
1616
lastPouringTime.current = Number.MAX_SAFE_INTEGER; // prevent concurrent calls
17-
await startPump();
17+
await API.startPump();
1818
lastPouringTime.current = Date.now() + interval;
1919
} catch(e) {
2020
lastPouringTime.current = 0; // run again on next tick
2121
}
2222
},
23-
[startPump, interval]
23+
[interval, API]
2424
);
2525

2626
useEffect(() => {
2727
if(!isPouring) {
2828
lastPouringTime.current = 0;
29-
stopPump();
29+
API.stopPump();
3030
return;
3131
}
3232
// tick every 100ms
3333
const tid = setInterval(onTick, 100);
3434
return async () => {
3535
clearInterval(tid);
36-
if(isPouring) await stopPump();
36+
if(isPouring) await API.stopPump();
3737
};
38-
}, [onTick, isPouring, stopPump, lastPouringTime]);
38+
}, [onTick, isPouring, API]);
3939

4040
const handlePress = () => { setIsPouring(true); };
4141
const handleRelease = () => { setIsPouring(false); };
@@ -65,43 +65,18 @@ export function HoldToPourComponent({ startPump, stopPump, interval }) {
6565
}
6666

6767
// Helper wrapper to simplify the code in the component
68-
function HoldToPourComponent_withExtras({ pouringTime, powerLevel, startPump, stopPump }) {
69-
const api = useWaterPumpAPI().API;
70-
// to prevent the callback from changing when the pouringTime or powerLevel changes
71-
const _pouringTime = React.useRef(pouringTime);
72-
React.useEffect(() => { _pouringTime.current = pouringTime; }, [pouringTime]);
73-
74-
const _powerLevel = React.useRef(powerLevel);
75-
React.useEffect(() => { _powerLevel.current = powerLevel; }, [powerLevel]);
76-
77-
const _startPump = React.useCallback(
78-
async () => {
79-
await startPump({
80-
api,
81-
pouringTime: _pouringTime.current,
82-
powerLevel: _powerLevel.current,
83-
});
84-
}, [api, startPump, _pouringTime, _powerLevel]
85-
);
86-
const _stopPump = React.useCallback(
87-
async () => { await stopPump({ api }); },
88-
[api, stopPump]
89-
);
68+
function HoldToPourComponent_withExtras({ pouringTime, ...props }) {
9069
// a bit smaller than the actual pouring time, to prevent the pump from stopping
9170
// which could damage the pump
9271
const interval = Math.max(Math.round(pouringTime - 500), 100);
9372
return (
94-
<HoldToPourComponent
95-
startPump={_startPump} stopPump={_stopPump}
96-
interval={interval}
97-
/>
73+
<HoldToPourComponent {...props} interval={interval} />
9874
);
9975
};
10076

10177
export default connect(
10278
state => ({
10379
pouringTime: state.UI.pouringTime,
104-
powerLevel: state.UI.powerLevelInPercents,
10580
}),
106-
{ startPump, stopPump }
81+
{ }
10782
)(HoldToPourComponent_withExtras);

ui/src/components/SystemControls.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,11 @@ import { connect } from 'react-redux';
33
import { Button, Container } from 'react-bootstrap';
44

55
import { useWaterPumpAPI } from '../contexts/WaterPumpAPIContext';
6-
import { startPump, stopPump } from '../store/slices/SystemStatus.js';
76

8-
export function SystemControlsComponent({
9-
pouringTime, powerLevel, systemStatus, startPump, stopPump
10-
}) {
11-
const api = useWaterPumpAPI().API;
12-
const handleStart = async () => {
13-
await startPump({ api, pouringTime, powerLevel });
14-
};
15-
16-
const handleStop = async () => {
17-
await stopPump({ api });
18-
};
7+
export function SystemControlsComponent({ systemStatus }) {
8+
const { API } = useWaterPumpAPI();
9+
const handleStart = async () => { await API.startPump(); };
10+
const handleStop = async () => { await API.stopPump(); };
1911

2012
const isRunning = systemStatus.pump.running;
2113
return (
@@ -32,8 +24,6 @@ export function SystemControlsComponent({
3224

3325
export default connect(
3426
state => ({
35-
pouringTime: state.UI.pouringTime,
36-
powerLevel: state.UI.powerLevelInPercents,
3727
systemStatus: state.systemStatus,
38-
}), { startPump, stopPump }
28+
}), { }
3929
)(SystemControlsComponent);

ui/src/components/WaterPumpStatusProvider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function WaterPumpStatusProviderComoponent({ children, updateStatus, systemStatu
1717
if(null == API) return;
1818

1919
nextFetchTime.current = Number.MAX_SAFE_INTEGER; // prevent concurrent fetches
20-
await updateStatus(API);
20+
await updateStatus({ api: API });
2121
nextFetchTime.current = Date.now() + FETCH_INTERVAL;
2222
},
2323
[API, updateStatus, nextFetchTime]
Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { useSelector } from 'react-redux';
2+
import { connect } from 'react-redux';
3+
import { startPump, stopPump } from '../store/slices/SystemStatus.js';
34
import { CWaterPumpAPI } from '../api/CWaterPumpAPI.js';
45
import WaterPumpStatusProvider from '../components/WaterPumpStatusProvider.js';
56

@@ -9,20 +10,65 @@ export function useWaterPumpAPI() {
910
return React.useContext(WaterPumpAPIContext);
1011
}
1112

12-
export function WaterPumpAPIProvider({ children }) {
13-
const apiHost = useSelector((state) => state.UI.apiHost);
13+
function WaterPumpAPIProviderComponent({
14+
children,
15+
apiHost, pouringTime, powerLevel,
16+
startPump, stopPump,
17+
}) {
18+
// to prevent the callbacks from changing when the pouringTime or powerLevel changes
19+
const _pouringTime = React.useRef(pouringTime);
20+
React.useEffect(() => { _pouringTime.current = pouringTime; }, [pouringTime]);
21+
22+
const _powerLevel = React.useRef(powerLevel);
23+
React.useEffect(() => { _powerLevel.current = powerLevel; }, [powerLevel]);
24+
1425
const apiObject = React.useMemo(
1526
() => new CWaterPumpAPI({ URL: apiHost }),
1627
[apiHost]
1728
);
18-
// TODO: provide also the API methods with binded values from the store
19-
// to simplify the code in the components (HodlToPour and PowerLevel)
20-
const value = { API: apiObject, };
29+
////////////////
30+
// create an API wrapper that dispatches actions to the Redux store
31+
const value = React.useMemo(
32+
() => {
33+
if(null == apiObject) return { API: null };
34+
return {
35+
API: {
36+
stopPump: async () => {
37+
return await stopPump({ api: apiObject });
38+
},
39+
startPump: async () => {
40+
return await startPump({
41+
api: apiObject,
42+
pouringTime: _pouringTime.current,
43+
powerLevel: _powerLevel.current,
44+
});
45+
},
46+
status: async () => {
47+
return await apiObject.status();
48+
}
49+
}
50+
};
51+
},
52+
[apiObject, startPump, stopPump, _pouringTime, _powerLevel]
53+
);
54+
2155
return (
2256
<WaterPumpAPIContext.Provider value={value}>
2357
<WaterPumpStatusProvider>
2458
{children}
2559
</WaterPumpStatusProvider>
2660
</WaterPumpAPIContext.Provider>
2761
);
28-
}
62+
}
63+
64+
const WaterPumpAPIProvider = connect(
65+
state => ({
66+
apiHost: state.UI.apiHost,
67+
pouringTime: state.UI.pouringTime,
68+
powerLevel: state.UI.powerLevelInPercents,
69+
}),
70+
{ startPump, stopPump }
71+
)(WaterPumpAPIProviderComponent);
72+
73+
export default WaterPumpAPIProvider;
74+
export { WaterPumpAPIProvider };

ui/src/store/slices/SystemStatus.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const stopPump = createAsyncThunk(
3939
export const updateSystemStatus = createAsyncThunk(
4040
'systemStatus/update',
4141
withNotification(
42-
async ( api ) => {
42+
async ({ api }) => {
4343
return await api.status();
4444
},
4545
'Failed to update system status'

0 commit comments

Comments
 (0)