Skip to content

Commit

Permalink
chore(deps): Update dependencies.
Browse files Browse the repository at this point in the history
  • Loading branch information
darkobits committed Mar 27, 2024
1 parent 8ca4f75 commit 07fe119
Show file tree
Hide file tree
Showing 11 changed files with 3,548 additions and 2,306 deletions.
5,603 changes: 3,407 additions & 2,196 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,32 @@
"@fontsource/montserrat": "^5.0.17",
"@popperjs/core": "^2.11.8",
"@signalstickers/stickers-client": "^2.0.0",
"axios": "^1.6.7",
"axios": "^1.6.8",
"bootstrap": "^5.3.3",
"bytes": "^3.1.2",
"classnames": "^2.5.1",
"debounce-fn": "^4.0.0",
"debounce-fn": "^6.0.0",
"formik": "^2.4.5",
"fuse.js": "^6.4.6",
"fuse.js": "^7.0.0",
"image-type": "^4.1.0",
"localforage": "^1.10.0",
"modernizr": "^3.13.0",
"p-queue": "^6.6.2",
"p-wait-for": "^3.2.0",
"p-queue": "^8.0.1",
"p-wait-for": "^5.0.2",
"polished": "^4.3.1",
"query-string": "^6.13.8",
"query-string": "^9.0.0",
"ramda": "^0.29.1",
"react-icons": "^5.0.1",
"react-linkify": "^1.0.0-alpha",
"react-router-dom": "^5.2.0",
"react-router-dom": "^5.3.4",
"react-router-hash-link": "^2.4.3",
"react-syntax-highlighter": "^15.5.0",
"react-waypoint": "^10.3.0",
"use-async-effect": "^2.2.7",
"use-breakpoint": "^1.1.5",
"webp-hero": "0.0.2"
},
"devDependencies": {
"@darkobits/tsx": "^0.12.12",
"@darkobits/tsx": "^0.12.13",
"@darkobits/vite-plugin-favicons": "^0.3.2",
"@types/bootstrap": "^5.2.10",
"@types/bytes": "^3.1.4",
Expand All @@ -69,6 +68,7 @@
"@types/react-linkify": "^1.0.4",
"@types/react-router-dom": "^5.3.3",
"@types/react-router-hash-link": "^2.4.9",
"@types/react-syntax-highlighter": "^13.5.0"
"@types/react-syntax-highlighter": "^15.5.11",
"rollup-plugin-visualizer": "^5.12.0"
}
}
38 changes: 34 additions & 4 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import React from 'react';
import { IconContext } from 'react-icons';
import { BrowserRouter as Router } from 'react-router-dom';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

import AppLayout from 'components/layout/AppLayout';
import { Provider as AppStateContextProvider } from 'contexts/AppStateContext';
import { Provider as StickersContextProvider } from 'contexts/StickersContext';
import { sendHomeBeacon } from 'lib/utils';


// Note: Each top-level route should be imported az a lazy-loaded component.
const Home = React.lazy(async () => import('components/home/Home'));
const Pack = React.lazy(async () => import('components/pack/StickerPackDetail'));
const Contribute = React.lazy(async () => import('components/contribute/Contribute'));
const ContributionStatus = React.lazy(async () => import('components/contributionstatus/ContributionStatus'));
const About = React.lazy(async () => import('components/about/About'));
const Report = React.lazy(async () => import('components/report/Report'));


