commit 3eaa4f7595bf7cf97b01d00b68759b5986c32b85
parent 2be9226e157219924d645b5a231e4e919d1f937d
Author: knutsen <samuel@knutsen.co>
Date: Fri, 18 Jun 2021 17:02:43 +0100
Working with Ruby 3.0
Diffstat:
7 files changed, 96 insertions(+), 46 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -4,6 +4,7 @@
# Shh, web stuff
tmp/
log/
+.env*
## System and release files ##
# OS files
diff --git a/Gemfile.lock b/Gemfile.lock
@@ -1,28 +1,30 @@
GEM
remote: https://rubygems.org/
specs:
- bson (4.3.0)
- daemons (1.2.6)
+ bson (4.12.1)
+ daemons (1.4.0)
eventmachine (1.2.7)
- json (2.3.0)
- mongo (2.6.2)
- bson (>= 4.3.0, < 5.0.0)
- mustermann (1.0.3)
- rack (2.1.4)
- rack-protection (2.0.4)
+ json (2.5.1)
+ mongo (2.14.0)
+ bson (>= 4.8.2, < 5.0.0)
+ mustermann (1.1.1)
+ ruby2_keywords (~> 0.0.1)
+ rack (2.2.3)
+ rack-protection (2.1.0)
rack
rack-ssl (1.4.1)
rack
- sinatra (2.0.4)
+ ruby2_keywords (0.0.4)
+ sinatra (2.1.0)
mustermann (~> 1.0)
- rack (~> 2.0)
- rack-protection (= 2.0.4)
+ rack (~> 2.2)
+ rack-protection (= 2.1.0)
tilt (~> 2.0)
- thin (1.7.2)
+ thin (1.8.1)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
- tilt (2.0.8)
+ tilt (2.0.10)
PLATFORMS
ruby
@@ -36,4 +38,4 @@ DEPENDENCIES
thin
BUNDLED WITH
- 2.0.1
+ 2.2.20
diff --git a/public/poll.css b/public/poll.css
@@ -25,6 +25,7 @@ td:first-child {
padding: 0 0 0 10px !important;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
+ border-left: 5px solid var(--fg);
}
td:last-child {
@@ -34,19 +35,19 @@ td:last-child {
tr:not(:first-child) {
border: none;
- background: #f5f5f5;
+ background: rgba(var(--fg-rgb), 0.05);
margin: 0;
padding: 0;
}
tr td:nth-child(2) {
- background: #eeeeee; /* Gradient-ish */
+ background: rgba(var(--fg-rgb), 0.08)
}
tr td:nth-child(3) {
- background: #e1e1e1;
+ background: rgba(var(--fg-rgb), 0.10)
}
tr td:nth-child(4) {
- background: #d7d7d7;
+ background: rgba(var(--fg-rgb), 0.13)
}
.row {
display: block;
diff --git a/public/poller.js b/public/poller.js
@@ -1,9 +1,18 @@
+const getVarCSS = name =>
+ getComputedStyle(document.documentElement)
+ .getPropertyValue(`--${name}`)
+ .trim();
+
+const dp = (number, places = 2) =>
+ Number.parseFloat(number).toFixed(2);
+
+const BASE = getVarCSS('fg-rgb');
+Chart.defaults.global.elements.arc.borderColor = `rgba(${BASE},0.1)`;
+Chart.defaults.global.defaultColor = `rgba(${BASE},0.1)`;
+
const POLL_CODE = window.location.pathname.split('/').slice(-1);
-let has_voted = false;
-const dp = (number, places = 2) => {
- return Number.parseFloat(number).toFixed(2);
-}
+let has_voted = false;
const disable_vote = () => {
has_voted = true;
@@ -12,16 +21,16 @@ const disable_vote = () => {
.val("You've already voted.")
.prop('disabled', true)
.css({
- background: "#eee",
+ opacity: 0.5,
+ color: getVarCSS('fg'),
padding: "0 10px"
});
$('#submit')
.addClass('disabled')
.prop('disabled', true)
.css({
- background: '#eee',
- color: "#888",
- border: "2px solid #aaa"
+ background: getVarCSS('fg'),
+ opacity: 0.7
});
};
@@ -131,7 +140,7 @@ const cast_button = name => {
$('document').ready(() => {
update_votes();
- setInterval(update_votes, 1500); // Live view of votes.
+ //setInterval(update_votes, 6000); // Live view of votes.
$.ajax({
url: POLL_CODE + '/has-voted',
@@ -155,10 +164,11 @@ $('document').ready(() => {
$('#submit').blur();
},
error: e => {
+ console.log(e);
issue(ISSUE.FATAL, `
An error occurred while casting your vote.\n
More Information:\n
- ${e}
+ ${e.responseText}
`);
}
});
diff --git a/public/stats.js b/public/stats.js
@@ -1,4 +1,3 @@
-Chart.defaults.global.elements.arc.borderColor = '#ddd';
const ALPHA_RANGE = {
min: 0.08,
max: 1
@@ -9,7 +8,7 @@ const chart_colors = chart => {
const N = chart.data.datasets[0].data.length;
backgrounds = Array(N);
for (let mono = range.min; mono <= range.max; mono += range.max / (N + 1))
- backgrounds[Math.round((mono - range.min) * N / range.max)] = `rgba(0,0,0,${mono})`;
+ backgrounds[Math.round((mono - range.min) * N / range.max)] = `rgba(${BASE},${mono})`;
chart.data.datasets[0].backgroundColor = backgrounds;
return backgrounds;
};
@@ -66,16 +65,20 @@ $(document).ready(() => {
datasets: [{
label: '№ of Votes',
data: [],
- backgroundColor: [],
+ backgroundColor: `rgba(${BASE}, 0.05)`,
}]
},
options: {
title: {
display: true,
+ color: '#fff',
text: 'Distribution of alternative/other votes.'
},
scales: {
yAxes: [{
+ gridLines: {
+ color: `rgba(${BASE}, 0.1)`,
+ },
categoryPercentage: 0.9,
barPercentage: 1.0,
ticks: {
@@ -84,6 +87,9 @@ $(document).ready(() => {
}
}],
xAxes: [{
+ gridLines: {
+ color: `rgba(${BASE}, 0.1)`,
+ },
ticks: {
stepSize: 1
}
diff --git a/public/styles.css b/public/styles.css
@@ -1,11 +1,33 @@
@import url('https://fonts.googleapis.com/css?family=Rubik:400,400i,500');
+:root {
+ --bg: #fff;
+ --fg: #000;
+ --bg-rgb: 255, 255, 255;
+ --fg-rgb: 000, 000, 000;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --bg: #090909;
+ --fg: #fff;
+ --bg-rgb: 009, 009, 009;
+ --fg-rgb: 255, 255, 255;
+ }
+
+ .github {
+ filter: invert(1);
+ }
+}
+
html, body {
margin: 0;
padding: 0;
font-size: 16px;
min-height: 100vh;
font-family: 'Rubik', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', sans-serif;
+ color: var(--fg);
+ background: var(--bg);
overflow-x: hidden;
}
@@ -45,15 +67,17 @@ ul {
padding: 5px 10px;
margin-top: 20px;
border-radius: 5px;
- background: #fff;
+ background: var(--fg);
+ color: var(--bg);
transition: all .1s ease;
cursor: pointer;
vertical-align: middle;
+ opacity: 0.8;
}
#options li input {
- background: #111;
- color: #eee;
+ background: var(--fg);
+ color: var(--bg);
border-bottom: 2px solid #222;
padding: 0 5px;
margin: 0;
@@ -65,17 +89,17 @@ ul {
}
#options li:nth-of-type(2n) {
- background: #f2f2f2;
+ background: rgba(var(--fg-rgb), 0.8);
}
#options li:hover {
- background: #222;
- color: #fff;
+ opacity: 1;
+ background: var(--fg);
}
.dark-option {
- background: #000 !important;
- color: #fff;
+ background: var(--fg) !important;
+ color: var(--bg);
}
#options li span {
@@ -107,8 +131,8 @@ label {
input[type=submit] {
font-weight: normal;
border-color: #000;
- color: #fff;
- background: #000;
+ color: var(--bg);
+ background: var(--fg);
transition: all .1s ease;
}
@@ -135,6 +159,7 @@ input[type=button], button {
input[type=text] {
background: transparent;
+ color: var(--fg);
font-size: 1em;
padding: 0;
border: none;
@@ -182,7 +207,7 @@ input[type=checkbox]:checked + label:before {
h1, h2, h3, h4, h5, h6 {
font-weight: 500;
- color: #000;
+ color: var(--fg);
}
h3 {
@@ -208,7 +233,7 @@ h3 {
footer {
margin-top: 2em;
- border-top: 1px solid #eee;
+ border-top: 1px solid rgb(var(--fg-rgb), 0.1);
display: flex;
align-items: center;
height: 4em;
@@ -235,10 +260,10 @@ footer span {
.home {
padding: 10px 20px;
cursor: pointer;
- color: #fff;
+ color: var(--bg);
text-transform: uppercase;
font-size: 11px;
- background: #000;
+ background: var(--fg);
border-radius: 4px;
float: right
}
diff --git a/server.rb b/server.rb
@@ -114,7 +114,7 @@ get '/share/:code' do
end
post '/new' do
- params[:code] = URI.decode params[:code]
+ params[:code] = URI.decode_www_form_component params[:code]
return nil if poll_exist? params[:code]
make_poll(
@@ -148,6 +148,11 @@ end
post '/poll/:poll/cast' do
params[:vote].pseudo_dot!
+ if params[:vote].strip.empty?
+ status 406
+ return "Cannot cast empty vote."
+ end
+
return nil if request.ip != '::1' && POLLS.find(:"$and" => [{:code => params[:poll]}, {:voters => request.ip}]).to_a.size > 0
POLLS.update_one({:code => params[:poll]}, {:"$push" => {:voters => request.ip}}) unless request.ip == '::1'