This commit is contained in:
igoradamenko
2018-05-02 02:18:38 +03:00
parent 0ef77f63f6
commit b9c567c10e
30 changed files with 217 additions and 144 deletions
@@ -1,14 +1,23 @@
.comment__action {
margin-left: 8px;
font-weight: 700;
color: #0aa;
font-size: 14px;
cursor: pointer;
user-select: none;
color: #8CD4D4;
&:hover {
color: #06c5c5;
color: #0aa;
}
&:focus {
outline: none;
}
+ .comment__controls {
&::before {
content: '';
margin-left: 8px;
margin-right: 8px;
color: #777;
}
}
}
@@ -0,0 +1,3 @@
.comment__avatar_default {
border: 1px solid #9cdddb;
}
@@ -1,10 +1,8 @@
@import '../comment.vars';
.comment__avatar {
display: inline-block;
width: $avatarSize;
height: $avatarSize;
margin-right: $avatarOffset;
width: 24px;
height: 24px;
margin-right: 8px;
vertical-align: middle;
border-radius: 4px;
}
@@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<style>
.st6{fill:#8ED0CF}
</style>
<g>
<path d="M4.6 20.5s0 .1 0 0c.9 0 .9-.7 1.9-.7.9 0 .9.8 1.9.8.9 0 .9-.8 1.9-.8s.9.8 1.9.8c.9 0 .9-.8 1.9-.8.9 0 .9.8 1.9.8.9 0 .9-.8 1.9-.8.9 0 .9.8 1.8.8l-.7-3.5c-.2-1.3-.3-2.7-.3-4V9.5c0-3.6-2.9-6.9-6.5-7-3.8-.1-6.9 2.9-6.9 6.7v3.9c0 1.3-.1 2.7-.3 4l-.4 3.4z" fill="#f5f4f4"/>
<path d="M8 17.1c.1-1.3.2-2.7.2-4V9.2c0-3.6 1.6-6.5 3.7-6.7-3.6.1-6.5 3-6.5 6.7v3.9c0 1.3-.1 2.7-.3 4l-.5 3.5c.9 0 .9-.8 1.9-.8.7 0 .9.4 1.3.6l.2-3.3z" opacity=".5" fill="#fff"/>
<g>
<path class="st6" d="M19.3 17c-.2-1.3-.3-2.6-.3-3.9V9.4c0-3.8-2.9-7-6.6-7.3-1.9-.1-3.8.6-5.2 1.9-1.4 1.4-2.3 3.2-2.3 5.2v3.9c0 1.3-.1 2.6-.3 3.9l-.5 3.5c0 .1 0 .2.1.3.1.1.2.2.3.2.6 0 .9-.3 1.2-.5.2-.2.4-.3.7-.3.3 0 .5.1.7.3.3.2.6.5 1.2.5s.9-.3 1.2-.5c.2-.2.4-.3.7-.3s.5.1.7.3c.3.2.6.5 1.2.5s.9-.3 1.2-.5c.2-.2.4-.3.7-.3s.5.1.7.3c.3.2.6.5 1.2.5s.9-.3 1.2-.5c.2-.2.4-.3.7-.3.3 0 .5.1.7.3.3.2.6.5 1.2.5.1 0 .2 0 .3-.1.1-.1.1-.2.1-.3l-.8-3.6zm-.5 2.9c-.3-.2-.6-.5-1.2-.5s-.9.3-1.2.5c-.2.2-.4.3-.7.3-.3 0-.5-.1-.7-.3-.3-.2-.6-.5-1.2-.5s-.9.3-1.2.5c-.2.2-.4.3-.7.3-.3 0-.5-.1-.7-.3-.3-.2-.6-.5-1.2-.5s-.9.3-1.2.5c-.2.2-.4.3-.7.3-.3 0-.5-.1-.7-.3-.3-.2-.6-.5-1.2-.5s-.9.3-1.2.5c.2 0 .1.1 0 .1l.4-2.9c.2-1.3.3-2.7.3-4V9.2c0-1.8.7-3.4 2-4.6 1.3-1.2 2.9-1.8 4.7-1.7 3.3.2 5.9 3.1 5.9 6.5V13c0 1.3.1 2.7.3 4l.4 3c-.1 0-.2-.1-.2-.1z"/>
<path class="st6" d="M9.7 7.6c-.6 0-.8.8-.8 1.6s.2 1.6.8 1.6.8-.8.8-1.6-.3-1.6-.8-1.6z"/>
<path class="st6" d="M14.4 7.6c-.6 0-.8.8-.8 1.6s.2 1.6.8 1.6.8-.8.8-1.6-.3-1.6-.8-1.6z"/>
</g>
<linearGradient gradientUnits="userSpaceOnUse" x1="4.1669" y1="14.7127" x2="21.3949" y2="6.6792" gradientTransform="matrix(1 0 0 -1 0 24)">
<stop offset="0" stop-color="#fff" stop-opacity=".2"/>
<stop offset="1" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -0,0 +1,17 @@
.comment__control {
margin-right: 8px;
cursor: pointer;
color: #8CD4D4;
&:last-child {
margin-right: 0;
}
&:hover {
color: #0aa;
}
&:focus {
outline: none;
}
}
@@ -2,17 +2,11 @@
display: inline;
vertical-align: middle;
user-select: none;
font-size: 14px;
font-weight: 700;
@media (hover: hover) {
font-weight: 700;
opacity: 0;
}
+ .comment__controls_view_admin {
&::before {
content: '';
margin-left: 8px;
color: #777;
}
}
}
@@ -1,3 +1,6 @@
.comment__info {
margin-bottom: 4px;
margin-bottom: 6px;
padding-right: 64px;
font-size: 14px;
line-height: 16px;
}
@@ -1,4 +1,3 @@
.comment__input {
padding-left: 32px;
margin-top: 8px;
}
@@ -1,3 +0,0 @@
.comment__score-sign {
font-size: 14px;
}
@@ -1,3 +1,6 @@
.comment__score-value {
display: inline-block;
min-width: 24px;
text-align: center;
font-size: 14px;
}
@@ -0,0 +1,3 @@
.comment__score_view_negative {
color: #cc0606;
}
@@ -0,0 +1,3 @@
.comment__score_view_positive {
color: #259e06;
}
@@ -1,8 +1,12 @@
.comment__score {
display: inline-block;
margin-left: 8px;
vertical-align: middle;
position: absolute;
top: 4px;
right: 0;
min-width: 60px;
font-size: 0;
color: #666;
font-weight: 700;
text-align: right;
color: #AAA;
user-select: none;
cursor: default;
}
@@ -1,6 +1,5 @@
.comment__time {
margin-left: 8px;
vertical-align: middle;
font-size: 14px;
color: #666;
color: #999;
}
@@ -1,6 +1,6 @@
.comment__vote {
display: inline-block;
border-top: 9px solid #ccc;
border-top: 9px solid #dedede;
border-right: 7px solid transparent;
border-left: 7px solid transparent;
font-size: 0;
@@ -1,13 +1,13 @@
@import '../comment.vars';
$step: 24px;
@for $i from 1 through 5 {
.comment_level {
&_#{$i} {
padding-left: $i * ($avatarSize + $avatarOffset);
padding-left: $i * $step;
&.comment_replying {
.comment__input {
margin-left: -$i * ($avatarSize + $avatarOffset);
margin-left: -$i * $step;
@media (min-width: 768px) {
margin-left: 0;
@@ -1,5 +1,3 @@
@import 'common/variables';
.comment_pinned {
&, &.comment_view_admin {
.comment__username {
@@ -1,5 +1,6 @@
.comment_replying {
border: 3px solid #eee;
padding-bottom: 0;
@media (min-width: 768px) {
border: 0;
@@ -18,11 +19,19 @@
border-left-width: 0;
border-right-width: 0;
border-bottom-width: 0;
padding-left: 0;
@media (min-width: 768px) {
border: 3px solid #eee;
padding-left: 32px;
}
}
.comment__score {
top: 12px;
right: 8px;
@media (min-width: 768px) {
top: 4px;
right: 0;
}
}
}
+103 -93
View File
@@ -176,13 +176,6 @@ export default class Comment extends Component {
const isAdmin = !guest && store.get('user').admin;
const isGuest = guest || !Object.keys(store.get('user')).length;
const time = new Date(data.time);
// TODO: which format for datetime should we choose?
// TODO: add smth that will count 'hours ago' (mb this: https://github.com/catamphetamine/javascript-time-ago)
// TODO: check out stash's impl;
// TODO: don't forget about optional locales, m?
// TODO: also date must be a link to the comment
const timeStr = `${time.toLocaleDateString([], { month: 'short', day: 'numeric' })}, ${time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
const o = {
...data,
text:
@@ -197,14 +190,16 @@ export default class Comment extends Component {
: data.text
)
),
time: timeStr,
time: formatTime(new Date(data.time)),
score: {
value: Math.abs(score),
sign: score > 0 ? '+' : (score < 0 ? '' : ''),
sign: score > 0 ? '+' : (score < 0 ? '' : null),
view: score > 0 ? 'positive' : (score < 0 ? 'negative' : null),
},
user: {
...data.user,
picture: data.user.picture.indexOf(API_BASE) === 0 ? `${BASE_URL}${data.user.picture}` : data.user.picture,
isDefaultPicture: data.user.picture.indexOf('/avatar/remark.image') > -1, // TODO: rewrite it on backend
},
};
@@ -234,116 +229,120 @@ export default class Comment extends Component {
<div className={b('comment', props, defaultMods)} id={`remark__comment-${o.id}`}>
<div className="comment__body">
<div className="comment__info">
<img src={o.user.picture} alt="" className="comment__avatar"/>
<img
className={b('comment__avatar', {}, { default: o.user.isDefaultPicture })}
src={o.user.isDefaultPicture ? require('./__avatar/comment__avatar.svg') : o.user.picture}
alt=""
/>
<span className="comment__username">{o.user.name}</span>
{
!isGuest && (
<span className="comment__score">
<span
className={b('comment__vote', {}, { type: 'up', selected: scoreIncreased })}
onClick={this.increaseScore}
>vote up</span>
<span className="comment__score-sign">{o.score.sign}</span>
<span className="comment__score-value">{o.score.value}</span>
<span
className={b('comment__vote', {}, { type: 'down', selected: scoreDecreased })}
onClick={this.decreaseScore}
>vote down</span>
</span>
)
}
<span className="comment__time">{o.time}</span>
{
isAdmin && userBlocked && (
<span className="comment__status">blocked</span>
<span className="comment__status">Blocked</span>
)
}
{
isAdmin && !userBlocked && deleted && (
<span className="comment__status">deleted</span>
<span className="comment__status">Deleted</span>
)
}
{
!mods.disabled && !isGuest && (
<span className="comment__controls">
!isGuest && (
<span className={b('comment__score', {}, { view: o.score.view })}>
<span
className="comment__action"
tabIndex="0"
onClick={this.toggleInputVisibility}
>reply</span>
</span>
)
}
className={b('comment__vote', {}, { type: 'up', selected: scoreIncreased })}
onClick={this.increaseScore}
>Vote up</span>
{
isAdmin &&
(
<span className={b('comment__controls', {}, { view: 'admin' })}>
<span className="comment__score-value">
{o.score.sign}{o.score.value}
</span>
{
!pinned && (
<span
className="comment__action"
tabIndex="0"
onClick={this.onPinClick}
>pin</span>
)
}
{
pinned && (
<span
className="comment__action"
tabIndex="0"
onClick={this.onUnpinClick}
>unpin</span>
)
}
{
userBlocked && (
<span
className="comment__action"
tabIndex="0"
onClick={this.onUnblockClick}
>unblock</span>
)
}
{
!userBlocked && (
<span
className="comment__action"
tabIndex="0"
onClick={this.onBlockClick}
>block</span>
)
}
{
!deleted && (
<span
className="comment__action"
tabIndex="0"
onClick={this.onDeleteClick}
>delete</span>
)
}
<span
className={b('comment__vote', {}, { type: 'down', selected: scoreDecreased })}
onClick={this.decreaseScore}
>Vote down</span>
</span>
)
}
</div>
<div className="comment__text" dangerouslySetInnerHTML={{ __html: o.text }}/>
<div className="comment__actions">
{
!mods.disabled && !isGuest && (
<span
className="comment__action"
tabIndex="0"
onClick={this.toggleInputVisibility}
>{isInputVisible ? 'Cancel' : 'Reply'}</span>
)
}
{
isAdmin &&
(
<span className="comment__controls">
{
!pinned && (
<span
className="comment__control"
tabIndex="0"
onClick={this.onPinClick}
>Pin</span>
)
}
{
pinned && (
<span
className="comment__control"
tabIndex="0"
onClick={this.onUnpinClick}
>Unpin</span>
)
}
{
userBlocked && (
<span
className="comment__control"
tabIndex="0"
onClick={this.onUnblockClick}
>Unblock</span>
)
}
{
!userBlocked && (
<span
className="comment__control"
tabIndex="0"
onClick={this.onBlockClick}
>Block</span>
)
}
{
!deleted && (
<span
className="comment__control"
tabIndex="0"
onClick={this.onDeleteClick}
>Delete</span>
)
}
</span>
)
}
</div>
</div>
{
@@ -366,3 +365,14 @@ function getTextSnippet(html) {
return (snippet.length === LENGTH && result.length !== LENGTH) ? `${snippet}...` : snippet;
}
function formatTime(time) {
// 'ru-RU' adds a dot as a separator
const date = time.toLocaleDateString(['ru-RU'], { day: '2-digit', month: '2-digit', year: '2-digit' });
// do it manually because Intl API doesn't add leading zeros to hours; idk why
const hours = `0${time.getHours()}`.slice(-2);
const mins = `0${time.getMinutes()}`.slice(-2);
return `${date} at ${hours}:${mins}`;
}
+3 -3
View File
@@ -1,9 +1,9 @@
@import 'common/variables';
.comment {
position: relative;
overflow: hidden;
margin-bottom: $offset / 2;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid #fcfcfc;
font-size: 16px;
line-height: 1.2;
@@ -1,2 +0,0 @@
$avatarSize: 24px;
$avatarOffset: 8px;
+8 -1
View File
@@ -3,12 +3,19 @@ export { default } from './comment';
require('./comment.scss');
require('./__action/comment__action.scss');
require('./__avatar/comment__avatar.scss');
require('./__avatar/_default/comment__avatar_default.scss');
require('./__control/comment__control.scss');
require('./__controls/comment__controls.scss');
require('./__info/comment__info.scss');
require('./__input/comment__input.scss');
require('./__score/comment__score.scss');
require('./__score-sign/comment__score-sign.scss');
require('./__score/_view/_negative/comment__score_view_negative.scss');
require('./__score/_view/_positive/comment__score_view_positive.scss');
require('./__score-value/comment__score-value.scss');
require('./__status/comment__status.scss');
require('./__text/comment__text.scss');
@@ -3,6 +3,7 @@
padding: 8px 12px;
font-size: 16px;
border: 0;
border-radius: 2px;
cursor: pointer;
&:focus {
+1
View File
@@ -3,5 +3,6 @@
display: block;
font-size: 0;
border: 3px solid #eee;
border-radius: 2px;
background: #eee;
}
@@ -1,5 +1,7 @@
.root__pinned-comment {
&:last-child {
margin-bottom: 0;
border-bottom: 0;
padding-bottom: 0;
}
}
@@ -4,5 +4,5 @@
margin-top: 24px;
padding: ($offset / 3) ($offset / 2);
border: 2px solid #0aa;
border-radius: 4px;
border-radius: 2px;
}
+4
View File
@@ -1,4 +1,8 @@
.root {
position: relative;
font-family: 'PT Sans', Helvetica, Arial, sans-serif;
::selection {
background: #c6efef;
}
}
-2
View File
@@ -1,3 +1 @@
export { default } from './thread';
require('./thread.scss');
-5
View File
@@ -1,5 +0,0 @@
@import 'common/variables';
.thread {
margin-bottom: $offset / 2;
}
+1 -1
View File
@@ -83,7 +83,7 @@ module.exports = {
],
},
{
test: /\.(png|jpg|jpeg|gif)$/,
test: /\.(png|jpg|jpeg|gif|svg)$/,
use: {
loader: 'file-loader',
options: {