rython-task-bot-v2/widgets/shared/scripts/streamerbot.js
2026-08-03 00:18:33 +10:00

209 lines
4.8 KiB
JavaScript

// STREAMER.BOT SETTINGS
const client = new StreamerbotClient({
host: configs.streamerBotSettings.host,
port: configs.streamerBotSettings.port,
endpoint: configs.streamerBotSettings.endpoint,
onConnect: onConnect,
onDisconnect: onDisconnect,
onError: onError,
});
client.on("General.Custom", (data) => onCustom(data));
if (configs.userColorSettings.autoUserColor) {
client.on("Twitch.ChatMessage", (data) => onChatMessage(data));
client.on("Kick.ChatMessage", (data) => onChatMessage(data));
}
let taskList;
let userColors = {};
function getUserColor(sectionId) {
return (
userColors[`${sectionId}-color`] ??
localStorage.getItem(`${sectionId}-color`)
);
}
function taskColorFromSettings(sectionId) {
const usernameColor = getUserColor(sectionId);
if (
configs.userColorSettings.autoUserColor &&
usernameColor != undefined &&
usernameColor != null
) {
return usernameColor;
}
return undefined;
}
async function onChatMessage(data) {
const userColor = data.data.user.color;
if (userColor != undefined && userColor != "undefined") {
const userId = data.data.user.id;
const key = `twitch-${userId}`;
localStorage.setItem(`${key}-color`, userColor);
userColors[`${key}-color`] = userColor;
}
}
function onDisconnect() {
showConnectionError("Connection Failed: Unable to connect to Streamer.bot");
}
function onError(err) {
showConnectionError(
"Connection Failed: " + (err?.message || "Unknown error"),
);
}
function showConnectionError(message) {
const existing = document.getElementById("connection-error");
if (existing) existing.remove();
const popup = document.createElement("div");
popup.id = "connection-error";
popup.textContent = message;
Object.assign(popup.style, {
position: "fixed",
top: "20px",
left: "50%",
transform: "translateX(-50%)",
background: "#e53935",
color: "#fff",
padding: "12px 24px",
borderRadius: "8px",
fontFamily: "'Fredoka', sans-serif",
fontSize: "1.1rem",
fontWeight: "700",
zIndex: "9999",
boxShadow: "0 4px 12px rgba(0,0,0,0.4)",
textAlign: "center",
});
document.body.appendChild(popup);
setTimeout(() => {
popup.animate([{ opacity: 1 }, { opacity: 0 }], {
duration: 300,
fill: "forwards",
}).onfinish = () => popup.remove();
}, 5000);
}
async function refresh() {
const response = await client.getGlobal("rython-task-bot", true);
if (response.status !== "ok" || !response.variable?.value) return;
const users = JSON.parse(response.variable.value);
const sections = transformToSections(users);
taskList.load(sections);
}
async function onConnect() {
taskList = new TaskList(".task-panel");
if (configs.emoteSettings.enabled) {
const broadcaster = await client.getBroadcaster();
const broadcasterName =
broadcaster.platforms.twitch?.broadcastUser ??
broadcaster.platforms.youtube?.broadcastUser ??
broadcaster.platforms.kick?.broadcastUser;
const broadcasterId =
broadcaster.platforms.twitch?.broadcastUserId ??
broadcaster.platforms.youtube?.broadcastUserId ??
broadcaster.platforms.kick?.broadcastUserId;
window.emoteManager = new EmoteManager({
channelName: broadcasterName,
channelId: broadcasterId,
providers: configs.emoteSettings.providers,
size: configs.emoteSettings.size,
});
window.emoteManager.init().then(() => {
if (taskList) {
taskList.load(taskList.getData());
}
});
}
refresh();
}
function transformToSections(users) {
return Object.entries(users).map(([userId, userData]) => ({
id: userId,
title: userData.Username,
tasks: userData.Tasks.map((task) => ({
text: task.Name,
done: task.Completed,
focused: task.Focused,
})),
}));
}
function onCustom(payload) {
const data = payload.data;
if (data.source !== "rython-task-bot") {
return;
}
if (!taskList) return;
const body = data.body;
const id = data.id;
const username = data.username;
switch (body.mode) {
case "add": {
const taskPayload = {
text: body.task,
done: body.completed,
focused: body.focused,
};
const color = taskColorFromSettings(id);
if (color) taskPayload.color = color;
taskList.addTask(id, taskPayload, username);
break;
}
case "focus":
taskList.focusTask(id, body.index);
break;
case "edit":
taskList.editTask(id, body.index, body.task, taskColorFromSettings(id));
break;
case "remove":
taskList.removeTask(id, body.index);
break;
case "done":
taskList.doneTask(id, body.index);
break;
case "undone":
taskList.undoneTask(id, body.index);
break;
case "unfocus":
taskList.unfocusTask(id);
break;
case "admindelete":
taskList.removeSection(body.id);
break;
case "clearmydone":
taskList.clearmydone(id);
break;
case "cleardone":
taskList.cleardone();
break;
case "clearall":
case "clearns":
case "clearold":
refresh();
break;
default:
break;
}
}