Merge branch 'devel'
This commit is contained in:
commit
a143e3737e
|
@ -5,18 +5,23 @@
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { shallowEqual, useSelector } from 'react-redux';
|
||||||
import { t } from 'ttag';
|
import { t } from 'ttag';
|
||||||
|
|
||||||
|
import { selectStats } from '../store/selectors/ranks';
|
||||||
|
|
||||||
|
|
||||||
const Rankings = () => {
|
const Rankings = () => {
|
||||||
const [orderDaily, setOrderDaily] = useState(false);
|
const [area, setArea] = useState('total');
|
||||||
const totalRanking = useSelector(
|
const [
|
||||||
(state) => state.ranks.totalRanking,
|
totalRanking,
|
||||||
);
|
totalDailyRanking,
|
||||||
const totalDailyRanking = useSelector(
|
dailyCRanking,
|
||||||
(state) => state.ranks.totalDailyRanking,
|
prevTop,
|
||||||
);
|
onlineStats,
|
||||||
|
cHistStats,
|
||||||
|
histStats,
|
||||||
|
] = useSelector(selectStats, shallowEqual);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -25,65 +30,124 @@ const Rankings = () => {
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
className={
|
className={
|
||||||
(!orderDaily) ? 'modallink selected' : 'modallink'
|
(area === 'total') ? 'modallink selected' : 'modallink'
|
||||||
}
|
}
|
||||||
onClick={() => setOrderDaily(false)}
|
onClick={() => setArea('total')}
|
||||||
>{t`Total`}</span>
|
>{t`Total`}</span>
|
||||||
<span className="hdivider" />
|
<span className="hdivider" />
|
||||||
<span
|
<span
|
||||||
role="button"
|
role="button"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
className={
|
className={
|
||||||
(orderDaily) ? 'modallink selected' : 'modallink'
|
(area === 'today') ? 'modallink selected' : 'modallink'
|
||||||
}
|
}
|
||||||
onClick={() => setOrderDaily(true)}
|
onClick={() => setArea('today')}
|
||||||
>{t`Daily`}</span>
|
>{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>
|
</div>
|
||||||
<table style={{
|
{(['total', 'today', 'yesterday', 'countries'].includes(area)) && (
|
||||||
display: 'inline',
|
<table style={{
|
||||||
}}
|
display: 'inline',
|
||||||
>
|
}}
|
||||||
<thead>
|
>
|
||||||
{(orderDaily) ? (
|
<thead>
|
||||||
<tr>
|
{{
|
||||||
<th>#</th>
|
total: (
|
||||||
<th>user</th>
|
<tr>
|
||||||
<th>Pixels</th>
|
<th>#</th>
|
||||||
<th># Total</th>
|
<th>{t`User`}</th>
|
||||||
<th>Total Pixels</th>
|
<th>Pixels</th>
|
||||||
</tr>
|
<th># Today</th>
|
||||||
) : (
|
<th>Pixels Today</th>
|
||||||
<tr>
|
</tr>
|
||||||
<th>#</th>
|
),
|
||||||
<th>user</th>
|
today: (
|
||||||
<th>Pixels</th>
|
<tr>
|
||||||
<th># Today</th>
|
<th>#</th>
|
||||||
<th>Pixels Today</th>
|
<th>{t`User`}</th>
|
||||||
</tr>
|
<th>Pixels</th>
|
||||||
)}
|
<th># Total</th>
|
||||||
</thead>
|
<th>Total Pixels</th>
|
||||||
<tbody>
|
</tr>
|
||||||
{(orderDaily)
|
),
|
||||||
? totalDailyRanking.map((rank) => (
|
yesterday: (
|
||||||
<tr key={rank.name}>
|
<tr>
|
||||||
<td>{rank.dr}</td>
|
<th>#</th>
|
||||||
<td><span>{rank.name}</span></td>
|
<th>{t`User`}</th>
|
||||||
<td>{rank.dt}</td>
|
<th>Pixels</th>
|
||||||
<td>{rank.r}</td>
|
</tr>
|
||||||
<td>{rank.t}</td>
|
),
|
||||||
</tr>
|
countries: (
|
||||||
))
|
<tr>
|
||||||
: totalRanking.map((rank) => (
|
<th>#</th>
|
||||||
<tr key={rank.name}>
|
<th>{t`Country`}</th>
|
||||||
<td>{rank.r}</td>
|
<th>Pixels</th>
|
||||||
<td><span>{rank.name}</span></td>
|
</tr>
|
||||||
<td>{rank.t}</td>
|
),
|
||||||
<td>{rank.dr}</td>
|
}[area]}
|
||||||
<td>{rank.dt}</td>
|
</thead>
|
||||||
</tr>
|
<tbody>
|
||||||
))}
|
{{
|
||||||
</tbody>
|
total: totalRanking.map((rank) => (
|
||||||
</table>
|
<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>
|
<p>
|
||||||
{t`Ranking updates every 5 min. Daily rankings get reset at midnight UTC.`}
|
{t`Ranking updates every 5 min. Daily rankings get reset at midnight UTC.`}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
getOnlineUserStats,
|
getOnlineUserStats,
|
||||||
storeOnlinUserAmount,
|
storeOnlinUserAmount,
|
||||||
getCountryDailyHistory,
|
getCountryDailyHistory,
|
||||||
|
getCountryRanks,
|
||||||
getTopDailyHistory,
|
getTopDailyHistory,
|
||||||
} from '../data/redis/ranks';
|
} from '../data/redis/ranks';
|
||||||
import socketEvents from '../socket/socketEvents';
|
import socketEvents from '../socket/socketEvents';
|
||||||
|
@ -23,6 +24,7 @@ class Ranks {
|
||||||
this.ranks = {
|
this.ranks = {
|
||||||
dailyRanking: [],
|
dailyRanking: [],
|
||||||
ranking: [],
|
ranking: [],
|
||||||
|
dailyCRanking: [],
|
||||||
prevTop: [],
|
prevTop: [],
|
||||||
onlineStats: [],
|
onlineStats: [],
|
||||||
cHistStats: [],
|
cHistStats: [],
|
||||||
|
@ -78,9 +80,11 @@ class Ranks {
|
||||||
1,
|
1,
|
||||||
100,
|
100,
|
||||||
));
|
));
|
||||||
|
const dailyCRanking = await getCountryRanks(1, 100);
|
||||||
const ret = {
|
const ret = {
|
||||||
ranking,
|
ranking,
|
||||||
dailyRanking,
|
dailyRanking,
|
||||||
|
dailyCRanking,
|
||||||
};
|
};
|
||||||
socketEvents.rankingListUpdate(ret);
|
socketEvents.rankingListUpdate(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -80,6 +80,21 @@ export async function getRanks(daily, start, amount) {
|
||||||
return ret;
|
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
|
* get top 10 from previous day
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -271,11 +271,24 @@ export function receiveMe(
|
||||||
export function receiveStats(
|
export function receiveStats(
|
||||||
rankings,
|
rankings,
|
||||||
) {
|
) {
|
||||||
const { ranking: totalRanking, dailyRanking: totalDailyRanking } = rankings;
|
const {
|
||||||
|
ranking: totalRanking,
|
||||||
|
dailyRanking: totalDailyRanking,
|
||||||
|
dailyCRanking,
|
||||||
|
prevTop,
|
||||||
|
onlineStats,
|
||||||
|
cHistStats,
|
||||||
|
histStats,
|
||||||
|
} = rankings;
|
||||||
return {
|
return {
|
||||||
type: 'REC_STATS',
|
type: 'REC_STATS',
|
||||||
totalRanking,
|
totalRanking,
|
||||||
totalDailyRanking,
|
totalDailyRanking,
|
||||||
|
dailyCRanking,
|
||||||
|
prevTop,
|
||||||
|
onlineStats,
|
||||||
|
cHistStats,
|
||||||
|
histStats,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,11 @@ const initialState = {
|
||||||
},
|
},
|
||||||
totalRanking: [],
|
totalRanking: [],
|
||||||
totalDailyRanking: [],
|
totalDailyRanking: [],
|
||||||
|
dailyCRanking: [],
|
||||||
|
prevTop: [],
|
||||||
|
onlineStats: [],
|
||||||
|
cHistStats: [],
|
||||||
|
histStats: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ranks(
|
export default function ranks(
|
||||||
|
@ -70,13 +75,26 @@ export default function ranks(
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'REC_STATS': {
|
case 'REC_STATS': {
|
||||||
const { totalRanking, totalDailyRanking } = action;
|
const {
|
||||||
|
totalRanking,
|
||||||
|
totalDailyRanking,
|
||||||
|
dailyCRanking,
|
||||||
|
prevTop,
|
||||||
|
onlineStats,
|
||||||
|
cHistStats,
|
||||||
|
histStats,
|
||||||
|
} = action;
|
||||||
const lastFetch = Date.now();
|
const lastFetch = Date.now();
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
lastFetch,
|
lastFetch,
|
||||||
totalRanking,
|
totalRanking,
|
||||||
totalDailyRanking,
|
totalDailyRanking,
|
||||||
|
dailyCRanking,
|
||||||
|
prevTop,
|
||||||
|
onlineStats,
|
||||||
|
cHistStats,
|
||||||
|
histStats,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/store/selectors/ranks.js
Normal file
15
src/store/selectors/ranks.js
Normal 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,
|
||||||
|
];
|
|
@ -15,7 +15,7 @@ import canvas from './reducers/canvas';
|
||||||
import chat from './reducers/chat';
|
import chat from './reducers/chat';
|
||||||
import fetching from './reducers/fetching';
|
import fetching from './reducers/fetching';
|
||||||
|
|
||||||
export const CURRENT_VERSION = 11;
|
export const CURRENT_VERSION = 12;
|
||||||
|
|
||||||
export const migrate = (state, version) => {
|
export const migrate = (state, version) => {
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
|
Loading…
Reference in New Issue
Block a user