|
// retoor <retoor@molodetz.nl>
|
|
|
|
import { OptimisticAction } from "./OptimisticAction.js";
|
|
|
|
export class VoteManager extends OptimisticAction {
|
|
constructor() {
|
|
super();
|
|
this.initVoteButtons();
|
|
}
|
|
|
|
initVoteButtons() {
|
|
document.querySelectorAll('form[action^="/votes/"] button[type="submit"]').forEach((button) => {
|
|
const form = button.closest("form");
|
|
button.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
this.cast(form, button);
|
|
});
|
|
});
|
|
}
|
|
|
|
cast(form, button) {
|
|
const action = form.getAttribute("action");
|
|
const clickedValue = parseInt(form.querySelector('input[name="value"]').value, 10);
|
|
const targetUid = action.split("/").pop();
|
|
const prevValue = this.currentValue(action);
|
|
const prevNet = this.currentNet(targetUid);
|
|
const newValue = prevValue === clickedValue ? 0 : clickedValue;
|
|
const predictedNet = prevNet + (newValue - prevValue);
|
|
return this.submitOptimistic(
|
|
action,
|
|
{ value: clickedValue },
|
|
button,
|
|
() => this.render(action, { net: predictedNet, value: newValue }),
|
|
() => this.render(action, { net: prevNet, value: prevValue }),
|
|
(result) => this.render(action, result),
|
|
);
|
|
}
|
|
|
|
currentValue(action) {
|
|
const voted = document.querySelector(`form[action="${action}"] button.voted`);
|
|
if (!voted) return 0;
|
|
return parseInt(voted.closest("form").querySelector('input[name="value"]').value, 10);
|
|
}
|
|
|
|
currentNet(targetUid) {
|
|
const counter = document.querySelector(`[data-vote-count="${targetUid}"]`);
|
|
if (!counter) return 0;
|
|
const parsed = parseInt(counter.textContent, 10);
|
|
return Number.isNaN(parsed) ? 0 : parsed;
|
|
}
|
|
|
|
render(action, result) {
|
|
const targetUid = action.split("/").pop();
|
|
document.querySelectorAll(`[data-vote-count="${targetUid}"]`).forEach((counter) => {
|
|
counter.textContent = result.net;
|
|
});
|
|
document.querySelectorAll(`form[action="${action}"] button[type="submit"]`).forEach((button) => {
|
|
const formValue = parseInt(button.closest("form").querySelector('input[name="value"]').value, 10);
|
|
button.classList.toggle("voted", result.value !== 0 && formValue === result.value);
|
|
});
|
|
}
|
|
}
|