import { DetailedHTMLProps, HTMLAttributes, MouseEvent, ReactNode, UIEvent, useState } from 'react' import VanillaTilt, { TiltOptions } from 'vanilla-tilt' import Icon from '@ant-design/icons' import '@/assets/css/pages/tools/store.scss' import { COLOR_BACKGROUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants' import { r_tool_store_get } from '@/services/tool' import Card from '@/components/common/Card' import FlexBox from '@/components/common/FlexBox' import FitFullscreen from '@/components/common/FitFullscreen' import HideScrollbar from '@/components/common/HideScrollbar' interface CommonCardProps extends DetailedHTMLProps, HTMLDivElement> { icon: ReactNode toolName: string toolId: string toolDesc: string options?: TiltOptions url: string authorName: string authorAvatar: string authorUsername: string ver: string } const CommonCard = ({ style, // eslint-disable-next-line @typescript-eslint/no-unused-vars ref, icon, toolName, toolId, toolDesc, options = { reverse: true, max: 8, glare: true, ['max-glare']: 0.3, scale: 1.03 }, url, authorName, authorAvatar, authorUsername, ver, ...props }: CommonCardProps) => { const navigate = useNavigate() const cardRef = useRef(null) useEffect(() => { cardRef.current && VanillaTilt.init(cardRef.current, options) }, [options]) const handleCardOnClick = () => { url && navigate(url) } const handleOnSourceBtnClick = (e: MouseEvent) => { e.stopPropagation() navigate(`/source/${authorUsername}/${toolId}`) } return (
{icon}
V{ver}
{toolName}
{`ID: ${toolId}`}
{toolDesc &&
{`简介:${toolDesc}`}
}
}} src={`data:image/png;base64,${authorAvatar}`} alt={'Avatar'} /> } style={{ background: COLOR_BACKGROUND }} />
{authorName}
) } interface LoadMoreCardProps { onClick: () => void } const LoadMoreCard = ({ onClick }: LoadMoreCardProps) => { const cardRef = useRef(null) useEffect(() => { cardRef.current && VanillaTilt.init(cardRef.current, { reverse: true, max: 8, glare: true, ['max-glare']: 0.3, scale: 1.03 }) }, []) return (
{' '}
加载更多
) } const Store = () => { const scrollTopRef = useRef(0) const [isLoading, setIsLoading] = useState(false) const [currentPage, setCurrentPage] = useState(0) const [hasNextPage, setHasNextPage] = useState(true) const [toolData, setToolData] = useState([]) const [hideSearch, setHideSearch] = useState(false) const handleOnSearch = (value: string) => { getTool(1, value) } const handleOnScroll = (event: UIEvent) => { if (event.currentTarget.scrollTop < scrollTopRef.current) { setHideSearch(false) } else { setHideSearch(true) } scrollTopRef.current = event.currentTarget.scrollTop } const handleOnLoadMore = () => { if (isLoading) { return } getTool(currentPage + 1, '') } const getTool = (page: number, searchValue: string) => { if (isLoading) { return } setIsLoading(true) void message.loading({ content: '加载工具列表中', key: 'LOADING', duration: 0 }) void r_tool_store_get({ currentPage: page, searchValue }) .then((res) => { const response = res.data switch (response.code) { case DATABASE_SELECT_SUCCESS: setCurrentPage(response.data!.current) if (response.data!.current === response.data!.pages) { setHasNextPage(false) } if (response.data!.current === 1) { setToolData(response.data!.records) } else { setToolData([...toolData, ...response.data!.records]) } break default: void message.error('加载失败,请稍后重试') } }) .finally(() => { setIsLoading(false) message.destroy('LOADING') }) } useEffect(() => { getTool(1, '') }, []) return ( <>
{toolData?.map((value) => ( } toolName={value.name} toolId={value.toolId} toolDesc={value.description} url={`/view/${value.author.username}/${value.toolId}`} authorName={value.author.userInfo.nickname} authorAvatar={value.author.userInfo.avatar} authorUsername={value.author.username} ver={value.ver} /> ))} {hasNextPage && }
) } export default Store