diff --git a/app/components/general-layout.tsx b/app/components/general-layout.tsx index 4aceb5f..4e67447 100644 --- a/app/components/general-layout.tsx +++ b/app/components/general-layout.tsx @@ -30,7 +30,7 @@ import { Avatar } from "@radix-ui/react-avatar"; import { cn } from "~/utils"; import { useGetIdentity, useLogout } from "@refinedev/core"; import { Identity } from "~/data/auth-provider"; -import { PinningNetworkBanner } from "./pinnning-network-banner"; +import { PinningNetworkBanner } from "./pinning-network-banner"; import { PinningProvider } from "~/providers/PinningProvider"; diff --git a/app/components/pinnning-network-banner.tsx b/app/components/pinning-network-banner.tsx similarity index 95% rename from app/components/pinnning-network-banner.tsx rename to app/components/pinning-network-banner.tsx index 2e626cc..91e12af 100644 --- a/app/components/pinnning-network-banner.tsx +++ b/app/components/pinning-network-banner.tsx @@ -6,14 +6,14 @@ import { AccordionTrigger, } from "./ui/accordion"; import { Progress } from "./ui/progress"; -import { usePinning, useUnpinMutation } from "~/hooks/usePinnning"; +import { usePinning } from "~/hooks/usePinning"; import { Tabs, TabsTrigger, TabsList, TabsContent } from "./ui/tabs"; import { Button } from "./ui/button"; import { Cross2Icon } from "@radix-ui/react-icons"; import { PinningStatus } from "~/data/pinning"; export const PinningNetworkBanner = () => { - const { data} = usePinning(); + const { data } = usePinning(); // TODO: Adapt to real API const itemsLeft = useMemo( @@ -73,7 +73,7 @@ export const PinningNetworkBanner = () => { }; const PinCidItem = ({ item }: { item: PinningStatus }) => { - const { mutate } = useUnpinMutation(); + const { mutate } = usePinning(); return (
@@ -86,6 +86,7 @@ const PinCidItem = ({ item }: { item: PinningStatus }) => { className="p-2 rounded-full h-6" onClick={() => mutate({ cid: item.id, + type: "unpin" })}> diff --git a/app/hooks/usePinning.ts b/app/hooks/usePinning.ts new file mode 100644 index 0000000..4547869 --- /dev/null +++ b/app/hooks/usePinning.ts @@ -0,0 +1,51 @@ +import { useMutation } from "@tanstack/react-query"; +import { useContext } from "react"; +import { PinningProcess } from "~/data/pinning"; +import { PinningContext } from "~/providers/PinningProvider"; + +// TODO: Adapt to real API + +export const usePinning = () => { + const context = useContext(PinningContext); + + const { mutate } = useMutation({ + mutationKey: ["pin-progress"], + mutationFn: async (variables: { cid: string, type: "pin" | "unpin" }) => { + const { cid, type } = variables; + switch (type) { + case "pin": { + const response = await PinningProcess.pin(cid); + + if (!response.success) { + open?.({ + type: "destructive", + message: "Erorr pinning " + cid, + description: response.message, + }); + } + break; + } + case "unpin": { + const response = await PinningProcess.unpin(cid); + + if (!response.success) { + open?.({ + type: "destructive", + message: "Erorr removing " + cid, + description: response.message, + }); + } + + break; + } + } + + context.queryClient.invalidateQueries({ queryKey: ["pin-progress"] }) + } + }); + + return { + ...context.query, + mutate + }; +}; diff --git a/app/hooks/usePinnning.ts b/app/hooks/usePinnning.ts deleted file mode 100644 index 324b8a0..0000000 --- a/app/hooks/usePinnning.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { PinningProcess } from "~/data/pinning"; - -// TODO: Adapt to real API - -export const usePinMutation = () => { - const queryClient = useQueryClient(); - const { mutate } = useMutation({ - mutationFn: async ({ cid }) => { - const response = await PinningProcess.pin(cid); - - if (!response.success) { - open?.({ - type: "destructive", - message: "Erorr pinning " + cid, - description: response.message, - }); - } - - queryClient.invalidateQueries({ queryKey: ["pin-progress"] }) - } - }); - - return { mutate } -} - -export const useUnpinMutation = () => { - const queryClient = useQueryClient(); - const { mutate } = useMutation({ - mutationFn: async ({ cid }) => { - const response = await PinningProcess.unpin(cid); - - if (!response.success) { - open?.({ - type: "destructive", - message: "Erorr pinning " + cid, - description: response.message, - }); - } - - queryClient.invalidateQueries({ queryKey: ["pin-progress"] }) - } - }); - - return { mutate } -} - -export const usePinning = () => { - const { data } = useQuery({ - queryKey: ["pin-progress"], - refetchInterval: (query) => { - if (!query.state.data || !query.state.data.items.length) { - return false; - } - - return 1000; - }, - refetchIntervalInBackground: true, - queryFn: () => { - const response = PinningProcess.pollAllProgress(); - const result = response.next(); - - return { - items: result.value || [], - lastUpdated: Date.now() - }; - }, - }) - - return { - data - }; -}; diff --git a/app/providers/PinningProvider.tsx b/app/providers/PinningProvider.tsx index b379059..660aa6c 100644 --- a/app/providers/PinningProvider.tsx +++ b/app/providers/PinningProvider.tsx @@ -1,25 +1,63 @@ -import { Dispatch, SetStateAction, createContext, useContext, useState } from "react"; +import { + QueryClient, + UseQueryResult, + useQuery, + useQueryClient, +} from "@tanstack/react-query"; +import { createContext, useContext } from "react"; +import { PinningProcess, PinningStatus } from "~/data/pinning"; export interface IPinningData { - cid: string; - progress: number + cid: string; + progress: number; } export interface IPinningContextType { - data: IPinningData[], - setData: Dispatch> + query: UseQueryResult< + { + items: PinningStatus[]; + lastUpdated: number; + }, + Error + >; + queryClient: QueryClient; } -export const PinningContext = createContext({} as IPinningContextType); +export const PinningContext = createContext( + {} as IPinningContextType, +); export const usePinningContext = () => useContext(PinningContext); -export const PinningProvider = ({ children }: React.PropsWithChildren) => { - const [data, setData] = useState([]); +const usePinProgressQuery = () => + useQuery({ + queryKey: ["pin-progress"], + refetchInterval: (query) => { + if (!query.state.data || !query.state.data.items.length) { + return false; + } - return ( - - {children} - - ) -} \ No newline at end of file + return 1000; + }, + refetchIntervalInBackground: true, + queryFn: () => { + const response = PinningProcess.pollAllProgress(); + const result = response.next(); + + return { + items: result.value || [], + lastUpdated: Date.now(), + }; + }, + }); + +export const PinningProvider = ({ children }: React.PropsWithChildren) => { + const queryClient = useQueryClient(); + const queryResult = usePinProgressQuery(); + + return ( + + {children} + + ); +}; diff --git a/app/routes/file-manager/columns.tsx b/app/routes/file-manager/columns.tsx index 57c8dee..b8a4f7f 100644 --- a/app/routes/file-manager/columns.tsx +++ b/app/routes/file-manager/columns.tsx @@ -11,7 +11,7 @@ import { DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; -import { usePinMutation } from "~/hooks/usePinnning"; +import { usePinning } from "~/hooks/usePinning"; import { cn } from "~/utils"; // This type is used to define the shape of our data. @@ -25,7 +25,7 @@ export type File = { const CreatedOnCell = ({ row }: { row: Row }) => { // const { open } = useNotification(); - const { mutate } = usePinMutation(); + const { mutate } = usePinning(); return (
@@ -45,6 +45,7 @@ const CreatedOnCell = ({ row }: { row: Row }) => { console.log(`Adding ${row.getValue("cid")} for pinning...`); mutate({ cid: row.getValue("cid"), + type: "pin" }); }}>