Skip to content

Commit c97778c

Browse files
committed
Include the unchecked words in the share output
To test this we need a reliable order - not great having a boolean flag at all, let alone one which is only used in tests - maybe there's a better way?
1 parent 3f827f9 commit c97778c

File tree

5 files changed

+106
-14
lines changed

5 files changed

+106
-14
lines changed

src/components/Card.test.tsx

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe("'New card' button", () => {
1212
test("changes the words on the card", () => {
1313
render(
1414
<BrowserRouter>
15-
<Card wordList={wordList} name={""} url={""} id={""} />
15+
<Card wordList={wordList} name={""} url={""} id={""} randomise={true} />
1616
</BrowserRouter>,
1717
);
1818
const initialCells = screen.queryAllByRole("gridcell");
@@ -29,7 +29,7 @@ describe("'New card' button", () => {
2929
test("clears any stamped cells", () => {
3030
render(
3131
<BrowserRouter>
32-
<Card wordList={wordList} name={""} url={""} id={""} />
32+
<Card wordList={wordList} name={""} url={""} id={""} randomise={true} />
3333
</BrowserRouter>,
3434
);
3535
const cells = screen.queryAllByRole("gridcell");
@@ -48,7 +48,7 @@ describe("'Clear' button", () => {
4848
test("clears any stamped cells", () => {
4949
render(
5050
<BrowserRouter>
51-
<Card wordList={wordList} name={""} url={""} id={""} />
51+
<Card wordList={wordList} name={""} url={""} id={""} randomise={true} />
5252
</BrowserRouter>,
5353
);
5454
const cells = screen.queryAllByRole("gridcell");
@@ -70,13 +70,47 @@ describe("'Clear' button", () => {
7070

7171
describe("'Share' button", () => {
7272
test("copies a representation of the card to the clipboard", async () => {
73+
const coordinates = [
74+
"A1",
75+
"A&nbsp;2", // non-breaking space
76+
"A&shy;3", // soft hyphen (only displays if the text wraps)
77+
"A&shy;&shy;4", // multiple hyphens
78+
"B1",
79+
"A5", // out of alphabetical order
80+
"B2",
81+
"B3",
82+
"B4",
83+
"B5",
84+
"C1",
85+
"C2",
86+
"C3",
87+
"C4",
88+
"C5",
89+
"D1",
90+
"D2",
91+
"D3",
92+
"D4",
93+
"D5",
94+
"E1",
95+
"E2",
96+
"E3",
97+
"E4",
98+
"E5",
99+
];
73100
const user = userEvent.setup();
74101
render(
75102
<BrowserRouter>
76-
<Card wordList={wordList} name={""} url={""} id={""} />
103+
<Card
104+
wordList={coordinates}
105+
name={""}
106+
url={""}
107+
id={""}
108+
randomise={false}
109+
/>
77110
<textarea rows={5} />
78111
</BrowserRouter>,
79112
);
113+
fireEvent.click(screen.getByText("New card"));
80114
const cells = screen.queryAllByRole("gridcell");
81115
const firstCell = cells[0];
82116
const lastCell = cells[24];
@@ -94,12 +128,36 @@ describe("'Share' button", () => {
94128
await user.click(textBox);
95129
await user.paste();
96130

97-
const emojiGrid = `
131+
const message = `
98132
🟦⬜⬜⬜⬜
99133
⬜⬜⬜⬜⬜
100134
⬜⬜⬜⬜⬜
101135
⬜⬜⬜⬜⬜
102-
⬜⬜⬜⬜🟦`;
103-
expect(textBox).toHaveValue(stripIndent(emojiGrid).trim());
136+
⬜⬜⬜⬜🟦
137+
Remaining:
138+
- A 2
139+
- A3
140+
- A4
141+
- A5
142+
- B1
143+
- B2
144+
- B3
145+
- B4
146+
- B5
147+
- C1
148+
- C2
149+
- C3
150+
- C4
151+
- C5
152+
- D1
153+
- D2
154+
- D3
155+
- D4
156+
- D5
157+
- E1
158+
- E2
159+
- E3
160+
- E4`;
161+
expect(textBox).toHaveValue(stripIndent(message).trim());
104162
});
105163
});

src/components/Card.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@ import Grid from "./Grid";
55
import MainLayout from "../layouts/MainLayout";
66
import emojiGrid from "../lib/emojiGrid";
77
import share from "../lib/share";
8-
import type { CellProps } from "./Cell";
8+
import { formatWord } from "../lib/normaliseWord";
9+
import type { CellProps, CellData } from "./Cell";
910
import type { ButtonClickHandler } from "../clickHandler";
1011

1112
const Card: React.FC<{
1213
id: string;
1314
name?: string;
1415
url: string;
1516
wordList: string[];
17+
randomise: boolean;
1618
videoListUrl?: string;
17-
}> = ({ id, name, url, wordList, videoListUrl }) => {
19+
}> = ({ id, name, url, wordList, randomise = true, videoListUrl }) => {
1820
const [cellDataList, toggleStamped, setNewWords, clearAllCells] = useCard(
1921
id,
2022
wordList,
23+
randomise,
2124
);
2225

2326
const cellPropsList: CellProps[] = cellDataList.map((cellData, index) => ({
@@ -26,14 +29,26 @@ const Card: React.FC<{
2629
}));
2730

2831
const shareCard: ButtonClickHandler = () => {
29-
const message = emojiGrid(cellDataList);
32+
const wordBullets = remainingWords(cellDataList).map((word) => `- ${word}`);
33+
const message = [
34+
emojiGrid(cellDataList),
35+
"Remaining:",
36+
...wordBullets,
37+
].join("\n");
3038
share({
3139
title: `${name} Bingo`,
3240
text: message,
3341
url: url,
3442
});
3543
};
3644

45+
const remainingWords = (cellDataList: CellData[]): string[] =>
46+
cellDataList
47+
.filter((cellData) => !cellData.stamped)
48+
.map((cellData) => cellData.word)
49+
.map(formatWord)
50+
.sort();
51+
3752
const headerContent = (
3853
<CardActions
3954
newClick={setNewWords}

src/hooks/useCard.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import useSession from "../hooks/useSession";
2-
import shuffle from "../lib/shuffle";
2+
import shuffle, { ArrayTransformation } from "../lib/shuffle";
33
import type { CellData, CellClickHandler } from "../components/Cell";
44
import type { ButtonClickHandler } from "../clickHandler";
55

@@ -10,8 +10,22 @@ type GetterSetters = [
1010
ButtonClickHandler,
1111
];
1212

13-
const useCard = (id: string, wordList: string[]): GetterSetters => {
14-
const newWords = (): string[] => shuffle(wordList).slice(0, 25);
13+
const useCard = (
14+
id: string,
15+
wordList: string[],
16+
randomise: boolean,
17+
): GetterSetters => {
18+
const newWords = (): string[] => orderer()(wordList).slice(0, 25);
19+
20+
const orderer = (): ArrayTransformation => {
21+
if (randomise) {
22+
return shuffle;
23+
} else {
24+
return nullOrderer;
25+
}
26+
};
27+
28+
const nullOrderer: ArrayTransformation = (array) => array;
1529

1630
const newCellDataList = function (): CellData[] {
1731
return newWords().map((word) => {

src/lib/normaliseWord.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ const normaliseWord = (string: string): string =>
77
.replace(new RegExp(htmlSoftHyphen, "g"), unicodeSoftHyphen)
88
.replace(new RegExp(htmlNonBreakingSpace, "g"), unicodeNonBreakingSpace);
99

10+
export const formatWord = (string: string): string =>
11+
string
12+
.replace(new RegExp(htmlSoftHyphen, "g"), "")
13+
.replace(new RegExp(htmlNonBreakingSpace, "g"), " ");
14+
1015
export default normaliseWord;

src/lib/shuffle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Implementation of the Fisher-Yates (aka Knuth) Shuffle
22
// Lifted from https://stackoverflow.com/a/2450976
33

4-
type ArrayTransformation = <T>(array: T[]) => T[];
4+
export type ArrayTransformation = <T>(array: T[]) => T[];
55

66
const shuffle: ArrayTransformation = (array) => {
77
let currentIndex = array.length,

0 commit comments

Comments
 (0)