diff --git a/apps/web/app/(org)/dashboard/caps/Caps.tsx b/apps/web/app/(org)/dashboard/caps/Caps.tsx index 6c0f3570e2..bc0ff17e6b 100644 --- a/apps/web/app/(org)/dashboard/caps/Caps.tsx +++ b/apps/web/app/(org)/dashboard/caps/Caps.tsx @@ -5,16 +5,13 @@ import { Button } from "@cap/ui"; import type { Video } from "@cap/web-domain"; import { faFolderPlus, faInfoCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { useQuery } from "@tanstack/react-query"; import { Effect, Exit } from "effect"; import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useMemo, useRef, useState } from "react"; import { toast } from "sonner"; -import { useEffectMutation, useEffectQuery } from "@/lib/EffectRuntime"; -import { - AnalyticsRequest, - useVideosAnalyticsQuery, -} from "@/lib/Requests/AnalyticsRequest"; +import { useEffectMutation } from "@/lib/EffectRuntime"; +import { useVideosAnalyticsQuery } from "@/lib/Queries/Analytics"; +import { AnalyticsRequest } from "@/lib/Requests/AnalyticsRequest"; import { Rpc, withRpc } from "@/lib/Rpcs"; import { useDashboardContext } from "../Contexts"; import { diff --git a/apps/web/app/(org)/dashboard/folder/[id]/components/FolderVideosSection.tsx b/apps/web/app/(org)/dashboard/folder/[id]/components/FolderVideosSection.tsx index 07801ee86a..443591ae44 100644 --- a/apps/web/app/(org)/dashboard/folder/[id]/components/FolderVideosSection.tsx +++ b/apps/web/app/(org)/dashboard/folder/[id]/components/FolderVideosSection.tsx @@ -1,14 +1,14 @@ "use client"; import type { Video } from "@cap/web-domain"; -import { useQuery } from "@tanstack/react-query"; import { Effect, Exit } from "effect"; import { useRouter } from "next/navigation"; import { useMemo, useRef, useState } from "react"; import { toast } from "sonner"; import { useDashboardContext } from "@/app/(org)/dashboard/Contexts"; import { useEffectMutation } from "@/lib/EffectRuntime"; -import { useVideosAnalyticsQuery } from "@/lib/Requests/AnalyticsRequest"; +import { useVideosAnalyticsQuery } from "@/lib/Queries/Analytics"; +import { AnalyticsRequest } from "@/lib/Requests/AnalyticsRequest"; import { Rpc, withRpc } from "@/lib/Rpcs"; import type { VideoData } from "../../../caps/Caps"; import { CapCard } from "../../../caps/components/CapCard/CapCard"; diff --git a/apps/web/app/(org)/dashboard/spaces/[spaceId]/SharedCaps.tsx b/apps/web/app/(org)/dashboard/spaces/[spaceId]/SharedCaps.tsx index 2068291bdc..f496d9aa9b 100644 --- a/apps/web/app/(org)/dashboard/spaces/[spaceId]/SharedCaps.tsx +++ b/apps/web/app/(org)/dashboard/spaces/[spaceId]/SharedCaps.tsx @@ -8,7 +8,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useQuery } from "@tanstack/react-query"; import { useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; -import { useVideosAnalyticsQuery } from "@/lib/Requests/AnalyticsRequest"; +import { useVideosAnalyticsQuery } from "@/lib/Queries/Analytics"; +import { AnalyticsRequest } from "@/lib/Requests/AnalyticsRequest"; import { useDashboardContext } from "../../Contexts"; import { CapPagination } from "../../caps/components/CapPagination"; import Folder, { type FolderDataType } from "../../caps/components/Folder"; diff --git a/apps/web/lib/Queries/Analytics.ts b/apps/web/lib/Queries/Analytics.ts new file mode 100644 index 0000000000..eb00f33bf6 --- /dev/null +++ b/apps/web/lib/Queries/Analytics.ts @@ -0,0 +1,47 @@ +import type { Video } from "@cap/web-domain"; +import { Effect } from "effect"; +import { useEffectQuery } from "../EffectRuntime"; +import { AnalyticsRequest } from "../Requests/AnalyticsRequest"; + +export function useVideosAnalyticsQuery( + videoIds: Video.VideoId[], + dubApiKeyEnabled?: boolean, +) { + return useEffectQuery({ + queryKey: ["analytics", videoIds], + queryFn: Effect.fn(function* () { + if (!dubApiKeyEnabled) return {}; + + const dataloader = yield* AnalyticsRequest.DataLoaderResolver; + + const results = yield* Effect.all( + videoIds.map((videoId) => + Effect.request( + new AnalyticsRequest.AnalyticsRequest({ videoId }), + dataloader, + ).pipe( + Effect.catchAll((e) => { + console.warn( + `Failed to fetch analytics for video ${videoId}:`, + e, + ); + return Effect.succeed({ count: 0 }); + }), + Effect.map(({ count }) => ({ videoId, count })), + ), + ), + { concurrency: "unbounded" }, + ); + + return results.reduce( + (acc, current) => { + acc[current.videoId] = current.count; + return acc; + }, + {} as Record, + ); + }), + refetchOnWindowFocus: false, + refetchOnMount: true, + }); +} diff --git a/apps/web/lib/Requests/AnalyticsRequest.ts b/apps/web/lib/Requests/AnalyticsRequest.ts index d122e520ab..da475c5bb2 100644 --- a/apps/web/lib/Requests/AnalyticsRequest.ts +++ b/apps/web/lib/Requests/AnalyticsRequest.ts @@ -3,7 +3,6 @@ import { dataLoader } from "@effect/experimental/RequestResolver"; import { Effect, Exit, Request, RequestResolver } from "effect"; import type { NonEmptyArray } from "effect/Array"; import { Rpc } from "@/lib/Rpcs"; -import { useEffectQuery } from "../EffectRuntime"; export namespace AnalyticsRequest { export class AnalyticsRequest extends Request.Class< @@ -50,46 +49,3 @@ export namespace AnalyticsRequest { }, ) {} } - -export function useVideosAnalyticsQuery( - videoIds: Video.VideoId[], - dubApiKeyEnabled?: boolean, -) { - return useEffectQuery({ - queryKey: ["analytics", videoIds], - queryFn: Effect.fn(function* () { - if (!dubApiKeyEnabled) return {}; - - const dataloader = yield* AnalyticsRequest.DataLoaderResolver; - - const results = yield* Effect.all( - videoIds.map((videoId) => - Effect.request( - new AnalyticsRequest.AnalyticsRequest({ videoId }), - dataloader, - ).pipe( - Effect.catchAll((e) => { - console.warn( - `Failed to fetch analytics for video ${videoId}:`, - e, - ); - return Effect.succeed({ count: 0 }); - }), - Effect.map(({ count }) => ({ videoId, count })), - ), - ), - { concurrency: "unbounded" }, - ); - - return results.reduce( - (acc, current) => { - acc[current.videoId] = current.count; - return acc; - }, - {} as Record, - ); - }), - refetchOnWindowFocus: false, - refetchOnMount: true, - }); -}