169 lines
6.2 KiB
PHP
169 lines
6.2 KiB
PHP
<?php
|
|
include __DIR__ . "/incl/util.php";
|
|
|
|
$conn = connectToDatabase();
|
|
|
|
$stmt = $conn->prepare("SELECT * FROM colors ORDER BY timestamp DESC");
|
|
$stmt->execute();
|
|
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$total = 255 * 255 * 255;
|
|
$named = count($result);
|
|
$remaining = $total - $named;
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Name A Color</title>
|
|
<link rel="icon" type="image/png" href="/favicon.png">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="preconnect" href="https://challenges.cloudflare.com">
|
|
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">
|
|
<style>
|
|
body {
|
|
font-family: "Lexend", sans-serif;
|
|
background-color: #121212;
|
|
color: #fff;
|
|
text-align: center;
|
|
}
|
|
|
|
.named-color {
|
|
display: inline-block;
|
|
margin: 10px;
|
|
background-color: #1e1e1e;
|
|
padding: 10px;
|
|
border-radius: 10px;
|
|
width: 128px;
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
.named-color.highlight {
|
|
border: 2px solid #006eff
|
|
}
|
|
|
|
.color {
|
|
width: 128px;
|
|
height: 128px;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.used-text {
|
|
display: none;
|
|
color: red;
|
|
}
|
|
</style>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const usedColors = <?= json_encode(array_column($result, 'color')) ?>;
|
|
const usedNames = <?= json_encode(array_column($result, 'name')) ?>;
|
|
const form = document.querySelector('form');
|
|
const colorInput = document.querySelector('.color-picker');
|
|
const nameInput = document.querySelector('.name-input');
|
|
const usedColorText = document.querySelector('.used-color');
|
|
const usedNameText = document.querySelector('.used-text');
|
|
const colorValue = document.querySelector('.color-value');
|
|
const submit = document.querySelector('.submit-button');
|
|
const colorContainer = document.querySelector(".colors");
|
|
|
|
colorInput.value = '#<?= bin2hex(random_bytes(3)) ?>';
|
|
|
|
const checkColor = () => {
|
|
colorValue.innerText = `Hex: ${colorInput.value}`;
|
|
if (usedColors.includes(colorInput.value.substr(1))) {
|
|
usedColorText.style.display = 'block';
|
|
submit.disabled = true;
|
|
} else {
|
|
usedColorText.style.display = 'none';
|
|
submit.disabled = false;
|
|
}
|
|
};
|
|
|
|
const checkName = () => {
|
|
if (usedNames.includes(btoa(nameInput.value))) {
|
|
usedNameText.style.display = 'block';
|
|
submit.disabled = true;
|
|
} else {
|
|
usedNameText.style.display = 'none';
|
|
submit.disabled = false;
|
|
}
|
|
};
|
|
|
|
colorInput.addEventListener('input', checkColor);
|
|
nameInput.addEventListener('input', checkName);
|
|
form.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const response = await fetch('/upload.php?' + new URLSearchParams(new FormData(form)));
|
|
const text = await response.text()
|
|
if (text == "-1") {
|
|
alert("Invalid color")
|
|
} else if (text == "-2") {
|
|
alert("Name too short")
|
|
} else if (text == "-3") {
|
|
alert("Name too long")
|
|
} else if (text == "-4") {
|
|
alert("Color already taken")
|
|
} else if (text == "-5") {
|
|
alert("Name already taken")
|
|
} else {
|
|
colorContainer?.firstElementChild?.classList.remove("highlight");
|
|
|
|
const namedColor = document.createElement("div");
|
|
namedColor.className = "named-color highlight";
|
|
|
|
const color = document.createElement("div");
|
|
color.className = "color";
|
|
color.style.background = colorInput.value;
|
|
|
|
const p = document.createElement("p");
|
|
p.textContent = `${nameInput.value} • ${colorInput.value}`;
|
|
|
|
namedColor.appendChild(color);
|
|
namedColor.appendChild(p);
|
|
colorContainer.prepend(namedColor);
|
|
|
|
usedColors.push(colorInput.value)
|
|
usedNames.push(btoa(nameInput.value))
|
|
|
|
colorInput.value = `#${Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, '0')}`;
|
|
nameInput.value = "";
|
|
}
|
|
});
|
|
|
|
checkColor();
|
|
checkName();
|
|
});
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<h1>Name A Color!</h1>
|
|
<p><?= formatWithCommas($named) ?>/<?= formatWithCommas($total) ?> colors named (<?= formatWithCommas($remaining) ?> left)</p>
|
|
<hr>
|
|
<h2>Name your own color!</h2>
|
|
<form>
|
|
<p class="used-color">This color has already been named!</p>
|
|
<p class="used-text">This name has already been used!</p>
|
|
<label for="color">Color:</label>
|
|
<input type="color" id="color" name="color" class="color-picker" required>
|
|
<label for="name">Name:</label>
|
|
<input type="text" id="name" name="name" maxlength="50" class="name-input" required>
|
|
<label class="color-value"></label>
|
|
<button type="submit" class="submit-button">Name it!</button>
|
|
</form>
|
|
<hr>
|
|
<h2>Colors that were named</h2>
|
|
<div class="colors">
|
|
<?php
|
|
foreach ($result as $row) {
|
|
echo "<div class=\"named-color\">";
|
|
echo "<div class=\"color\" style=\"background: #" . $row['color'] . ";\"></div>";
|
|
echo "<p>" . htmlspecialchars(base64_decode($row['name'])) . " • #" . $row["color"] . "</p>";
|
|
echo "</div>";
|
|
}
|
|
?>
|
|
</div>
|
|
</body>
|
|
</html>
|