fix: post summary card (#196)

* fix: post summery card
This commit is contained in:
Awais Ansari
2022-06-16 17:23:45 +05:00
committed by GitHub
parent b9cb2f3e2e
commit 275dd99b18
27 changed files with 358 additions and 287 deletions

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function Help(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 24,
height: 24,
viewBox: '0 0 24 24',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z',
fill: '#2D494E',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function People() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
viewBox="0 0 16 16"
>
<path
fill="#000"
d="M11.072 7.332a1.992 1.992 0 001.993-2 1.997 1.997 0 10-3.993 0c0 1.107.893 2 2 2zm-5.334 0a1.992 1.992 0 001.994-2 1.997 1.997 0 10-3.993 0c0 1.107.893 2 2 2zm0 1.333c-1.553 0-4.666.78-4.666 2.334v1.666h9.333V11c0-1.554-3.113-2.334-4.667-2.334zm5.334 0c-.194 0-.414.014-.647.034.773.56 1.313 1.313 1.313 2.3v1.666h4V11c0-1.554-3.113-2.334-4.666-2.334z"
/>
</svg>
);
}

View File

@@ -0,0 +1,35 @@
import React from 'react';
export default function Question() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="29"
height="28"
fill="none"
viewBox="0 0 29 28"
>
<g clipPath="url(#clip0_5714_503)">
<path
fill="#2D494E"
stroke="#fff"
strokeWidth="2"
d="M14.404 1.333C7.412 1.333 1.737 7.008 1.737 14s5.675 12.667 12.667 12.667S27.07 20.992 27.07 14 21.396 1.333 14.404 1.333z"
/>
<path
fill="#fff"
d="M13.237 22.167h2.333v-2.334h-2.333v2.334zM16.936 14.198l1.05-1.073A3.712 3.712 0 0019.07 10.5a4.665 4.665 0 00-4.666-4.667A4.665 4.665 0 009.737 10.5h2.333a2.34 2.34 0 012.334-2.333 2.34 2.34 0 012.333 2.333c0 .642-.256 1.225-.688 1.645l-1.447 1.47a4.696 4.696 0 00-1.365 3.302v.583h2.333c0-1.75.526-2.45 1.366-3.302z"
/>
</g>
<defs>
<clipPath id="clip0_5714_503">
<path
fill="#fff"
d="M0 0H28V28H0z"
transform="translate(.404)"
/>
</clipPath>
</defs>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function QuestionAnswer(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M16.7371 4.00002H14.2371V11.5H3.4038V14H13.4038L16.7371 17.3334V4.00002ZM12.5705 9.83335V0.666687H0.0704651V13.1667L3.4038 9.83335H12.5705Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function QuestionAnswer() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="20"
fill="none"
viewBox="0 0 21 20"
>
<path
fill="currentColor"
d="M18.737 5h-2.5v7.5H5.404V15h10l3.333 3.333V5zm-4.166 5.833V1.667H2.07v12.5l3.333-3.334h9.166z"
/>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function QuestionAnswerOutline(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M 16.7371 4 H 14.2371 V 11.5 H 3.4038 V 14 H 13.4038 L 16.7371 17.3334 V 4 Z M 12.5705 9.8333 V 0.6667 H 0.0705 V 13.1667 L 3.4038 9.8333 H 12.5705 Z M 11.465 8.618 H 1.038 V 1.683 H 11.465Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function QuestionAnswerOutline() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="none"
viewBox="0 0 20 20"
>
<path
fill="currentColor"
d="M12.6 3.267v6.067H4.08l-.512.512-.502.502v-7.08H12.6zm.867-1.733H2.198a.87.87 0 00-.867.867v12.134L4.8 11.068h8.668a.87.87 0 00.866-.867v-7.8a.87.87 0 00-.867-.867zM17.8 5h-1.733v7.8H4.799v1.734c0 .476.39.867.867.867H15.2l3.467 3.466v-13A.87.87 0 0017.8 5z"
/>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function StarFilled(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M8.4038 13.3917L13.5538 16.5L12.1871 10.6417L16.7371 6.70002L10.7455 6.19169L8.4038 0.666687L6.06213 6.19169L0.0704651 6.70002L4.62047 10.6417L3.2538 16.5L8.4038 13.3917Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function StarFilled() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="20"
fill="none"
viewBox="0 0 21 20"
>
<path
fill="currentColor"
d="M10.404 14.392l5.15 3.108-1.367-5.858 4.55-3.942-5.991-.508-2.342-5.525-2.342 5.525L2.07 7.7l4.55 3.942L5.254 17.5l5.15-3.108z"
/>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function StarOutline(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M16.7371 6.69999L10.7455 6.18332L8.4038 0.666656L6.06213 6.19166L0.0704651 6.69999L4.62047 10.6417L3.2538 16.5L8.4038 13.3917L13.5538 16.5L12.1955 10.6417L16.7371 6.69999ZM8.4038 11.8333L5.27047 13.725L6.1038 10.1583L3.33713 7.75832L6.98713 7.44166L8.4038 4.08332L9.8288 7.44999L13.4788 7.76666L10.7121 10.1667L11.5455 13.7333L8.4038 11.8333Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function StarOutline() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="none"
viewBox="0 0 20 20"
>
<path
fill="currentColor"
d="M18.737 7.7l-5.991-.517-2.342-5.516-2.342 5.525L2.07 7.7l4.55 3.942L5.254 17.5l5.15-3.108 5.15 3.108-1.359-5.858L18.737 7.7zm-8.333 5.133L7.27 14.725l.834-3.567-2.767-2.4 3.65-.316 1.417-3.359 1.425 3.367 3.65.317-2.767 2.4.834 3.566-3.142-1.9z"
/>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function ThumbUpFilled(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M11.2122 0.833344L5.23715 6.81668V17.5H15.4955L18.5705 10.3333V6.66668H11.6455L12.5788 2.18334L11.2122 0.833344ZM0.237152 7.50001H3.57049V17.5H0.237152V7.50001Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
export default function ThumbUpFilled() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="21"
height="20"
fill="none"
viewBox="0 0 21 20"
>
<path
fill="currentColor"
d="M12.212.833L6.237 6.817V17.5h10.258l3.075-7.167V6.667h-6.925l.934-4.484-1.367-1.35zM1.237 7.5H4.57v10H1.237v-10z"
/>
</svg>
);
}

View File

@@ -1,16 +0,0 @@
import * as React from 'react';
import { _extends } from './common';
export default function ThumbUpOutline(props) {
return /* #__PURE__ */React.createElement('svg', _extends({
width: 20,
height: 20,
viewBox: '0 0 20 20',
fill: 'none',
xmlns: 'http://www.w3.org/2000/svg',
}, props), /* #__PURE__ */React.createElement('path', {
d: 'M18.5705 6.66668V10.3333L15.4955 17.5L5.23715 17.5L5.23715 6.81668L11.2122 0.833344L12.5788 2.18334L11.6455 6.66668L18.5705 6.66668ZM6.90382 7.50834L6.90382 15.8333L14.3955 15.8333L16.9038 9.99168V8.33334L9.59548 8.33334L10.5205 3.88334L6.90382 7.50834Z M3.57049 17.5H0.237152L0.237152 7.50001H3.57049L3.57049 17.5Z',
fill: 'currentColor',
}));
}

View File

@@ -0,0 +1,21 @@
import React from 'react';
export default function ThumbUpOutline() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="none"
viewBox="0 0 20 20"
>
<path
fill="currentColor"
fillRule="evenodd"
d="M19.57 6.667v3.666L16.495 17.5H6.238V6.817L12.212.833l1.367 1.35-.934 4.484h6.925zm-11.666.841v8.325h7.492l2.508-5.841V8.333h-7.309l.925-4.45-3.616 3.625z"
clipRule="evenodd"
/>
<path fill="currentColor" d="M4.57 17.5H1.237v-10H4.57v10z" />
</svg>
);
}

View File

@@ -1,21 +0,0 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-func-assign */
/* eslint-disable prefer-object-spread */
/* eslint-disable prefer-rest-params */
/* eslint-disable no-param-reassign */
/* eslint-disable no-restricted-syntax */
// eslint-disable-next-line import/prefer-default-export
export function _extends() {
_extends = Object.assign || function (target) {
for (let i = 1; i < arguments.length; i++) {
const source = arguments[i];
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}

View File

@@ -1,4 +1,5 @@
export { default as Help } from './Help';
export { default as People } from './People';
export { default as Question } from './Question';
export { default as QuestionAnswer } from './QuestionAnswer';
export { default as QuestionAnswerOutline } from './QuestionAnswerOutline';
export { default as StarFilled } from './StarFilled';

View File

@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import capitalize from 'lodash/capitalize';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Icon } from '@edx/paragon';
@@ -18,6 +19,7 @@ function AuthorLabel({
}) {
let icon = null;
let authorLabelMessage = null;
if (authorLabel === 'Staff') {
icon = Institution;
authorLabelMessage = intl.formatMessage(messages.authorLabelStaff);
@@ -26,9 +28,15 @@ function AuthorLabel({
icon = School;
authorLabelMessage = intl.formatMessage(messages.authorLabelTA);
}
const fontWeight = authorLabelMessage ? 'font-weight-500' : 'font-weight-normal text-primary-500';
const className = classNames('d-flex align-items-center', labelColor);
const labelContents = (
<>
<span className="mr-1 font-weight-normal font-size-14 font-style-normal font-family-inter">{author}</span>
<span className={`mr-1 font-size-14 font-style-normal font-family-inter ${fontWeight}`}>
{capitalize(author)}
</span>
{icon && (
<Icon
style={{
@@ -39,13 +47,16 @@ function AuthorLabel({
/>
)}
{authorLabelMessage && (
<span className="mr-3 ml-1 font-weight-normal font-size-14 font-style-normal font-family-inter">
<span
className={`mr-3 font-size-14 font-style-normal font-family-inter ${fontWeight}`}
style={{ marginLeft: '2px' }}
>
{authorLabelMessage}
</span>
)}
</>
);
const className = classNames('d-flex align-items-center', labelColor);
return linkToProfile
? React.createElement('a', { href: '#nowhere', className }, labelContents)
: React.createElement('div', { className }, labelContents);

View File

@@ -11,8 +11,8 @@ export default function timeLocale(number, index, totalSec) {
['%sd', 'in %s days'],
['1w', 'in 1 week'],
['%sw', 'in %s weeks'],
['1M', 'in 1 month'],
['%sM', 'in %s months'],
['1m', 'in 1 month'],
['%sm', 'in %s months'],
['1y', 'in 1 year'],
['%sy', 'in %s years'],
][index];

View File

@@ -114,18 +114,21 @@ describe('PostsView', () => {
});
expect(screen.getAllByText(/this is thread-\d+/i)).toHaveLength(threadCount);
});
test('displays a list of user posts', async () => {
await act(async () => {
await renderComponent({ myPosts: true });
});
expect(screen.getAllByText('abc123')).toHaveLength(threadCount);
expect(screen.getAllByText('Abc123')).toHaveLength(threadCount);
});
test('displays a list of posts in a topic', async () => {
await act(async () => {
await renderComponent({ topicId: 'some-topic-1' });
});
expect(screen.getAllByText(/this is thread-\d+ in topic some-topic-1/i)).toHaveLength(Math.ceil(threadCount / 3));
});
test('displays a list of posts in a category', async () => {
await act(async () => {
await renderComponent({ category: 'test-usage-key' });

View File

@@ -2,9 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import {
Icon, IconButton, OverlayTrigger, Tooltip,
} from '@edx/paragon';
import { Icon, IconButtonWithTooltip } from '@edx/paragon';
import { ThumbUpFilled, ThumbUpOutline } from '../../../components/icons';
import messages from './messages';
@@ -24,23 +22,19 @@ function LikeButton({
};
return (
<div className="d-flex align-items-center align-content-center mr-4">
<OverlayTrigger
overlay={(
<Tooltip id={`like-${count}-tooltip`}>
{intl.formatMessage(voted ? messages.removeLike : messages.like)}
</Tooltip>
)}
>
<IconButton
onClick={handleClick}
className="p-3 mr-1.5"
alt="Like"
iconAs={Icon}
size="inline"
src={voted ? ThumbUpFilled : ThumbUpOutline}
/>
</OverlayTrigger>
<div className="d-flex align-items-center mr-4">
<IconButtonWithTooltip
id={`like-${count}-tooltip`}
tooltipPlacement="top"
tooltipContent={intl.formatMessage(voted ? messages.removeLike : messages.like)}
src={voted ? ThumbUpFilled : ThumbUpOutline}
iconAs={Icon}
alt="Like"
onClick={handleClick}
size="inline"
className="p-3 mr-0.5"
iconClassNames="icon-size"
/>
{(count && count > 0) ? count : null}
</div>
);

View File

@@ -6,13 +6,14 @@ import * as timeago from 'timeago.js';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import {
Badge, Icon, IconButton, OverlayTrigger, Tooltip,
Badge, Icon, IconButtonWithTooltip, OverlayTrigger, Tooltip,
} from '@edx/paragon';
import {
Locked, People,
Locked,
} from '@edx/paragon/icons';
import {
People,
QuestionAnswer,
QuestionAnswerOutline,
StarFilled,
@@ -31,6 +32,7 @@ function PostFooter({
}) {
const dispatch = useDispatch();
timeago.register('time-locale', timeLocale);
return (
<div className="d-flex align-items-center">
<LikeButton
@@ -38,71 +40,61 @@ function PostFooter({
onClick={() => dispatch(updateExistingThread(post.id, { voted: !post.voted }))}
voted={post.voted}
/>
<OverlayTrigger
overlay={(
<Tooltip id={`follow-${post.id}-tooltip`}>
{intl.formatMessage(post.following ? messages.unfollow : messages.follow)}
</Tooltip>
)}
>
<IconButton
onClick={() => {
dispatch(updateExistingThread(post.id, { following: !post.following }));
return true;
}}
alt="Follow"
iconAs={Icon}
size="inline"
src={post.following ? StarFilled : StarOutline}
/>
</OverlayTrigger>
{preview && post.commentCount > 1
&& (
<IconButtonWithTooltip
id={`follow-${post.id}-tooltip`}
tooltipPlacement="top"
tooltipContent={intl.formatMessage(post.following ? messages.unFollow : messages.follow)}
src={post.following ? StarFilled : StarOutline}
iconAs={Icon}
alt="Follow"
onClick={() => {
dispatch(updateExistingThread(post.id, { following: !post.following }));
return true;
}}
size="inline"
className="p-3"
iconClassNames="icon-size"
/>
{preview && post.commentCount > 1 && (
<div className="d-flex align-items-center ml-4">
<IconButtonWithTooltip
tooltipPlacement="top"
tooltipContent={intl.formatMessage(messages.viewActivity)}
src={post.unreadCommentCount ? QuestionAnswer : QuestionAnswerOutline}
iconAs={Icon}
alt="Comment Count"
size="inline"
className="p-3 mr-0.5"
iconClassNames="icon-size"
/>
{post.commentCount}
</div>
)}
{preview && post?.unreadCommentCount > 0 && post.commentCount > 1 && (
<Badge variant="light" className="ml-2">
{intl.formatMessage(messages.newLabel, { count: post.unreadCommentCount })}
</Badge>
)}
<div className="d-flex flex-fill justify-content-end align-items-center">
{post.groupId && (
<>
<Icon src={post.unreadCommentCount ? QuestionAnswer : QuestionAnswerOutline} className="ml-4 mr-2 my-0 mt-1.5" />
<span style={{ minWidth: '1rem' }}>
{post.commentCount}
<OverlayTrigger
overlay={(
<Tooltip id={`visibility-${post.id}-tooltip`}>{post.groupName}</Tooltip>
)}
>
<span data-testid="cohort-icon">
<People />
</span>
</OverlayTrigger>
<span
className="text-light-700 mx-1.5 font-weight-500"
style={{ fontSize: '16px' }}
>
·
</span>
</>
)}
{post.unreadCommentCount && post.unreadCommentCount > 0 && post.commentCount > 1 ? (
<Badge variant="light">{intl.formatMessage(messages.newLabel, { count: post.unreadCommentCount })}</Badge>
) : null}
<div className="d-flex flex-fill justify-content-end align-items-center">
{
post.groupId
? (
<>
<OverlayTrigger
overlay={(
<Tooltip id={`visibility-${post.id}-tooltip`}>
{post.groupName || intl.formatMessage(messages.visibleToAll)}
</Tooltip>
)}
>
<Icon
data-testid="cohort-icon"
src={People}
style={{
width: '1em',
height: '1em',
color: 'black',
}}
/>
</OverlayTrigger>
<span
className="text-light-700 mx-1.5 ml-1.5 font-weight-500"
style={{
height: '1.5rem',
width: '0.31rem',
fontSize: '16px',
}}
>
·
</span>
</>
) : null
}
<span title={post.createdAt} className="text-gray-500">
{timeago.format(post.createdAt, 'time-locale')}
</span>

View File

@@ -61,7 +61,7 @@ describe('PostFooter', () => {
});
it("shows 'x new' badge for new comments", () => {
renderComponent(mockPost);
renderComponent(mockPost, true);
expect(screen.getByText('2 New')).toBeTruthy();
});
@@ -84,6 +84,7 @@ describe('PostFooter', () => {
renderComponent({ ...mockPost, groupId: 5, groupName: 'Test Cohort' });
expect(screen.getByTestId('cohort-icon')).toBeTruthy();
});
it.each([[true, /unfollow/i], [false, /follow/i]])('test follow button when following=%s', async (following, message) => {
renderComponent({ ...mockPost, following });
const followButton = screen.getByRole('button', { name: /follow/i });

View File

@@ -6,7 +6,7 @@ import { useSelector } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Avatar, Badge, Icon } from '@edx/paragon';
import { Help } from '../../../components/icons';
import { Question } from '../../../components/icons';
import { AvatarBorderAndLabelColors, ThreadType } from '../../../data/constants';
import { ActionsDropdown, AuthorLabel } from '../../common';
import { selectAuthorAvatars } from '../data/selectors';
@@ -16,31 +16,37 @@ import { postShape } from './proptypes';
export function PostAvatar({ post, authorLabel, fromPostLink }) {
const authorAvatars = useSelector(selectAuthorAvatars(post.author));
const borderColor = AvatarBorderAndLabelColors[authorLabel];
return (
<div style={{ width: '3.75rem' }} className="d-flex pr-2.5">
<div className="ml-auto mr-auto">
{post.type === ThreadType.QUESTION && (
<div className={`mr-3 ${post.type !== ThreadType.QUESTION && 'pt-1.5'}`}>
{post.type === ThreadType.QUESTION && (
<Icon
src={Help}
src={Question}
className="position-absolute bg-white rounded-circle"
style={{
width: '1.5rem',
height: '1.5rem',
width: '1.75rem',
height: '1.75rem',
top: fromPostLink ? '10px' : '',
left: fromPostLink ? '14px' : '',
marginTop: !fromPostLink ? '5px' : '',
}}
/>
)}
<Avatar
size={fromPostLink ? 'sm' : 'md'}
className={`${borderColor && `border-${borderColor}`} ${post.type === ThreadType.QUESTION ? 'mt-2.5 ml-2.5' : ''}`}
style={{
borderWidth: '2px',
height: post.type === ThreadType.QUESTION ? '1.5rem' : '2rem',
width: post.type === ThreadType.QUESTION ? '1.5rem' : '2rem',
}}
alt={post.author}
src={authorAvatars?.imageUrlSmall}
/>
</div>
)}
<Avatar
size={fromPostLink ? 'sm' : 'md'}
className={`${borderColor && `border-${borderColor}`}
${post.type === ThreadType.QUESTION && fromPostLink ? 'mt-3 ml-2' : ''}
`}
style={{
borderWidth: '2px',
height: post.type === ThreadType.QUESTION ? '1.5rem' : '2rem',
width: post.type === ThreadType.QUESTION ? '1.5rem' : '2rem',
marginTop: post.type === ThreadType.QUESTION ? '22px' : '',
marginLeft: post.type === ThreadType.QUESTION ? '18px' : '',
}}
alt={post.author}
src={authorAvatars?.imageUrlSmall}
/>
</div>
);
}

View File

@@ -39,11 +39,11 @@ function PostLink({
const authorLabelColor = AvatarBorderAndLabelColors[post.authorLabel];
return (
<Link
className="discussion-post list-group-item list-group-item-action p-0 text-decoration-none text-gray-900 mw-100"
className="discussion-post list-group-item list-group-item-action p-0 text-decoration-none text-gray-900"
to={linkUrl}
style={{ lineHeight: '21px', height: '7.5rem' }}
aria-current={isSelected(post.id) ? 'page' : undefined}
onClick={() => isSelected(post.id)}
style={{ lineHeight: '21px' }}
>
{post.pinned && (
<div className="d-flex flex-fill justify-content-end mr-4 text-light-500 p-0">
@@ -52,44 +52,53 @@ function PostLink({
</div>
)}
<div
className={classNames('d-flex flex-row flex-fill mw-100 p-2.5 pr-4 border-primary-500', { 'bg-light-300': post.read })}
className={
classNames('d-flex flex-row py-2.5 px-4 border-primary-500',
{ 'bg-light-300': post.read })
}
style={post.id === postId ? {
borderRightWidth: '4px',
borderRightStyle: 'solid',
} : null}
>
<PostAvatar post={post} authorLabel={post.authorLabel} fromPostLink />
<div className="d-flex flex-column" style={{ width: 'calc(100% - 4rem)' }}>
<div className="align-items-center d-flex flex-row flex-fill">
<div className="d-flex flex-column justify-content-start mw-100 flex-fill">
<div className="d-flex align-items-center pb-0 mb-0 flex-fill font-weight-500">
<div className="flex-fill text-truncate text-primary-500 font-weight-500 font-size-14 font-style-normal font-family-inter">
{post.title}
</div>
{showAnsweredBadge
&& (
<div className="ml-auto">
<Badge variant="success">{intl.formatMessage(messages.answered)}</Badge>
<span className="sr-only">{' '}answered</span>
</div>
)}
{(post.abuseFlagged || post.abuseFlaggedCount)
&& (
<div className={showAnsweredBadge ? 'ml-2' : 'ml-auto'}>
<Badge variant="danger" data-testid="reported-post">{intl.formatMessage(messages.contentReported)}</Badge>
<span className="sr-only">{' '}reported</span>
</div>
)}
<div className="d-flex flex-column flex-fill" style={{ minWidth: 0 }}>
<div className="d-flex flex-column justify-content-start mw-100 flex-fill">
<div className="d-flex align-items-center pb-0 mb-0 flex-fill font-weight-500">
<div
className="text-truncate font-weight-500 font-size-14 text-primary-500 font-style-normal font-family-inter"
>
{post.title}
</div>
<AuthorLabel
author={post.author || intl.formatMessage(messages.anonymous)}
authorLabel={post.authorLabel}
labelColor={authorLabelColor && `text-${authorLabelColor}`}
/>
{showAnsweredBadge && (
<Badge variant="success" className="font-weight-500 ml-auto badge-padding">
{intl.formatMessage(messages.answered)}
<span className="sr-only">{' '}answered</span>
</Badge>
)}
{(post.abuseFlagged || post.abuseFlaggedCount) && (
<Badge
variant="danger"
data-testid="reported-post"
className={`font-weight-500 badge-padding ${showAnsweredBadge ? 'ml-2' : 'ml-auto'}`}
>
{intl.formatMessage(messages.contentReported)}
<span className="sr-only">{' '}reported</span>
</Badge>
)}
</div>
</div>
<div className="text-truncate text-primary-500 font-weight-normal font-size-14 font-style-normal font-family-inter" style={{ maxHeight: '1.6em' }}>
<AuthorLabel
author={post.author || intl.formatMessage(messages.anonymous)}
authorLabel={post.authorLabel}
labelColor={authorLabelColor && `text-${authorLabelColor}`}
/>
<div
className="text-truncate text-primary-500 font-weight-normal font-size-14 font-style-normal font-family-inter"
style={{ maxHeight: '1.5rem' }}
>
{isPostPreviewAvailable(post.previewBody)
? post.previewBody
: intl.formatMessage(messages.postWithoutPreview)}

View File

@@ -33,8 +33,8 @@ const messages = defineMessages({
defaultMessage: 'Answered',
description: 'Tooltip/alttext for button to unfollow a discussion post',
},
unfollow: {
id: 'discussions.post.unfollow',
unFollow: {
id: 'discussions.post.unFollow',
defaultMessage: 'Unfollow',
description: 'Tooltip/alttext for button to unfollow a discussion post',
},
@@ -45,9 +45,14 @@ const messages = defineMessages({
},
removeLike: {
id: 'discussions.post.removeLike',
defaultMessage: 'Remove like',
defaultMessage: 'Unlike',
description: 'Tooltip/alttext for button to remove the like applied to a discussion post',
},
viewActivity: {
id: 'discussions.post.viewActivity',
defaultMessage: 'View Activity',
description: 'Tooltip/alttext for button to view the activity of a discussion post',
},
postClosed: {
id: 'discussions.post.closed',
defaultMessage: 'Post closed for responses and comments',
@@ -58,11 +63,6 @@ const messages = defineMessages({
defaultMessage: 'Related to',
description: 'Message followed the category and topic of post linking to in-course context',
},
visibleToAll: {
id: 'discussions.post.cohort.everyone',
defaultMessage: 'Everyone',
description: 'Cohort visibility indicator for all people',
},
deletePostTitle: {
id: 'discussions.editor.delete.post.title',
defaultMessage: 'Delete post',

View File

@@ -6,8 +6,9 @@
$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";
#post, #comment, #reply {
#post,
#comment,
#reply {
img {
height: auto;
max-width: 100%;
@@ -22,6 +23,10 @@ $fa-font-path: "~font-awesome/fonts";
border-color: #998200;
}
.border-anonymous {
border-color: #F2F0EF;
}
.font-size-14 {
font-size: 14px;
}
@@ -35,5 +40,23 @@ $fa-font-path: "~font-awesome/fonts";
}
.font-family-inter {
font-family: 'Inter';
}
font-family: "Inter";
}
.icon-size {
height: 20px !important;
width: 20px !important;
}
.mr-0\.5 {
margin-right: 2px;
}
.badge-padding {
padding-top: 1px;
padding-bottom: 1px
}
.discussion-post:hover {
background-color: unset !important;
}