From cf841c9bb2d84486b3629855a1e419fe8b637e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:05:34 -0500 Subject: [PATCH] feat: migrated app store --- src/app/auth/[provider]/page.tsx | 3 +- src/app/components/Checks.tsx | 76 ++++++++++--- src/app/components/PatreonPlug.tsx | 4 +- src/app/layout.tsx | 105 +++++++++--------- src/app/settings/page.tsx | 7 +- .../components/Model/components/Options.tsx | 4 +- src/components/Navbar/index.tsx | 19 +++- src/core/blitz/extendAuthPatreon.ts | 20 ---- src/core/blitz/extendAuthWargaming.ts | 59 ---------- src/core/blitz/logoutPatreon.ts | 7 -- src/core/blitz/logoutWargaming.ts | 7 -- src/hooks/useAdExempt.ts | 4 +- src/stores/app/constants.ts | 1 + src/stores/{app.ts => app/index.ts} | 31 +++--- 14 files changed, 156 insertions(+), 191 deletions(-) delete mode 100644 src/core/blitz/extendAuthPatreon.ts delete mode 100644 src/core/blitz/extendAuthWargaming.ts delete mode 100644 src/core/blitz/logoutPatreon.ts delete mode 100644 src/core/blitz/logoutWargaming.ts create mode 100644 src/stores/app/constants.ts rename src/stores/{app.ts => app/index.ts} (52%) diff --git a/src/app/auth/[provider]/page.tsx b/src/app/auth/[provider]/page.tsx index 46cfbf8ca..306aa141c 100644 --- a/src/app/auth/[provider]/page.tsx +++ b/src/app/auth/[provider]/page.tsx @@ -4,7 +4,7 @@ import { Flex, Heading, Text } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; import { useEffect } from 'react'; import PageWrapper from '../../../components/PageWrapper'; -import { mutateApp } from '../../../stores/app'; +import * as App from '../../../stores/app'; export interface PatreonAuthResponse { access_token: string; @@ -23,6 +23,7 @@ export default function Page({ searchParams: { [key: string]: string }; }) { const router = useRouter(); + const mutateApp = App.useMutation(); useEffect(() => { switch (params.provider) { diff --git a/src/app/components/Checks.tsx b/src/app/components/Checks.tsx index 719907fcb..b22ac8dce 100644 --- a/src/app/components/Checks.tsx +++ b/src/app/components/Checks.tsx @@ -10,13 +10,21 @@ import { } from '@radix-ui/themes'; import { usePathname } from 'next/navigation'; import { useEffect, useState } from 'react'; -import { extendAuthPatreon } from '../../core/blitz/extendAuthPatreon'; -import { extendAuthWargaming } from '../../core/blitz/extendAuthWargaming'; -import { logoutPatreon } from '../../core/blitz/logoutPatreon'; -import { logoutWargaming } from '../../core/blitz/logoutWargaming'; +import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID'; +import { idToRegion } from '../../core/blitz/idToRegion'; import isDev from '../../core/blitzkit/isDev'; import { isLocalhost } from '../../core/blitzkit/isLocalhost'; -import { CURRENT_POLICIES_AGREEMENT_INDEX, useApp } from '../../stores/app'; +import * as App from '../../stores/app'; +import { CURRENT_POLICIES_AGREEMENT_INDEX } from '../../stores/app/constants'; +import { PatreonAuthResponse } from '../auth/[provider]/page'; + +interface Extension { + data: { + access_token: string; + account_id: number; + expires_at: number; + }; +} const DEV_BUILD_AGREEMENT_COOLDOWN = 8 * 24 * 60 * 60 * 1000; @@ -27,8 +35,10 @@ const DEV_BUILD_AGREEMENT_COOLDOWN = 8 * 24 * 60 * 60 * 1000; export function Checks() { const [showDevBuildAlert, setShowDevBuildAlert] = useState(false); - const logins = useApp((state) => state.logins); - const policiesAgreementIndex = useApp( + const mutateApp = App.useMutation(); + const logins = App.use((state) => state.logins); + const appStore = App.useStore(); + const policiesAgreementIndex = App.use( (state) => state.policiesAgreementIndex, ); const pathname = usePathname(); @@ -39,7 +49,7 @@ export function Checks() { setShowDevBuildAlert( isDev() && !isLocalhost() && - Date.now() - useApp.getState().devBuildAgreementTime >= + Date.now() - appStore.getState().devBuildAgreementTime >= DEV_BUILD_AGREEMENT_COOLDOWN, ); }, []); @@ -55,9 +65,31 @@ export function Checks() { const expiresInDays = expiresIn / 1000 / 60 / 60 / 24; if (expiresInDays < 0) { - logoutWargaming(); + mutateApp((draft) => { + draft.logins.wargaming = undefined; + }); } else if (expiresInDays < 7) { - extendAuthWargaming(); + const { wargaming } = appStore.getState().logins; + + if (!wargaming) return; + + fetch( + `https://api.worldoftanks.${idToRegion( + wargaming.id, + )}/wot/auth/prolongate/?application_id=${WARGAMING_APPLICATION_ID}&access_token=${ + wargaming.token + }`, + ) + .then((response) => response.json() as Promise) + .then((json) => { + mutateApp((draft) => { + draft.logins.wargaming = { + id: wargaming.id, + token: json.data.access_token, + expires: json.data.expires_at * 1000, + }; + }); + }); } } @@ -66,9 +98,25 @@ export function Checks() { const expiresInDays = expiresIn / 1000 / 60 / 60 / 24; if (expiresInDays < 0) { - logoutPatreon(); + mutateApp((draft) => { + draft.logins.patreon = undefined; + }); } else if (expiresInDays < 15) { - extendAuthPatreon(); + const { patreon } = appStore.getState().logins; + + if (!patreon) return; + + fetch(`/api/patreon/refresh/${patreon.refreshToken}`) + .then((response) => response.json() as Promise) + .then((data) => { + mutateApp((draft) => { + draft.logins.patreon = { + token: data.access_token, + refreshToken: data.refresh_token, + expires: Date.now() + data.expires_in * 1000, + }; + }); + }); } } }); @@ -93,7 +141,7 @@ export function Checks() { variant="solid" onClick={() => { setShowDevBuildAlert(false); - useApp.setState({ devBuildAgreementTime: Date.now() }); + appStore.setState({ devBuildAgreementTime: Date.now() }); }} > Continue @@ -158,7 +206,7 @@ export function Checks() { @@ -176,7 +179,11 @@ export default function Navbar() { diff --git a/src/core/blitz/extendAuthPatreon.ts b/src/core/blitz/extendAuthPatreon.ts deleted file mode 100644 index 3bf7ae0af..000000000 --- a/src/core/blitz/extendAuthPatreon.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PatreonAuthResponse } from '../../app/auth/[provider]/page'; -import { mutateApp, useApp } from '../../stores/app'; - -export async function extendAuthPatreon() { - const { patreon } = useApp.getState().logins; - - if (!patreon) return; - - const data = (await fetch( - `/api/patreon/refresh/${patreon.refreshToken}`, - ).then((response) => response.json())) as PatreonAuthResponse; - - mutateApp((draft) => { - draft.logins.patreon = { - token: data.access_token, - refreshToken: data.refresh_token, - expires: Date.now() + data.expires_in * 1000, - }; - }); -} diff --git a/src/core/blitz/extendAuthWargaming.ts b/src/core/blitz/extendAuthWargaming.ts deleted file mode 100644 index fe507db07..000000000 --- a/src/core/blitz/extendAuthWargaming.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID'; -import { mutateApp, useApp } from '../../stores/app'; -import { idToRegion } from './idToRegion'; - -interface Extension { - data: { - access_token: string; - account_id: number; - expires_at: number; - }; -} - -export async function extendAuthWargaming() { - const { wargaming } = useApp.getState().logins; - - if (!wargaming) return; - - // error handling? what's that? - /* - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠙⠛⠛⠛⠿⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⡀⠠⠤⠒⢂⣉⣉⣉⣑⣒⣒⠒⠒⠒⠒⠒⠒⠒⠀⠀⠐⠒⠚⠻⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⡠⠔⠉⣀⠔⠒⠉⣀⣀⠀⠀⠀⣀⡀⠈⠉⠑⠒⠒⠒⠒⠒⠈⠉⠉⠉⠁⠂⠀⠈⠙⢿⣿⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠔⠁⠠⠖⠡⠔⠊⠀⠀⠀⠀⠀⠀⠀⠐⡄⠀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠉⠲⢄⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⠊⠀⢀⣀⣤⣤⣤⣤⣀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠜⠀⠀⠀⠀⣀⡀⠀⠈⠃⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⡿⠥⠐⠂⠀⠀⠀⠀⡄⠀⠰⢺⣿⣿⣿⣿⣿⣟⠀⠈⠐⢤⠀⠀⠀⠀⠀⠀⢀⣠⣶⣾⣯⠀⠀⠉⠂⠀⠠⠤⢄⣀⠙⢿⣿⣿⣿⣿ - ⣿⡿⠋⠡⠐⠈⣉⠭⠤⠤⢄⡀⠈⠀⠈⠁⠉⠁⡠⠀⠀⠀⠉⠐⠠⠔⠀⠀⠀⠀⠀⠲⣿⠿⠛⠛⠓⠒⠂⠀⠀⠀⠀⠀⠀⠠⡉⢢⠙⣿⣿⣿ - ⣿⠀⢀⠁⠀⠊⠀⠀⠀⠀⠀⠈⠁⠒⠂⠀⠒⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⣀⡠⠔⠒⠒⠂⠀⠈⠀⡇⣿⣿⣿⣿⣿ - ⣿⠀⢸⠀⠀⠀⢀⣀⡠⠋⠓⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠈⠢⠤⡀⠀⠀⠀⠀⠀⠀⢠⠀⠀⠀⡠⠀⡇⣿⣿⣿⣿⣿ - ⣿⡀⠘⠀⠀⠀⠀⠀⠘⡄⠀⠀⠀⠈⠑⡦⢄⣀⠀⠀⠐⠒⠁⢸⠀⠀⠠⠒⠄⠀⠀⠀⠀⠀⢀⠇⠀⣀⡀⠀⠀⢀⢾⡆⠀⠈⡀⠎⣸⣿⣿⣿ - ⣿⣿⣄⡈⠢⠀⠀⠀⠀⠘⣶⣄⡀⠀⠀⡇⠀⠀⠈⠉⠒⠢⡤⣀⡀⠀⠀⠀⠀⠀⠐⠦⠤⠒⠁⠀⠀⠀⠀⣀⢴⠁⠀⢷⠀⠀⠀⢰⣿⣿⣿⣿ - ⣿⣿⣿⣿⣇⠂⠀⠀⠀⠀⠈⢂⠀⠈⠹⡧⣀⠀⠀⠀⠀⠀⡇⠀⠀⠉⠉⠉⢱⠒⠒⠒⠒⢖⠒⠒⠂⠙⠏⠀⠘⡀⠀⢸⠀⠀⠀⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠑⠄⠰⠀⠀⠁⠐⠲⣤⣴⣄⡀⠀⠀⠀⠀⢸⠀⠀⠀⠀⢸⠀⠀⠀⠀⢠⠀⣠⣷⣶⣿⠀⠀⢰⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠁⢀⠀⠀⠀⠀⠀⡙⠋⠙⠓⠲⢤⣤⣷⣤⣤⣤⣤⣾⣦⣤⣤⣶⣿⣿⣿⣿⡟⢹⠀⠀⢸⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠑⠀⢄⠀⡰⠁⠀⠀⠀⠀⠀⠈⠉⠁⠈⠉⠻⠋⠉⠛⢛⠉⠉⢹⠁⢀⢇⠎⠀⠀⢸⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣀⠈⠢⢄⡉⠂⠄⡀⠀⠈⠒⠢⠄⠀⢀⣀⣀⣰⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⢀⣎⠀⠼⠊⠀⠀⠀⠘⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠉⠢⢄⡈⠑⠢⢄⡀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁⠀⠀⢀⠀⠀⠀⠀⠀⢻⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣀⡈⠑⠢⢄⡀⠈⠑⠒⠤⠄⣀⣀⠀⠉⠉⠉⠉⠀⠀⠀⣀⡀⠤⠂⠁⠀⢀⠆⠀⠀⢸⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡀⠁⠉⠒⠂⠤⠤⣀⣀⣉⡉⠉⠉⠉⠉⢀⣀⣀⡠⠤⠒⠈⠀⠀⠀⠀⣸⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿ - ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣶⣶⣤⣤⣤⣤⣀⣀⣤⣤⣤⣶⣾⣿⣿⣿⣿⣿ - */ - - const response = await fetch( - `https://api.worldoftanks.${idToRegion( - wargaming.id, - )}/wot/auth/prolongate/?application_id=${WARGAMING_APPLICATION_ID}&access_token=${ - wargaming.token - }`, - ); - const json = (await response.json()) as Extension; - - mutateApp((draft) => { - draft.logins.wargaming = { - id: wargaming.id, - token: json.data.access_token, - expires: json.data.expires_at * 1000, - }; - }); -} diff --git a/src/core/blitz/logoutPatreon.ts b/src/core/blitz/logoutPatreon.ts deleted file mode 100644 index fe7152882..000000000 --- a/src/core/blitz/logoutPatreon.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { mutateApp } from '../../stores/app'; - -export function logoutPatreon() { - mutateApp((draft) => { - draft.logins.patreon = undefined; - }); -} diff --git a/src/core/blitz/logoutWargaming.ts b/src/core/blitz/logoutWargaming.ts deleted file mode 100644 index f96421385..000000000 --- a/src/core/blitz/logoutWargaming.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { mutateApp } from '../../stores/app'; - -export function logoutWargaming() { - mutateApp((draft) => { - draft.logins.wargaming = undefined; - }); -} diff --git a/src/hooks/useAdExempt.ts b/src/hooks/useAdExempt.ts index b1d7bf49e..d06c2269b 100644 --- a/src/hooks/useAdExempt.ts +++ b/src/hooks/useAdExempt.ts @@ -1,10 +1,10 @@ import { use, useMemo } from 'react'; -import { useApp } from '../stores/app'; +import * as App from '../stores/app'; let cache: Record = {}; export function useAdExempt() { - const patreon = useApp((state) => state.logins.patreon); + const patreon = App.use((state) => state.logins.patreon); const promise = useMemo( () => new Promise(async (resolve) => { diff --git a/src/stores/app/constants.ts b/src/stores/app/constants.ts new file mode 100644 index 000000000..97c26f664 --- /dev/null +++ b/src/stores/app/constants.ts @@ -0,0 +1 @@ +export const CURRENT_POLICIES_AGREEMENT_INDEX = 0; diff --git a/src/stores/app.ts b/src/stores/app/index.ts similarity index 52% rename from src/stores/app.ts rename to src/stores/app/index.ts index f0355572b..4b5109878 100644 --- a/src/stores/app.ts +++ b/src/stores/app/index.ts @@ -1,7 +1,7 @@ -import { produce } from 'immer'; import { merge } from 'lodash'; import { create } from 'zustand'; import { persist } from 'zustand/middleware'; +import { createNextSafeStore } from '../../core/zustand/createNextSafeStore'; interface WargamingLogin { id: number; @@ -25,20 +25,17 @@ export interface App { policiesAgreementIndex: number; } -export const CURRENT_POLICIES_AGREEMENT_INDEX = 0; - -export const useApp = create()( - persist( - (set) => ({ - devBuildAgreementTime: 0, - developerMode: false, - policiesAgreementIndex: -1, - logins: {}, - }), - { name: 'app', merge: (a, b) => merge(b, a) }, - ), +export const { Provider, use, useMutation, useStore } = createNextSafeStore( + () => + create()( + persist( + (set) => ({ + devBuildAgreementTime: 0, + developerMode: false, + policiesAgreementIndex: -1, + logins: {}, + }), + { name: 'app', merge: (a, b) => merge(b, a) }, + ), + ), ); - -export function mutateApp(recipe: (draft: App) => void) { - useApp.setState(produce(recipe)); -}