renew avatar

This commit is contained in:
Pavel Mineev
2021-05-17 15:14:35 -05:00
committed by Umputun
parent f9eb39db03
commit 93b29e934b
15 changed files with 201 additions and 69 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
const SvgrUrl = 'https://url-to-svg-image';
const SvgrUrl = '/image.svg';
export default SvgrUrl;
@@ -1,3 +0,0 @@
.avatar-icon_default {
border: 1px solid var(--color40);
}
@@ -1,22 +0,0 @@
<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="avatar-icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(4.000000, 2.000000)">
<g id="bg" transform="translate(0.600000, 0.497571)" fill-rule="nonzero">
<path d="M1.0658141e-14,18.0024291 C0.9,18.0024291 14.2,18.1024291 15.1,18.1024291 L14.4,14.6024291 C14.2,13.3024291 14.1,11.9024291 14.1,10.6024291 L14.1,7.00242909 C14.1,3.40242909 11.2,0.102429093 7.6,0.00242909307 C3.8,-0.0975709069 0.7,2.90242909 0.7,6.70242909 L0.7,10.6024291 C0.7,11.9024291 0.6,13.3024291 0.4,14.6024291 L1.0658141e-14,18.0024291 Z" id="Path" fill="#F5F4F4"></path>
<path d="M3.6,10.6024291 L3.6,6.70242909 C3.6,3.10242909 5.2,0.202429093 7.3,0.00242909307 C3.7,0.102429093 0.8,3.00242909 0.8,6.70242909 L0.8,10.6024291 C0.8,11.9024291 0.7,13.3024291 0.5,14.6024291 L5.77315973e-15,18.1024291 C0.9,18.1024291 2.62326389,17.9024291 3.02326389,18.1024291 L3.4,14.6024291 C3.5,13.3024291 3.6,11.9024291 3.6,10.6024291 Z" id="Path" fill="#FFFFFF" opacity="0.5"></path>
</g>
<path d="M15,11.1 L15,7.4 C15,3.6 12.1,0.4 8.4,0.1 C6.5,1.2490009e-16 4.6,0.7 3.2,2 C1.8,3.4 0.9,5.2 0.9,7.2 L0.9,11.1 C0.9,12.4 0.8,13.7 0.6,15 L0.1,18.5 C0.1,18.6 0.1,18.7 0.2,18.8 C0.3,18.9 0.4,19 0.5,19 C1.1,19 15.1,19 15.7,19 C15.8,19 15.9,19 16,18.9 C16.1,18.8 16.1,18.7 16.1,18.6 L15.3,15 C15.1,13.7 15,12.4 15,11.1 Z M1,18 L1.4,15.1 C1.6,13.8 1.7,12.4 1.7,11.1 L1.7,7.2 C1.7,5.4 2.4,3.8 3.7,2.6 C5,1.4 6.6,0.8 8.4,0.9 C11.7,1.1 14.3,4 14.3,7.4 L14.3,11 C14.3,12.3 14.4,13.7 14.6,15 L15,18 C14.9,18 1.1,18 1,18 Z" id="Shape" fill="#8ED0CF" fill-rule="nonzero"></path>
<g id="tie" transform="translate(1.000000, 12.000000)" stroke="#8ED0CF">
<polygon id="Triangle" stroke-width="0.9" fill="#8ED0CF" transform="translate(7.000000, 4.500000) scale(1, -1) translate(-7.000000, -4.500000) " points="7 3 9 6 5 6"></polygon>
<path d="M5,3 L3.5,6.5" id="Line-4" stroke-linecap="round"></path>
<path d="M9,3 L13.5,0.5" id="Line" stroke-linecap="round"></path>
<path d="M5,3 L0.5,0.5" id="Line-2" stroke-linecap="round"></path>
<path d="M9,3 L10.5,6.5" id="Line-3" stroke-linecap="round"></path>
</g>
<g id="eyes" transform="translate(4.000000, 5.000000)" fill="#8ED0CF" fill-rule="nonzero">
<path d="M1.7,0.6 C1.1,0.6 0.9,1.4 0.9,2.2 C0.9,3 1.1,3.8 1.7,3.8 C2.3,3.8 2.5,3 2.5,2.2 C2.5,1.4 2.2,0.6 1.7,0.6 Z" id="Path"></path>
<path d="M6.4,0.6 C5.8,0.6 5.6,1.4 5.6,2.2 C5.6,3 5.8,3.8 6.4,3.8 C7,3.8 7.2,3 7.2,2.2 C7.2,1.4 6.9,0.6 6.4,0.6 Z" id="Path"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

