MISC: Refactor InvitationModal and AlertManager (#1287)

This commit is contained in:
catloversg 2024-05-23 08:43:31 +07:00 committed by GitHub
parent fe7e1c86bc
commit 7bb36ec111
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 96 additions and 64 deletions

@ -16,7 +16,7 @@ import {
} from "../PersonObjects/formulas/reputation";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { InvitationEvent } from "./ui/InvitationModal";
import { FactionInvitationEvents } from "./ui/FactionInvitationManager";
import { SFC32RNG } from "../Casino/RNG";
import { isFactionWork } from "../Work/FactionWork";
import { getAugCost } from "../Augmentation/AugmentationHelpers";
@ -28,7 +28,7 @@ export function inviteToFaction(faction: Faction): void {
faction.alreadyInvited = true;
faction.discovery = FactionDiscovery.known;
if (!Settings.SuppressFactionInvites) {
InvitationEvent.emit(faction);
FactionInvitationEvents.emit({ type: "New", factionName: faction.name });
}
}

@ -0,0 +1,89 @@
import React, { useState, useEffect } from "react";
import { joinFaction } from "../FactionHelpers";
import { Modal } from "../../ui/React/Modal";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { Report } from "@mui/icons-material";
import { Settings } from "../../Settings/Settings";
import { FactionName } from "../Enums";
import { Factions } from "../Factions";
type NewInvitation = {
type: "New";
factionName: FactionName;
};
type ClearAllInvitations = {
type: "ClearAll";
};
type FactionInvitationEvent = NewInvitation | ClearAllInvitations;
export const FactionInvitationEvents = new EventEmitter<[FactionInvitationEvent]>();
export function FactionInvitationManager({ hidden }: { hidden: boolean }): React.ReactElement {
const [factions, setFactions] = useState<FactionName[]>([]);
useEffect(
() =>
FactionInvitationEvents.subscribe((event) => {
if (event.type === "ClearAll") {
setFactions([]);
return;
}
setFactions((currentFactions) => {
if (currentFactions.includes(event.factionName)) {
return currentFactions;
}
return [...currentFactions, event.factionName];
});
}),
[],
);
function close(): void {
setFactions((currentFactions) => {
return currentFactions.slice(1);
});
}
const faction = factions.length > 0 ? Factions[factions[0]] : null;
const enemies = faction?.getInfo().enemies ?? [];
function join(): void {
if (faction === null || !faction.alreadyInvited) {
return;
}
joinFaction(faction);
close();
}
return (
<Modal open={!hidden && faction !== null} onClose={close}>
<Typography variant="h4">You received a faction invitation.</Typography>
<Typography>
Would you like to join <b>{faction?.name}</b>?
</Typography>
{enemies.length > 0 && (
<Typography component="div">
<br />
Joining this faction will prevent you from joining its enemies until your next augmentation.
<br />
{faction?.name} is enemies with:
{enemies.map((enemy) => (
<Typography key={enemy} sx={{ display: "flex", alignItems: "center" }}>
<Report sx={{ marginLeft: 2, marginRight: 1, color: Settings.theme.error }} />
{enemy}
</Typography>
))}
</Typography>
)}
<br />
<Button onClick={join} sx={{ marginRight: 1 }}>
Join
</Button>
<Button onClick={close}>Decide later</Button>
</Modal>
);
}

@ -1,52 +0,0 @@
import React, { useState, useEffect } from "react";
import { joinFaction } from "../FactionHelpers";
import { Faction } from "../Faction";
import { Modal } from "../../ui/React/Modal";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { Report } from "@mui/icons-material";
import { Settings } from "../../Settings/Settings";
export const InvitationEvent = new EventEmitter<[Faction | null]>();
export function InvitationModal({ hidden }: { hidden: boolean }): React.ReactElement {
const [faction, setFaction] = useState<Faction | null>(null);
const enemies = faction?.getInfo().enemies ?? [];
function join(): void {
if (faction === null) return;
if (!faction.alreadyInvited) return;
joinFaction(faction);
setFaction(null);
}
useEffect(() => InvitationEvent.subscribe((faction) => setFaction(faction)), []);
return (
<Modal open={!hidden && faction !== null} onClose={() => setFaction(null)}>
<Typography variant="h4">You have received a faction invitation.</Typography>
<Typography>
Would you like to join <b>{faction?.name}</b>?
</Typography>
{enemies.length > 0 && (
<Typography component="div">
<br />
Joining this Faction will prevent you from joining its enemies until your next augmentation.
<br />
{faction?.name} is enemies with:
{enemies.map((enemy) => (
<Typography key={enemy} sx={{ display: "flex", alignItems: "center" }}>
<Report sx={{ ml: 2, mr: 1, color: Settings.theme.error }} />
{enemy}
</Typography>
))}
</Typography>
)}
<br />
<Button onClick={join}>Join!</Button>
<Button onClick={() => setFaction(null)}>Decide later</Button>
</Modal>
);
}

@ -26,7 +26,7 @@ import { CONSTANTS } from "../../Constants";
import { Exploit } from "../../Exploits/Exploit";
import { Faction } from "../../Faction/Faction";
import { Factions } from "../../Faction/Factions";
import { InvitationEvent } from "../../Faction/ui/InvitationModal";
import { FactionInvitationEvents } from "../../Faction/ui/FactionInvitationManager";
import { resetGangs } from "../../Gang/AllGangs";
import { Cities } from "../../Locations/Cities";
import { Locations } from "../../Locations/Locations";
@ -104,7 +104,7 @@ export function prestigeAugmentation(this: PlayerObject): void {
this.factionInvitations = [];
this.factionRumors.clear();
// Clear any pending invitation modals
InvitationEvent.emit(null);
FactionInvitationEvents.emit({ type: "ClearAll" });
this.queuedAugmentations = [];

@ -56,7 +56,7 @@ import { Snackbar, SnackbarProvider } from "./React/Snackbar";
import { LogBoxManager } from "./React/LogBoxManager";
import { AlertManager } from "./React/AlertManager";
import { PromptManager } from "./React/PromptManager";
import { InvitationModal } from "../Faction/ui/InvitationModal";
import { FactionInvitationManager } from "../Faction/ui/FactionInvitationManager";
import { calculateAchievements } from "../Achievements/Achievements";
import { RecoveryMode, RecoveryRoot } from "./React/RecoveryRoot";
@ -407,7 +407,7 @@ export function GameRoot(): React.ReactElement {
<LogBoxManager hidden={!withPopups} />
<AlertManager hidden={!withPopups} />
<PromptManager hidden={!withPopups} />
<InvitationModal hidden={!withPopups} />
<FactionInvitationManager hidden={!withPopups} />
<Snackbar hidden={!withPopups} />
<Apr1 />
</SnackbarProvider>

@ -8,19 +8,15 @@ import { sha256 } from "js-sha256";
export const AlertEvents = new EventEmitter<[string | JSX.Element]>();
interface Alert {
id: string;
text: string | JSX.Element;
hash: string;
}
let i = 0;
export function AlertManager({ hidden }: { hidden: boolean }): React.ReactElement {
const [alerts, setAlerts] = useState<Alert[]>([]);
useEffect(
() =>
AlertEvents.subscribe((text: string | JSX.Element) => {
const id = i + "";
i++;
setAlerts((old) => {
const hash = getMessageHash(text);
if (old.some((a) => a.hash === hash)) {
@ -29,7 +25,6 @@ export function AlertManager({ hidden }: { hidden: boolean }): React.ReactElemen
return [
...old,
{
id: id,
text: text,
hash: hash,
},
@ -58,7 +53,7 @@ export function AlertManager({ hidden }: { hidden: boolean }): React.ReactElemen
function close(): void {
setAlerts((old) => {
return old.slice(1, 1e99);
return old.slice(1);
});
}