From 03e6d87a5d8d4315d01bc979696da7bf8b9ef42f Mon Sep 17 00:00:00 2001 From: nflnkr Date: Fri, 7 Apr 2023 12:43:37 +0300 Subject: [PATCH] refactor tickets state --- .../dashboard/Content/Support/Support.tsx | 6 ++--- .../Content/Support/TicketList/TicketList.tsx | 22 +++++++++---------- src/stores/tickets.ts | 15 +++++++++++++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/pages/dashboard/Content/Support/Support.tsx b/src/pages/dashboard/Content/Support/Support.tsx index 08f57e4..8dc197d 100644 --- a/src/pages/dashboard/Content/Support/Support.tsx +++ b/src/pages/dashboard/Content/Support/Support.tsx @@ -1,11 +1,11 @@ import { Box, useMediaQuery, useTheme } from "@mui/material"; -import { useEffect, useRef, useState } from "react"; +import { useEffect } from "react"; import Chat from "./Chat/Chat"; import Collapse from "./Collapse"; import TicketList from "./TicketList/TicketList"; import { getTickets, subscribeToAllTickets } from "@root/api/tickets"; import { GetTicketsRequest, Ticket } from "@root/model/ticket"; -import { clearTickets, updateTickets } from "@root/stores/tickets"; +import { clearTickets, setTicketsFetchState, updateTickets, useTicketStore } from "@root/stores/tickets"; import { enqueueSnackbar } from "notistack"; import { clearMessages } from "@root/stores/messages"; import { authStore } from "@root/stores/auth"; @@ -95,4 +95,4 @@ export default function Support() { {upMd && ticketList} ); -} +} \ No newline at end of file diff --git a/src/pages/dashboard/Content/Support/TicketList/TicketList.tsx b/src/pages/dashboard/Content/Support/TicketList/TicketList.tsx index 0896e60..09a752e 100644 --- a/src/pages/dashboard/Content/Support/TicketList/TicketList.tsx +++ b/src/pages/dashboard/Content/Support/TicketList/TicketList.tsx @@ -2,21 +2,17 @@ import HighlightOffOutlinedIcon from '@mui/icons-material/HighlightOffOutlined'; import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined'; import { Box, Button, useMediaQuery, useTheme } from "@mui/material"; import { Ticket } from "@root/model/ticket"; -import { useTicketStore } from "@root/stores/tickets"; +import { incrementTicketsApiPage, useTicketStore } from "@root/stores/tickets"; import { throttle } from '@root/utils/throttle'; -import { MutableRefObject, useEffect, useRef } from "react"; +import { useEffect, useRef } from "react"; import TicketItem from "./TicketItem"; -interface Props { - fetchingStateRef: MutableRefObject<"idle" | "fetching" | "all fetched">; - incrementCurrentPage: () => void; -} - -export default function TicketList({ fetchingStateRef, incrementCurrentPage }: Props) { +export default function TicketList() { const theme = useTheme(); const upMd = useMediaQuery(theme.breakpoints.up("md")); const tickets = useTicketStore(state => state.tickets); + const ticketsFetchStateRef = useRef(useTicketStore.getState().fetchState); const ticketsBoxRef = useRef(null); useEffect(function updateCurrentPageOnScroll() { @@ -26,9 +22,9 @@ export default function TicketList({ fetchingStateRef, incrementCurrentPage }: P const scrollHandler = () => { const scrollBottom = ticketsBox.scrollHeight - ticketsBox.scrollTop - ticketsBox.clientHeight; if ( - scrollBottom < 10 && - fetchingStateRef.current === "idle" - ) incrementCurrentPage(); + scrollBottom < ticketsBox.clientHeight && + ticketsFetchStateRef.current === "idle" + ) incrementTicketsApiPage(); }; const throttledScrollHandler = throttle(scrollHandler, 200); @@ -37,7 +33,9 @@ export default function TicketList({ fetchingStateRef, incrementCurrentPage }: P return () => { ticketsBox.removeEventListener("scroll", throttledScrollHandler); }; - }, [incrementCurrentPage, fetchingStateRef]); + }, []); + + useEffect(() => useTicketStore.subscribe(state => (ticketsFetchStateRef.current = state.fetchState)), []); const sortedTickets = tickets.sort(sortTicketsByUpdateTime).sort(sortTicketsByUnread); diff --git a/src/stores/tickets.ts b/src/stores/tickets.ts index e3a07cf..48bbc7c 100644 --- a/src/stores/tickets.ts +++ b/src/stores/tickets.ts @@ -5,12 +5,18 @@ import { devtools } from "zustand/middleware"; interface TicketStore { tickets: Ticket[]; + fetchState: "idle" | "fetching" | "all fetched"; + apiPage: number; + ticketsPerPage: number; } export const useTicketStore = create()( devtools( (set, get) => ({ tickets: [], + fetchState: "idle", + apiPage: 0, + ticketsPerPage: 20, }), { name: "Tickets store (admin)" @@ -18,6 +24,15 @@ export const useTicketStore = create()( ) ); +export const setTicketsFetchState = (fetchState: TicketStore["fetchState"]) => useTicketStore.setState({ fetchState }); + +export const incrementTicketsApiPage = () => { + const state = useTicketStore.getState(); + if (state.fetchState !== "idle") return; + + useTicketStore.setState({ apiPage: state.apiPage + 1 }); +}; + export const updateTickets = (receivedTickets: Ticket[]) => { const state = useTicketStore.getState(); const ticketIdToTicketMap: { [ticketId: string]: Ticket; } = {};