Implement low-hanging-fruit feed card comment frontend tweaks (#19416)
This commit is contained in:
parent
5faae0bb6d
commit
cb2c200404
10 changed files with 204 additions and 37 deletions
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
.crayons-comment {
|
||||
font-size: var(--fs-s);
|
||||
padding: var(--su-2) var(--su-3);
|
||||
padding-bottom: var(--su-3);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding-left: var(--su-3);
|
||||
margin-right: var(--su-3);
|
||||
|
||||
&__meta {
|
||||
display: flex;
|
||||
|
|
@ -14,11 +18,60 @@
|
|||
}
|
||||
}
|
||||
|
||||
&__metainner {
|
||||
color: var(--base-80);
|
||||
margin-bottom: var(--su-1);
|
||||
}
|
||||
|
||||
&__body {
|
||||
padding-left: var(--su-7);
|
||||
max-height: 310px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: var(--card-tertiary-bg);
|
||||
&:hover {
|
||||
background: var(--card-tertiary-bg-hover);
|
||||
}
|
||||
|
||||
border-radius: var(--radius);
|
||||
padding: var(--su-4);
|
||||
padding-bottom: var(--su-1);
|
||||
.crayons-comment__inner {
|
||||
.c-embed {
|
||||
padding-top: var(--su-3);
|
||||
padding-bottom: var(--su-1);
|
||||
}
|
||||
.c-embed__cover {
|
||||
display: none;
|
||||
}
|
||||
.c-embed__body {
|
||||
font-size: var(--fs-s);
|
||||
}
|
||||
div:not(.crayons-comment__readmore) {
|
||||
margin-bottom: var(--su-3);
|
||||
background: var(--card-secondary-bg);
|
||||
}
|
||||
.liquid-comment .body {
|
||||
:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.crayons-comment__readmore {
|
||||
color: var(--base-80);
|
||||
font-weight: var(--fw-medium);
|
||||
margin-bottom: var(--su-1);
|
||||
margin-top: -3px;
|
||||
padding-bottom: var(--su-1);
|
||||
}
|
||||
img {
|
||||
max-height: 130px;
|
||||
border-radius: var(--radius);
|
||||
max-width: 220px;
|
||||
}
|
||||
iframe {
|
||||
max-height: 240px;
|
||||
border-radius: var(--radius);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline; //todo: default for all in-content links
|
||||
|
|
@ -42,19 +95,6 @@
|
|||
margin: var(--su-1) auto;
|
||||
font-size: 90%; // little adjustment for feed comments since default monospace font looks really tiny there.
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: linear-gradient(
|
||||
var(--story-comments-bg-top) 250px,
|
||||
var(--story-comments-bg-bottom)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
& + & {
|
||||
|
|
|
|||
|
|
@ -217,18 +217,19 @@
|
|||
|
||||
&__comments {
|
||||
cursor: default;
|
||||
background: var(--story-comments-bg);
|
||||
border-radius: var(--radius);
|
||||
position: relative;
|
||||
bottom: var(--su-2);
|
||||
margin: var(--su-2);
|
||||
margin-bottom: 0;
|
||||
margin-top: -3px;
|
||||
padding: var(--su-2) 0;
|
||||
|
||||
@media (min-width: $breakpoint-s) {
|
||||
bottom: var(--su-3);
|
||||
margin: var(--su-3);
|
||||
margin-bottom: 0;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
&__headline {
|
||||
|
|
@ -242,6 +243,9 @@
|
|||
&__actions {
|
||||
padding-left: calc(var(--su-6) + var(--su-4));
|
||||
margin-top: var(--su-1);
|
||||
a {
|
||||
font-weight: var(--fw-medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
--card-color-secondary: rgb(var(--grey-700));
|
||||
--card-color-tertiary: rgb(var(--grey-600));
|
||||
--card-secondary-bg: rgb(var(--grey-50));
|
||||
--card-tertiary-bg: rgb(var(--grey-100));
|
||||
--card-tertiary-bg-hover: rgba(var(--grey-200), 0.55);
|
||||
--card-secondary-color: rgb(var(--grey-700));
|
||||
--card-border: rgba(var(--grey-900), 0.1);
|
||||
--card-secondary-border: rgba(var(--grey-900), 0.05);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@
|
|||
text-align: right;
|
||||
display: block;
|
||||
width: 100px;
|
||||
:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
a {
|
||||
color: var(--card-color-tertiary);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
padding: calc(0.6vw + 8px) calc(0.8vw + 8px);
|
||||
padding-right: 8px;
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--radius);
|
||||
img {
|
||||
width: calc(1.2vw + 40px);
|
||||
height: calc(1.2vw + 40px);
|
||||
|
|
@ -90,7 +91,7 @@
|
|||
box-sizing: border-box;
|
||||
max-width: 55px;
|
||||
max-height: 55px;
|
||||
}
|
||||
}
|
||||
.ltag__link__user__pic {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
|
|
@ -123,7 +124,7 @@
|
|||
padding: 0;
|
||||
font-weight: var(--fw-bold);
|
||||
font-size: calc(1.45em + 0.2vw);
|
||||
line-height: var(--lh-tight)
|
||||
line-height: var(--lh-tight);
|
||||
}
|
||||
h3 {
|
||||
margin: calc(0.3vw + 1px) 0;
|
||||
|
|
@ -206,4 +207,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@
|
|||
--card-color-tertiary: rgb(var(--grey-400));
|
||||
--card-secondary-bg: rgb(var(--grey-900));
|
||||
--card-secondary-color: rgb(var(--grey-200));
|
||||
--card-tertiary-bg: rgb(var(--grey-100));
|
||||
--card-tertiary-bg-hover: rgba(var(--grey-200), 0.55);
|
||||
--card-border: rgba(var(--white), 0.15);
|
||||
--card-secondary-border: rgba(var(--white), 0.1);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
articleWithReactions,
|
||||
videoArticle,
|
||||
articleWithComments,
|
||||
articleWithCommentWithLongParagraph,
|
||||
podcastArticle,
|
||||
podcastEpisodeArticle,
|
||||
userArticle,
|
||||
|
|
@ -200,6 +201,36 @@ describe('<Article /> component', () => {
|
|||
expect(comments.textContent).toEqual(`213 ${locale('core.comment')}s`);
|
||||
});
|
||||
|
||||
it('should render second paragraph, but not third', () => {
|
||||
const { queryByTestId } = render(
|
||||
<Article
|
||||
{...commonProps}
|
||||
isBookmarked={false}
|
||||
article={articleWithComments}
|
||||
/>,
|
||||
);
|
||||
|
||||
const comments = queryByTestId('comment-content');
|
||||
|
||||
expect(comments.textContent).toContain('Kitsch hoodie artisan');
|
||||
expect(comments.classList).not.toContain('Third paragraph');
|
||||
});
|
||||
|
||||
it('should render the first part of a long paragraph', () => {
|
||||
const { queryByTestId } = render(
|
||||
<Article
|
||||
{...commonProps}
|
||||
isBookmarked={false}
|
||||
article={articleWithCommentWithLongParagraph}
|
||||
/>,
|
||||
);
|
||||
|
||||
const comments = queryByTestId('comment-content');
|
||||
|
||||
expect(comments.textContent).toContain('Start of paragraph');
|
||||
expect(comments.classList).not.toContain('End of paragraph');
|
||||
});
|
||||
|
||||
it('should render with an add comment button when there are no comments', () => {
|
||||
const { queryByTestId } = render(
|
||||
<Article {...commonProps} isBookmarked={false} article={article} />,
|
||||
|
|
|
|||
|
|
@ -198,7 +198,53 @@ export const articleWithComments = {
|
|||
user_id: 6,
|
||||
published_timestamp: '2020-04-21T19:41:40Z',
|
||||
published_at_int: new Date(),
|
||||
safe_processed_html: '<p>Kitsch hoodie artisan.</p>\n\n',
|
||||
safe_processed_html:
|
||||
'<p>Kitsch hoodie artisan.</p><p>Second paragraph.</p><p>Third paragraph.</p>\n\n',
|
||||
path: '/naoma_dr_rice/comment/n',
|
||||
username: 'naoma_dr_rice',
|
||||
name: 'Dr. Naoma Rice',
|
||||
profile_image_90: '/images/7.png',
|
||||
},
|
||||
],
|
||||
public_reactions_count: 428,
|
||||
comments_count: 213,
|
||||
};
|
||||
|
||||
export const articleWithCommentWithLongParagraph = {
|
||||
id: 62407,
|
||||
title: 'Unbranded Home Loan Account',
|
||||
path: '/some-post/path',
|
||||
type_of: '',
|
||||
class_name: 'Article',
|
||||
flare_tag: {
|
||||
id: 35682,
|
||||
name: 'javascript',
|
||||
hotness_score: 99,
|
||||
points: 23,
|
||||
bg_color_hex: '#000000',
|
||||
text_color_hex: '#ffffff',
|
||||
},
|
||||
tag_list: ['javascript', 'ruby', 'go'],
|
||||
cached_tag_list_array: [],
|
||||
user_id: 23289,
|
||||
user: {
|
||||
username: 'Emil99',
|
||||
name: 'Stella Macejkovic',
|
||||
profile_image_90: '/images/10.png',
|
||||
},
|
||||
published_at_int: 1582037964819,
|
||||
published_timestamp: 'Tue, 18 Feb 2020 14:59:24 GMT',
|
||||
published_at: '2020-03-19T10:04:15-05:00',
|
||||
readable_publish_date: 'February 18',
|
||||
top_comments: [
|
||||
{
|
||||
comment_id: 23,
|
||||
user_id: 6,
|
||||
published_timestamp: '2020-04-21T19:41:40Z',
|
||||
published_at_int: new Date(),
|
||||
safe_processed_html:
|
||||
`<p>Start of paragraph. This is a long test paragraph. This is a long test paragraph. This is a long test paragraph. This is a long test paragraph. This is a long test paragraph.
|
||||
This is a long test paragraph. This is a long test paragraph. Yes it is really really really really really long. For real, like really real. Okay, this is long enough. End of paragraph</p>\n\n`,
|
||||
path: '/naoma_dr_rice/comment/n',
|
||||
username: 'naoma_dr_rice',
|
||||
name: 'Dr. Naoma Rice',
|
||||
|
|
|
|||
|
|
@ -8,11 +8,43 @@ function userProfilePage(username) {
|
|||
return str;
|
||||
}
|
||||
|
||||
function contentAwareComments(comment) {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(
|
||||
comment.safe_processed_html,
|
||||
'text/html',
|
||||
);
|
||||
const nodes = htmlDoc.body.childNodes;
|
||||
let text = '';
|
||||
let nodesSelected = 0;
|
||||
nodes.forEach((node) => {
|
||||
if (
|
||||
node.outerHTML &&
|
||||
node.tagName === 'P' &&
|
||||
nodesSelected < 2 &&
|
||||
node.outerHTML.length > 250
|
||||
) {
|
||||
text = `${text} ${node.outerHTML.substring(0, 230)} ...`;
|
||||
nodesSelected = 2;
|
||||
} else if (node.outerHTML && nodesSelected < 2) {
|
||||
text = text + node.outerHTML;
|
||||
nodesSelected++;
|
||||
} else if (node.outerHTML && nodesSelected < 3) {
|
||||
text = `${text} <div class="crayons-comment__readmore">See more</div>`;
|
||||
nodesSelected++;
|
||||
}
|
||||
});
|
||||
return text;
|
||||
}
|
||||
|
||||
export const CommentListItem = ({ comment }) => (
|
||||
<div
|
||||
className="crayons-comment cursor-pointer"
|
||||
role="presentation"
|
||||
onClick={(_event) => {
|
||||
if (_event.target.closest('a')) {
|
||||
return;
|
||||
}
|
||||
if (_event.which > 1 || _event.metaKey || _event.ctrlKey) {
|
||||
// Indicates should open in _blank
|
||||
window.open(comment.path, '_blank');
|
||||
|
|
@ -35,23 +67,28 @@ export const CommentListItem = ({ comment }) => (
|
|||
alt="{comment.username} avatar"
|
||||
/>
|
||||
</span>
|
||||
{comment.name}
|
||||
</a>
|
||||
<a href={comment.path} className="crayons-story__tertiary ml-1">
|
||||
<time>
|
||||
{timeAgo({
|
||||
oldTimeInSeconds: comment.published_at_int,
|
||||
formatter: (x) => x,
|
||||
maxDisplayedAge: NaN,
|
||||
})}
|
||||
</time>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="crayons-comment__body"
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html: comment.safe_processed_html }}
|
||||
/>
|
||||
<div className="crayons-comment__body">
|
||||
<div class="crayons-comment__metainner">
|
||||
<span class="fw-medium">{comment.name}</span>
|
||||
<a href={comment.path} className="crayons-story__tertiary ml-1">
|
||||
<time>
|
||||
{timeAgo({
|
||||
oldTimeInSeconds: comment.published_at_int,
|
||||
formatter: (x) => x,
|
||||
maxDisplayedAge: NaN,
|
||||
})}
|
||||
</time>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
data-testid="comment-content"
|
||||
className="crayons-comment__inner"
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html: contentAwareComments(comment) }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export const CommentsCount = ({ count, articlePath, articleTitle }) => {
|
|||
url={`${articlePath}#comments`}
|
||||
icon={commentsSVG}
|
||||
tagName="a"
|
||||
className="flex items-center"
|
||||
aria-label={commentsAriaLabelText}
|
||||
>
|
||||
<span title="Number of comments">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue