Skip to content

Commit

Permalink
feat: check IndexedDB support (#1630)
Browse files Browse the repository at this point in the history
* check indexed db support and display message

* fix typo
  • Loading branch information
ajbura authored Jan 23, 2024
1 parent ef2733d commit 983d533
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 14 deletions.
31 changes: 17 additions & 14 deletions src/app/pages/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { isAuthenticated } from '../../client/state/auth';
import Client from '../templates/client/Client';
import { getLoginPath } from './pathUtils';
import { ConfigConfigError, ConfigConfigLoading } from './ConfigConfig';
import { FeatureCheck } from './FeatureCheck';

const createRouter = (clientConfig: ClientConfig) => {
const { hashRouter } = clientConfig;
Expand Down Expand Up @@ -62,20 +63,22 @@ const createRouter = (clientConfig: ClientConfig) => {
// TODO: app crash boundary
function App() {
return (
<ClientConfigLoader
fallback={() => <ConfigConfigLoading />}
error={(err, retry, ignore) => (
<ConfigConfigError error={err} retry={retry} ignore={ignore} />
)}
>
{(clientConfig) => (
<ClientConfigProvider value={clientConfig}>
<JotaiProvider>
<RouterProvider router={createRouter(clientConfig)} />
</JotaiProvider>
</ClientConfigProvider>
)}
</ClientConfigLoader>
<FeatureCheck>
<ClientConfigLoader
fallback={() => <ConfigConfigLoading />}
error={(err, retry, ignore) => (
<ConfigConfigError error={err} retry={retry} ignore={ignore} />
)}
>
{(clientConfig) => (
<ClientConfigProvider value={clientConfig}>
<JotaiProvider>
<RouterProvider router={createRouter(clientConfig)} />
</JotaiProvider>
</ClientConfigProvider>
)}
</ClientConfigLoader>
</FeatureCheck>
);
}

Expand Down
42 changes: 42 additions & 0 deletions src/app/pages/FeatureCheck.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { ReactNode, useEffect } from 'react';
import { Box, Dialog, Text, config } from 'folds';
import { AsyncStatus, useAsyncCallback } from '../hooks/useAsyncCallback';
import { checkIndexedDBSupport } from '../utils/featureCheck';
import { SplashScreen } from '../components/splash-screen';

export function FeatureCheck({ children }: { children: ReactNode }) {
const [idbSupportState, checkIDBSupport] = useAsyncCallback(checkIndexedDBSupport);

useEffect(() => {
checkIDBSupport();
}, [checkIDBSupport]);

if (idbSupportState.status === AsyncStatus.Success && idbSupportState.data === false) {
return (
<SplashScreen>
<Box grow="Yes" alignItems="Center" justifyContent="Center">
<Dialog>
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
<Text>Missing Browser Feature</Text>
<Text size="T300" priority="400">
No IndexedDB support found. This application requires IndexedDB to store session
data locally. Please make sure your browser support IndexedDB and have it enabled.
</Text>
<Text size="T200">
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API"
rel="noreferrer noopener"
target="_blank"
>
What is IndexedDB?
</a>
</Text>
</Box>
</Dialog>
</Box>
</SplashScreen>
);
}

return children;
}
21 changes: 21 additions & 0 deletions src/app/utils/featureCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const checkIndexedDBSupport = async (): Promise<boolean> => {
const ts = new Date().getTime();
const dbName = `checkIndexedDBSupport-${ts}`;
return new Promise((resolve) => {
let db;
try {
db = indexedDB.open(dbName);
} catch {
resolve(false);
return;
}
db.onsuccess = () => {
resolve(true);
indexedDB.deleteDatabase(dbName);
};
db.onerror = () => {
resolve(false);
indexedDB.deleteDatabase(dbName);
};
});
};

0 comments on commit 983d533

Please sign in to comment.