mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-24 08:08:18 -05:00
Merge pull request #4655 from picklesrus/use-minutes
Disable comment box functionality when you've just been muted.
This commit is contained in:
commit
0f83b0c7c8
3 changed files with 98 additions and 8 deletions
|
@ -275,6 +275,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.compose-disabled {
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
.comments-root-reply {
|
.comments-root-reply {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ class ComposeComment extends React.Component {
|
||||||
'handleCancel',
|
'handleCancel',
|
||||||
'handleInput',
|
'handleInput',
|
||||||
'handleMuteClose',
|
'handleMuteClose',
|
||||||
'handleMuteOpen'
|
'handleMuteOpen',
|
||||||
|
'isMuted'
|
||||||
]);
|
]);
|
||||||
this.state = {
|
this.state = {
|
||||||
message: '',
|
message: '',
|
||||||
|
@ -115,6 +115,10 @@ class ComposeComment extends React.Component {
|
||||||
return Math.ceil(((timeStampInSec * 1000) - Date.now()) / (60 * 1000));
|
return Math.ceil(((timeStampInSec * 1000) - Date.now()) / (60 * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isMuted () {
|
||||||
|
return this.state.muteExpiresAt * 1000 > Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
handleMuteClose () {
|
handleMuteClose () {
|
||||||
this.setState({
|
this.setState({
|
||||||
muteOpen: false
|
muteOpen: false
|
||||||
|
@ -163,10 +167,10 @@ class ComposeComment extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{this.state.status === ComposeStatus.REJECTED_MUTE ? (
|
{this.isMuted() ? (
|
||||||
<FlexRow className="comment">
|
<FlexRow className="comment">
|
||||||
<CommentingStatus>
|
<CommentingStatus>
|
||||||
<p>Scratch thinks your comment was disrespectful.</p>
|
<p>Scratch thinks your most recent comment was disrespectful.</p>
|
||||||
<p>
|
<p>
|
||||||
For the next {this.convertToMinutesFromNow(this.state.muteExpiresAt)} minutes you
|
For the next {this.convertToMinutesFromNow(this.state.muteExpiresAt)} minutes you
|
||||||
won't be able to post comments.
|
won't be able to post comments.
|
||||||
|
@ -182,7 +186,10 @@ class ComposeComment extends React.Component {
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
) : null }
|
) : null }
|
||||||
<div
|
<div
|
||||||
className="flex-row comment"
|
className={classNames('flex-row',
|
||||||
|
'comment',
|
||||||
|
this.state.status === ComposeStatus.REJECTED_MUTE ?
|
||||||
|
'compose-disabled' : '')}
|
||||||
>
|
>
|
||||||
<a href={`/users/${this.props.user.username}`}>
|
<a href={`/users/${this.props.user.username}`}>
|
||||||
<Avatar src={this.props.user.thumbnailUrl} />
|
<Avatar src={this.props.user.thumbnailUrl} />
|
||||||
|
@ -205,6 +212,7 @@ class ComposeComment extends React.Component {
|
||||||
className={classNames('compose-input',
|
className={classNames('compose-input',
|
||||||
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ?
|
MAX_COMMENT_LENGTH - this.state.message.length >= 0 ?
|
||||||
'compose-valid' : 'compose-invalid')}
|
'compose-valid' : 'compose-invalid')}
|
||||||
|
disabled={this.state.status === ComposeStatus.REJECTED_MUTE}
|
||||||
handleUpdate={onUpdate}
|
handleUpdate={onUpdate}
|
||||||
name="compose-comment"
|
name="compose-comment"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
|
|
@ -66,23 +66,73 @@ describe('Compose Comment test', () => {
|
||||||
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(false);
|
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Comment Status shows when state is REJECTED_MUTE ', () => {
|
test('Comment Status shows when mute expiration in the future ', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
const component = getComposeCommentWrapper({});
|
const component = getComposeCommentWrapper({});
|
||||||
const commentInstance = component.instance();
|
const commentInstance = component.instance();
|
||||||
commentInstance.setState({status: 'REJECTED_MUTE'});
|
commentInstance.setState({muteExpiresAt: 100});
|
||||||
component.update();
|
component.update();
|
||||||
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
||||||
expect(component.find('MuteModal').exists()).toEqual(false);
|
expect(component.find('MuteModal').exists()).toEqual(false);
|
||||||
expect(component.find('CommentingStatus').exists()).toEqual(true);
|
expect(component.find('CommentingStatus').exists()).toEqual(true);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
test('Comment Status shows when user just submitted a comment that got them muted', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
|
const component = getComposeCommentWrapper({});
|
||||||
|
const commentInstance = component.instance();
|
||||||
|
commentInstance.setState({
|
||||||
|
status: 'REJECTED_MUTE',
|
||||||
|
muteExpiresAt: 100
|
||||||
|
});
|
||||||
|
component.update();
|
||||||
|
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
||||||
|
expect(component.find('MuteModal').exists()).toEqual(false);
|
||||||
|
expect(component.find('CommentingStatus').exists()).toEqual(true);
|
||||||
|
// Compose box is disabled
|
||||||
|
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
|
||||||
|
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(true);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
test('Comment Error does not show for mutes', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
|
const component = getComposeCommentWrapper({});
|
||||||
|
const commentInstance = component.instance();
|
||||||
|
commentInstance.setState({
|
||||||
|
status: 'REJECTED_MUTE',
|
||||||
|
error: 'a mute error'
|
||||||
|
});
|
||||||
|
component.update();
|
||||||
|
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(false);
|
||||||
|
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
test('Comment Error does show for non-mute errors', () => {
|
||||||
|
const component = getComposeCommentWrapper({});
|
||||||
|
const commentInstance = component.instance();
|
||||||
|
commentInstance.setState({
|
||||||
|
error: 'some error',
|
||||||
|
status: 'FLOOD'
|
||||||
|
});
|
||||||
|
component.update();
|
||||||
|
expect(component.find('FlexRow.compose-error-row').exists()).toEqual(true);
|
||||||
|
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
||||||
|
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
|
||||||
|
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Mute Modal shows when muteOpen is true ', () => {
|
test('Mute Modal shows when muteOpen is true ', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
const component = getComposeCommentWrapper({});
|
const component = getComposeCommentWrapper({});
|
||||||
const commentInstance = component.instance();
|
const commentInstance = component.instance();
|
||||||
commentInstance.setState({muteOpen: true});
|
commentInstance.setState({muteOpen: true});
|
||||||
component.update();
|
component.update();
|
||||||
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
|
|
||||||
expect(component.find('MuteModal').exists()).toEqual(true);
|
expect(component.find('MuteModal').exists()).toEqual(true);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shouldShowMuteModal is false when list is undefined ', () => {
|
test('shouldShowMuteModal is false when list is undefined ', () => {
|
||||||
|
@ -130,4 +180,32 @@ describe('Compose Comment test', () => {
|
||||||
global.Date.now = realDateNow;
|
global.Date.now = realDateNow;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('isMuted: expiration is in the future ', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0; // Set "now" to 0 for easier testing.
|
||||||
|
|
||||||
|
const commentInstance = getComposeCommentWrapper({}).instance();
|
||||||
|
commentInstance.setState({muteExpiresAt: 100});
|
||||||
|
expect(commentInstance.isMuted()).toBe(true);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('isMuted: expiration is in the past ', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
|
|
||||||
|
const commentInstance = getComposeCommentWrapper({}).instance();
|
||||||
|
commentInstance.setState({muteExpiresAt: -100});
|
||||||
|
expect(commentInstance.isMuted()).toBe(false);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('isMuted: expiration is not set ', () => {
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => 0;
|
||||||
|
|
||||||
|
const commentInstance = getComposeCommentWrapper({}).instance();
|
||||||
|
expect(commentInstance.isMuted()).toBe(false);
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue