[Comment/Livestream] Markdown and style fixes (#55)

* Fix CSS for live chat embeds

* Fix Markdown Lists in Comments

* Disable copy link menu option on livestream comments

* Fix nested indents in Live Chat

* Fix mentions and timestamps not parsed in bullet lists

* Highlight livestream comment and menu button on hover

* Fix mention parsing
This commit is contained in:
saltrafael 2021-10-12 18:06:20 -03:00 committed by GitHub
parent 6f3c43c95f
commit 7c518aa712
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 33 deletions

View file

@ -20,6 +20,7 @@ type Props = {
disableEdit?: boolean,
disableRemove?: boolean,
supportAmount?: any,
isLiveComment: boolean,
// --- select ---
claim: ?Claim,
claimIsMine: boolean,
@ -54,6 +55,7 @@ function CommentMenuList(props: Props) {
disableEdit,
disableRemove,
supportAmount,
isLiveComment,
doToast,
handleEditComment,
openModal,
@ -229,7 +231,7 @@ function CommentMenuList(props: Props) {
</>
)}
{IS_WEB && (
{IS_WEB && !isLiveComment && (
<MenuItem className="comment__menu-option" onSelect={handleCopyCommentLink}>
<div className="menu__link">
<Icon aria-hidden icon={ICONS.COPY_LINK} />

View file

@ -10,7 +10,7 @@ import remarkFrontMatter from 'remark-frontmatter';
import reactRenderer from 'remark-react';
import MarkdownLink from 'component/markdownLink';
import defaultSchema from 'hast-util-sanitize/lib/github.json';
import { formatedLinks, inlineLinks } from 'util/remark-lbry';
import { formattedLinks, inlineLinks } from 'util/remark-lbry';
import { formattedTimestamp, inlineTimestamp } from 'util/remark-timestamp';
import ZoomableImage from 'component/zoomableImage';
import { CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS, SIMPLE_SITE } from 'config';
@ -144,8 +144,9 @@ const MarkdownPreview = (props: MarkdownProps) => {
disableTimestamps,
stakedLevel,
} = props;
const strippedContent = content
? content.replace(REPLACE_REGEX, (iframeHtml, y, iframeSrc) => {
? content.replace(REPLACE_REGEX, (iframeHtml) => {
// Let the browser try to create an iframe to see if the markup is valid
const outer = document.createElement('div');
outer.innerHTML = iframeHtml;
@ -163,6 +164,10 @@ const MarkdownPreview = (props: MarkdownProps) => {
})
: '';
const initialQuote = strippedContent.split(' ').find((word) => word.length > 0 || word.charAt(0) === '>');
let stripQuote;
if (initialQuote && initialQuote.charAt(0) === '>') stripQuote = true;
const remarkOptions: Object = {
sanitize: schema,
fragment: React.Fragment,
@ -203,10 +208,22 @@ const MarkdownPreview = (props: MarkdownProps) => {
};
// Strip all content and just render text
if (strip) {
if (strip || stripQuote) {
// Remove new lines and extra space
remarkOptions.remarkReactComponents.p = SimpleText;
return (
return stripQuote ? (
<span dir="auto" className="markdown-preview">
<blockquote>
{
remark()
.use(remarkStrip)
.use(remarkFrontMatter, ['yaml'])
.use(reactRenderer, remarkOptions)
.processSync(content).contents
}
</blockquote>
</span>
) : (
<span dir="auto" className="markdown-preview">
{
remark()
@ -226,7 +243,7 @@ const MarkdownPreview = (props: MarkdownProps) => {
.use(remarkAttr, remarkAttrOpts)
// Remark plugins for lbry urls
// Note: The order is important
.use(formatedLinks)
.use(formattedLinks)
.use(inlineLinks)
.use(disableTimestamps || isMarkdownPost ? null : inlineTimestamp)
.use(disableTimestamps || isMarkdownPost ? null : formattedTimestamp)

View file

@ -119,10 +119,11 @@ function LivestreamComment(props: Props) {
commentId={commentId}
authorUri={authorUri}
commentIsMine={commentIsMine}
disableEdit
isTopLevel
isPinned={isPinned}
disableRemove={supportAmount > 0}
isTopLevel
disableEdit
isLiveComment
/>
</Menu>
</div>

View file

@ -268,9 +268,12 @@ $thumbnailWidthSmall: 1rem;
max-width: 35rem;
color: var(--color-text);
ul li,
ol li {
list-style-position: inside;
ul li {
list-style-type: disc;
ul li {
list-style-type: circle;
}
}
p {

View file

@ -87,16 +87,39 @@ $recent-msg-button__height: 2rem;
list-style-type: none;
position: relative;
@media (min-width: $breakpoint-small) {
&:hover {
background-color: var(--color-card-background-highlighted);
}
&:not(:hover) {
.menu__button:not(:focus):not([aria-expanded='true']) {
opacity: 0;
}
}
}
.channel-name {
font-size: var(--font-xsmall);
}
}
.livestream-comment__info {
overflow: hidden;
}
.livestream-comment--superchat {
+ .livestream-comment--superchat {
margin-bottom: var(--spacing-xxs);
}
.livestream-comment__body {
display: flex;
align-items: flex-start;
flex-direction: unset;
flex: unset;
}
.livestream-comment__info {
margin-top: calc(var(--spacing-xxs) / 2);
}
@ -116,13 +139,10 @@ $recent-msg-button__height: 2rem;
.livestream-comment__body {
display: flex;
align-items: flex-start;
}
.livestream-comment__body {
display: flex;
align-items: flex-start;
flex-direction: column;
flex: 2;
margin-left: var(--spacing-s);
overflow: hidden;
.channel-thumbnail {
@include handleChannelGif(2rem);
@ -354,6 +374,7 @@ $recent-msg-button__height: 2rem;
.livestream-comment__text {
padding-right: var(--spacing-xl);
padding-bottom: var(--spacing-xxs);
.markdown-preview {
p {
word-break: break-word;

View file

@ -1,4 +1,6 @@
.markdown-preview {
word-break: break-all;
> :first-child {
margin-top: 0;
}

View file

@ -12,13 +12,19 @@ const mentionRegex = /@[^\s()"]*/gm;
const invalidRegex = /[-_.+=?!@#$%^&*:;,{}<>\w/\\]/;
function handlePunctuation(value) {
const modifierIndex =
(value.indexOf(':') >= 0 && value.indexOf(':')) || (value.indexOf('#') >= 0 && value.indexOf('#'));
const protocolIndex = value.indexOf('lbry://') === 0 ? protocol.length - 1 : 0;
const channelModifierIndex =
(value.indexOf(':', protocolIndex) >= 0 && value.indexOf(':', protocolIndex)) ||
(value.indexOf('#', protocolIndex) >= 0 && value.indexOf('#', protocolIndex));
const claimModifierIndex =
(value.indexOf(':', channelModifierIndex + 1) >= 0 && value.indexOf(':', channelModifierIndex + 1)) ||
(value.indexOf('#', channelModifierIndex + 1) >= 0 && value.indexOf('#', channelModifierIndex + 1)) ||
channelModifierIndex;
let punctuationIndex;
punctuationMarks.some((p) => {
if (modifierIndex) {
punctuationIndex = value.indexOf(p, modifierIndex + 1) >= 0 && value.indexOf(p, modifierIndex + 1);
if (claimModifierIndex) {
punctuationIndex = value.indexOf(p, claimModifierIndex + 1) >= 0 && value.indexOf(p, claimModifierIndex + 1);
}
return punctuationIndex;
});
@ -108,15 +114,15 @@ function tokenizeURI(eat, value, silent) {
// Configure tokenizer for lbry urls
tokenizeURI.locator = locateURI;
tokenizeURI.notInList = true;
tokenizeURI.notInList = false;
tokenizeURI.notInLink = true;
tokenizeURI.notInBlock = true;
tokenizeURI.notInBlock = false;
// Configure tokenizer for lbry channels
tokenizeMention.locator = locateMention;
tokenizeMention.notInList = true;
tokenizeMention.notInList = false;
tokenizeMention.notInLink = true;
tokenizeMention.notInBlock = true;
tokenizeMention.notInBlock = false;
const visitor = (node, index, parent) => {
if (node.type === 'link' && parent && parent.type === 'paragraph') {
@ -149,7 +155,7 @@ const transform = (tree) => {
visit(tree, ['link'], visitor);
};
export const formatedLinks = () => transform;
export const formattedLinks = () => transform;
// Main module
export function inlineLinks() {

View file

@ -108,9 +108,9 @@ function tokenizeTimestamp(eat, value, silent) {
}
tokenizeTimestamp.locator = locateTimestamp;
tokenizeTimestamp.notInList = true; // Flag doesn't work? It'll always tokenizes in List and never in Bullet.
tokenizeTimestamp.notInList = false; // Flag doesn't work? It'll always tokenizes in List and never in Bullet.
tokenizeTimestamp.notInLink = true;
tokenizeTimestamp.notInBlock = true;
tokenizeTimestamp.notInBlock = false;
export function inlineTimestamp() {
const Parser = this.Parser;

View file

@ -60,14 +60,10 @@ ol {
position: relative;
list-style-position: outside;
margin: var(--spacing-xs) 0;
margin-left: var(--spacing-s);
margin-bottom: 0;
@media (min-width: $breakpoint-small) {
margin-left: var(--spacing-xl);
}
}
}
.ul--no-style {
list-style: none;