diff --git a/package.json b/package.json index 93cc5da..d2f2808 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "country-flag-icons": "^1.5.19", "formik": "^2.4.6", "howler": "^2.2.4", + "rc-slider": "^11.1.9", "react": "^19.1.1", "react-dom": "^19.1.1", "react-modal": "^3.16.3", diff --git a/src/assets/sounds/ui/Beep.wav b/src/assets/sounds/ui/Beep.wav new file mode 100644 index 0000000..015e1f6 Binary files /dev/null and b/src/assets/sounds/ui/Beep.wav differ diff --git a/src/assets/sounds/ui/Ding.wav b/src/assets/sounds/ui/Ding.wav new file mode 100644 index 0000000..91a65a3 Binary files /dev/null and b/src/assets/sounds/ui/Ding.wav differ diff --git a/src/assets/sounds/ui/Warning.wav b/src/assets/sounds/ui/Warning.wav new file mode 100644 index 0000000..e9b946e Binary files /dev/null and b/src/assets/sounds/ui/Warning.wav differ diff --git a/src/assets/sounds/ui/readClick.wav b/src/assets/sounds/ui/readClick.wav new file mode 100644 index 0000000..3892721 Binary files /dev/null and b/src/assets/sounds/ui/readClick.wav differ diff --git a/src/assets/sounds/ui/shutter.mp3 b/src/assets/sounds/ui/shutter.mp3 new file mode 100644 index 0000000..9729d79 Binary files /dev/null and b/src/assets/sounds/ui/shutter.mp3 differ diff --git a/src/components/SettingForms/BearerType/BearerTypeFields.tsx b/src/components/SettingForms/BearerType/BearerTypeFields.tsx index b06dde3..d2207c6 100644 --- a/src/components/SettingForms/BearerType/BearerTypeFields.tsx +++ b/src/components/SettingForms/BearerType/BearerTypeFields.tsx @@ -29,11 +29,7 @@ const BearerTypeFields = () => { }; return ( - + {({ isSubmitting }) => (
@@ -60,11 +56,9 @@ const BearerTypeFields = () => {
diff --git a/src/components/SettingForms/Channel1-JSON/ChannelFields.tsx b/src/components/SettingForms/Channel1-JSON/ChannelFields.tsx index 5fe42fe..ef554b4 100644 --- a/src/components/SettingForms/Channel1-JSON/ChannelFields.tsx +++ b/src/components/SettingForms/Channel1-JSON/ChannelFields.tsx @@ -4,10 +4,7 @@ import { useEffect, useState } from "react"; import { faEyeSlash, faEye } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useCameraOutput } from "../../../hooks/useCameraOutput"; -import type { - InitialValuesForm, - InitialValuesFormErrors, -} from "../../../types/types"; +import type { InitialValuesForm, InitialValuesFormErrors } from "../../../types/types"; import { toast } from "sonner"; const ChannelFields = () => { @@ -17,10 +14,8 @@ const ChannelFields = () => { const backOfficeURL = backOfficeQuery?.data?.propBackofficeURL?.value; const username = backOfficeQuery?.data?.propUsername?.value; const password = backOfficeQuery?.data?.propPassword?.value; - const connectTimeoutSeconds = - backOfficeQuery?.data?.propConnectTimeoutSeconds?.value; - const readTimeoutSeconds = - backOfficeQuery?.data?.propReadTimeoutSeconds?.value; + const connectTimeoutSeconds = backOfficeQuery?.data?.propConnectTimeoutSeconds?.value; + const readTimeoutSeconds = backOfficeQuery?.data?.propReadTimeoutSeconds?.value; const initialValues: InitialValuesForm = { backOfficeURL: backOfficeURL ?? "", @@ -44,9 +39,7 @@ const ChannelFields = () => { return null; }; - const validateValues = ( - values: InitialValuesForm - ): InitialValuesFormErrors => { + const validateValues = (values: InitialValuesForm): InitialValuesFormErrors => { const errors: InitialValuesFormErrors = {}; const url = values.backOfficeURL?.trim(); @@ -78,12 +71,7 @@ const ChannelFields = () => { }; return ( - + {({ errors, touched, isSubmitting }) => (
@@ -98,9 +86,7 @@ const ChannelFields = () => { id="backoffice" placeholder="https://www.backoffice.com" className={`p-1.5 border ${ - errors.backOfficeURL && touched.backOfficeURL - ? "border-red-500" - : "border-gray-400 " + errors.backOfficeURL && touched.backOfficeURL ? "border-red-500" : "border-gray-400 " } rounded-lg w-full md:w-60`} /> @@ -112,9 +98,7 @@ const ChannelFields = () => { id="username" placeholder="Back office username" className={`p-1.5 border ${ - errors.username && touched.username - ? "border-red-500" - : "border-gray-400 " + errors.username && touched.username ? "border-red-500" : "border-gray-400 " } rounded-lg w-full md:w-60`} /> @@ -127,9 +111,7 @@ const ChannelFields = () => { id="password" placeholder="Back office password" className={`p-1.5 border ${ - errors.password && touched.password - ? "border-red-500" - : "border-gray-400 " + errors.password && touched.password ? "border-red-500" : "border-gray-400 " } rounded-lg w-full md:w-60`} /> { - + @@ -164,20 +142,16 @@ const ChannelFields = () => { id="readTimeoutSeconds" placeholder="https://example.com" className={`p-1.5 border ${ - errors.readTimeoutSeconds && touched.readTimeoutSeconds - ? "border-red-500" - : "border-gray-400 " + errors.readTimeoutSeconds && touched.readTimeoutSeconds ? "border-red-500" : "border-gray-400 " } rounded-lg w-full md:w-60`} />
diff --git a/src/components/SettingForms/NPED/NPEDHotlist.tsx b/src/components/SettingForms/NPED/NPEDHotlist.tsx index 003a398..b33421f 100644 --- a/src/components/SettingForms/NPED/NPEDHotlist.tsx +++ b/src/components/SettingForms/NPED/NPEDHotlist.tsx @@ -31,7 +31,7 @@ const NPEDHotlist = () => { type="file" name="file" id="file" - className="file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5" + className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5" onChange={(e) => { if (e.target.files) { if (e.target.files[0].type !== "text/csv") { diff --git a/src/components/SettingForms/Sound/SoundSettingsCard.tsx b/src/components/SettingForms/Sound/SoundSettingsCard.tsx index e2b904c..b4d0e1a 100644 --- a/src/components/SettingForms/Sound/SoundSettingsCard.tsx +++ b/src/components/SettingForms/Sound/SoundSettingsCard.tsx @@ -4,7 +4,7 @@ import SoundSettingsFields from "./SoundSettingsFields"; const SoundSettingsCard = () => { return ( - + diff --git a/src/components/SettingForms/Sound/SoundSettingsFields.tsx b/src/components/SettingForms/Sound/SoundSettingsFields.tsx index 3cc4d6f..b46b7fc 100644 --- a/src/components/SettingForms/Sound/SoundSettingsFields.tsx +++ b/src/components/SettingForms/Sound/SoundSettingsFields.tsx @@ -4,6 +4,7 @@ import type { FormValues, Hotlist } from "../../../types/types"; import { useSoundContext } from "../../../context/SoundContext"; import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard"; import { toast } from "sonner"; +import SliderComponent from "../../UI/Slider"; const SoundSettingsFields = () => { const { state, dispatch } = useSoundContext(); @@ -12,7 +13,7 @@ const SoundSettingsFields = () => { const hotlists: Hotlist[] = state.hotlists; const soundOptions = state?.soundOptions?.map((soundOption) => ({ - value: soundOption?.name, + value: soundOption?.soundFile, label: soundOption?.name, })); @@ -23,11 +24,17 @@ const SoundSettingsFields = () => { }; const handleSubmit = async (values: FormValues) => { - dispatch({ type: "UPDATE", payload: values }); + const updatedValues = { + ...values, + sightingVolume: state.sightingVolume, + NPEDsoundVolume: state.NPEDsoundVolume, + }; + + dispatch({ type: "UPDATE", payload: updatedValues }); const result = await mutation.mutateAsync({ operation: "INSERT", path: "soundSettings", - value: values, + value: updatedValues, }); if (result.reason !== "OK") { toast.error("Cannot update sound settings"); @@ -40,34 +47,40 @@ const SoundSettingsFields = () => { {({ values }) => (
- - - {soundOptions?.map(({ value, label }) => { - return ( +
+ + + {soundOptions?.map(({ value, label }) => { + return ( + + ); + })} + + +
+
+ +
+ + + {soundOptions?.map(({ value, label }) => ( - ); - })} - - - - - - {soundOptions?.map(({ value, label }) => ( - - ))} - + ))} + + +

Hotlist Sounds

@@ -78,14 +91,8 @@ const SoundSettingsFields = () => {
{values?.hotlists?.length > 0 ? ( values?.hotlists?.map((hotlist, index) => ( -
-
@@ -157,18 +157,26 @@ const SightingModal = ({ isSightingModalOpen, handleClose, sighting, onDelete }:
{sighting?.seenCount ?? "-"}
-
-
Make
-
{sighting?.make ?? "-"}
-
-
-
Model
-
{sighting?.model ?? "-"}
-
-
-
Colour
-
{sighting?.color ?? "-"}
-
+ {sighting?.make && ( +
+
Make
+
{sighting?.make ?? "-"}
+
+ )} + {sighting?.model || + (!sighting?.model.trim() && ( +
+
Model
+
{sighting?.model ?? "-"}
+
+ ))} + {sighting?.color && ( +
+
Colour
+
{sighting?.color ?? "-"}
+
+ )} +
Time
{sighting?.timeStamp ?? "-"}
@@ -192,7 +200,7 @@ const SightingModal = ({ isSightingModalOpen, handleClose, sighting, onDelete }: onClick={handleAcknowledgeButton} > - Accept + Acknowledge )} {onDelete ? ( diff --git a/src/components/SightingsWidget/SightingWidget.tsx b/src/components/SightingsWidget/SightingWidget.tsx index 731166d..0d6bb2d 100644 --- a/src/components/SightingsWidget/SightingWidget.tsx +++ b/src/components/SightingsWidget/SightingWidget.tsx @@ -38,10 +38,7 @@ type SightingHistoryProps = { className?: string; }; -export default function SightingHistoryWidget({ - className, - title, -}: SightingHistoryProps) { +export default function SightingHistoryWidget({ className, title }: SightingHistoryProps) { useNow(1000); const { state } = useSoundContext(); @@ -53,7 +50,7 @@ export default function SightingHistoryWidget({ return getSoundFileURL(state?.hotlists?.[0]?.sound) ?? notification; }, [state.hotlists]); - const { play: npedSound } = useSound(soundSrcNped); + const { play: npedSound } = useSound(soundSrcNped, { volume: state.NPEDsoundVolume }); const { play: hotlistsound } = useSound(soundSrcHotlist); const { sightings, @@ -98,10 +95,7 @@ export default function SightingHistoryWidget({ [setSelectedSighting, setSightingModalOpen] ); - const rows = useMemo( - () => sightings?.filter(Boolean) as SightingType[], - [sightings] - ); + const rows = useMemo(() => sightings?.filter(Boolean) as SightingType[], [sightings]); useEffect(() => { if (!rows?.length) return; @@ -129,13 +123,7 @@ export default function SightingHistoryWidget({ break; } } - }, [ - rows, - hotlistsound, - npedSound, - setSightingModalOpen, - setSelectedSighting, - ]); + }, [rows, hotlistsound, npedSound, setSightingModalOpen, setSelectedSighting]); useEffect(() => { rows?.forEach((obj) => { @@ -187,12 +175,7 @@ export default function SightingHistoryWidget({ }; return ( <> - +
{isLoading && ( @@ -215,45 +198,16 @@ export default function SightingHistoryWidget({ className={`border border-gray-700 rounded-md mb-2 p-2 cursor-pointer `} onClick={() => onRowClick(obj)} > -
+
- colour patch + colour patch
{isHotListHit && ( - hotlistHit - )} - {isNPEDHitA && ( - hotlistHit - )} - {isNPEDHitB && ( - hotlistHit - )} - {isNPEDHitC && ( - hotlistHit + hotlistHit )} + {isNPEDHitA && hotlistHit} + {isNPEDHitB && hotlistHit} + {isNPEDHitC && hotlistHit}
@@ -262,11 +216,7 @@ export default function SightingHistoryWidget({
- + ); } diff --git a/src/components/UI/ModalComponent.tsx b/src/components/UI/ModalComponent.tsx index fd0e759..2910484 100644 --- a/src/components/UI/ModalComponent.tsx +++ b/src/components/UI/ModalComponent.tsx @@ -7,16 +7,12 @@ type ModalComponentProps = { close: () => void; }; -const ModalComponent = ({ - isModalOpen, - children, - close, -}: ModalComponentProps) => { +const ModalComponent = ({ isModalOpen, children, close }: ModalComponentProps) => { return ( {children} diff --git a/src/components/UI/NavigationArrow.tsx b/src/components/UI/NavigationArrow.tsx index 3e2c701..e133a88 100644 --- a/src/components/UI/NavigationArrow.tsx +++ b/src/components/UI/NavigationArrow.tsx @@ -11,7 +11,6 @@ const NavigationArrow = ({ side, settingsPage }: NavigationArrowProps) => { const navigate = useNavigate(); const navigationDest = (side: string | undefined) => { - console.log(side); if (settingsPage) { navigate("/"); return; diff --git a/src/components/UI/Slider.tsx b/src/components/UI/Slider.tsx new file mode 100644 index 0000000..39cdce7 --- /dev/null +++ b/src/components/UI/Slider.tsx @@ -0,0 +1,47 @@ +import "rc-slider/assets/index.css"; +import Slider from "rc-slider"; +import { useSoundContext } from "../../context/SoundContext"; + +const SliderComponent = ({ soundCategory }: { soundCategory: "SIGHTINGVOLUME" | "NPEDVOLUME" | "HOTLISTVOLUME" }) => { + const { dispatch, state } = useSoundContext(); + const volume = soundCategory === "SIGHTINGVOLUME" ? state.sightingVolume : state.NPEDsoundVolume; + + const handleChange = (value: number | number[]) => { + const number = typeof value === "number" ? value : value[0]; + dispatch({ type: soundCategory, payload: number }); + }; + + return ( +
+ + {volume * 10} +
+ ); +}; + +export default SliderComponent; diff --git a/src/context/SoundContext.ts b/src/context/SoundContext.ts index 9c5fac2..b48ad68 100644 --- a/src/context/SoundContext.ts +++ b/src/context/SoundContext.ts @@ -7,13 +7,10 @@ type SoundContextType = { audioArmed: boolean; }; -export const SoundContext = createContext( - undefined -); +export const SoundContext = createContext(undefined); export const useSoundContext = () => { const ctx = useContext(SoundContext); - if (!ctx) - throw new Error("useSoundContext must be used within "); + if (!ctx) throw new Error("useSoundContext must be used within "); return ctx; }; diff --git a/src/context/providers/SoundContextProvider.tsx b/src/context/providers/SoundContextProvider.tsx index 7eed5ee..8f7fa57 100644 --- a/src/context/providers/SoundContextProvider.tsx +++ b/src/context/providers/SoundContextProvider.tsx @@ -1,11 +1,4 @@ -import { - useEffect, - useMemo, - useReducer, - useRef, - useState, - type ReactNode, -} from "react"; +import { useEffect, useMemo, useReducer, useRef, useState, type ReactNode } from "react"; import { SoundContext } from "../SoundContext"; import { initialState, reducer } from "../reducers/SoundContextReducer"; import { useCameraBlackboard } from "../../hooks/useCameraBlackboard"; @@ -27,7 +20,7 @@ const SoundContextProvider = ({ children }: SoundContextProviderProps) => { operation: "VIEW", path: "soundSettings", }); - + console.log(result.result); dispatch({ type: "UPDATE", payload: result.result }); }; fetchSound(); @@ -63,13 +56,8 @@ const SoundContextProvider = ({ children }: SoundContextProviderProps) => { }; }, []); - const value = useMemo( - () => ({ state, dispatch, audioArmed }), - [state, audioArmed] - ); - return ( - {children} - ); + const value = useMemo(() => ({ state, dispatch, audioArmed }), [state, audioArmed]); + return {children}; }; export default SoundContextProvider; diff --git a/src/context/reducers/SoundContextReducer.ts b/src/context/reducers/SoundContextReducer.ts index 6250239..791c400 100644 --- a/src/context/reducers/SoundContextReducer.ts +++ b/src/context/reducers/SoundContextReducer.ts @@ -5,10 +5,17 @@ export const initialState: SoundState = { NPEDsound: "popup", hotlists: [{ name: "hotlistName", sound: "notification" }], soundOptions: [ - { name: "switch (Default)", soundFile: null }, - { name: "popup", soundFile: null }, - { name: "notification", soundFile: null }, + { name: "Switch (Default)", soundFile: "switch" }, + { name: "Popup", soundFile: "popup" }, + { name: "Notification", soundFile: "notification" }, + { name: "Beep", soundFile: "beep" }, + { name: "Ding", soundFile: "ding" }, + { name: "Shutter", soundFile: "shutter" }, + { name: "Warning (voice)", soundFile: "warning" }, ], + sightingVolume: 1, + NPEDsoundVolume: 1, + hotlistSoundVolume: 1, }; export function reducer(state: SoundState, action: SoundAction): SoundState { @@ -22,6 +29,8 @@ export function reducer(state: SoundState, action: SoundAction): SoundState { name: hotlist.name, sound: hotlist.sound, })), + NPEDsoundVolume: action.payload.NPEDsoundVolume, + sightingVolume: action.payload.sightingVolume, }; } @@ -31,6 +40,18 @@ export function reducer(state: SoundState, action: SoundAction): SoundState { soundOptions: [...(state.soundOptions ?? []), action.payload], }; } + // todo: refactor to use single state coupled with sound name. e.g : {name: , volume: } + case "SIGHTINGVOLUME": + return { + ...state, + sightingVolume: action.payload, + }; + + case "NPEDVOLUME": + return { + ...state, + NPEDsoundVolume: action.payload, + }; default: return state; diff --git a/src/hooks/useSightingFeed.ts b/src/hooks/useSightingFeed.ts index 35b7f44..d9a386d 100644 --- a/src/hooks/useSightingFeed.ts +++ b/src/hooks/useSightingFeed.ts @@ -75,8 +75,9 @@ export function useSightingFeed(url: string | undefined) { }); //use latestref instead of trigger to revert back + useSoundOnChange(soundSrc, trigger, { - volume: 1, + volume: state.sightingVolume, initial: false, }); diff --git a/src/pages/SystemSettings.tsx b/src/pages/SystemSettings.tsx index 138070c..0d38273 100644 --- a/src/pages/SystemSettings.tsx +++ b/src/pages/SystemSettings.tsx @@ -47,7 +47,7 @@ const SystemSettings = () => {
-
+
diff --git a/src/types/types.ts b/src/types/types.ts index 8d35242..2bfd7b7 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -43,9 +43,7 @@ export type CameraSettingValues = { id: number | string; }; -export type CameraSettingErrorValues = Partial< - Record ->; +export type CameraSettingErrorValues = Partial>; export type BearerTypeFieldType = { format: string; @@ -299,6 +297,9 @@ export type SoundState = { NPEDsound: SoundValue; hotlists: Hotlist[]; soundOptions?: SoundUploadValue[]; + sightingVolume: number; + NPEDsoundVolume: number; + hotlistSoundVolume: number; }; type UpdateAction = { @@ -307,6 +308,9 @@ type UpdateAction = { sightingSound: SoundValue; NPEDsound: SoundValue; hotlists: Hotlist[]; + sightingVolume: number; + NPEDsoundVolume: number; + hotlistSoundVolume?: number; }; }; @@ -315,7 +319,12 @@ type AddAction = { payload: SoundUploadValue; }; -export type SoundAction = UpdateAction | AddAction; +type VolumeAction = { + type: "SIGHTINGVOLUME" | "NPEDVOLUME" | "HOTLISTVOLUME"; + payload: number; +}; + +export type SoundAction = UpdateAction | AddAction | VolumeAction; export type WifiSettingValues = { ssid: string; password: string; diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 65a4fc8..78c7b30 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,6 +1,11 @@ import switchSound from "../assets/sounds/ui/switch.mp3"; import popup from "../assets/sounds/ui/popup_open.mp3"; import notification from "../assets/sounds/ui/notification.mp3"; +import beep from "../assets/sounds/ui/Beep.wav"; +import warning from "../assets/sounds/ui/Warning.wav"; +import ding from "../assets/sounds/ui/Ding.wav"; +import shutter from "../assets/sounds/ui/shutter.mp3"; + import type { HotlistMatches, SightingType } from "../types/types"; export function getSoundFileURL(name: string) { @@ -8,6 +13,10 @@ export function getSoundFileURL(name: string) { switch: switchSound, popup: popup, notification: notification, + beep: beep, + warning: warning, + ding: ding, + shutter: shutter, }; return sounds[name] ?? null; } diff --git a/yarn.lock b/yarn.lock index 76c7760..db3053e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -138,7 +138,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/runtime@^7.1.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.18.3": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== @@ -1044,6 +1044,11 @@ chownr@^3.0.0: resolved "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz" integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== +classnames@^2.2.5: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== + clsx@^2.0.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" @@ -1875,6 +1880,23 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +rc-slider@^11.1.9: + version "11.1.9" + resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-11.1.9.tgz#d872130fbf4ec51f28543d62e90451091d6f5208" + integrity sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.5" + rc-util "^5.36.0" + +rc-util@^5.36.0: + version "5.44.4" + resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.44.4.tgz#89ee9037683cca01cd60f1a6bbda761457dd6ba5" + integrity sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w== + dependencies: + "@babel/runtime" "^7.18.3" + react-is "^18.2.0" + react-dom@^19.1.1: version "19.1.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz" @@ -1892,6 +1914,11 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + react-lifecycles-compat@^3.0.0: version "3.0.4" resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"