Apps Home
|
Create an App
Timed Voting Booth
Author:
genuwin
Description
Source Code
Launch App
Current Users
Created by:
Genuwin
// Modified 'Timed vote with tips' by genuwin // Added minimum tip required to vote // Original author: asdfghjkl28 const COLOR_ERROR = '#B94A48'; // Red: Everything fails const COLOR_NOTICE = '#6900CC'; // Bluish purple: General chat notice // CB app settings cb.settings_choices = [ {name: 'timeLimit', label: 'Time limit - after this time, the winning option will be chosen (minutes)', type: 'int', minValue: 1, defaultValue: 15}, {name: 'mintip', label: 'Minimum tip required to count towards vote - Default 5', type: 'int', minValue: 1, defaultValue: 5}, {name: 'busyMode', type: 'choice', label: 'Run in busy room mode?', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'choice_1', label: 'Option 1', type: 'str', maxLength: 200}, {name: 'choice_2', label: 'Option 2', type: 'str', maxLength: 200}, {name: 'choice_3', label: 'Option 3', type: 'str', maxLength: 200, required: false}, {name: 'choice_4', label: 'Option 4', type: 'str', maxLength: 200, required: false}, {name: 'choice_5', label: 'Option 5', type: 'str', maxLength: 200, required: false} ]; var choices = []; var choiceLookup = {}; var startTime = new Date().getTime(); var oneMinute = 60 * 1000; var thirtySeconds = 30 * 1000; var oneSecond = 1000; var timeUp = false; var timeLeft = cb.settings.timeLimit * oneMinute; var timeLeftMessage = cb.settings.timeLimit / oneMinute + ' mins'; var goalChosen = ""; var lastThirtyMessageDone = false; var busyMode = false; if (cb.settings.busyMode == 'Yes') { busyMode = true; } for ( i = 1; i < 6; i++) { var name = 'choice_' + i; if (cb.settings[name]) { choices[i - 1] = ({label: cb.settings[name], tokens: 0, index: i - 1}); choiceLookup[cb.settings[name]] = {index: i - 1}; } } function doUpdateChecks() { updateTimeLeft(); // Only update subject on big gaps if (timeLeft >= thirtySeconds - (5 * oneSecond) || timeLeft < oneSecond) { updateSubject(); } if (!busyMode) { // Always update panel cb.drawPanel(); } if (timeLeft <= oneMinute && timeLeft >= thirtySeconds) { cb.log("Doing 30 second updates"); cb.setTimeout(doUpdateChecks, thirtySeconds); printOptionsWithTokens("Not long left!\nVoting Options:", null); } else if ((timeLeft < thirtySeconds && timeLeft > 0)) { cb.log("Doing 5 second updates"); cb.setTimeout(doUpdateChecks, 5 * oneSecond); if (!lastThirtyMessageDone) { printOptionsWithTokens("Last 30 seconds!\nVoting Options:", null); lastThirtyMessageDone = true; } } else if (timeLeft > oneMinute) { cb.log("Doing 60 second updates"); cb.setTimeout(doUpdateChecks, oneMinute); printOptionsWithTokens("Voting options: ", null); } else { cb.log("Final update"); } } function updateTimeLeft() { var secondsPassed = (new Date().getTime()) - startTime; timeLeft = (cb.settings.timeLimit * oneMinute) - secondsPassed; if (timeLeft <= 0) { cb.log("Timer finished"); timeUp = true; goalChosen = getTopGoal(); timeLeftMessage = "No time"; } else if (timeLeft < oneMinute) { timeLeftMessage = Math.ceil(timeLeft / oneSecond) + ' secs'; } else { timeLeftMessage = Math.ceil(timeLeft / oneMinute) + ' mins'; } cb.log("Time left: " + timeLeft); } // Show choices in tip options cb.tipOptions(function (user) { if (!goalChosen) { choices.sort(dynamicSort("index")); cb.log(choices.map(getLabel).join(', ')); return {options: choices.map(labelsOnly), label: "Vote with your tip:"}; } else { return; } }); function getTopGoal() { var top_goal_display = '--'; // Reverse sort choice list by tokens so far choices.sort(dynamicSort("-tokens")); if (choices.length > 0 && choices[0].tokens > 0) { top_goal_display = choices[0].label + " (" + choices[0].tokens + " tokens)"; } return top_goal_display; } // Show current winner and remaining time cb.onDrawPanel(function (user) { if (!busyMode) { if (!timeUp) { return { 'template': '3_rows_12_22_31', 'row1_label': 'Time remaining:', 'row1_value': timeLeftMessage, 'row2_label': 'Top choice:', 'row2_value': getTopGoal(), 'row3_value': cb.room_slug+' Voting booth open. Minimum tip: '+cb.settings.mintip+' - type /stats for info' }; } else { if (goalChosen == '--') { return { 'template': '3_rows_12_22_31', 'row1_label': 'Time\'s up!', 'row1_value': '', 'row2_label': 'No tips received', 'row2_value': 'No vote winner', 'row3_value': 'Type /stats to see the final result' }; } else { return { 'template': '3_rows_12_22_31', 'row1_label': 'Time\'s up!', 'row1_value': '', 'row2_label': 'Winning choice:', 'row2_value': goalChosen, 'row3_value': 'Type /stats to see the final result' }; } } } }) ; function sendStats(user) { printOptionsWithTokens("Voting stats: ", user); } function printOptionsWithTokens(title, user) { var msg = title; choices.sort(dynamicSort("-tokens")); for (var i = 0; i < choices.length; i++) { msg += "\n" + choices[i].label + " (" + choices[i].tokens + " tokens)"; } // if (choices[0].tokens > 0) { // var tokenLead = choices[0].tokens - choices[1].tokens; // msg += "\nTip " + (tokenLead + 1) + " tokens to move " + choices[1].label + " into the lead!"; // } if (user != null) { msg += "\n Voting Booth is now open. Tip a minimum of "+cb.settings.mintip+" to cast your vote. The Booth will be closing in "+timeLeftMessage+"."; cb.chatNotice(msg, user); } else { msg += "\n Voting Booth is now open. Tip a minimum of "+cb.settings.mintip+" to cast your vote. The Booth will be closing in "+timeLeftMessage+"."; cb.chatNotice(msg); } } cb.onTip(function (tip) { var u = tip['from_user']; if (tip['amount'] < cb.settings.mintip) { cb.sendNotice("* A tip of atleast "+cb.settings.mintip+" is required to vote.",u,'',COLOR_ERROR,'bold'); } else { if (!goalChosen) { if (choiceLookup[tip['message']]) { choices[choiceLookup[tip['message']].index].tokens += tip['amount']; cb.sendNotice("* Thank you for your vote!!",u,'',COLOR_NOTICE,'bold'); } updateTimeLeft(); if (!busyMode) { cb.drawPanel(); } updateSubject(); } } }); cb.onMessage(function (msg) { var u = msg['user']; var isMod = msg['is_mod']; var theBC = cb.room_slug; var isBC = (u == theBC); if (msg['m'] == '/stats') { msg['X-Spam'] = true; sendStats(msg['user']); } if (msg['m'] == '/end') { if (isMod || isBC) { endearly(); } } if (msg['m'] == '/info') { if (isMod || isBC) { cb.sendNotice("Voting Booth is now open. Tip a minimum of "+cb.settings.mintip+" to cast your vote. The booth will be closing in "+timeLeftMessage+".",'','',COLOR_NOTICE,'bold'); } } return msg; }); function endearly() { timeUp = true; timeLeft = 0; goalChosen = getTopGoal(); cb.drawPanel(); updateSubject(); } function updateSubject() { var newSubject = ""; if (!timeUp) { newSubject = cb.room_slug+" voting booth: Currently in the lead " + getTopGoal() + " [" + timeLeftMessage + " remaining]"; } else { newSubject = "Chosen goal: " + goalChosen; } cb.changeRoomSubject(newSubject); } // Start Helper functions section function dynamicSort(property) { var sortOrder = 1; if (property[0] === "-") { sortOrder = -1; property = property.substr(1, property.length - 1); } return function (a, b) { var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; return result * sortOrder; } } function getLabel(a, b) { return a.label; } function labelsOnly(a, b) { return {label: a.label}; } // End Helper functions section // Initialisation doUpdateChecks();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.