From dde92bf1eccee9bdd725c9ceab27b68f5c0b7c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 10 Jul 2024 13:08:00 -0500 Subject: [PATCH] feat: next safe ad exempt --- src/app/components/PatreonPlug.tsx | 10 +++++-- src/hooks/useAdExempt.ts | 46 +++++++++++++++++------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/app/components/PatreonPlug.tsx b/src/app/components/PatreonPlug.tsx index 80ecd5abd..e6d29813e 100644 --- a/src/app/components/PatreonPlug.tsx +++ b/src/app/components/PatreonPlug.tsx @@ -2,14 +2,20 @@ import { CheckIcon } from '@radix-ui/react-icons'; import { Button, Flex, Link, Text } from '@radix-ui/themes'; +import { useLayoutEffect, useState } from 'react'; import { patreonLoginUrl } from '../../core/blitzkit/patreonLoginUrl'; import { useAdExempt } from '../../hooks/useAdExempt'; import { PatreonIcon } from '../../icons/Patreon'; import * as App from '../../stores/app'; export function PatreonPlug() { - const patreon = App.use((state) => state.logins.patreon); + const [hasPatreon, setHasPatreon] = useState(false); const exempt = useAdExempt(); + const patreon = App.use((state) => state.logins.patreon); + + useLayoutEffect(() => { + setHasPatreon(patreon !== undefined); + }, [patreon]); return ( - {!patreon && !exempt && ( + {!hasPatreon && !exempt && ( diff --git a/src/hooks/useAdExempt.ts b/src/hooks/useAdExempt.ts index d06c2269b..070971d7d 100644 --- a/src/hooks/useAdExempt.ts +++ b/src/hooks/useAdExempt.ts @@ -1,30 +1,36 @@ -import { use, useMemo } from 'react'; +import { useLayoutEffect, useState } from 'react'; import * as App from '../stores/app'; -let cache: Record = {}; +let cache: Record> = {}; export function useAdExempt() { const patreon = App.use((state) => state.logins.patreon); - const promise = useMemo( - () => - new Promise(async (resolve) => { - if (!patreon) return resolve(false); - if (patreon.token in cache) return resolve(cache[patreon.token]); + const [exempt, setExempt] = useState(false); - const response = await fetch( - `/api/patreon/membership/${patreon.token}`, - { cache: 'force-cache' }, - ); + useLayoutEffect(() => { + (async () => { + if (!patreon) return setExempt(false); - if (!response.ok) return resolve(false); + if (!(patreon.token in cache)) { + cache[patreon.token] = new Promise(async (resolve) => { + const response = await fetch( + `/api/patreon/membership/${patreon.token}`, + { cache: 'force-cache' }, + ); - const json = await response.json(); - const exempt = typeof json === 'boolean' && json; - cache[patreon.token] = exempt; + if (!response.ok) return resolve(false); - resolve(exempt); - }), - [patreon?.token], - ); - return use(promise); + const json = await response.json(); + const exempt = typeof json === 'boolean' && json; + + cache[patreon.token] = exempt; + resolve(exempt); + }); + } + + setExempt(await cache[patreon.token]); + })(); + }, []); + + return exempt; }