Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
{
"version": 3,
"sources": ["../../../server/chat-plugins/poll.ts"],
"sourcesContent": ["/*\n * Poll chat plugin\n * By bumbadadabum and Zarel.\n */\nimport { Utils } from '../../lib';\n\nconst MINUTES = 60000;\nconst MAX_QUESTIONS = 10;\n\ninterface PollAnswer {\n\tname: string; votes: number; correct?: boolean;\n}\n\nexport interface PollOptions {\n\tactivityNumber?: number;\n\tquestion: string;\n\tsupportHTML: boolean;\n\tmultiPoll: boolean;\n\tpendingVotes?: { [userid: string]: number[] };\n\tvoters?: { [k: string]: number[] };\n\tvoterIps?: { [k: string]: number[] };\n\tmaxVotes?: number;\n\ttotalVotes?: number;\n\ttimeoutMins?: number;\n\ttimerEnd?: number;\n\tisQuiz?: boolean;\n\tanswers: string[] | PollAnswer[];\n}\n\nexport interface PollData extends PollOptions {\n\treadonly activityid: 'poll';\n}\n\nexport class Poll extends Rooms.MinorActivity {\n\treadonly activityid = 'poll' as ID;\n\tname = \"Poll\";\n\tactivityNumber: number;\n\tquestion: string;\n\tmultiPoll: boolean;\n\tpendingVotes: { [userid: string]: number[] };\n\tvoters: { [k: string]: number[] };\n\tvoterIps: { [k: string]: number[] };\n\ttotalVotes: number;\n\tisQuiz: boolean;\n\t/** Max votes of 0 means no vote cap */\n\tmaxVotes: number;\n\tanswers: Map<number, PollAnswer>;\n\tconstructor(room: Room, options: PollOptions) {\n\t\tsuper(room);\n\t\tthis.activityNumber = options.activityNumber || room.nextGameNumber();\n\t\tthis.question = options.question;\n\t\tthis.supportHTML = options.supportHTML;\n\t\tthis.multiPoll = options.multiPoll;\n\t\tthis.pendingVotes = options.pendingVotes || {};\n\t\tthis.voters = options.voters || {};\n\t\tthis.voterIps = options.voterIps || {};\n\t\tthis.totalVotes = options.totalVotes || 0;\n\t\tthis.maxVotes = options.maxVotes || 0;\n\n\t\t// backwards compatibility\n\t\tif (!options.answers) options.answers = (options as any).questions;\n\n\t\tthis.answers = Poll.getAnswers(options.answers);\n\t\tthis.isQuiz = options.isQuiz ?? [...this.answers.values()].some(answer => answer.correct);\n\t\tthis.setTimer(options);\n\t}\n\n\tselect(user: User, option: number) {\n\t\tconst userid = user.id;\n\t\tif (!this.multiPoll) {\n\t\t\t// vote immediately\n\t\t\tthis.pendingVotes[userid] = [option];\n\t\t\tthis.submit(user);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.pendingVotes[userid]) {\n\t\t\tthis.pendingVotes[userid] = [];\n\t\t}\n\t\tif (this.pendingVotes[userid].includes(option)) {\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`That option is already selected.`);\n\t\t}\n\t\tthis.pendingVotes[userid].push(option);\n\t\tthis.updateFor(user);\n\t\tthis.save();\n\t}\n\n\tdeselect(user: User, option: number) {\n\t\tconst userid = user.id;\n\t\tconst pendingVote = this.pendingVotes[userid];\n\t\tif (!pendingVote?.includes(option)) {\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`That option is not selected.`);\n\t\t}\n\t\tpendingVote.splice(pendingVote.indexOf(option), 1);\n\t\tthis.updateFor(user);\n\t\tthis.save();\n\t}\n\n\tsubmit(user: User) {\n\t\tconst ip = user.latestIp;\n\t\tconst userid = user.id;\n\n\t\tif (userid in this.voters || (!Config.noipchecks && ip in this.voterIps)) {\n\t\t\tdelete this.pendingVotes[userid];\n\t\t\tthrow new Chat.ErrorMessage(this.room.tr`You have already voted for this poll.`);\n\t\t}\n\t\tconst selected = this.pendingVotes[userid];\n\t\tif (!selected) throw new Chat.ErrorMessage(this.room.tr`No options selected.`);\n\n\t\tthis.voters[userid] = selected;\n\t\tthis.voterIps[ip] = selected;\n\t\tfor (const option of selected) {\n\t\t\tthis.answers.get(option)!.votes++;\n\t\t}\n\t\tdelete this.pendingVotes[userid];\n\t\tthis.totalVotes++;\n\t\tif (this.maxVotes && this.totalVotes >= this.maxVotes) {\n\t\t\tthis.end(this.room);\n\t\t\treturn this.room\n\t\t\t\t.add(`|c|~|/log The poll hit the max vote cap of ${this.maxVotes}, and has ended.`)\n\t\t\t\t.update();\n\t\t}\n\n\t\tthis.update();\n\t\tthis.save();\n\t}\n\n\tblankvote(user: User) {\n\t\tconst ip = user.latestIp;\n\t\tconst userid = user.id;\n\n\t\tif (!(userid in this.voters) || !(ip in this.voterIps)) {\n\t\t\tthis.voters[userid] = [];\n\t\t\tthis.voterIps[ip] = [];\n\t\t}\n\n\t\tthis.updateTo(user);\n\t\tthis.save();\n\t}\n\n\tgenerateVotes(user: User | null) {\n\t\tconst iconText = this.isQuiz ?\n\t\t\t`<i class=\"fa fa-question\"></i> ${this.room.tr`Quiz`}` :\n\t\t\t`<i class=\"fa fa-bar-chart\"></i> ${this.room.tr`Poll`}`;\n\t\tlet output = `<div class=\"infobox\"><p style=\"margin: 2px 0 5px 0\"><span style=\"border:1px solid #6A6;color:#484;border-radius:4px;padding:0 3px\">${iconText}</span>`;\n\t\toutput += ` <strong style=\"font-size:11pt\">${Poll.getQuestionMarkup(this.question, this.supportHTML)}</strong></p>`;\n\n\t\tif (this.multiPoll) {\n\t\t\tconst empty = `<i class=\"fa fa-square-o\" aria-hidden=\"true\"></i>`;\n\t\t\tconst chosen = `<i class=\"fa fa-check-square-o\" aria-hidden=\"true\"></i>`;\n\n\t\t\tconst pendingVotes = (user && this.pendingVotes[user.id]) || [];\n\t\t\tfor (const [num, answer] of this.answers) {\n\t\t\t\tconst selected = pendingVotes.includes(num);\n\t\t\t\toutput += `<div style=\"margin-top: 5px\"><button style=\"text-align: left; border: none; background: none; color: inherit;\" value=\"/poll ${selected ? 'de' : ''}select ${num}\" name=\"send\" title=\"${selected ? \"Deselect\" : \"Select\"} ${num}. ${Utils.escapeHTML(answer.name)}\">${selected ? \"<strong>\" : ''}${selected ? chosen : empty} ${num}. `;\n\t\t\t\toutput += `${Poll.getAnswerMarkup(answer, this.supportHTML)}${selected ? \"</strong>\" : ''}</button></div>`;\n\t\t\t}\n\t\t\tconst submitButton = pendingVotes.length ? (\n\t\t\t\t`<button class=\"button\" value=\"/poll submit\" name=\"send\" title=\"${this.room.tr`Submit your vote`}\"><strong>${this.room.tr`Submit`}</strong></button>`\n\t\t\t) : (\n\t\t\t\t`<button class=\"button\" value=\"/poll results\" name=\"send\" title=\"${this.room.tr`View results`} - ${this.room.tr`you will not be able to vote after viewing results`}\">(${this.room.tr`View results`})</button>`\n\t\t\t);\n\t\t\toutput += `<div style=\"margin-top: 7px; padding-left: 12px\">${submitButton}</div>`;\n\t\t\toutput += `</div>`;\n\t\t} else {\n\t\t\tfor (const [num, answer] of this.answers) {\n\t\t\t\toutput += `<div style=\"margin-top: 5px\"><button class=\"button\" style=\"text-align: left\" value=\"/poll vote ${num}\" name=\"send\" title=\"${this.room.tr`Vote for ${num}`}. ${Utils.escapeHTML(answer.name)}\">${num}.`;\n\t\t\t\toutput += ` <strong>${Poll.getAnswerMarkup(answer, this.supportHTML)}</strong></button></div>`;\n\t\t\t}\n\t\t\toutput += `<div style=\"margin-top: 7px; padding-left: 12px\"><button value=\"/poll results\" name=\"send\" title=\"${this.room.tr`View results`} - ${this.room.tr`you will not be able to vote after viewing results`}\"><small>(${this.room.tr`View results`})</small></button></div>`;\n\t\t\toutput += `</div>`;\n\t\t}\n\n\t\treturn output;\n\t}\n\n\tstatic generateResults(\n\t\toptions: Rooms.MinorActivityData, room: Room,\n\t\tended = false, choice: number[] | null = null\n\t) {\n\t\tconst iconText = options.isQuiz ?\n\t\t\t`<i class=\"fa fa-question\"></i> ${room.tr`Quiz`}` :\n\t\t\t`<i class=\"fa fa-bar-chart\"></i> ${room.tr`Poll`}`;\n\t\tconst icon = `<span style=\"border:1px solid #${ended ? '777;color:#555' : '6A6;color:#484'};border-radius:4px;padding:0 3px\">${iconText}${ended ? ' ' + room.tr`ended` : \"\"}</span> <small>${options.totalVotes || 0} ${room.tr`votes`}</small>`;\n\t\tlet output = `<div class=\"infobox\"><p style=\"margin: 2px 0 5px 0\">${icon} <strong style=\"font-size:11pt\">${this.getQuestionMarkup(options.question, options.supportHTML)}</strong></p>`;\n\t\tconst answers = Poll.getAnswers(options.answers);\n\n\t\t// indigo, blue, green\n\t\t// nums start at 1 so the actual order is 1. blue, 2. green, 3. indigo, 4. blue\n\t\tconst colors = ['#88B', '#79A', '#8A8'];\n\t\tfor (const [num, answer] of answers) {\n\t\t\tconst chosen = choice?.includes(num);\n\t\t\tconst percentage = Math.round((answer.votes * 100) / (options.totalVotes || 1));\n\t\t\tconst answerMarkup = options.isQuiz ?\n\t\t\t\t`<span style=\"color:${answer.correct ? 'green' : 'red'};\">${answer.correct ? '' : '<s>'}${this.getAnswerMarkup(answer, options.supportHTML)}${answer.correct ? '' : '</s>'}</span>` :\n\t\t\t\tthis.getAnswerMarkup(answer, options.supportHTML);\n\t\t\toutput += `<div style=\"margin-top: 3px\">${num}. <strong>${chosen ? '<em>' : ''}${answerMarkup}${chosen ? '</em>' : ''}</strong> <small>(${answer.votes} vote${answer.votes === 1 ? '' : 's'})</small><br /><span style=\"font-size:7pt;background:${colors[num % 3]};padding-right:${percentage * 3}px\"></span><small>&nbsp;${percentage}%</small></div>`;\n\t\t}\n\t\tif (!choice && !ended) {\n\t\t\toutput += `<div><small>(${room.tr`You can't vote after viewing results`})</small></div>`;\n\t\t}\n\t\toutput += '</div>';\n\n\t\treturn output;\n\t}\n\n\tstatic getQuestionMarkup(question: string, supportHTML = false) {\n\t\tif (supportHTML) return question;\n\t\treturn Chat.formatText(question);\n\t}\n\n\tstatic getAnswerMarkup(answer: PollAnswer, supportHTML = false) {\n\t\tif (supportHTML) return answer.name;\n\t\treturn Chat.formatText(answer.name);\n\t}\n\n\tupdate() {\n\t\tconst state = this.toJSON();\n\t\t// Update the poll results for everyone that has voted\n\t\tconst blankvote = Poll.generateResults(state, this.room, false);\n\n\t\tfor (const id in this.room.users) {\n\t\t\tconst user = this.room.users[id];\n\t\t\tconst selection = this.voters[user.id] || this.voterIps[user.latestIp];\n\t\t\tif (selection) {\n\t\t\t\tif (selection.length) {\n\t\t\t\t\tuser.sendTo(\n\t\t\t\t\t\tthis.room,\n\t\t\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tuser.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${blankvote}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tupdateTo(user: User, connection: Connection | null = null) {\n\t\tconst state = this.toJSON();\n\t\tconst recipient = connection || user;\n\t\tconst selection = this.voters[user.id] || this.voterIps[user.latestIp];\n\t\tif (selection) {\n\t\t\trecipient.sendTo(\n\t\t\t\tthis.room,\n\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`\n\t\t\t);\n\t\t} else {\n\t\t\trecipient.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${this.generateVotes(user)}`);\n\t\t}\n\t}\n\n\tupdateFor(user: User) {\n\t\tconst state = this.toJSON();\n\t\tif (user.id in this.voters) {\n\t\t\tuser.sendTo(\n\t\t\t\tthis.room,\n\t\t\t\t`|uhtmlchange|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, this.voters[user.id])}`\n\t\t\t);\n\t\t} else {\n\t\t\tuser.sendTo(this.room, `|uhtmlchange|poll${this.activityNumber}|${this.generateVotes(user)}`);\n\t\t}\n\t}\n\n\tdisplay() {\n\t\tconst state = this.toJSON();\n\t\tconst blankvote = Poll.generateResults(state, this.room, false);\n\t\tconst blankquestions = this.generateVotes(null);\n\n\t\tfor (const id in this.room.users) {\n\t\t\tconst thisUser = this.room.users[id];\n\t\t\tconst selection = this.voters[thisUser.id] || this.voterIps[thisUser.latestIp];\n\t\t\tif (selection) {\n\t\t\t\tif (selection.length) {\n\t\t\t\t\tthisUser.sendTo(this.room,\n\t\t\t\t\t\t`|uhtml|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, selection)}`);\n\t\t\t\t} else {\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${blankvote}`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.multiPoll && thisUser.id in this.pendingVotes) {\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${this.generateVotes(thisUser)}`);\n\t\t\t\t} else {\n\t\t\t\t\tthisUser.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${blankquestions}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdisplayTo(user: User, connection: Connection | null = null) {\n\t\tconst state = this.toJSON();\n\t\tconst recipient = connection || user;\n\t\tif (user.id in this.voters) {\n\t\t\trecipient.sendTo(\n\t\t\t\tthis.room,\n\t\t\t\t`|uhtml|poll${this.activityNumber}|${Poll.generateResults(state, this.room, false, this.voters[user.id])}`\n\t\t\t);\n\t\t} else if (user.latestIp in this.voterIps && !Config.noipchecks) {\n\t\t\trecipient.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${Poll.generateResults(\n\t\t\t\tstate, this.room, false, this.voterIps[user.latestIp]\n\t\t\t)}`);\n\t\t} else {\n\t\t\trecipient.sendTo(this.room, `|uhtml|poll${this.activityNumber}|${this.generateVotes(user)}`);\n\t\t}\n\t}\n\n\tonConnect(user: User, connection: Connection | null = null) {\n\t\tthis.displayTo(user, connection);\n\t}\n\n\tonRename(user: User, oldid: ID, joining: boolean) {\n\t\tif (user.id in this.voters) {\n\t\t\tthis.updateFor(user);\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tconst results = Poll.generateResults(this.toJSON(), this.room, true);\n\t\tthis.room.send(`|uhtmlchange|poll${this.activityNumber}|<div class=\"infobox\">(${this.room.tr`The poll has ended &ndash; scroll down to see the results`})</div>`);\n\t\tthis.room.add(`|html|${results}`).update();\n\t\tthis.room.setMinorActivity(null);\n\t}\n\n\ttoJSON(): PollData {\n\t\treturn {\n\t\t\tactivityid: 'poll',\n\t\t\tactivityNumber: this.activityNumber,\n\t\t\tquestion: this.question,\n\t\t\tsupportHTML: this.supportHTML,\n\t\t\tmultiPoll: this.multiPoll,\n\t\t\tpendingVotes: this.pendingVotes,\n\t\t\tvoters: this.voters,\n\t\t\tvoterIps: this.voterIps,\n\t\t\ttotalVotes: this.totalVotes,\n\t\t\ttimeoutMins: this.timeoutMins,\n\t\t\ttimerEnd: this.timerEnd,\n\t\t\tisQuiz: this.isQuiz,\n\t\t\tanswers: [...this.answers.values()],\n\t\t};\n\t}\n\n\tsave() {\n\t\tthis.room.settings.minorActivity = this.toJSON();\n\t\tthis.room.saveSettings();\n\t}\n\n\tstatic getAnswers(answers: string[] | PollAnswer[]) {\n\t\tconst out = new Map<number, PollAnswer>();\n\t\tif (answers.length && typeof answers[0] === 'string') {\n\t\t\tfor (const [i, answer] of (answers as string[]).entries()) {\n\t\t\t\tout.set(i + 1, {\n\t\t\t\t\tname: answer.startsWith('+') ? answer.slice(1) : answer,\n\t\t\t\t\tvotes: 0,\n\t\t\t\t\tcorrect: answer.startsWith('+'),\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [i, answer] of (answers as PollAnswer[]).entries()) {\n\t\t\t\tout.set(i + 1, answer);\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n}\n\nexport const commands: Chat.ChatCommands = {\n\tpoll: {\n\t\thtmlcreate: 'new',\n\t\tcreate: 'new',\n\t\tcreatemulti: 'new',\n\t\thtmlcreatemulti: 'new',\n\t\tqueue: 'new',\n\t\tqueuehtml: 'new',\n\t\thtmlqueue: 'new',\n\t\tqueuemulti: 'new',\n\t\thtmlqueuemulti: 'new',\n\t\tnew(target, room, user, connection, cmd, message) {\n\t\t\troom = this.requireRoom();\n\t\t\tif (!target) return this.parse('/help poll new');\n\t\t\ttarget = target.trim();\n\t\t\tif (target.length > 1024) return this.errorReply(this.tr`Poll too long.`);\n\t\t\tif (room.battle) return this.errorReply(this.tr`Battles do not support polls.`);\n\n\t\t\tconst text = this.filter(target);\n\t\t\tif (target !== text) return this.errorReply(this.tr`You are not allowed to use filtered words in polls.`);\n\n\t\t\tconst supportHTML = cmd.includes('html');\n\t\t\tconst multiPoll = cmd.includes('multi');\n\t\t\tconst queue = cmd.includes('queue');\n\n\t\t\tlet params = [];\n\t\t\tlet separator = '';\n\t\t\tif (text.includes('\\n')) {\n\t\t\t\tseparator = '\\n';\n\t\t\t} else if (text.includes('|')) {\n\t\t\t\tseparator = '|';\n\t\t\t} else if (text.includes(',')) {\n\t\t\t\tseparator = ',';\n\t\t\t} else {\n\t\t\t\treturn this.errorReply(this.tr`Not enough arguments for /poll new.`);\n\t\t\t}\n\n\t\t\tlet currentParam = \"\";\n\t\t\tfor (let i = 0; i < text.length; ++i) {\n\t\t\t\tconst currentCharacter = text[i];\n\t\t\t\tconst nextCharacter = text[i + 1];\n\n\t\t\t\t// If the current character is an escape character, insert the next character\n\t\t\t\t// into the param and then skip over checking it in our loop.\n\t\t\t\tconst isEscapeCharacter = currentCharacter === '\\\\';\n\t\t\t\tif (isEscapeCharacter) {\n\t\t\t\t\tif (nextCharacter) {\n\t\t\t\t\t\tcurrentParam += nextCharacter;\n\t\t\t\t\t\ti += 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn this.errorReply(this.tr`Extra escape character. To end a poll with '\\\\', enter it as '\\\\\\\\'`);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// At this point, we know this separator hasn't been escaped, so split here.\n\t\t\t\tconst isSeparator = currentCharacter === separator;\n\t\t\t\tif (isSeparator) {\n\t\t\t\t\tparams.push(currentParam);\n\t\t\t\t\tcurrentParam = \"\";\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// The current character hasn't been escaped and isn't a separator, so it can just be added to the param.\n\t\t\t\tcurrentParam += currentCharacter;\n\t\t\t}\n\t\t\t// Be sure to get the last param we constructed into the array.\n\t\t\tparams.push(currentParam);\n\t\t\tparams = params.map(param => param.trim());\n\n\t\t\tthis.checkCan('minigame', null, room);\n\t\t\tif (supportHTML) this.checkCan('declare', null, room);\n\t\t\tthis.checkChat();\n\t\t\tif (room.minorActivity && !queue) {\n\t\t\t\treturn this.errorReply(this.tr`There is already a poll or announcement in progress in this room.`);\n\t\t\t}\n\n\t\t\tif (params.length < 3) return this.errorReply(this.tr`Not enough arguments for /poll new.`);\n\n\t\t\t// the function throws on failure, so no handling needs to be done anymore\n\t\t\tif (supportHTML) params = params.map(parameter => this.checkHTML(parameter));\n\n\t\t\tconst questions = params.splice(1);\n\t\t\tif (questions.length > MAX_QUESTIONS) {\n\t\t\t\treturn this.errorReply(this.tr`Too many options for poll (maximum is ${MAX_QUESTIONS}).`);\n\t\t\t}\n\n\t\t\tif (new Set(questions).size !== questions.length) {\n\t\t\t\treturn this.errorReply(this.tr`There are duplicate options in the poll.`);\n\t\t\t}\n\n\t\t\tif (room.minorActivity) {\n\t\t\t\troom.queueMinorActivity({\n\t\t\t\t\tquestion: params[0], answers: questions, multiPoll, supportHTML, activityid: 'poll',\n\t\t\t\t});\n\t\t\t\tthis.modlog('QUEUEPOLL');\n\t\t\t\treturn this.privateModAction(room.tr`${user.name} queued a poll.`);\n\t\t\t}\n\t\t\troom.setMinorActivity(new Poll(room, {\n\t\t\t\tquestion: params[0], supportHTML, answers: questions, multiPoll,\n\t\t\t}));\n\n\t\t\tthis.roomlog(`${user.name} used ${message}`);\n\t\t\tthis.modlog('POLL');\n\t\t\tthis.addModAction(room.tr`A poll was started by ${user.name}.`);\n\t\t},\n\t\tnewhelp: [\n\t\t\t`/poll create [question], [option1], [option2], [...] - Creates a poll. Requires: % @ # ~`,\n\t\t\t`/poll createmulti [question], [option1], [option2], [...] - Creates a poll, allowing for multiple answers to be selected. Requires: % @ # ~`,\n\t\t\t`To queue a poll, use [queue], [queuemulti], [queuehtml], or [htmlqueuemulti].`,\n\t\t\t`Polls can be used as quiz questions. To do this, prepend all correct answers with a +.`,\n\t\t],\n\n\t\tviewqueue(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tthis.parse(`/join view-pollqueue-${room.roomid}`);\n\t\t},\n\t\tviewqueuehelp: [`/viewqueue - view the queue of polls in the room. Requires: % @ # ~`],\n\n\t\tdeletequeue(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tif (!target) return this.parse('/help deletequeue');\n\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tconst queue = room.getMinorActivityQueue();\n\t\t\tif (!queue) {\n\t\t\t\treturn this.errorReply(this.tr`The queue is already empty.`);\n\t\t\t}\n\t\t\tconst slot = parseInt(target);\n\t\t\tif (isNaN(slot)) {\n\t\t\t\treturn this.errorReply(this.tr`Can't delete poll at slot ${target} - \"${target}\" is not a number.`);\n\t\t\t}\n\t\t\tif (!queue[slot - 1]) return this.errorReply(this.tr`There is no poll in queue at slot ${slot}.`);\n\n\t\t\troom.clearMinorActivityQueue(slot - 1);\n\n\t\t\troom.modlog({\n\t\t\t\taction: 'DELETEQUEUE',\n\t\t\t\tloggedBy: user.id,\n\t\t\t\tnote: slot.toString(),\n\t\t\t});\n\t\t\troom.sendMods(this.tr`(${user.name} deleted the queued poll in slot ${slot}.)`);\n\t\t\troom.update();\n\t\t\tthis.refreshPage(`pollqueue-${room.roomid}`);\n\t\t},\n\t\tdeletequeuehelp: [\n\t\t\t`/poll deletequeue [number] - deletes poll at the corresponding queue slot (1 = next, 2 = the one after that, etc). Requires: % @ # ~`,\n\t\t],\n\t\tclearqueue(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tconst queue = room.getMinorActivityQueue();\n\t\t\tif (!queue) {\n\t\t\t\treturn this.errorReply(this.tr`The queue is already empty.`);\n\t\t\t}\n\t\t\troom.clearMinorActivityQueue();\n\t\t\tthis.modlog('CLEARQUEUE');\n\t\t\tthis.sendReply(this.tr`Cleared poll queue.`);\n\t\t},\n\t\tclearqueuehelp: [\n\t\t\t`/poll clearqueue - deletes the queue of polls. Requires: % @ # ~`,\n\t\t],\n\n\t\tdeselect: 'select',\n\t\tvote: 'select',\n\t\tselect(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\t\t\tif (!target) return this.parse('/help poll vote');\n\n\t\t\tconst parsed = parseInt(target);\n\t\t\tif (isNaN(parsed)) return this.errorReply(this.tr`To vote, specify the number of the option.`);\n\n\t\t\tif (!poll.answers.has(parsed)) return this.sendReply(this.tr`Option not in poll.`);\n\n\t\t\tif (cmd === 'deselect') {\n\t\t\t\tpoll.deselect(user, parsed);\n\t\t\t} else {\n\t\t\t\tpoll.select(user, parsed);\n\t\t\t}\n\t\t},\n\t\tselecthelp: [\n\t\t\t`/poll select [number] - Select option [number].`,\n\t\t\t`/poll deselect [number] - Deselects option [number].`,\n\t\t],\n\n\t\tsubmit(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\n\t\t\tpoll.submit(user);\n\t\t},\n\t\tsubmithelp: [`/poll submit - Submits your vote.`],\n\n\t\ttimer(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\n\t\t\tif (target) {\n\t\t\t\tthis.checkCan('minigame', null, room);\n\t\t\t\tif (target === 'clear') {\n\t\t\t\t\tif (!poll.endTimer()) return this.errorReply(this.tr(\"There is no timer to clear.\"));\n\t\t\t\t\treturn this.add(this.tr`The poll timer was turned off.`);\n\t\t\t\t}\n\t\t\t\tconst timeoutMins = parseFloat(target);\n\t\t\t\tif (isNaN(timeoutMins) || timeoutMins <= 0 || timeoutMins > 7 * 24 * 60) {\n\t\t\t\t\treturn this.errorReply(this.tr`Time should be a number of minutes less than one week.`);\n\t\t\t\t}\n\t\t\t\tpoll.setTimer({ timeoutMins });\n\t\t\t\troom.add(this.tr`The poll timer was turned on: the poll will end in ${Chat.toDurationString(timeoutMins * MINUTES)}.`);\n\t\t\t\tthis.modlog('POLL TIMER', null, `${timeoutMins} minutes`);\n\t\t\t\treturn this.privateModAction(room.tr`The poll timer was set to ${timeoutMins} minute(s) by ${user.name}.`);\n\t\t\t} else {\n\t\t\t\tif (!this.runBroadcast()) return;\n\t\t\t\tif (poll.timeout) {\n\t\t\t\t\treturn this.sendReply(this.tr`The poll timer is on and will end in ${Chat.toDurationString(poll.timeoutMins * MINUTES)}.`);\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(this.tr`The poll timer is off.`);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttimerhelp: [\n\t\t\t`/poll timer [minutes] - Sets the poll to automatically end after [minutes] minutes. Requires: % @ # ~`,\n\t\t\t`/poll timer clear - Clears the poll's timer. Requires: % @ # ~`,\n\t\t],\n\n\t\tresults(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\n\t\t\tpoll.blankvote(user);\n\t\t},\n\t\tresultshelp: [\n\t\t\t`/poll results - Shows the results of the poll without voting. NOTE: you can't go back and vote after using this.`,\n\t\t],\n\n\t\tclose: 'end',\n\t\tstop: 'end',\n\t\tend(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('minigame', null, room);\n\t\t\tthis.checkChat();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\t\t\tthis.modlog('POLL END');\n\t\t\tthis.privateModAction(room.tr`The poll was ended by ${user.name}.`);\n\t\t\tpoll.end(room, Poll);\n\t\t},\n\t\tendhelp: [`/poll end - Ends a poll and displays the results. Requires: % @ # ~`],\n\n\t\tshow: '',\n\t\tdisplay: '',\n\t\t''(target, room, user, connection) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\t\t\tif (!this.runBroadcast()) return;\n\t\t\troom.update();\n\n\t\t\tif (this.broadcasting) {\n\t\t\t\tpoll.display();\n\t\t\t} else {\n\t\t\t\tpoll.displayTo(user, connection);\n\t\t\t}\n\t\t},\n\t\tdisplayhelp: [`/poll display - Displays the poll`],\n\n\t\tmv: 'maxvotes',\n\t\tmaxvotes(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('mute', null, room);\n\t\t\tconst poll = this.requireMinorActivity(Poll);\n\t\t\tlet num = parseInt(target);\n\t\t\tif (this.meansNo(target)) { // special case for convenience\n\t\t\t\tnum = 0;\n\t\t\t}\n\t\t\tif (isNaN(num)) {\n\t\t\t\treturn this.errorReply(`Invalid max vote cap: '${target}'`);\n\t\t\t}\n\t\t\tif (poll.maxVotes === num) {\n\t\t\t\treturn this.errorReply(`The poll's vote cap is already set to ${num}.`);\n\t\t\t}\n\t\t\tpoll.maxVotes = num;\n\t\t\tthis.addModAction(`${user.name} set the poll's vote cap to ${num}.`);\n\t\t\tlet ended = false;\n\t\t\tif (poll.totalVotes > poll.maxVotes) {\n\t\t\t\tpoll.end(room);\n\t\t\t\tthis.addModAction(`The poll has more votes than the maximum vote cap, and has ended.`);\n\t\t\t\tended = true;\n\t\t\t}\n\t\t\tif (!ended) poll.save();\n\t\t\tthis.modlog('POLL MAXVOTES', null, `${poll.maxVotes}${ended ? ` (ended poll)` : \"\"}`);\n\t\t},\n\t},\n\tpollhelp() {\n\t\tthis.sendReply(\n\t\t\t`|html|<details class=\"readmore\"><summary>/poll allows rooms to run their own polls (limit 1 at a time).<br />` +\n\t\t\t`Polls can be used as quiz questions, by putting <code>+</code> before correct answers.<br />` +\n\t\t\t`<code>/poll create [question], [option1], [option2], [...]</code> - Creates a poll. Requires: % @ # ~</summary>` +\n\t\t\t`<code>/poll createmulti [question], [option1], [option2], [...]</code> - Creates a poll, allowing for multiple answers to be selected. Requires: % @ # ~<br />` +\n\t\t\t`<code>/poll htmlcreate(multi) [question], [option1], [option2], [...]</code> - Creates a poll, with HTML allowed in the question and options. Requires: # ~<br />` +\n\t\t\t`<code>/poll vote [number]</code> - Votes for option [number].<br />` +\n\t\t\t`<code>/poll timer [minutes]</code> - Sets the poll to automatically end after [minutes]. Requires: % @ # ~.<br />` +\n\t\t\t`<code>/poll results</code> - Shows the results of the poll without voting. NOTE: you can't go back and vote after using this.<br />` +\n\t\t\t`<code>/poll display</code> - Displays the poll.<br />` +\n\t\t\t`<code>/poll end</code> - Ends a poll and displays the results. Requires: % @ # ~.<br />` +\n\t\t\t`<code>/poll queue [question], [option1], [option2], [...]</code> - Add a poll in queue. Requires: % @ # ~<br />` +\n\t\t\t`<code>/poll deletequeue [number]</code> - Deletes poll at the corresponding queue slot (1 = next, 2 = the one after that, etc).<br />` +\n\t\t\t`<code>/poll clearqueue</code> - Deletes the queue of polls. Requires: % @ # ~.<br />` +\n\t\t\t`<code>/poll viewqueue</code> - View the queue of polls in the room. Requires: % @ # ~<br />` +\n\t\t\t`<code>/poll maxvotes [number]</code> - Set the max poll votes to the given [number]. Requires: % @ # ~<br />` +\n\t\t\t`</details>`\n\t\t);\n\t},\n};\n\nexport const pages: Chat.PageTable = {\n\tpollqueue(args, user) {\n\t\tconst room = this.requireRoom();\n\n\t\tlet buf = `<div class=\"pad\"><strong>${this.tr`Queued polls:`}</strong>`;\n\t\tbuf += `<button class=\"button\" name=\"send\" value=\"/join view-pollqueue-${room.roomid}\" style=\"float: right\">`;\n\t\tbuf += `<i class=\"fa fa-refresh\"></i> ${this.tr`Refresh`}</button><br />`;\n\t\tconst queue = room.getMinorActivityQueue()?.filter(activity => activity.activityid === 'poll');\n\t\tif (!queue) {\n\t\t\tbuf += `<hr /><strong>${this.tr`No polls queued.`}</strong></div>`;\n\t\t\treturn buf;\n\t\t}\n\t\tfor (const [i, poll] of queue.entries()) {\n\t\t\tconst number = i + 1; // for translation convienence\n\t\t\tconst button = (\n\t\t\t\t`<strong>${this.tr`#${number} in queue`} </strong>` +\n\t\t\t\t`<button class=\"button\" name=\"send\" value=\"/msgroom ${room.roomid},/poll deletequeue ${i + 1}\">` +\n\t\t\t\t`(${this.tr`delete`})</button>`\n\t\t\t);\n\t\t\tbuf += `<hr />`;\n\t\t\tbuf += `${button}<br />${Poll.generateResults(poll, room, false)}`;\n\t\t}\n\t\tbuf += `<hr />`;\n\t\treturn buf;\n\t},\n};\n\nprocess.nextTick(() => {\n\tChat.multiLinePattern.register('/poll (new|create|createmulti|htmlcreate|htmlcreatemulti|queue|queuemulti|htmlqueuemulti) ');\n});\n\n// convert from old format (should handle restarts and also hotpatches)\nfor (const room of Rooms.rooms.values()) {\n\tif (room.getMinorActivityQueue(true)) {\n\t\tfor (const poll of room.getMinorActivityQueue(true)!) {\n\t\t\tif (!poll.activityid) {\n\t\t\t\t// @ts-expect-error old format\n\t\t\t\tpoll.activityid = poll.activityId;\n\t\t\t\t// @ts-expect-error old format\n\t\t\t\tdelete poll.activityId;\n\t\t\t}\n\t\t\tif (!poll.activityNumber) {\n\t\t\t\t// @ts-expect-error old format\n\t\t\t\tpoll.activityNumber = poll.pollNumber;\n\t\t\t\t// @ts-expect-error old format\n\t\t\t\tdelete poll.pollNumber;\n\t\t\t}\n\t\t\troom.saveSettings();\n\t\t}\n\t}\n\tif (room.settings.minorActivity) {\n\t\tif (!room.settings.minorActivity.activityid) {\n\t\t\t// @ts-expect-error old format\n\t\t\troom.settings.minorActivity.activityid = room.settings.minorActivity.activityId;\n\t\t\t// @ts-expect-error old format\n\t\t\tdelete room.settings.minorActivity.activityId;\n\t\t}\n\t\tif (typeof room.settings.minorActivity.activityNumber !== 'number') {\n\t\t\t// @ts-expect-error old format\n\t\t\troom.settings.minorActivity.activityNumber = room.settings.minorActivity.pollNumber ||\n\t\t\t\t// @ts-expect-error old format\n\t\t\t\troom.settings.minorActivity.announcementNumber;\n\t\t}\n\t\troom.saveSettings();\n\t}\n\tif (room.settings.minorActivity?.activityid === 'poll') {\n\t\troom.setMinorActivity(new Poll(room, room.settings.minorActivity), true);\n\t}\n}\n"],
"mappings": "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",
"names": []
}