From 9b22a86785ee7c2318cde1dab1760bd7f8c8163c Mon Sep 17 00:00:00 2001
From: ZennilGreenherald <144579645+ZennilGreenherald@users.noreply.github.com>
Date: Sat, 8 Nov 2025 17:53:33 -0800
Subject: [PATCH 1/4] Update twitch_chat.js
---
src/twitch_chat.js | 70 +++++++++++++++++++---------------------------
1 file changed, 28 insertions(+), 42 deletions(-)
diff --git a/src/twitch_chat.js b/src/twitch_chat.js
index 2360874..51d40e0 100644
--- a/src/twitch_chat.js
+++ b/src/twitch_chat.js
@@ -2,27 +2,30 @@
globalThis.twitchChatConnect = twitchChatConnect;
const TwitchWebSocketUrl = 'wss://irc-ws.chat.twitch.tv:443';
-// const chatBody = (document.querySelector("#ChatMessages"));
+
let wsTwitch;
let channelName;
let parseChatCallback;
+
export function twitchChatConnect(name, chatParseCallback)
{
channelName = name;
parseChatCallback = chatParseCallback;
wsTwitch = new WebSocket(TwitchWebSocketUrl);
- wsTwitch.onopen = ()=>{
+ wsTwitch.onopen = () => {
console.log("chat opened");
wsTwitch.send(`CAP REQ :twitch.tv/commands twitch.tv/tags`);
wsTwitch.send(`NICK justinfan6969`);
wsTwitch.send(`JOIN #${channelName}`);
- console.log('WebSocket connection opened'); //debug
+ console.log('WebSocket connection opened');
let chatMSG = document.createElement("div");
let auth = document.createElement("div");
- parseChatCallback("",
+ parseChatCallback(
+ "",
`Connected to ${channelName}'s chat!`,
- auth, chatMSG
+ auth,
+ chatMSG
);
}
wsTwitch.onmessage = onMessage;
@@ -32,72 +35,55 @@ export function twitchChatConnect(name, chatParseCallback)
function onMessage(fullmsg)
{
- // console.log("fullmsg: ", fullmsg);
- let txt = fullmsg.data;
- // console.log("txt: ", txt);
+ const txt = fullmsg.data;
+ console.log("txt: ", txt);
let name = '';
let outmsg = '';
let indx = 0;
- // let just_tags = '';
- // let tags_obj = {};
- // const emote_list = [];
if (txt[0] == '@') {
- indx = txt.indexOf(' ');
- // just_tags = txt.slice(0, indx);
- indx++;
- // tags_obj = parse_tags(just_tags);
- // get_emote_list(tags_obj['emotes'], emote_list);
+ indx = txt.indexOf(' ') + 1;
}
if (txt[indx] == ':') {
- // get the important data positions
- let pos1 = txt.indexOf('@', indx) + 1;
- let pos2 = txt.indexOf(".", pos1);
- let pos3 = txt.indexOf(`#${channelName}`)+2;
- pos3 += channelName.length + 1;
-
- // create strings based on those positions
+ const pos1 = txt.indexOf('@', indx) + 1;
+ const pos2 = txt.indexOf(".", pos1);
name = txt.substring(pos1, pos2).trim();
+ if (new Set([":tmi", "justinfan6969", "@emote-only=0;", ":justinfan6969"]).has(name)) {
+ console.log(`Invalid name: _${name}_`);
+ return;
+ }
- if ( (name == ":tmi")
- || (name == "justinfan6969")
- || (name.includes("@emote-only=0;"))
- || (name == ":justinfan6969"))
- { return; }
-
+ const pos3 = txt.indexOf(`#${channelName}`) + channelName.length + 3;
outmsg = txt.substring(pos3).trim();
+ console.log(`outmsg: ${outmsg}`);
}
else {
- // handle pings
- // other twitch specific things should
- // be handled here too
- let pos2 = txt.indexOf(":");
+ // handle pings & other twitch specific things
+ const pos2 = txt.indexOf(":");
name = txt.slice(0, pos2).trim();
outmsg = txt.slice(pos2).trim();
if (name == 'PING') {
- // console.log('PONG ' + outmsg);
+ console.log('PONG ' + outmsg);
wsTwitch.send('PONG ' + outmsg);
}
return;
}
//not running bot commands here
+ console.log(`Invalid message: _${outmsg}_`);
if (outmsg[0] == '!') {
return;
}
- // return display_msg(name, outmsg);
+ console.log(`name ${name}, outmsg: ${outmsg}`);
display_msg(name, outmsg);
- // console.log("name", name);
- // console.log("outmsg", outmsg);
-
}
// display chat message on stream
// calls parseChatCallback() with elements created here
-//auth & chatMSG are both stylized here
+// auth & chatMSG are both stylized here
function display_msg(name, outmsg, tags_obj, emote_list)
{
let emote;
@@ -118,13 +104,13 @@ function display_msg(name, outmsg, tags_obj, emote_list)
auth.textContent = (tags_obj?.display_name || name) + ' ';
if (tags_obj?.emotes) {
- let parts = [];
- let end_indx = outmsg.length;
+ let parts = [];
+ let end_indx = outmsg.length;
for (let i = emote_list.length; --i >= 0; ) {
emote = document.createElement("img");
emote.setAttribute('src', emote_list[i].url);
- if (i!==0) {
+ if (i !== 0) {
emote.style = 'margin-left: -14px';
}
From 44e3f421a29bf9d7359540dabb07eac648dc6549 Mon Sep 17 00:00:00 2001
From: ZennilGreenherald <144579645+ZennilGreenherald@users.noreply.github.com>
Date: Sat, 8 Nov 2025 17:54:08 -0800
Subject: [PATCH 2/4] Update movie_trivia.js
---
src/movie_trivia.js | 907 ++++++++++++++++++--------------------------
1 file changed, 369 insertions(+), 538 deletions(-)
diff --git a/src/movie_trivia.js b/src/movie_trivia.js
index 5c70c0e..833f4bc 100644
--- a/src/movie_trivia.js
+++ b/src/movie_trivia.js
@@ -1,267 +1,263 @@
"use strict";
let twitchChatConnect;
-import ("./twitch_chat.js").then((e)=>{
- //this way only works with modules enabled
- //(see script assignments in index.html)
- //(L270 at time of writing this comment)
- twitchChatConnect = e.twitchChatConnect;
+import ("./twitch_chat.js").then(e => {
+ //this way only works with modules enabled (see script assignments in index.html)
+ twitchChatConnect = e.twitchChatConnect;
+ console.log(`twitchChatConnect is set via import!`);
});
-// let lastTime;
-// function fpsCounter() {
-// let currentTime = new Date().getTime();
-// let counter = document.getElementById("fps");
-// counter.innerText = 1000/(currentTime-lastTime);
-// lastTime = currentTime;
-// requestAnimationFrame(animationCallback);
-// }
-
-// play_movie_trivia();
-
-
-//FrankL81:
-// you do a
-// customElements.define("trivia-game", class extends HTMLElement {
-// connectedCallback(){ //..... } ))
-
-//BakerStaunch:
-// Yeah but I mean just have a setInterval
-// once at the start and inside the
-// interval callback check if it's
-// paused or not rather than trying to
-// manage the interval itself
-//BakerStaunch:
-// You can treat it like a "main loop"
-// by having a single interval
-// (or requestAnimationFrame)
-//BakerStaunch:
-// btw, I'd suggest using performance.now()
-// for the time instead of Date.now() - system
-// clocks can change, performance.now()
-// is meant to be number of milliseconds
-// since the page loaded
-
-const answerBtn = document.getElementById("answer");
-const playBtn = document.getElementById("pause");
-const prevBtn = document.getElementById("prev");
-const nextBtn = document.getElementById("next");
-const twitchName = document.getElementById("twitchName");
-const triviaDiv = document.getElementById("trivia");
-const connectBtn = document.getElementById("connectChatBtn");
-const timer = document.getElementById("timer");
-const sound = document.getElementById("sound");
-let question = document.createElement("img");
-
-
-
-let maxMsgCount = 5;
-let countdownTime = 30;
-let answerTime = 15;
-let questionCount = 10;
-let twitchChatWS;
+const randInt = n => Math.floor(Math.random() * n);
+const getById = id => document.getElementById(id);
+const createEl = (tagName, props) => {
+ const el = document.createElement(tagName);
+ Object.entries(props || {}).forEach(([k, v]) => el[k] = v);
+ return el;
+}
+
+
+const buttons = {
+ answerBtn: getById("answer"),
+ playBtn: getById("pause"),
+ prevBtn: getById("prev"),
+ nextBtn: getById("next"),
+ setAnswerText: function(t) {
+ this.answerBtn.innerText = t;
+ },
+ setPlayText: function(t) {
+ this.playBtn.innerText = t;
+ },
+ setAnswerOnClick: function(onclick) {
+ this.answerBtn.onclick = onclick;
+ },
+ setPlayOnClick: function(onclick) {
+ this.playBtn.onclick = onclick;
+ },
+ isShowingNext: function() {
+ return this.answerBtn.innerText === "Next";
+ },
+ isShowingAnswer: function() {
+ return this.answerBtn.innerText === "Answer";
+ },
+ setPrevOnClick: function(onclick) {
+ this.prevBtn.onclick = onclick;
+ },
+ setPrevEnabled: function(b) {
+ this.prevBtn.disabled = !b;
+ },
+ setNextOnClick: function(onclick) {
+ this.nextBtn.onclick = onclick;
+ },
+ setDisabled: function(b) {
+ this.nextBtn.disabled = b;
+ this.prevBtn.disabled = b;
+ this.playBtn.disabled = b;
+ },
+ showRestart: function(k) {
+ this.setDisabled(true);
+ this.setAnswerText("Restart?");
+
+ this.answerBtn.onclick = () => {
+ this.setDisabled(false);
+ this.setAnswerText("Answer");
+ k();
+ }
+ }
+};
+
+
+const timer = {
+ label: getById("timer"),
+ state: 'running',
+ setText: function(t) {
+ this.label.innerText = t;
+ },
+ getText: function() {
+ return +this.label.innerText;
+ },
+ pause: function() {
+ this.state = "paused";
+ },
+ run: function() {
+ this.state = "running";
+ },
+ isRunning: function() {
+ return this.state == "running";
+ }
+};
+
+
+const stopwatch = {
+ setEnd: function(numSeconds) {
+ this.timeEnd = performance.now() + 1000 * numSeconds;
+ },
+ setEndNow: function() {
+ this.setEnd(0);
+ },
+ secondsTilExpiry: function() {
+ const msToGo = this.timeEnd - performance.now();
+ return Math.floor(msToGo % (1000 * 60) / 1000)
+ },
+ isShowAnswerTimeExpired: function(showAnswerTimeSecs) {
+ return performance.now() > this.timeEnd + showAnswerTimeSecs * 1000
+ }
+};
+
+
+const twitchName = getById("twitchName");
+const connectBtn = getById("connectChatBtn");
+const sound = getById("sound");
+let question = createEl("img");
+
+let maxMsgCount = 5;
+let countdownTime = 30;
+let showAnswerTime = 15;
+let questionCount = 10;
+
+let twitchChatWS;
let tmdbList;
+
let answered = [];
let winners = [];
let triviaIndex = 0;
let score = {};
-let endTime;
+
let correctAnsIdx;
-let timerState = "running";
let triviaQuestions;
+
+
async function play_trivia()
{
- let prevState;
-
- // triviaQuestions = await createQuestions();
await createQuestions();
initButtons();
- endTime = performance.now() + 1000*countdownTime;
+ stopwatch.setEnd(countdownTime);
- // question.src = `/Movie-Tracker/bg/${triviaQuestions[0].question}`;
question.src = await getTriviaURL(0);
- // question.src = `/assets/junior-1994-0.gif`;
- // let p = await new Promise((res)=>{
- // question.addEventListener('load', ()=>{
- // console.log("qa",question);
- // res(true);
- // });
- // question.addEventListener('error',()=>{
- // console.log("qb",question);
- // res(false);
- // });
- // });
- // console.log("p",await p);
- // question.src = `https://quantumapprentice.github.io/movieTrivia-MiniGame/assets/junior-1994-1.gif`
question.id = "question";
- triviaDiv.appendChild(question);
- timer.innerText = countdownTime;
+ getById("trivia").appendChild(question);
+ timer.setText(countdownTime);
- function updateButtons() {
- if (triviaIndex === 0 || triviaIndex == triviaCount-1) {
- //disable prevBtn if on first trivia or score screen
- prevBtn.disabled = true;
- } else {
- prevBtn.disabled = false;
- }
- // const playBtn = document.getElementById("pause");
- // if (timerState === "paused") {
- // playBtn.innerText = "Play";
- // }
- // if (timerState === "running") {
- // playBtn.innerText = "Pause";
- // }
- }
-
- function updateTimer() {
- playBtn.innerText = "Pause";
- if (answerBtn.innerText !== "Next") {
- const now = performance.now();
- timer.innerText = Math.floor((endTime - now)%(1000*60)/1000);
- }
+ multipleChoice();
+ stateMachine();
+}
- if (timer.innerText <= 0) {
- answerBtn.innerText = "Next";
- timer.innerText = triviaQuestions[triviaIndex].answer;
- }
- if (performance.now() > endTime + answerTime*1000) {
- //reset timer and load next trivia
- answerBtn.innerText = "Answer";
- nextTrivia();
- }
+
+function updateTimer() {
+ if (!timer.isRunning()) {
+ return;
}
- function stateMachine() {
- if (timerState !== prevState) {
- prevState = timerState;
- }
- if (timerState !== "paused") {
- updateTimer();
- updateButtons();
- }
- requestAnimationFrame(stateMachine);
+ buttons.setPlayText("Pause");
+ if (!buttons.isShowingNext()) {
+ timer.setText(stopwatch.secondsTilExpiry());
}
- multipleChoice();
- stateMachine();
+ if (timer.getText() <= 0) {
+ buttons.setAnswerText("Next");
+ timer.setText(triviaQuestions[triviaIndex % triviaQuestions.length].answer);
+ }
+ if (stopwatch.isShowAnswerTimeExpired(showAnswerTime)) {
+ // reset timer and load next trivia
+ buttons.setAnswerText("Answer");
+ nextTrivia();
+ }
+ buttons.setPrevEnabled(triviaIndex > 0 && triviaIndex < triviaCount.value);
+}
+
+
+function stateMachine() {
+ updateTimer();
+ requestAnimationFrame(stateMachine);
}
+
async function getTriviaURL(index)
{
let baseURL = `https://quantumapprentice.github.io/Movie-Tracker/bg/${triviaQuestions[index].question}`;
// let baseURL = `/Movie-Tracker/bg/${triviaQuestions[index].question}`;
let imageName = triviaQuestions[index].question.slice(0,-4);
- // let imageName = `junior-1994.jpg`.slice(0,-4);
- // console.log("i",imageName);
const img = new Image();
let difficulty = 0;
let temp;
let p = false;
while (!p && difficulty < 3) {
- temp = `/assets/${imageName}-${difficulty++}.gif`;
+ temp = `https://quantumapprentice.github.io/movieTrivia-MiniGame/assets/${imageName}-${difficulty++}.gif`;
img.src = temp;
- p = await new Promise(res=>{
- img.addEventListener('load', ()=>res(true) );
- img.addEventListener('error',()=>res(false));
+ p = await new Promise(res => {
+ img.addEventListener('load', () => res(true));
+ img.addEventListener('error',() => res(false));
});
}
- if (p) {
- console.log('t',temp);
- return temp;
- }
-
- return baseURL;
-
+ return p ? temp : baseURL;
}
-
-
-
-
-
-
-
-
-
-
-
-
function initButtons()
{
//answer/next
- answerBtn.onclick = (e)=>{
- if (e.target.innerText === "Answer") {
- e.target.innerText = "Next";
- //show the answer in the timer label
- timer.innerText = triviaQuestions[triviaIndex].answer;
+ buttons.setAnswerOnClick(e => {
+ if (buttons.isShowingAnswer()) {
+ buttons.setAnswerText("Next");
+ timer.setText(triviaQuestions[triviaIndex].answer);
} else {
- e.target.innerText = "Answer";
+ buttons.setAnswerText("Answer");
nextTrivia();
}
- }
+ });
+
//play/pause
- playBtn.onclick = (e)=>{
- if (timerState === "paused") {
- e.target.innerText = "Pause";
- timerState = "running";
+ buttons.setPlayOnClick(e => {
+ if (!timer.isRunning()) {
+ buttons.setPlayText("Pause");
+ timer.run();
restartTimer();
} else {
- e.target.innerText = "Play";
- timerState = "paused";
+ buttons.setPlayText("Play");
+ timer.pause();
}
- }
+ });
+
//next >>
- prevBtn.onclick = async ()=>{
+ buttons.setPrevOnClick(async () => {
triviaIndex -= 1;
if (triviaIndex < 0) {
- triviaIndex = triviaQuestions.length-1;
+ triviaIndex = triviaQuestions.length - 1;
}
- // question.src = `/Movie-Tracker/bg/${triviaQuestions[triviaIndex].question}`;
question.src = await getTriviaURL(triviaIndex);
resetTimer();
multipleChoice();
- // clearRound();
- answerBtn.innerText = "Answer";
- }
+ buttons.setAnswerText("Answer");
+ });
//previous <<
- nextBtn.onclick = ()=>{
+ buttons.setNextOnClick(() => {
nextTrivia();
- answerBtn.innerText = "Answer";
- }
+ buttons.setAnswerText("Answer");
+ });
//sound button
- sound.onclick = (e)=>{
+ sound.onclick = e => {
if (e.currentTarget.classList.value === "soundOn") {
e.currentTarget.classList = "soundOff";
- document.getElementById("sadTrombone").muted = true;
+ getById("sadTrombone").muted = true;
} else {
e.currentTarget.classList = "soundOn";
- document.getElementById("sadTrombone").muted = false;
+ getById("sadTrombone").muted = false;
}
}
//twitch chat connection stuff
//specifically attached to the connect button
- twitchName.addEventListener("keypress", (e)=>{
+ twitchName.addEventListener("keypress", e => {
if (e.key === "Enter") {
e.stopPropagation();
- // console.log("val",e.target.value);
-
-
-
if (!e.target.value) {
- let chatMSG = document.createElement("div");
- let auth = document.createElement("div");
- parseChatCallback("TriviaBot",
- `No channel-name provided. Add a channel name in ☰ Options.`,
- auth, chatMSG);
+ parseChatCallback("TriviaBot", `No channel-name provided. Add a channel name in ☰ Options.`);
return;
}
@@ -269,178 +265,158 @@ function initButtons()
connectBtn.innerText = "Disconnect";
startChat(e.target.value, parseChatCallback);
} else {
- twitchChatWS.onclose = ()=>{
+ twitchChatWS.onclose = () => {
connectBtn.innerText = "Connect to Twitch Chat";
- let chatMSG = document.createElement("div");
- let auth = document.createElement("div");
- parseChatCallback("TriviaBot",
- `Disconnected from twitch chat.`,
- auth, chatMSG);
+ parseChatCallback("TriviaBot", `Disconnected from twitch chat.`);
}
twitchChatWS.close();
}
}
});
- connectBtn.onclick = (e)=>{
+
+ connectBtn.onclick = e => {
e.stopPropagation();
if (!twitchName.value) {
- let chatMSG = document.createElement("div");
- let auth = document.createElement("div");
- parseChatCallback("TriviaBot",
- `No channel-name provided. Add a channel name in ☰ Options.`,
- auth, chatMSG);
+ parseChatCallback("TriviaBot", `No channel-name provided. Add a channel name in ☰ Options.`);
return;
}
-
if (e.target.innerText === "Connect to Twitch Chat") {
e.target.innerText = "Disconnect";
startChat(twitchName.value, parseChatCallback);
} else {
- twitchChatWS.onclose = ()=>{
+ twitchChatWS.onclose = () => {
e.target.innerText = "Connect to Twitch Chat";
- let chatMSG = document.createElement("div");
- let auth = document.createElement("div");
- parseChatCallback("TriviaBot",
- `Disconnected from twitch chat.`,
- auth, chatMSG);
+ parseChatCallback("TriviaBot", `Disconnected from twitch chat.`);
}
twitchChatWS.close();
}
}
//sidebar hamburger button
- const hamburger = document.getElementById("hamburger");
- hamburger.onclick = (e)=>{
+ const hamburger = getById("hamburger");
+ hamburger.onclick = e => {
e.stopPropagation();
e.currentTarget.classList.toggle("change");
- document.getElementById("sidebar").classList.toggle("change");
+ getById("sidebar").classList.toggle("change");
}
//number of trivia elements in this run
- const triviaCount = document.getElementById("triviaCount");
+ const triviaCount = getById("triviaCount");
if (triviaCount.value != questionCount) {
questionCount = triviaCount.value;
createQuestions();
}
- triviaCount.onchange = (e)=>{
+
+ triviaCount.onchange = e => {
questionCount = e.target.value;
createQuestions();
}
//amount of time trivia question will stay on screen
- const triviaTime = document.getElementById("triviaTime");
+ const triviaTime = getById("triviaTime");
if (triviaTime.value != countdownTime) {
countdownTime = triviaTime.value;
}
- triviaTime.onchange = (e)=>{
+
+ triviaTime.onchange = e => {
countdownTime = e.target.value;
- const countdown = timer.innerText;
- if (countdownTime < Number(countdown)) {
+ const countdown = timer.getText();
+ if (countdownTime < countdown) {
restartTimer();
}
}
- //amount of time the answer stays on screen
- //before starting the next trivia question
- const pauseTime = document.getElementById("pauseTime");
- if (pauseTime.value != answerTime) {
- answerTime = pauseTime.value;
+ // amount of time the answer stays on screen before starting the next trivia question
+ const pauseTime = getById("pauseTime");
+ if (pauseTime.value != showAnswerTime) {
+ showAnswerTime = pauseTime.value;
}
- pauseTime.onchange = (e)=>{
- answerTime = e.target.value;
+
+ pauseTime.onchange = e => {
+ showAnswerTime = e.target.value;
}
}
-//get the next trivia entry and fill
-//the question.src with new entry
+
+// get the next trivia entry and fill the question.src with new entry
async function nextTrivia() {
triviaIndex += 1;
if (triviaIndex >= triviaQuestions.length) {
- timerState = "paused";
- // clearRound();
+ timer.pause();
showScore();
return;
}
- //change the trivia question.src to match new index
- // question.src = `/Movie-Tracker/bg/${triviaQuestions[triviaIndex].question}`;
- // question.src = `https://quantumapprentice.github.io/Movie-Tracker/bg/${triviaQuestions[triviaIndex].question}`;
- question.src = await getTriviaURL(triviaIndex);
- //reset for next round
+ // must reset timer before the async call to getTriviaURL so that we don't keep cycling to next trivia questions.
resetTimer();
+ question.src = await getTriviaURL(triviaIndex);
+
+ // reset for next round
multipleChoice();
- // clearRound();
}
+
async function restartTrivia()
{
- // triviaQuestions = await createQuestions();
-
- console.log("restarting");
resetAnswered();
resetWinners();
await createQuestions();
- // endTime = performance.now() + 1000*countdownTime;
resetTimer();
triviaIndex = 0;
multipleChoice();
- const title = document.getElementById("title");
- title.innerText = "Name That Movie";
- const scoreCard = document.getElementById("score");
- question = document.createElement("img");
- // question.src = `/Movie-Tracker/bg/${triviaQuestions[0].question}`;
- question.src = await getTriviaURL(0);
- question.id = "question";
+ getById("title").innerText = "Name That Movie";
+ const scoreCard = getById("score");
+ question = createEl("img", {
+ src: await getTriviaURL(0),
+ id: "question"
+ });
scoreCard.replaceWith(question);
- // triviaDiv.appendChild(question);
- timer.innerText = countdownTime;
+ timer.setText(countdownTime);
}
+
function restartTimer() {
- const countdown = timer.innerText;
- if (Number(countdown)) {
- endTime = performance.now() + 1000*countdown;
+ const countdown = timer.getText();
+ if (countdown) {
+ stopwatch.setEnd(+countdown);
}
- timerState = "running";
+ timer.run();
}
+
+
function resetTimer() {
- timer.innerText = countdownTime;
- endTime = performance.now() + countdownTime*1000;
- timerState = "running";
+ timer.setText(countdownTime);
+ stopwatch.setEnd(countdownTime);
+ timer.run();
}
+
async function startChat(chatName, chatParser)
{
- let chatMSG = document.createElement("div");
- let auth = document.createElement("div");
- if (!twitchChatWS) {
- } else {
+ if (twitchChatWS) {
if (twitchChatWS.readyState === twitchChatWS.OPEN) {
twitchChatWS.close();
- parseChatCallback("TriviaBot",
- `Disconnecting from ${chatName} and...`,
- auth, chatMSG);
+ parseChatCallback("TriviaBot", `Disconnecting from ${chatName} and...`);
}
}
- //used the globalThis variable to share twitch_chat
- //this bypasses module requirements for import
+ // used the globalThis variable to share twitch_chat
+ // this bypasses module requirements for import
twitchChatWS = await globalThis.twitchChatConnect(chatName, chatParser);
-
- // console.log("twitchChatWS?",twitchChatWS);
-
-
}
function parseChatCallback(name, outmsg, auth, chatMSG)
{
+ if (!auth) auth = createEl('div');
+ if (!chatMSG) chatMSG = createEl('div');
+
const winner = parseTriviaChat(name, outmsg);
//for some reason the twitch chat api sends a message
@@ -448,22 +424,17 @@ function parseChatCallback(name, outmsg, auth, chatMSG)
//but does nothing when chat connection succeeds
if (outmsg === "This channel does not exist or has been suspended.") {
connectBtn.innerText = "Connect to Twitch Chat";
- // console.log("a",auth);
- // console.log("n",name);
- // auth.innerText = name;
}
- // console.log('chatting?');
-
- //option to hide chat except for
- //those who guess correctly
- const chatBody = document.getElementById("twitchChat");
+ //option to hide chat except for those who guess correctly
+ const chatBody = getById("twitchChat");
let hideChat = false;
if (hideChat) {
if (winner.won) {
- let msg = document.createElement("div");
+ const msg = createEl("div", {
+ innerHTML: outmsg
+ });
msg.classList.add("msg");
- msg.innerHTML = outmsg;
msg.classList.add("winner");
auth.classList.add("winner");
@@ -473,22 +444,22 @@ function parseChatCallback(name, outmsg, auth, chatMSG)
chatBody.prepend(chatMSG);
}
} else {
- let msg = document.createElement("div");
+ const msg = createEl("div", {
+ innerHTML: outmsg
+ });
msg.classList.add("msg");
- msg.innerHTML = outmsg;
if (winner.won) {
msg.classList.add("winner");
auth.classList.add("winner");
- document.getElementById(`${Number(outmsg)}`).classList.add("winnerChoice");
- document.getElementById("sadTrombone").play();
+ getById(`${Number(outmsg)}`).classList.add("winnerChoice");
+ getById("sadTrombone").play();
}
msg.innerText += winner.str;
chatMSG.append(auth, msg);
// chat message has to be prepended to appear on bottom
- // const chatBody = document.getElementById("twitchChat");
chatBody.prepend(chatMSG);
}
chatMSG.classList.add("message_box");
@@ -497,27 +468,19 @@ function parseChatCallback(name, outmsg, auth, chatMSG)
if (chatBody.children.length > maxMsgCount) {
chatBody.lastElementChild.remove();
}
+}
-
-}
play_trivia();
+
async function loadTMDB()
{
- // const res = await fetch("/Movie-Tracker/src/tmdbList.json");
- // const res = await fetch(`https://raw.githubusercontent.com/QuantumApprentice/Movie-Tracker/refs/heads/master/src/tmdbList.json`);
- // if (!res.ok) {
- // throw new Error(`Response failed? ${res.status}`);
- // }
- // return res.json();
- return fetch(`https://raw.githubusercontent.com/QuantumApprentice/Movie-Tracker/refs/heads/master/src/tmdbList.json`)
- .then((r)=>{
- if (!r.ok) {
- throw new Error(`Response failed? ${r.status}`);
- }
- return r.json()
- });
+ const r = await fetch(`https://raw.githubusercontent.com/QuantumApprentice/Movie-Tracker/refs/heads/master/src/tmdbList.json`);
+ if (!r.ok) {
+ throw new Error(`Response failed? ${JSON.stringify(r)}`);
+ }
+ return r.json();
}
@@ -531,238 +494,143 @@ async function createQuestions()
for (let i = 0; i < questionCount; i++) {
let currIndex;
do {
- currIndex = Math.floor(Math.random() * tmdbList.length);
- } while (
- indexArr.includes(currIndex)
- || !tmdbList[currIndex].bg
- );
+ currIndex = randInt(tmdbList.length);
+ } while (indexArr.includes(currIndex) || !tmdbList[currIndex].bg);
indexArr[i] = currIndex;
}
- triviaQuestions = indexArr.map((e)=>{
+ triviaQuestions = indexArr.map(i => {
return {
- answer: tmdbList[e].title,
- question: tmdbList[e].bg
+ answer: tmdbList[i].title,
+ question: tmdbList[i].bg
}
});
}
-function parseTriviaChat(name, outmsg)
+
+function createAnswers()
{
- if (triviaIndex >= triviaQuestions.length) {
- return {won: false, str: ""}; //should show scoreboard
- }
- if (winners[triviaIndex]) {
- return {won: false, str: ""}; //round over, wait for next round
- }
- if (answered.includes(name)) {
- return {won: false, str: " -- Oops, you already played this round."}; //already answered incorrectly
- }
+ let nextQuestion = triviaQuestions[triviaIndex % triviaQuestions.length];
+
+ // prevent same answer index from appearing twice in a row
+ const nextAnswerIndex = ((correctAnsIdx || 1) + randInt(3)) % 4;
+ correctAnsIdx = nextAnswerIndex + 1;
+ const newAnswers = [{ ...nextQuestion }];
- // console.log("outmsg: ", outmsg);
- // console.log("answer: ", correctAnsIdx);
- if (Number(outmsg) === correctAnsIdx) {
- winners.push(name);
- endTime = performance.now();
- score[name] = score[name] ? (score[name]+=1) : 1;
- return {won: true, str: ""}; //winner through multiple choice
+ const foundAnswerTitles = new Set();
+
+ while (newAnswers.length < 4) {
+ const rng = randInt(tmdbList.length);
+ if (!foundAnswerTitles.has(tmdbList[rng].title)) {
+ newAnswers.push({
+ answer: tmdbList[rng].title,
+ question: tmdbList[rng].bg
+ });
+ foundAnswerTitles.add(tmdbList[rng].title);
+ }
}
- if (outmsg.toLowerCase().indexOf(triviaQuestions[triviaIndex].answer) != -1) {
- winners.push(name);
- endTime = performance.now();
- score[name] = score[name] ? (score[name]+=1) : 1;
- return {won: true, str: " -- Oh wow, you actually typed it out?"}; //won by typing name?
+
+ if (nextAnswerIndex != 0) {
+ const t = newAnswers[nextAnswerIndex];
+ newAnswers[nextAnswerIndex] = newAnswers[0];
+ newAnswers[0] = t;
}
- if (!isNaN(outmsg) && (Number(outmsg) > 0 && Number(outmsg) < 5)) {
- answered.push(name);
- return {won: false, str: " -- Sorry, you didn't win this time."};
+
+ return newAnswers;
+}
+
+
+function parseTriviaChat(name, outmsg)
+{
+ const showScoreboard = triviaIndex >= triviaQuestions.length;
+ const roundOver = winners[triviaIndex];
+ if (showScoreboard || roundOver) {
+ return { won: false, str: "" };
+ }
+ else if (answered.includes(name)) {
+ return { won: false, str: " -- Oops, you already played this round." };
+ }
+ else {
+ const guessedCorrectNumber = Number(outmsg) === correctAnsIdx;
+ const guessedPartialTitle = outmsg.toLowerCase().indexOf(triviaQuestions[triviaIndex].answer) != -1;
+ if (guessedCorrectNumber || guessedPartialTitle) {
+ winners.push(name);
+ stopwatch.setEndNow();
+ score[name] = score[name] ? score[name] + 1 : 1;
+ return { won: true, str: guessedCorrectNumber ? "" : " -- Oh wow, you actually typed it out?" };
+ }
+ else {
+ outmsg = +outmsg;
+ const isValidNumber = outmsg > 0 && outmsg < 5;
+ if (isValidNumber) {
+ answered.push(name);
+ return { won: false, str: " -- Sorry, you didn't win this time." };
+ }
+ else {
+ // all regular chat
+ return { won: false, str: "" };
+ }
+ }
}
- return {won: false, str: ""}; //all regular chat
}
+// reset so same people can answer again
function resetAnswered()
{
- answered = []; //reset so same people can answer again
+ answered = [];
}
+
function resetWinners()
{
winners = [];
}
-function createAnswers()
-{
- resetAnswered();
- /////////////////////////////////////////////
- //QuantumApprentice
- // let answers = new Set();
- // let ansArr = [triviaQuestions[triviaIndex].answer];
- // answers.add(triviaQuestions[triviaIndex].answer);
- // while (answers.size < 4) {
- // let randAnswer = triviaQuestions[Math.floor(Math.random() * triviaQuestions.length)].answer;
- // if (!answers.has(randAnswer)) {
- // answers.add(randAnswer);
- // ansArr.push(randAnswer);
- // }
- // }
- // let swap = Math.floor(Math.random()*4);
- // let temp = ansArr[swap];
- // ansArr[0] = temp;
- // ansArr[swap] = triviaQuestions[triviaIndex].answer;
- // correctAnsIdx = swap+1;
- // console.log(ansArr);
-
-
- /////////////////////////////////////////////
- //BakerStaunch
- let question = triviaQuestions[triviaIndex]; //does not modify original array
- console.log("answer", question.answer);
-
- let answersB = Array(4);
- let answerIndex;
- //prevent same answer index from appearing twice in a row
- do {
- answerIndex = Math.floor(Math.random()*4);
- } while (answerIndex == correctAnsIdx-1);
-
- correctAnsIdx = answerIndex+1;
- answersB[answerIndex] = {...question};
-
- for (let i = 1; i <= 3; i += 1) {
- let wrongAnswer;
- while (answersB.includes(wrongAnswer)) {
-
- //TODO: might need to swap out this while loop
- // for something that deep checks objects?
- // while (answersB.find((e)=>{
- // console.log("e",e);
- // if (!e) {
- // return false;
- // }
- // return (e?.answer === wrongAnswer?.answer);
- // })) {
-
-
-
- //get another random answer and
- //set it at index (answerIndex + i) % 4
- let rng = Math.floor(Math.random() * tmdbList.length);
- wrongAnswer = {
- answer: tmdbList[rng].title,
- question: tmdbList[rng].bg
- }
- }
- answersB[(answerIndex + i) %4] = wrongAnswer;
- }
-
- const ansArr = answersB;
- // console.log(answersB)
-
- //Eskiminha (chatGPT)
- /////////////////////////////////////////////
- // const questions = triviaQuestions;
- // const { q, a } = {
- // q: questions[Math.floor(Math.random() * questions.length)],
- // a: ((q, a = Array(4).fill(null),
- // u = new Set(a[(i = Math.floor(Math.random() * 4))] = q.answer)
- // ) => (Array(4).fill(0).forEach(
- // (_, j) => j - i || (
- // () => {
- // let x;
- // do x = questions[Math.floor(Math.random() * questions.length)].answer;
- // while (
- // u.has(x)
- // );
- // a[j] = x;
- // u.add(x);
- // })()),
- // a))
- // (questions[Math.floor(
- // Math.random() * questions.length
- // )])
- // };
- // console.log("Question:", q, "Answers:", a);
- // const ignore = null;
-
- //tvjosh
- /////////////////////////////////////////////
- // const ls = Array(10).fill().map((_, i) => i);
- // const ls = triviaQuestions;
- // const numToShuffle = 4;
- // const copyLs = ls.slice().map((x, i, thisLs) => {
- // if (i < numToShuffle) {
- // // const k = Math.floor(Math.random() * (ls.length/numToShuffle) + i*(ls.length/numToShuffle));
- // const k = Math.floor(Math.random() * (ls.length - i)) + i;
- // const t = thisLs[i];
- // thisLs[i] = thisLs[k];
- // thisLs[k] = t;
- // return thisLs[i];
- // }
- // return x
- // }).slice(0, numToShuffle);
- // console.log(copyLs);
-
-
- /////////////////////////////////////////////
- //FrankL81
- // const Questions = triviaQuestions;
- // console.log(Questions);
- // const schuffle = (array) => array.sort(() => Math.random() < 0.5 ? 1 : -1);
- // const currentQuestion = schuffle(Questions).slice(0,4).map((e)=>e.answer);
- // // const [imgSrc,answer] = currentQuestion[0];
- // ansArr = currentQuestion;
- // console.log("ansArr", ansArr);
- // document.getElementById("canvas").innerHTML =
- // `
${schuffle(currentQuestion.map(([,answer],idx) => ``)).join("
")}
- //
- // currentAnswer is: ${answer}`;
-
-
- /////////////////////////////////////////////
- return ansArr;
-}
function multipleChoice() {
- const choiceDiv = document.getElementById("choiceDiv");
+ const choiceDiv = getById("choiceDiv");
choiceDiv.innerHTML = ""; //clear previous answer choices
- // const timeStart = performance.now();
+ resetAnswered();
+
const ansArr = createAnswers();
- //create array of answer buttons - choiceBtnArr[]
- //and fill with ansArr[] answers
+ //create array of answer buttons - choiceBtnArr[] and fill with ansArr[] answers
let choiceBtnArr = [];
for (let i = 0; i < 4; i++) {
- const choiceBtnDiv = document.createElement("div");
- choiceBtnDiv.className = "choiceBtn";
- choiceBtnDiv.id = `${i+1}`;
+ const choiceBtnDiv = createEl("div", {
+ className: "choiceBtn",
+ id: `${i + 1}`
+ });
- const choiceAns = document.createElement("div");
- choiceAns.className = "choiceTxt";
- choiceAns.innerText = `${ansArr[i].answer}`;
+ const choiceAns = createEl("div", {
+ className: "choiceTxt",
+ innerText: `${ansArr[i].answer}`
+ });
- const choiceNum = document.createElement("div");
- choiceNum.className = "choiceNum";
- choiceNum.innerText = `${i+1}`;
+ const choiceNum = createEl("div", {
+ className: "choiceNum",
+ innerText: `${i + 1}`
+ });
choiceBtnDiv.append(choiceNum);
choiceBtnDiv.append(choiceAns);
choiceBtnDiv.onclick = handleClick;
choiceBtnArr.push(choiceBtnDiv);
+
+ choiceDiv.append(choiceBtnDiv);
}
- //onClick for the right answer only
- //(maybe add wrong answer stuff?)
- function handleClick(e) {
- // console.log("e",e.currentTarget);
+ // onClick for the right answer only (maybe add wrong answer stuff?)
+ function handleClick(e) {
//if button has the correct answer...
if (e.currentTarget.lastChild.textContent === triviaQuestions[triviaIndex].answer) {
//display correct answer in timer
- if (answerBtn.innerText !== "Next") {
- answerBtn.innerText = "Next";
- endTime = performance.now();
- timer.innerText = triviaQuestions[triviaIndex].answer;
- score["Me"] = score["Me"] ? (score["Me"]+1) : 1;
+ if (!buttons.isShowingNext()) {
+ buttons.setAnswerText("Next");
+ stopwatch.setEndNow();
+ timer.setText(triviaQuestions[triviaIndex].answer);
+ score["Me"] = score["Me"] ? score["Me"] + 1 : 1;
//TODO: wtf? why isn't this pointing
// to the parent element directly?
@@ -770,95 +638,58 @@ function multipleChoice() {
// but it's null if just logging out "e"
// need to log out currentTarget to see
e.currentTarget.classList.add("winnerChoice");
- const sadTrombone = document.getElementById("sadTrombone");
+ const sadTrombone = getById("sadTrombone");
sadTrombone.play();
}
} else {
e.currentTarget.classList.add("wrongChoice");
choiceBtnArr.forEach(e => {
e.classList.add("disabledChoice");
- e.onclick = {};
+ e.onclick = null;
});
}
}
-
- choiceBtnArr.map((e, i)=>{
- choiceDiv.append(e);
- });
-
-}
-
-function clearRound()
-{
- const name = document.getElementById("twitchName");
- const chat = document.getElementById("chatMsg");
- name.innerText = "";
- chat.innerText = "";
}
-
-
function showScore()
{
- // const timer = document.getElementById("timer");
- timer.innerText = "";
- const title = document.getElementById("title");
- title.innerText = "Score";
-
- nextBtn.disabled = true;
- prevBtn.disabled = true;
- playBtn.disabled = true;
- setTimeout(()=>{
- answerBtn.innerText = "Restart?";
- }, 10);
- // console.log("answer:", answBtn.innerText);
- answerBtn.onclick = ()=>{
- nextBtn.disabled = false;
- prevBtn.disabled = false;
- playBtn.disabled = false;
- setTimeout(()=>{
- answerBtn.innerText = "Answer";
- }, 10);
+ timer.setText("");
+ getById("title").innerText = "Score";
+ buttons.showRestart(() => {
initButtons();
restartTrivia();
- }
+ });
- // triviaDiv.removeChild(document.getElementById("question"));
- const scoreCard = document.createElement("table");
- // triviaDiv.appendChild(scoreCard);
- scoreCard.className = "scoreCard";
- scoreCard.id = "score";
+ const scoreCard = createEl("table", {
+ className: "scoreCard",
+ id: "score"
+ });
question.replaceWith(scoreCard);
const scoreArr = Object.entries(score);
- scoreArr.sort((a, b)=>{
- return b[1]-a[1];
+ scoreArr.sort((a, b) => {
+ return b[1] - a[1];
});
- // console.log("score", scoreArr);
- scoreArr.forEach((e)=>{
- const row = document.createElement("tr");
- const td1 = document.createElement("td");
- const td2 = document.createElement("td");
- td1.className = "scoreName";
- td1.innerText = e[0];
- const r = Math.floor(Math.random()*255);
- const g = Math.floor(Math.random()*255);
- const b = Math.floor(Math.random()*255);
-
- td1.style = `color : rgb(${r}, ${g}, ${b});`;
+ scoreArr.forEach(e => {
+ const td1 = createEl("td", {
+ className: "scoreName",
+ innerText: e[0],
+ style: `color : rgb(${randInt(255)} ${randInt(255)} ${randInt(255)});`
+ });
- td2.innerText = e[1];
- td2.className = "scoreAmount";
+ const td2 = createEl("td", {
+ innerText: e[1],
+ className: "scoreAmount"
+ });
+ const row = createEl("tr");
row.appendChild(td1);
row.appendChild(td2);
scoreCard.appendChild(row);
});
}
-// #region this is cool
-
From aaff232fddae5adaa3fb65818523c115eb7bbad8 Mon Sep 17 00:00:00 2001
From: ZennilGreenherald <144579645+ZennilGreenherald@users.noreply.github.com>
Date: Sat, 8 Nov 2025 17:54:34 -0800
Subject: [PATCH 3/4] Update index.html
---
index.html | 382 +----------------------------------------------------
1 file changed, 2 insertions(+), 380 deletions(-)
diff --git a/index.html b/index.html
index 45c9eae..61014b7 100644
--- a/index.html
+++ b/index.html
@@ -1,369 +1,7 @@