fix broken verify icon on admin view and optimize the icon

This commit is contained in:
Paul Mineev
2022-04-13 03:40:39 -05:00
committed by Umputun
parent c987513886
commit 000d64d78f
13 changed files with 116 additions and 83 deletions
@@ -1,3 +0,0 @@
.comment__verification_active {
background-image: url('./comment__verification_active.svg');
}
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="none" fill-rule="evenodd"><path fill="#4fbbd6" d="m5.823 14.822-1.28.206a.824.824 0 0 1-.9-.52l-.463-1.212a.824.824 0 0 0-.476-.476l-1.212-.462a.824.824 0 0 1-.52-.9l.206-1.281a.824.824 0 0 0-.175-.65L.185 8.52a.824.824 0 0 1 0-1.04l.818-1.006a.824.824 0 0 0 .175-.65L.972 4.542a.824.824 0 0 1 .52-.9l1.212-.463a.824.824 0 0 0 .476-.476l.462-1.212a.824.824 0 0 1 .9-.52l1.281.206a.824.824 0 0 0 .65-.175L7.48.185a.824.824 0 0 1 1.04 0l1.006.818a.824.824 0 0 0 .65.175l1.281-.206a.824.824 0 0 1 .9.52l.463 1.212c.084.22.257.392.476.476l1.212.462c.365.14.582.515.52.9l-.206 1.281a.824.824 0 0 0 .175.65l.818 1.007a.824.824 0 0 1 0 1.04l-.818 1.006a.824.824 0 0 0-.175.65l.206 1.281a.824.824 0 0 1-.52.9l-1.212.463a.824.824 0 0 0-.476.476l-.462 1.212a.824.824 0 0 1-.9.52l-1.281-.206a.824.824 0 0 0-.65.175l-1.007.818a.824.824 0 0 1-1.04 0l-1.006-.818a.824.824 0 0 0-.65-.175z"/><path stroke="#FFF" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" d="M4.755 8.252 7 10.5l4.495-4.495"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,3 +0,0 @@
.comment__verification_clickable {
cursor: pointer;
}
@@ -1,13 +0,0 @@
.comment__verification {
display: inline-block;
width: 12px;
height: 12px;
margin-left: 4px;
vertical-align: middle;
background: url('./comment__verification.svg') center no-repeat;
background-size: cover;
&:hover {
opacity: 0.75;
}
}
@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<g fill="none" fill-rule="evenodd">
<path fill="#BBB" d="M5.823 14.822l-1.28.206a.824.824 0 0 1-.9-.52l-.463-1.212a.824.824 0 0 0-.476-.476l-1.212-.462a.824.824 0 0 1-.52-.9l.206-1.281a.824.824 0 0 0-.175-.65L.185 8.52a.824.824 0 0 1 0-1.04l.818-1.006a.824.824 0 0 0 .175-.65L.972 4.542a.824.824 0 0 1 .52-.9l1.212-.463a.824.824 0 0 0 .476-.476l.462-1.212a.824.824 0 0 1 .9-.52l1.281.206a.824.824 0 0 0 .65-.175L7.48.185a.824.824 0 0 1 1.04 0l1.006.818a.824.824 0 0 0 .65.175l1.281-.206a.824.824 0 0 1 .9.52l.463 1.212c.084.22.257.392.476.476l1.212.462c.365.14.582.515.52.9l-.206 1.281a.824.824 0 0 0 .175.65l.818 1.007a.824.824 0 0 1 0 1.04l-.818 1.006a.824.824 0 0 0-.175.65l.206 1.281a.824.824 0 0 1-.52.9l-1.212.463a.824.824 0 0 0-.476.476l-.462 1.212a.824.824 0 0 1-.9.52l-1.281-.206a.824.824 0 0 0-.65.175l-1.007.818a.824.824 0 0 1-1.04 0l-1.006-.818a.824.824 0 0 0-.65-.175z"/>
<path stroke="#FFF" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" d="M4.755 8.252L7 10.5l4.495-4.495"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -6,3 +6,24 @@
.user > * + * {
margin-left: 4px;
}
.verificationButton {
display:flex;
align-items: center;
padding: 2px;
width: 16px;
height: 16px;
}
.verificationIcon {
color: var(--color29);
}
.verificationIconInactive {
color: var(--color1);
transition: opacity 0.15s;
&:hover {
opacity: 0.75;
}
}
@@ -37,8 +37,9 @@ function getDefaultProps() {
vote: 0,
user: {
id: 'someone',
name: 'username',
picture: 'somepicture-url',
} as User,
},
time: new Date().toString(),
locator: {
url: 'somelocatorurl',
@@ -50,7 +51,7 @@ function getDefaultProps() {
id: 'testuser',
picture: 'somepicture-url',
} as User,
} as CommentProps;
} as CommentProps & { user: User };
}
const DefaultProps = getDefaultProps();
@@ -65,6 +66,36 @@ describe('<Comment />', () => {
expect(patreonSubscriberIcon.tagName).toBe('IMG');
});
describe('verification', () => {
it('should render active verification icon', () => {
const props = getDefaultProps();
props.data.user.verified = true;
render(<CommentWithIntl {...props} />);
expect(screen.getByTitle('Verified user')).toBeVisible();
});
it('should not render verification icon', () => {
const props = getDefaultProps();
render(<CommentWithIntl {...props} />);
expect(screen.queryByTitle('Verified user')).not.toBeInTheDocument();
});
it('should render verification button for admin', () => {
const props = getDefaultProps();
props.user.admin = true;
render(<CommentWithIntl {...props} />);
expect(screen.getByTitle('Toggle verification')).toBeVisible();
});
it('should render active verification icon for admin', () => {
const props = getDefaultProps();
props.user.admin = true;
props.data.user.verified = true;
render(<CommentWithIntl {...props} />);
expect(screen.queryByTitle('Verified user')).toBeVisible();
});
});
describe('voting', () => {
it('should be disabled for an anonymous user', () => {
const wrapper = mountComment({ ...DefaultProps, user: { id: 'anonymous_1' } } as CommentProps);
@@ -230,23 +261,6 @@ describe('<Comment />', () => {
expect(controls.at(0).text()).toEqual('Hide');
});
it('verification badge clickable for admin', () => {
const element = mountComment({ ...DefaultProps, user: { ...DefaultProps.user, admin: true } } as CommentProps);
const controls = element.find('.comment__verification').first();
expect(controls.hasClass('comment__verification_clickable')).toEqual(true);
});
it('verification badge not clickable for regular user', () => {
const element = mountComment({
...DefaultProps,
data: { ...DefaultProps.data, user: { ...DefaultProps.data!.user, verified: true } },
} as CommentProps);
const controls = element.find('.comment__verification').first();
expect(controls.hasClass('comment__verification_clickable')).toEqual(false);
});
it('should be editable', async () => {
StaticStore.config.edit_duration = 300;
+21 -17
View File
@@ -1,5 +1,7 @@
import { h, JSX, Component, createRef, ComponentType } from 'preact';
import { FormattedMessage, IntlShape, defineMessages } from 'react-intl';
import b from 'bem-react-helper';
import clsx from 'clsx';
import { getHandleClickProps } from 'common/accessibility';
import { COMMENT_NODE_CLASSNAME_PREFIX } from 'common/constants';
@@ -15,14 +17,14 @@ import { CommentFormProps } from 'components/comment-form';
import { Avatar } from 'components/avatar';
import { Button } from 'components/button';
import { Countdown } from 'components/countdown';
import { VerificationIcon } from 'components/icons/verification';
import { getPreview, uploadImage } from 'common/api';
import { postMessageToParent } from 'utils/post-message';
import { FormattedMessage, IntlShape, defineMessages } from 'react-intl';
import { getVoteMessage, VoteMessagesTypes } from './getVoteMessage';
import { getBlockingDurations } from './getBlockingDurations';
import { boundActions } from './connected-comment';
import style from './comment.module.css';
import styles from './comment.module.css';
import './styles';
export type CommentProps = {
@@ -596,12 +598,28 @@ export class Comment extends Component<CommentProps, State> {
<Avatar url={o.user.picture} />
</div>
)}
<div className={style.user}>
<div className={styles.user}>
{props.view !== 'user' && (
<button onClick={() => this.toggleUserInfoVisibility()} className="comment__username">
{o.user.name}
</button>
)}
{isAdmin && props.view !== 'user' && (
<button
className={styles.verificationButton}
onClick={this.toggleVerify}
title={intl.formatMessage(messages.toggleVerification)}
>
<VerificationIcon
title={intl.formatMessage(o.user.verified ? messages.verifiedUser : messages.unverifiedUser)}
className={clsx(styles.verificationIcon, !o.user.verified && styles.verificationIconInactive)}
/>
</button>
)}
{!isAdmin && !!o.user.verified && props.view !== 'user' && (
<VerificationIcon className={styles.verificationIcon} title={intl.formatMessage(messages.verifiedUser)} />
)}
{o.user.paid_sub && (
<img
width={12}
@@ -610,20 +628,6 @@ export class Comment extends Component<CommentProps, State> {
alt={intl.formatMessage(messages.paidPatreon)}
/>
)}
{isAdmin && props.view !== 'user' && (
<span
{...getHandleClickProps(this.toggleVerify)}
aria-label={intl.formatMessage(messages.toggleVerification)}
title={intl.formatMessage(o.user.verified ? messages.verifiedUser : messages.unverifiedUser)}
className={b('comment__verification', {}, { active: o.user.verified, clickable: true })}
/>
)}
{!isAdmin && !!o.user.verified && props.view !== 'user' && (
<span
title={intl.formatMessage(messages.verifiedUser)}
className={b('comment__verification', {}, { active: true })}
/>
)}
</div>
<a href={`${o.locator.url}#${COMMENT_NODE_CLASSNAME_PREFIX}${o.id}`} className="comment__time">
@@ -26,10 +26,6 @@ import './__time/comment__time.css';
import './__user-id/comment__user-id.css';
import './__username/comment__username.css';
import './__verification/comment__verification.css';
import './__verification/_active/comment__verification_active.css';
import './__verification/_clickable/comment__verification_clickable.css';
import './__vote/comment__vote.css';
import './__vote/_disabled/comment__vote_disabled.css';
import './__vote/_selected/comment__vote_selected.css';
@@ -0,0 +1,18 @@
import { h } from 'preact';
import '@testing-library/jest-dom';
import { screen } from '@testing-library/preact';
import { render } from 'tests/utils';
import { VerificationIcon } from './verification';
describe('<VerificationIcon />', () => {
it('should be rendered with default size', async () => {
render(<VerificationIcon title="icon" />);
expect(await screen.findByTitle('icon')).toHaveAttribute('width', '12');
expect(await screen.findByTitle('icon')).toHaveAttribute('height', '12');
});
it('should be rendered with provided size', async () => {
render(<VerificationIcon title="icon" size={16} />);
expect(await screen.findByTitle('icon')).toHaveAttribute('width', '16');
expect(await screen.findByTitle('icon')).toHaveAttribute('height', '16');
});
});
@@ -0,0 +1,22 @@
import { h, JSX } from 'preact';
type Props = JSX.SVGAttributes<SVGSVGElement> & { size?: number };
export function VerificationIcon({ size = 12, ...props }: Props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 16 16" {...props}>
<path
fill="currentColor"
d="m5.823 14.822-1.28.206a.824.824 0 0 1-.9-.52l-.463-1.212a.824.824 0 0 0-.476-.476l-1.212-.462a.824.824 0 0 1-.52-.9l.206-1.281a.824.824 0 0 0-.175-.65L.185 8.52a.824.824 0 0 1 0-1.04l.818-1.006a.824.824 0 0 0 .175-.65L.972 4.542a.824.824 0 0 1 .52-.9l1.212-.463a.824.824 0 0 0 .476-.476l.462-1.212a.824.824 0 0 1 .9-.52l1.281.206a.824.824 0 0 0 .65-.175L7.48.185a.824.824 0 0 1 1.04 0l1.006.818a.824.824 0 0 0 .65.175l1.281-.206a.824.824 0 0 1 .9.52l.463 1.212c.084.22.257.392.476.476l1.212.462c.365.14.582.515.52.9l-.206 1.281a.824.824 0 0 0 .175.65l.818 1.007a.824.824 0 0 1 0 1.04l-.818 1.006a.824.824 0 0 0-.175.65l.206 1.281a.824.824 0 0 1-.52.9l-1.212.463a.824.824 0 0 0-.476.476l-.462 1.212a.824.824 0 0 1-.9.52l-1.281-.206a.824.824 0 0 0-.65.175l-1.007.818a.824.824 0 0 1-1.04 0l-1.006-.818a.824.824 0 0 0-.65-.175z"
/>
<path
fill="none"
stroke="#fff"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
d="M4.755 8.252 7 10.5l4.495-4.495"
/>
</svg>
);
}
-17
View File
@@ -1,17 +0,0 @@
export function Verified() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
<path
fill="#4fbbd6"
d="M5.823 14.822l-1.28.206a.824.824 0 0 1-.9-.52l-.463-1.212a.824.824 0 0 0-.476-.476l-1.212-.462a.824.824 0 0 1-.52-.9l.206-1.281a.824.824 0 0 0-.175-.65L.185 8.52a.824.824 0 0 1 0-1.04l.818-1.006a.824.824 0 0 0 .175-.65L.972 4.542a.824.824 0 0 1 .52-.9l1.212-.463a.824.824 0 0 0 .476-.476l.462-1.212a.824.824 0 0 1 .9-.52l1.281.206a.824.824 0 0 0 .65-.175L7.48.185a.824.824 0 0 1 1.04 0l1.006.818a.824.824 0 0 0 .65.175l1.281-.206a.824.824 0 0 1 .9.52l.463 1.212c.084.22.257.392.476.476l1.212.462c.365.14.582.515.52.9l-.206 1.281a.824.824 0 0 0 .175.65l.818 1.007a.824.824 0 0 1 0 1.04l-.818 1.006a.824.824 0 0 0-.175.65l.206 1.281a.824.824 0 0 1-.52.9l-1.212.463a.824.824 0 0 0-.476.476l-.462 1.212a.824.824 0 0 1-.9.52l-1.281-.206a.824.824 0 0 0-.65.175l-1.007.818a.824.824 0 0 1-1.04 0l-1.006-.818a.824.824 0 0 0-.65-.175z"
/>
<path
stroke="#fff"
stroke-width="1.6"
stroke-linecap="round"
stroke-linejoin="round"
d="M4.755 8.252L7 10.5l4.495-4.495"
/>
</svg>
);
}
+1
View File
@@ -27,6 +27,7 @@ button {
transition-timing-function: linear;
transition-duration: 150ms;
appearance: none;
cursor: pointer;
}
#remark42 {