all repos — felt @ 7cdcdf5528695ac45bb7a23cbdcb824e4506e4dd

virtual tabletop for dungeons and dragons (and similar) using Go, MongoDB, and websockets

implement themes
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmSs9+UACgkQO3+8IhRO
Y5jc8A//Z1FLjJkNsKs/bNoe5XuPeGaZIyXPsrvMR4SVn0OaUGcX4EXUWtfBMiGK
Cdtwyj9zoJDnvPbs3m6mbtfztDjpe/7U5WBgGB0b8DMhBQz0o7+V3uWhtS/o1ALy
OOz+AqjlTiVgGCIRHhVKb8VR47J67i3hXCCvHhji6u2slJSgPGWMRKFCSF+y/8wm
tad1Xi/iuF96CzN8yzejZpucsfIH2h+59PO0rPPP/ztHlqFDbbjJ4z4Bdxh08smp
+vS2tpvnIceyPllZ0e+HjmACnvOwV2SzRAngVpmCLZn475qDiSbtCZ7MjKmRZFzt
YfRQ+YwrMmv6LjIfLUaC3cCkXB7jEZF4FgkFKJk4C766bKJpSxfrV5tS0OGKydxc
HJL7VSBIpPVpinlnqa/jBDEjk/tMUtpm7QwfyJ/ZV3V8F2yQvfwqg1Zt5HC7nzPx
wsY/exbDrbawKkszpsw1QUFE2s9YSI5JieHSr7LU71jWVm2k4LMW1DCJCVVyZxv8
yFjuuQmMvtT97O5lZ0YWAyYwtvxRxqKfhhzOzMZstl5Np6Tq0FzqViwD2ydxdodF
lVao0h+eM4/1/1H2O+A/x6NtyWfOSmr+/jpyQl2heIrk8G/PmvQcF2DbbuqcL8zB
RQUv2yNuOc8YCyB+U3d/BMOLSHaspfwD67aF0zHFiihbaLwdQeQ=
=RSa0
-----END PGP SIGNATURE-----
commit

7cdcdf5528695ac45bb7a23cbdcb824e4506e4dd

parent

faccff3fb22052b9048f7960127048a0914ce0fe

M register/register.goregister/register.go

@@ -57,7 +57,6 @@ return data

} func (self *SymmetricCrypt) Encrypt(text string) (string, error) { - fmt.Println(text) block, err := aes.NewCipher([]byte(self.Secret)) if err != nil { return "", err
M static/index.htmlstatic/index.html

@@ -17,6 +17,19 @@ <section id="user_section">

<details class="ui_win" open><summary>identity</summary> <label for="name_entry">username</label> <input id="name_entry" onblur="saveName()"> + <details id="theme_accordion"><summary>theme</summary> + <form id="theme_cfg" onsubmit="return false"> + <label>bg color<input type="color" id="bg_col_input"/></label><br/> + <label>bg opacity<input type="range" id="bg_col_opacity" min="0" max="255"/></label><br/> + <label>fg color<input type="color" id="fg_col_input"/></label><br/> + <label>fg opacity<input type="range" id="fg_col_opacity" min="0" max="255"/></label><br/> + <label>main color<input type="color" id="main_col_input"/></label><br/> + <label>main opacity<input type="range" id="main_col_opacity" min="0" max="255"/></label><br/> + <label>sub color<input type="color" id="sub_col_input"/></label><br/> + <label>sub opacity<input type="range" id="sub_col_opacity" min="0" max="255"/></label><br/> + <button onclick="setTheme()">Apply</button><button onclick="resetTheme(defaultTheme)">Reset</button> + </form> + </details> </details><br/> <details class="ui_win"><summary>goto</summary>
M static/style.cssstatic/style.css

@@ -10,6 +10,7 @@ box-sizing: border-box;

padding: 0; margin: 0; appearance: none; + -webkit-appearance: none; outline: none; }

@@ -228,4 +229,80 @@ }

#registration a:hover { color: var(--fg_color); +} + +#theme_accordion summary { + text-align: right; +} + +input[type=range] { + -webkit-appearance: none; /* Hides the slider so that custom slider can be made */ + width: 100%; /* Specific width is required for Firefox. */ + background: transparent; /* Otherwise white in Chrome */ +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; +} + +input[type=range]:focus { + outline: none; /* Removes the blue border. You should probably do some kind of focus styling for accessibility reasons though. */ +} + +input[type=range]::-ms-track { + width: 100%; + cursor: pointer; + + /* Hides the slider so custom styles can be added */ + background: transparent; + border-color: transparent; + color: transparent; +} + +input[type=range]::-webkit-slider-thumb { + height: 16px; + width: 16px; + border: none; + border-radius: 0px; + background: var(--main_color); + cursor: pointer; +} + +/* All the same stuff for Firefox */ +input[type=range]::-moz-range-thumb { + height: 16px; + width: 16px; + border-radius: 0px; + border: none; + background: var(--main_color); + cursor: pointer; +} + +/* All the same stuff for IE */ +input[type=range]::-ms-thumb { + height: 16px; + width: 16px; + border-radius: 0px; + border: none; + background: var(--main_color); + cursor: pointer; +} + +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 16px; + cursor: pointer; + background: var(--sub_color); + border-radius: 0; + border: solid 1px var(--sub_color); +} + + +input[type=range]::-moz-range-track { + background: var(--sub_color); + height: 16px; +} + +.error { + border-bottom: solid 2px crimson; }
M static/util.jsstatic/util.js

