React: make Poll into a hook
This commit is contained in:
parent
5821a02ba1
commit
c884494618
@ -9,10 +9,7 @@ import {
|
|||||||
import Header from "./components/Header"
|
import Header from "./components/Header"
|
||||||
import Leaderboard from "./components/Leaderboard"
|
import Leaderboard from "./components/Leaderboard"
|
||||||
import GameProposal from "./components/GameProposal"
|
import GameProposal from "./components/GameProposal"
|
||||||
import DataPolling from './components/DataPolling';
|
import DataPolling from './components/OfflineToggle';
|
||||||
|
|
||||||
//import { UserProvider } from "../contexts/UserProvider"
|
|
||||||
//import { GameProposalProvider } from './context/GameProposal';
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import React from "react"
|
|
||||||
import { AppData } from "../../context/data"
|
|
||||||
import { AppContext } from "../../context/app"
|
|
||||||
|
|
||||||
export default function DataPolling() {
|
|
||||||
const [appData, dispatchData] = React.useContext(AppData)
|
|
||||||
//const [appCtx, dispatchAppData] = React.useContext(AppContext)
|
|
||||||
|
|
||||||
return <div className={DataPolling.name}>
|
|
||||||
polling
|
|
||||||
<button onClick={() => dispatchData({type: "togglePolling"})}>
|
|
||||||
{ appData.disablePolling === true ? "off" : "on" }
|
|
||||||
</button>
|
|
||||||
{ appData.fetching }
|
|
||||||
</div>
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import Reject from './Reject'
|
|||||||
import Cancel from './GameProposalCancel'
|
import Cancel from './GameProposalCancel'
|
||||||
|
|
||||||
import { AppData } from "../../context/data"
|
import { AppData } from "../../context/data"
|
||||||
|
//import { AppContext } from "../../context/app"
|
||||||
|
|
||||||
export default function GameProposal() {
|
export default function GameProposal() {
|
||||||
const [data] = React.useContext(AppData)
|
const [data] = React.useContext(AppData)
|
||||||
|
12
webapp/src/components/OfflineToggle/index.jsx
Normal file
12
webapp/src/components/OfflineToggle/index.jsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { AppData } from "../../context/data"
|
||||||
|
|
||||||
|
export default function OfflineToggle() {
|
||||||
|
const [appData, dispatchData] = React.useContext(AppData)
|
||||||
|
|
||||||
|
return <div className="OfflineToggle">
|
||||||
|
<button onClick={() => dispatchData({type: "toggleOfflineMode"})}>
|
||||||
|
{ appData.offlineMode === true ? "offline" : "online" }
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
@ -9,8 +9,8 @@ import { useState, useCallback, useEffect, } from "react"
|
|||||||
- stop
|
- stop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function Poll(url, interval_sec, disabled) {
|
export default function Poll(url, interval_sec, offlineMode) {
|
||||||
const [cache, setCache] = useState(null)
|
const [dataCache, setDataCache] = useState(null)
|
||||||
const [fetching, setFetching] = useState(false)
|
const [fetching, setFetching] = useState(false)
|
||||||
const [timeoutID, setTimeoutID] = useState(null)
|
const [timeoutID, setTimeoutID] = useState(null)
|
||||||
|
|
||||||
@ -23,27 +23,24 @@ export default function Poll(url, interval_sec, disabled) {
|
|||||||
setFetching(false)
|
setFetching(false)
|
||||||
return response.json()
|
return response.json()
|
||||||
})
|
})
|
||||||
.then((freshData) => setCache(freshData))
|
.then((freshData) => setDataCache(freshData))
|
||||||
.catch((err) => console.log(err.message))
|
.catch((err) => console.log(err.message))
|
||||||
}, [url])
|
}, [url])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cache == null) {
|
if (dataCache == null) {
|
||||||
fecthData() // <<-- run immediatly on startup
|
fecthData() // <<-- run immediatly on startup
|
||||||
}
|
}
|
||||||
else if (disabled === true) {
|
else if (offlineMode === true) {
|
||||||
clearTimeout(timeoutID) // cancel already scheduled fetch
|
clearTimeout(timeoutID) // cancel already scheduled fetch
|
||||||
setTimeoutID(null)
|
setTimeoutID(null) // & stop interval fetching
|
||||||
}
|
}
|
||||||
else if (timeoutID === null) {
|
else if (timeoutID === null) {
|
||||||
const timeoutID = setTimeout(fecthData, interval_sec * 1000)
|
const timeoutID = setTimeout(fecthData, interval_sec * 1000)
|
||||||
setTimeoutID(timeoutID)
|
setTimeoutID(timeoutID)
|
||||||
console.log("Fetch '" +url +"' scheduled in " +interval_sec +" sec")
|
console.log("Fetch '" +url +"' scheduled in " +interval_sec +" sec")
|
||||||
}
|
}
|
||||||
}, [url, cache, fecthData, timeoutID, disabled, interval_sec]);
|
}, [url, dataCache, fecthData, timeoutID, offlineMode, interval_sec]);
|
||||||
|
|
||||||
return {
|
return [ dataCache, fetching ]
|
||||||
data: cache,
|
|
||||||
fetching
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,19 +12,14 @@ export const AppDataProvider = ({ children }) => {
|
|||||||
|
|
||||||
const [data, dispatchData] = React.useReducer(reducer, initialState)
|
const [data, dispatchData] = React.useReducer(reducer, initialState)
|
||||||
|
|
||||||
const games = Poll('api/gamestate', 30, data.disablePolling)
|
const [games, gamesFetching ] = Poll('api/gamestate' , 30, data.offlineMode)
|
||||||
const leaderboard = Poll('api/leaderboard', 60, data.disablePolling)
|
const [leaderboard, leaderboardFetching ] = Poll('api/leaderboard', 60, data.offlineMode)
|
||||||
|
|
||||||
data.games = games.data
|
data.games = games
|
||||||
data.leaderboard = leaderboard.data
|
data.gamesFetching = gamesFetching
|
||||||
|
|
||||||
var fetching = []
|
data.leaderboard = leaderboard
|
||||||
if (games.fetching === true)
|
data.leaderboardFetching = leaderboardFetching
|
||||||
fetching = [...fetching, "games"]
|
|
||||||
if (leaderboard.fetching === true)
|
|
||||||
fetching = [...fetching, "leaderboard"]
|
|
||||||
|
|
||||||
data.fetching = fetching
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppData.Provider value={[data, dispatchData]}>
|
<AppData.Provider value={[data, dispatchData]}>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
export const reducer = (state, action) => {
|
export const reducer = (state, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
|
||||||
case "togglePolling":
|
case "toggleOfflineMode":
|
||||||
return { ...state,
|
return { ...state,
|
||||||
disablePolling: !state.disablePolling // on/off
|
offlineMode: !state.offlineMode // on/off
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -14,8 +14,10 @@ export const reducer = (state, action) => {
|
|||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
games: null,
|
games: null,
|
||||||
leaderboard: null,
|
gamesFetching: false,
|
||||||
|
|
||||||
disablePolling: false,
|
leaderboard: null,
|
||||||
fetching: []
|
leaderboardFetching: false,
|
||||||
|
|
||||||
|
offlineMode: false
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user