Block timeout was changed from "hours" to "seconds" in Commentron
This commit is contained in:
parent
a05ccdd44f
commit
663376e970
6 changed files with 71 additions and 27 deletions
2
flow-typed/Comment.js
vendored
2
flow-typed/Comment.js
vendored
|
@ -201,7 +201,7 @@ declare type ModerationBlockParams = {
|
|||
creator_channel_name?: string,
|
||||
// Blocks identity from comment universally, requires Admin rights on commentron instance
|
||||
block_all?: boolean,
|
||||
time_out_hrs?: number,
|
||||
time_out?: number,
|
||||
// If true will delete all comments of the offender, requires Admin rights on commentron for universal delete
|
||||
delete_all?: boolean,
|
||||
// The usual signature stuff
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
"electron-updater": "^4.2.4",
|
||||
"express": "^4.17.1",
|
||||
"if-env": "^1.0.4",
|
||||
"parse-duration": "^1.0.0",
|
||||
"react-datetime-picker": "^3.2.1",
|
||||
"react-plastic": "^1.1.1",
|
||||
"react-top-loading-bar": "^2.0.1",
|
||||
|
|
|
@ -1744,6 +1744,11 @@
|
|||
"Moderator Block": "Moderator Block",
|
||||
"Block this channel on behalf of %creator%": "Block this channel on behalf of %creator%",
|
||||
"creator": "creator",
|
||||
"Enter the timeout duration. Examples: %examples%": "Enter the timeout duration. Examples: %examples%",
|
||||
"Wow, banned for more than 100 years?": "Wow, banned for more than 100 years?",
|
||||
"Invalid duration.": "Invalid duration.",
|
||||
"Permanent": "Permanent",
|
||||
"Timeout --[time-based ban instead of permanent]--": "Timeout",
|
||||
"Create a channel to change this setting.": "Create a channel to change this setting.",
|
||||
"Invalid channel URL \"%url%\"": "Invalid channel URL \"%url%\"",
|
||||
"Delegation": "Delegation",
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import parseDuration from 'parse-duration';
|
||||
import Button from 'component/button';
|
||||
import ChannelThumbnail from 'component/channelThumbnail';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Card from 'component/common/card';
|
||||
import { FormField } from 'component/common/form';
|
||||
import Icon from 'component/common/icon';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
import { Modal } from 'modal/modal';
|
||||
|
||||
|
@ -64,11 +67,12 @@ export default function ModalBlockChannel(props: Props) {
|
|||
|
||||
const [tab, setTab] = usePersistedState('ModalBlockChannel:tab', TAB.PERSONAL);
|
||||
const [blockType, setBlockType] = usePersistedState('ModalBlockChannel:blockType', BLOCK.PERMANENT);
|
||||
const [timeoutHrs, setTimeoutHrs] = usePersistedState('ModalBlockChannel:timeoutHrs', 1);
|
||||
const [timeoutHrsError, setTimeoutHrsError] = React.useState('');
|
||||
const [timeoutInput, setTimeoutInput] = usePersistedState('ModalBlockChannel:timeoutInput', '10m');
|
||||
const [timeoutInputErr, setTimeoutInputErr] = React.useState('');
|
||||
const [timeoutSec, setTimeoutSec] = React.useState(-1);
|
||||
|
||||
const personalIsTheOnlyTab = !activeChannelIsModerator && !activeChannelIsAdmin;
|
||||
const blockButtonDisabled = blockType === BLOCK.TIMEOUT && (timeoutHrs === 0 || !Number.isInteger(timeoutHrs));
|
||||
const blockButtonDisabled = blockType === BLOCK.TIMEOUT && timeoutSec < 1;
|
||||
|
||||
// **************************************************************************
|
||||
// **************************************************************************
|
||||
|
@ -84,18 +88,39 @@ export default function ModalBlockChannel(props: Props) {
|
|||
}
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// 'timeoutHrs' sanity check.
|
||||
// 'timeoutInput' to 'timeoutSec' conversion.
|
||||
React.useEffect(() => {
|
||||
if (Number.isInteger(timeoutHrs) && timeoutHrs > 0) {
|
||||
if (timeoutHrsError) {
|
||||
setTimeoutHrsError('');
|
||||
const setInvalid = (errMsg: string) => {
|
||||
if (timeoutSec !== -1) {
|
||||
setTimeoutSec(-1);
|
||||
}
|
||||
if (!timeoutInputErr) {
|
||||
setTimeoutInputErr(errMsg);
|
||||
}
|
||||
};
|
||||
|
||||
const setValid = (seconds) => {
|
||||
if (seconds !== timeoutSec) {
|
||||
setTimeoutSec(seconds);
|
||||
}
|
||||
if (timeoutInputErr) {
|
||||
setTimeoutInputErr('');
|
||||
}
|
||||
};
|
||||
|
||||
const ONE_HUNDRED_YEARS_IN_SECONDS = 3154000000;
|
||||
const seconds = parseDuration(timeoutInput, 's');
|
||||
|
||||
if (Number.isInteger(seconds) && seconds > 0) {
|
||||
if (seconds > ONE_HUNDRED_YEARS_IN_SECONDS) {
|
||||
setInvalid('Wow, banned for more than 100 years?');
|
||||
} else {
|
||||
setValid(seconds);
|
||||
}
|
||||
} else {
|
||||
if (!timeoutHrsError) {
|
||||
setTimeoutHrsError('Invalid duration.');
|
||||
}
|
||||
setInvalid('Invalid duration.');
|
||||
}
|
||||
}, [timeoutHrs, timeoutHrsError]);
|
||||
}, [timeoutInput, timeoutInputErr, timeoutSec]);
|
||||
|
||||
// **************************************************************************
|
||||
// **************************************************************************
|
||||
|
@ -143,19 +168,27 @@ export default function ModalBlockChannel(props: Props) {
|
|||
}
|
||||
|
||||
function getTimeoutDurationElem() {
|
||||
const examples = '\n- 30s\n- 10m\n- 1h\n- 2d\n- 3mo\n- 1y';
|
||||
return (
|
||||
<FormField
|
||||
name="time_out_hrs"
|
||||
label={__('Hours')}
|
||||
className="form-field--price-amount"
|
||||
max="1000"
|
||||
min="1"
|
||||
step="1"
|
||||
type="number"
|
||||
placeholder="1"
|
||||
value={timeoutHrs}
|
||||
onChange={(e) => setTimeoutHrs(parseInt(e.target.value))}
|
||||
error={timeoutHrsError}
|
||||
name="time_out"
|
||||
label={
|
||||
<>
|
||||
{__('Duration')}
|
||||
<Icon
|
||||
customTooltipText={__('Enter the timeout duration. Examples: %examples%', { examples })}
|
||||
className="icon--help"
|
||||
icon={ICONS.HELP}
|
||||
tooltip
|
||||
size={16}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
type="text"
|
||||
placeholder="30s, 10m, 1h, 2d, 3mo, 1y"
|
||||
value={timeoutInput}
|
||||
onChange={(e) => setTimeoutInput(e.target.value)}
|
||||
error={timeoutInputErr}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -180,7 +213,7 @@ export default function ModalBlockChannel(props: Props) {
|
|||
}
|
||||
|
||||
function handleBlock() {
|
||||
const duration = blockType === BLOCK.TIMEOUT && timeoutHrs ? timeoutHrs : undefined;
|
||||
const duration = blockType === BLOCK.TIMEOUT && timeoutSec > 0 ? timeoutSec : undefined;
|
||||
|
||||
switch (tab) {
|
||||
case TAB.PERSONAL:
|
||||
|
@ -232,7 +265,7 @@ export default function ModalBlockChannel(props: Props) {
|
|||
<div className="block-modal--values">
|
||||
<fieldset>
|
||||
{getBlockTypeElem(BLOCK.PERMANENT, 'Permanent')}
|
||||
{getBlockTypeElem(BLOCK.TIMEOUT, 'Timeout')}
|
||||
{getBlockTypeElem(BLOCK.TIMEOUT, 'Timeout --[time-based ban instead of permanent]--')}
|
||||
</fieldset>
|
||||
{blockType === BLOCK.TIMEOUT && getTimeoutDurationElem()}
|
||||
</div>
|
||||
|
|
|
@ -738,7 +738,7 @@ function doCommentModToggleBlock(
|
|||
creatorId: string,
|
||||
blockerIds: Array<string>, // [] = use all my channels
|
||||
blockLevel: string,
|
||||
timeoutHours?: number,
|
||||
timeoutSec?: number,
|
||||
showLink: boolean = false
|
||||
) {
|
||||
return async (dispatch: Dispatch, getState: GetState) => {
|
||||
|
@ -845,7 +845,7 @@ function doCommentModToggleBlock(
|
|||
block_all: unblock ? undefined : blockLevel === BLOCK_LEVEL.ADMIN,
|
||||
global_un_block: unblock ? blockLevel === BLOCK_LEVEL.ADMIN : undefined,
|
||||
...sharedModBlockParams,
|
||||
time_out_hrs: unblock ? undefined : timeoutHours,
|
||||
time_out: unblock ? undefined : timeoutSec,
|
||||
})
|
||||
)
|
||||
)
|
||||
|
|
|
@ -11916,6 +11916,11 @@ parse-asn1@^5.0.0:
|
|||
pbkdf2 "^3.0.3"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
parse-duration@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-duration/-/parse-duration-1.0.0.tgz#8605651745f61088f6fb14045c887526c291858c"
|
||||
integrity sha512-X4kUkCTHU1N/kEbwK9FpUJ0UZQa90VzeczfS704frR30gljxDG0pSziws06XlK+CGRSo/1wtG1mFIdBFQTMQNw==
|
||||
|
||||
parse-entities@^1.0.2, parse-entities@^1.1.0:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
|
||||
|
|
Loading…
Reference in a new issue