Skip to content

Commit c00c3f3

Browse files
Add contextual fun facts to Watch Mode
- Restructure funfacts.json with season/contestant tags (60 facts) - Show relevant fun facts during task scoring in Watch Mode - Priority: contestant-specific > season-specific > general facts - No repeats per player within a game session - Dashboard updated to handle new tagged format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1730844 commit c00c3f3

4 files changed

Lines changed: 136 additions & 33 deletions

File tree

client/public/data/funfacts.json

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,62 @@
11
[
2-
"Mel Giedroyc (Series 4) is the only contestant to win the same prize twice — Ray's shampoo bag.",
3-
"The Taskmaster house is actually a former groundskeeper's cottage on a golf course in Chiswick, west London.",
4-
"Alex Horne never intended to be the Taskmaster himself — he always wanted to be on the ground with contestants.",
5-
"Bob Mortimer (Series 5) filmed some tasks in November and others in May — flowers had bloomed between shoots.",
6-
"Mel Giedroyc completed all her tasks in roughly a single week — one of the fastest filming stints ever.",
7-
"The show was originally a live stage show at the Edinburgh Festival Fringe before becoming a TV series.",
8-
"Greg Davies' golden head bust that winners receive is made of resin and weighs about 2kg.",
9-
"There's a task involving popping an entire roll of bubble wrap that has been tried in Series 1, 2, and 3 — but never aired because it made terrible TV.",
10-
"Frank Skinner agreed to do Series 1, which Alex Horne credits as a major stamp of approval that helped recruit future contestants.",
11-
"The Taskmaster crew is surprisingly small — only about 15–20 people work behind the scenes.",
12-
"Alex Horne comes up with the majority of tasks himself, though the small crew pitches in ideas too.",
13-
"Contestants are kept in a tiny green room between tasks — described as 'fundamentally rock 'n' roll' with a jar of sweets and a fridge.",
14-
"Each series, the Taskmaster house is redecorated with a different theme inspired by a specific artist.",
15-
"The studio tasks are always tested beforehand, but location tasks are almost never tried out before filming.",
16-
"Romesh Ranganathan nearly choked on a watermelon on the very first day of filming Series 1.",
17-
"Ed Gamble (Series 9 winner) is the only contestant who went on to co-host the Taskmaster podcast.",
18-
"Jo Brand (Series 9) famously chose a caravan holiday for the entire cast as the final prize — nobody wanted it.",
19-
"James Acaster (Series 7) scored the lowest ever points in a single episode with just 2 points.",
20-
"Lee Mack (Series 11) won 7 out of 10 episodes — the highest episode win rate in show history at the time.",
21-
"The show moved from Dave to Channel 4 starting with Series 10.",
22-
"Bob Mortimer's Fuji 9 segment and 'Do we need em?' became one of the most beloved moments in Taskmaster history.",
23-
"There have been over 45 international versions of Taskmaster, including in Norway, Sweden, and New Zealand.",
24-
"The Taskmaster house garden has been the site of over 500 individual task attempts across all series.",
25-
"Liza Tarbuck (Series 6 winner) was known for her creative lateral thinking, often finding loopholes in tasks.",
26-
"Rhod Gilbert (Series 7) holds the record for the most heated arguments with the Taskmaster Greg Davies.",
27-
"The iconic 'Your time starts now' phrase was inspired by Alex Horne's love of countdown-based games.",
28-
"Paul Sinha (Series 8) is also a professional quizzer known as 'The Sinnerman' on The Chase.",
29-
"Noel Fielding (Series 4 winner) brought his signature surreal art style to many creative tasks.",
30-
"Sarah Kendall (Series 11 winner) was the first Australian contestant on the show.",
31-
"The Taskmaster New Year's specials feature returning champions competing against each other."
2+
{ "text": "Mel Giedroyc (Series 4) is the only contestant to win the same prize twice — Ray's shampoo bag.", "seasons": [4], "contestants": ["Mel Giedroyc"] },
3+
{ "text": "The Taskmaster house is actually a former groundskeeper's cottage on a golf course in Chiswick, west London.", "seasons": [], "contestants": [] },
4+
{ "text": "Alex Horne never intended to be the Taskmaster himself — he always wanted to be on the ground with contestants.", "seasons": [], "contestants": [] },
5+
{ "text": "Bob Mortimer (Series 5) filmed some tasks in November and others in May — flowers had bloomed between shoots.", "seasons": [5], "contestants": ["Bob Mortimer"] },
6+
{ "text": "Mel Giedroyc completed all her tasks in roughly a single week — one of the fastest filming stints ever.", "seasons": [4], "contestants": ["Mel Giedroyc"] },
7+
{ "text": "The show was originally a live stage show at the Edinburgh Festival Fringe before becoming a TV series.", "seasons": [], "contestants": [] },
8+
{ "text": "Greg Davies' golden head bust that winners receive is made of resin and weighs about 2kg.", "seasons": [], "contestants": [] },
9+
{ "text": "There's a task involving popping an entire roll of bubble wrap that has been tried in Series 1, 2, and 3 — but never aired because it made terrible TV.", "seasons": [1, 2, 3], "contestants": [] },
10+
{ "text": "Frank Skinner agreed to do Series 1, which Alex Horne credits as a major stamp of approval that helped recruit future contestants.", "seasons": [1], "contestants": ["Frank Skinner"] },
11+
{ "text": "The Taskmaster crew is surprisingly small — only about 15–20 people work behind the scenes.", "seasons": [], "contestants": [] },
12+
{ "text": "Alex Horne comes up with the majority of tasks himself, though the small crew pitches in ideas too.", "seasons": [], "contestants": [] },
13+
{ "text": "Contestants are kept in a tiny green room between tasks — described as 'fundamentally rock 'n' roll' with a jar of sweets and a fridge.", "seasons": [], "contestants": [] },
14+
{ "text": "Each series, the Taskmaster house is redecorated with a different theme inspired by a specific artist.", "seasons": [], "contestants": [] },
15+
{ "text": "The studio tasks are always tested beforehand, but location tasks are almost never tried out before filming.", "seasons": [], "contestants": [] },
16+
{ "text": "Romesh Ranganathan nearly choked on a watermelon on the very first day of filming Series 1.", "seasons": [1], "contestants": ["Romesh Ranganathan"] },
17+
{ "text": "Ed Gamble (Series 9 winner) is the only contestant who went on to co-host the Taskmaster podcast.", "seasons": [9], "contestants": ["Ed Gamble"] },
18+
{ "text": "Jo Brand (Series 9) famously chose a caravan holiday for the entire cast as the final prize — nobody wanted it.", "seasons": [9], "contestants": ["Jo Brand"] },
19+
{ "text": "James Acaster (Series 7) scored the lowest ever points in a single episode with just 2 points.", "seasons": [7], "contestants": ["James Acaster"] },
20+
{ "text": "Lee Mack (Series 11) won 7 out of 10 episodes — the highest episode win rate in show history at the time.", "seasons": [11], "contestants": ["Lee Mack"] },
21+
{ "text": "The show moved from Dave to Channel 4 starting with Series 10.", "seasons": [10], "contestants": [] },
22+
{ "text": "Bob Mortimer's Fuji 9 segment and 'Do we need em?' became one of the most beloved moments in Taskmaster history.", "seasons": [5], "contestants": ["Bob Mortimer"] },
23+
{ "text": "There have been over 45 international versions of Taskmaster, including in Norway, Sweden, and New Zealand.", "seasons": [], "contestants": [] },
24+
{ "text": "The Taskmaster house garden has been the site of over 500 individual task attempts across all series.", "seasons": [], "contestants": [] },
25+
{ "text": "Liza Tarbuck (Series 6 winner) was known for her creative lateral thinking, often finding loopholes in tasks.", "seasons": [6], "contestants": ["Liza Tarbuck"] },
26+
{ "text": "Rhod Gilbert (Series 7) holds the record for the most heated arguments with the Taskmaster Greg Davies.", "seasons": [7], "contestants": ["Rhod Gilbert"] },
27+
{ "text": "The iconic 'Your time starts now' phrase was inspired by Alex Horne's love of countdown-based games.", "seasons": [], "contestants": [] },
28+
{ "text": "Paul Sinha (Series 8) is also a professional quizzer known as 'The Sinnerman' on The Chase.", "seasons": [8], "contestants": ["Paul Sinha"] },
29+
{ "text": "Noel Fielding (Series 4 winner) brought his signature surreal art style to many creative tasks.", "seasons": [4], "contestants": ["Noel Fielding"] },
30+
{ "text": "Sarah Kendall (Series 11 winner) was the first Australian contestant on the show.", "seasons": [11], "contestants": ["Sarah Kendall"] },
31+
{ "text": "The Taskmaster New Year's specials feature returning champions competing against each other.", "seasons": [], "contestants": [] },
32+
{ "text": "Josh Widdicombe won the very first series of Taskmaster and set the bar for future champions.", "seasons": [1], "contestants": ["Josh Widdicombe"] },
33+
{ "text": "Tim Key (Series 1) is a poet as well as a comedian — he brought a uniquely literary approach to tasks.", "seasons": [1], "contestants": ["Tim Key"] },
34+
{ "text": "Roisin Conaty (Series 1) accidentally left a potato in her handbag for weeks during a task.", "seasons": [1], "contestants": ["Roisin Conaty"] },
35+
{ "text": "Joe Wilkinson (Series 2) was disqualified from a task for stepping over a line — one of the show's most infamous moments.", "seasons": [2], "contestants": ["Joe Wilkinson"] },
36+
{ "text": "Richard Osman (Series 2) is 6'7\" tall, making him one of the tallest contestants in the show's history.", "seasons": [2], "contestants": ["Richard Osman"] },
37+
{ "text": "Katherine Ryan (Series 2) was the first Canadian contestant on the show.", "seasons": [2], "contestants": ["Katherine Ryan"] },
38+
{ "text": "Rob Beckett (Series 3 winner) credits his competitive nature for carrying him to victory.", "seasons": [3], "contestants": ["Rob Beckett"] },
39+
{ "text": "Dave Gorman (Series 3) is known for his data-driven comedy — a skill that sometimes helped with analytical tasks.", "seasons": [3], "contestants": ["Dave Gorman"] },
40+
{ "text": "Hugh Dennis (Series 4) was one of the oldest contestants when he appeared and brought dad-joke energy to every task.", "seasons": [4], "contestants": ["Hugh Dennis"] },
41+
{ "text": "Joe Lycett (Series 4) legally changed his name to Hugo Boss in a publicity stunt before appearing on the show.", "seasons": [4], "contestants": ["Joe Lycett"] },
42+
{ "text": "Aisling Bea (Series 5) was the first Irish contestant on Taskmaster.", "seasons": [5], "contestants": ["Aisling Bea"] },
43+
{ "text": "Sally Phillips (Series 5) famously tried to befriend the Taskmaster's assistant during tasks.", "seasons": [5], "contestants": ["Sally Phillips"] },
44+
{ "text": "Nish Kumar (Series 5) is known for being one of the most enthusiastic but least successful contestants.", "seasons": [5], "contestants": ["Nish Kumar"] },
45+
{ "text": "Russell Howard (Series 6) brought boundless energy and often tried physical solutions to creative tasks.", "seasons": [6], "contestants": ["Russell Howard"] },
46+
{ "text": "Tim Vine (Series 6) holds a Guinness World Record for the most jokes told in an hour.", "seasons": [6], "contestants": ["Tim Vine"] },
47+
{ "text": "Phil Wang (Series 7) famously asked philosophical questions about whether something counted as completing a task.", "seasons": [7], "contestants": ["Phil Wang"] },
48+
{ "text": "Kerry Godliman (Series 7 winner) was praised for her consistent, methodical approach to tasks.", "seasons": [7], "contestants": ["Kerry Godliman"] },
49+
{ "text": "Iain Stirling (Series 8) is the voice of Love Island — he brought narration-style humour to his tasks.", "seasons": [8], "contestants": ["Iain Stirling"] },
50+
{ "text": "Sian Gibson (Series 8) is best known for co-starring in Peter Kay's Car Share.", "seasons": [8], "contestants": ["Sian Gibson"] },
51+
{ "text": "Lou Sanders (Series 8 winner) had one of the most unpredictable and chaotic approaches to tasks.", "seasons": [8], "contestants": ["Lou Sanders"] },
52+
{ "text": "Rose Matafeo (Series 9) won the Edinburgh Comedy Award the same year she appeared on Taskmaster.", "seasons": [9], "contestants": ["Rose Matafeo"] },
53+
{ "text": "David Baddiel (Series 9) admitted to being terrible at practical tasks but excelled at prize tasks.", "seasons": [9], "contestants": ["David Baddiel"] },
54+
{ "text": "Mike Wozniak (Series 11) became a fan favourite for his gentlemanly demeanour and unexpected task solutions.", "seasons": [11], "contestants": ["Mike Wozniak"] },
55+
{ "text": "Charlotte Ritchie (Series 11) revealed that filming tasks took about five solid days of shooting.", "seasons": [11], "contestants": ["Charlotte Ritchie"] },
56+
{ "text": "Victoria Coren Mitchell (Series 12) is the only person to win two separate televised poker tournaments.", "seasons": [12], "contestants": ["Victoria Coren Mitchell"] },
57+
{ "text": "Alan Davies (Series 12) is best known as the permanent panelist on QI for over 19 years.", "seasons": [12], "contestants": ["Alan Davies"] },
58+
{ "text": "Dara Ó Briain (Series 14 winner) has a degree in mathematical physics from University College Dublin.", "seasons": [14], "contestants": ["Dara Ó Briain"] },
59+
{ "text": "Fern Brady (Series 14) wrote a bestselling memoir about growing up autistic before appearing on the show.", "seasons": [14], "contestants": ["Fern Brady"] },
60+
{ "text": "Frankie Boyle (Series 15) was known for his darkly creative approaches to the prize tasks.", "seasons": [15], "contestants": ["Frankie Boyle"] },
61+
{ "text": "Jack Dee (Series 18 winner) was the original host of I'm a Celebrity before becoming a Taskmaster champion.", "seasons": [18], "contestants": ["Jack Dee"] }
3262
]

