diff --git a/web/app/home/page.tsx b/web/app/home/page.tsx index fbfaf64e..aedd1545 100644 --- a/web/app/home/page.tsx +++ b/web/app/home/page.tsx @@ -1,6 +1,7 @@ "use client"; import CloseIcon from "@mui/icons-material/Close"; +import type { User } from "common/types"; import { motion, useAnimation } from "framer-motion"; import { useCallback, useEffect, useState } from "react"; import { MdThumbUp } from "react-icons/md"; @@ -12,26 +13,35 @@ import FullScreenCircularProgress from "~/components/common/FullScreenCircularPr import { NavigateByAuthState } from "~/components/common/NavigateByAuthState"; export default function Home() { - const { data: recommended, error } = useRecommended(); - const [nth, setNth] = useState(0); - const displayedUser = recommended?.[nth]; - const nextUser = recommended?.[nth + 1]; + const { data, error } = useRecommended(); const controls = useAnimation(); const [clickedButton, setClickedButton] = useState(""); const { state: { data: myId }, } = useMyID(); - const reject = useCallback(() => { - if (!displayedUser) return; - recommended?.push(displayedUser); - setNth((n) => n + 1); - }, [displayedUser, recommended]); + const [_, rerender] = useState({}); + const [recommended, setRecommended] = useState>( + () => new Queue([]), + ); + useEffect(() => { + if (data) setRecommended(new Queue(data)); + }, [data]); + const displayedUser = recommended.peek(1); + const nextUser = recommended.peek(2); + const reject = useCallback(() => { + const current = recommended.pop(); + if (!current) return; + recommended.push(current); + rerender({}); + }, [recommended]); const accept = useCallback(async () => { - setNth((n) => n + 1); - if (displayedUser?.id) request.send(displayedUser.id); - }, [displayedUser?.id]); + const current = recommended.pop(); + if (!current) return; + request.send(current.id); + rerender({}); + }, [recommended]); const onClickClose = useCallback(() => { setClickedButton("cross"); @@ -61,12 +71,6 @@ export default function Home() { }); }, [controls, accept]); - useEffect(() => { - if (!displayedUser) { - setNth(0); - } - }, [displayedUser]); - if (recommended == null) { return ; } @@ -144,3 +148,23 @@ const CloseIconStyled = () => ; const FavoriteIconStyled = () => ( ); + +class Queue { + private store: T[]; + constructor(initial: T[]) { + this.store = initial; + } + push(top: T): void { + this.store.push(top); + } + // peek(1) to peek the next elem to be popped, peek(2) peeks the second next element to be popped. + peek(nth: number): T | undefined { + return this.store[nth - 1]; + } + pop(): T | undefined { + return this.store.shift(); + // yes, I know what you want to say, it has O(n) time complexity. + // it doesn't really matter if there is only like 100 people in home queue at most. + // if you really care about performance, why don't you go and limit the amount of people to fetch? that probably has significantly more impact to the performance. + } +}