display yesterdays ranks

This commit is contained in:
HF 2022-09-24 16:25:41 +02:00
parent 54627ec4f1
commit c0186d3101
7 changed files with 190 additions and 61 deletions

View File

@ -5,18 +5,23 @@
/* eslint-disable max-len */
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { shallowEqual, useSelector } from 'react-redux';
import { t } from 'ttag';
import { selectStats } from '../store/selectors/ranks';
const Rankings = () => {
const [orderDaily, setOrderDaily] = useState(false);
const totalRanking = useSelector(
(state) => state.ranks.totalRanking,
);
const totalDailyRanking = useSelector(
(state) => state.ranks.totalDailyRanking,
);
const [area, setArea] = useState('total');
const [
totalRanking,
totalDailyRanking,
dailyCRanking,
prevTop,
onlineStats,
cHistStats,
histStats,
] = useSelector(selectStats, shallowEqual);
return (
<>
@ -25,65 +30,124 @@ const Rankings = () => {
role="button"
tabIndex={-1}
className={
(!orderDaily) ? 'modallink selected' : 'modallink'
(area === 'total') ? 'modallink selected' : 'modallink'
}
onClick={() => setOrderDaily(false)}
onClick={() => setArea('total')}
>{t`Total`}</span>
<span className="hdivider" />
<span
role="button"
tabIndex={-1}
className={
(orderDaily) ? 'modallink selected' : 'modallink'
(area === 'today') ? 'modallink selected' : 'modallink'
}
onClick={() => setOrderDaily(true)}
>{t`Daily`}</span>
onClick={() => setArea('today')}
>{t`Today`}</span>
<span className="hdivider" />
<span
role="button"
tabIndex={-1}
className={
(area === 'yesterday') ? 'modallink selected' : 'modallink'
}
onClick={() => setArea('yesterday')}
>{t`Yesterday`}</span>
<span className="hdivider" />
<span
role="button"
tabIndex={-1}
className={
(area === 'countries') ? 'modallink selected' : 'modallink'
}
onClick={() => setArea('countries')}
>{t`Countries Today`}</span>
</div>
<table style={{
display: 'inline',
}}
>
<thead>
{(orderDaily) ? (
<tr>
<th>#</th>
<th>user</th>
<th>Pixels</th>
<th># Total</th>
<th>Total Pixels</th>
</tr>
) : (
<tr>
<th>#</th>
<th>user</th>
<th>Pixels</th>
<th># Today</th>
<th>Pixels Today</th>
</tr>
)}
</thead>
<tbody>
{(orderDaily)
? totalDailyRanking.map((rank) => (
<tr key={rank.name}>
<td>{rank.dr}</td>
<td><span>{rank.name}</span></td>
<td>{rank.dt}</td>
<td>{rank.r}</td>
<td>{rank.t}</td>
</tr>
))
: totalRanking.map((rank) => (
<tr key={rank.name}>
<td>{rank.r}</td>
<td><span>{rank.name}</span></td>
<td>{rank.t}</td>
<td>{rank.dr}</td>
<td>{rank.dt}</td>
</tr>
))}
</tbody>
</table>
{(['total', 'today', 'yesterday', 'countries'].includes(area)) && (
<table style={{
display: 'inline',
}}
>
<thead>
{{
total: (
<tr>
<th>#</th>
<th>{t`User`}</th>
<th>Pixels</th>
<th># Today</th>
<th>Pixels Today</th>
</tr>
),
today: (
<tr>
<th>#</th>
<th>{t`User`}</th>
<th>Pixels</th>
<th># Total</th>
<th>Total Pixels</th>
</tr>
),
yesterday: (
<tr>
<th>#</th>
<th>{t`User`}</th>
<th>Pixels</th>
</tr>
),
countries: (
<tr>
<th>#</th>
<th>{t`Country`}</th>
<th>Pixels</th>
</tr>
),
}[area]}
</thead>
<tbody>
{{
total: totalRanking.map((rank) => (
<tr key={rank.name}>
<td>{rank.r}</td>
<td><span>{rank.name}</span></td>
<td>{rank.t}</td>
<td>{rank.dr}</td>
<td>{rank.dt}</td>
</tr>
)),
today: totalDailyRanking.map((rank) => (
<tr key={rank.name}>
<td>{rank.dr}</td>
<td><span>{rank.name}</span></td>
<td>{rank.dt}</td>
<td>{rank.r}</td>
<td>{rank.t}</td>
</tr>
)),
yesterday: prevTop.map((rank, ind) => (
<tr key={rank.name}>
<td>{ind + 1}</td>
<td><span>{rank.name}</span></td>
<td>{rank.px}</td>
</tr>
)),
countries: prevTop.map((rank, ind) => (
<tr key={rank.name}>
<td>{ind + 1}</td>
<td title={rank.cc}><img
style={{
height: '1em',
imageRendering: 'crisp-edges',
}}
alt={rank.cc}
src={`/cf/${rank.cc}.gif`}
/></td>
<td>{rank.px}</td>
</tr>
)),
}[area]}
</tbody>
</table>
)}
<p>
{t`Ranking updates every 5 min. Daily rankings get reset at midnight UTC.`}
</p>

View File

@ -10,6 +10,7 @@ import {
getOnlineUserStats,
storeOnlinUserAmount,
getCountryDailyHistory,
getCountryRanks,
getTopDailyHistory,
} from '../data/redis/ranks';
import socketEvents from '../socket/socketEvents';
@ -23,6 +24,7 @@ class Ranks {
this.ranks = {
dailyRanking: [],
ranking: [],
dailyCRanking: [],
prevTop: [],
onlineStats: [],
cHistStats: [],
@ -78,9 +80,11 @@ class Ranks {
1,
100,
));
const dailyCRanking = await getCountryRanks(1, 100);
const ret = {
ranking,
dailyRanking,
dailyCRanking,
};
socketEvents.rankingListUpdate(ret);
return ret;

View File

@ -80,6 +80,21 @@ export async function getRanks(daily, start, amount) {
return ret;
}
/*
* get daily country ranking
*/
export async function getCountryRanks(start, amount) {
let ranks = await client.zRangeWithScores(
DAILY_CRANKED_KEY, start, start + amount, {
REV: true,
});
ranks = ranks.map((r) => ({
cc: r.value,
px: Number(r.score),
}));
return ranks;
}
/*
* get top 10 from previous day
*/

View File

@ -271,11 +271,24 @@ export function receiveMe(
export function receiveStats(
rankings,
) {
const { ranking: totalRanking, dailyRanking: totalDailyRanking } = rankings;
const {
ranking: totalRanking,
dailyRanking: totalDailyRanking,
dailyCRanking,
prevTop,
onlineStats,
cHistStats,
histStats,
} = rankings;
return {
type: 'REC_STATS',
totalRanking,
totalDailyRanking,
dailyCRanking,
prevTop,
onlineStats,
cHistStats,
histStats,
};
}

View File

@ -17,6 +17,11 @@ const initialState = {
},
totalRanking: [],
totalDailyRanking: [],
dailyCRanking: [],
prevTop: [],
onlineStats: [],
cHistStats: [],
histStats: [],
};
export default function ranks(
@ -70,13 +75,26 @@ export default function ranks(
}
case 'REC_STATS': {
const { totalRanking, totalDailyRanking } = action;
const {
totalRanking,
totalDailyRanking,
dailyCRanking,
prevTop,
onlineStats,
cHistStats,
histStats,
} = action;
const lastFetch = Date.now();
return {
...state,
lastFetch,
totalRanking,
totalDailyRanking,
dailyCRanking,
prevTop,
onlineStats,
cHistStats,
histStats,
};
}

View File

@ -0,0 +1,15 @@
/*
* selectors for ranks
*/
/* eslint-disable import/prefer-default-export */
export const selectStats = (state) => [
state.ranks.totalRanking,
state.ranks.totalDailyRanking,
state.ranks.dailyCRanking,
state.ranks.prevTop,
state.ranks.onlineStats,
state.ranks.cHistStats,
state.ranks.histStats,
];

View File

@ -15,7 +15,7 @@ import canvas from './reducers/canvas';
import chat from './reducers/chat';
import fetching from './reducers/fetching';
export const CURRENT_VERSION = 11;
export const CURRENT_VERSION = 12;
export const migrate = (state, version) => {
// eslint-disable-next-line no-underscore-dangle