diff --git a/app/entry.client.tsx b/app/entry.client.tsx index 5c7dc795ab..e23cb4e70e 100644 --- a/app/entry.client.tsx +++ b/app/entry.client.tsx @@ -1,4 +1,5 @@ import { RemixBrowser } from "@remix-run/react"; +import React from "react"; import { hydrateRoot } from "react-dom/client"; import { registerServiceWorker } from "./misc/register-service-worker.client"; import { initializePublicConfigClient } from "./utils/config-public"; @@ -6,7 +7,14 @@ import { initializePublicConfigClient } from "./utils/config-public"; function main() { registerServiceWorker(); initializePublicConfigClient(); - hydrateRoot(window.document, ); + React.startTransition(() => { + hydrateRoot( + window.document, + + + + ); + }); } main(); diff --git a/app/utils/youtube.ts b/app/utils/youtube.ts index 437f0d6256..4e9966a9f4 100644 --- a/app/utils/youtube.ts +++ b/app/utils/youtube.ts @@ -6,13 +6,11 @@ import { tinyassert, zip, } from "@hiogawa/utils"; -import { useRefCallbackEffect, useStableCallback } from "@hiogawa/utils-react"; import { useMutation } from "@tanstack/react-query"; import { XMLParser } from "fast-xml-parser"; -import React from "react"; -import { toast } from "react-hot-toast"; import { z } from "zod"; import { loadScript } from "./dom-utils"; +import { useIntersectionObserver } from "./hooks-client-utils"; import { FILTERED_LANGUAGE_CODES, LanguageCode, @@ -497,27 +495,16 @@ export function usePlayerLoader( playerOptions: YoutubePlayerOptions, { onReady }: { onReady: (player: YoutubePlayer) => void } ) { - onReady = useStableCallback(onReady); - - const ref = useRefCallbackEffect((el) => { - if (el && mutation.isIdle) { - mutation.mutate(el); + const ref = useIntersectionObserver(([entry]) => { + if (entry && entry.target instanceof HTMLElement && mutation.isIdle) { + mutation.mutate(entry.target); } }); - const mutation = useMutation( - (el: HTMLElement) => loadYoutubePlayer(el, playerOptions), - { - onSuccess: onReady, - onError: () => { - toast.error("Failed to initialize youtube player"); - }, - } - ); - - React.useEffect(() => { - return () => mutation.data?.destroy(); - }, []); + const mutation = useMutation({ + mutationFn: (el: HTMLElement) => loadYoutubePlayer(el, playerOptions), + onSuccess: onReady, + }); return { ref,