import { publishNoteStream } from "../../stream.js"; import { PollVotes, NoteWatchings, Polls, Blockings } from "../../../models/index.js"; import { Not } from "typeorm"; import { genId } from "../../../misc/gen-id.js"; import { createNotification } from "../../create-notification.js"; export default async function(user, note, choice) { const poll = await Polls.findOneBy({ noteId: note.id }); if (poll == null) throw new Error("poll not found"); // Check whether is valid choice if (poll.choices[choice] == null) throw new Error("invalid choice param"); // Check blocking if (note.userId !== user.id) { const blocked = await Blockings.exist({ where: [ { blockerId: note.userId, blockeeId: user.id, groupId: null }, ...note.groupId ? [ { groupId: note.groupId, blockeeId: user.id } ] : [] ] }); if (blocked) { throw new Error("blocked"); } } // if already voted const exist = await PollVotes.findBy({ noteId: note.id, userId: user.id }); if (poll.multiple) { if (exist.some((x)=>x.choice === choice)) { throw new Error("already voted"); } } else if (exist.length !== 0) { throw new Error("already voted"); } // Create vote await PollVotes.insert({ id: genId(), createdAt: new Date(), noteId: note.id, userId: user.id, choice: choice }); // Increment votes count const index = choice + 1; // In SQL, array index is 1 based await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`); publishNoteStream(note.id, "pollVoted", { choice: choice, userId: user.id }); // Notify createNotification(note.userId, "pollVote", { notifierId: user.id, note: note, noteId: note.id, choice: choice }); // Fetch watchers NoteWatchings.findBy({ noteId: note.id, userId: Not(user.id) }).then((watchers)=>{ for (const watcher of watchers){ createNotification(watcher.userId, "pollVote", { notifierId: user.id, note: note, noteId: note.id, choice: choice }); } }); }