mirror of
https://github.com/Wolvan/poll.horse.git
synced 2024-11-21 20:47:59 +01:00
Implement auto update
Every 5 seconds the system attempts to fetch the most recent vote state of the poll and display it to the user.
This commit is contained in:
parent
dca2cc3eeb
commit
e9aaedb494
5 changed files with 42 additions and 3 deletions
|
@ -9,6 +9,8 @@
|
|||
"MAX_POLL_OPTIONS": "readonly",
|
||||
"MAX_CHARACTER_LENGTH": "readonly",
|
||||
"POLL_VOTE_DATA_STRING": "readonly",
|
||||
"POLL_BACKEND_URL": "readonly",
|
||||
"POLL_ID": "readonly",
|
||||
|
||||
"textFit": "readonly",
|
||||
"google": "readonly"
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" defer="true"></script>
|
||||
<script type="text/javascript">
|
||||
const POLL_VOTE_DATA_STRING = `{{ POLL_OPTION_VOTES }}`;
|
||||
const POLL_BACKEND_URL = "{{ BACKEND_BASE_PATH }}";
|
||||
const POLL_ID = "{{ POLL_ID }}";
|
||||
</script>
|
||||
<script type="text/javascript" src="/static/js/result.js" defer="true"></script>
|
||||
</head>
|
||||
|
|
|
@ -41,7 +41,7 @@ main .notepad .poll-option .progress .poll-bar {
|
|||
vertical-align: top;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
width: calc(100% - 60px);
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
main .notepad .poll-option .progress .poll-bar .poll-bar-fill {
|
||||
height: calc(100% - 5px);
|
||||
|
@ -51,6 +51,10 @@ main .notepad .poll-option .progress .poll-bar .poll-bar-fill {
|
|||
}
|
||||
main .notepad .poll-option .progress .poll-bar-text {
|
||||
width: 50px;
|
||||
}
|
||||
main .notepad .poll-option .progress .poll-bar-text::after {
|
||||
content: "%";
|
||||
margin-left: 5px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
|
@ -60,6 +64,7 @@ aside#chart {
|
|||
right: -200px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const POLL_REFRESH_INTERVAL = 5000;
|
||||
|
||||
const textFitOptions = {
|
||||
multiLine: true
|
||||
};
|
||||
|
@ -42,6 +44,33 @@ function domLoaded() {
|
|||
textFit(document.querySelector(".poll-title"), textFitOptions);
|
||||
document.querySelectorAll(".poll-option .poll-option-text").forEach(element => textFit(element, textFitOptions));
|
||||
});
|
||||
|
||||
let prevResult = null;
|
||||
async function fetchNewestResults() {
|
||||
try {
|
||||
const response = await fetch(POLL_BACKEND_URL + "/_backend/poll-result/" + POLL_ID);
|
||||
const json = await response.json();
|
||||
if (json.error) throw new Error(json.error);
|
||||
const votes = json.votes;
|
||||
const totalVotes = Object.values(votes).reduce((a, b) => a + b, 0);
|
||||
if (!prevResult || Object.entries(votes).some(([key, value]) => value !== prevResult[key])) {
|
||||
drawChart(Object.entries(votes));
|
||||
Object.entries(votes).forEach(([key, value]) => {
|
||||
const el = document.querySelector("main .notepad .poll-option[option='" + key + "']");
|
||||
if (!el) return;
|
||||
|
||||
el.querySelector(".poll-option-votes").innerText = value;
|
||||
el.querySelector(".poll-bar-fill").style.width = (value / totalVotes * 100) + "%";
|
||||
el.querySelector(".poll-bar-text").innerText = Math.round(value / totalVotes * 100);
|
||||
});
|
||||
prevResult = votes;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
setTimeout(fetchNewestResults, POLL_REFRESH_INTERVAL);
|
||||
}
|
||||
setTimeout(fetchNewestResults, POLL_REFRESH_INTERVAL);
|
||||
}
|
||||
|
||||
if (document.readyState === "complete" || document.readyState === "loaded") domLoaded();
|
||||
|
|
|
@ -106,14 +106,14 @@ export default function init(router: Router): void {
|
|||
if (!poll || poll.error) return res.redirect("/");
|
||||
const totalVotes = Object.values(poll.votes).reduce((acc, cur) => acc + cur, 0);
|
||||
const pollOptionsDivs = Object.entries(poll.votes).map(([option, votes]) => `
|
||||
<div class="poll-option">
|
||||
<div class="poll-option" option="${ option }">
|
||||
<div class="poll-option-info">
|
||||
<div class="poll-option-text">${ option }</div><div class="poll-option-votes">${ votes }</div>
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="poll-bar">
|
||||
<div class="poll-bar-fill" style="width: ${ (votes / totalVotes) * 100 }%"></div>
|
||||
</div><div class="poll-bar-text">${ Math.round((votes / totalVotes) * 100) }%</div>
|
||||
</div><div class="poll-bar-text">${ Math.round((votes / totalVotes) * 100) }</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join("");
|
||||
|
@ -123,6 +123,7 @@ export default function init(router: Router): void {
|
|||
"POLL_TITLE": poll.title,
|
||||
"POLL_OPTION_DIVS": pollOptionsDivs,
|
||||
"POLL_VOTES_TOTAL": totalVotes,
|
||||
"BACKEND_BASE_PATH": (program.opts().backendBaseUrl || ""),
|
||||
"POLL_OPTION_VOTES": JSON.stringify(Object.entries(poll.votes))
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
Loading…
Reference in a new issue