client/src/components/Dashboard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ export default function Dashboard() {
118118
Promise.all([fetchAnalysis(), fetchContestants(), fetchFunFacts()]).then(([a, c, facts]) => {
119119
setAnalysis(a);
120120
setContestants(c);
121-
setFunFact(facts[Math.floor(Math.random() * facts.length)]);
121+
const fact = facts[Math.floor(Math.random() * facts.length)];
122+
setFunFact(typeof fact === "string" ? fact : fact.text);
122123
setLoading(false);
123124
});
124125
}, []);

client/src/components/WatchModeScorer.tsx

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { useState } from "react";
1+
import { useState, useEffect } from "react";
2+
import { fetchFunFacts } from "../hooks/useData";
3+
4+
interface FunFact {
5+
text: string;
6+
seasons: number[];
7+
contestants: string[];
8+
}
29

310
interface Task {
411
id: number;
@@ -28,6 +35,56 @@ export default function WatchModeScorer({ tasks, players, seasonNumber, onComple
2835
const [allScores, setAllScores] = useState<Record<string, Record<number, Record<number, number>>>>({});
2936
// allScores[playerId][taskId][contestantId] = score
3037
const [showResults, setShowResults] = useState(false);
38+
const [funFacts, setFunFacts] = useState<FunFact[]>([]);
39+
const [shownFacts, setShownFacts] = useState<Record<string, Set<string>>>({}); // playerId -> set of shown fact texts
40+
41+
useEffect(() => {
42+
fetchFunFacts().then((facts) => {
43+
setFunFacts(facts.map((f: FunFact | string) => typeof f === "string" ? { text: f, seasons: [], contestants: [] } : f));
44+
});
45+
}, []);
46+
47+
const seasonContestants = tasks[0]?.contestants.map((c) => c.name) || [];
48+
49+
// Pick a relevant, non-repeated fun fact for the current player
50+
const getFactForPlayer = (playerId: string): string | null => {
51+
const seen = shownFacts[playerId] || new Set<string>();
52+
// Priority 1: facts about contestants in this season
53+
const contestantFacts = funFacts.filter(
54+
(f) => f.contestants.some((c) => seasonContestants.includes(c)) && !seen.has(f.text)
55+
);
56+
if (contestantFacts.length > 0) return contestantFacts[Math.floor(Math.random() * contestantFacts.length)].text;
57+
// Priority 2: facts about this season number
58+
const seasonFacts = funFacts.filter(
59+
(f) => f.seasons.includes(seasonNumber) && !seen.has(f.text)
60+
);
61+
if (seasonFacts.length > 0) return seasonFacts[Math.floor(Math.random() * seasonFacts.length)].text;
62+
// Priority 3: general facts (no season/contestant tags)
63+
const generalFacts = funFacts.filter(
64+
(f) => f.seasons.length === 0 && f.contestants.length === 0 && !seen.has(f.text)
65+
);
66+
if (generalFacts.length > 0) return generalFacts[Math.floor(Math.random() * generalFacts.length)].text;
67+
return null;
68+
};
69+
70+
// Memoize the current fact so it doesn't change on re-render
71+
const [currentFact, setCurrentFact] = useState<string | null>(null);
72+
73+
useEffect(() => {
74+
if (funFacts.length === 0) return;
75+
const playerId = players[currentPlayerIdx]?.id;
76+
if (!playerId) return;
77+
const fact = getFactForPlayer(playerId);
78+
setCurrentFact(fact);
79+
if (fact) {
80+
setShownFacts((prev) => {
81+
const playerSeen = new Set(prev[playerId] || []);
82+
playerSeen.add(fact);
83+
return { ...prev, [playerId]: playerSeen };
84+
});
85+
}
86+
// eslint-disable-next-line react-hooks/exhaustive-deps
87+
}, [currentTaskIdx, currentPlayerIdx, funFacts]);
3188

3289
const currentTask = scorableTasks[currentTaskIdx];
3390
const currentPlayer = players[currentPlayerIdx];
@@ -165,6 +222,21 @@ export default function WatchModeScorer({ tasks, players, seasonNumber, onComple
165222
))}
166223
</div>
167224

225+
{currentFact && (
226+
<div style={{
227+
background: "linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)",
228+
border: "1px solid #334155",
229+
borderRadius: "8px",
230+
padding: "0.75rem 1rem",
231+
marginTop: "1rem",
232+
}}>
233+
<p style={{ margin: 0, fontSize: "0.85rem", color: "#94a3b8" }}>
234+
<span style={{ marginRight: "0.4rem" }}>💡</span>
235+
{currentFact}
236+
</p>
237+
</div>
238+
)}
239+
168240
<button
169241
className="btn-primary"
170242
style={{ width: "100%", marginTop: "1rem", padding: "0.75rem" }}

client/src/hooks/useData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export async function fetchAnalysis() {
2020
return res.json();
2121
}
2222

23-
export async function fetchFunFacts(): Promise<string[]> {
23+
export async function fetchFunFacts(): Promise<{ text: string; seasons: number[]; contestants: string[] }[]> {
2424
const res = await fetch(`${DATA_BASE}/funfacts.json`);
2525
return res.json();
2626
}

0 commit comments

Comments
 (0)