2021-12-30 20:22:48 +00:00
|
|
|
import { ArrayOverlap, Not } from 'typeorm';
|
2022-02-27 02:07:39 +00:00
|
|
|
import { publishNoteStream } from '@/services/stream.js';
|
2022-07-12 12:41:10 +00:00
|
|
|
import { CacheableUser } from '@/models/entities/user.js';
|
2022-02-27 02:07:39 +00:00
|
|
|
import { Note } from '@/models/entities/note.js';
|
2021-12-30 20:22:48 +00:00
|
|
|
import { PollVotes, NoteWatchings, Polls, Blockings, NoteThreadMutings } from '@/models/index.js';
|
2022-02-27 02:07:39 +00:00
|
|
|
import { genId } from '@/misc/gen-id.js';
|
|
|
|
import { createNotification } from '../../create-notification.js';
|
2019-01-21 04:27:19 +00:00
|
|
|
|
2022-03-25 07:27:41 +00:00
|
|
|
export default async function(user: CacheableUser, note: Note, choice: number) {
|
2022-03-26 06:34:00 +00:00
|
|
|
const poll = await Polls.findOneBy({ noteId: note.id });
|
2019-04-07 12:50:36 +00:00
|
|
|
|
2019-04-13 19:17:24 +00:00
|
|
|
if (poll == null) throw new Error('poll not found');
|
2019-04-12 16:43:22 +00:00
|
|
|
|
2019-04-07 12:50:36 +00:00
|
|
|
// Check whether is valid choice
|
2019-04-12 16:43:22 +00:00
|
|
|
if (poll.choices[choice] == null) throw new Error('invalid choice param');
|
2019-01-21 04:27:19 +00:00
|
|
|
|
2021-08-17 12:48:59 +00:00
|
|
|
// Check blocking
|
|
|
|
if (note.userId !== user.id) {
|
2022-03-26 06:34:00 +00:00
|
|
|
const block = await Blockings.findOneBy({
|
2021-08-17 12:48:59 +00:00
|
|
|
blockerId: note.userId,
|
|
|
|
blockeeId: user.id,
|
|
|
|
});
|
|
|
|
if (block) {
|
|
|
|
throw new Error('blocked');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-21 04:27:19 +00:00
|
|
|
// if already voted
|
2022-03-26 06:34:00 +00:00
|
|
|
const exist = await PollVotes.findBy({
|
2019-04-07 12:50:36 +00:00
|
|
|
noteId: note.id,
|
2021-12-09 14:58:30 +00:00
|
|
|
userId: user.id,
|
2019-01-21 04:27:19 +00:00
|
|
|
});
|
|
|
|
|
2019-04-07 12:50:36 +00:00
|
|
|
if (poll.multiple) {
|
|
|
|
if (exist.some(x => x.choice === choice)) {
|
2019-04-12 16:43:22 +00:00
|
|
|
throw new Error('already voted');
|
2019-04-07 12:50:36 +00:00
|
|
|
}
|
|
|
|
} else if (exist.length !== 0) {
|
2019-04-12 16:43:22 +00:00
|
|
|
throw new Error('already voted');
|
2019-01-21 04:27:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create vote
|
2021-03-21 12:27:09 +00:00
|
|
|
await PollVotes.insert({
|
2019-04-07 12:50:36 +00:00
|
|
|
id: genId(),
|
2019-01-21 04:27:19 +00:00
|
|
|
createdAt: new Date(),
|
2019-04-07 12:50:36 +00:00
|
|
|
noteId: note.id,
|
|
|
|
userId: user.id,
|
2022-08-03 12:49:55 +00:00
|
|
|
choice,
|
2019-01-21 04:27:19 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Increment votes count
|
2019-04-07 12:50:36 +00:00
|
|
|
const index = choice + 1; // In SQL, array index is 1 based
|
2019-04-13 10:08:41 +00:00
|
|
|
await Polls.query(`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`);
|
2019-01-21 04:27:19 +00:00
|
|
|
|
2019-04-07 12:50:36 +00:00
|
|
|
publishNoteStream(note.id, 'pollVoted', {
|
2022-08-03 12:49:55 +00:00
|
|
|
choice,
|
2021-12-09 14:58:30 +00:00
|
|
|
userId: user.id,
|
2019-01-21 04:27:19 +00:00
|
|
|
});
|
|
|
|
|
2021-12-30 20:22:48 +00:00
|
|
|
// check if this thread and notification type is muted
|
|
|
|
const muted = await NoteThreadMutings.findOne({
|
|
|
|
userId: note.userId,
|
|
|
|
threadId: note.threadId || note.id,
|
|
|
|
mutingNotificationTypes: ArrayOverlap(['pollVote']),
|
2019-01-21 04:27:19 +00:00
|
|
|
});
|
2021-12-30 20:22:48 +00:00
|
|
|
// Notify
|
|
|
|
if (!muted) {
|
|
|
|
createNotification(note.userId, 'pollVote', {
|
|
|
|
notifierId: user.id,
|
|
|
|
noteId: note.id,
|
|
|
|
choice: choice,
|
|
|
|
});
|
|
|
|
}
|
2019-01-21 04:27:19 +00:00
|
|
|
|
|
|
|
// Fetch watchers
|
2022-03-26 06:34:00 +00:00
|
|
|
NoteWatchings.findBy({
|
2019-04-07 12:50:36 +00:00
|
|
|
noteId: note.id,
|
|
|
|
userId: Not(user.id),
|
|
|
|
})
|
|
|
|
.then(watchers => {
|
|
|
|
for (const watcher of watchers) {
|
2020-03-28 09:07:41 +00:00
|
|
|
createNotification(watcher.userId, 'pollVote', {
|
|
|
|
notifierId: user.id,
|
2019-04-07 12:50:36 +00:00
|
|
|
noteId: note.id,
|
2022-08-03 12:49:55 +00:00
|
|
|
choice,
|
2019-04-07 12:50:36 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2019-04-12 16:43:22 +00:00
|
|
|
}
|