diff --git a/src/components/image/index.tsx b/src/components/image/index.tsx index 844ee10..3738dac 100644 --- a/src/components/image/index.tsx +++ b/src/components/image/index.tsx @@ -1,77 +1,68 @@ -import { useCallback, useMemo, useState, memo, ReactElement } from "react"; -import { InView } from "react-intersection-observer"; +import { useCallback, ReactElement, useEffect, useState } from "react"; +import { useInView } from "react-intersection-observer"; import { Once } from "@utils/index"; import { ImageProps } from "./imagetype"; import styles from "./image.module.less"; -import { - getImageSize, - getResizeHeight, - fallbackUrl as DefaultFallbackUrl, - ImageSize, -} from "./tool"; -import { styled } from "@mui/material"; - -/** - * @description 图片预加载hook - */ - -function useLoading(url: string) { - const [obj, setObj] = useState({ - width: 0, - height: 0, - again: false, - isLoaded: false, - success: true, - }); - useMemo(async () => { - const res = await getImageSize(url); - setObj(() => ({ ...res, isLoaded: true })); - }, [url]); - return obj; -} - -/** - *@description 图片组件库,默认支持图片加载fallback。 - */ -export default memo(function Image({ +import { styled } from "@mui/material"; +import { fallbackUrl, getImageSize } from "./tool"; +export function InviewImage({ url, - width = 200, - height, - fallbackUrl = DefaultFallbackUrl, observer, callback, children, + title, + ...resProps }: ImageProps & { + title: string; children?: ReactElement; + [k: string]: any; }) { - const res = useLoading(url), - { isLoaded, success } = res, - real_width = width, - real_height = height || getResizeHeight(res, real_width), - real_fallback_url = fallbackUrl || DefaultFallbackUrl; + const [isImgLoading, setImgLoading] = useState(true); const once_callback = useCallback(Once(callback!!), []); + const { ref, inView, entry } = useInView(); + const [onceInView, setOnceInView] = useState(inView); + useEffect(() => { + if (inView) { + setOnceInView(() => true); + } + }, [inView]); + useEffect(() => { + if (observer && inView) { + once_callback(inView); + } + }, [inView, observer]); + useEffect(() => { + const handler = async () => { + await getImageSize(url); + setImgLoading(() => false); + }; + onceInView && handler(); + }, [onceInView]); return ( - - {({ inView, ref, entry }) => ( - - - <>{observer && inView && once_callback(inView)} - {children} - - )} - + + {title} + + {children} + ); -}); +} export function ImageBasic({ url, @@ -86,16 +77,17 @@ export function ImageBasic({ [k: string]: any; }) { const once_callback = useCallback(Once(callback!!), []); + const { ref, inView, entry } = useInView(); + useEffect(() => { + if (observer && inView) { + once_callback(inView); + } + }, [inView, observer]); return ( - - {({ inView, ref, entry }) => ( - - {title} - <>{observer && inView && once_callback(inView)} - {children} - - )} - + + {title} + {children} + ); } diff --git a/src/components/masonry/index.tsx b/src/components/masonry/index.tsx deleted file mode 100644 index 3bbf9ea..0000000 --- a/src/components/masonry/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { FC, useState, useEffect, useCallback } from "react"; -import { Masonry as Masonic_masonry } from "masonic"; -import Image from "@components/image"; -import { SingleRun, concurrencyRequest } from "@utils/index"; -import { fetchPhotos } from "@utils/fetch"; -import { nanoid } from "nanoid"; -import { getImageSize } from "../image/tool"; -export default function Masonry() { - const [lists, setLists] = useState([]); - const fetchMoreItems = async ( - startIndex: number, - stopIndex: number, - currentItems: any[] - ) => { - const res = await fetchPhotos({ - type: "recommend", - page: 0, - topic_id: 0, - }), - data = res.data.result; - }; - const fetchMoreItemsHandler = useCallback(SingleRun(fetchMoreItems), [ - setLists, - ]); - useEffect(() => { - fetchMoreItemsHandler(0, 20, []); - }, [fetchMoreItemsHandler]); - return ( -
-
- -
-
- ); -} - -type MasonryImageType = { - id: string; - image: string; - name: string; - observer?: boolean; - callback?: (inView: boolean) => void; -}; - -type CardType = { - data: MasonryImageType; -}; - -const FakerCard: FC = ({ data: { id, image, name, ...res } }) => { - return ( -
- -
-

- {name} -

-
-
- ); -}; diff --git a/src/normalize.css b/src/normalize.css index 780ad9c..d9992dd 100644 --- a/src/normalize.css +++ b/src/normalize.css @@ -26,6 +26,11 @@ body { margin: 0; } +html, +body { + scroll-behavior: smooth; +} + /** * Render the `main` element consistently in IE. */ diff --git a/src/routers/layout/index.tsx b/src/routers/layout/index.tsx index 97df7a3..ff6a29c 100644 --- a/src/routers/layout/index.tsx +++ b/src/routers/layout/index.tsx @@ -1,14 +1,18 @@ import { Flipped, Flipper } from "react-flip-toolkit"; -import { Outlet, useMatch } from "react-router-dom"; +import { Outlet, useLocation, useMatch } from "react-router-dom"; import Header from "./header"; import { useAppSelector } from "@store/hooks"; import { selectNavMoreShowed } from "@store/device/index"; -import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward"; -import { Link } from "@mui/material"; + import styles from "./layout.module.less"; import Header_Nav from "./nav"; +import { useEffect } from "react"; export default function Layout() { const showed = useAppSelector(selectNavMoreShowed); + const location = useLocation(); + useEffect(() => { + window.scrollTo({ top: 0 }); + }, [location.pathname, location.search]); return ( <> { const curParmas = useGetEuFetchParmas(); const filterItem = OrderItemLists.filter((item) => item.param !== curParmas); const curItem = OrderItemLists.filter((item) => item.param === curParmas); + const isLoading = useGetEuIsloading(); const updateParamer = useSetEuFetchParamas(), handleUpdateParmas = () => updateParamer(filterItem[0].param); return (
{curItem.map((item) => (