From 496f359554801a347e46d058f586719f29142fa2 Mon Sep 17 00:00:00 2001 From: master1lan <278457198@qq.com> Date: Wed, 11 Jan 2023 15:35:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0tag=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/proview/tagSelect.tsx | 65 ++++++++++++++++++++++++++++ src/main.tsx | 5 ++- src/routers/layout/header.tsx | 2 +- src/routers/layout/nav/index.tsx | 55 +++++++++++++---------- src/routers/video/index.tsx | 12 ++++- src/routers/video/masonry.tsx | 10 +++-- src/utils/fetch/index.ts | 11 ++--- src/utils/time/index.ts | 13 +++++- tsconfig.json | 3 +- 9 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 src/components/proview/tagSelect.tsx diff --git a/src/components/proview/tagSelect.tsx b/src/components/proview/tagSelect.tsx new file mode 100644 index 0000000..21a53ac --- /dev/null +++ b/src/components/proview/tagSelect.tsx @@ -0,0 +1,65 @@ +import { NavQueryItemType } from "@routers/layout/nav/tools"; +import { + useContext, + useState, + createContext, + useEffect, + ReactElement, + useReducer, +} from "react"; + +type TagSelectProps = { + children: ReactElement; +}; +interface TagStates { + tags: NavQueryItemType[]; +} +enum TagsActionKind { + INCREASE = "INCREASE", + DECREASE = "DECREASE", +} +interface TagsAction { + type: TagsActionKind; + payload: NavQueryItemType; +} +const TagSelectContext = createContext< + TagStates & { + handerAddTag: (item: NavQueryItemType) => void; + handerDeleteTag: (item: NavQueryItemType) => void; + } +>({ + tags: [], + handerAddTag: () => {}, + handerDeleteTag: () => {}, +}); +function reducer(state: TagStates, action: TagsAction) { + const { type, payload } = action; + switch (type) { + case TagsActionKind.INCREASE: + return { tags: [...state.tags, payload] }; + case TagsActionKind.DECREASE: + return { tags: state.tags.filter((item) => item.id !== payload.id) }; + default: + return state; + } +} +const TagSelectProview = ({ children }: TagSelectProps) => { + const [tags, tagsDispath] = useReducer(reducer, { + tags: [] as NavQueryItemType[], + }), + handerAddTag = (item: NavQueryItemType) => + tagsDispath({ type: TagsActionKind.INCREASE, payload: item }), + handerDeleteTag = (item: NavQueryItemType) => + tagsDispath({ type: TagsActionKind.DECREASE, payload: item }); + return ( + + {children} + + ); +}; + +export const useTagsSelected = () => useContext(TagSelectContext); + +export default TagSelectProview; diff --git a/src/main.tsx b/src/main.tsx index 9d0e1a7..6d36901 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -17,6 +17,7 @@ import ScreenProview from "@components/proview/screenSize"; import "intersection-observer"; import "./normalize.css"; import "loading-attribute-polyfill"; +import TagSelectProview from "@components/proview/tagSelect"; const router = createBrowserRouter([ { path: "/", @@ -60,7 +61,9 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( // // - + + + // diff --git a/src/routers/layout/header.tsx b/src/routers/layout/header.tsx index 2910be6..cf45ce0 100644 --- a/src/routers/layout/header.tsx +++ b/src/routers/layout/header.tsx @@ -20,7 +20,7 @@ export default function Header() { ); } - +//todo 添加搜索 function Search() { const { focused, bind } = useFocus(); return ( diff --git a/src/routers/layout/nav/index.tsx b/src/routers/layout/nav/index.tsx index 342b523..fc1838c 100644 --- a/src/routers/layout/nav/index.tsx +++ b/src/routers/layout/nav/index.tsx @@ -29,9 +29,9 @@ import { useNavList, } from "./tools"; import { setLocalstorage } from "../tools"; +import { useTagsSelected } from "@components/proview/tagSelect"; //todo 拆分组件 export default function Header_Nav() { - //todo 这里在loacalstorage中查找 const [navLists, setLists] = useNavList(); //tag区是否展开 const [showed, setShow] = useState(false); @@ -147,41 +147,50 @@ const NavItem: FC = memo((props) => {
{props.type === "router" ? ( - + ) : ( - + )}
); }); -const NavRouterChipItem: FC> = - memo((props) => ( - - `${styles["navlink"]} ${isActive ? styles["navlink-active"] : ""}` - } - > - - - )); +const NavRouterChipItem: FC = memo((props) => ( + + `${styles["navlink"]} ${isActive ? styles["navlink-active"] : ""}` + } + > + + +)); -const NavTagChipItem: FC> = memo((props) => { - const [clicked, setClick] = useState(false); +const NavTagChipItem: FC = memo((props) => { + const [clicked, setClick] = useState(false), + { handerAddTag, handerDeleteTag } = useTagsSelected(); return ( setClick((clicked) => !clicked)} + onClick={() => + setClick((clicked) => { + //注意这里是要改变点击状态,所以应该反着来 + //说明之前是点击状态,现在要取消点击 + if (clicked) { + handerDeleteTag(props); + } else { + handerAddTag(props); + } + return !clicked; + }) + } /> ); }); diff --git a/src/routers/video/index.tsx b/src/routers/video/index.tsx index b2a6542..ea599dc 100644 --- a/src/routers/video/index.tsx +++ b/src/routers/video/index.tsx @@ -1,10 +1,18 @@ import VideoMasonry from "./masonry"; +import { useTagsSelected } from "@components/proview/tagSelect"; export default function VideoPage() { + const { tags } = useTagsSelected(), + qlists = tags + .filter((item) => item.queryType === "q") + .reduceRight((pre, cur) => { + return `${cur.queryString}+${pre}`; + }, ""), + q = qlists.length < 1 ? undefined : `tag.${qlists}`; return ( <> - + ); } - +//todo 优化搜索设置 //todo 添加上拉刷新 diff --git a/src/routers/video/masonry.tsx b/src/routers/video/masonry.tsx index 09ba61f..463b59e 100644 --- a/src/routers/video/masonry.tsx +++ b/src/routers/video/masonry.tsx @@ -11,18 +11,18 @@ import styles from "./video.module.less"; /** * @description 该组件负责渲染视频图片的瀑布流 */ -export default function VideoMasonry(props: any) { +export default function VideoMasonry(props: { q?: string }) { const [lists, setLists] = useState< (VideoRouterImageCardType & { id: string })[] >([]); const [isLoading, setLoading] = useState(true); useEffect(() => { // 在内部定义fetchHandler,保证拿到的是同步的 - const fetchHandler = async (page: number = 1, ...resProps: any[]) => { + const fetchHandler = async (page: number = 1) => { const res = await fetchVideos({ order: "view", page, - ...resProps, + q: props.q, }), data = res.data.result; // , @@ -71,7 +71,9 @@ export default function VideoMasonry(props: any) { }), ]); }; - fetchHandler().then(() => setLoading(false)); + setLists([]); + setLoading(true); + fetchHandler(1).then(() => setLoading(false)); }, [props]); return (
diff --git a/src/utils/fetch/index.ts b/src/utils/fetch/index.ts index c754362..10fab49 100644 --- a/src/utils/fetch/index.ts +++ b/src/utils/fetch/index.ts @@ -11,11 +11,12 @@ import { IFetchVideoParams, RFetchVideoRes } from "./fetchtype"; export function fetchVideos( params: IFetchVideoParams ): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(videoJson); - }, 1000); - }); + console.log({ params }); + // return new Promise((resolve) => { + // setTimeout(() => { + // resolve(videoJson); + // }, 1000); + // }); return fetch( `/v1/video-interface/advanced-search?order=${params.order}&page=${ params.page diff --git a/src/utils/time/index.ts b/src/utils/time/index.ts index 920c511..5064a00 100644 --- a/src/utils/time/index.ts +++ b/src/utils/time/index.ts @@ -1,13 +1,22 @@ import dayJs from "dayjs"; import realtiveTime from "dayjs/plugin/relativeTime"; import duration from "dayjs/plugin/duration"; +import isToday from "dayjs/plugin/isToday"; +import isYesterday from "dayjs/plugin/isYesterday"; import "dayjs/locale/zh-cn"; dayJs.locale("zh-cn"); dayJs.extend(realtiveTime); +dayJs.extend(isToday); +dayJs.extend(isYesterday); dayJs.extend(duration); -//todo 修改时间显示,1天前这种要改成具体的时间 export default function getrealtiveTime(time: number): string { - return dayJs(time).fromNow(); + const format_time = dayJs(time); + if (format_time.isToday()) { + return format_time.fromNow(); + } else if (format_time.isYesterday()) { + return "昨天"; + } + return format_time.format("M-D"); } export function getVideoTime(time: string): string { diff --git a/tsconfig.json b/tsconfig.json index 5fb5ce5..7e4915c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ "paths": { "@utils/*": ["src/utils/*"], "@components/*": ["src/components/*"], - "@store/*": ["src/store/*"] + "@store/*": ["src/store/*"], + "@routers/*": ["src/routers/*"] } }, "include": ["src"]