Apps Home
|
Create an App
blackberry goal meter
Author:
yungblackberry
Description
Source Code
Launch App
Current Users
Created by:
Yungblackberry
// ============================ // Animated Goal Tracker (CB App) // - Smooth animated progress in the panel // - Goal hits tracking // - Subject updates // - Broadcaster commands: !settok, !setreached // ============================ // vars var times_goal_reached = 0; var last_time_goal_reached = null; var current_goal_tipped = 0; // NEW: animated display amount (what panel shows) var display_goal_tipped = 0; var pulse_on = false; var set_tokens_command = '!settok'; var set_reached_command = '!setreached'; cb.settings_choices = [ { name: 'tokens', type: 'int', minValue: 1, defaultValue: 100 }, { name: 'goal_description', type: 'str', minLength: 1, maxLength: 255, defaultValue: "Goal" }, // NEW: theme + animation speed { name: 'theme', type: 'choice', label: 'Panel Theme', choice1: 'Diamond (Purple)', choice2: 'Heart (Red)', choice3: 'Emerald (Green)', choice4: 'Gold (Yellow)', choice5: 'Neon (Blue)', defaultValue: 'Diamond (Purple)' }, { name: 'anim_speed', type: 'choice', label: 'Animation Speed', choice1: 'Smooth', choice2: 'Fast', defaultValue: 'Smooth' } ]; // ---------------------------- // Tip handler // ---------------------------- cb.onTip(function (tip) { current_goal_tipped += tip['amount']; if (current_goal_tipped >= cb.settings.tokens) { goalReached(tip['from_user']); } update_subject(); cb.drawPanel(); }); // ---------------------------- // Panel drawing // ---------------------------- cb.onDrawPanel(function (user) { var goalTokens = cb.settings.tokens; var total = (times_goal_reached * goalTokens) + current_goal_tipped; // Use animated display value for percent/bar var shown = display_goal_tipped; if (shown < 0) shown = 0; if (shown > goalTokens) shown = goalTokens; var pct = Math.floor((shown / goalTokens) * 100); if (pct < 0) pct = 0; if (pct > 100) pct = 100; var theme = getTheme(cb.settings.theme); var bar = progressBar(pct, 14); var sparkle = pulse_on ? " ✨" : ""; var lastReachedText = "Never"; if (times_goal_reached > 0 && last_time_goal_reached) { var minsAgo = Math.floor(((new Date()).getTime() - last_time_goal_reached.getTime()) / 60000); lastReachedText = minsAgo + " minutes ago"; } return { 'template': '3_rows_of_labels', 'row1_label': theme.icon + " " + cb.settings.goal_description, 'row1_value': shown + " / " + goalTokens + " " + bar + " " + pct + "%"+ sparkle, 'row2_label': theme.mini + " Hit Goal For:", 'row2_value': times_goal_reached + " time(s) | Total: " + total, 'row3_label': "🕒 Last Reached:", 'row3_value': lastReachedText }; }); // ---------------------------- // Broadcaster commands // ---------------------------- cb.onMessage(function (msg) { var m = msg['m'] || ""; if (m.length === 0) return msg; if (m.charAt(0) === '!' && msg['user'] === cb.room_slug) { if (startsWith(m, set_tokens_command)) { msg['X-Spam'] = true; var numStr = m.slice(set_tokens_command.length).trim(); var number = parseInt(numStr, 10); if (isNaN(number)) { cb.chatNotice("Usage: !settok <number>", msg['user']); return false; } times_goal_reached = Math.floor(number / cb.settings.tokens); current_goal_tipped = number % cb.settings.tokens; last_time_goal_reached = new Date(); // keep animation in sync display_goal_tipped = current_goal_tipped; update_subject(); cb.drawPanel(); cb.chatNotice('Tokens received has been updated!', msg['user']); return false; } else if (startsWith(m, set_reached_command)) { msg['X-Spam'] = true; var numStr2 = m.slice(set_reached_command.length).trim(); var number2 = parseInt(numStr2, 10); if (isNaN(number2)) { cb.chatNotice("Usage: !setreached <number>", msg['user']); return false; } times_goal_reached = number2; last_time_goal_reached = new Date(); current_goal_tipped = 0; // keep animation in sync display_goal_tipped = 0; update_subject(); cb.drawPanel(); cb.chatNotice('Times reached has been updated!', msg['user']); return false; } } return msg; }); // ---------------------------- // Animation loop (this is the "animated" part) // ---------------------------- function animatePanelTick() { // pulse sparkle pulse_on = !pulse_on; // step the displayed value toward the real value var goalTokens = cb.settings.tokens; var target = current_goal_tipped; // Speed control var step; if (cb.settings.anim_speed === "Fast") { step = Math.max(2, Math.ceil(goalTokens / 40)); // bigger steps } else { step = Math.max(1, Math.ceil(goalTokens / 90)); // smoother steps } if (display_goal_tipped < target) { display_goal_tipped = Math.min(target, display_goal_tipped + step); } else if (display_goal_tipped > target) { display_goal_tipped = Math.max(target, display_goal_tipped - step); } cb.drawPanel(); cb.setTimeout(animatePanelTick, 800); // ~0.8s feels animated without spamming } // ---------------------------- // Subject + goal logic (your originals, kept) // ---------------------------- function update_subject() { var new_subject = cb.settings.goal_description + " [" + tips_remaining() + " tokens remaining]"; cb.changeRoomSubject(new_subject); } function goalReached(userName) { last_time_goal_reached = new Date(); var curr_times_reached = Math.floor(current_goal_tipped / cb.settings.tokens); for (var i = 0; i < curr_times_reached; i++) { times_goal_reached++; current_goal_tipped -= cb.settings.tokens; cb.chatNotice("Goal was reached for the " + getNumberString(times_goal_reached) + " time!"); // Optional: make the hit REALLY stand out cb.sendNotice( "🎯 GOAL HIT! " + cb.settings.goal_description + " (" + getNumberString(times_goal_reached) + ") by " + userName, "", "#0B0F14", "#FFD24A", "bolder" ); } update_subject(); cb.drawPanel(); } function getNumberString(number) { var lastChar = String(number).charAt(String(number).length - 1); if ((lastChar == '1') && ((number % 100) != 11)) return number + "st"; if ((lastChar == '2') && ((number % 100) != 12)) return number + "nd"; if ((lastChar == '3') && ((number % 100) != 13)) return number + "rd"; return "" + number + "th"; } function tips_remaining() { var r = cb.settings.tokens - current_goal_tipped; return (r < 0) ? 0 : r; } function startsWith(source, str) { return source.substring(0, str.length) === str; } // ---------------------------- // UI helpers (text-based "animated" look) // ---------------------------- function progressBar(percent, width) { // Unicode block bar: █ filled, ░ empty var filled = Math.round((percent / 100) * width); var s = ""; for (var i = 0; i < width; i++) s += (i < filled) ? "█" : "░"; return s; } function getTheme(name) { if (name === "Heart (Red)") return { icon: "💎➡️❤️", mini: "❤️" }; if (name === "Emerald (Green)") return { icon: "💠 EMERALD", mini: "🌿" }; if (name === "Gold (Yellow)") return { icon: "🔶 GOLD", mini: "🏦" }; if (name === "Neon (Blue)") return { icon: "🔷 NEON", mini: "📈" }; return { icon: "💎 DIAMOND", mini: "💸" }; // default } // ---------------------------- // Init // ---------------------------- function init() { update_subject(); display_goal_tipped = Math.min(current_goal_tipped, cb.settings.tokens); cb.drawPanel(); animatePanelTick(); } init();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.