Refactor app context types

This commit is contained in:
Manav Rathi 2024-05-26 17:53:49 +05:30
parent 5bbe768acb
commit 6bf6f78147
No known key found for this signature in database
5 changed files with 94 additions and 69 deletions

View file

@ -1,6 +1,7 @@
import { CustomHead } from "@/next/components/Head";
import { setupI18n } from "@/next/i18n";
import { logUnhandledErrorsAndRejections } from "@/next/log-web";
import type { AppName, BaseAppContextT } from "@/next/types/app";
import { PAGES } from "@ente/accounts/constants/pages";
import { accountLogout } from "@ente/accounts/services/logout";
import { APPS, APP_TITLES } from "@ente/shared/apps/constants";
@ -22,16 +23,15 @@ import { useRouter } from "next/router";
import { createContext, useEffect, useState } from "react";
import "styles/global.css";
interface AppContextProps {
isMobile: boolean;
showNavBar: (show: boolean) => void;
setDialogBoxAttributesV2: (attrs: DialogBoxAttributesV2) => void;
logout: () => void;
}
/** The accounts app has no extra properties on top of the base context. */
type AppContextT = BaseAppContextT;
export const AppContext = createContext<AppContextProps>({} as AppContextProps);
/** The React {@link Context} available to all pages. */
export const AppContext = createContext<AppContextT | undefined>(undefined);
export default function App({ Component, pageProps }: AppProps) {
const appName: AppName = "account";
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [showNavbar, setShowNavBar] = useState(false);
@ -83,6 +83,14 @@ export default function App({ Component, pageProps }: AppProps) {
void accountLogout().then(() => router.push(PAGES.ROOT));
};
const appContext = {
appName,
logout,
showNavBar,
isMobile,
setDialogBoxAttributesV2,
};
// TODO: This string doesn't actually exist
const title = isI18nReady
? t("title", { context: "accounts" })
@ -101,14 +109,7 @@ export default function App({ Component, pageProps }: AppProps) {
attributes={dialogBoxAttributeV2 as any}
/>
<AppContext.Provider
value={{
isMobile,
showNavBar,
setDialogBoxAttributesV2,
logout,
}}
>
<AppContext.Provider value={appContext}>
{!isI18nReady && (
<Overlay
sx={(theme) => ({

View file

@ -4,6 +4,7 @@ import {
logStartupBanner,
logUnhandledErrorsAndRejections,
} from "@/next/log-web";
import type { AppName, BaseAppContextT } from "@/next/types/app";
import { accountLogout } from "@ente/accounts/services/logout";
import {
APPS,
@ -32,21 +33,23 @@ import { createContext, useEffect, useRef, useState } from "react";
import LoadingBar, { type LoadingBarRef } from "react-top-loading-bar";
import "../../public/css/global.css";
type AppContextType = {
showNavBar: (show: boolean) => void;
/**
* Properties available via the {@link AppContext} to the Auth app's React tree.
*/
type AppContextT = BaseAppContextT & {
startLoading: () => void;
finishLoading: () => void;
isMobile: boolean;
themeColor: THEME_COLOR;
setThemeColor: (themeColor: THEME_COLOR) => void;
somethingWentWrong: () => void;
setDialogBoxAttributesV2: (attrs: DialogBoxAttributesV2) => void;
logout: () => void;
};
export const AppContext = createContext<AppContextType | undefined>(undefined);
/** The React {@link Context} available to all pages. */
export const AppContext = createContext<AppContextT | undefined>(undefined);
export default function App({ Component, pageProps }: AppProps) {
const appName: AppName = "auth";
const router = useRouter();
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
@ -131,6 +134,19 @@ export default function App({ Component, pageProps }: AppProps) {
void accountLogout().then(() => router.push(PAGES.ROOT));
};
const appContext = {
appName,
logout,
showNavBar,
isMobile,
setDialogBoxAttributesV2,
startLoading,
finishLoading,
themeColor,
setThemeColor,
somethingWentWrong,
};
// TODO: Refactor this to have a fallback
const title = isI18nReady
? t("title", { context: "auth" })
@ -156,19 +172,7 @@ export default function App({ Component, pageProps }: AppProps) {
attributes={dialogBoxAttributeV2}
/>
<AppContext.Provider
value={{
showNavBar,
startLoading,
finishLoading,
isMobile,
themeColor,
setThemeColor,
somethingWentWrong,
setDialogBoxAttributesV2,
logout,
}}
>
<AppContext.Provider value={appContext}>
{(loading || !isI18nReady) && (
<Overlay
sx={(theme) => ({

View file

@ -5,6 +5,7 @@ import {
logStartupBanner,
logUnhandledErrorsAndRejections,
} from "@/next/log-web";
import type { AppName, BaseAppContextT } from "@/next/types/app";
import { AppUpdate } from "@/next/types/ipc";
import {
APPS,
@ -74,8 +75,11 @@ const redirectMap = new Map([
[REDIRECTS.FAMILIES, getFamilyPortalRedirectURL],
]);
type AppContextType = {
showNavBar: (show: boolean) => void;
/**
* Properties available via the {@link AppContext} to the Photos app's React
* tree.
*/
type AppContextT = BaseAppContextT & {
mlSearchEnabled: boolean;
mapEnabled: boolean;
updateMlSearchEnabled: (enabled: boolean) => Promise<void>;
@ -89,19 +93,19 @@ type AppContextType = {
setWatchFolderView: (isOpen: boolean) => void;
watchFolderFiles: FileList;
setWatchFolderFiles: (files: FileList) => void;
isMobile: boolean;
themeColor: THEME_COLOR;
setThemeColor: (themeColor: THEME_COLOR) => void;
somethingWentWrong: () => void;
setDialogBoxAttributesV2: (attrs: DialogBoxAttributesV2) => void;
isCFProxyDisabled: boolean;
setIsCFProxyDisabled: (disabled: boolean) => void;
logout: () => void;
};
export const AppContext = createContext<AppContextType>(null);
/** The React {@link Context} available to all pages. */
export const AppContext = createContext<AppContextT | undefined>(undefined);
export default function App({ Component, pageProps }: AppProps) {
const appName: AppName = "photos";
const router = useRouter();
const [isI18nReady, setIsI18nReady] = useState<boolean>(false);
const [loading, setLoading] = useState(false);
@ -324,6 +328,32 @@ export default function App({ Component, pageProps }: AppProps) {
void photosLogout().then(() => router.push(PAGES.ROOT));
};
const appContext = {
appName,
showNavBar,
mlSearchEnabled,
updateMlSearchEnabled,
startLoading,
finishLoading,
closeMessageDialog,
setDialogMessage,
watchFolderView,
setWatchFolderView,
watchFolderFiles,
setWatchFolderFiles,
isMobile,
setNotificationAttributes,
themeColor,
setThemeColor,
somethingWentWrong,
setDialogBoxAttributesV2,
mapEnabled,
updateMapEnabled,
isCFProxyDisabled,
setIsCFProxyDisabled,
logout,
};
const title = isI18nReady
? t("title", { context: "photos" })
: APP_TITLES.get(APPS.PHOTOS);
@ -359,32 +389,7 @@ export default function App({ Component, pageProps }: AppProps) {
attributes={notificationAttributes}
/>
<AppContext.Provider
value={{
showNavBar,
mlSearchEnabled,
updateMlSearchEnabled,
startLoading,
finishLoading,
closeMessageDialog,
setDialogMessage,
watchFolderView,
setWatchFolderView,
watchFolderFiles,
setWatchFolderFiles,
isMobile,
setNotificationAttributes,
themeColor,
setThemeColor,
somethingWentWrong,
setDialogBoxAttributesV2,
mapEnabled,
updateMapEnabled,
isCFProxyDisabled,
setIsCFProxyDisabled,
logout,
}}
>
<AppContext.Provider value={appContext}>
{(loading || !isI18nReady) && (
<Overlay
sx={(theme) => ({

View file

@ -1,5 +1,22 @@
import type { DialogBoxAttributesV2 } from "@ente/shared/components/DialogBoxV2/types";
/**
* Arbitrary names that we used as keys for indexing various constants
* corresponding to our apps.
* corresponding to our apps that rely on this package.
*/
export type AppName = "account" | "albums" | "auth" | "photos";
/**
* Properties guaranteed to be present in the AppContext types for apps that are
* listed in {@link AppName}.
*/
export interface BaseAppContextT {
/** The unique key for the app. */
appName: AppName;
/** Perform the (possibly app specific) logout sequence. */
logout: () => void;
/** Show or hide the app's navigation bar. */
showNavBar: (show: boolean) => void;
isMobile: boolean;
setDialogBoxAttributesV2: (attrs: DialogBoxAttributesV2) => void;
}

View file

@ -1,7 +1,6 @@
import { TwoFactorType } from "@ente/accounts/constants/twofactor";
import type { DialogBoxAttributesV2 } from "@ente/shared/components/DialogBoxV2/types";
import { APPS } from "./constants";
import type { AppName } from "@/next/types/app";
export interface PageProps {
appContext: {
@ -11,6 +10,5 @@ export interface PageProps {
logout: () => void;
};
appName: APPS;
appName2?: AppName;
twoFactorType?: TwoFactorType;
}