@@ -1,12 +0,0 @@
import '@testing-library/jest-dom';
import { h } from 'preact';
import { render } from '@testing-library/preact';
import { AvatarIcon } from './avatar-icon';
describe('<AvatarIcon/>', () => {
it('should get', () => {
const { getByAltText } = render(<AvatarIcon alt="avatar" />);
expect(getByAltText('avatar')).toHaveAttribute('src', 'https://url-to-svg-image');
});
});
@@ -1,20 +0,0 @@
import { h, JSX } from 'preact';
import b from 'bem-react-helper';
import { Theme } from 'common/types';
type Props = JSX.HTMLAttributes<HTMLImageElement> & {
picture?: string;
mix?: string;
theme?: Theme;
};
export function AvatarIcon({ mix, theme, picture, ...props }: Props) {
return (
<img
className={b('avatar-icon', { mix }, { theme, default: !picture })}
src={picture || require('./avatar-icon.svg').default}
alt=""
{...props}
/>
);
}
@@ -1,4 +0,0 @@
import './avatar-icon.css';
import './_default/avatar-icon_default.css';
export { AvatarIcon } from './avatar-icon';

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,4 +1,4 @@
.avatar-icon {
.avatar {
display: inline-block;
width: 24px;
height: 24px;
@@ -6,3 +6,8 @@
vertical-align: middle;
border-radius: 4px;
}
.avatarGhost {
box-sizing: border-box;
border: 1px solid var(--color40);
}
@@ -0,0 +1,16 @@
import '@testing-library/jest-dom';
import { h } from 'preact';
import { render } from '@testing-library/preact';
import { BASE_URL } from 'common/constants.config';
import { Avatar } from './avatar';
describe('<Avatar/>', () => {
it('should get', () => {
const { getByAltText } = render(<Avatar className="avatar" alt="avatar" />);
expect(getByAltText('avatar')).toHaveAttribute('src', `${BASE_URL}/image.svg`);
expect(getByAltText('avatar')).toHaveAttribute('alt', 'avatar');
});
});
+22
View File
@@ -0,0 +1,22 @@
import clsx from 'clsx';
import { h } from 'preact';
import { BASE_URL } from 'common/constants.config';
import styles from './avatar.module.css';
type Props = {
url?: string;
alt: string;
/** className should be used only in puprose of put permanent class on Avatar for user themization */
className: string;
};
export function Avatar({ url, className, alt }: Props) {
const avatarUrl = url || `${BASE_URL}${require('./assets/ghost.svg').default}`;
return (
// eslint-disable-next-line jsx-a11y/alt-text
<img className={clsx('avatar', className, styles.avatar, !url && styles.avatarGhost)} src={avatarUrl} alt={alt} />
);
}
+1
View File
@@ -0,0 +1 @@
export * from './avatar';
+2 -3
View File
@@ -12,7 +12,7 @@ import { extractErrorMessageFromResponse, FetcherError } from 'utils/errorUtils'
import { isUserAnonymous } from 'utils/isUserAnonymous';
import { CommentFormProps } from 'components/comment-form';
import { AvatarIcon } from 'components/avatar-icon';
import { Avatar } from 'components/avatar';
import { Button } from 'components/button';
import { Countdown } from 'components/countdown';
import { getPreview, uploadImage } from 'common/api';
@@ -661,9 +661,8 @@ export class Comment extends Component<CommentProps, State> {
)}
<div className="comment__info">
{props.view !== 'user' && !props.collapsed && (
<AvatarIcon mix="comment__avatar" theme={this.props.theme} picture={o.user.picture} />
<Avatar className="comment__avatar" url={o.user.picture} alt={o.user.name} />
)}
{props.view !== 'user' && (
<span
{...getHandleClickProps(this.toggleUserInfoVisibility)}
@@ -7,12 +7,11 @@ import { StoreState } from 'store';
import { Comment } from 'common/types';
import { fetchInfo } from 'store/user-info/actions';
import { userInfo } from 'common/user-info-settings';
import { postMessage } from 'utils/postMessage';
import { bindActions } from 'utils/actionBinder';
import { useActions } from 'hooks/useAction';
import { Avatar } from 'components/avatar';
import { AvatarIcon } from '../avatar-icon';
import { LastCommentsList } from './last-comments-list';
const boundActions = bindActions({ fetchInfo });
@@ -67,7 +66,7 @@ class UserInfo extends Component<Props, State> {
return (
<div className={b('root user-info', {})}>
<AvatarIcon mix="user-info__avatar" picture={user.picture} />
<Avatar className="user-info__avatar" url={user.picture} alt={user.name} />
<p className="user-info__title">
<FormattedMessage
id="user-info.last-comments"
+80
View File
@@ -0,0 +1,80 @@
:root {
--color0: #0f172a;
--color8: #262626;
--color22: #2d2d2c;
--color24: #313133;
--color7: #333;
--color23: #393734;
--color18: #383838;
--color19: #404040;
--color36: #575757;
--color34: #555;
--color37: #586069;
--color14: #6a6a6a;
--color10: #777;
--color13: #888;
--color11: #969696;
--color32: #a6a6a6;
--color1: #aaa;
--color35: #d1d5db;
--color20: #ddd;
--color46: rgba(27, 31, 35, 0.15);
--color45: rgba(0, 0, 0, 0.1);
--color41: #efefef;
--color5: #eee;
--color44: rgba(255, 255, 255, 0.3);
--color6: #fff;
--color3: #e2efef;
--color4: #edf6f7;
--color16: #e2e8f0;
--color31: #cbd5e1;
--color21: #f1f5f9;
--color29: #0e7e9d;
--color9: #0aa;
--color15: #099;
--color33: #06c5c5;
--color40: #9cdddb;
--color43: #b7dddd;
--color42: #c6efef;
--color48: rgba(37, 156, 154, 0.6);
--color47: rgba(37, 156, 154, 0.4);
--color12: #259e06;
--color28: #672323;
--color25: #9a0000;
--color30: #cc0606;
--color38: #ef0000;
--color27: #f98989;
--color26: #ffd7d7;
/* code-highlight */
--chroma-bg: rgba(0, 0, 0, 0.05);
--chroma-base: #586e75;
--chroma-c: #7d7d7d;
--chroma-01: #589000;
--chroma-02: #cb4b16;
--chroma-03: #268bd2;
--chroma-04: #2aa198;
--chroma-05: #859900;
--chroma-06: #d33682;
--chroma-07: #00aee2;
/* Named variables */
--primary-color: 0, 170, 170;
--primary-brighter-color: 0, 153, 153;
--secondary-text-color: 100, 116, 139;
--black-color: 0, 0, 0;
--white-color: 255, 255, 255;
--error-color: #b91c1c;
--error-background: #ff466f2b;
--line-color: var(--color16);
--line-brighter-color: var(--color31);
}
:root .dark {
--line-color: var(--color36);
--primary-color: 0, 153, 153;
--primary-brighter-color: 0, 170, 170;
--secondary-text-color: 209, 213, 219;
--error-color: #ffa0a0;
--line-brighter-color: var(--color11);
}
+71
View File
@@ -0,0 +1,71 @@
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0;
padding: 6px;
font-family: PT Sans, Helvetica, Arial, sans-serif;
}
/* Preloader */
.preloader,
.preloader::before,
.preloader::after {
border-radius: 50%;
width: 10px;
height: 10px;
text-align: left;
animation-name: bouncing;
animation-timing-function: ease-in-out;
animation-fill-mode: both;
animation-duration: 1.8s;
animation-iteration-count: infinite;
}
.preloader {
/* stylelint-disable-next-line */
color: #fff;
color: var(--color6, #fff);
position: relative;
transform: translate3d(0, -10px, 0);
animation-delay: -0.16s;
}
.preloader::before,
.preloader::after {
content: '';
position: absolute;
top: 0;
}
.preloader::before {
transform: translate3d(-15px, 0, 0);
animation-delay: -0.32s;
}
.preloader::after {
transform: translate3d(15px, 0, 0);
}
.preloader_view_iframe {
margin: 0 auto;
/* stylelint-disable-next-line */
color: #888;
color: var(--color13, #888);
}
:focus:not(.focus-visible):not(.button) {
outline: none;
}
@keyframes bouncing {
0%,
80%,
100% {
box-shadow: 0 10px 0 -10px;
}
40% {
box-shadow: 0 10px 0 0;
}
}