From 51dea048a8f518eac5737c7a6e2ae585a8bfe398 Mon Sep 17 00:00:00 2001 From: master1lan <278457198@qq.com> Date: Sat, 28 Jan 2023 20:06:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87=E9=A1=B5?= =?UTF-8?q?=EF=BC=8Cv0.02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/image/index.tsx | 14 +- src/components/proview/themePreview.tsx | 3 - src/routers/error.tsx | 12 +- src/routers/layout/logo.tsx | 33 +++- .../layout/nav/{tools.ts => VideoTools.ts} | 36 ++-- src/routers/layout/nav/index.tsx | 155 ++++++++++++------ src/routers/layout/nav/photoTools.ts | 108 ++++++++++++ src/routers/layout/routernav/menu.tsx | 7 +- src/routers/photo/index.tsx | 20 ++- src/routers/photo/item/index.tsx | 27 ++- src/routers/photo/item/photo.module.less | 7 - src/routers/photo/masonry.tsx | 73 ++++++--- src/routers/photo/photo.module.less | 10 ++ src/routers/photo/phototype.ts | 2 +- src/routers/photo/tools.ts | 3 +- src/store/tags/index.ts | 82 ++++++++- src/utils/fetch/index.ts | 1 + 17 files changed, 448 insertions(+), 145 deletions(-) rename src/routers/layout/nav/{tools.ts => VideoTools.ts} (82%) create mode 100644 src/routers/layout/nav/photoTools.ts create mode 100644 src/routers/photo/photo.module.less diff --git a/src/components/image/index.tsx b/src/components/image/index.tsx index 1f3ba3d..b8e753c 100644 --- a/src/components/image/index.tsx +++ b/src/components/image/index.tsx @@ -54,7 +54,7 @@ export default memo(function Image({ return ( {({ inView, ref, entry }) => ( -
+ <>{observer && inView && once_callback(inView)} {children} -
+ )}
); @@ -88,15 +88,7 @@ export function ImageBasic({ {({ inView, ref, entry }) => ( - + <>{observer && inView && once_callback(inView)} {children} diff --git a/src/components/proview/themePreview.tsx b/src/components/proview/themePreview.tsx index f8cc3a4..9f4886d 100644 --- a/src/components/proview/themePreview.tsx +++ b/src/components/proview/themePreview.tsx @@ -36,9 +36,6 @@ declare module "@mui/material/Button" { } } const theme = createTheme({ - typography: { - fontFamily: "Proxima Soft", - }, palette: { luzao: { main: "#3dff9e", contrastText: "#fff" }, luzaoRed: { main: "#A0191D", contrastText: "#fff" }, diff --git a/src/routers/error.tsx b/src/routers/error.tsx index ca872ec..8eed330 100644 --- a/src/routers/error.tsx +++ b/src/routers/error.tsx @@ -1,3 +1,4 @@ +import message from "@components/message"; import { Button } from "@mui/material"; import { Link } from "react-router-dom"; @@ -24,11 +25,15 @@ export default function ErrorPage() { - 和 - + 、 + - 两个页面(虽然两个是同一个页面)。 + 和 + + + + 。

请尝试点击链接 @@ -49,4 +54,5 @@ export default function ErrorPage() { const deleteAllDataStorage = () => { localStorage.clear(); sessionStorage.clear(); + message.info("重置网站数据成功!"); }; diff --git a/src/routers/layout/logo.tsx b/src/routers/layout/logo.tsx index aa6278c..82ca977 100644 --- a/src/routers/layout/logo.tsx +++ b/src/routers/layout/logo.tsx @@ -1,4 +1,4 @@ -import { Button, Modal, styled } from "@mui/material"; +import { Button, Link, Modal, styled } from "@mui/material"; import { FC, useState } from "react"; import styles from "./layout.module.less"; @@ -56,6 +56,37 @@ const Explain: FC<{ open: boolean; handlerClick: () => void }> = (props) => (

+
  • +

    + Q: + 如何进行用户反馈? +

    +

    + A: + + 请前往 + + eoefans反馈 + + +

    +
  • +
  • +

    + Q: + 图片页图片太小了? +

    +

    + A: + + 图片页可点击图片进入放大镜模式,支持手势返回和空白处返回;可使用双指放大对图片大小进行调整。 + +

    +
  • - ); -}); + const color = nameToColor[props.query] || "info"; + return ( + + ); + } +); const nameToColor = { 露早: "luzaoRed", diff --git a/src/routers/layout/nav/photoTools.ts b/src/routers/layout/nav/photoTools.ts new file mode 100644 index 0000000..7b12cc4 --- /dev/null +++ b/src/routers/layout/nav/photoTools.ts @@ -0,0 +1,108 @@ +import { nanoid } from "nanoid"; +import { useMemo, useState } from "react"; +import { Storage } from "../tools"; +import { getVersion } from "@utils/index"; +import { IFetchPhotoParams } from "@utils/fetch/fetchtype"; + +export interface PhotoNavStorage { + version: string; + res: PhotoNavQueryItemType[]; +} +export const PhotoNavStorage = new Storage("photonavTagLists"); + +export function usePhotoNavList(): [ + PhotoNavQueryItemType[], + React.Dispatch> +] { + const nav_ok_lists = useMemo(() => { + const local_lists = PhotoNavStorage.getLocalStorage({ + version: getVersion(), + res: [], + } as PhotoNavStorage); + if (!local_lists.version || local_lists.res.length < 2) { + return photo_query_nav_list; + } + //todo change logi + if (parseFloat(local_lists.version) < parseFloat(getVersion())) { + return photo_query_nav_list; + } + return local_lists.res; + }, []); + const [navLists, setLists] = useState(nav_ok_lists); + return [navLists, setLists]; +} + +export type PhotoTopicType = { + id: String; + type: "photo-selected"; + query: string; + queryType: "topic_id"; + queryString: IFetchPhotoParams["topic_id"]; +}; +export type PhotoSearchType = { + id: String; + type: "photo-selected"; + query: string; + queryType: "type"; + queryString: IFetchPhotoParams["type"]; +}; + +export type PhotoNavQueryItemType = PhotoTopicType | PhotoSearchType; + +const nav_tag_list_no_id: Pick< + PhotoNavQueryItemType, + "query" | "queryString" | "queryType" + >[] = [ + { + query: "最新图片", + queryType: "type", + queryString: "latest", + }, + { + query: "推荐图片", + queryType: "type", + queryString: "recommend", + }, + { + query: "全部", + queryType: "topic_id", + queryString: 0, + }, + { + query: "露早", + queryType: "topic_id", + queryString: 29067608, + }, + { + query: "柚恩", + queryType: "topic_id", + queryString: 28950030, + }, + { + query: "莞儿", + queryType: "topic_id", + queryString: 28953983, + }, + { + query: "米诺", + queryType: "topic_id", + queryString: 29069147, + }, + { + query: "虞莫", + queryType: "topic_id", + queryString: 28948378, + }, + { + query: "EOE组合", + queryType: "topic_id", + queryString: 29156150, + }, + ], + photo_query_nav_list = nav_tag_list_no_id.map((item) => ({ + ...item, + id: nanoid(3), + type: "photo-selected", + })) as PhotoNavQueryItemType[]; + +export const PhotoQueryNavList = photo_query_nav_list; diff --git a/src/routers/layout/routernav/menu.tsx b/src/routers/layout/routernav/menu.tsx index 931cf0a..3bb2b2d 100644 --- a/src/routers/layout/routernav/menu.tsx +++ b/src/routers/layout/routernav/menu.tsx @@ -29,7 +29,12 @@ export default function MenuRouter() { } function RouterItem(props: TabProps & { onClick: () => void }) { return ( - + ); diff --git a/src/routers/photo/index.tsx b/src/routers/photo/index.tsx index e3a679a..38b5904 100644 --- a/src/routers/photo/index.tsx +++ b/src/routers/photo/index.tsx @@ -1,13 +1,23 @@ import Masonry from "./masonry"; +import { useAppSelector } from "@store/hooks"; +import { selectPhotoActiveTags } from "@store/tags"; +import { + PhotoSearchType, + PhotoTopicType, +} from "@routers/layout/nav/photoTools"; export default function PhotoPage() { + const activeTags = useAppSelector(selectPhotoActiveTags), + typeitem = activeTags.find( + (item) => item.queryType === "type" + )! as PhotoSearchType, + topicItem = activeTags.find( + (item) => item.queryType === "topic_id" + ) as PhotoTopicType; + return ( <> - + ); } -//todo 替换掉nav,应该在每个路由下有单独的nav -//todo 添加滚动加载-photo页面 -//todo 选好nav列表 -//todo photo图片进行收缩 diff --git a/src/routers/photo/item/index.tsx b/src/routers/photo/item/index.tsx index 82294cd..bd290eb 100644 --- a/src/routers/photo/item/index.tsx +++ b/src/routers/photo/item/index.tsx @@ -2,7 +2,7 @@ import { PhotoRouterImageCardType } from "../phototype"; import { useState } from "react"; import ImgModals from "./modal"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; -import { Link } from "@mui/material"; +import { Link, styled } from "@mui/material"; import style from "./photo.module.less"; import { ImageBasic } from "@components/image"; import { Omit } from "@utils/index"; @@ -11,20 +11,21 @@ type CardType = { }; export default function PhotoCard(props: CardType) { - const { images, dynamic_id } = props.data; + const { images, dynamic_id, ...resPorps } = props.data; const [open, set] = useState(false), handlerChangeOpen = () => set((open) => !open); const modalPorps = { open, images, onClose: handlerChangeOpen }; return (
    -
    + -
    +
    ); } +const DivJump = styled("div")(({ theme }) => ({ + borderBottomLeftRadius: "8px", + borderBottomRightRadius: "8px", + position: "absolute", + bottom: "0px", + width: "100%", + backgroundImage: `linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.8) 100%)`, + [theme.breakpoints.down("sm")]: { + borderBottomLeftRadius: "4px", + borderBottomRightRadius: "4px", + }, +})); diff --git a/src/routers/photo/item/photo.module.less b/src/routers/photo/item/photo.module.less index f1952e7..dbf589a 100644 --- a/src/routers/photo/item/photo.module.less +++ b/src/routers/photo/item/photo.module.less @@ -9,11 +9,4 @@ width: 100%; border-radius: 4px; } - - .jump { - position: absolute; - bottom: 0; - width: 100%; - background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.8) 100%); - } } \ No newline at end of file diff --git a/src/routers/photo/masonry.tsx b/src/routers/photo/masonry.tsx index 24c1072..7cf9eed 100644 --- a/src/routers/photo/masonry.tsx +++ b/src/routers/photo/masonry.tsx @@ -1,16 +1,17 @@ import { selectPhotoLoadingState } from "@store/loading"; import { Masonry as Masonic_masonry } from "masonic"; -import { useState, useEffect, FC } from "react"; +import { useState, useEffect } from "react"; import { useAppSelector, useAppDispatch } from "@store/hooks"; import { changeLoading } from "@store/loading/index"; import { fetchPhotoHandler } from "./tools"; -import { PhotoRouterImageCardType } from "./phototype"; +import { PhotoRouterImageCardType, PhotoRouterMasonryType } from "./phototype"; import PhotoCard from "./item"; import { useScreenSize } from "@components/proview/screenSize"; - +import message from "@components/message"; +import styles from "./photo.module.less"; //todo props type change -export default function Masonry(props: any) { +export default function Masonry(props: PhotoRouterMasonryType) { const [lists, setList] = useState([]); const isLoading = useAppSelector(selectPhotoLoadingState), dispatch = useAppDispatch(), @@ -25,38 +26,58 @@ export default function Masonry(props: any) { const fetchHandler = async (page: number = 0) => { const data = await fetchPhotoHandler({ page, - topic_id: 0, - type: "latest", + ...props, }); setList((lists) => { return [ ...lists, - ...data.map((item) => ({ - dynamic_id: item.dynamic_id, - images: item.pictures.map((img) => ({ - src: img.img_src, - height: img.img_height, - width: img.img_width, - })), - })), + ...data.map((item, index) => { + const itemRes = { + dynamic_id: item.dynamic_id, + images: item.pictures.map((img) => ({ + src: img.img_src, + height: img.img_height, + width: img.img_width, + })), + }; + if (data.length < 3) { + message.info("没有更多图片了,尝试使用其他tag吧!"); + } + if (index === data.length - 3) { + return { + ...itemRes, + observer: true, + callback: (inView: boolean) => { + fetchHandler(page + 1); + }, + }; + } + return itemRes; + }), ]; }); }; - fetchHandler(); + setList(() => []); + handerChangeLoading(true); + fetchHandler(1).then(() => handerChangeLoading(false)); }, [props]); const { sm, md } = useScreenSize(), minCount = sm ? { columnCount: 2 } : {}; return ( - <> - - +
    + {isLoading || ( + + )} +
    ); } diff --git a/src/routers/photo/photo.module.less b/src/routers/photo/photo.module.less new file mode 100644 index 0000000..2cf7492 --- /dev/null +++ b/src/routers/photo/photo.module.less @@ -0,0 +1,10 @@ +.container:empty { + display: flex; + justify-content: center; + + &::before { + margin-top: 50px; + content: "暂无数据"; + color: #c1c1c1; + } +} \ No newline at end of file diff --git a/src/routers/photo/phototype.ts b/src/routers/photo/phototype.ts index e73b313..7adbae2 100644 --- a/src/routers/photo/phototype.ts +++ b/src/routers/photo/phototype.ts @@ -14,4 +14,4 @@ export type PhotoRouterImageCardType = { callback?: (inView: boolean) => void; }; -export type PhotoRouterMasonryType = IFetchPhotoParams; +export type PhotoRouterMasonryType = Omit; diff --git a/src/routers/photo/tools.ts b/src/routers/photo/tools.ts index 1e82a2f..6de1a6b 100644 --- a/src/routers/photo/tools.ts +++ b/src/routers/photo/tools.ts @@ -8,8 +8,9 @@ export const fetchPhotoHandler = async (params: IFetchPhotoParams) => { res.code === 400 && message.info("参数错误,请尝试其他tag"); res.code === 500 && message.info(res.message); return []; - } else if (res.data.result.length < 1) { + } else if (res.data.result == null || res.data.result.length < 1) { message.info("没有更多数据了,请尝试其他tag"); + return []; } return res.data.result; }; diff --git a/src/store/tags/index.ts b/src/store/tags/index.ts index de6c058..89131f4 100644 --- a/src/store/tags/index.ts +++ b/src/store/tags/index.ts @@ -1,16 +1,31 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit"; -import { NavQueryItemType } from "@routers/layout/nav/tools"; - +import { VideoNavQueryItemType } from "@routers/layout/nav/VideoTools"; +import { + PhotoNavQueryItemType, + PhotoQueryNavList, +} from "@routers/layout/nav/photoTools"; import type { RootState } from ".."; +const Photo_Topic_id_all = PhotoQueryNavList.find( + (item) => item.queryString === 0 + )!, + Photo_type_default = PhotoQueryNavList.find( + (item) => item.queryString === "recommend" + )!; + interface TagStates { /** * @description video页面点击tags */ - VideoActiveTags: NavQueryItemType[]; + VideoActiveTags: VideoNavQueryItemType[]; + /** + * @description photo page active tags + */ + PhotoActivetags: PhotoNavQueryItemType[]; } const initialState: TagStates = { VideoActiveTags: [], + PhotoActivetags: [Photo_Topic_id_all, Photo_type_default], }; export const ActiveTagsSlice = createSlice({ name: "VideoActiveTags", @@ -19,7 +34,10 @@ export const ActiveTagsSlice = createSlice({ /** * @description video页面添加tag */ - handerVideoAddTag: (state, action: PayloadAction) => { + handerVideoAddTag: ( + state, + action: PayloadAction + ) => { //这里需要注意的是queryType多种,只有q可以同存. switch (action.payload.queryType) { case "q": @@ -33,20 +51,68 @@ export const ActiveTagsSlice = createSlice({ } state.VideoActiveTags = [...state.VideoActiveTags, action.payload]; }, + /** + * @description photo page add activeTags + */ + handerPhotoAddTag: ( + state, + action: PayloadAction + ) => { + state.PhotoActivetags = state.PhotoActivetags.filter( + (item) => item.queryType !== action.payload.queryType + ); + state.PhotoActivetags.push(action.payload); + }, /** * @description video页面删除tag */ - handerVideoDeleteTag: (state, action: PayloadAction) => { + handerVideoDeleteTag: ( + state, + action: PayloadAction + ) => { state.VideoActiveTags = state.VideoActiveTags.filter( (item) => item.id !== action.payload.id ); }, + /** + * @description photo page delete activetags + */ + handerPhotoDeleteTag: ( + state, + action: PayloadAction + ) => { + state.PhotoActivetags = state.PhotoActivetags.filter( + (item) => item.id !== action.payload.id + ); + if ( + !state.PhotoActivetags.some( + (item) => item.queryType === action.payload.queryType + ) + ) { + switch (action.payload.queryType) { + case "topic_id": { + state.PhotoActivetags.push(Photo_Topic_id_all); + break; + } + default: { + state.PhotoActivetags.push(Photo_type_default); + break; + } + } + } + }, }, }); -export const { handerVideoAddTag, handerVideoDeleteTag } = - ActiveTagsSlice.actions; +export const { + handerVideoAddTag, + handerVideoDeleteTag, + handerPhotoAddTag, + handerPhotoDeleteTag, +} = ActiveTagsSlice.actions; export const selectVideoActiveTags = (state: RootState) => - state.ActiveTags.VideoActiveTags; + state.ActiveTags.VideoActiveTags, + selectPhotoActiveTags = (state: RootState) => + state.ActiveTags.PhotoActivetags; export default ActiveTagsSlice.reducer; diff --git a/src/utils/fetch/index.ts b/src/utils/fetch/index.ts index b3f1b87..30b2043 100644 --- a/src/utils/fetch/index.ts +++ b/src/utils/fetch/index.ts @@ -74,6 +74,7 @@ export async function fetchVideos( export async function fetchPhotos( params: IFetchPhotoParams ): Promise { + // console.log({ params }); try { const res = await BackEndAxios.get(`/pic/${params.type}`, { params: Omit(params, "type"),