mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 20:55:44 +01:00
UI: Add a Credits button in options menu (#836)
This commit is contained in:
parent
a8e48ddb12
commit
3c52984d61
89
src/GameOptions/ui/CreditsModal.tsx
Normal file
89
src/GameOptions/ui/CreditsModal.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
import { Typography, Link, Button } from "@mui/material";
|
||||||
|
|
||||||
|
import { CONSTANTS } from "../../Constants";
|
||||||
|
|
||||||
|
interface CreditsModalProps {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const enclosed = /(\([^)]+\))/gm; //grab all filled () pairs
|
||||||
|
const recentPatchData = Array.from(new Set(CONSTANTS.LatestUpdate.match(enclosed)));
|
||||||
|
|
||||||
|
const isDate = (data: string) => {
|
||||||
|
const regex = /^\(last update/gm; //(this) isn't @name, but may be useful
|
||||||
|
return regex.test(data);
|
||||||
|
};
|
||||||
|
const updateMessage = []; //store last update message, eg (last updated 9/12/23)
|
||||||
|
if (isDate(recentPatchData[0])) updateMessage.push(recentPatchData[0]);
|
||||||
|
|
||||||
|
const handle: string[] = [];
|
||||||
|
for (let i = 0; i < recentPatchData.length; i++) {
|
||||||
|
const atName = /(?:^[(]?(@[^\s),]+)[),]?)/gm; //make an array of only unique @handles
|
||||||
|
const whatWeWant = recentPatchData[i].replace(atName, "$1");
|
||||||
|
if (isDate(recentPatchData[i]) || !recentPatchData[i].includes("@")) continue;
|
||||||
|
if (recentPatchData[i].includes(", ")) {
|
||||||
|
//if (@1, @2, ...@n)
|
||||||
|
recentPatchData.push(...recentPatchData[i].split(", "));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!handle.includes(whatWeWant)) handle.push(whatWeWant);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CreditsModal(props: CreditsModalProps): React.ReactElement {
|
||||||
|
const leadDevs = `danielyxie
|
||||||
|
Olivier Gagnon
|
||||||
|
@Snarling
|
||||||
|
`;
|
||||||
|
|
||||||
|
const currentMaintainer = `@Snarling`;
|
||||||
|
|
||||||
|
const handles = handle.sort((a, b) => a.localeCompare(b)).join(", ");
|
||||||
|
const contributorsURL = `https://github.com/bitburner-official/bitburner-src/graphs/contributors`;
|
||||||
|
const contributorsMessage = `Visit GitHub to see all contributors
|
||||||
|
or to participate yourself`;
|
||||||
|
const maxEM = Math.floor(contributorsMessage.length / 2);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={props.open}
|
||||||
|
onClose={props.onClose}
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography alignContent={"start"} variant="h3">
|
||||||
|
Bitburner
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{ textDecoration: "underline" }}>Original Code and Concept</Typography>
|
||||||
|
<Typography>danielyxie</Typography>
|
||||||
|
<br />
|
||||||
|
<Typography sx={{ textDecoration: "underline" }}>Lead Developers:</Typography>
|
||||||
|
<Typography style={{ whiteSpace: "pre-wrap" }}>{leadDevs}</Typography>
|
||||||
|
<br />
|
||||||
|
<Typography sx={{ textDecoration: "underline" }}>Current Maintainer</Typography>
|
||||||
|
<Typography>{currentMaintainer}</Typography>
|
||||||
|
<br />
|
||||||
|
<Typography sx={{ textDecoration: "underline" }}>Recent patch contributors:</Typography>
|
||||||
|
<Typography style={{ whiteSpace: "pre-wrap", maxWidth: maxEM + "rem", textOverflow: "clip" }}>
|
||||||
|
{/*rem unit = character px based, dynamic with font. balance contributor overflow vs longest other message*/}
|
||||||
|
{/*textoverflow "clip" forces very long @names to stretch a single line, it's silly*/}
|
||||||
|
{handles}
|
||||||
|
</Typography>
|
||||||
|
<br />
|
||||||
|
<Typography style={{ whiteSpace: "pre-wrap" }}>
|
||||||
|
<Link href={contributorsURL} target="_blank">
|
||||||
|
{contributorsMessage}
|
||||||
|
</Link>
|
||||||
|
</Typography>
|
||||||
|
<br />
|
||||||
|
<Typography fontSize={"large"}>
|
||||||
|
<Button onClick={props.onClose} size="large">
|
||||||
|
Thanks for Playing!
|
||||||
|
</Button>
|
||||||
|
</Typography>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,14 @@
|
|||||||
import { BugReport, Chat, Download, LibraryBooks, Palette, Reddit, Save, Upload } from "@mui/icons-material";
|
import {
|
||||||
|
BugReport,
|
||||||
|
Chat,
|
||||||
|
Download,
|
||||||
|
LibraryBooks,
|
||||||
|
Palette,
|
||||||
|
Fingerprint,
|
||||||
|
Reddit,
|
||||||
|
Save,
|
||||||
|
Upload,
|
||||||
|
} from "@mui/icons-material";
|
||||||
import { Box, Button, List, ListItemButton, Paper, Tooltip, Typography } from "@mui/material";
|
import { Box, Button, List, ListItemButton, Paper, Tooltip, Typography } from "@mui/material";
|
||||||
import { default as React, useRef, useState } from "react";
|
import { default as React, useRef, useState } from "react";
|
||||||
import { FileDiagnosticModal } from "../../Diagnostic/FileDiagnosticModal";
|
import { FileDiagnosticModal } from "../../Diagnostic/FileDiagnosticModal";
|
||||||
@ -6,6 +16,7 @@ import { ImportData, saveObject } from "../../SaveObject";
|
|||||||
import { StyleEditorButton } from "../../Themes/ui/StyleEditorButton";
|
import { StyleEditorButton } from "../../Themes/ui/StyleEditorButton";
|
||||||
import { ThemeEditorButton } from "../../Themes/ui/ThemeEditorButton";
|
import { ThemeEditorButton } from "../../Themes/ui/ThemeEditorButton";
|
||||||
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
|
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
|
||||||
|
import { CreditsModal } from "./CreditsModal";
|
||||||
import { DeleteGameButton } from "../../ui/React/DeleteGameButton";
|
import { DeleteGameButton } from "../../ui/React/DeleteGameButton";
|
||||||
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
import { SnackbarEvents } from "../../ui/React/Snackbar";
|
||||||
import { ToastVariant } from "@enums";
|
import { ToastVariant } from "@enums";
|
||||||
@ -49,6 +60,7 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => {
|
|||||||
const [importData, setImportData] = useState<ImportData | null>(null);
|
const [importData, setImportData] = useState<ImportData | null>(null);
|
||||||
|
|
||||||
const [confirmResetOpen, setConfirmResetOpen] = useState(false);
|
const [confirmResetOpen, setConfirmResetOpen] = useState(false);
|
||||||
|
const [creditsOpen, setCreditsOpen] = useState(false);
|
||||||
|
|
||||||
function startImport(): void {
|
function startImport(): void {
|
||||||
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) return;
|
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) return;
|
||||||
@ -225,7 +237,8 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => {
|
|||||||
sx={{
|
sx={{
|
||||||
gridArea: "links",
|
gridArea: "links",
|
||||||
display: "grid",
|
display: "grid",
|
||||||
gridTemplateAreas: `"bug bug"
|
gridTemplateAreas: `"credits credits"
|
||||||
|
"bug bug"
|
||||||
"discord reddit"
|
"discord reddit"
|
||||||
"tut tut"
|
"tut tut"
|
||||||
"plaza plaza"`,
|
"plaza plaza"`,
|
||||||
@ -233,14 +246,20 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => {
|
|||||||
my: 1,
|
my: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Tooltip title={<Typography>Start a GitHub issue to help the devs find bugs!</Typography>}>
|
||||||
startIcon={<BugReport />}
|
<Button
|
||||||
href="https://github.com/bitburner-official/bitburner-src/issues/new"
|
startIcon={<BugReport />}
|
||||||
target="_blank"
|
href="https://github.com/bitburner-official/bitburner-src/issues/new"
|
||||||
sx={{ gridArea: "bug" }}
|
target="_blank"
|
||||||
>
|
sx={{ gridArea: "bug" }}
|
||||||
Report Bug
|
>
|
||||||
|
Report Bug
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<Button startIcon={<Fingerprint />} onClick={() => setCreditsOpen(true)} sx={{ gridArea: "credits" }}>
|
||||||
|
Credits
|
||||||
</Button>
|
</Button>
|
||||||
|
<CreditsModal open={creditsOpen} onClose={() => setCreditsOpen(false)} />
|
||||||
<Button startIcon={<LibraryBooks />} onClick={() => setConfirmResetOpen(true)} sx={{ gridArea: "tut" }}>
|
<Button startIcon={<LibraryBooks />} onClick={() => setConfirmResetOpen(true)} sx={{ gridArea: "tut" }}>
|
||||||
Reset tutorial
|
Reset tutorial
|
||||||
</Button>
|
</Button>
|
||||||
|
Loading…
Reference in New Issue
Block a user