add option to set profile private

This commit is contained in:
HF 2022-09-26 23:19:14 +02:00
parent b432f193ca
commit b441c76c47
12 changed files with 160 additions and 30 deletions

View File

@ -3,32 +3,52 @@
*/ */
import React from 'react'; import React from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { t } from 'ttag'; import { t } from 'ttag';
import { import {
setBlockingDm, setBlockingDm,
setPrivatize,
setUserBlock, setUserBlock,
} from '../store/actions/thunks'; } from '../store/actions/thunks';
import SettingsItem from './SettingsItem'; import SettingsItem from './SettingsItem';
const selectBlocks = (state) => [
state.chat.blocked,
state.user.blockDm,
state.user.priv,
state.fetching.fetchingApi,
];
const SocialSettings = ({ done }) => { const SocialSettings = ({ done }) => {
const blocked = useSelector((state) => state.chat.blocked); const [
const blockDm = useSelector((state) => state.user.blockDm); blocked,
const fetching = useSelector((state) => state.fetching.fetchingApi); blockDm,
priv,
fetching,
] = useSelector(selectBlocks, shallowEqual);
const dispatch = useDispatch(); const dispatch = useDispatch();
return ( return (
<div className="inarea"> <div className="inarea">
<SettingsItem <SettingsItem
title={t`Block all Private Messages`} title={t`Block DMs`}
value={blockDm} value={blockDm}
onToggle={() => { onToggle={() => {
if (!fetching) { if (!fetching) {
dispatch(setBlockingDm(!blockDm)); dispatch(setBlockingDm(!blockDm));
} }
}} }}
/> >{t`Block all Private Messages`}</SettingsItem>
<SettingsItem
title={t`Private`}
value={priv}
onToggle={() => {
if (!fetching) {
dispatch(setPrivatize(!priv));
}
}}
>{t`Don't show me in global stats`}</SettingsItem>
<h3 <h3
style={{ style={{
textAlign: 'left', textAlign: 'left',

View File

@ -107,13 +107,10 @@ class Ranks {
static async hourlyUpdateRanking() { static async hourlyUpdateRanking() {
const onlineStats = await getOnlineUserStats(); const onlineStats = await getOnlineUserStats();
const cHistStats = await getCountryDailyHistory(); const cHistStats = await getCountryDailyHistory();
const histStats = await getTopDailyHistory();
histStats.users = await populateRanking(histStats.users);
const pHourlyStats = await getHourlyPixelStats(); const pHourlyStats = await getHourlyPixelStats();
const ret = { const ret = {
onlineStats, onlineStats,
cHistStats, cHistStats,
histStats,
pHourlyStats, pHourlyStats,
}; };
if (socketEvents.amIImportant()) { if (socketEvents.amIImportant()) {
@ -128,9 +125,15 @@ class Ranks {
await getPrevTop(), await getPrevTop(),
); );
const pDailyStats = await getDailyPixelStats(); const pDailyStats = await getDailyPixelStats();
const histStats = await getTopDailyHistory();
histStats.users = await populateRanking(histStats.users);
histStats.stats = histStats.stats.map((day) => day.filter(
(r) => histStats.users.some((u) => u.id === r.id),
));
const ret = { const ret = {
prevTop, prevTop,
pDailyStats, pDailyStats,
histStats,
}; };
if (socketEvents.amIImportant()) { if (socketEvents.amIImportant()) {
// only main shard sends to others // only main shard sends to others

View File

@ -246,8 +246,7 @@ export function getHistChartData(histStats) {
const labels = []; const labels = [];
let ts = Date.now(); let ts = Date.now();
let c = stats.length; let c = stats.length;
// skipping todays dataset while (c) {
while (c > 1) {
const dAmount = stats.length - c; const dAmount = stats.length - c;
c -= 1; c -= 1;
// x label // x label

View File

@ -241,6 +241,7 @@ class User {
name: null, name: null,
mailVerified: false, mailVerified: false,
blockDm: false, blockDm: false,
priv: false,
mailreg: false, mailreg: false,
}; };
} }
@ -256,6 +257,7 @@ class User {
name: regUser.name, name: regUser.name,
mailVerified: regUser.mailVerified, mailVerified: regUser.mailVerified,
blockDm: regUser.blockDm, blockDm: regUser.blockDm,
priv: regUser.priv,
totalPixels, totalPixels,
dailyTotalPixels, dailyTotalPixels,
ranking, ranking,

View File

@ -194,17 +194,11 @@ export async function getDailyPixelStats() {
export async function getTopDailyHistory() { export async function getTopDailyHistory() {
const stats = []; const stats = [];
const users = []; const users = [];
let ts; let ts = Date.now();
let key; for (let c = 0; c < 13; c += 1) {
for (let c = 0; c < 14; c += 1) { ts -= 1000 * 3600 * 24;
if (!ts) { const dateKey = getDateKeyOfTs(ts);
ts = Date.now(); const key = `${DAY_STATS_RANKS_KEY}:${dateKey}`;
key = DAILY_RANKED_KEY;
} else {
ts -= 1000 * 3600 * 24;
const dateKey = getDateKeyOfTs(ts);
key = `${DAY_STATS_RANKS_KEY}:${dateKey}`;
}
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
let dData = await client.zRangeWithScores(key, 0, 9, { let dData = await client.zRangeWithScores(key, 0, 9, {
REV: true, REV: true,

View File

@ -28,11 +28,14 @@ const RegUser = sequelize.define('User', {
allowNull: false, allowNull: false,
}, },
// currently just moderator /*
roles: { * if account is private,
type: DataTypes.TINYINT, * exclude it from statistics etc.
*/
priv: {
type: DataTypes.BOOLEAN,
allowNull: false, allowNull: false,
defaultValue: 0, defaultValue: false,
}, },
// null if external oauth authentification // null if external oauth authentification
@ -41,6 +44,13 @@ const RegUser = sequelize.define('User', {
allowNull: true, allowNull: true,
}, },
// currently just moderator
roles: {
type: DataTypes.TINYINT,
allowNull: false,
defaultValue: 0,
},
// mail and Minecraft verified // mail and Minecraft verified
verified: { verified: {
type: DataTypes.TINYINT, type: DataTypes.TINYINT,
@ -205,6 +215,7 @@ export async function populateRanking(rawRanks) {
], ],
where: { where: {
id: uids, id: uids,
priv: false,
}, },
raw: true, raw: true,
}); });
@ -216,7 +227,7 @@ export async function populateRanking(rawRanks) {
dat.age = age; dat.age = age;
} }
} }
return rawRanks; return rawRanks.filter((r) => r.name);
} }
export default RegUser; export default RegUser;

View File

@ -14,6 +14,7 @@ import startDm from './startdm';
import leaveChan from './leavechan'; import leaveChan from './leavechan';
import block from './block'; import block from './block';
import blockdm from './blockdm'; import blockdm from './blockdm';
import privatize from './privatize';
import modtools from './modtools'; import modtools from './modtools';
import baninfo from './baninfo'; import baninfo from './baninfo';
import getiid from './getiid'; import getiid from './getiid';
@ -94,6 +95,8 @@ router.post('/block', block);
router.post('/blockdm', blockdm); router.post('/blockdm', blockdm);
router.post('/privatize', privatize);
router.get('/chathistory', chatHistory); router.get('/chathistory', chatHistory);
router.get('/me', me); router.get('/me', me);

View File

@ -0,0 +1,40 @@
/*
*
* block all private messages
*
*/
import logger from '../../core/logger';
async function privatize(req, res) {
const { priv } = req.body;
const { user } = req;
const errors = [];
if (typeof priv !== 'boolean') {
errors.push('Not defined if setting or unsetting private');
}
if (!user || !user.regUser) {
errors.push('You are not logged in');
}
if (errors.length) {
res.status(400);
res.json({
errors,
});
return;
}
logger.info(
`User ${user.getName()} set private status to ${priv}`,
);
await user.regUser.update({
priv,
});
res.json({
status: 'ok',
});
}
export default privatize;

View File

@ -151,6 +151,25 @@ export async function requestBlock(userId, block) {
return t`Unknown Error`; return t`Unknown Error`;
} }
/*
* set / unset provile as private
* @param priv
* @return error string or null if successful
*/
export async function requestPrivatize(priv) {
const res = await makeAPIPOSTRequest(
'/api/privatize',
{ priv },
);
if (res.errors) {
return res.errors[0];
}
if (res.status === 'ok') {
return null;
}
return t`Unknown Error`;
}
/* /*
* start new DM channel with user * start new DM channel with user
* @param query Object with either userId or userName: string * @param query Object with either userId or userName: string

View File

@ -475,6 +475,13 @@ export function blockingDm(blockDm) {
}; };
} }
export function privatize(priv) {
return {
type: 's/SET_PRIVATE',
priv,
};
}
export function removeChatChannel(cid) { export function removeChatChannel(cid) {
return { return {
type: 's/REMOVE_CHAT_CHANNEL', type: 's/REMOVE_CHAT_CHANNEL',

View File

@ -5,6 +5,7 @@ import {
requestStartDm, requestStartDm,
requestBlock, requestBlock,
requestBlockDm, requestBlockDm,
requestPrivatize,
requestLeaveChan, requestLeaveChan,
requestRankings, requestRankings,
requestChatMessages, requestChatMessages,
@ -19,6 +20,7 @@ import {
blockUser, blockUser,
unblockUser, unblockUser,
blockingDm, blockingDm,
privatize,
removeChatChannel, removeChatChannel,
} from './index'; } from './index';
@ -127,9 +129,7 @@ export function setUserBlock(
}; };
} }
export function setBlockingDm( export function setBlockingDm(block) {
block,
) {
return async (dispatch) => { return async (dispatch) => {
dispatch(setApiFetching(true)); dispatch(setApiFetching(true));
const res = await requestBlockDm(block); const res = await requestBlockDm(block);
@ -147,6 +147,25 @@ export function setBlockingDm(
}; };
} }
export function setPrivatize(priv) {
return async (dispatch) => {
dispatch(setApiFetching(true));
const res = await requestPrivatize(priv);
if (res) {
dispatch(pAlert(
'Setting User Private Error',
res,
'error',
'OK',
));
} else {
dispatch(privatize(priv));
}
dispatch(setApiFetching(false));
};
}
export function setLeaveChannel( export function setLeaveChannel(
cid, cid,
) { ) {

View File

@ -10,6 +10,8 @@ const initialState = {
mailreg: false, mailreg: false,
// blocking all Dms // blocking all Dms
blockDm: false, blockDm: false,
// privile is private
priv: false,
// if user is using touchscreen // if user is using touchscreen
isOnMobile: false, isOnMobile: false,
// small notifications for received cooldown // small notifications for received cooldown
@ -92,6 +94,7 @@ export default function user(
name, name,
mailreg, mailreg,
blockDm, blockDm,
priv,
userlvl, userlvl,
} = action; } = action;
const messages = (action.messages) ? action.messages : []; const messages = (action.messages) ? action.messages : [];
@ -102,6 +105,7 @@ export default function user(
messages, messages,
mailreg, mailreg,
blockDm, blockDm,
priv,
userlvl, userlvl,
}; };
} }
@ -114,6 +118,7 @@ export default function user(
messages: [], messages: [],
mailreg: false, mailreg: false,
blockDm: false, blockDm: false,
priv: false,
userlvl: 0, userlvl: 0,
}; };
} }
@ -134,6 +139,14 @@ export default function user(
}; };
} }
case 's/SET_PRIVATE': {
const { priv } = action;
return {
...state,
priv,
};
}
case 'SET_NOTIFICATION': { case 'SET_NOTIFICATION': {
return { return {
...state, ...state,