add client to apply color, small fixes

This commit is contained in:
Lea 2023-03-26 00:29:03 +01:00
parent 300cde1217
commit 14ab7af989
Signed by: Lea
GPG key ID: 1BAFFE8347019C42
4 changed files with 125 additions and 4 deletions

25
client.html Normal file
View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>Apply gradient</title>
<link rel="stylesheet" href="./index.css">
<script src="./client.js"></script>
</head>
<body>
<p id="status"></p>
<div id="setup">
<p>
This tool lets you apply your new gradient to a role using a bot account.
<br />
Once you enter a bot token, you will be shown a list of all roles in the servers the bot can access.
<br />
The bot token is only sent to Revolt and will not be stored.
</p>
<input id="token" type="password" autocomplete="off">
<label for="token">Bot token</label>
<button onclick="login()">Go!</button>
</div>
<div id="servers"></div>
</body>
</html>

83
client.js Normal file
View file

@ -0,0 +1,83 @@
let colour;
window.onload = () => {
colour = new URLSearchParams(window.location.search).get('colour');
if (!colour) {
alert(`The 'colour' query parameter was not provided; cannot proceed!`);
document.getElementById('setup').hidden = true;
const statusText = document.getElementById('status');
statusText.innerText = `The 'colour' query parameter was not provided; cannot proceed!`;
}
colour = decodeURIComponent(colour);
}
function login() {
const statusText = document.getElementById('status');
const token = document.getElementById('token').value;
document.getElementById('setup').hidden = true;
statusText.innerText = 'Connecting...';
const socket = new WebSocket(`wss://ws.revolt.chat?version=1&token=${token}`);
let success = false;
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('<', data);
if (data.type == "Ready") {
success = true;
const servers = data.servers;
socket.close();
statusText.innerText = `Received ${servers.length} servers!`;
const serverList = document.getElementById('servers');
for (const server of servers) {
const title = document.createElement('h3');
title.innerText = server.name;
serverList.appendChild(title);
const roleDiv = document.createElement('div');
serverList.appendChild(roleDiv);
for (const role of Object.entries(server.roles)) {
const roleButton = document.createElement('button');
roleButton.innerText = role[1].name;
roleDiv.appendChild(roleButton);
roleDiv.appendChild(document.createElement('br'));
roleButton.onclick = async () => {
const response = confirm(`If your bot has access to it, this will update the color of the role "${role[1].name}" (${role[0]}) in the server "${server.name}" to your new gradient. Are you sure you want to continue?\n\nThe current color of this role is: ${role[1].colour}`);
if (!response) return;
try {
const res = await fetch(
`https://api.revolt.chat/servers/${server._id}/roles/${role[0]}`,
{
method: 'PATCH',
headers: {
"X-Bot-Token": token,
"Content-Type": 'application/json',
},
body: JSON.stringify({
colour: colour,
}, null, 4),
}
);
console.log(res);
alert(`Response: ${res.status} - ${res.statusText}`);
} catch(e) {
console.log(e);
alert('Error: ' + e);
}
}
}
}
}
}
socket.onclose = (event) => {
if (!success) {
statusText.innerText = `Disconnected - ${event.code}`;
document.getElementById('setup').hidden = false;
}
}
}

View file

@ -15,7 +15,8 @@
<h1>Revolt role gradient generator</h1> <h1>Revolt role gradient generator</h1>
<p id="preview">This is a preview of your gradient.</p> <p id="preview">This is a preview of your gradient.</p>
<input type="text" id="output" style="width: calc(100% - 8px)" value="Adjust the options, the output will appear here :3" readonly autocomplete="off" /> <input type="text" id="output" style="width: calc(100% - 8px - 104px)" value="Adjust the options, the output will appear here :3" readonly autocomplete="off" />
<button style="width: 96px;" onclick="let css = generateCss(); if (!css) return; window.open(`./client.html?colour=${encodeURIComponent(css)}`, 'client', 'popup')">Apply to role</button>
<p id="output_error"></p> <p id="output_error"></p>
<h3>Gradient type</h3> <h3>Gradient type</h3>
@ -62,6 +63,9 @@
<div id="config_conic" style="display: none;"> <div id="config_conic" style="display: none;">
<h4>Conic</h4> <h4>Conic</h4>
<p>The following options are <i>disallowed</i> by Revolt, and have been disabled. (Shame because they're quite fun to play around with)</p>
<input id="rotation_conic" type="range" min="0" max="360" value="90" autocomplete="off" oninput="rotation_span_conic.innerText = this.value + '°'; updateUi();"> <input id="rotation_conic" type="range" min="0" max="360" value="90" autocomplete="off" oninput="rotation_span_conic.innerText = this.value + '°'; updateUi();">
<span id="rotation_span_conic">90°</span> <span id="rotation_span_conic">90°</span>
<br /> <br />

View file

@ -1,6 +1,9 @@
const colors = ['#ff0000', '#00ff00', '#0000ff']; const colors = ['#ff0000', '#00ff00', '#0000ff'];
let colorsChanged = true; let colorsChanged = true;
// Copied from https://github.com/revoltchat/backend/blob/master/crates/quark/src/util/regex.rs
const RE_COLOUR = "^(?:[a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|(repeating-)?(linear|conic|radial)-gradient\(([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|\d+deg)([ ]+(\d{1,3}%|0))?(,[ ]*([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+)([ ]+(\d{1,3}%|0))?)+\))$";
function updateUi() { function updateUi() {
const radios = document.getElementsByName('gradient_type'); const radios = document.getElementsByName('gradient_type');
document.getElementById('config_linear').style.display = radios[0].checked ? 'unset' : 'none'; document.getElementById('config_linear').style.display = radios[0].checked ? 'unset' : 'none';
@ -69,6 +72,10 @@ function updateUi() {
if (css.length > 128) { if (css.length > 128) {
document.getElementById('output_error').innerText = `Warning: The generated CSS is ${css.length} characters long, which exceeds Revolt's limit of 128 characters. You will not be able to use this gradient on Revolt.`; document.getElementById('output_error').innerText = `Warning: The generated CSS is ${css.length} characters long, which exceeds Revolt's limit of 128 characters. You will not be able to use this gradient on Revolt.`;
} }
// for some reason this won't work
//else if (!css.match(new RegExp(RE_COLOUR, 'i'))) {
// document.getElementById('output_error').innerText = `Warning: The generated CSS doesn't match against the validation regex. This means that Revolt will not accept one of the set parameters.`;
//}
else document.getElementById('output_error').innerText = ''; else document.getElementById('output_error').innerText = '';
} }
} }
@ -156,10 +163,12 @@ function generateCssConic() {
const showCustomPos = document.getElementById('conic_custom_position').checked; const showCustomPos = document.getElementById('conic_custom_position').checked;
const x = document.getElementById('conic_x').value; const x = document.getElementById('conic_x').value;
const y = document.getElementById('conic_y').value; const y = document.getElementById('conic_y').value;
return `conic-gradient(from ${rotation}deg${showCustomPos ? ` at ${x}% ${y}%` : ''}, ${generateColorList()})`; // have to remove all of this because Revolt doesn't allow it, smh
// from ${rotation}deg${showCustomPos ? ` at ${x}% ${y}%` : ''},
return `conic-gradient(${generateColorList()})`;
} }
// Initial update // Initial update
setTimeout(() => { window.onload = () => {
updateUi(); updateUi();
}, 0); };