@@ -3,6 +3,16 @@ const errWrapper = document.getElementById("errWrapper");

const defaultTheme = [ "#000000cc", "#ccccccff", "#1f9b92ff", "#002b36ff" ]; +const bgCol_input = document.getElementById("bg_col_input"); +const fgCol_input = document.getElementById("fg_col_input"); +const mainCol_input = document.getElementById("main_col_input"); +const subCol_input = document.getElementById("sub_col_input"); + +const bgOp_input = document.getElementById("bg_col_opacity"); +const fgOp_input = document.getElementById("fg_col_opacity"); +const mainOp_input = document.getElementById("main_col_opacity"); +const subOp_input = document.getElementById("sub_col_opacity"); + const saveData = { username: "", theme: defaultTheme,

@@ -25,8 +35,8 @@ }

function loadStorage() { saveData.username = localStorage.getItem("username"); - saveData.theme = JSON.parse(localStorage.getItem("theme")); - + savedTheme = JSON.parse(localStorage.getItem("theme")); + saveData.theme = savedTheme || defaultTheme; const username = document.getElementById("name_entry"); if (username) { username.value = saveData.username;

@@ -34,7 +44,6 @@ }

} function saveName() { - console.log("saving username"); const username = document.getElementById("name_entry"); if (username) { saveData.username = username.value;

@@ -44,13 +53,82 @@ }

function setupDiceAutoScroll() { const diceWin = document.getElementById("dice_win"); - diceWin.addEventListener("toggle", e => { - if (diceWin.open) { - const diceLog = document.getElementById("dice_log"); - diceLog.children[diceLog.children.length - 1].scrollIntoView(); - } - }); + if (diceWin) { + diceWin.addEventListener("toggle", e => { + if (diceWin.open) { + const diceLog = document.getElementById("dice_log"); + diceLog.children[diceLog.children.length - 1].scrollIntoView(); + } + }); + } +} + +function hexToBytes(hex) { + let bytes = []; + for (let c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; +} + +function toByte(v) { + return ('0' + + Math.min(Math.max(parseInt(v), 0), 255).toString(16) + ).slice(-2); +} + +function resetTheme(theme) { + try{ + let bg_col = theme[0]; + let fg_col = theme[1]; + let main_col = theme[2]; + let sub_col = theme[3]; + + let fg_opacity = hexToBytes(fg_col.substr(7)); + fg_col = fg_col.substr(0,7); + let bg_opacity = hexToBytes(bg_col.substr(7)); + bg_col = bg_col.substr(0,7); + let main_opacity = hexToBytes(main_col.substr(7)); + main_col = main_col.substr(0,7); + let sub_opacity = hexToBytes(sub_col.substr(7)); + sub_col = sub_col.substr(0,7); + + bgCol_input.value = bg_col; + bgOp_input.value = bg_opacity; + fgCol_input.value = fg_col; + fgOp_input.value = fg_opacity; + mainCol_input.value = main_col; + mainOp_input.value = main_opacity; + subCol_input.value = sub_col; + subOp_input.value = sub_opacity; + } catch {} +} + +function setTheme() { + try{ + let bg_col = bgCol_input.value; + let bg_opacity = toByte(bgOp_input.value); + let fg_col = fgCol_input.value; + let fg_opacity =(toByte(fgOp_input.value)); + let main_col = mainCol_input.value; + let main_opacity = (toByte(mainOp_input.value)); + let sub_col = subCol_input.value; + let sub_opacity = (toByte(subOp_input.value)); + + saveData.theme[0] = bg_col + bg_opacity; + saveData.theme[1] = fg_col + fg_opacity; + saveData.theme[2] = main_col + main_opacity; + saveData.theme[3] = sub_col + sub_opacity; + + localStorage.setItem("theme", JSON.stringify(saveData.theme)); + } catch {} finally { + document.body.style.setProperty("--bg_color", saveData.theme[0]); + document.body.style.setProperty("--fg_color", saveData.theme[1]); + document.body.style.setProperty("--main_color", saveData.theme[2]); + document.body.style.setProperty("--sub_color", saveData.theme[3]); + } } setupDiceAutoScroll(); -loadStorage();+loadStorage(); +resetTheme(saveData.theme); +setTheme();
M templates/register.htmltemplates/register.html

@@ -13,13 +13,14 @@ <main id="registration">

<h1>Felt Admin Registration</h1> {{ if $valid }} <form action="/register/{{ $cipher }}" method="post"> - <label>username <input id="username" name="username"/></label> - <label>password <input id="password" name="password" type="password"/></label> + <label>username <input id="username" name="username" required/></label> + <label>password <input id="password" name="password" type="password" required/></label> <button type="submit">Register</button> </form> {{ else }} - <p class="error">The registration token you provided is invalid</p> + <span class="error">The registration token you provided is invalid;<br/> obtain a new one.</span> {{end}} </main> </body> +<script src="/table/util.js" type="text/javascript"></script> </html>
M templates/registered.htmltemplates/registered.html

@@ -14,8 +14,9 @@ <h1>Registration Complete</h1>

<p>Success! <a href="/table">Let's game!</a></p> {{ else }} <h1>Error</h1> - <p class="error">Something went wrong; please try a different username or obtain a new registration code.</p> + <span class="error">Something went wrong; please try a different username or obtain a new registration code.</span> {{end}} </main> </body> +<script src="/table/util.js" type="text/javascript"></script> </html>