Update README.md
[KisSync.git] / src / poll.js
blobaa4d9bac60db8eb51c12ca103698f1d8761f272a
1 const link = /(\w+:\/\/(?:[^:/[\]\s]+|\[[0-9a-f:]+\])(?::\d+)?(?:\/[^/\s]*)*)/ig;
2 const XSS = require('./xss');
4 function sanitizedWithLinksReplaced(text) {
5 return XSS.sanitizeText(text)
6 .replace(link, '<a href="$1" target="_blank" rel="noopener noreferer">$1</a>');
9 class Poll {
10 static create(createdBy, title, choices, options = { hideVotes: false, retainVotes: false }) {
11 let poll = new Poll();
12 poll.createdAt = new Date();
13 poll.createdBy = createdBy;
14 poll.title = sanitizedWithLinksReplaced(title);
15 poll.choices = choices.map(choice => sanitizedWithLinksReplaced(choice));
16 poll.hideVotes = options.hideVotes;
17 poll.retainVotes = options.retainVotes;
18 poll.votes = new Map();
19 return poll;
22 static fromChannelData({ initiator, title, options, _counts, votes, timestamp, obscured, retainVotes }) {
23 let poll = new Poll();
24 if (timestamp === undefined) // Very old polls still in the database lack timestamps
25 timestamp = Date.now();
26 poll.createdAt = new Date(timestamp);
27 poll.createdBy = initiator;
28 poll.title = title;
29 poll.choices = options;
30 poll.votes = new Map();
31 Object.keys(votes).forEach(key => {
32 if (votes[key] !== null)
33 poll.votes.set(key, votes[key]);
34 });
35 poll.hideVotes = obscured;
36 poll.retainVotes = retainVotes || false;
37 return poll;
40 toChannelData() {
41 let counts = new Array(this.choices.length);
42 counts.fill(0);
44 // TODO: it would be desirable one day to move away from using an Object here.
45 // This is just for backwards-compatibility with the existing format.
46 let votes = {};
48 this.votes.forEach((index, key) => {
49 votes[key] = index;
50 counts[index]++;
51 });
53 return {
54 title: this.title,
55 initiator: this.createdBy,
56 options: this.choices,
57 counts,
58 votes,
59 obscured: this.hideVotes,
60 retainVotes: this.retainVotes,
61 timestamp: this.createdAt.getTime()
65 countVote(key, choiceId) {
66 if (choiceId < 0 || choiceId >= this.choices.length)
67 return false;
69 let changed = !this.votes.has(key) || this.votes.get(key) !== choiceId;
70 this.votes.set(key, choiceId);
71 return changed;
74 uncountVote(key) {
75 let changed = this.votes.has(key);
76 this.votes.delete(key);
77 return changed;
80 toUpdateFrame(showHiddenVotes) {
81 let counts = new Array(this.choices.length);
82 counts.fill(0);
84 this.votes.forEach(index => counts[index]++);
86 if (this.hideVotes) {
87 counts = counts.map(c => {
88 if (showHiddenVotes) return `${c}?`;
89 else return '?';
90 });
93 return {
94 title: this.title,
95 options: this.choices,
96 counts: counts,
97 initiator: this.createdBy,
98 timestamp: this.createdAt.getTime()
103 exports.Poll = Poll;