120 lines
2.9 KiB
TypeScript
120 lines
2.9 KiB
TypeScript
import type { Question } from "../party-types";
|
|
import {
|
|
buildOptionsWithCorrect,
|
|
buildOrderedOptions,
|
|
buildQuestionWindow,
|
|
getMostSharedGenreNames,
|
|
getTopClusterArtists,
|
|
getTopClusterTracks,
|
|
type PartyAnalytics,
|
|
pickRandom,
|
|
} from "./question-utils";
|
|
|
|
export function buildAudioMetadataQuestion(
|
|
analytics: PartyAnalytics,
|
|
index: number,
|
|
): Question {
|
|
type ChoiceQuestion = Extract<Question, { type: "choice" }>;
|
|
const questions: Array<
|
|
Omit<ChoiceQuestion, "startTimestamp" | "endTimestamp">
|
|
> = [];
|
|
|
|
const genreOptions = buildOrderedOptions(
|
|
getMostSharedGenreNames(analytics),
|
|
4,
|
|
);
|
|
if (genreOptions) {
|
|
questions.push({
|
|
type: "choice",
|
|
text: "Which genre appears most in the party analytics?",
|
|
options: genreOptions,
|
|
correct: 0,
|
|
points: 10,
|
|
});
|
|
}
|
|
|
|
const topArtists = getTopClusterArtists(analytics);
|
|
const topArtist = topArtists[0];
|
|
if (topArtist) {
|
|
const artistOptions = buildOptionsWithCorrect(topArtist, topArtists, 4);
|
|
if (artistOptions) {
|
|
questions.push({
|
|
type: "choice",
|
|
text: "Which artist shows up most often in the shared audio data?",
|
|
options: artistOptions,
|
|
correct: 0,
|
|
points: 10,
|
|
});
|
|
}
|
|
}
|
|
|
|
const topTracks = getTopClusterTracks(analytics);
|
|
if (topTracks.length > 0) {
|
|
const trackNames = topTracks.map((track) => track.name);
|
|
const topTrackName = trackNames[0];
|
|
const trackOptions = topTrackName
|
|
? buildOptionsWithCorrect(topTrackName, trackNames, 4)
|
|
: null;
|
|
if (trackOptions) {
|
|
questions.push({
|
|
type: "choice",
|
|
text: "Which track looks most shared across the party?",
|
|
options: trackOptions,
|
|
correct: 0,
|
|
points: 10,
|
|
});
|
|
}
|
|
}
|
|
|
|
const randomTopTrack = pickRandom(topTracks);
|
|
if (randomTopTrack) {
|
|
const trackArtists =
|
|
randomTopTrack.artists?.map((artist) => artist.name) ?? [];
|
|
const allArtists = topArtists.length > 0 ? topArtists : trackArtists;
|
|
const correctArtist = trackArtists[0] ?? allArtists[0];
|
|
if (correctArtist) {
|
|
const artistOptions = buildOptionsWithCorrect(
|
|
correctArtist,
|
|
allArtists,
|
|
4,
|
|
);
|
|
if (artistOptions) {
|
|
questions.push({
|
|
type: "choice",
|
|
text: `Who performs "${randomTopTrack.name}"?`,
|
|
options: artistOptions,
|
|
correct: 0,
|
|
points: 10,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (randomTopTrack.albumName) {
|
|
const albumNames = topTracks
|
|
.map((track) => track.albumName)
|
|
.filter((name): name is string => Boolean(name));
|
|
const albumOptions = buildOptionsWithCorrect(
|
|
randomTopTrack.albumName,
|
|
albumNames,
|
|
4,
|
|
);
|
|
if (albumOptions) {
|
|
questions.push({
|
|
type: "choice",
|
|
text: `"${randomTopTrack.name}" appears on which album?`,
|
|
options: albumOptions,
|
|
correct: 0,
|
|
points: 10,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (questions.length === 0) {
|
|
throw new Error("Question not found");
|
|
}
|
|
|
|
const question = questions[index % questions.length];
|
|
if (!question) throw new Error("Question not found");
|
|
return buildQuestionWindow(question);
|
|
}
|