decent simple config

This commit is contained in:
talksik
2022-05-12 17:32:47 -05:00
parent f7646c4350
commit dad50345a6
4 changed files with 105 additions and 129 deletions
+7 -2
View File
@@ -11,7 +11,12 @@
"plugin:import/recommended", "plugin:import/recommended",
"plugin:import/electron", "plugin:import/electron",
"plugin:import/typescript", "plugin:import/typescript",
"plugin:reac/recommended" "plugin:react/recommended",
"plugin:react-hooks/recommended"
], ],
"parser": "@typescript-eslint/parser" "parser": "@typescript-eslint/parser",
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
} }
+3 -1
View File
@@ -82,6 +82,8 @@
"electron": "17.1.2", "electron": "17.1.2",
"eslint": "^8.0.1", "eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.0", "eslint-plugin-import": "^2.25.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.5.0",
"fork-ts-checker-webpack-plugin": "^6.0.1", "fork-ts-checker-webpack-plugin": "^6.0.1",
"mini-css-extract-plugin": "^2.6.0", "mini-css-extract-plugin": "^2.6.0",
"node-loader": "^2.0.0", "node-loader": "^2.0.0",
@@ -98,8 +100,8 @@
}, },
"dependencies": { "dependencies": {
"@getstation/electron-google-oauth2": "^2.1.0", "@getstation/electron-google-oauth2": "^2.1.0",
"@nirvana/core": "*",
"@nirvana/components": "*", "@nirvana/components": "*",
"@nirvana/core": "*",
"antd": "^4.20.2", "antd": "^4.20.2",
"axios": "^0.26.1", "axios": "^0.26.1",
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
+70 -126
View File
@@ -1,29 +1,25 @@
import { $desktopMode, $selectedLineId } from "../../controller/recoil"; import { $desktopMode, $selectedLineId } from '../../controller/recoil';
import { Avatar, Skeleton, Tooltip } from "antd"; import { Avatar, Skeleton, Tooltip } from 'antd';
import { FiActivity, FiHeadphones, FiSettings, FiSun } from "react-icons/fi"; import { FiActivity, FiHeadphones, FiSettings, FiSun } from 'react-icons/fi';
import { GlobalHotKeys, KeyMap } from "react-hotkeys"; import { GlobalHotKeys, KeyMap } from 'react-hotkeys';
import { useCallback, useEffect, useMemo, useState } from "react"; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useGetUserDetails, useUserLines } from "../../controller/index"; import { useGetUserDetails, useUserLines } from '../../controller/index';
import { useRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useSetRecoilState } from 'recoil';
import { FaPlus } from "react-icons/fa"; import { FaPlus } from 'react-icons/fa';
import LineIcon from "../../components/lines/lineIcon/index"; import LineIcon from '../../components/lines/lineIcon/index';
import { LineMemberState } from "@nirvana/core/models/line.model"; import { LineMemberState } from '@nirvana/core/models/line.model';
import LineRow from "../../components/lines/lineRow.tsx/index"; import LineRow from '../../components/lines/lineRow.tsx/index';
import MasterLineData from "@nirvana/core/models/masterLineData.model"; import MasterLineData from '@nirvana/core/models/masterLineData.model';
import NewLineModal from "./newLine"; import NewLineModal from './newLine';
import toast from "react-hot-toast"; import toast from 'react-hot-toast';
import { useLineDataProvider } from "../../controller/lineDataProvider"; import { useLineDataProvider } from '../../controller/lineDataProvider';
/** /**
* Socket Provider * Socket Provider
* Line Data Provider * Line Data Provider
*/ */
export default function NirvanaTerminal({ export default function NirvanaTerminal({ overlayOnly }: { overlayOnly: boolean }) {
overlayOnly,
}: {
overlayOnly: boolean;
}) {
const [isModalVisible, setIsModalVisible] = useState<boolean>(false); const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
const { data: userDetails } = useGetUserDetails(); const { data: userDetails } = useGetUserDetails();
@@ -33,8 +29,7 @@ export default function NirvanaTerminal({
// simply using this query for specific data on loading // simply using this query for specific data on loading
// todo: add these properties in context provider value although more work down the line for control // todo: add these properties in context provider value although more work down the line for control
const { isLoading: isLoadingInitialLines } = useUserLines(); const { isLoading: isLoadingInitialLines } = useUserLines();
const { linesMap, handleTuneToLine, handleUnTuneToLine } = const { linesMap, handleTuneToLine, handleUnTuneToLine } = useLineDataProvider();
useLineDataProvider();
useEffect(() => { useEffect(() => {
// console.log("change/update in lines map"); // console.log("change/update in lines map");
@@ -52,8 +47,7 @@ export default function NirvanaTerminal({
// TODO: sort based on the audio blocks and currentMember lastActiveDate // TODO: sort based on the audio blocks and currentMember lastActiveDate
return masterLines.filter( return masterLines.filter(
(masterLine) => (masterLine) => masterLine.currentUserMember.state === LineMemberState.INBOX,
masterLine.currentUserMember.state === LineMemberState.INBOX
); );
}, [linesMap]); }, [linesMap]);
@@ -61,8 +55,7 @@ export default function NirvanaTerminal({
const masterLines: MasterLineData[] = Object.values(linesMap); const masterLines: MasterLineData[] = Object.values(linesMap);
return masterLines.filter( return masterLines.filter(
(masterLine) => (masterLine) => masterLine.currentUserMember.state === LineMemberState.TUNED,
masterLine.currentUserMember.state === LineMemberState.TUNED
); );
}, [linesMap]); }, [linesMap]);
@@ -76,11 +69,7 @@ export default function NirvanaTerminal({
const foundSelectedLine = linesMap[selectedLineId]; const foundSelectedLine = linesMap[selectedLineId];
// on mount of this, we want to temporarily tune into the line if we are not already tuned in...which would happen if we toggle tuned in // on mount of this, we want to temporarily tune into the line if we are not already tuned in...which would happen if we toggle tuned in
if ( if (!foundSelectedLine.tunedInMemberIds?.includes(userDetails?.user?._id.toString())) {
!foundSelectedLine.tunedInMemberIds?.includes(
userDetails?.user?._id.toString()
)
) {
handleTuneToLine(selectedLineId, false); handleTuneToLine(selectedLineId, false);
} }
@@ -93,7 +82,7 @@ export default function NirvanaTerminal({
// todo: sort/order based on activity and activity date and currently broadcasting/live // todo: sort/order based on activity and activity date and currently broadcasting/live
const handleEscape = useCallback(() => { const handleEscape = useCallback(() => {
console.log("deselecting line"); console.log('deselecting line');
setSelectedLineId((prevSelectedLineId) => { setSelectedLineId((prevSelectedLineId) => {
// ! only want to untune if it's a temporarily tuned line // ! only want to untune if it's a temporarily tuned line
@@ -111,31 +100,28 @@ export default function NirvanaTerminal({
setSelectedLineId((prevSelectedLineId) => { setSelectedLineId((prevSelectedLineId) => {
// untune myself from the previously selected if it was a temporary one/inbox // untune myself from the previously selected if it was a temporary one/inbox
// todo: p3: consolidate this logic as it's used in escape but different scenarios sort of so p3 // todo: p3: consolidate this logic as it's used in escape but different scenarios sort of so p3
if ( if (prevSelectedLineId && selectedLine.currentUserMember?.state === LineMemberState.INBOX)
prevSelectedLineId &&
selectedLine.currentUserMember?.state === LineMemberState.INBOX
)
handleUnTuneToLine(prevSelectedLineId); handleUnTuneToLine(prevSelectedLineId);
return newLineIdToSelect; return newLineIdToSelect;
}); });
} }
}, },
[setSelectedLineId, selectedLine] [setSelectedLineId, selectedLine],
); );
const handleToggleTuneToLine = useCallback( const handleToggleTuneToLine = useCallback(
(lineId: string, turnToggleOn: boolean) => { (lineId: string, turnToggleOn: boolean) => {
// inhibit if they are trying to turn on and already have 3 toggle tuned // inhibit if they are trying to turn on and already have 3 toggle tuned
if (toggleTunedLines?.length >= 3 && turnToggleOn) { if (toggleTunedLines?.length >= 3 && turnToggleOn) {
toast.error("You cannot toggle more than 3 lines!"); toast.error('You cannot toggle more than 3 lines!');
return; return;
} }
handleTuneToLine(lineId, turnToggleOn); handleTuneToLine(lineId, turnToggleOn);
}, },
[toggleTunedLines, handleTuneToLine] [toggleTunedLines, handleTuneToLine],
); );
const handleStartBroadcast = useCallback( const handleStartBroadcast = useCallback(
@@ -146,7 +132,7 @@ export default function NirvanaTerminal({
// if (lineId) handleUserBroadcast(lineId, true); // if (lineId) handleUserBroadcast(lineId, true);
}, },
[] [],
); );
const handleStopBroadcast = useCallback( const handleStopBroadcast = useCallback(
@@ -157,22 +143,22 @@ export default function NirvanaTerminal({
// if (lineId) handleUserBroadcast(lineId, false); // if (lineId) handleUserBroadcast(lineId, false);
}, },
[] [],
); );
const keyMap: KeyMap = useMemo( const keyMap: KeyMap = useMemo(
() => ({ () => ({
DESELECT_LINE: "esc", DESELECT_LINE: 'esc',
START_BROADCAST: { START_BROADCAST: {
sequence: "`", sequence: '`',
action: "keydown", action: 'keydown',
}, },
STOP_BROADCAST: { STOP_BROADCAST: {
sequence: "`", sequence: '`',
action: "keyup", action: 'keyup',
}, },
}), }),
[] [],
); );
const handlers = useMemo( const handlers = useMemo(
@@ -181,7 +167,7 @@ export default function NirvanaTerminal({
START_BROADCAST: handleStartBroadcast(selectedLineId), START_BROADCAST: handleStartBroadcast(selectedLineId),
STOP_BROADCAST: handleStopBroadcast(selectedLineId), STOP_BROADCAST: handleStopBroadcast(selectedLineId),
}), }),
[selectedLineId] [selectedLineId],
); );
return ( return (
@@ -191,25 +177,20 @@ export default function NirvanaTerminal({
<div className="flex flex-row flex-1"> <div className="flex flex-row flex-1">
<div className="flex flex-col bg-white w-[400px] relative group"> <div className="flex flex-col bg-white w-[400px] relative group">
{/* modal for creating new line */} {/* modal for creating new line */}
<NewLineModal <NewLineModal open={isModalVisible} handleClose={() => setIsModalVisible(false)} />
open={isModalVisible}
handleClose={() => setIsModalVisible(false)}
/>
{/* tuned in lines block */} {/* tuned in lines block */}
<div className="bg-gray-100 flex flex-col shadow-lg"> <div className="bg-gray-100 flex flex-col shadow-lg">
{/* tuned in header + general controls */} {/* tuned in header + general controls */}
<Tooltip placement="right" title={"These are your active rooms..."}> <Tooltip placement="right" title={'These are your active rooms...'}>
<div className="flex flex-row items-center py-3 px-4 pb-0"> <div className="flex flex-row items-center py-3 px-4 pb-0">
<span className="flex flex-row gap-2 items-center justify-start text-gray-400 animate-pulse"> <span className="flex flex-row gap-2 items-center justify-start text-gray-400 animate-pulse">
<FiActivity className="text-sm" /> <FiActivity className="text-sm" />
<h2 className="text-inherit text-sm">Rooms</h2> <h2 className="text-inherit text-sm">Rooms</h2>
<p className="text-slate-300 text-xs">{`${ <p className="text-slate-300 text-xs">{`${toggleTunedLines?.length || 0}/3`}</p>
toggleTunedLines?.length || 0
}/3`}</p>
</span> </span>
</div> </div>
</Tooltip> </Tooltip>
@@ -228,13 +209,12 @@ export default function NirvanaTerminal({
{!(allLines.length > 0) && !(toggleTunedLines.length > 0) && ( {!(allLines.length > 0) && !(toggleTunedLines.length > 0) && (
<span className="text-gray-300 text-sm my-5 text-center"> <span className="text-gray-300 text-sm my-5 text-center">
You have no lines! <br /> Create one to connect to your team You have no lines! <br /> Create one to connect to your team instantly.
instantly.
</span> </span>
)} )}
{/* rest of the lines */} {/* rest of the lines */}
<div className={"flex flex-col"}> <div className={'flex flex-col'}>
{isLoadingInitialLines ? ( {isLoadingInitialLines ? (
<Skeleton /> <Skeleton />
) : ( ) : (
@@ -273,9 +253,7 @@ export default function NirvanaTerminal({
className="flex flex-col flex-1 justify-center items-center bg-gray-100 className="flex flex-col flex-1 justify-center items-center bg-gray-100
border-l border-l-gray-200" border-l border-l-gray-200"
> >
<span className="text-xl text-gray-800"> <span className="text-xl text-gray-800">{`Hi ${userDetails?.user?.givenName}!`}</span>
{`Hi ${userDetails?.user?.givenName}!`}
</span>
<span className="text-md text-gray-400">You're all set!</span> <span className="text-md text-gray-400">You're all set!</span>
</div> </div>
)} )}
@@ -293,21 +271,18 @@ function LineDetailsTerminal({
}) { }) {
const { data: userDetails } = useGetUserDetails(); const { data: userDetails } = useGetUserDetails();
console.log("selected line", selectedLine); console.log('selected line', selectedLine);
const isUserToggleTuned = useMemo( const isUserToggleTuned = useMemo(
() => selectedLine?.currentUserMember?.state === LineMemberState.TUNED, () => selectedLine?.currentUserMember?.state === LineMemberState.TUNED,
[selectedLine] [selectedLine],
); );
// seeing if I am in the list of broadcasters // seeing if I am in the list of broadcasters
// the source of truth from the socket connections telling me if my clicking actually made a round trip // the source of truth from the socket connections telling me if my clicking actually made a round trip
const isUserBroadcasting = useMemo( const isUserBroadcasting = useMemo(
() => () => selectedLine?.currentBroadcastersUserIds?.includes(userDetails?.user._id.toString()),
selectedLine?.currentBroadcastersUserIds?.includes( [userDetails, selectedLine],
userDetails?.user._id.toString()
),
[userDetails, selectedLine]
); );
// showing all tuned in members...they may not hear me since they might be doing something else // showing all tuned in members...they may not hear me since they might be doing something else
@@ -329,7 +304,7 @@ function LineDetailsTerminal({
} }
const otherUserObject = selectedLine.otherUserObjects?.find( const otherUserObject = selectedLine.otherUserObjects?.find(
(userObj) => userObj._id.toString() === tunedInMemberUserId (userObj) => userObj._id.toString() === tunedInMemberUserId,
); );
if (otherUserObject?.picture) if (otherUserObject?.picture)
pictureSources.push({ pictureSources.push({
@@ -365,15 +340,12 @@ function LineDetailsTerminal({
className="p-4 className="p-4
flex flex-row items-center gap-2 justify-end border-b-gray-200 border-b" flex flex-row items-center gap-2 justify-end border-b-gray-200 border-b"
> >
{profilePictures && ( {profilePictures && <LineIcon grayscale={false} sourceImages={profilePictures} />}
<LineIcon grayscale={false} sourceImages={profilePictures} />
)}
<div className="flex flex-col items-start mr-auto group"> <div className="flex flex-col items-start mr-auto group">
<span className="flex flex-row gap-2 items-center"> <span className="flex flex-row gap-2 items-center">
<h2 className={`text-lg text-slate-800 font-semibold`}> <h2 className={`text-lg text-slate-800 font-semibold`}>
{selectedLine.lineDetails.name || {selectedLine.lineDetails.name || selectedLine.otherUserObjects[0].givenName}
selectedLine.otherUserObjects[0].givenName}
</h2> </h2>
<button <button
@@ -398,25 +370,17 @@ function LineDetailsTerminal({
{/* TODO: move to on hover of line row */} {/* TODO: move to on hover of line row */}
<Tooltip <Tooltip
placement="left" placement="left"
title={`${ title={`${isUserToggleTuned ? 'click to untoggle' : 'click to stay tuned in'}`}
isUserToggleTuned ? "click to untoggle" : "click to stay tuned in"
}`}
> >
<button <button
className={`p-2 flex justify-center items-center shadow-lg className={`p-2 flex justify-center items-center shadow-lg
hover:scale-105 transition-all animate-pulse ${ hover:scale-105 transition-all animate-pulse ${
isUserToggleTuned ? "bg-gray-800 text-white" : "text-black" isUserToggleTuned ? 'bg-gray-800 text-white' : 'text-black'
}`} }`}
onClick={() => onClick={() =>
isUserToggleTuned isUserToggleTuned
? handleToggleTuneToLine( ? handleToggleTuneToLine(selectedLine.lineDetails._id.toString(), false)
selectedLine.lineDetails._id.toString(), : handleToggleTuneToLine(selectedLine.lineDetails._id.toString(), true)
false
)
: handleToggleTuneToLine(
selectedLine.lineDetails._id.toString(),
true
)
} }
> >
<FiActivity className="text-md" /> <FiActivity className="text-md" />
@@ -426,15 +390,11 @@ function LineDetailsTerminal({
{/* line timeline */} {/* line timeline */}
<div className="flex flex-col items-center gap-2 my-2 mx-auto max-w-lg w-full"> <div className="flex flex-col items-center gap-2 my-2 mx-auto max-w-lg w-full">
<span <span className={'text-gray-300 text-sm cursor-pointer hover:underline'}>load more</span>
className={"text-gray-300 text-sm cursor-pointer hover:underline"}
>
load more
</span>
<span className={"text-gray-300 text-sm"}>yesterday</span> <span className={'text-gray-300 text-sm'}>yesterday</span>
<div className={"rounded border border-gray-200 flex flex-col w-full"}> <div className={'rounded border border-gray-200 flex flex-col w-full'}>
{selectedLine.otherUserObjects.map((otherUser) => ( {selectedLine.otherUserObjects.map((otherUser) => (
<div <div
className="flex flex-row p-2 gap-2 items-center bg-transparent className="flex flex-row p-2 gap-2 items-center bg-transparent
@@ -444,9 +404,9 @@ function LineDetailsTerminal({
key={`linehistory-${1}`} key={`linehistory-${1}`}
src={otherUser.picture} src={otherUser.picture}
shape="square" shape="square"
size={"default"} size={'default'}
// grayscale if not playing? // grayscale if not playing?
className={`${true && "grayscale"}`} className={`${true && 'grayscale'}`}
/> />
<span className="text-gray-500">{otherUser.givenName}</span> <span className="text-gray-500">{otherUser.givenName}</span>
@@ -468,11 +428,11 @@ function LineDetailsTerminal({
key={`linehistory-${1}`} key={`linehistory-${1}`}
src={userDetails.user.picture} src={userDetails.user.picture}
shape="square" shape="square"
size={"default"} size={'default'}
// grayscale if not playing? // grayscale if not playing?
className={`${true && "grayscale"}`} className={`${true && 'grayscale'}`}
/> />
<span className="text-gray-500">{"Arjun Patel"}</span> <span className="text-gray-500">{'Arjun Patel'}</span>
<span className="ml-auto text-xs text-gray-300">{`${ <span className="ml-auto text-xs text-gray-300">{`${
Math.floor(Math.random() * 10) + 1 Math.floor(Math.random() * 10) + 1
@@ -484,13 +444,9 @@ function LineDetailsTerminal({
</div> </div>
</div> </div>
<span className={"text-gray-300 text-sm"}>today</span> <span className={'text-gray-300 text-sm'}>today</span>
<div <div className={'rounded border border-gray-400 flex flex-col w-full shadow-xl'}>
className={
"rounded border border-gray-400 flex flex-col w-full shadow-xl"
}
>
{selectedLine.otherUserObjects.map((otherUser) => ( {selectedLine.otherUserObjects.map((otherUser) => (
// TODO: show the shadow if it's unheard // TODO: show the shadow if it's unheard
<div <div
@@ -501,13 +457,11 @@ function LineDetailsTerminal({
key={`linehistory-${1}`} key={`linehistory-${1}`}
src={otherUser.picture} src={otherUser.picture}
shape="square" shape="square"
size={"default"} size={'default'}
// grayscale if not playing? // grayscale if not playing?
className={`${false && "grayscale"}`} className={`${false && 'grayscale'}`}
/> />
<span className="text-gray-600 font-semibold"> <span className="text-gray-600 font-semibold">{otherUser.name}</span>
{otherUser.name}
</span>
<span className="ml-auto text-xs text-gray-400">{`${ <span className="ml-auto text-xs text-gray-400">{`${
Math.floor(Math.random() * 10) + 1 Math.floor(Math.random() * 10) + 1
@@ -521,32 +475,24 @@ function LineDetailsTerminal({
</div> </div>
{/* live broadcasters */} {/* live broadcasters */}
<span <span className={'flex flex-row gap-2 items-center text-teal-500 text-sm'}>
className={"flex flex-row gap-2 items-center text-teal-500 text-sm"}
>
<FiSun className="animate-ping" /> <FiSun className="animate-ping" />
<span>right now</span> <span>right now</span>
</span> </span>
<div <div className={'rounded border border-teal-500 flex flex-col w-full shadow-2xl'}>
className={
"rounded border border-teal-500 flex flex-col w-full shadow-2xl"
}
>
{selectedLine.otherUserObjects.map((otherUser) => ( {selectedLine.otherUserObjects.map((otherUser) => (
<div className="flex flex-row p-2 gap-2 items-center bg-transparent"> <div className="flex flex-row p-2 gap-2 items-center bg-transparent">
<Avatar <Avatar
key={`linehistory-${1}`} key={`linehistory-${1}`}
src={otherUser.picture} src={otherUser.picture}
shape="square" shape="square"
size={"large"} size={'large'}
// grayscale if not playing? // grayscale if not playing?
className={`shadow-lg`} className={`shadow-lg`}
/> />
<span className="text-gray-600 font-semibold"> <span className="text-gray-600 font-semibold">{otherUser.name}</span>
{otherUser.name}
</span>
<Tooltip title={"audio only"}> <Tooltip title={'audio only'}>
<FiHeadphones className="text-gray-600 text-md ml-auto" /> <FiHeadphones className="text-gray-600 text-md ml-auto" />
</Tooltip> </Tooltip>
</div> </div>
@@ -557,9 +503,7 @@ function LineDetailsTerminal({
<button <button
className={`p-3 absolute right-3 bottom-3 flex justify-center items-center shadow-2xl className={`p-3 absolute right-3 bottom-3 flex justify-center items-center shadow-2xl
hover:scale-105 transition-all ${ hover:scale-105 transition-all ${
isUserBroadcasting isUserBroadcasting ? 'bg-teal-800 text-white' : 'text-teal-800 border-teal-800 border'
? "bg-teal-800 text-white"
: "text-teal-800 border-teal-800 border"
}`} }`}
> >
<FiSun className="text-lg" /> <FiSun className="text-lg" />
+25
View File
@@ -3360,6 +3360,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
eslint-plugin-react-hooks@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz#5f762dfedf8b2cf431c689f533c9d3fa5dcf25ad"
integrity sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==
[email protected]: [email protected]:
version "7.29.1" version "7.29.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.1.tgz#6c40bc83142bb63d132a1b3565e2ea655411f800" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.1.tgz#6c40bc83142bb63d132a1b3565e2ea655411f800"
@@ -3380,6 +3385,26 @@ [email protected]:
semver "^6.3.0" semver "^6.3.0"
string.prototype.matchall "^4.0.6" string.prototype.matchall "^4.0.6"
eslint-plugin-react@^7.29.4:
version "7.29.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz#4717de5227f55f3801a5fd51a16a4fa22b5914d2"
integrity sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==
dependencies:
array-includes "^3.1.4"
array.prototype.flatmap "^1.2.5"
doctrine "^2.1.0"
estraverse "^5.3.0"
jsx-ast-utils "^2.4.1 || ^3.0.0"
minimatch "^3.1.2"
object.entries "^1.1.5"
object.fromentries "^2.0.5"
object.hasown "^1.1.0"
object.values "^1.1.5"
prop-types "^15.8.1"
resolve "^2.0.0-next.3"
semver "^6.3.0"
string.prototype.matchall "^4.0.6"
[email protected], eslint-scope@^5.1.1: [email protected], eslint-scope@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"