diff --git a/webapp/src/App.js b/webapp/src/App.js
index 3aa63ee..80f2778 100644
--- a/webapp/src/App.js
+++ b/webapp/src/App.js
@@ -1,31 +1,34 @@
import './App.css';
-import React, { useReducer } from 'react'
-import { BrowserRouter, Routes, Route } from "react-router-dom"
+import React from 'react';
+import { BrowserRouter, Routes, Route } from "react-router-dom";
import Header from "./container/Header"
import Leaderboard from "./container/Leaderboard"
import Game from "./components/Game"
import About from "./components/About"
-import Polling from './flux/polling';
-import User from './flux/user';
+import usePollingReducer from './reducer/polling';
+import useUserReducer from './reducer/user';
+import useLeaderboardReducer from './reducer/leaderboard';
+
import useLeaderboardApi from './api/leaderboard';
import useUserApi from './api/user';
function App() {
- const pollingFlux = useReducer(Polling.reducer, Polling.initialState);
- const userFlux = useReducer(User.reducer, User.initialState);
+ const pollingReducer = usePollingReducer();
+ const userReducer = useUserReducer();
+ const leaderboardReducer = useLeaderboardReducer();
- const leaderboardApi = useLeaderboardApi(pollingFlux);
- const userApi = useUserApi(userFlux);
+ const leaderboardApi = useLeaderboardApi(leaderboardReducer);
+ const userApi = useUserApi(userReducer);
- const leaderboard = leaderboardApi.get();
+ const leaderboard = leaderboardApi.get(pollingReducer);
const user = userApi.get();
return (
-
+
{/* https://stackoverflow.com/questions/40541994/multiple-path-names-for-a-same-component-in-react-router */}
} />
diff --git a/webapp/src/api/leaderboard.js b/webapp/src/api/leaderboard.js
index d32b4b6..1b7ca18 100644
--- a/webapp/src/api/leaderboard.js
+++ b/webapp/src/api/leaderboard.js
@@ -2,19 +2,26 @@ import usePolling from "../util/Polling"
const uri = '/api/leaderboard';
-export default function useLeaderboardApi([polling, dispatchPolling]) {
+export default function useLeaderboardApi(leaderboardReducer) {
+ const [leaderboard, dispatchLeaderboaed] = leaderboardReducer;
+
+ const useGet = (pollingReducer) => {
+ const [polling, dispatchPolling] = pollingReducer;
- const useGet = () => {
const mode = (polling.enabled === true)
? { interval_sec: 300 } // update leaderbord stats every 5 min
: { interval_stop: true } // user has fliped OfflineToggel
- const [leaderboard, isFetching] = usePolling(uri, mode);
+ const [table, isFetching] = usePolling(uri, mode);
if (polling.leaderboard !== isFetching) {
dispatchPolling({ type: 'next', leaderboard: isFetching });
}
+ if (leaderboard.table !== table) {
+ dispatchLeaderboaed({ type: 'next', table });
+ }
+
return leaderboard;
}
diff --git a/webapp/src/container/Header.jsx b/webapp/src/container/Header.jsx
index 72f52bf..dc4d2a0 100644
--- a/webapp/src/container/Header.jsx
+++ b/webapp/src/container/Header.jsx
@@ -4,8 +4,8 @@ import { NavLink } from "react-router-dom";
import OnlineToggle from '../components/OnlineToggle';
import Wobler from '../components/Wobler';
-export default function Header({ pollingFlux }) {
- const [polling, dispatchPolling] = pollingFlux;
+export default function Header({ pollingReducer }) {
+ const [polling, dispatchPolling] = pollingReducer;
return (
@@ -33,4 +33,4 @@ export default function Header({ pollingFlux }) {
)
-}
+}
\ No newline at end of file
diff --git a/webapp/src/container/Leaderboard.jsx b/webapp/src/container/Leaderboard.jsx
index 44e338b..54457c7 100644
--- a/webapp/src/container/Leaderboard.jsx
+++ b/webapp/src/container/Leaderboard.jsx
@@ -4,14 +4,15 @@ import Loading from '../components/Loading';
export default function Leaderboard({ leaderboard, user }) {
- if (leaderboard == null)
+ const table = leaderboard?.table;
+ if (!table)
return
const isCurrentUser = (playerName) =>
- user.isCurrentUser(playerName) === true ? true : null;
+ user?.isCurrentUser(playerName) === true ? true : null;
- const tableRows = Object.keys(leaderboard).map(playerName => {
- var rank = leaderboard[playerName];
+ const tableRows = Object.keys(table).map(playerName => {
+ var rank = table[playerName];
return
{playerName} |
diff --git a/webapp/src/flux/user.js b/webapp/src/flux/user.js
deleted file mode 100644
index 0d286cd..0000000
--- a/webapp/src/flux/user.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { localeCompare } from '../util/Locale'
-import StateHelper from '../util/StateHelper';
-
-export const userInitialState = {
- username: '',
- isCurrentUser: function (otherUsername) {
- return localeCompare(this.username, otherUsername)
- },
-
-};
-
-export function userReducer(state, action) {
- switch (action.type) {
-
- case 'next':
- return StateHelper.next(state, action);
-
- default:
- throw Error('Unknown action.type: ' + action.type);
- }
-}
-
-const User = {
- reducer: userReducer,
- initialState: userInitialState
-};
-
-export default User;
\ No newline at end of file
diff --git a/webapp/src/reducer/leaderboard.js b/webapp/src/reducer/leaderboard.js
new file mode 100644
index 0000000..06352a4
--- /dev/null
+++ b/webapp/src/reducer/leaderboard.js
@@ -0,0 +1,21 @@
+import { useReducer } from 'react';
+import { nextState } from '../util/StateHelper';
+
+export const leaderboardInitialState = {
+ table: null,
+};
+
+export function leaderboardReducer(state, action) {
+ switch (action.type) {
+
+ case 'next':
+ return nextState(state, action);
+
+ default:
+ throw Error('LeaderboardReducer: Unknown action.type', action.type);
+ }
+}
+
+export default function useLeaderboardReducer() {
+ return useReducer(leaderboardReducer, leaderboardInitialState);
+}
\ No newline at end of file
diff --git a/webapp/src/flux/polling.js b/webapp/src/reducer/polling.js
similarity index 77%
rename from webapp/src/flux/polling.js
rename to webapp/src/reducer/polling.js
index c4ce599..521f5c7 100644
--- a/webapp/src/flux/polling.js
+++ b/webapp/src/reducer/polling.js
@@ -1,4 +1,5 @@
-import { useLocalStorage } from '../util/PersistentStorage'
+import { useReducer } from 'react';
+import { useLocalStorage } from '../util/PersistentStorage';
import { nextState } from '../util/StateHelper';
const Persistent = (() => {
@@ -33,9 +34,6 @@ export function pollingReducer(curntState, action) {
}
}
-const Polling = {
- reducer: pollingReducer,
- initialState: pollingInitialState
-};
-
-export default Polling
\ No newline at end of file
+export default function usePollingReducer() {
+ return useReducer(pollingReducer, pollingInitialState);
+}
\ No newline at end of file
diff --git a/webapp/src/reducer/user.js b/webapp/src/reducer/user.js
new file mode 100644
index 0000000..4128100
--- /dev/null
+++ b/webapp/src/reducer/user.js
@@ -0,0 +1,26 @@
+import { useReducer } from 'react';
+import { localeCompare } from '../util/Locale';
+import { nextState } from '../util/StateHelper';
+
+export const userInitialState = {
+ username: '',
+
+ isCurrentUser: function (otherUsername) {
+ return localeCompare(this.username, otherUsername)
+ }
+};
+
+export function userReducer(state, action) {
+ switch (action.type) {
+
+ case 'next':
+ return nextState(state, action);
+
+ default:
+ throw Error('Unknown action.type', action.type);
+ }
+}
+
+export default function useUserReducer() {
+ return useReducer(userReducer, userInitialState);
+}
\ No newline at end of file
diff --git a/webapp/src/util/Polling.js b/webapp/src/util/Polling.js
index ed3fac6..49a1f9a 100644
--- a/webapp/src/util/Polling.js
+++ b/webapp/src/util/Polling.js
@@ -47,7 +47,7 @@ export default function usePolling(url, mode) {
}, [url, mode, isFetching, cache, fetchData, delayID]);
return [
- cache, // API response
+ cache, // API responce
isFetching // true / false
]
}