From ec9f684a7be973525cb458f2e24dd7bf86f4d8f9 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 6 May 2023 13:20:17 +0900 Subject: [PATCH 1/6] chore: setup React.StrictMode --- app/entry.client.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/entry.client.tsx b/app/entry.client.tsx index e601e4a686..78b6e1eaf0 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 { initializeConfigClient } from "./utils/config"; @@ -6,7 +7,14 @@ import { initializeConfigClient } from "./utils/config"; function main() { registerServiceWorker(); initializeConfigClient(); - hydrateRoot(window.document, ); + React.startTransition(() => { + hydrateRoot( + window.document, + + + + ); + }); } main(); From 4842dde1bb14b103d4be0ad0deb66a6a005a79d0 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 6 May 2023 13:21:15 +0900 Subject: [PATCH 2/6] fix: fix usePlayerLoader --- app/utils/youtube.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/utils/youtube.ts b/app/utils/youtube.ts index 72bb4f0a8e..882b35a3eb 100644 --- a/app/utils/youtube.ts +++ b/app/utils/youtube.ts @@ -386,7 +386,10 @@ export function usePlayerLoader( const ref = useRefCallbackEffect((el) => { if (el && mutation.isIdle) { - mutation.mutate(el); + // workaroudn for StrictMode? https://github.com/TanStack/query/issues/4983 + window.setTimeout(() => { + mutation.mutate(el); + }); } }); From a52a2c1ac90a12ef6468c9cd04858d8b92a18b6c Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 6 May 2023 13:35:52 +0900 Subject: [PATCH 3/6] chore: comment --- app/utils/youtube.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/utils/youtube.ts b/app/utils/youtube.ts index 882b35a3eb..37a3192716 100644 --- a/app/utils/youtube.ts +++ b/app/utils/youtube.ts @@ -386,7 +386,7 @@ export function usePlayerLoader( const ref = useRefCallbackEffect((el) => { if (el && mutation.isIdle) { - // workaroudn for StrictMode? https://github.com/TanStack/query/issues/4983 + // workaround for React.StrictMode https://github.com/TanStack/query/issues/4983 window.setTimeout(() => { mutation.mutate(el); }); From 8cdff49a6cb1dfde06db8718681c9e6d1d3c7fa8 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 6 May 2023 13:45:36 +0900 Subject: [PATCH 4/6] fix: fix /users/redirect toast --- app/routes/users/redirect.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/routes/users/redirect.tsx b/app/routes/users/redirect.tsx index 6e9cc892a8..69b21b7613 100644 --- a/app/routes/users/redirect.tsx +++ b/app/routes/users/redirect.tsx @@ -18,14 +18,15 @@ export default function PageComponent() { Object.fromEntries(searchParams.entries()) ); if (parsed.success) { + const options = { id: parsed.data.type }; // stable toast for React.StrictMode if (parsed.data.type === "register") { - toast.success("Successfully registered"); + toast.success("Successfully registered", options); } if (parsed.data.type === "signin") { - toast.success("Successfully signed in"); + toast.success("Successfully signed in", options); } if (parsed.data.type === "signout") { - toast.success("Successfully signed out"); + toast.success("Successfully signed out", options); } } navigate($R["/"](), { replace: true }); From 85e0137a5582829a1c9a32f6141d4fb338474507 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 6 May 2023 13:51:58 +0900 Subject: [PATCH 5/6] fix: fix flash message double effect --- app/routes/users/redirect.tsx | 2 +- app/utils/flash-message-hook.tsx | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/routes/users/redirect.tsx b/app/routes/users/redirect.tsx index 69b21b7613..fcf5cfbb95 100644 --- a/app/routes/users/redirect.tsx +++ b/app/routes/users/redirect.tsx @@ -18,7 +18,7 @@ export default function PageComponent() { Object.fromEntries(searchParams.entries()) ); if (parsed.success) { - const options = { id: parsed.data.type }; // stable toast for React.StrictMode + const options = { id: parsed.data.type }; // stable toast id for React.StrictMode if (parsed.data.type === "register") { toast.success("Successfully registered", options); } diff --git a/app/utils/flash-message-hook.tsx b/app/utils/flash-message-hook.tsx index a8c3b99170..57be7f48e3 100644 --- a/app/utils/flash-message-hook.tsx +++ b/app/utils/flash-message-hook.tsx @@ -5,17 +5,18 @@ import type { FlashMessage } from "./flash-message"; export function useFlashMessages(flashMessages: FlashMessage[]) { React.useEffect(() => { for (const message of flashMessages) { + const options = { id: message.content }; // stable toast id for React.StrictMode switch (message.variant) { case "success": { - toast.success(message.content); + toast.success(message.content, options); break; } case "error": { - toast.error(message.content); + toast.error(message.content, options); break; } default: { - toastInfo(message.content); + toastInfo(message.content, options); } } } From 629ae4a85ff72b25042ccdd07d49a4643dbf59b1 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sat, 27 May 2023 11:03:51 +0900 Subject: [PATCH 6/6] refactor: simiplify usePlayerLoader by useIntersectionObserver --- app/utils/youtube.ts | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/app/utils/youtube.ts b/app/utils/youtube.ts index c9532f26db..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,30 +495,16 @@ export function usePlayerLoader( playerOptions: YoutubePlayerOptions, { onReady }: { onReady: (player: YoutubePlayer) => void } ) { - onReady = useStableCallback(onReady); - - const ref = useRefCallbackEffect((el) => { - if (el && mutation.isIdle) { - // workaround for React.StrictMode https://github.com/TanStack/query/issues/4983 - window.setTimeout(() => { - 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,