diff --git a/common/components/thread/post-content/index.jsx b/common/components/thread/post-content/index.jsx index e778b300d90f592eae5fa9609464392bbae50bc5..e8d59d49822677a95c27887bf10979f082819afb 100644 --- a/common/components/thread/post-content/index.jsx +++ b/common/components/thread/post-content/index.jsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useState, useMemo, useRef, useEffect, useCallback } from 'react'; +import { Button, Icon } from '@discuzq/design'; import s9e from '@common/utils/s9e'; import xss from '@common/utils/xss'; @@ -7,13 +8,88 @@ import styles from './index.module.scss'; /** * 帖子内容展示 - * @prop {string} content 内容 + * @prop {string} content 内容 + * @prop {boolean} useShowMore 是否显示查看更多 + * @prop {boolean} isPayContent 是否付费内容 + * @prop {number} hidePercent 隐藏内容的百分比 eg: 80 + * @prop {number} payAmount 查看隐藏内容支付金额 + * @prop {function} onPay 付款点击事件 + * @prop {function} onRedirectToDetail 跳转到详情页面,当点击内容或查看更多内容超出屏幕时跳转到详情页面 */ -const Index = ({ content, ...props }) => { - const filterContent = React.useMemo(() => (content ? xss(s9e.parse(content)) : '')); +const Index = ({ + content, + useShowMore = true, + isPayContent, + hidePercent = 0, + payAmount = 0, + onPay, + onRedirectToDetail, + ...props +}) => { + // 内容是否超出屏幕高度 + const [contentToo, setContentToo] = useState(true); + const [showMore, setShowMore] = useState(!useShowMore); + const contentWrapperRef = useRef(null); - return
; + const texts = { + showMore: '查看更多', + hidePercent: `剩余${hidePercent}%内容已隐藏`, + payButton: `支付${payAmount}元查看剩余内容`, + }; + // 过滤内容 + const filterContent = useMemo(() => (content ? xss(s9e.parse(content)) : '')); + // 是否显示遮罩 是付费内容并且隐藏内容百分比大于0 或 显示查看更多并且查看更多状态为false 则显示遮罩 + const showHideCover = (isPayContent && hidePercent > 0) || (useShowMore && !showMore); + + const onShowMore = useCallback(() => { + if (contentToo) { + // 内容过长直接跳转到详情页面 + onRedirectToDetail && onRedirectToDetail(); + } else { + setShowMore(true); + } + }, [contentToo]); + + useEffect(() => { + const el = contentWrapperRef.current; + if (el) { + if (el.scrollHeight <= el.clientHeight) { + // 内容小于6行 隐藏查看更多 + setShowMore(true); + } + if (window && el.scrollHeight <= window.screen.height) { + setContentToo(false); + } + } + }, [contentWrapperRef.current]); + + return ( +
+
+
+
+ {useShowMore && !showMore && ( +
+
{texts.showMore}
+ +
+ )} + {showMore && isPayContent && ( +
+
{texts.hidePercent}
+ +
+ )} +
+ ); }; export default React.memo(Index); diff --git a/common/components/thread/post-content/index.module.scss b/common/components/thread/post-content/index.module.scss index 91c8cb29c6f2ce5620051ec8c6235eec1ea503e9..cdc5d98892d540651b893e15e40ba6dbb0d8ee11 100644 --- a/common/components/thread/post-content/index.module.scss +++ b/common/components/thread/post-content/index.module.scss @@ -1,42 +1,87 @@ + +@import '@common/styles/variable/index.scss'; +@import '@common/styles/fn/rem.scss'; .container { + width: 100%; position: relative; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - line-height: 0.24rem; - font-size: 0.16rem !important; - color: #000; - max-width: 5.85rem; - margin-top: 0.03rem; - p, - h1, - h2, - h3, - h4, - h5, - h6 { - font-size: 0.16rem !important; + .content { + position: relative; + display: inline-block; + line-height: rem($font-line-height-middle); + font-size: rem($font-size-middle) !important; + color: #0b0b37; + margin-top: rem($padding-1n); + word-break: break-all; + p, + h1, + h2, + h3, + h4, + h5, + h6 { + font-size: rem($font-size-middle) !important; + } + img { + max-width: 100%; + max-height: rem(2); + overflow: hidden; + } + /* + :global(.qq-emotion) { + height: rem(20); + margin-top: rem(-1); + } + */ } - img { - max-width: 100%; - max-height: 2rem; + .hideCover { + position: relative; overflow: hidden; + max-height: rem(150); + &:after { + position: absolute; + display: block; + left: 0; + bottom: 0; + content: ''; + width: 100%; + height: 100px; + background: linear-gradient(rgba(255, 255, 255, 0), rgba(255, 255, 255, 1)); + } } - /* - :global(.qq-emotion) { - height: 22px; - vertical-align: middle; - margin-top: -2px; + .showMore { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + font-weight: normal; + font-size: rem($font-size-primary); + line-height: rem($font-line-height-primary); + color: #0466ff; + .icon { + margin-left: rem(9); + transform: rotateZ(90deg); + } } - @media screen and (max-width: 1005px) { - max-height: 80px; - line-height: 20px; - max-width: 410px; - :global(.qq-emotion) { - height: 20px; - margin-top: -1px; + .payInfo { + display: flex; + flex-direction: column; + align-items: center; + .hidePercent { + font-weight: normal; + font-size: rem($font-size-primary); + line-height: rem($font-line-height-primary); + text-align: left; + color: #0466ff; + } + .payButton { + margin-top: rem($padding-4n); + line-height: rem(16.8); + } + .payButtonIcon { + margin-right: rem($padding-2n); + width: rem(13.93); + height: rem(16.62); + background-color: white; } } - */ }