Skip to content

Commit

Permalink
Merge pull request #101 from MegaAntiCheat/meat/fix-multiple-popovers
Browse files Browse the repository at this point in the history
Fixed contextMenu not closing on click
  • Loading branch information
megascatterbomb authored May 17, 2024
2 parents f0af56b + 4d56160 commit d0e17a1
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 45 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"browser": true
},
"rules": {
"react/react-in-jsx-scope": "off",
"prefer-const": "warn",
"arrow-parens": ["error", "always"],
"no-confusing-arrow": "error",
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,6 @@ dist
.yarn/install-state.gz
.pnp.*

placeholderData.ts
placeholderData.ts

.idea
42 changes: 24 additions & 18 deletions src/components/General/ContextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import React from 'react';
import { CSSProperties, useContext, useEffect, useRef, useState } from 'react';
import './ContextMenu.css';

import { ContextMenuContext } from '../../../Context';
import { ContextMenuContext } from '@context';
import { ChevronRight } from 'lucide-react';

const ContextMenuContent = () => {
const contextMenuRef = React.useRef<HTMLDivElement>(null);
const [showMulti, setShowMulti] = React.useState<number[]>([]);
const [forceUpdate, setForceUpdate] = React.useState(false);
const contextMenuRef = useRef<HTMLDivElement>(null);
const [showMulti, setShowMulti] = useState<number[]>([]);
const [forceUpdate, setForceUpdate] = useState(false);
const { isVisible, position, menuItems, hideMenu } =
React.useContext(ContextMenuContext);
useContext(ContextMenuContext);

if (!isVisible) return null;

const handleOutsideClick = (event: MouseEvent) => {
if (!contextMenuRef.current?.contains(event.target as Node)) {
hideMenu();
}
};

const style: React.CSSProperties = {
const style: CSSProperties = {
top: position.y,
left: position.x,
};
Expand Down Expand Up @@ -52,14 +46,26 @@ const ContextMenuContent = () => {
const { top, height } = contextMenuRef.current.getBoundingClientRect();
const windowHeight = window.innerHeight;
const spaceBelow = windowHeight - top - height;
console.log(height, spaceBelow);
return spaceBelow >= height;
};

React.useEffect(() => {
document.addEventListener('click', handleOutsideClick);
let timesVisible = 0;
useEffect(() => {
const handleClick = () => {
if (isVisible) {
if (timesVisible) {
hideMenu();
}
timesVisible++;
}
};
if (isVisible) {
document.addEventListener('click', handleClick);
document.addEventListener('contextmenu', handleClick);
}
return () => {
document.removeEventListener('click', handleOutsideClick);
document.removeEventListener('click', handleClick);
document.removeEventListener('contextmenu', handleClick);
};
}, []);

Expand Down Expand Up @@ -117,7 +123,7 @@ const ContextMenuContent = () => {
};

const ContextMenu = () => {
const { isVisible } = React.useContext(ContextMenuContext);
const { isVisible } = useContext(ContextMenuContext);

if (!isVisible) return null;

Expand Down
32 changes: 16 additions & 16 deletions src/components/TF2/Player/Player.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { MouseEvent, useContext, useEffect, useRef, useState } from 'react';
import './Player.css';

import { t } from '@i18n';
import { updatePlayer } from '@api/players';
import { ContextMenu, Select, Tooltip } from '@components/General';
import { ContextMenuContext, MenuItem } from '../../../Context';
import { ContextMenuContext, MenuItem } from '@context';
import {
buildIconList,
displayColor,
Expand All @@ -19,7 +19,7 @@ import PlayerDetails from './PlayerDetails';
import { verifyImageExists } from '@api/utils';
import { kickPlayer } from '@api/commands';
import { Info } from 'lucide-react';
import { useModal } from '../../../Context';
import { useModal } from '@context';
import ChangeAliasModal from './Modals/ChangeAliasModal';

interface PlayerProps {
Expand All @@ -41,17 +41,17 @@ const Player = ({
openInApp,
cheatersInLobby,
}: PlayerProps) => {
const isFirstRefresh = React.useRef(true);
const isFirstRefresh = useRef(true);
// Context Menu
const { showMenu } = React.useContext(ContextMenuContext);
const { showMenu } = useContext(ContextMenuContext);

// Modal
const { openModal } = useModal();

// States
const [playtime, setPlaytime] = React.useState(0);
const [pfp, setPfp] = React.useState<string>('./person.webp');
const [showPlayerDetails, setShowPlayerDetails] = React.useState(false);
const [playtime, setPlaytime] = useState(0);
const [pfp, setPfp] = useState<string>('./person.webp');
const [showPlayerDetails, setShowPlayerDetails] = useState(false);

const urlToOpen = openInApp
? `steam://url/SteamIDPage/${player.steamID64}`
Expand All @@ -67,11 +67,11 @@ const Player = ({

// const color = displayColor(playerColors!, player, cheatersInLobby);

const [color, setColor] = React.useState<string | undefined>(
const [color, setColor] = useState<string | undefined>(
displayColor(playerColors!, player, cheatersInLobby),
);

React.useEffect(() => {
useEffect(() => {
setColor(displayColor(playerColors!, player, cheatersInLobby));
}, [player.localVerdict, playerColors, player, cheatersInLobby]);

Expand All @@ -80,8 +80,8 @@ const Player = ({
const disconnected = displayStatus === 'Disconnected';

// Prevent text selection on click (e.g Dropdown)
React.useEffect(() => {
function preventDefault(e: MouseEvent) {
useEffect(() => {
function preventDefault(e: globalThis.MouseEvent) {
if (e.detail != 2) return;

e.preventDefault();
Expand All @@ -92,7 +92,7 @@ const Player = ({
}, []);

// Sync time if not yet set or out of sync (e.g. switched servers)
React.useEffect(() => {
useEffect(() => {
if (
!isFirstRefresh.current &&
Math.abs(playtime - (player.gameInfo?.time ?? playtime)) <= 3
Expand All @@ -105,7 +105,7 @@ const Player = ({
}, [player.gameInfo?.time]);

// Update playtime every second
React.useEffect(() => {
useEffect(() => {
const interval = setInterval(() => {
if (disconnected) return;
setPlaytime((prev) => prev + 1);
Expand All @@ -115,7 +115,7 @@ const Player = ({
}, [disconnected]);

// Update pfp on mount
React.useEffect(() => {
useEffect(() => {
if (!player.steamInfo?.pfp) return;

verifyImageExists(player.steamInfo?.pfp, './person.webp').then((src) => {
Expand All @@ -125,7 +125,7 @@ const Player = ({
});
}, [player.steamInfo?.pfp]);

const handleContextMenu = (event: React.MouseEvent<HTMLDivElement>) => {
const handleContextMenu = (event: MouseEvent<HTMLDivElement>) => {
event.preventDefault();
const menuItems: MenuItem[] = [
{
Expand Down
12 changes: 5 additions & 7 deletions src/components/TF2/ScoreboardTable/ScoreboardTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import { useEffect, useState } from 'react';
import './ScoreboardTable.css';

import { getAllSettings } from '@api/preferences';
Expand All @@ -19,10 +19,8 @@ const ScoreboardTable = ({
UNASSIGNED,
}: ScoreboardTableProps) => {
// Store the users playerID
const [userSteamID, setUserSteamID] = React.useState('0');
const [playerSettings, setPlayerSettings] = React.useState<
Settings['external']
>({
const [userSteamID, setUserSteamID] = useState('0');
const [playerSettings, setPlayerSettings] = useState<Settings['external']>({
colors: {
You: 'none',
Player: 'none',
Expand All @@ -37,7 +35,7 @@ const ScoreboardTable = ({
openInApp: false,
});

React.useEffect(() => {
useEffect(() => {
const fetchTeamColors = async () => {
try {
const { external } = await getAllSettings(); // Replace this with the actual async function that fetches colors
Expand All @@ -49,7 +47,7 @@ const ScoreboardTable = ({
fetchTeamColors();
}, []);

React.useEffect(() => {
useEffect(() => {
const fetchSelf = () => {
const combinedPlayers = RED?.concat(
BLU ?? [],
Expand Down
4 changes: 1 addition & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"jsx": "react",
"jsx": "react-jsx",
/* Visit https://aka.ms/tsconfig to read more about this file */

/* Projects */
Expand All @@ -17,8 +17,6 @@
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
"jsxFactory": "React.createElement" /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */,
"jsxFragmentFactory": "React.Fragment" /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */,
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
Expand Down

0 comments on commit d0e17a1

Please sign in to comment.