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 { useDispatch, useSelector } from 'react-redux';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { t } from 'ttag';
import {
setBlockingDm,
setPrivatize,
setUserBlock,
} from '../store/actions/thunks';
import SettingsItem from './SettingsItem';
const selectBlocks = (state) => [
state.chat.blocked,
state.user.blockDm,
state.user.priv,
state.fetching.fetchingApi,
];
const SocialSettings = ({ done }) => {
const blocked = useSelector((state) => state.chat.blocked);
const blockDm = useSelector((state) => state.user.blockDm);
const fetching = useSelector((state) => state.fetching.fetchingApi);
const [
blocked,
blockDm,
priv,
fetching,
] = useSelector(selectBlocks, shallowEqual);
const dispatch = useDispatch();
return (
<div className="inarea">
<SettingsItem
title={t`Block all Private Messages`}
title={t`Block DMs`}
value={blockDm}
onToggle={() => {
if (!fetching) {
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
style={{
textAlign: 'left',

View File

@ -107,13 +107,10 @@ class Ranks {
static async hourlyUpdateRanking() {
const onlineStats = await getOnlineUserStats();
const cHistStats = await getCountryDailyHistory();
const histStats = await getTopDailyHistory();
histStats.users = await populateRanking(histStats.users);
const pHourlyStats = await getHourlyPixelStats();
const ret = {
onlineStats,
cHistStats,
histStats,
pHourlyStats,
};
if (socketEvents.amIImportant()) {
@ -128,9 +125,15 @@ class Ranks {
await getPrevTop(),
);
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 = {
prevTop,
pDailyStats,
histStats,
};
if (socketEvents.amIImportant()) {
// only main shard sends to others

View File

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

View File

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

View File

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

View File

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

View File

@ -14,6 +14,7 @@ import startDm from './startdm';
import leaveChan from './leavechan';
import block from './block';
import blockdm from './blockdm';
import privatize from './privatize';
import modtools from './modtools';
import baninfo from './baninfo';
import getiid from './getiid';
@ -94,6 +95,8 @@ router.post('/block', block);
router.post('/blockdm', blockdm);
router.post('/privatize', privatize);
router.get('/chathistory', chatHistory);
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`;
}
/*
* 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
* @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) {
return {
type: 's/REMOVE_CHAT_CHANNEL',

View File

@ -5,6 +5,7 @@ import {
requestStartDm,
requestBlock,
requestBlockDm,
requestPrivatize,
requestLeaveChan,
requestRankings,
requestChatMessages,
@ -19,6 +20,7 @@ import {
blockUser,
unblockUser,
blockingDm,
privatize,
removeChatChannel,
} from './index';
@ -127,9 +129,7 @@ export function setUserBlock(
};
}
export function setBlockingDm(
block,
) {
export function setBlockingDm(block) {
return async (dispatch) => {
dispatch(setApiFetching(true));
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(
cid,
) {

View File

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