From 08be3e6a7f111882b84c76366e6ee87318a036a3 Mon Sep 17 00:00:00 2001 From: master1lan <278457198@qq.com> Date: Thu, 26 Jan 2023 22:26:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0photo=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E8=BF=98=E9=9C=80=E8=A6=81=E4=BF=AE=E6=94=B9=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=A0=87=E7=AD=BE=E6=A0=B7=E5=BC=8F=E7=AD=89=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 +- pnpm-lock.yaml | 21 +++++++ src/components/image/index.tsx | 6 +- src/components/masonry/index.tsx | 38 ++---------- src/components/modal/index.tsx | 74 +++++++++++++++++++++++ src/components/modal/modal.module.less | 11 ++++ src/components/modal/scrollFn.ts | 22 +++++++ src/components/proview/imageSize.tsx | 32 ---------- src/main.tsx | 2 +- src/routers/layout/header.tsx | 38 +++++++----- src/routers/layout/index.tsx | 15 ++--- src/routers/photo.tsx | 11 ---- src/routers/photo/index.tsx | 9 +++ src/routers/photo/item/index.tsx | 29 +++++++++ src/routers/photo/item/modal.tsx | 77 ++++++++++++++++++++++++ src/routers/photo/item/photo.module.less | 30 +++++++++ src/routers/photo/masonry.tsx | 57 ++++++++++++++++++ src/routers/photo/phototype.ts | 16 +++++ src/routers/photo/tools.ts | 15 +++++ src/routers/video/masonry.tsx | 51 ++++++++-------- src/routers/video/tools.ts | 2 +- src/routers/video/videotype.ts | 2 +- src/store/loading/index.ts | 28 ++++++++- src/utils/fetch/fetchtype.ts | 64 ++++++++++++++++++-- src/utils/fetch/index.ts | 34 ++++++++++- src/utils/fetch/tool.ts | 2 +- 26 files changed, 543 insertions(+), 146 deletions(-) create mode 100644 src/components/modal/index.tsx create mode 100644 src/components/modal/modal.module.less create mode 100644 src/components/modal/scrollFn.ts delete mode 100644 src/components/proview/imageSize.tsx delete mode 100644 src/routers/photo.tsx create mode 100644 src/routers/photo/index.tsx create mode 100644 src/routers/photo/item/index.tsx create mode 100644 src/routers/photo/item/modal.tsx create mode 100644 src/routers/photo/item/photo.module.less create mode 100644 src/routers/photo/masonry.tsx create mode 100644 src/routers/photo/phototype.ts create mode 100644 src/routers/photo/tools.ts diff --git a/package.json b/package.json index 81b07d8..8b28b8b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "react-photo-view": "^1.2.3", "react-redux": "^8.0.5", "react-router-dom": "^6.6.1", - "react-use": "^17.4.0" + "react-use": "^17.4.0", + "swiper": "^8.4.6" }, "devDependencies": { "@babel/core": ">=7.0.0 <8.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 078b737..bb26cb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,6 +39,7 @@ specifiers: react-router-dom: ^6.6.1 react-use: ^17.4.0 rollup-plugin-visualizer: ^5.9.0 + swiper: ^8.4.6 terser: '>=5.4.0 <6.0.0' typescript: ^4.9.3 vite: 4.0.3 @@ -72,6 +73,7 @@ dependencies: react-redux: 8.0.5_ie75ejlwqy5zh3tldgt7pftwcu react-router-dom: 6.6.1_biqbaboplfbrettd7655fr4n2y react-use: 17.4.0_biqbaboplfbrettd7655fr4n2y + swiper: 8.4.6 devDependencies: '@babel/core': 7.20.7 @@ -1530,6 +1532,12 @@ packages: csstype: 3.1.1 dev: false + /dom7/4.0.4: + resolution: {integrity: sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==} + dependencies: + ssr-window: 4.0.2 + dev: false + /electron-to-chromium/1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} @@ -2537,6 +2545,10 @@ packages: deprecated: Please use @jridgewell/sourcemap-codec instead dev: false + /ssr-window/4.0.2: + resolution: {integrity: sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==} + dev: false + /stack-generator/2.0.10: resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} dependencies: @@ -2598,6 +2610,15 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /swiper/8.4.6: + resolution: {integrity: sha512-HACW035vBz2T6Kfut23EAzXhcDpgR8doX+wjq0ZUvJgS5SQApGrV885DAPLBFnmPUISsAhNSVxPKDxqroFvXvQ==} + engines: {node: '>= 4.7.0'} + requiresBuild: true + dependencies: + dom7: 4.0.4 + ssr-window: 4.0.2 + dev: false + /systemjs/6.13.0: resolution: {integrity: sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==} dev: true diff --git a/src/components/image/index.tsx b/src/components/image/index.tsx index 70d1da3..9743c85 100644 --- a/src/components/image/index.tsx +++ b/src/components/image/index.tsx @@ -1,6 +1,5 @@ import { useCallback, useMemo, useState, memo, ReactElement } from "react"; import { InView } from "react-intersection-observer"; -import { useImageShouldResize } from "@components/proview/imageSize"; import { Once } from "@utils/index"; import { ImageProps } from "./imagetype"; import styles from "./image.module.less"; @@ -53,14 +52,13 @@ export default memo(function Image({ real_height = height || getResizeHeight(res, real_width), real_fallback_url = fallbackUrl || DefaultFallbackUrl; const once_callback = useCallback(Once(callback!!), []); - const { isShouldchangeSize } = useImageShouldResize(); return ( {({ inView, ref, entry }) => (
{ - const res = await fetchVideos({ - order: "view", - page: 1, + const res = await fetchPhotos({ + type: "recommend", + page: 0, + topic_id: 0, }), - data = res.data.result, - urls = data.map((item) => item.face); - const fetchimagres = await concurrencyRequest(urls, getImageSize, 6); - setLists((lists) => { - return [ - ...lists, - ...data.map((item, index) => { - // if (index !== data.length - 6) { - return { - image: item.face, - name: item.name, - id: nanoid(10), - }; - // } - return { - image: item.face, - name: item.name, - id: nanoid(10), - observer: true, - callback: (inView: boolean) => { - //@ts-ignore - fetchMoreItems(); - console.log("fetching!"); - }, - }; - }), - ]; - }); + data = res.data.result; }; const fetchMoreItemsHandler = useCallback(SingleRun(fetchMoreItems), [ setLists, diff --git a/src/components/modal/index.tsx b/src/components/modal/index.tsx new file mode 100644 index 0000000..71e017a --- /dev/null +++ b/src/components/modal/index.tsx @@ -0,0 +1,74 @@ +import { memo, useState, ReactElement } from "react"; +import styles from "./modal.module.less"; +import { createPortal } from "react-dom"; +import { useEffect } from "react"; +import { enableScroll, disableScroll } from "./scrollFn"; + +type __Click_modal__Type = { + children: ReactElement; + visible: boolean; + closeModal: (event: any) => void; + resProps: Object; +}; + +export const __Click_Modal__ = (props: __Click_modal__Type) => { + const { children, visible, closeModal, ...resProps } = props; + function handleClick(event: { + stopPropagation: () => void; + target: any; + currentTarget: any; + }) { + //点击蒙层本身时关闭模态框,点击模态框内容时不关闭 + event.stopPropagation(); + // event.nativeEvent.stopImmediatePropagation(); + if (event.target === event.currentTarget) { + closeModal(event); + } + } + let modal; + typeof document !== "undefined" && + (modal = createPortal( +
+ {children} +
, + document.body + )); + return <>{visible && modal}; +}; + +type ModalType = { + isNoScroll: boolean; + children: ReactElement; + visible: boolean; + closeModal: (event: any) => void; +}; +export default memo(function Modal(props: ModalType) { + const { isNoScroll = false, children, ...resProps } = props; + useEffect(() => { + if (isNoScroll) { + disableScroll(); + return enableScroll; + } + }, [isNoScroll]); + //@ts-ignore + return <__Click_Modal__ {...resProps}>{children}; +}); + +type useModalConfigOutputType = { + visible: boolean; + isNoScroll: boolean; + closeModal: () => void; +}; + +export const useModalConfig = ( + _isvisible: boolean, + _isNoScroll: boolean +): useModalConfigOutputType => { + const [isvisible, setVisible] = useState(_isvisible || false); + const [isNoScroll, setScroll] = useState(_isNoScroll || false); + const clickFunc = () => { + setScroll(!isNoScroll); + setVisible(!isvisible); + }; + return { visible: isvisible, isNoScroll, closeModal: clickFunc }; +}; diff --git a/src/components/modal/modal.module.less b/src/components/modal/modal.module.less new file mode 100644 index 0000000..5801b68 --- /dev/null +++ b/src/components/modal/modal.module.less @@ -0,0 +1,11 @@ +/* modal.less */ +.modal { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 1; + min-height: 100vh; + background-color: rgba(0, 0, 0, 0.7); +} \ No newline at end of file diff --git a/src/components/modal/scrollFn.ts b/src/components/modal/scrollFn.ts new file mode 100644 index 0000000..5524a8b --- /dev/null +++ b/src/components/modal/scrollFn.ts @@ -0,0 +1,22 @@ +//@ts-nocheck +//阻止默认行为 +export function preventDefault(e) { + // console.log({ e }); + e.preventDefault(); +} + +export function enableScroll() { + const wheelEvent = + "onwheel" in document.createElement("div") ? "wheel" : "mousewheel"; + window.removeEventListener("DOMMouseScroll", preventDefault, false); + window.removeEventListener(wheelEvent, preventDefault, { passive: false }); + window.removeEventListener("touchmove", preventDefault, { passive: false }); +} + +export function disableScroll() { + const wheelEvent = + "onwheel" in document.createElement("div") ? "wheel" : "mousewheel"; + window.addEventListener("DOMMouseScroll", preventDefault, false); // older FF + window.addEventListener(wheelEvent, preventDefault, { passive: false }); // modern desktop + window.addEventListener("touchmove", preventDefault, { passive: false }); // mobile +} diff --git a/src/components/proview/imageSize.tsx b/src/components/proview/imageSize.tsx deleted file mode 100644 index 70c6ed2..0000000 --- a/src/components/proview/imageSize.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useContext, useState, createContext, useEffect } from "react"; -import { thorttleFn } from "@utils/index"; -import { ReactChildrenType } from "./type"; -export const image_order_width = 200; - -const ImageContext = createContext<{ isShouldchangeSize: boolean }>({ - isShouldchangeSize: false, -}); - -const ImageShouldResizeProview = ({ children }: ReactChildrenType) => { - const [isShouldchangeSize, setIs] = useState(false); - useEffect(() => { - const handleWindowResize = () => { - setIs(() => window.innerWidth < image_order_width * 2.5); - }; - handleWindowResize(); - const handlerThrttleResize = thorttleFn(handleWindowResize, 10); - window.addEventListener("resize", handlerThrttleResize); - return () => window.removeEventListener("resize", handlerThrttleResize); - }, []); - return ( - - {children} - - ); -}; - -export const useImageShouldResize = () => { - return useContext(ImageContext); -}; - -export default ImageShouldResizeProview; diff --git a/src/main.tsx b/src/main.tsx index 838daac..9a0e893 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -16,7 +16,7 @@ import "intersection-observer"; import "./normalize.css"; import "loading-attribute-polyfill"; import "./index.less"; - +import "swiper/css/bundle"; const router = createBrowserRouter([ { path: "/", diff --git a/src/routers/layout/header.tsx b/src/routers/layout/header.tsx index e9f5052..e78d040 100644 --- a/src/routers/layout/header.tsx +++ b/src/routers/layout/header.tsx @@ -1,19 +1,29 @@ -import { useSearchFocus } from "@components/proview/searchFocus"; -import { Flipped } from "react-flip-toolkit"; import styles from "./layout.module.less"; import LOGO from "./logo"; -import RightSide from "./rightSide"; -import Search from "./search"; +import { useAppDispatch } from "@store/hooks"; +import { Link, useLocation } from "react-router-dom"; +import { useEffect, useMemo } from "react"; +import { changeLoadingCauseByUrl } from "@store/loading"; export default function Header() { - // const { focused } = useSearchFocus(); - return ( - // -
- {/* {!focused && } - - {!focused && } */} - -
- //
+ const dispatch = useAppDispatch(), + location = useLocation(); + useEffect(() => { + dispatch( + changeLoadingCauseByUrl({ + stateName: + location.pathname == "/photo" ? "photoIsloading" : "videoIsLoading", + }) + ); + }, [location.pathname]); + const JSXRes = useMemo( + () => ( +
+ + video + photo +
+ ), + [] ); + return <>{JSXRes}; } diff --git a/src/routers/layout/index.tsx b/src/routers/layout/index.tsx index 3f5ab14..78c1011 100644 --- a/src/routers/layout/index.tsx +++ b/src/routers/layout/index.tsx @@ -4,16 +4,13 @@ import Header from "./header"; import Header_Nav from "./nav"; import { useAppSelector } from "@store/hooks"; import { selectNavMoreShowed } from "@store/device/index"; -import { useSearchFocus } from "@components/proview/searchFocus"; import styles from "./layout.module.less"; export default function Layout() { - const showed = useAppSelector(selectNavMoreShowed), - { focused } = useSearchFocus(); - + const showed = useAppSelector(selectNavMoreShowed); return ( <> -
-
- -
+
+
diff --git a/src/routers/photo.tsx b/src/routers/photo.tsx deleted file mode 100644 index c036aca..0000000 --- a/src/routers/photo.tsx +++ /dev/null @@ -1,11 +0,0 @@ -export default function PhotoPage() { - return ( -

- 🙇‍♂️🙇‍♂️🙇‍♂️二创图片页还在制作中,敬请期待! -

- ); -} diff --git a/src/routers/photo/index.tsx b/src/routers/photo/index.tsx new file mode 100644 index 0000000..8c32250 --- /dev/null +++ b/src/routers/photo/index.tsx @@ -0,0 +1,9 @@ +import Masonry from "./masonry"; + +export default function PhotoPage() { + return ( + <> + + + ); +} diff --git a/src/routers/photo/item/index.tsx b/src/routers/photo/item/index.tsx new file mode 100644 index 0000000..558adc9 --- /dev/null +++ b/src/routers/photo/item/index.tsx @@ -0,0 +1,29 @@ +import { PhotoRouterImageCardType } from "../phototype"; +import { useState } from "react"; +import ImgModals from "./modal"; + +type CardType = { + data: PhotoRouterImageCardType; +}; + +export default function PhotoCard(props: CardType) { + const { images } = props.data; + const [open, set] = useState(false), + handlerChangeOpen = () => set((open) => !open); + const modalPorps = { open, images, onClose: handlerChangeOpen }; + return ( + <> +
+ +
+ + + ); +} diff --git a/src/routers/photo/item/modal.tsx b/src/routers/photo/item/modal.tsx new file mode 100644 index 0000000..d6cb71e --- /dev/null +++ b/src/routers/photo/item/modal.tsx @@ -0,0 +1,77 @@ +import Modal from "@components/modal"; +import { basicImageType } from "../phototype"; +// Import Swiper React components +import { Swiper, SwiperSlide } from "swiper/react"; +// import required modules +import { Pagination, Navigation } from "swiper"; +// Import Swiper styles +import "swiper/css"; +import "swiper/css/pagination"; +import style from "./photo.module.less"; +import { useEffect } from "react"; +import { useLocation } from "react-router-dom"; +type ModalType = { + images: basicImageType[]; + open: boolean; + onClose: () => void; +}; + +export default function ImgModals(props: ModalType) { + const { open, onClose, images } = props; + const location = useLocation(); + useEffect(() => { + let flag = false; + const handler = () => { + flag = true; + onClose(); + }; + if (open) { + console.log("push"); + history.pushState(null, "", location.pathname); + window.addEventListener("popstate", handler, { + once: true, + }); + return () => { + !flag && history.back(); + window.removeEventListener("popstate", handler); + }; + } + }, [open]); + return ( + +
+ + {images.map((item, index) => ( + +
+ +
+
+ ))} +
+
+
+ ); +} +//todo 修改navigation的样式 +//todo 修改滚动条样式 +//todo 移动到外界过于灵敏 +//todo 添加关闭按钮 +//todo 根据url切换tag_lists diff --git a/src/routers/photo/item/photo.module.less b/src/routers/photo/item/photo.module.less new file mode 100644 index 0000000..4efa246 --- /dev/null +++ b/src/routers/photo/item/photo.module.less @@ -0,0 +1,30 @@ +.box { + display: flex; + justify-content: center; + align-items: center; + max-width: 600px; + max-height: 100vh; + width: 100%; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 4px; + border: 1px solid #fff; + padding: 5px; + box-sizing: border-box; + background-color: #fff; +} + +.imgwrapper { + max-height: 80vh; + overflow-y: auto; + position: relative; + height: 100%; + display: flex; + align-items: center; +} + +.swiper-fix { + height: auto !important; +} \ No newline at end of file diff --git a/src/routers/photo/masonry.tsx b/src/routers/photo/masonry.tsx new file mode 100644 index 0000000..5aaa207 --- /dev/null +++ b/src/routers/photo/masonry.tsx @@ -0,0 +1,57 @@ +import { selectPhotoLoadingState } from "@store/loading"; +import { Masonry as Masonic_masonry } from "masonic"; +import { useState, useEffect, FC } from "react"; +import { useAppSelector, useAppDispatch } from "@store/hooks"; + +import { changeLoading } from "@store/loading/index"; +import { fetchPhotoHandler } from "./tools"; +import { PhotoRouterImageCardType } from "./phototype"; +import PhotoCard from "./item"; + +//todo props type change +export default function Masonry(props: any) { + const [lists, setList] = useState([]); + const isLoading = useAppSelector(selectPhotoLoadingState), + dispatch = useAppDispatch(), + handerChangeLoading = (state: boolean) => + dispatch( + changeLoading({ + stateName: "photoIsloading", + Tostate: state, + }) + ); + useEffect(() => { + const fetchHandler = async (page: number = 0) => { + const data = await fetchPhotoHandler({ + page, + topic_id: 0, + type: "latest", + }); + setList((lists) => { + return [ + ...lists, + ...data.map((item) => ({ + images: item.pictures.map((img) => ({ + src: img.img_src, + height: img.img_height, + width: img.img_width, + })), + })), + ]; + }); + }; + fetchHandler(); + }, [props]); + return ( + <> + + + ); +} diff --git a/src/routers/photo/phototype.ts b/src/routers/photo/phototype.ts new file mode 100644 index 0000000..1445cf2 --- /dev/null +++ b/src/routers/photo/phototype.ts @@ -0,0 +1,16 @@ +import { IFetchPhotoParams } from "@utils/fetch/fetchtype"; +export type basicImageType = { + src: string; + width: number; + height: number; +}; +/** + * 定义photo路由的类型 + */ +export type PhotoRouterImageCardType = { + images: basicImageType[]; + observer?: boolean; + callback?: (inView: boolean) => void; +}; + +export type PhotoRouterMasonryType = IFetchPhotoParams; diff --git a/src/routers/photo/tools.ts b/src/routers/photo/tools.ts new file mode 100644 index 0000000..1e82a2f --- /dev/null +++ b/src/routers/photo/tools.ts @@ -0,0 +1,15 @@ +import message from "@components/message"; +import { fetchPhotos } from "@utils/fetch"; +import { IFetchPhotoParams } from "@utils/fetch/fetchtype"; + +export const fetchPhotoHandler = async (params: IFetchPhotoParams) => { + const res = await fetchPhotos(params); + if (res.code !== 0) { + res.code === 400 && message.info("参数错误,请尝试其他tag"); + res.code === 500 && message.info(res.message); + return []; + } else if (res.data.result.length < 1) { + message.info("没有更多数据了,请尝试其他tag"); + } + return res.data.result; +}; diff --git a/src/routers/video/masonry.tsx b/src/routers/video/masonry.tsx index 93e45f9..5cf5f3f 100644 --- a/src/routers/video/masonry.tsx +++ b/src/routers/video/masonry.tsx @@ -1,12 +1,11 @@ import { useState, useEffect, FC, memo } from "react"; import { VideoRouterImageCardType, VideoRouterMasonryType } from "./videotype"; import { Unstable_Grid2 as Grid } from "@mui/material"; -import ImageShouldResizeProview from "@components/proview/imageSize"; import { VideoRouterImageCard } from "./item"; import { Skeleton } from "@mui/material"; import { nanoid } from "nanoid"; import styles from "./video.module.less"; -import { fetchVideohnadler, PickVideoRouterImageCardType } from "./tools"; +import { fetchVideohandler, PickVideoRouterImageCardType } from "./tools"; import { useAppSelector, useAppDispatch } from "@store/hooks"; import { changeLoading, selectVideoLoadingState } from "@store/loading/index"; /** @@ -23,7 +22,7 @@ export default function VideoMasonry(props: VideoRouterMasonryType) { useEffect(() => { // 在内部定义fetchHandler,保证拿到的是同步的 const fetchHandler = async (page: number = 1) => { - const data = await fetchVideohnadler(page, props); + const data = await fetchVideohandler(page, props); setLists((lists) => [ ...lists, ...data.map((item, index) => { @@ -48,30 +47,28 @@ export default function VideoMasonry(props: VideoRouterMasonryType) { }, [props]); return (
- - - {lists.map((item) => ( - - ))} - {isLoading && } - - + + {lists.map((item) => ( + + ))} + {isLoading && } +
); } diff --git a/src/routers/video/tools.ts b/src/routers/video/tools.ts index f69a641..2f3f79e 100644 --- a/src/routers/video/tools.ts +++ b/src/routers/video/tools.ts @@ -3,7 +3,7 @@ import { fetchVideos } from "@utils/fetch/index"; import message from "@components/message"; import { Pick } from "@utils/index"; -export const fetchVideohnadler = async ( +export const fetchVideohandler = async ( page: number = 1, props: VideoRouterMasonryType ) => { diff --git a/src/routers/video/videotype.ts b/src/routers/video/videotype.ts index ce56040..cb4f14f 100644 --- a/src/routers/video/videotype.ts +++ b/src/routers/video/videotype.ts @@ -3,7 +3,7 @@ */ import { ImageProps } from "@components/image/imagetype"; import { RFetchVideoRes } from "@utils/fetch/fetchtype"; -import { IFetchVideoParams } from "../../utils/fetch/fetchtype"; +import { IFetchVideoParams } from "@utils/fetch/fetchtype"; /** * @description video路由瀑布流卡片参数 diff --git a/src/store/loading/index.ts b/src/store/loading/index.ts index b220a74..f3c2856 100644 --- a/src/store/loading/index.ts +++ b/src/store/loading/index.ts @@ -7,6 +7,10 @@ interface LoadingState { * @description 视频接口是否正在获取 */ videoIsLoading: boolean; + /** + * @description 图片接口是否正在获取 + */ + photoIsloading: boolean; } interface IchangeLoadingItem { stateName: keyof LoadingState; @@ -15,13 +19,14 @@ interface IchangeLoadingItem { const initialState: LoadingState = { videoIsLoading: true, + photoIsloading: true, }; export const LoadingSlice = createSlice({ name: "loading", initialState, reducers: { /** - * + * @description 修改加载状态,注意因为spa的限制所有每个页面只有一种加载情况 */ changeLoading: (state, action: PayloadAction) => { const { stateName, Tostate } = action.payload; @@ -31,11 +36,28 @@ export const LoadingSlice = createSlice({ state[stateName] = !state[stateName]; } }, + /** + * @description 此reducer应该只在url修改时调用 + */ + changeLoadingCauseByUrl: ( + state, + action: PayloadAction + ) => { + Object.keys(state).map((name) => { + state[name as keyof LoadingState] = + name === action.payload.stateName ? true : false; + }); + }, }, }); -export const { changeLoading } = LoadingSlice.actions; +const selectLoadingState = (state: RootState, name: keyof LoadingState) => + state.loading[name]; + +export const { changeLoading, changeLoadingCauseByUrl } = LoadingSlice.actions; export const selectVideoLoadingState = (state: RootState) => - state.loading.videoIsLoading; + selectLoadingState(state, "videoIsLoading"), + selectPhotoLoadingState = (state: RootState) => + selectLoadingState(state, "photoIsloading"); export default LoadingSlice.reducer; diff --git a/src/utils/fetch/fetchtype.ts b/src/utils/fetch/fetchtype.ts index 90afbe4..6d05df3 100644 --- a/src/utils/fetch/fetchtype.ts +++ b/src/utils/fetch/fetchtype.ts @@ -165,10 +165,8 @@ interface RFetchVideoResData { numResults: number; result: RFetchVideoResResult[]; } -/** - * @description video接口的返回类型 - */ -export interface RFetchVideoRes { + +type CustomFetchRes = { /** * @example 0 */ @@ -184,5 +182,61 @@ export interface RFetchVideoRes { /** * @description 放数据的 */ - data: RFetchVideoResData; + data: T; +}; +/** + * @description video接口的返回类型 + */ +export type RFetchVideoRes = CustomFetchRes; + +interface RFetchPhotoResPicturesArr { + /** + * @description img url src + */ + img_src: string; + img_size: number; + /** + * @description img origin width + */ + img_width: number; + /** + * @description img origin height + */ + img_height: number; } + +interface RFetchPhotoResData { + page: number; + total: number; + result: { + dynamic_id: number; + sent_at: number; + pictures: RFetchPhotoResPicturesArr[]; + }[]; +} + +/** + * @description photo接口的返回类型 + */ +export type RFetchPhotoRes = CustomFetchRes; + +/** + * + */ +export type IFetchPhotoParams = { + /** + * @description photo display rules + */ + type: "recommend" | "latest"; + /** + * @description topic recommend:28953983->莞儿 + 28950030->柚恩 + 29067608->露早 + 28948378->虞莫 + 29069147->猴子 + 29156150->官号 + 0 -> default,all + */ + topic_id: 28953983 | 28950030 | 29067608 | 28948378 | 29069147 | 29156150 | 0; + page: number; +}; diff --git a/src/utils/fetch/index.ts b/src/utils/fetch/index.ts index 27d0582..fa78f30 100644 --- a/src/utils/fetch/index.ts +++ b/src/utils/fetch/index.ts @@ -2,8 +2,14 @@ import axios from "axios"; /** * 类型文件导入 */ -import { IFetchVideoParams, RFetchVideoRes } from "./fetchtype"; +import { + IFetchVideoParams, + RFetchPhotoRes, + RFetchVideoRes, + IFetchPhotoParams, +} from "./fetchtype"; import { Host_Url } from "./tool"; +import { Omit } from "../index"; export const BackEndAxios = axios.create({ baseURL: Host_Url, @@ -28,7 +34,7 @@ export async function fetchVideos( params: IFetchVideoParams ): Promise { try { - const res = await BackEndAxios.get("/v1/video-interface/advanced-search", { + const res = await BackEndAxios.get("/video-interface/advanced-search", { params: { order: params.order || "score", page: params.page, @@ -52,3 +58,27 @@ export async function fetchVideos( }; } } +/** + * photo图片数据获取接口 + */ +export async function fetchPhotos( + params: IFetchPhotoParams +): Promise { + try { + const res = await BackEndAxios.get(`/pic/${params.type}`, { + params: Omit(params, "type"), + }); + return res.data; + } catch (e) { + return { + code: 500, + message: "网络请求错误,您似乎处于断网状态", + ttl: 0, + data: { + page: 0, + total: 0, + result: [], + }, + }; + } +} diff --git a/src/utils/fetch/tool.ts b/src/utils/fetch/tool.ts index 1e1d51b..ff6aa87 100644 --- a/src/utils/fetch/tool.ts +++ b/src/utils/fetch/tool.ts @@ -1 +1 @@ -export const Host_Url = isdev ? "" : `https://api.eoe.best/eoefans-api`; +export const Host_Url = isdev ? "/v1" : `https://api.eoe.best/eoefans-api/v1`;