Skip to content

Commit

Permalink
Add click-outside handling to overlay
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswilty committed Oct 13, 2023
1 parent dd62df7 commit 8ee06ec
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 41 deletions.
25 changes: 8 additions & 17 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import MainBody from "./components/MainComponent/MainBody";
import { useEffect, useState } from "react";
import { LEVEL_NAMES } from "./models/level";
import {
getChatHistory,
clearChat,
addMessageToChatHistory,
clearChat,
getChatHistory,
} from "./service/chatService";
import { EmailInfo } from "./models/email";
import { clearEmails, getSentEmails } from "./service/emailService";
Expand All @@ -25,12 +25,6 @@ import { getCompletedLevels } from "./service/levelService";
import Overlay from "./components/Overlay/Overlay";
import { OVERLAY_TYPE } from "./models/overlay";

/*
TODO
- Add click handler
- Manually test!
*/

function App({ isNewUser }: { isNewUser: boolean }) {
const [MainBodyKey, setMainBodyKey] = useState<number>(0);
const [currentLevel, setCurrentLevel] = useState<LEVEL_NAMES>(
Expand All @@ -43,11 +37,7 @@ function App({ isNewUser }: { isNewUser: boolean }) {

const [emails, setEmails] = useState<EmailInfo[]>([]);
const [messages, setMessages] = useState<ChatMessage[]>([]);

const [showOverlay, setShowOverlay] = useState<boolean>(isNewUser);
const [overlayType, setOverlayType] = useState<OVERLAY_TYPE>(
OVERLAY_TYPE.WELCOME
);
const [overlayType, setOverlayType] = useState<OVERLAY_TYPE | null>(null);

function loadCurrentLevel() {
// get current level from local storage
Expand All @@ -71,6 +61,9 @@ function App({ isNewUser }: { isNewUser: boolean }) {
console.error(err);
});
void setNewLevel(currentLevel);
if (isNewUser) {
setOverlayType(OVERLAY_TYPE.WELCOME);
}
}, []);

useEffect(() => {
Expand All @@ -83,18 +76,16 @@ function App({ isNewUser }: { isNewUser: boolean }) {
if (overlayType === OVERLAY_TYPE.WELCOME) {
openInformationOverlay();
} else {
setShowOverlay(false);
setOverlayType(null);
}
}

function openHandbook() {
setOverlayType(OVERLAY_TYPE.HANDBOOK);
setShowOverlay(true);
}

function openInformationOverlay() {
setOverlayType(OVERLAY_TYPE.INFORMATION);
setShowOverlay(true);
}

// methods to modify messages
Expand Down Expand Up @@ -233,7 +224,7 @@ function App({ isNewUser }: { isNewUser: boolean }) {

return (
<div id="app-content">
{showOverlay && (
{overlayType !== null && (
<Overlay
currentLevel={currentLevel}
overlayType={overlayType}
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/components/HandbookOverlay/HandbookAttacks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import "./HandbookAttacks.css";

function HandbookAttacks({ currentLevel }: { currentLevel: LEVEL_NAMES }) {
const attacks: AttackInfo[] =
currentLevel === LEVEL_NAMES.LEVEL_2
? ATTACKS_LEVEL_2
: ATTACKS_ALL;
currentLevel === LEVEL_NAMES.LEVEL_2 ? ATTACKS_LEVEL_2 : ATTACKS_ALL;

return (
<div className="handbook-attacks">
Expand Down
14 changes: 9 additions & 5 deletions frontend/src/components/HandbookOverlay/HandbookOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ function HandbookOverlay({ currentLevel }: { currentLevel: LEVEL_NAMES }) {
);

const pageContent =
selectedPage === HANDBOOK_PAGES.ATTACKS
? <HandbookAttacks currentLevel={currentLevel} />
: selectedPage === HANDBOOK_PAGES.TOOLS
? <div><h2>Placeholder</h2></div>
: <MissionInformation currentLevel={currentLevel} />;
selectedPage === HANDBOOK_PAGES.ATTACKS ? (
<HandbookAttacks currentLevel={currentLevel} />
) : selectedPage === HANDBOOK_PAGES.TOOLS ? (
<div>
<h2>Placeholder</h2>
</div>
) : (
<MissionInformation currentLevel={currentLevel} />
);

return (
<div className="handbook-overlay">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
transition: ease 0.1s;
}

.handbook-tabs button[aria-selected=true] {
.handbook-tabs button[aria-selected="true"] {
background-color: var(--overlay-tab-colour);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ function HandbookOverlayTabs({
currentLevel === LEVEL_NAMES.LEVEL_1
? [HANDBOOK_PAGES.MISSION_INFO]
: [
HANDBOOK_PAGES.MISSION_INFO,
HANDBOOK_PAGES.ATTACKS,
HANDBOOK_PAGES.TOOLS,
];
HANDBOOK_PAGES.MISSION_INFO,
HANDBOOK_PAGES.ATTACKS,
HANDBOOK_PAGES.TOOLS,
];

return (
<div className="handbook-tabs" role="tablist">
Expand Down
59 changes: 48 additions & 11 deletions frontend/src/components/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useCallback, useEffect, useRef } from "react";
import { LEVEL_NAMES } from "../../models/level";
import { OVERLAY_TYPE } from "../../models/overlay";
import "./Overlay.css";
import HandbookWelcome from "./OverlayWelcome";
import HandbookOverlay from "../HandbookOverlay/HandbookOverlay";
import MissionInformation from "../Overlay/MissionInformation";
import { useEffect, useRef } from 'react';
import MissionInformation from "./MissionInformation";
import HandbookWelcome from "./OverlayWelcome";

import "./Overlay.css";

function Overlay({
currentLevel,
Expand All @@ -16,19 +17,53 @@ function Overlay({
closeOverlay: () => void;
}) {
const dialogRef = useRef<HTMLDialogElement>(null);
const contentRef = useRef<HTMLDivElement>(null);

const handleOverlayClick = useCallback(
(event: MouseEvent) => {
contentRef.current &&
!event.composedPath().includes(contentRef.current) &&
closeOverlay();
},
[closeOverlay, contentRef]
);

const handleEscape = useCallback(
(event: KeyboardEvent) => {
event.code === "Escape" && closeOverlay();
},
[closeOverlay]
);

useEffect(() => {
dialogRef.current?.showModal();
return () => {
dialogRef.current?.close();
}
};
}, []);

useEffect(() => {
window.addEventListener("keydown", handleEscape);
setTimeout(() => {
// Need timeout, else dialog consumes same click that
// opened it and closes immediately!
window.addEventListener("click", handleOverlayClick);
});

return () => {
window.removeEventListener("keydown", handleEscape);
window.removeEventListener("click", handleOverlayClick);
};
}, [overlayType]);

const overlayContent =
overlayType === OVERLAY_TYPE.HANDBOOK
? <HandbookOverlay currentLevel={currentLevel} />
: overlayType === OVERLAY_TYPE.INFORMATION
? <MissionInformation currentLevel={currentLevel} />
: <HandbookWelcome />;
overlayType === OVERLAY_TYPE.HANDBOOK ? (
<HandbookOverlay currentLevel={currentLevel} />
) : overlayType === OVERLAY_TYPE.INFORMATION ? (
<MissionInformation currentLevel={currentLevel} />
) : (
<HandbookWelcome />
);

return (
<dialog ref={dialogRef} className="overlay">
Expand All @@ -39,7 +74,9 @@ function Overlay({
>
X
</button>
<div className="overlay-content">{overlayContent}</div>
<div ref={contentRef} className="overlay-content">
{overlayContent}
</div>
</dialog>
);
}
Expand Down

0 comments on commit 8ee06ec

Please sign in to comment.