Chat/comment markdown and style fixes #7193

Closed
saltrafael wants to merge 6 commits from chat-markdown into master
8 changed files with 76 additions and 25 deletions

View file

@ -20,6 +20,7 @@ type Props = {
disableEdit?: boolean, disableEdit?: boolean,
disableRemove?: boolean, disableRemove?: boolean,
supportAmount?: any, supportAmount?: any,
isLiveComment: boolean,
// --- select --- // --- select ---
claim: ?Claim, claim: ?Claim,
claimIsMine: boolean, claimIsMine: boolean,
@ -54,6 +55,7 @@ function CommentMenuList(props: Props) {
disableEdit, disableEdit,
disableRemove, disableRemove,
supportAmount, supportAmount,
isLiveComment,
doToast, doToast,
handleEditComment, handleEditComment,
openModal, openModal,
@ -229,7 +231,7 @@ function CommentMenuList(props: Props) {
</> </>
)} )}
{IS_WEB && ( {IS_WEB && !isLiveComment && (
<MenuItem className="comment__menu-option" onSelect={handleCopyCommentLink}> <MenuItem className="comment__menu-option" onSelect={handleCopyCommentLink}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.COPY_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 reactRenderer from 'remark-react';
import MarkdownLink from 'component/markdownLink'; import MarkdownLink from 'component/markdownLink';
import defaultSchema from 'hast-util-sanitize/lib/github.json'; 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 { formattedTimestamp, inlineTimestamp } from 'util/remark-timestamp';
infinite-persistence commented 2021-10-11 17:50:36 +02:00 (Migrated from github.com)
Review

Dash parsing in channel name broken

I think this issue came from changes in Channel Mention. Can fix together if possible:

In a post,

----
Playlist:
<iframe id="lbry-iframe" width="560" height="315" src="https://lbry.tv/$/embed/Wrestling/e9a586dcf13c5fe8f30692c6b39d1c8e9323ea69?r=4bWsJBCcfyXoHwYBHEXV61pTrf3RW5Fe" allowfullscreen></iframe>

<iframe src="lbry://@ip-test-2#c/Wrestling#e"></iframe>

<iframe id="lbry-iframe" width="560" height="315" src="lbry://@ip-test-2#c/Wrestling#e" allowfullscreen></iframe>
----

yields:
image

The commit before Channel Mention yields (the correct version):
image

## Dash parsing in channel name broken I think this issue came from changes in Channel Mention. Can fix together if possible: In a post, ``` ---- Playlist: <iframe id="lbry-iframe" width="560" height="315" src="https://lbry.tv/$/embed/Wrestling/e9a586dcf13c5fe8f30692c6b39d1c8e9323ea69?r=4bWsJBCcfyXoHwYBHEXV61pTrf3RW5Fe" allowfullscreen></iframe> <iframe src="lbry://@ip-test-2#c/Wrestling#e"></iframe> <iframe id="lbry-iframe" width="560" height="315" src="lbry://@ip-test-2#c/Wrestling#e" allowfullscreen></iframe> ---- ``` yields: ![image](https://user-images.githubusercontent.com/64950861/136819141-830232df-31d2-464c-82c7-30c7b795add5.png) The commit before Channel Mention yields (the correct version): ![image](https://user-images.githubusercontent.com/64950861/136819409-1d3c06c9-a927-4e7f-8bc6-7a1ac5a9d81d.png)
import ZoomableImage from 'component/zoomableImage'; import ZoomableImage from 'component/zoomableImage';
infinite-persistence commented 2021-10-11 17:54:20 +02:00 (Migrated from github.com)
Review

Some embeds not showing

The picture on the left is before the Channel Mention commit. The picture on the right is this PR.

image

The markdown is:

----
Video 1:
<iframe src="lbry://@Tasteshow#9/the-crispiest-chicken-wings-recipe-with#9"></iframe>
----
## Some embeds not showing The picture on the left is before the Channel Mention commit. The picture on the right is this PR. ![image](https://user-images.githubusercontent.com/64950861/136819818-d82f98c8-50a4-4e5c-86eb-3e0fe3376767.png) The markdown is: ``` ---- Video 1: <iframe src="lbry://@Tasteshow#9/the-crispiest-chicken-wings-recipe-with#9"></iframe> ---- ```
import { CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS, SIMPLE_SITE } from 'config'; import { CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS, SIMPLE_SITE } from 'config';
infinite-persistence commented 2021-10-11 18:08:37 +02:00 (Migrated from github.com)
Review

#5845 says "don't allow embeds on livestreams", but with a level 5 account, I was able to.

image

#5845 says "don't allow embeds on livestreams", but with a level 5 account, I was able to. ![image](https://user-images.githubusercontent.com/64950861/136821799-5d0ef4f4-7804-4a94-a991-0e996560d1bd.png)
infinite-persistence commented 2021-10-11 18:34:51 +02:00 (Migrated from github.com)
Review

Same goes for images. I thought we were supposed to disable them in favor of stickers (I could be wrong)

image

Same goes for images. I thought we were supposed to disable them in favor of stickers (I could be wrong) ![image](https://user-images.githubusercontent.com/64950861/136824947-24f39aac-e43c-402b-9883-e0e657729320.png)
saltrafael commented 2021-10-12 14:59:51 +02:00 (Migrated from github.com)
Review

yeah those will be disabled along with the stickers, so it's okay for now

yeah those will be disabled along with the stickers, so it's okay for now
@ -133,8 +133,9 @@ function isStakeEnoughForPreview(stakedLevel) {
const MarkdownPreview = (props: MarkdownProps) => { const MarkdownPreview = (props: MarkdownProps) => {
const { content, strip, simpleLinks, noDataStore, className, parentCommentId, isMarkdownPost, stakedLevel } = props; const { content, strip, simpleLinks, noDataStore, className, parentCommentId, isMarkdownPost, stakedLevel } = props;
const strippedContent = content 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 // Let the browser try to create an iframe to see if the markup is valid
const outer = document.createElement('div'); const outer = document.createElement('div');
outer.innerHTML = iframeHtml; outer.innerHTML = iframeHtml;
@ -152,6 +153,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 = { const remarkOptions: Object = {
sanitize: schema, sanitize: schema,
fragment: React.Fragment, fragment: React.Fragment,
@ -192,10 +197,22 @@ const MarkdownPreview = (props: MarkdownProps) => {
}; };
// Strip all content and just render text // Strip all content and just render text
if (strip) { if (strip || stripQuote) {
// Remove new lines and extra space // Remove new lines and extra space
remarkOptions.remarkReactComponents.p = SimpleText; 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"> <span dir="auto" className="markdown-preview">
{ {
remark() remark()
@ -215,7 +232,7 @@ const MarkdownPreview = (props: MarkdownProps) => {
.use(remarkAttr, remarkAttrOpts) .use(remarkAttr, remarkAttrOpts)
// Remark plugins for lbry urls // Remark plugins for lbry urls
// Note: The order is important // Note: The order is important
.use(formatedLinks) .use(formattedLinks)
.use(inlineLinks) .use(inlineLinks)
.use(isMarkdownPost ? null : inlineTimestamp) .use(isMarkdownPost ? null : inlineTimestamp)
.use(isMarkdownPost ? null : formattedTimestamp) .use(isMarkdownPost ? null : formattedTimestamp)

View file

@ -11,6 +11,7 @@ import classnames from 'classnames';
import CommentMenuList from 'component/commentMenuList'; import CommentMenuList from 'component/commentMenuList';
import Button from 'component/button'; import Button from 'component/button';
import CreditAmount from 'component/common/credit-amount'; import CreditAmount from 'component/common/credit-amount';
import useHover from 'effects/use-hover';
type Props = { type Props = {
uri: string, uri: string,
@ -43,14 +44,18 @@ function LivestreamComment(props: Props) {
isPinned, isPinned,
} = props; } = props;
const commentByOwnerOfContent = claim && claim.signing_channel && claim.signing_channel.permanent_url === authorUri; const commentRef = React.useRef();
const isHovering = useHover(commentRef);
const commentByContentOwner = claim && claim.signing_channel && claim.signing_channel.permanent_url === authorUri;
const { claimName } = parseURI(authorUri); const { claimName } = parseURI(authorUri);
return ( return (
<li <li
className={classnames('livestream-comment', { className={classnames('livestream-comment', {
'livestream-comment--superchat': supportAmount > 0, 'livestream-comment--superchat': supportAmount > 0,
'livestream-comment--hover': isHovering,
})} })}
ref={commentRef}
> >
{supportAmount > 0 && ( {supportAmount > 0 && (
<div className="super-chat livestream-superchat__banner"> <div className="super-chat livestream-superchat__banner">
@ -78,7 +83,7 @@ function LivestreamComment(props: Props) {
</Tooltip> </Tooltip>
)} )}
{commentByOwnerOfContent && ( {commentByContentOwner && (
<Tooltip label={__('Streamer')}> <Tooltip label={__('Streamer')}>
<span className="comment__badge"> <span className="comment__badge">
<Icon icon={ICONS.BADGE_STREAMER} size={16} /> <Icon icon={ICONS.BADGE_STREAMER} size={16} />
@ -88,7 +93,7 @@ function LivestreamComment(props: Props) {
<Button <Button
className={classnames('button--uri-indicator comment__author', { className={classnames('button--uri-indicator comment__author', {
'comment__author--creator': commentByOwnerOfContent, 'comment__author--creator': commentByContentOwner,
})} })}
target="_blank" target="_blank"
navigate={authorUri} navigate={authorUri}
@ -119,10 +124,11 @@ function LivestreamComment(props: Props) {
commentId={commentId} commentId={commentId}
authorUri={authorUri} authorUri={authorUri}
commentIsMine={commentIsMine} commentIsMine={commentIsMine}
disableEdit
isTopLevel
isPinned={isPinned} isPinned={isPinned}
disableRemove={supportAmount > 0} disableRemove={supportAmount > 0}
isTopLevel
disableEdit
isLiveComment
/> />
</Menu> </Menu>
</div> </div>

View file

@ -268,9 +268,12 @@ $thumbnailWidthSmall: 1rem;
max-width: 35rem; max-width: 35rem;
color: var(--color-text); color: var(--color-text);
ul li, ul li {
ol li { list-style-type: disc;
list-style-position: inside;
ul li {
list-style-type: circle;
}
} }
p { p {
infinite-persistence commented 2021-10-11 18:11:16 +02:00 (Migrated from github.com)
Review

On large layout, the bullet appears correctly, but on small, it doesn't appear.

image

On large layout, the bullet appears correctly, but on small, it doesn't appear. ![image](https://user-images.githubusercontent.com/64950861/136822121-33cf9a8a-6df7-4fbe-9926-4526df5b45d6.png)

View file

@ -91,11 +91,22 @@ $recent-msg-button__height: 2rem;
} }
} }
.livestream-comment__info {
overflow: hidden;
}
.livestream-comment--superchat { .livestream-comment--superchat {
+ .livestream-comment--superchat { + .livestream-comment--superchat {
margin-bottom: var(--spacing-xxs); margin-bottom: var(--spacing-xxs);
} }
.livestream-comment__body {
display: flex;
align-items: flex-start;
flex-direction: unset;
flex: unset;
}
.livestream-comment__info { .livestream-comment__info {
margin-top: calc(var(--spacing-xxs) / 2); margin-top: calc(var(--spacing-xxs) / 2);
} }
@ -113,15 +124,24 @@ $recent-msg-button__height: 2rem;
} }
} }
.livestream-comment__body { .livestream-comment--hover {
display: flex; background-color: var(--color-card-background-highlighted);
align-items: flex-start; }
@media (min-width: $breakpoint-small) {
.livestream-comment:not(:hover) {
.menu__button:not(:focus):not([aria-expanded='true']) {
opacity: 0;
}
}
} }
.livestream-comment__body { .livestream-comment__body {
display: flex; display: flex;
align-items: flex-start; flex-direction: column;
flex: 2;
margin-left: var(--spacing-s); margin-left: var(--spacing-s);
overflow: hidden;
.channel-thumbnail { .channel-thumbnail {
@include handleChannelGif(2rem); @include handleChannelGif(2rem);
@ -353,6 +373,7 @@ $recent-msg-button__height: 2rem;
.livestream-comment__text { .livestream-comment__text {
padding-right: var(--spacing-xl); padding-right: var(--spacing-xl);
padding-bottom: var(--spacing-xxs); padding-bottom: var(--spacing-xxs);
.markdown-preview { .markdown-preview {
p { p {
word-break: break-word; word-break: break-word;

View file

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

View file

@ -108,15 +108,15 @@ function tokenizeURI(eat, value, silent) {
// Configure tokenizer for lbry urls // Configure tokenizer for lbry urls
tokenizeURI.locator = locateURI; tokenizeURI.locator = locateURI;
tokenizeURI.notInList = true; tokenizeURI.notInList = false;
tokenizeURI.notInLink = true; tokenizeURI.notInLink = true;
tokenizeURI.notInBlock = true; tokenizeURI.notInBlock = false;
// Configure tokenizer for lbry channels // Configure tokenizer for lbry channels
tokenizeMention.locator = locateMention; tokenizeMention.locator = locateMention;
tokenizeMention.notInList = true; tokenizeMention.notInList = false;
tokenizeMention.notInLink = true; tokenizeMention.notInLink = true;
tokenizeMention.notInBlock = true; tokenizeMention.notInBlock = false;
const visitor = (node, index, parent) => { const visitor = (node, index, parent) => {
if (node.type === 'link' && parent && parent.type === 'paragraph') { if (node.type === 'link' && parent && parent.type === 'paragraph') {
@ -149,7 +149,7 @@ const transform = (tree) => {
visit(tree, ['link'], visitor); visit(tree, ['link'], visitor);
}; };
export const formatedLinks = () => transform; export const formattedLinks = () => transform;
// Main module // Main module
export function inlineLinks() { export function inlineLinks() {

View file

@ -108,9 +108,9 @@ function tokenizeTimestamp(eat, value, silent) {
} }
tokenizeTimestamp.locator = locateTimestamp; 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.notInLink = true;
tokenizeTimestamp.notInBlock = true; tokenizeTimestamp.notInBlock = false;
export function inlineTimestamp() { export function inlineTimestamp() {
const Parser = this.Parser; const Parser = this.Parser;