From 8da13014d8ce9fb93f5870d10673a54d19267e52 Mon Sep 17 00:00:00 2001 From: non_hana <1209220829@qq.com> Date: Sun, 14 Jul 2024 20:47:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/explore/latest-list/index.tsx | 3 + src/components/explore/work-list/index.tsx | 3 + .../followed-new/main-list/index.tsx | 3 + src/components/home/followed-works/index.tsx | 5 + .../home/recommended-works/index.tsx | 3 + src/components/illustrator/waterfall-flow.tsx | 18 +- .../personal-center/favorites/header.tsx | 22 +- .../personal-center/favorites/work-list.tsx | 16 +- .../personal-center/history/history-list.tsx | 3 + .../personal-center/work-list/index.tsx | 3 + .../search-result/work-list/index.tsx | 4 +- .../work-detail/view-list/index.tsx | 205 ++++++++++++++++-- src/pages/illustrator/index.tsx | 10 +- .../personal-center/my-favorites/index.tsx | 5 +- src/utils/constants.ts | 2 + 15 files changed, 267 insertions(+), 38 deletions(-) diff --git a/src/components/explore/latest-list/index.tsx b/src/components/explore/latest-list/index.tsx index a104c45..794f26b 100644 --- a/src/components/explore/latest-list/index.tsx +++ b/src/components/explore/latest-list/index.tsx @@ -13,6 +13,8 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' const LatestList: FC = () => { const location = useLocation() @@ -85,6 +87,7 @@ const LatestList: FC = () => { dispatch(pushToLatestWorkList(result)) dispatch(setCurrentList('latestWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['latestWorkList']}`) } return ( diff --git a/src/components/explore/work-list/index.tsx b/src/components/explore/work-list/index.tsx index d354eb0..0a7c667 100644 --- a/src/components/explore/work-list/index.tsx +++ b/src/components/explore/work-list/index.tsx @@ -14,6 +14,8 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' const WorkList: FC = () => { const location = useLocation() @@ -86,6 +88,7 @@ const WorkList: FC = () => { dispatch(pushToRecommendWorkList(result)) dispatch(setCurrentList('recommendWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['recommendWorkList']}`) } return ( diff --git a/src/components/followed-new/main-list/index.tsx b/src/components/followed-new/main-list/index.tsx index 4af1a45..6675e6e 100644 --- a/src/components/followed-new/main-list/index.tsx +++ b/src/components/followed-new/main-list/index.tsx @@ -16,6 +16,8 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' type MainListProps = { pageSize: number @@ -58,6 +60,7 @@ const MainList: FC = ({ pageSize, current }) => { dispatch(pushToFollowingNewWorkList(data)) dispatch(setCurrentList('followingNewWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['followingNewWorkList']}`) } return ( diff --git a/src/components/home/followed-works/index.tsx b/src/components/home/followed-works/index.tsx index bed2f0d..fe2732d 100644 --- a/src/components/home/followed-works/index.tsx +++ b/src/components/home/followed-works/index.tsx @@ -13,7 +13,10 @@ import { pushToFollowingNewWorkList, resetOtherList, setCurrentList, + setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' type FollowedWorksProps = { loading: boolean @@ -39,6 +42,8 @@ const FollowedWorks: FC = ({ loading, workList: sourceData } dispatch(resetOtherList()) dispatch(pushToFollowingNewWorkList(data)) dispatch(setCurrentList('followingNewWorkList')) + dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['followingNewWorkList']}`) } return ( diff --git a/src/components/home/recommended-works/index.tsx b/src/components/home/recommended-works/index.tsx index 29554df..ece195f 100644 --- a/src/components/home/recommended-works/index.tsx +++ b/src/components/home/recommended-works/index.tsx @@ -14,6 +14,8 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' type RecommendedWorksProps = { loading: boolean @@ -39,6 +41,7 @@ const RecommendedWorks: FC = ({ loading, workList: source dispatch(pushToRecommendWorkList(sourceData.map((item) => item.id))) dispatch(setCurrentList('recommendWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['recommendWorkList']}`) } return ( diff --git a/src/components/illustrator/waterfall-flow.tsx b/src/components/illustrator/waterfall-flow.tsx index b29f494..1e6b8b5 100644 --- a/src/components/illustrator/waterfall-flow.tsx +++ b/src/components/illustrator/waterfall-flow.tsx @@ -1,5 +1,5 @@ import { FC, useEffect, useState, useRef } from 'react' -import { useLocation } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { useDispatch } from 'react-redux' import { useParams } from 'react-router-dom' import { getIllustratorWorksInPagesAPI, getIllustratorWorksIdListAPI } from '@/apis' @@ -12,12 +12,19 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' const listClass = 'absolute w-80 flex flex-col gap-5' type WaterfallItemInfo = WorkNormalItem & { index: number; height: number } -const WaterfallFlow: FC = () => { +type WaterfallFlowProps = { + startAppreciate: boolean +} + +const WaterfallFlow: FC = ({ startAppreciate }) => { + const navigate = useNavigate() const location = useLocation() const dispatch = useDispatch() @@ -84,8 +91,15 @@ const WaterfallFlow: FC = () => { dispatch(pushToIllustratorWorkList(data)) dispatch(setCurrentList('illustratorWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['illustratorWorkList']}`) } + useEffect(() => { + if (!startAppreciate) return + navigate(`/work-detail/${workList[0].id}`) + addIllustratorWorks() + }, [startAppreciate]) + return (
diff --git a/src/components/personal-center/favorites/header.tsx b/src/components/personal-center/favorites/header.tsx index d587e23..e3e1c84 100644 --- a/src/components/personal-center/favorites/header.tsx +++ b/src/components/personal-center/favorites/header.tsx @@ -1,16 +1,22 @@ import { FC } from 'react' import type { FavoriteDetailInfo } from '@/utils/types' import { Link } from 'react-router-dom' -import { Button, message } from 'antd' +import { Button } from 'antd' import LazyImg from '@/components/common/lazy-img' -type HeaderProps = FavoriteDetailInfo - -const Header: FC = ({ name, intro, creatorId, creatorName, cover, workNum }) => { - const handleViewWorkList = () => { - message.info('该功能暂未开放,敬请期待~!') - } +type HeaderProps = FavoriteDetailInfo & { + setStartAppreciate: (status: boolean) => void +} +const Header: FC = ({ + name, + intro, + creatorId, + creatorName, + cover, + workNum, + setStartAppreciate, +}) => { return (
@@ -31,7 +37,7 @@ const Header: FC = ({ name, intro, creatorId, creatorName, cover, w {intro}
-
diff --git a/src/components/personal-center/favorites/work-list.tsx b/src/components/personal-center/favorites/work-list.tsx index 8587875..5e2284c 100644 --- a/src/components/personal-center/favorites/work-list.tsx +++ b/src/components/personal-center/favorites/work-list.tsx @@ -1,5 +1,5 @@ import { FC, useEffect, useState, useContext } from 'react' -import { useSearchParams, useLocation } from 'react-router-dom' +import { useSearchParams, useLocation, useNavigate } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' import type { AppState } from '@/store/types' import type { WorkNormalItemInfo } from '@/utils/types' @@ -23,6 +23,7 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { VIEW_LIST_MAP } from '@/utils' const { Search } = Input const { confirm } = Modal @@ -38,6 +39,7 @@ type WorkListProps = { setSearchStatus: (status: boolean) => void refresh: () => Promise // 刷新作品列表 like: (id: string) => void + startAppreciate: boolean } const WorkList: FC = ({ @@ -51,7 +53,9 @@ const WorkList: FC = ({ setSearchStatus, refresh, like, + startAppreciate, }) => { + const navigate = useNavigate() const location = useLocation() const { isMe } = useContext(PersonalContext) @@ -214,8 +218,18 @@ const WorkList: FC = ({ dispatch(pushToFavoriteWorkList(data)) dispatch(setCurrentList('favoriteWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['favoriteWorkList']}`) } + useEffect(() => { + if (!startAppreciate) return + if (workList.length === 0) { + messageApi.info('暂无作品,快去收藏一些吧~') + } + navigate(`/work-detail/${workList[0].id}`) + addFavoriteWorks() + }, [startAppreciate]) + return ( <> {contextHolder} diff --git a/src/components/personal-center/history/history-list.tsx b/src/components/personal-center/history/history-list.tsx index 4d8119e..a038d2a 100644 --- a/src/components/personal-center/history/history-list.tsx +++ b/src/components/personal-center/history/history-list.tsx @@ -12,6 +12,8 @@ import GreyButton from '@/components/common/grey-button' import dayjs from 'dayjs' import { getViewHistoryAPI, getViewHistoryTotalAPI } from '@/apis' import { resetOtherList, setCurrentList, setPrevPosition } from '@/store/modules/viewList' +import { message } from 'antd' +import { VIEW_LIST_MAP } from '@/utils' const HistoryList: FC = () => { const location = useLocation() @@ -81,6 +83,7 @@ const HistoryList: FC = () => { dispatch(resetOtherList()) dispatch(setCurrentList('userWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['userWorkList']}`) } return ( diff --git a/src/components/personal-center/work-list/index.tsx b/src/components/personal-center/work-list/index.tsx index 72bf16c..1cead80 100644 --- a/src/components/personal-center/work-list/index.tsx +++ b/src/components/personal-center/work-list/index.tsx @@ -23,6 +23,7 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { VIEW_LIST_MAP } from '@/utils' type WorkListProps = { workCount: number @@ -110,11 +111,13 @@ const WorkList: FC = ({ workCount, getWorkCount }) => { if (currentPath === 'works') { dispatch(resetOtherList()) dispatch(setCurrentList('userWorkList')) + message.success(`成功进入至 ${VIEW_LIST_MAP['userWorkList']}`) } else { const { data } = await getUserLikeWorksIdListAPI({ id: userId! }) dispatch(resetOtherList()) dispatch(pushToLikeWorkList(data)) dispatch(setCurrentList('likeWorkList')) + message.success(`成功进入至 ${VIEW_LIST_MAP['likeWorkList']}`) } dispatch(setPrevPosition(location.pathname + location.search)) } diff --git a/src/components/search-result/work-list/index.tsx b/src/components/search-result/work-list/index.tsx index 915e47f..7d5c368 100644 --- a/src/components/search-result/work-list/index.tsx +++ b/src/components/search-result/work-list/index.tsx @@ -5,7 +5,7 @@ import type { WorkNormalItemInfo } from '@/utils/types' import { useMap } from '@/hooks' import WorkNormalItem from '@/components/common/work-normal-item' import Pagination from '@/components/common/pagination' -import { Radio, RadioChangeEvent } from 'antd' +import { message, Radio, RadioChangeEvent } from 'antd' import { likeActionsAPI, searchWorksByLabelAPI, searchWorksIdListAPI } from '@/apis' import Empty from '@/components/common/empty' import { CSSTransition } from 'react-transition-group' @@ -16,6 +16,7 @@ import { setCurrentList, setPrevPosition, } from '@/store/modules/viewList' +import { VIEW_LIST_MAP } from '@/utils' const sortOptions = [ { label: '按最新排序', value: 'new' }, @@ -99,6 +100,7 @@ const WorkList: FC = ({ labelName, sortType: URLSortType, workCou dispatch(pushToSearchResultWorkList(data)) dispatch(setCurrentList('searchResultWorkList')) dispatch(setPrevPosition(location.pathname + location.search)) + message.success(`成功进入至 ${VIEW_LIST_MAP['searchResultWorkList']}`) } return ( diff --git a/src/components/work-detail/view-list/index.tsx b/src/components/work-detail/view-list/index.tsx index b71eff1..826be7d 100644 --- a/src/components/work-detail/view-list/index.tsx +++ b/src/components/work-detail/view-list/index.tsx @@ -3,8 +3,14 @@ import { Link, useNavigate } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' import type { AppState } from '@/store/types' import { VIEW_LIST_MAP, VIEW_LIST_ICON_MAP } from '@/utils' -import { getRecommendWorksAPI, getUserWorksIdListAPI, getWorkSimpleAPI } from '@/apis' import { + getRecommendWorksAPI, + getLatestWorksAPI, + getUserWorksIdListAPI, + getWorkSimpleAPI, +} from '@/apis' +import { + pushToLatestWorkList, pushToRecommendWorkList, pushToUserWorkList, setCurrentIndex, @@ -89,7 +95,7 @@ const ViewList: FC = ({ const recommendPageSize = 30 const [recommendIsFinal, setRecommendIsFinal] = useState(false) const [recommendCurrentChanged, setRecommendCurrentChanged] = useState(0) - const [loading, setLoading] = useState(false) + const [recommendLoading, setRecommendLoading] = useState(false) const [recommendWorkList, setRecommendWorkList] = useState< { page: number @@ -133,7 +139,7 @@ const ViewList: FC = ({ }, [allowListName]) const getRecommendWorksList = async () => { - setLoading(true) + setRecommendLoading(true) try { const { data } = await getRecommendWorksAPI({ current: recommendCurrent!, @@ -158,7 +164,7 @@ const ViewList: FC = ({ console.log('出现错误了喵!!', error) return } finally { - setLoading(false) + setRecommendLoading(false) } } @@ -170,10 +176,10 @@ const ViewList: FC = ({ useEffect(() => { if (allowListName === 'recommendWorkList') { - if (loading) messageApi.loading('正在获取推荐作品列表...', 0) + if (recommendLoading) messageApi.loading('正在获取推荐作品列表...', 0) else messageApi.destroy() } - }, [loading, allowListName]) + }, [recommendLoading, allowListName]) useEffect(() => { if (allowListName === 'recommendWorkList' && recommendCurrentChanged > 1) { @@ -199,6 +205,118 @@ const ViewList: FC = ({ }, [recommendListEnd, allowListName]) //#endregion + //#region 分页获取最新作品列表 + const [latestCurrent, setLatestCurrent] = useState() + const latestPageSize = 30 + const [latestIsFinal, setLatestIsFinal] = useState(false) + const [latestCurrentChanged, setLatestCurrentChanged] = useState(0) + const [latestLoading, setLatestLoading] = useState(false) + const [latestWorkList, setLatestWorkList] = useState< + { + page: number + list: WorkNormalItemInfo[] + }[] + >([]) + const [latestListEnd, setLatestListEnd] = useState(false) + const [latestInit, setLatestInit] = useState(true) + + const initLatestWorksList = async (initPage: number) => { + setLatestInit(true) + try { + for (let i = 1; i <= initPage; i++) { + const targetList = lists.latestWorkList.slice((i - 1) * latestPageSize, i * latestPageSize) + const resultList = await Promise.all( + targetList.map(async (id) => { + const { data } = await getWorkSimpleAPI({ id }) + return data + }), + ) + setLatestWorkList((prev) => [...prev, { page: i, list: resultList }]) + } + setLatestWorkList((prev) => [...prev, { page: initPage + 1, list: [] }]) + } catch (error) { + console.log('出现错误了喵!!', error) + return + } finally { + setLatestInit(false) + } + } + + useEffect(() => { + if (allowListName === 'latestWorkList') { + const initPage = Math.ceil(lists.latestWorkList.length / latestPageSize) + setLatestCurrent(initPage) + initLatestWorksList(initPage) + } + }, [allowListName]) + + const getLatestWorksList = async () => { + setLatestLoading(true) + try { + const { data } = await getLatestWorksAPI({ + current: latestCurrent!, + pageSize: latestPageSize, + }) + if (data.length < latestPageSize) { + setLatestIsFinal(true) + } + setLatestWorkList((prev) => { + const result = prev.map((item) => { + if (item.page === latestCurrent) { + return { page: item.page, list: data } + } + return item + }) + if (!latestIsFinal) result.push({ page: latestCurrent! + 1, list: [] }) + return result + }) + const result = data.map((work) => work.id) + dispatch(pushToLatestWorkList(result)) + } catch (error) { + console.log('出现错误了喵!!', error) + return + } finally { + setLatestLoading(false) + } + } + + useEffect(() => { + if (allowListName === 'latestWorkList' && latestCurrent) { + setLatestCurrentChanged((prev) => prev + 1) + } + }, [latestCurrent, allowListName]) + + useEffect(() => { + if (allowListName === 'latestWorkList') { + if (latestLoading) messageApi.loading('正在获取最新作品列表...', 0) + else messageApi.destroy() + } + }, [latestLoading, allowListName]) + + useEffect(() => { + if (allowListName === 'latestWorkList' && latestCurrentChanged > 1) { + getLatestWorksList() + } + }, [latestCurrentChanged, allowListName]) + + useEffect(() => { + if ( + allowListName === 'latestWorkList' && + currentIndex >= currentListLength && + !latestIsFinal && + latestCurrent + ) { + setLatestCurrent((prev) => prev! + 1) + } + }, [currentIndex, allowListName]) + + useEffect(() => { + if (allowListName === 'latestWorkList' && latestListEnd && !latestIsFinal) { + setLatestCurrent((prev) => prev! + 1) + } + }, [latestListEnd, allowListName]) + //#endregion + //#region 分页获取当前浏览的作品列表信息(用户作品列表和推荐作品列表除外) const [current, setCurrent] = useState(1) const [isFinal, setIsFinal] = useState(false) @@ -334,6 +452,24 @@ const ViewList: FC = ({ return () => window.removeEventListener('keydown', handleKeyDown) }, [currentIndex, currentListLength, showIndexInput]) + // WorkSlideWindow 展示状态数组 + const [showSlideWindows, setShowSlideWindows] = useState<[boolean, boolean, boolean, boolean]>([ + false, + false, + false, + false, + ]) + useEffect(() => { + setShowSlideWindows([ + currentList !== 'userWorkList' && + currentList !== 'recommendWorkList' && + currentList !== 'latestWorkList', + currentList === 'recommendWorkList', + currentList === 'latestWorkList', + currentList === 'userWorkList', + ]) + }, [currentList]) + return ( <> {contextHolder} @@ -387,19 +523,17 @@ const ViewList: FC = ({
@@ -416,13 +550,14 @@ const ViewList: FC = ({
@@ -438,14 +573,38 @@ const ViewList: FC = ({
+ + + +
+
changeList('userWorkList')}> 用户作品 - {currentList === 'userWorkList' && + {showSlideWindows[3] && (!showIndexInput ? ( setShowIndexInput(true)}>{currentIndex}/ ) : ( @@ -471,13 +630,13 @@ const ViewList: FC = ({
diff --git a/src/pages/illustrator/index.tsx b/src/pages/illustrator/index.tsx index c849024..468daa9 100644 --- a/src/pages/illustrator/index.tsx +++ b/src/pages/illustrator/index.tsx @@ -30,6 +30,8 @@ const Illustrator: FC = () => { getIllustratorDetail() }, [illustratorId]) + const [startAppreciate, setStartAppreciate] = useState(false) + return (
@@ -67,14 +69,18 @@ const Illustrator: FC = () => { -
)}
- +
diff --git a/src/pages/personal-center/my-favorites/index.tsx b/src/pages/personal-center/my-favorites/index.tsx index 5327bb1..704392e 100644 --- a/src/pages/personal-center/my-favorites/index.tsx +++ b/src/pages/personal-center/my-favorites/index.tsx @@ -145,6 +145,8 @@ const MyFavorites: FC = () => { fetchFavoriteList() }, [userId]) + const [startAppreciate, setStartAppreciate] = useState(false) + return (
{ {folderId ? ( favoriteDetailInfo && ( <> -
+
{ handleSearch={handleSearch} refresh={refresh} like={like} + startAppreciate={startAppreciate} /> ) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 9e8a6e8..fce8ca2 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -89,6 +89,7 @@ export const VIEW_LIST_MAP = { favoriteWorkList: '收藏作品', followingNewWorkList: '关注作品', recommendWorkList: '推荐作品', + latestWorkList: '最新作品', illustratorWorkList: '原作作品', searchResultWorkList: '搜索结果', } @@ -100,6 +101,7 @@ export const VIEW_LIST_ICON_MAP = { favoriteWorkList: 'material-symbols:star-outline', followingNewWorkList: 'material-symbols:bookmark-outline', recommendWorkList: 'material-symbols:recommend-outline', + latestWorkList: 'material-symbols:alarm-outline', illustratorWorkList: 'material-symbols:school-outline', searchResultWorkList: 'material-symbols:search', }