CB Mod Assist

Helper script for mods on chaturbate.com that lets you save predefined messages and send them to chat with two clicks

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name        CB Mod Assist
// @author      TheKrucible
// @namespace   https://sorte.ninja
// @version     1.2
// @include     https://chaturbate.com/*
// @grant       GM.registerMenuCommand
// @description Helper script for mods on chaturbate.com that lets you save predefined messages and send them to chat with two clicks
// ==/UserScript==

const host = document.createElement('div');
host.setAttribute('class', 'cbma');
document.body.appendChild(host);

const KEY = 'cbma-text';
const EDITOR_ID = 'cbma-textarea';
const STYLES = `
.cbma .editor {
  position: fixed;
  left: 20vw;
  top: 10vh;
  width: 60vw;
  background-color: white;
  padding: 20px;
  box-sizing: border-box;
}
.cbma .editor textarea {
  width: 100%;
  height: 60vh;
  box-sizing: border-box;
  resize: none;
}
.cbma .speak {
  position: absolute;
  right: 50px;
  bottom: 0px;
  width: fit-content;
  max-width: 50vw;
  background-color: white;
  padding: 20px;
  box-sizing: border-box;
}
.cbma .speak ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.cbma .speak ul li {
  cursor: pointer;
}
.cbma .speak ul li.off {
  font-style: italic;
  color: gray;
}
.cbma .speak ul li:hover {
  text-decoration: underline;
}
.cbma .buttonbar {
  margin-top: 20px;
  text-align: right;
}
button.cbma-speak {
  position: absolute;
  right: 75px;
  top: calc(50% - 10px);
  background-color: green;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 3px 5px;
  text-transform: uppercase;
}
`;

function showEditor() {
  const text = window.localStorage.getItem(KEY) || '';
  host.innerHTML = `
<div class="editor">
  <h1>CB Mod Assist Editor</h1>
  <p>
    Enter lines you want to speak in chat here. One line = one chat item. Empty lines are ignored.<br>
    Lines starting with one or more spaces are shown "grayed out" in select box, but can still be spoken.<br>
    Do multi-line speaks with two plus signs: 'This will ++ send three lines ++ to chat'.<br>
    Make model specific sections with a line '# modelname'. Everything following that line will only show in that models room.
  </p>
	<textarea id="${EDITOR_ID}">${text}</textarea>
  <div class="buttonbar">
	  <button id="cbma-close">Save and close</button>
  </div>
</div>
`;
  document.getElementById('cbma-close').addEventListener('click', closeEditor);
}

function closeEditor() {
  const text = document.getElementById(EDITOR_ID).value;
  window.localStorage.setItem(KEY, text);
  host.innerHTML = '';
}

function showSpeak() {
  const items = (window.localStorage.getItem(KEY) || '')
  	.split('\n')
  	.filter(i => i.trim() !== '');

  if (items.length === 0) {
    host.innerHTML = `
<div class="speak">
  <h1>CB Mod Assist</h1>
  <p>No lines entered. Please click 'Edit' below to enter lines.</p>
  <div class="buttonbar">
    <button id="cbma-edit">Edit</button>
    <button id="cbma-close">Cancel</button>
  </div>
</div>
`;
  }
  else {
    host.innerHTML = `
<div class="speak">
  <h1>CB Mod Assist</h1>
  <p>Click line below to speak in chat. Shift+click to copy to chat box without sending.</p>
	<ul id="cbma-list"></ul>
  <div class="buttonbar">
    <button id="cbma-edit">Edit</button>
	  <button id="cbma-close">Cancel</button>
  </div>
</div>
`;
    const list = document.getElementById('cbma-list');
    let model = '';
    items.forEach(item => {
      if (item.startsWith('#')) {
        model = '/' + item.substring(1).trim() + '/'
      }
      else if (window.location.pathname.startsWith(model)) {
        const li = document.createElement('li');
        if (item.startsWith(' ')) {
          li.setAttribute('class', 'off');
        }
        li.textContent = item.trim();
        list.appendChild(li);
      }
    });
    list.addEventListener('click', speak);
  }
  document.getElementById('cbma-edit').addEventListener('click', showEditor);
  document.getElementById('cbma-close').addEventListener('click', cancelSpeak);
}

function speak(event) {
  const speach = event.target.textContent.split('++').map(x => x.trim()).filter(x => !!x);
  const input = document.querySelector('.inputDiv .chat-input-field');
  const button = input.parentElement.parentElement.querySelector('.SendButton');
  if (!input || !button) {
    return;
  }

  if (event.shiftKey) {
    input.innerText = event.target.textContent;
    return;
  }

  if (speach.length > 0) {
    doSpeak(speach, input, button);
  }

  cancelSpeak();
}

function doSpeak(lines, input, button) {
  const line = lines.shift();
  input.innerText = line;
  button.click();

  if (lines.length > 0) {
    window.setTimeout(() => doSpeak(lines, input, button), 300);
  }
}

function cancelSpeak() {
  host.innerHTML = '';
}

GM.registerMenuCommand('CB Mod Assist - Edit', showEditor);
GM.registerMenuCommand('CB Mod Assist - Speak', showSpeak);

function addGlobalStyle(css) {
  const head = document.getElementsByTagName('head')[0];
  if (!head) {
    return;
  }
  const style = document.createElement('style');
  style.type = 'text/css';
  style.innerHTML = css;
  head.appendChild(style);
}

function init() {
  addGlobalStyle(STYLES);
  const input = document.querySelector('div.inputDiv');
  if (input) {
    const button = document.createElement('button');
    button.setAttribute('class', 'cbma-speak');
    button.innerHTML = 'Assist';
    input.appendChild(button);
    const textarea = input.querySelector('.chat-input-field');
    textarea.style.width = (textarea.clientWidth - 60) + 'px';
    button.addEventListener('click', showSpeak);
  }
}

window.addEventListener('load', () => window.setTimeout(init, 2000));