129 lines
4.7 KiB
TypeScript
129 lines
4.7 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { EntityDict } from '@project/oak-app-domain';
|
|
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
|
import Styles from './styles.module.less';
|
|
import MdViewer from '@project/components/common/byteMD/MdViewer';
|
|
import FrontendFooter from '@project/components/frontend/home/FrontendFooter';
|
|
import { Button } from 'antd';
|
|
import { VerticalAlignTopOutlined } from '@ant-design/icons';
|
|
import OakIcon from 'oak-frontend-base/es/components/icon';
|
|
|
|
const EssayDetails = (
|
|
props: WebComponentProps<
|
|
EntityDict,
|
|
'essay',
|
|
false,
|
|
{
|
|
item: RowWithActions<EntityDict, 'essay'>;
|
|
cover: string;
|
|
isLiked: boolean;
|
|
likeNums: number;
|
|
}
|
|
>
|
|
) => {
|
|
const { item, cover, isLiked, likeNums } = props.data;
|
|
const [showScrollTop, setShowScrollTop] = useState(false);
|
|
const { t, update, execute } = props.methods;
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
if (window.scrollY > 300) {
|
|
setShowScrollTop(true);
|
|
} else {
|
|
setShowScrollTop(false);
|
|
}
|
|
};
|
|
|
|
window.addEventListener('scroll', handleScroll);
|
|
return () => window.removeEventListener('scroll', handleScroll);
|
|
}, []);
|
|
|
|
const scrollToTop = () => {
|
|
window.scrollTo({
|
|
top: 0,
|
|
behavior: 'smooth',
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className={Styles.essay}>
|
|
{item && (
|
|
<>
|
|
<div className={Styles.top}>
|
|
{cover ? (
|
|
<>
|
|
<img
|
|
className={Styles.backgroundfilter}
|
|
src={cover}
|
|
alt={item.title}
|
|
></img>
|
|
<img
|
|
className={Styles.backgroundImage}
|
|
src={cover}
|
|
alt={item.title}
|
|
></img>
|
|
</>
|
|
) : (
|
|
<div className={Styles.noCover}>{item.title}</div>
|
|
)}
|
|
<div className={Styles.title}>{item.title}</div>
|
|
</div>
|
|
{/* viewer */}
|
|
<div className={Styles.viewer}>
|
|
{/* 操作按钮,返回 */}
|
|
<div className={Styles.btns}>
|
|
<Button
|
|
className={Styles.back}
|
|
onClick={() => window.history.back()}
|
|
>
|
|
返回
|
|
</Button>
|
|
|
|
<div className={Styles.likes}>
|
|
{isLiked ? (
|
|
<Button
|
|
onClick={() => {
|
|
update({
|
|
}, 'unlike');
|
|
execute();
|
|
}}
|
|
shape='circle'
|
|
>
|
|
<OakIcon name='praise_fill' size={24} />
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
shape='circle'
|
|
onClick={() => {
|
|
update({}, 'like');
|
|
execute();
|
|
}}
|
|
>
|
|
<OakIcon name='praise' size={24} />
|
|
</Button>
|
|
)}
|
|
<div className={Styles.nums}>{likeNums}</div>
|
|
</div>
|
|
</div>
|
|
<MdViewer md={item.content!} />
|
|
</div>
|
|
<div className={Styles.blank}></div>
|
|
</>
|
|
)}
|
|
<div className={Styles.footer}>
|
|
<FrontendFooter />
|
|
</div>
|
|
{showScrollTop && (
|
|
<button
|
|
className={Styles.scrollTopButton}
|
|
onClick={scrollToTop}
|
|
>
|
|
<VerticalAlignTopOutlined />
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EssayDetails;
|