-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvote.js
143 lines (130 loc) · 5.26 KB
/
vote.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Link to the results page. Will be set by the server.
let resultsLink;
window.addEventListener('load', function () {
// We want to display all dates in the user's locale.
replaceDateElements();
document.querySelectorAll("input[type=radio]").forEach(onRadioClick);
loadExistingVote().then(() => {}); // then-clause exists only to avoid warning about unresolved promise.
});
function onRadioClick(radio) {
// When the user enters a vote, the closing confirmation should be enabled.
radio.addEventListener("input", () => {
runOnVersion('6.2', Telegram.WebApp.enableClosingConfirmation);
});
}
/**
* Loads an existing vote from the server and displays it, if it exists.
*/
async function loadExistingVote() {
// If a vote already exists, we want to load it so the user can edit the vote.
const response = await fetch("/poll?" + Telegram.WebApp.initData);
if (!response.ok) {
const text = await response.text();
showAlert("An error occurred while loading your vote: " + text, Telegram.WebApp.close);
return;
}
const data = await response.json();
resultsLink = data["results"];
const vote = data["votes"];
let buttonTitle;
if (vote === null || Object.keys(vote).length === 0) {
buttonTitle = "Confirm vote";
} else {
buttonTitle = "Edit vote";
// We need to display a warning that the user has already voted, along with the option to view the results.
document.getElementById("alreadyVoted").style.display = "block";
document.getElementById("viewResults").addEventListener("click", () => leave(true));
for (const dayElement of document.getElementsByClassName("day-item")) {
const optionsName = "options-" + dayElement.dataset.day;
const selectedOption = dayElement.querySelector(`input[name="${optionsName}"][data-choice="${vote[dayElement.dataset.day]}"]`);
// Should be true due to form validation.
selectedOption.checked = true;
}
}
Telegram.WebApp.MainButton.setText(buttonTitle).show().onClick(confirmVote);
}
/**
* Validates the form. This may display feedback messages to the user.
* @returns {boolean} Whether the form is valid.
*/
function validateForm() {
const voteForm = document.getElementById("voteForm");
if (!voteForm.classList.contains("was-validated")) {
voteForm.classList.add("was-validated");
}
return voteForm.checkValidity();
}
/**
* Validates the form and sends the vote to the server.
*/
function confirmVote() {
if (validateForm()) {
runOnVersion('6.1', () => Telegram.WebApp.HapticFeedback.notificationOccurred("success"));
// Since users can edit their votes, we do not need to ask for confirmation.
saveVote().then(() => {}); // then-clause exists only to avoid warning about unresolved promise.
} else {
runOnVersion('6.1', () => Telegram.WebApp.HapticFeedback.notificationOccurred("error"));
}
}
/**
* Sends the vote to the server, and asks the user whether they want to view the results afterwards.
*/
async function saveVote() {
const days = {};
for (const dayElement of document.getElementsByClassName("day-item")) {
const optionsName = "options-" + dayElement.dataset.day;
const selectedOption = dayElement.querySelector(`input[name="${optionsName}"]:checked`);
// Should be true due to form validation.
console.assert(selectedOption !== null, "No option selected for day " + dayElement.dataset.day);
days[dayElement.dataset.day] = selectedOption.dataset.choice;
}
Telegram.WebApp.MainButton.showProgress();
try {
const response = await fetch("/poll", {
method: "PATCH",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
days: days,
initData: Telegram.WebApp.initData,
})
});
if (!response.ok) {
const text = await response.text();
showAlert("An error occurred while sending your vote: " + text, Telegram.WebApp.close);
} else {
runOnVersion('6.2', () => Telegram.WebApp.showPopup({
title: "Vote sent",
message: "Your vote has been sent. Do you want to view the results now?",
buttons: [
{
id: "viewResults",
text: "View results",
type: "default",
},
{
id: "close",
type: "close",
}
]
}, id => leave(id === "viewResults")), () => leave(true));
}
} catch (e) {
console.error(e);
showAlert("An error occurred while sending your vote: " + e);
} finally {
Telegram.WebApp.MainButton.hideProgress();
}
}
/**
* Leaves the web app. If viewResults is true, the user will be redirected to the results page.
* @param viewResults Whether the user should be redirected to the results page.
*/
function leave(viewResults) {
if (viewResults && resultsLink !== undefined) {
Telegram.WebApp.openTelegramLink(resultsLink);
} else {
Telegram.WebApp.close();
}
}