refactor: Update progress bar component and provider

master^2
Tudor Stanciu 2024-08-16 00:52:54 +03:00
parent 8a95bd9886
commit b1fa0e1c6a
7 changed files with 165 additions and 3 deletions

View File

@ -19,6 +19,7 @@
"i18next": "^22.4.15",
"i18next-browser-languagedetector": "^7.0.1",
"i18next-http-backend": "^2.2.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -26,10 +27,12 @@
"react-lazylog": "^4.5.3",
"react-router-dom": "^6.10.0",
"react-toastify": "^9.1.3",
"react-world-flags": "^1.6.0"
"react-world-flags": "^1.6.0",
"swr": "^2.2.5"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@types/lodash": "^4.17.7",
"@types/react": "^18.2.33",
"@types/react-dom": "^18.2.14",
"@types/react-world-flags": "^1.4.5",
@ -4890,6 +4893,12 @@
"dev": true,
"peer": true
},
"node_modules/@types/lodash": {
"version": "4.17.7",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
"integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@ -6973,6 +6982,11 @@
"node": ">=0.10.0"
}
},
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
},
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@ -19483,6 +19497,18 @@
"boolbase": "~1.0.0"
}
},
"node_modules/swr": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz",
"integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==",
"dependencies": {
"client-only": "^0.0.1",
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@ -20209,6 +20235,14 @@
"requires-port": "^1.0.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -24773,6 +24807,12 @@
"dev": true,
"peer": true
},
"@types/lodash": {
"version": "4.17.7",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz",
"integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==",
"dev": true
},
"@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@ -26391,6 +26431,11 @@
}
}
},
"client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
},
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@ -35637,6 +35682,15 @@
}
}
},
"swr": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz",
"integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==",
"requires": {
"client-only": "^0.0.1",
"use-sync-external-store": "^1.2.0"
}
},
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@ -36186,6 +36240,12 @@
"requires-port": "^1.0.0"
}
},
"use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
"requires": {}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View File

@ -24,6 +24,7 @@
"i18next": "^22.4.15",
"i18next-browser-languagedetector": "^7.0.1",
"i18next-http-backend": "^2.2.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -31,10 +32,12 @@
"react-lazylog": "^4.5.3",
"react-router-dom": "^6.10.0",
"react-toastify": "^9.1.3",
"react-world-flags": "^1.6.0"
"react-world-flags": "^1.6.0",
"swr": "^2.2.5"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@types/lodash": "^4.17.7",
"@types/react": "^18.2.33",
"@types/react-dom": "^18.2.14",
"@types/react-world-flags": "^1.4.5",

View File

@ -7,6 +7,7 @@ import LightDarkToggle from "./LightDarkToggle";
import SensitiveInfoToggle from "./SensitiveInfoToggle";
import { styled } from "@mui/material/styles";
import { drawerWidth } from "./constants";
import { ProgressBar } from "units/progress";
interface AppBarProps extends MuiAppBarProps {
open?: boolean;
@ -64,7 +65,7 @@ const TopBar: React.FC<TopBarProps> = ({ open, onDrawerOpen }) => {
<ProfileButton />
</Box>
</Toolbar>
{/* <ProgressBar /> */}
<ProgressBar />
</AppBar>
);
};

View File

@ -0,0 +1,15 @@
import React from "react";
import { Box, LinearProgress } from "@mui/material";
import { useProgressBar } from "./hooks";
const ProgressBar: React.FC = () => {
const { progress } = useProgressBar();
if (!progress) return <></>;
return (
<Box sx={{ width: "100%" }}>
<LinearProgress color="secondary" />
</Box>
);
};
export default ProgressBar;

View File

@ -0,0 +1,65 @@
import { isArray } from "lodash";
import React, { createContext, useCallback, useMemo, useState } from "react";
export type ProgressBarUnit = { key: string | null; acting: boolean };
type ProgressBarContextPayload = {
progress: boolean;
actions: {
add: (key: string) => void;
remove: (key: string) => void;
observe: (unit?: ProgressBarUnit | ProgressBarUnit[]) => void;
};
};
const initialContext: ProgressBarContextPayload = {
progress: false,
actions: {
add: () => undefined,
remove: () => undefined,
observe: () => undefined
}
};
const ProgressBarContext = createContext<ProgressBarContextPayload>(initialContext);
type Props = { children: React.ReactNode };
const ProgressBarProvider: React.FC<Props> = ({ children }) => {
const [network, setNetwork] = useState<string[]>([]);
const handleAdd = useCallback((key: string) => setNetwork(prev => [...prev, key]), []);
const handleRemove = useCallback((key: string) => setNetwork(prev => prev.filter(z => z !== key)), []);
const handleObserve = useCallback(
(unit?: ProgressBarUnit | ProgressBarUnit[]) => {
const items: ProgressBarUnit[] = [];
if (unit) {
if (isArray(unit)) {
items.push(...unit);
} else {
items.push(unit);
}
}
for (const z of items) {
if (!z.key) continue;
if (z.acting) {
handleAdd(z.key);
} else {
handleRemove(z.key);
}
}
},
[handleAdd, handleRemove]
);
const progress = useMemo(() => network.length > 0, [network.length]);
const payload = useMemo(
() => ({ progress, actions: { add: handleAdd, remove: handleRemove, observe: handleObserve } }),
[progress, handleAdd, handleRemove, handleObserve]
);
return <ProgressBarContext.Provider value={payload}>{children}</ProgressBarContext.Provider>;
};
export { ProgressBarContext };
export default ProgressBarProvider;

View File

@ -0,0 +1,14 @@
import { useContext } from "react";
import { ProgressBarContext, ProgressBarUnit } from "./ProgressBarProvider";
type UseProgressBarResult = {
progress: boolean;
observe: (unit?: ProgressBarUnit | ProgressBarUnit[]) => void;
};
const useProgressBar = (): UseProgressBarResult => {
const context = useContext(ProgressBarContext);
return { progress: context.progress, observe: context.actions.observe };
};
export { useProgressBar };

View File

@ -0,0 +1,4 @@
import ProgressBarProvider from "./ProgressBarProvider";
import ProgressBar from "./ProgressBar";
export { ProgressBarProvider, ProgressBar };
export * from "./hooks";