export default function App() {
sendHomeBeacon();

Expand All @@ -26,9 +35,30 @@ export default function App() {
>
<AppStateContextProvider>
<StickersContextProvider>
<Router>
<AppLayout />
</Router>
<BrowserRouter>
<AppLayout>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/pack/:packId/report">
<Report />
</Route>
<Route path="/pack/:packId">
<Pack />
</Route>
<Route path="/contribute">
<Contribute />
</Route>
<Route path="/contribution-status">
<ContributionStatus />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
</AppLayout>
</BrowserRouter>
</StickersContextProvider>
</AppStateContextProvider>
</IconContext.Provider>
Expand Down
48 changes: 2 additions & 46 deletions src/components/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,12 @@
import React from 'react';
import { Switch, Route } from 'react-router-dom';

import Navbar from 'components/layout/Navbar';
import SuspenseFallback from 'components/layout/SuspenseFallback';
import AppStateContext from 'contexts/AppStateContext';


// Note: Each top-level route should be imported az a lazy-loaded component.
const Home = React.lazy(async () => import('components/home/Home'));
const Pack = React.lazy(async () => import('components/pack/StickerPackDetail'));
const Contribute = React.lazy(async () => import('components/contribute/Contribute'));
const ContributionStatus = React.lazy(async () => import('components/contributionstatus/ContributionStatus'));
const About = React.lazy(async () => import('components/about/About'));
const Report = React.lazy(async () => import('components/report/Report'));


export default function AppLayout() {
const { useAppState } = React.useContext(AppStateContext);
const [darkMode] = useAppState<boolean>('darkMode');
export default function AppLayout({ children }: React.PropsWithChildren) {
const contentRef = React.createRef<HTMLDivElement>();


/**
* Adds or removes a data attribute to the <html> element to enable or disable
* dark mode.
*/
React.useEffect(() => {
const htmlEl = document.querySelector('html');
if (!htmlEl) return;
htmlEl.dataset.bsTheme = darkMode ? 'dark' : 'light';
}, [darkMode]);


return (<>
<Navbar />
<div
Expand All @@ -42,26 +17,7 @@ export default function AppLayout() {
>
<div className="container d-flex flex-column flex-grow-1 px-3">
<React.Suspense fallback={<SuspenseFallback />}>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/pack/:packId/report">
<Report />
</Route>
<Route path="/pack/:packId">
<Pack />
</Route>
<Route path="/contribute">
<Contribute />
</Route>
<Route path="/contribution-status">
<ContributionStatus />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
{children}
</React.Suspense>
</div>
</div>
Expand Down
7 changes: 6 additions & 1 deletion src/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,12 @@ export default function Nav() {
// unsafe area with the navbar's background color.
style={{ paddingTop: 'calc(env(safe-area-inset-top, 0px) + var(--bs-navbar-padding-y))' }}
>
<div className="container ps-3">
<div
className={cx(
'ps-3',
IS_STANDALONE ? 'container-fluid' : 'container'
)}
>
{/* Brand / Home Link */}
<Link
to="/"
Expand Down
26 changes: 17 additions & 9 deletions src/contexts/AppStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,31 @@ export function Provider(props: React.PropsWithChildren<Record<string, unknown>>


const useAppState = React.useCallback<AppStateContext['useAppState']>((key: string) => {
const setState = (value: any) => {
dispatch({ key, value });
};

const setState = (value: any) => void dispatch({ key, value });
return [state[key], setState];
}, [state, dispatch]);


const toggleAppState = React.useCallback<AppStateContext['toggleAppState']>((key: string) => {
const setState = () => {
dispatch({ key, value: !state[key] });
};

return [state[key], setState];
const toggleState = () => void dispatch({ key, value: !state[key] });
return [state[key], toggleState];
}, [state, dispatch]);


const [darkMode] = useAppState<boolean>('darkMode');


/**
* Adds or removes a data attribute to the <html> element to enable or disable
* dark mode.
*/
React.useEffect(() => {
const htmlEl = document.querySelector('html');
if (!htmlEl) return;
htmlEl.dataset.bsTheme = darkMode ? 'dark' : 'light';
}, [darkMode]);


return (
<Context.Provider
value={{
Expand Down
1 change: 1 addition & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
<!-- Resource Hints -->
<link rel="preconnect" href="https://cdn-ca.signal.org" crossorigin="anonymous">
<link rel="preconnect" href="https://api.signalstickers.org">
<!-- End Resource Hints -->
</head>
<body class="safe-area-padding">
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
58 changes: 25 additions & 33 deletions src/lib/convert-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,28 @@ let converter: Promise<WebpMachine> | undefined;
* import/instantiate it once.
*/
async function importWebpHero() {
if (!converter) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
converter = new Promise(async resolve => {
const modules = await Promise.all([
import(
/* webpackChunkName: "webp-hero" */
'webp-hero/libwebp/dist/webp.js'
),
import(
/* webpackChunkName: "webp-hero-machine" */
'webp-hero/dist/webp-machine'
)
]);

const {Webp} = modules[0];
const {WebpMachine, defaultDetectWebpImage} = modules[1];

// One of Webp Hero's dependencies seems to block user input when a
// conversion is run. This fix can be found here:
// See: https://github.com/chase-moskal/webp-hero/issues/18#issuecomment-560188272
const webp = new Webp();
webp.Module.doNotCaptureKeyboard = true;

resolve(new WebpMachine({
webp,
webpSupport: detectWebpSupport(),
detectWebpImage: defaultDetectWebpImage
}));
const initWebPMachine = async () => {
const modules = await Promise.all([
import('webp-hero/libwebp/dist/webp.js'),
import('webp-hero/dist/webp-machine')
]);

const { Webp } = modules[0];
const { WebpMachine } = modules[1];

// One of Webp Hero's dependencies seems to block user input when a
// conversion is run. This fix can be found here:
// See: https://github.com/chase-moskal/webp-hero/issues/18#issuecomment-560188272
const webp = new Webp();
webp.Module.doNotCaptureKeyboard = true;

return new WebpMachine({
webp,
webpSupport: detectWebpSupport()
});
}
};

if (!converter) converter = initWebPMachine();
return converter;
}

Expand All @@ -73,7 +64,7 @@ const hasWebpSupportPromise = detectWebpSupport();
* Module-local asynchronous queue facility that will allow us to limit the
* number of concurrent image conversion operations.
*/
const imageConversionQueue = new pQueue({concurrency: 1});
const imageConversionQueue = new pQueue({ concurrency: 1 });


// ----- Functions -------------------------------------------------------------
Expand All @@ -82,8 +73,7 @@ const imageConversionQueue = new pQueue({concurrency: 1});
* Provided a UInt8Array or Buffer containing image data, returns the image's
* MIME type.
*/
// eslint-disable-next-line no-undef
function getImageMimeType(rawImageData: Uint8Array | Buffer): string {
function getImageMimeType(rawImageData: Uint8Array) {
const typeInfo = imageType(rawImageData);

if (!typeInfo) {
Expand Down Expand Up @@ -124,7 +114,7 @@ export async function convertImage(rawImageData: Uint8Array) {
// user's machine, but is the only way we can display these images at this
// time.
if (mimeType === 'image/webp' && !hasWebpSupport) {
return imageConversionQueue.add(async () => {
return imageConversionQueue.add<string>(async () => {
try {
const converter = await importWebpHero();
// @ts-expect-error (`busy` is not an exposed member of WebpMachine.)
Expand All @@ -134,6 +124,8 @@ export async function convertImage(rawImageData: Uint8Array) {
console.error(`[convertImage] Image conversion failed: ${err.message}`);
throw err;
}
}, {
throwOnTimeout: true
});
}

Expand Down
14 changes: 9 additions & 5 deletions src/lib/search/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@
*
* See: https://fusejs.io/
*/
import Fuse from 'fuse.js';
import Fuse, {
type Expression,
type FuseResult,
type FuseOptionKeyObject
} from 'fuse.js';
import * as R from 'ramda';


Expand All @@ -42,7 +46,7 @@ import * as R from 'ramda';
* See: https://www.fusejs.io/api/query.html#and
*/
interface AndExpression {
$and: Array<Fuse.Expression>;
$and: Array<Expression>;
}


Expand All @@ -61,7 +65,7 @@ export interface QueryObject {
* Utility type that, provided the member type of a collection, represents a
* collection of search results.
*/
export type SearchResults<T> = Array<Fuse.FuseResult<T>>;
export type SearchResults<T> = Array<FuseResult<T>>;


/**
Expand Down Expand Up @@ -89,7 +93,7 @@ export interface SearchFactoryOptions<T> {
*
* See: https://fusejs.io/examples.html#nested-search
*/
keys: Array<Fuse.FuseOptionKeyObject<T>>;
keys: Array<FuseOptionKeyObject<T>>;
}


Expand Down Expand Up @@ -227,7 +231,7 @@ export default function SearchFactory<T>(options: SearchFactoryOptions<T>): Sear
// Filter-out results with a score above MAX_SCORE.
R.filter(R.compose(R.gte(MAX_SCORE), R.propOr(undefined, 'score'))),
// De-dupe results by calling the configured identity callback.
R.uniqBy<Fuse.FuseResult<T>, any>(result => options.identity(result.item))
R.uniqBy<FuseResult<T>, any>(result => options.identity(result.item))
)(results);
};

Expand Down
1 change: 0 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"jquery",
"node",
"vite/client",
// "unplugin-icons/types/react",
"vite-plugin-svgr/client"
]
}
Expand Down
Loading

0 comments on commit 07fe119

Please sign in to comment.