Skip to content

Commit

Permalink
BUGFIX: Wrong plural form in modal of coding contract (#1939)
Browse files Browse the repository at this point in the history
  • Loading branch information
catloversg authored Feb 2, 2025
1 parent 1cc0288 commit 67aff2a
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 20 deletions.
4 changes: 3 additions & 1 deletion src/Achievements/AchievementList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Achievement, PlayerAchievement } from "./Achievements";
import { Settings } from "../Settings/Settings";
import { getFiltersFromHex } from "../ThirdParty/colorUtils";
import { CorruptableText } from "../ui/React/CorruptableText";
import { pluralize } from "../utils/I18nUtils";

interface IProps {
achievements: Achievement[];
Expand Down Expand Up @@ -101,7 +102,8 @@ export function AchievementList({ achievements, playerAchievements }: IProps): J
</AccordionSummary>
<AccordionDetails>
<Typography sx={{ mt: 1 }}>
{unavailable.length} additional achievements hidden behind content you don't have access to.
{pluralize(unavailable.length, "additional achievement")} hidden behind content you don't have access
to.
</Typography>
</AccordionDetails>
</Accordion>
Expand Down
5 changes: 2 additions & 3 deletions src/Bladeburner/Bladeburner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { shuffleArray } from "../Infiltration/ui/BribeGame";
import { assertObject } from "../utils/TypeAssertion";
import { throwIfReachable } from "../utils/helpers/throwIfReachable";
import { loadActionIdentifier } from "./utils/loadActionIdentifier";
import { pluralize } from "../utils/I18nUtils";

export const BladeburnerPromise: PromisePair<number> = { promise: null, resolve: null };

Expand Down Expand Up @@ -167,9 +168,7 @@ export class Bladeburner implements OperationTeam {
this.setSkillLevel(skillName, currentSkillLevel + availability.actualCount);
return {
success: true,
message: `Upgraded skill ${skillName} by ${availability.actualCount} level${
availability.actualCount > 1 ? "s" : ""
}`,
message: `Upgraded skill ${skillName} by ${pluralize(availability.actualCount, "level")}`,
};
}

Expand Down
5 changes: 2 additions & 3 deletions src/Gang/ui/RecruitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import { RecruitmentResult } from "../Gang";
import { pluralize } from "../../utils/I18nUtils";

interface IProps {
onRecruit: () => void;
Expand Down Expand Up @@ -35,9 +36,7 @@ export function RecruitButton(props: IProps): React.ReactElement {
<>
<Box display="flex" alignItems="center" sx={{ mx: 1 }}>
<Button onClick={() => setOpen(true)}>Recruit Gang Member</Button>
<Typography sx={{ ml: 1 }}>
Can recruit {recruitsAvailable} more gang member{recruitsAvailable === 1 ? "" : "s"}
</Typography>
<Typography sx={{ ml: 1 }}>Can recruit {pluralize(recruitsAvailable, "more gang member")}</Typography>
</Box>
<RecruitModal open={open} onClose={() => setOpen(false)} onRecruit={props.onRecruit} />
</>
Expand Down
10 changes: 4 additions & 6 deletions src/Terminal/commands/grep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ContentFile, ContentFilePath, allContentFiles } from "../../Paths/Conte
import { Settings } from "../../Settings/Settings";
import { help } from "../commands/help";
import { Output } from "../OutputTypes";
import { pluralize } from "../../utils/I18nUtils";

type LineParser = (options: Options, filename: string, line: string, i: number) => ParsedLine;

Expand Down Expand Up @@ -290,12 +291,9 @@ class Results {

getVerboseInfo(files: ContentFile[], pattern: string | RegExp, options: Options): string {
if (!options.isVerbose) return "";
const suffix = (pre: string, num: number) => pre + (num === 1 ? "" : "s");
const totalLines = this.results.length;
const matchCount = Math.abs((options.isInvertMatch ? totalLines : 0) - this.numMatches);
const inputStr = options.isPipeIn
? "piped from terminal "
: `in ${files.length} ${suffix("file", files.length)}:\n`;
const inputStr = options.isPipeIn ? "piped from terminal " : `in ${pluralize(files.length, "file")}:\n`;
const filesStr = files
.map((file, i) => `${i % 2 ? WHITE : ""}${file.filename}(${file.content.split("\n").length}loc)${DEFAULT}`)
.join(", ");
Expand All @@ -304,9 +302,9 @@ class Results {
`\n${
(this.params.maxMatches ? this.params.maxMatches : matchCount) + (options.isInvertMatch ? " INVERTED" : "")
} `,
suffix("line", matchCount) + " matched ",
pluralize(matchCount, "line", undefined, true) + " matched ",
`against PATTERN "${pattern.toString()}" `,
`in ${totalLines} ${suffix("line", totalLines)}, `,
`in ${pluralize(totalLines, "line")}, `,
inputStr,
`${filesStr}`,
].join("");
Expand Down
5 changes: 4 additions & 1 deletion src/Terminal/commands/runScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ScriptFilePath, isLegacyScript } from "../../Paths/ScriptFilePath";
import { sendDeprecationNotice } from "./common/deprecation";
import { roundToTwo } from "../../utils/helpers/roundToTwo";
import { RamCostConstants } from "../../Netscript/RamCostGenerator";
import { pluralize } from "../../utils/I18nUtils";

export function runScript(path: ScriptFilePath, commandArgs: (string | number | boolean)[], server: BaseServer): void {
// This takes in the absolute filepath, see "run.ts"
Expand Down Expand Up @@ -77,7 +78,9 @@ export function runScript(path: ScriptFilePath, commandArgs: (string | number |
sendDeprecationNotice();
}
Terminal.print(
`Running script with ${numThreads} thread(s), pid ${runningScript.pid} and args: ${JSON.stringify(args)}.`,
`Running script with ${pluralize(numThreads, "thread")}, pid ${runningScript.pid} and args: ${JSON.stringify(
args,
)}.`,
);
if (tailFlag) {
LogBoxEvents.emit(runningScript);
Expand Down
6 changes: 4 additions & 2 deletions src/ui/React/CodingContractModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import { pluralize } from "../../utils/I18nUtils";

interface CodingContractProps {
c: CodingContract;
Expand Down Expand Up @@ -63,8 +64,9 @@ export function CodingContractModal(): React.ReactElement {
<Modal open={contract !== null} onClose={close}>
<CopyableText variant="h4" value={contract.c.type} />
<Typography>
You are attempting to solve a Coding Contract. You have {contract.c.getMaxNumTries() - contract.c.tries} tries
remaining, after which the contract will self-destruct.
You are attempting to solve a Coding Contract. You have{" "}
{pluralize(contract.c.getMaxNumTries() - contract.c.tries, "try", "tries")} remaining, after which the contract
will self-destruct.
</Typography>
<br />
<Typography>{description}</Typography>
Expand Down
5 changes: 4 additions & 1 deletion src/utils/APIBreaks/APIBreak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { GetAllServers } from "../../Server/AllServers";
import { resolveTextFilePath } from "../../Paths/TextFilePath";
import { dialogBoxCreate as dialogBoxCreateOriginal } from "../../ui/React/DialogBox";
import { Terminal } from "../../Terminal";
import { pluralize } from "../I18nUtils";

// Temporary until fixing alerts manager to store alerts outside of react scope
const dialogBoxCreate = (text: string) => setTimeout(() => dialogBoxCreateOriginal(text), 2000);
Expand Down Expand Up @@ -64,7 +65,9 @@ export function showAPIBreaks(version: string, ...breakInfos: APIBreakInfo[]) {
[...scriptImpactMap]
.map(
([filename, lineNumbers]) =>
`${filename}: (Line number${lineNumbers.length > 1 ? "s" : ""}: ${lineNumbers.join(", ")})`,
`${filename}: (${pluralize(lineNumbers.length, "Line number", undefined, true)}: ${lineNumbers.join(
", ",
)})`,
)
.join("\n"),
)
Expand Down
10 changes: 10 additions & 0 deletions src/utils/I18nUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const pluralRules = new Intl.PluralRules("en-US");

export function pluralize(count: number, singular: string, plural?: string, skipCountInReturnedValue = false): string {
const countText = !skipCountInReturnedValue ? `${count} ` : "";
const pluralRule = pluralRules.select(count);
if (pluralRule === "one") {
return countText + singular;
}
return countText + (plural !== undefined ? plural : `${singular}s`);
}
7 changes: 4 additions & 3 deletions src/utils/StringHelperFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Settings } from "../Settings/Settings";
import { CONSTANTS } from "../Constants";
import { pluralize } from "./I18nUtils";

/*
Converts a date representing time in milliseconds to a string with the format H hours M minutes and S seconds
Expand Down Expand Up @@ -38,13 +39,13 @@ export function convertTimeMsToTimeElapsedString(time: number, showMilli = false

let res = "";
if (days > 0) {
res += `${days} day${days === 1 ? "" : "s"} `;
res += `${pluralize(days, "day")} `;
}
if (hours > 0 || (Settings.ShowMiddleNullTimeUnit && res != "")) {
res += `${hours} hour${hours === 1 ? "" : "s"} `;
res += `${pluralize(hours, "hour")} `;
}
if (minutes > 0 || (Settings.ShowMiddleNullTimeUnit && res != "")) {
res += `${minutes} minute${minutes === 1 ? "" : "s"} `;
res += `${pluralize(minutes, "minute")} `;
}
res += `${seconds} second${!showMilli && secTruncMinutes === 1 ? "" : "s"}`;

Expand Down

0 comments on commit 67aff2a

Please sign in to comment.