idicon/static/index.html

277 lines
8.6 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Idicon</title>
<style>
:root {
--blue: #649ed7;
}
* {
box-sizing: border-box;
color: #333;
}
body {
font-family: sans-serif;
margin: 0;
}
main {
text-align: center;
min-height: calc(100vh - 12em);
}
main > div {
margin: 1em 0;
}
footer {
margin-top: 2em;
border-top: 1px solid lightgray;
background-color: #eee;
height: 8em;
padding: 1em;
}
footer svg {
height: 1.2em;
}
.content {
max-width: 720px;
margin: 0 auto;
}
footer .content {
text-align: center;
}
footer .content div {
padding: .5em;
}
h1 {
padding: 1em 0;
margin: 1em 0;
border-bottom: 1px solid lightgray;
}
input {
box-shadow: inset 1px 1px 4px lightgray;
}
input, select {
outline: none;
}
button {
cursor: pointer;
}
button, input, img, select {
border: 1px solid lightgray;
padding: .25em;
border-radius: .25em;
}
fieldset {
margin: 1em 4em;
border: 1px solid lightgray;
border-radius: .25em;
font-size: small;
}
#action-notice {
font-size: small;
margin: 0 4em;
}
#action-notice > div {
margin: .5em 0;
padding: .25em;
color: darkred;
background-color: #f001;
border: 1px solid darkred;
border-radius: .25em;
transition: opacity .5s;
}
#action-notice > div.tohide {
opacity: 0;
}
#value-input > input {
font-size: larger;
width: 90%;
}
#size-input, #color-input, #type-input, #contenttype-input {
display: flex;
flex-direction: column;
margin: 0 auto;
}
#size-input > input, #color-input > select, #type-input > select, #contenttype-input > select {
width: 8em;
}
#settings {
grid-template-columns: repeat(4, 1fr);
display: grid;
}
label {
margin: .2em;
text-align: left;
}
#value, #size, #color, #type {
transition: box-shadow .1s, border .1s;
}
#value:focus, #size:focus, #color:focus, #type:focus {
box-shadow: 0 0 3px var(--blue);
border: 1px solid var(--blue);
}
label:has(+ *:focus) {
color: var(--blue);
}
img {
width: 200px;
height: 200px;
margin: 4em;
background: #f0f0f0;
}
.small {
font-size: x-small;
}
</style>
</head>
<body>
<main class="content">
<h1>Generate an identicon</h1>
<div id="value-input">
<input id="value" placeholder="Mail address, GitHub username, ..." oninput="idicon(this.value)" />
</div>
<div>
<img id="idicon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIAAAUAAeImBZsAAAAASUVORK5CYII=" />
</div>
<fieldset id="settings">
<legend>Settings</legend>
<div id="size-input" class="small">
<label for="size">Size</label>
<input id="size" type="number" value="200" min="8" max="512" step="8" oninput="newsize(this.value)" />
</div>
<div id="color-input" class="small">
<label for="color">Colorscheme</label>
<select id="color" onchange="newcolor(this.value)">
<option value="v1">V1</option>
<option value="v2">V2</option>
<option value="gh" selected>GH</option>
</select>
</div>
<div id="type-input" class="small">
<label for="type">Type</label>
<select id="type" onchange="newtype(this.value)">
<option value="">Default</option>
<option value="gh" selected>GH</option>
</select>
</div>
<div id="contenttype-input" class="small">
<label for="contenttype">Content-Type</label>
<select id="contenttype" onchange="newcontenttype(this.value)">
<option value="png" selected>PNG</option>
<option value="svg">SVG</option>
</select>
</div>
</fieldset>
<fieldset id="actions">
<legend>Actions</legend>
<button id="fetchGhId" onclick="fetchGhId()">Fetch GitHub ID</button>
</fieldset>
<div id="action-notice"></div>
</main>
<footer>
<div class="content">
<div>
A simple implementation of an identicon service.
</div>
<div>
Copyright &copy; 2024 Paul-Christian Volkmer
</div>
<div>
<a href="https://github.com/pcvolkmer/idicon">
<svg fill="currentColor" viewBox="0 0 24 24" class="h-6 w-6" aria-hidden="true"><path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"></path></svg>
</a>
</div>
</div>
</footer>
</body>
<script>
let currentsize = document.getElementById('size').value;
let currentcolor = document.getElementById('color').value;
let currenttype = document.getElementById('type').value;
let currentcontenttype = document.getElementById('contenttype').value;
idicon(document.getElementById('value').value);
function fetchGhId() {
let username = document.getElementById('value').value;
if (username.trim() !== '') {
fetch(`https://api.github.com/users/${username}`)
.then(res => res.json())
.then(json => {
if (json !== undefined && json.id !== undefined) {
document.getElementById('value').value = json.id;
idicon(document.getElementById('value').value);
} else {
let node = document.createElement('div');
node.innerText = `Fetching GitHub ID for username '${username}' not possible!`;
document.getElementById('action-notice').append(node);
setTimeout(() => {
node.className = 'tohide';
}, 4500);
setTimeout(() => {
node.remove();
}, 5000);
}
});
}
}
function newsize(value) {
currentsize = value;
idicon(document.getElementById('value').value);
}
function newcolor(value) {
currentcolor = value;
idicon(document.getElementById('value').value);
}
function newtype(value) {
currenttype = value;
idicon(document.getElementById('value').value);
}
function newcontenttype(value) {
currentcontenttype = value;
idicon(document.getElementById('value').value);
}
function idicon(value) {
if (value.trim() === '') {
document.getElementById('idicon').src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIAAAUAAeImBZsAAAAASUVORK5CYII=';
return;
}
document.getElementById('idicon').src = `./avatar/${value}?s=${currentsize}&c=${currentcolor}&d=${currenttype}&ct=${currentcontenttype}`
}
</script>
</html>