diff --git a/src/components/App.js b/src/components/App.js index eee5e34..fe76894 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,7 +1,6 @@ import React from 'react'; import AppContextProvider from './ContextProvider'; - import Pool from './Pool'; import '../static/css/main.css'; diff --git a/src/components/ContextProvider.js b/src/components/ContextProvider.js index 1c9af43..035f8ad 100644 --- a/src/components/ContextProvider.js +++ b/src/components/ContextProvider.js @@ -12,11 +12,24 @@ const AppContextProvider = props => { const Api = new ApiHelper({ state }); + const getNetworkStats = () => { + return Api.getNetworkStats() + .then(networkStats => { + dispatch({ type: 'UPDATE_NETWORK_STATS', networkStats }); + }); + }; + const getPoolConfig = () => { - Api.getPoolConfig() + return Api.getPoolConfig() .then(config => { dispatch({ type: 'UPDATE_POOL_CONFIG', config }); - dispatch({ type: 'APP_LOADED', appLoaded: true }); + }); + }; + + const getPoolStats = () => { + return Api.getPoolStats() + .then(stats => { + dispatch({ type: 'UPDATE_POOL_STATS', stats }); }); }; @@ -24,8 +37,25 @@ const AppContextProvider = props => { getPoolConfig, }; + const setIntervals = () => { + const { appSettings } = state; + const intervals = [ + { fn: getPoolStats, time: appSettings.poolStatsUpdateInterval }, + { fn: getNetworkStats, time: appSettings.networkUpdateInterval }, + ]; + dispatch({ type: 'SET_INTERVALS', intervals }); + } + useEffectOnce(() => { - getPoolConfig(); + getPoolConfig().then(() => + getPoolStats().then(() => + getNetworkStats().then(() => { + // initial API responses completed, app ready now + setIntervals(); + dispatch({type: 'APP_LOADED', appLoaded: true}); + }) + ) + ); }) return ( diff --git a/src/components/Pool.js b/src/components/Pool.js index 97deb91..3a1df9d 100644 --- a/src/components/Pool.js +++ b/src/components/Pool.js @@ -1,10 +1,42 @@ -import React from 'react'; +import React, { useContext } from 'react'; +import { AppContext } from './ContextProvider'; +import { ToCoins, ToDate, ToHashes } from '../helpers/utils'; -const Pool = () => ( -
-

welcome good friend <3 thank so much for mining!

-
-); + +const Pool = () => { + const { state } = useContext(AppContext); + const { pool } = state; + const { config, networkStats, stats } = pool; + const { pool_statistics: poolStats } = stats; + + const networkHashRate = Math.floor(networkStats.difficulty / 300); + const poolPercentage = poolStats.hashRate / networkHashRate * 100; + + return ( +
+

wow!

+ +
+ +

welcome good friend <3 thank so much for mining!

+

very mining with you from blocke 62

+

such good pool:

+ + +
+ +

all wow miners:

+

this pool miners: {poolStats.miners} miners digging (only {poolPercentage.toFixed(2)}%)

+

world blocke: {networkStats.height} with discovered {}

+

pool blocke: {poolStats.lastBlockFound} discovered {}

+
+ ) +}; export default Pool; diff --git a/src/components/useAppState.js b/src/components/useAppState.js index 1dea0c2..8c72b0b 100644 --- a/src/components/useAppState.js +++ b/src/components/useAppState.js @@ -6,14 +6,21 @@ const initialState = () => ({ apiURL: 'https://pool.wowne.ro/api', appLoaded: false, coinDecimals: 11, + coinSymbol: 9077, // hex 2375 (⍵) https://git.wownero.com/wownero/meta/issues/2 + networkUpdateInterval: 15, + poolStatsUpdateInterval: 30, }, + intervals: [], + messages: {}, pool: { config: null, + hasAids: false, + networkStats: null, + stats: null, }, user: { loggedIn: false, }, - messages: {}, }); let updatedState; @@ -23,6 +30,9 @@ const reducer = (state, action) => { const { appLoaded, config, + hasAids, + networkStats, + stats, loggedIn, } = action; @@ -36,8 +46,12 @@ const reducer = (state, action) => { }, }; break; - case 'CLEAR_MESSAGES': - result = { ...state, messages: {} }; + case 'SET_INTERVALS': + const intervals = action.intervals.map(i => setInterval(i.fn, i.time * 1000)); + result = { + ...state, + intervals, + }; break; case 'USER_LOGGED_IN': result = { ...state, user: { loggedIn } }; @@ -51,6 +65,43 @@ const reducer = (state, action) => { } }; break; + case 'UPDATE_POOL_STATS': + result = { + ...state, + pool: { + ...state.pool, + stats, + } + }; + break; + case 'UPDATE_NETWORK_STATS': + result = { + ...state, + pool: { + ...state.pool, + networkStats, + } + }; + break; + case 'CLEAR_APP': + state.intervals.forEach(interval => clearInterval(interval)); + result = { + ...state, + intervals: [], + }; + break; + case 'CLEAR_MESSAGES': + result = { ...state, messages: {} }; + break; + case 'HAS_AIDS': + result = { + ...state, + pool: { + ...state.pool, + hasAids, + } + } + break; default: throw new Error(); } diff --git a/src/helpers/ApiHelper.js b/src/helpers/ApiHelper.js index ba4359c..6c0d6eb 100644 --- a/src/helpers/ApiHelper.js +++ b/src/helpers/ApiHelper.js @@ -3,11 +3,21 @@ export default class ApiHelper { this.apiURL = options.state.appSettings.apiURL; } + getNetworkStats = () => { + return this.fetch(`${this.apiURL}/network/stats`, { method: 'GET' }) + .then(res => Promise.resolve(res)); + } + getPoolConfig = () => { return this.fetch(`${this.apiURL}/config`, { method: 'GET' }) .then(res => Promise.resolve(res)); } + getPoolStats = () => { + return this.fetch(`${this.apiURL}/pool/stats`, { method: 'GET' }) + .then(res => Promise.resolve(res)); + } + fetch = (url, options) => { const headers = options.headers || { Accept: 'application/json', diff --git a/src/helpers/utils.js b/src/helpers/utils.js new file mode 100644 index 0000000..bbfe7a1 --- /dev/null +++ b/src/helpers/utils.js @@ -0,0 +1,28 @@ +import React, { useContext } from 'react'; + +import { AppContext } from '../components/ContextProvider'; + + +export const ToCoins = props => { + const { state } = useContext(AppContext); + const { appSettings } = state; + const { coins, symbol } = props; + + return (<>{coins / Math.pow(10, appSettings.coinDecimals)} {symbol || String.fromCharCode(appSettings.coinSymbol)}); +} + +export const ToDate = props => { + const { timeStamp } = props; + return (<>{new Date(timeStamp * 1000).toLocaleString()}); +} + +export const ToHashes = props => { + const { hashes, suffix = 'hashes' } = props; + + let res = `${(hashes || 0)} ${suffix}`; + if (hashes > 1e3) res = `${parseFloat((hashes / 1e3).toFixed(2))} kilo${suffix}`; + if (hashes > 1e6) res = `${parseFloat((hashes / 1e6).toFixed(2))} mega${suffix}`; + if (hashes > 1e9) res = `${parseFloat((hashes / 1e9).toFixed(2))} giga${suffix}`; + + return (<>{res}); +} diff --git a/src/static/css/main.css b/src/static/css/main.css index 5b7e679..80c9e42 100644 --- a/src/static/css/main.css +++ b/src/static/css/main.css @@ -1,3 +1,5 @@ -body { +@import url('https://fonts.googleapis.com/css2?family=Gaegu:wght@300&display=swap'); +body { + font-family: 'Gaegu', cursive; }