diff --git a/ui/component/commentMenuList/view.jsx b/ui/component/commentMenuList/view.jsx index b938f1b16..c2ef10c29 100644 --- a/ui/component/commentMenuList/view.jsx +++ b/ui/component/commentMenuList/view.jsx @@ -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 && (
diff --git a/ui/component/common/markdown-preview.jsx b/ui/component/common/markdown-preview.jsx index fba66eea5..da487dee5 100644 --- a/ui/component/common/markdown-preview.jsx +++ b/ui/component/common/markdown-preview.jsx @@ -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'; @@ -133,8 +133,9 @@ function isStakeEnoughForPreview(stakedLevel) { const MarkdownPreview = (props: MarkdownProps) => { const { content, strip, simpleLinks, noDataStore, className, parentCommentId, isMarkdownPost, 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; @@ -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 = { sanitize: schema, fragment: React.Fragment, @@ -192,10 +197,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 ? ( + +
+ { + remark() + .use(remarkStrip) + .use(remarkFrontMatter, ['yaml']) + .use(reactRenderer, remarkOptions) + .processSync(content).contents + } +
+
+ ) : ( { remark() @@ -215,7 +232,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(isMarkdownPost ? null : inlineTimestamp) .use(isMarkdownPost ? null : formattedTimestamp) diff --git a/ui/component/livestreamComment/view.jsx b/ui/component/livestreamComment/view.jsx index cefdfc8ae..ba926dc6e 100644 --- a/ui/component/livestreamComment/view.jsx +++ b/ui/component/livestreamComment/view.jsx @@ -11,6 +11,7 @@ import classnames from 'classnames'; import CommentMenuList from 'component/commentMenuList'; import Button from 'component/button'; import CreditAmount from 'component/common/credit-amount'; +import useHover from 'effects/use-hover'; type Props = { uri: string, @@ -43,14 +44,18 @@ function LivestreamComment(props: Props) { isPinned, } = 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); return (
  • 0, + 'livestream-comment--hover': isHovering, })} + ref={commentRef} > {supportAmount > 0 && (
    @@ -78,7 +83,7 @@ function LivestreamComment(props: Props) { )} - {commentByOwnerOfContent && ( + {commentByContentOwner && ( @@ -88,7 +93,7 @@ function LivestreamComment(props: Props) {
    diff --git a/ui/scss/component/_comments.scss b/ui/scss/component/_comments.scss index 68812eda2..fb164327e 100644 --- a/ui/scss/component/_comments.scss +++ b/ui/scss/component/_comments.scss @@ -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 { diff --git a/ui/scss/component/_livestream.scss b/ui/scss/component/_livestream.scss index a2373f683..9fe1b8dcf 100644 --- a/ui/scss/component/_livestream.scss +++ b/ui/scss/component/_livestream.scss @@ -91,11 +91,22 @@ $recent-msg-button__height: 2rem; } } +.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); } @@ -113,15 +124,24 @@ $recent-msg-button__height: 2rem; } } -.livestream-comment__body { - display: flex; - align-items: flex-start; +.livestream-comment--hover { + background-color: var(--color-card-background-highlighted); +} + +@media (min-width: $breakpoint-small) { + .livestream-comment:not(:hover) { + .menu__button:not(:focus):not([aria-expanded='true']) { + opacity: 0; + } + } } .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); @@ -353,6 +373,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; diff --git a/ui/scss/component/_markdown-preview.scss b/ui/scss/component/_markdown-preview.scss index ae39627d0..2af7c40d4 100644 --- a/ui/scss/component/_markdown-preview.scss +++ b/ui/scss/component/_markdown-preview.scss @@ -1,4 +1,6 @@ .markdown-preview { + word-break: break-all; + > :first-child { margin-top: 0; } diff --git a/ui/util/remark-lbry.js b/ui/util/remark-lbry.js index ad0ea9145..99c1601cb 100644 --- a/ui/util/remark-lbry.js +++ b/ui/util/remark-lbry.js @@ -108,15 +108,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 +149,7 @@ const transform = (tree) => { visit(tree, ['link'], visitor); }; -export const formatedLinks = () => transform; +export const formattedLinks = () => transform; // Main module export function inlineLinks() { diff --git a/ui/util/remark-timestamp.js b/ui/util/remark-timestamp.js index 288047667..0f410619e 100644 --- a/ui/util/remark-timestamp.js +++ b/ui/util/remark-timestamp.js @@ -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;