这是页面代码/**
* @Date: 2023-12-20 09:59:06
* @LastEditTime: 2024-01-09 18:22:35
* @FilePath: \工作\xinsheng-chasiwu-legacy-front\src\h5\components\Detail\modules\VideoSummaryH5\index.js
* @Description: 智能视频摘要
* @
* @Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
*/
import { useState, useRef } from 'react';
import PropTypes from 'prop-types';
import SvgIcon from '@src/components/SvgIcon';
import css from './style.m.css';
import eventBus from '@src/utils/eventBus';
import { useLocalStorage } from '@src/components/Detail/modules/VideoPlayer/modules/VideoSummary/summaryHooks';
import { getNls, locale } from '@src/utils/i18n';
import { useEffect } from 'react';
const dict = getNls('components_LiveDetail_modules_Content_modules_Summary');
import { useTypeWriterHooks } from '@src/components/Detail/modules/VideoPlayer/modules/VideoSummary/summaryHooks.js';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import Panel, { PanelItem } from '@hui/react-mobile/Panel';
const isEn = locale === 'en';
/**
* @description: 添加回放视频下方的评论组件的class
* @param {number} type 0 添加 1 删除
* @return {*}
*/
const addCommentsClass = ({ seth5VideoHeight, h5VideoHeight, type = 0 }) => {
const commentDom = document.querySelector('#content-main .ev_tab_container');
if (!commentDom) return;
if (type === 1) {
commentDom.classList.remove('live-comments-top');
} else if (!commentDom.classList.contains('live-comments-top')) {
commentDom.classList.add('live-comments-top');
if (seth5VideoHeight) seth5VideoHeight(h5VideoHeight + 56); // 兼容包含视频字幕的场景
}
};
const renderExpandTitle = (item) => {
return (
<div className={css.summaryTitleBox}>
<div className={css.summaryTimeItem}>{item.time.split('~')[0]}</div>
<div className={css.summaryTitleItem}>{item.title}</div>
</div>
);
};
function renderContent(props) {
const {
showAll,
aiSummaryTitle,
aiSummaryContent,
aiSummaryContentEn,
keyWordsTitle,
keyWordsContent,
keyList,
keyListEn,
selectedIndex,
setSelectedIndex,
} = props;
const keyListContent = isEn ? keyListEn : keyList;
return (
<div className={`${css.summaryContent} h5ap-font-14`}>
<div className={css.summaryContentWidth}>
<div className={`${css.label} h5ap-font-14`}>{aiSummaryTitle}</div>
<div className={css.description}>{isEn ? aiSummaryContentEn : aiSummaryContent}</div>
{keyWordsContent && (
<>
<div className={`${css.label} ${css.keywordsLabel}`}>{keyWordsTitle}</div>
<p className={css.keywords}>{keyWordsContent}</p>
</>
)}
{showAll && (
<Panel
enableMultiExpand={true}
selectedIndex={selectedIndex}
onExpand={(index, event, isExpand) => {
if (!isExpand) {
setSelectedIndex([...selectedIndex, index]);
}
}}
onClose={(index, event, isExpand) => {
const indexArr = selectedIndex.filter((f) => f !== index);
if (isExpand) {
setSelectedIndex(indexArr);
}
}}
>
{keyListContent.map((item, index) => {
return (
<PanelItem
titlePosition="left"
key={index}
closable={false}
expandTitle={renderExpandTitle(item)}
shrinkTitle={renderExpandTitle(item)}
>
{item.content}
</PanelItem>
);
})}
</Panel>
)}
</div>
</div>
);
}
function VideoSummaryH5(props) {
const { videoId, videoUuids, columnType, seth5VideoHeight, h5VideoHeight } = props;
const [isNotFirstClosed, setIsNotFirstClosed] = useLocalStorage(videoUuids, 'isNotFirstClosed');
const [isFirstClosed, setIsFirstClosed] = useState(isNotFirstClosed); // 首次是否关闭
const [visible, setVisible] = useState(false);
const [showAll, setShowAll] = useState(false); // 展示全部
const [selectedIndex, setSelectedIndex] = useState([0]);
const [isOverflow, setIsOverflow] = useState(false); // 是否超出三行
const contentRef = useRef(null);
// 获取ai摘要的相关内容
const {
aiSummaryTitle,
aiSummaryContent,
aiSummaryContentEn,
keyWordsTitle,
keyWordsContent,
isShowGenerateBtn,
keyList,
keyListEn,
} = useTypeWriterHooks(props);
let params = { aiSummaryContent, aiSummaryContentEn, keyWordsTitle, keyWordsContent, showAll, setShowAll };
params = { ...params, aiSummaryTitle, isShowGenerateBtn, keyList, keyListEn, selectedIndex, setSelectedIndex };
useEffect(() => {
const el = contentRef.current;
if (!el) return;
const checkOverflow = () => {
const isOverflowing = el.scrollHeight > el.clientHeight;
setIsOverflow(isOverflowing);
};
const timer = setTimeout(checkOverflow, 50);
const resizeObserver = new ResizeObserver(checkOverflow);
resizeObserver.observe(el);
return () => {
clearTimeout(timer);
resizeObserver.unobserve(el);
};
}, [showAll]);
const click = () => {
eventBus.emit(`showFloatWindow${videoId}`, true);
setIsFirstClosed(true);
setIsNotFirstClosed(true);
if (columnType !== 'live') return;
addCommentsClass({ seth5VideoHeight, h5VideoHeight, type: 1 });
};
useEffect(() => {
eventBus.removeAllListeners(`evt_showSummaryH5`);
eventBus.on(`evt_showSummaryH5`, (value) => {
setVisible(value);
if (columnType !== 'live') return;
if (!isFirstClosed && value) {
addCommentsClass({ seth5VideoHeight, h5VideoHeight });
} else {
addCommentsClass({ seth5VideoHeight, h5VideoHeight, type: 1 });
}
});
return () => {
eventBus.removeAllListeners(`evt_showSummaryH5`);
};
}, []);
if (isFirstClosed || !visible) return null;
return (
<div className={`${css.videoSummaryH5} video-summary-h5 ${locale === 'en' ? css.summaryH5En : ''}`}>
<div className={css.summaryH5Notice}>
<div className={css.summaryH5Left}>
<SvgIcon iconClass="summaryIcon" svgClass={css.svg} />
<div className={css.title}>{dict.aiSummary}</div>
</div>
<div className={css.summaryH5Right}>
<SvgIcon iconClass="close" {...{ click }} />
</div>
</div>
{/* 主体:带展开功能的内容区 */}
<div className={css.summaryH5Container}>
{/* 文本容器 */}
<div ref={contentRef} className={showAll ? css.summaryH5Expanded : css.summaryH5Clamp}>
{renderContent({ ...params, showAll })}
</div>
{/* 条件渲染:只有在折叠状态下且内容溢出时才显示展开按钮 */}
{!showAll && isOverflow && (
<span
className={css.expandIcon}
onClick={(e) => {
e.stopPropagation();
setShowAll(true);
}}
>
<DownOutlined />
</span>
)}
{/* 收起按钮:始终显示上拉箭头(可选) */}
{showAll && (
<span
className={css.expandIcon}
onClick={(e) => {
e.stopPropagation();
setShowAll(false);
}}
>
<UpOutlined />
</span>
)}
</div>
</div>
);
}
VideoSummaryH5.propTypes = {
videoId: PropTypes.string,
videoUuids: PropTypes.string,
columnType: PropTypes.string,
seth5VideoHeight: PropTypes.func,
h5VideoHeight: PropTypes.number,
};
export default VideoSummaryH5;
这是页面样式:.videoSummaryH5 {
/* height: 40px; */
background: rgba(0, 65, 211, 0.05);
padding: 8px 24px;
line-height: 1.5;
}
.svg {
font-size: 16px;
margin-right: 4px;
}
.summaryH5Notice {
display: flex;
justify-content: space-between;
align-items: center;
}
.summaryH5Right,
.summaryH5Left {
display: flex;
align-items: center;
}
.summaryH5Left {
color: #0041d3;
}
/* 三行截断 */
.summaryH5Clamp {
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3 !important;
-webkit-box-orient: vertical;
word-break: break-all;
box-sizing: border-box;
}
/* 展开后全文显示 */
.summaryH5Expanded {
white-space: pre-wrap;
overflow: visible;
text-overflow: unset;
display: block;
}
/* 平滑过渡动画 */
.summaryH5Clamp,
.summaryH5Expanded {
line-height: 1.4em;
transition: max-height 0.3s ease;
}
/* 新增:容器用于定位图标 */
.summaryH5Container {
position: relative;
padding-right: 20px; /* 给图标留位置 */
}
/* 新增:展开图标 */
.expandIcon {
position: absolute;
right: 0;
bottom: 0;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
cursor: pointer;
color: #0041d3;
font-size: 12px;
}
.summaryContent {
overflow-y: auto;
border-radius: 0.8rem;
padding-bottom: 1.6rem;
width: 32rem;
font-size: 1.4rem;
line-height: 2.4rem;
position: relative;
}
.summaryContentWidth {
width: 28.8rem;
}
.label {
color: #666666;
margin-bottom: 4px;
}
.description,
.keywords {
color: #000000;
text-align: justify;
}
.keywordsLabel {
margin-top: 16px;
}
.summaryContent :global .ev_Panel {
margin-top: 24px;
}
.summaryContent :global .ev_Panel .ev_PanelItem:not(:first-child) {
margin-top: 16px;
}
.summaryContent :global .ev_Panel .ev_PanelItem_title {
flex-direction: row-reverse;
justify-content: space-between;
height: auto;
}
.summaryContent :global .ev_Panel .ev_PanelItem_title .ev_PanelItem_title_titleInfo {
flex: 1;
font-size: 14px;
color: #666666;
line-height: 24px;
word-break: break-all;
}
.summaryContent :global .ev_Panel .ev_PanelItem .ev_PanelItem_title .ev_PanelItem_title_showChange {
margin-right: 0;
align-self: flex-start;
margin-left: 4px;
width: 24px !important;
height: 24px !important;
line-height: 24px !important;
display: flex;
align-items: center;
justify-content: center;
}
.summaryContent :global .ev_Panel .ev_PanelItem .ev_PanelItem_title .panelHide {
justify-content: flex-start;
}
.summaryContent :global .ev_Panel .ev_PanelItem .ev_PanelItem_title .panelShow {
justify-content: flex-end;
}
.summaryContent :global .ev_Panel .ev_PanelItem .ev_PanelItem_title .ev_PanelItem_title_showChange > .ev_icon {
display: flex;
align-items: center;
justify-content: center;
}
.summaryContent :global .ev_Panel .ev_PanelItem .ev_PanelItem_title .ev_PanelItem_title_showChange svg {
width: 12px;
height: 12px;
}
.summaryContent :global .ev_Panel .ev_PanelItem_container {
padding: 0;
margin-top: 6px;
font-size: 14px;
color: #000000;
text-align: justify;
line-height: 24px;
}
.summaryTitleBox {
display: flex;
}
.summaryTimeItem {
text-wrap: nowrap;
margin-right: 8px;
max-width: 60px;
}
.summaryTitleItem {
flex: 1;
word-break: break-all;
}
.test {
background: #ffffff;
border-radius: 4px;
padding: 6px 10px;
font-size: 16px;
height: 24px;
transform: scale(0.5) translateX(10%);
color: #0041d3;
line-height: 12px;
position: absolute;
top: -12px;
text-wrap: nowrap;
}
.button {
background: #0041d3;
border-radius: 12px;
font-size: 11px;
color: #ffffff;
text-align: center;
height: 24px;
padding: 0 16px;
line-height: 24px;
margin-right: 24px;
position: relative;
}
.summaryH5En .title {
font-size: 12px;
}
.summaryH5En .button {
padding: 0 8px;
margin-right: 20px;
}
.summaryH5En .test {
transform: scale(0.5) translateX(100%);
}
:global .video-summary-h5 .summaryTest {
width: max-content !important;
white-space: nowrap !important;
max-width: max-content !important;
}
请你检查一下是哪里导致了页面刚加载文本默认多行显示而不是三行,并且下拉图标不显示,并且将完整代码发给我
最新发布