diff --git a/src/game.js b/src/game.js index 88bbf8e..04dcf3e 100644 --- a/src/game.js +++ b/src/game.js @@ -1,4 +1,4 @@ -import { formatCount } from "./util"; +import { formatANoun, formatCount } from "./util"; export const BASE_RATING = 1200; export const SCALING_FACTOR = 800; @@ -139,7 +139,7 @@ export function addCard(deck, card, gameMode, findState) { } const set = setTypes[setType].checkFn(...cards); if (!set) { - return { kind: "error", cards, error: `Not a ${setType}` }; + return { kind: "error", cards, error: `Not ${formatANoun(setType)}` }; } if (modes[gameMode].puzzle && foundSets.has(set.slice().sort().join("|"))) { return { kind: "error", cards, error: `This ${setType} was already found` }; diff --git a/src/pages/BannedPage.js b/src/pages/BannedPage.js index de98665..f797bf8 100644 --- a/src/pages/BannedPage.js +++ b/src/pages/BannedPage.js @@ -2,8 +2,9 @@ import Container from "@material-ui/core/Container"; import Link from "@material-ui/core/Link"; import Typography from "@material-ui/core/Typography"; +import { formatDateTime } from "../util"; + function BannedPage({ time }) { - const date = new Date(time); return ( @@ -11,7 +12,7 @@ function BannedPage({ time }) { Due to a violation of the site's code of conduct,{" "} - you have been banned until {date.toLocaleString()}. + you have been banned until {formatDateTime(time)}. Please take some time to cool off. If you have questions about this, diff --git a/src/pages/GamePage.js b/src/pages/GamePage.js index 3f9e29a..93b3b8b 100644 --- a/src/pages/GamePage.js +++ b/src/pages/GamePage.js @@ -37,6 +37,7 @@ import { } from "../game"; import useFirebaseRef from "../hooks/useFirebaseRef"; import useKeydown, { getModifierState } from "../hooks/useKeydown"; +import { formatANoun } from "../util"; import LoadingPage from "./LoadingPage"; import NotFoundPage from "./NotFoundPage"; @@ -288,7 +289,7 @@ function GamePage({ match }) { setSnack({ open: true, variant: "success", - message: `Found a ${state.setType}`, + message: `Found ${formatANoun(state.setType)}`, }); } return []; diff --git a/src/util.js b/src/util.js index 9b297ad..f3e7c24 100644 --- a/src/util.js +++ b/src/util.js @@ -143,6 +143,11 @@ export function formatCount(count, singular, plural = null) { return `${count} ${noun}`; } +export function formatANoun(word) { + const a = /^[aeiou]/i.test(word) ? "an" : "a"; // crud heuristic + return `${a} ${word}`; +} + export function censorText(text) { return censor.applyTo(text, badWords.getAllMatches(text)); } @@ -153,8 +158,8 @@ export function capitalizeFirst(text) { export function formatDateTime(timestamp) { const d = new Date(timestamp); - const opts = { timeStyle: "short", hour12: false }; - return `${d.toLocaleDateString()} ${d.toLocaleTimeString(undefined, opts)}`; + const opts = { dateStyle: "medium", timeStyle: "short", hour12: false }; + return d.toLocaleString(undefined, opts); } export function parseDuration(spec) { diff --git a/src/util.test.js b/src/util.test.js index d7673fe..89b3b4e 100644 --- a/src/util.test.js +++ b/src/util.test.js @@ -1,4 +1,4 @@ -import { badWords, parseDuration } from "./util"; +import { badWords, formatANoun, parseDuration } from "./util"; describe("bad words filter", () => { it("sort of works", () => { @@ -17,6 +17,13 @@ describe("bad words filter", () => { }); }); +it("parseDuration works", () => { + expect(formatANoun("Set")).toBe("a Set"); + expect(formatANoun("UltraSet")).toBe("an UltraSet"); + expect(formatANoun("GhostSet")).toBe("a GhostSet"); + expect(formatANoun("4Set")).toBe("a 4Set"); +}); + it("parseDuration works", () => { expect(parseDuration("2w")).toBe(2 * 7 * 24 * 3600); expect(parseDuration("3d")).toBe(3 * 24 * 3600);