diff options
Diffstat (limited to 'src/services/note')
| -rw-r--r-- | src/services/note/create.ts | 101 | ||||
| -rw-r--r-- | src/services/note/polls/update.ts | 11 | ||||
| -rw-r--r-- | src/services/note/polls/vote.ts | 16 | ||||
| -rw-r--r-- | src/services/note/reaction/create.ts | 4 | ||||
| -rw-r--r-- | src/services/note/reaction/delete.ts | 2 |
5 files changed, 65 insertions, 69 deletions
diff --git a/src/services/note/create.ts b/src/services/note/create.ts index 6906bc71ce..9c5989696a 100644 --- a/src/services/note/create.ts +++ b/src/services/note/create.ts @@ -10,7 +10,7 @@ import { parse } from '../../mfm/parse'; import { resolveUser } from '../../remote/resolve-user'; import config from '../../config'; import { updateHashtag } from '../update-hashtag'; -import { erase, concat } from '../../prelude/array'; +import { concat } from '../../prelude/array'; import insertNoteUnread from './unread'; import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc'; import extractMentions from '../../misc/extract-mentions'; @@ -27,6 +27,7 @@ import { notesChart, perUserNotesChart, activeUsersChart, instanceChart } from ' import { Poll, IPoll } from '../../models/entities/poll'; import { createNotification } from '../create-notification'; import { isDuplicateKeyValueError } from '../../misc/is-duplicate-key-value-error'; +import { ensure } from '../../prelude/ensure'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -83,25 +84,25 @@ class NotificationManager { } type Option = { - createdAt?: Date; - name?: string; - text?: string; - reply?: Note; - renote?: Note; - files?: DriveFile[]; - geo?: any; - poll?: IPoll; - viaMobile?: boolean; - localOnly?: boolean; - cw?: string; + createdAt?: Date | null; + name?: string | null; + text?: string | null; + reply?: Note | null; + renote?: Note | null; + files?: DriveFile[] | null; + geo?: any | null; + poll?: IPoll | null; + viaMobile?: boolean | null; + localOnly?: boolean | null; + cw?: string | null; visibility?: string; - visibleUsers?: User[]; - apMentions?: User[]; - apHashtags?: string[]; - apEmojis?: string[]; - questionUri?: string; - uri?: string; - app?: App; + visibleUsers?: User[] | null; + apMentions?: User[] | null; + apHashtags?: string[] | null; + apEmojis?: string[] | null; + questionUri?: string | null; + uri?: string | null; + app?: App | null; }; export default async (user: User, data: Option, silent = false) => new Promise<Note>(async (res, rej) => { @@ -117,10 +118,6 @@ export default async (user: User, data: Option, silent = false) => new Promise<N data.visibility = 'home'; } - if (data.visibleUsers) { - data.visibleUsers = erase(null, data.visibleUsers); - } - // Renote対象が「ホームまたは全体」以外の公開範囲ならreject if (data.renote && data.renote.visibility != 'public' && data.renote.visibility != 'home') { return rej('Renote target is not public or home'); @@ -156,10 +153,10 @@ export default async (user: User, data: Option, silent = false) => new Promise<N // Parse MFM if needed if (!tags || !emojis || !mentionedUsers) { - const tokens = data.text ? parse(data.text) : []; - const cwTokens = data.cw ? parse(data.cw) : []; + const tokens = data.text ? parse(data.text)! : []; + const cwTokens = data.cw ? parse(data.cw)! : []; const choiceTokens = data.poll && data.poll.choices - ? concat(data.poll.choices.map(choice => parse(choice))) + ? concat(data.poll.choices.map(choice => parse(choice)!)) : []; const combinedTokens = tokens.concat(cwTokens).concat(choiceTokens); @@ -173,19 +170,21 @@ export default async (user: User, data: Option, silent = false) => new Promise<N tags = tags.filter(tag => tag.length <= 100); - if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply.userId)) { - mentionedUsers.push(await Users.findOne(data.reply.userId)); + if (data.reply && (user.id !== data.reply.userId) && !mentionedUsers.some(u => u.id === data.reply!.userId)) { + mentionedUsers.push(await Users.findOne(data.reply.userId).then(ensure)); } if (data.visibility == 'specified') { + if (data.visibleUsers == null) throw 'invalid param'; + for (const u of data.visibleUsers) { if (!mentionedUsers.some(x => x.id === u.id)) { mentionedUsers.push(u); } } - if (data.reply && !data.visibleUsers.some(x => x.id === data.reply.userId)) { - data.visibleUsers.push(await Users.findOne(data.reply.userId)); + if (data.reply && !data.visibleUsers.some(x => x.id === data.reply!.userId)) { + data.visibleUsers.push(await Users.findOne(data.reply.userId).then(ensure)); } } @@ -215,6 +214,8 @@ export default async (user: User, data: Option, silent = false) => new Promise<N // 未読通知を作成 if (data.visibility == 'specified') { + if (data.visibleUsers == null) throw 'invalid param'; + for (const u of data.visibleUsers) { insertNoteUnread(u, note, true); } @@ -252,7 +253,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N deliverNoteToMentionedRemoteUsers(mentionedUsers, user, noteActivity); } - const profile = await UserProfiles.findOne({ userId: user.id }); + const profile = await UserProfiles.findOne({ userId: user.id }).then(ensure); // If has in reply to note if (data.reply) { @@ -321,18 +322,18 @@ function incRenoteCount(renote: Note) { Notes.increment({ id: renote.id }, 'score', 1); } -async function publish(user: User, note: Note, reply: Note, renote: Note, noteActivity: any) { +async function publish(user: User, note: Note, reply: Note | null | undefined, renote: Note | null | undefined, noteActivity: any) { if (Users.isLocalUser(user)) { // 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送 if (reply && reply.userHost !== null) { - Users.findOne(reply.userId).then(u => { + Users.findOne(reply.userId).then(ensure).then(u => { deliver(user, noteActivity, u.inbox); }); } // 投稿がRenoteかつ投稿者がローカルユーザーかつRenote元の投稿の投稿者がリモートユーザーなら配送 if (renote && renote.userHost !== null) { - Users.findOne(renote.userId).then(u => { + Users.findOne(renote.userId).then(ensure).then(u => { deliver(user, noteActivity, u.inbox); }); } @@ -340,14 +341,14 @@ async function publish(user: User, note: Note, reply: Note, renote: Note, noteAc if (['public', 'home', 'followers'].includes(note.visibility)) { // フォロワーに配信 - publishToFollowers(note, user, noteActivity, reply); + publishToFollowers(note, user, noteActivity); } } async function insertNote(user: User, data: Option, tags: string[], emojis: string[], mentionedUsers: User[]) { const insert = new Note({ - id: genId(data.createdAt), - createdAt: data.createdAt, + id: genId(data.createdAt!), + createdAt: data.createdAt!, fileIds: data.files ? data.files.map(file => file.id) : [], replyId: data.reply ? data.reply.id : null, renoteId: data.renote ? data.renote.id : null, @@ -358,8 +359,8 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri tags: tags.map(tag => tag.toLowerCase()), emojis, userId: user.id, - viaMobile: data.viaMobile, - localOnly: data.localOnly, + viaMobile: data.viaMobile!, + localOnly: data.localOnly!, geo: data.geo || null, appId: data.app ? data.app.id : null, visibility: data.visibility as any, @@ -401,10 +402,10 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri const poll = new Poll({ noteId: note.id, - choices: data.poll.choices, - expiresAt: data.poll.expiresAt, - multiple: data.poll.multiple, - votes: new Array(data.poll.choices.length).fill(0), + choices: data.poll!.choices, + expiresAt: data.poll!.expiresAt, + multiple: data.poll!.multiple, + votes: new Array(data.poll!.choices.length).fill(0), noteVisibility: note.visibility, userId: user.id, userHost: user.host @@ -416,7 +417,7 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri note = await Notes.save(insert); } - return note; + return note!; } catch (e) { // duplicate key error if (isDuplicateKeyValueError(e)) { @@ -434,7 +435,7 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri function index(note: Note) { if (note.text == null || config.elasticsearch == null) return; - es.index({ + es!.index({ index: 'misskey', type: 'note', id: note.id.toString(), @@ -466,7 +467,7 @@ async function notifyToWatchersOfReplyee(reply: Note, user: User, nm: Notificati } } -async function publishToFollowers(note: Note, user: User, noteActivity: any, reply: Note) { +async function publishToFollowers(note: Note, user: User, noteActivity: any) { const followers = await Followings.find({ followeeId: note.userId }); @@ -474,7 +475,7 @@ async function publishToFollowers(note: Note, user: User, noteActivity: any, rep const queue: string[] = []; for (const following of followers) { - if (following.followerHost !== null) { + if (Followings.isRemoteFollower(following)) { // フォロワーがリモートユーザーかつ投稿者がローカルユーザーなら投稿を配信 if (Users.isLocalUser(user)) { const inbox = following.followerSharedInbox || following.followerInbox; @@ -523,11 +524,9 @@ async function extractMentionedUsers(user: User, tokens: ReturnType<typeof parse const mentions = extractMentions(tokens); - let mentionedUsers = await Promise.all(mentions.map(m => + let mentionedUsers = (await Promise.all(mentions.map(m => resolveUser(m.username, m.host || user.host).catch(() => null) - )); - - mentionedUsers = mentionedUsers.filter(x => x != null); + ))).filter(x => x != null) as User[]; // Drop duplicate users mentionedUsers = mentionedUsers.filter((u, i, self) => diff --git a/src/services/note/polls/update.ts b/src/services/note/polls/update.ts index beb35cc278..277ace204d 100644 --- a/src/services/note/polls/update.ts +++ b/src/services/note/polls/update.ts @@ -7,8 +7,10 @@ import { Note } from '../../../models/entities/note'; export async function deliverQuestionUpdate(noteId: Note['id']) { const note = await Notes.findOne(noteId); + if (note == null) throw 'note not found'; const user = await Users.findOne(note.userId); + if (user == null) throw 'note not found'; const followers = await Followings.find({ followeeId: user.id @@ -19,13 +21,8 @@ export async function deliverQuestionUpdate(noteId: Note['id']) { // フォロワーがリモートユーザーかつ投稿者がローカルユーザーならUpdateを配信 if (Users.isLocalUser(user)) { for (const following of followers) { - const follower = { - inbox: following.followerInbox, - sharedInbox: following.followerSharedInbox - }; - - if (following.followerHost !== null) { - const inbox = follower.sharedInbox || follower.inbox; + if (Followings.isRemoteFollower(following)) { + const inbox = following.followerSharedInbox || following.followerInbox; if (!queue.includes(inbox)) queue.push(inbox); } } diff --git a/src/services/note/polls/vote.ts b/src/services/note/polls/vote.ts index 3051ff42d9..3bae617b4f 100644 --- a/src/services/note/polls/vote.ts +++ b/src/services/note/polls/vote.ts @@ -7,11 +7,13 @@ import { Not } from 'typeorm'; import { genId } from '../../../misc/gen-id'; import { createNotification } from '../../create-notification'; -export default (user: User, note: Note, choice: number) => new Promise(async (res, rej) => { +export default async function(user: User, note: Note, choice: number) { const poll = await Polls.findOne({ noteId: note.id }); + if (poll == null) throw 'poll not found'; + // Check whether is valid choice - if (poll.choices[choice] == null) return rej('invalid choice param'); + if (poll.choices[choice] == null) throw new Error('invalid choice param'); // if already voted const exist = await PollVotes.find({ @@ -21,10 +23,10 @@ export default (user: User, note: Note, choice: number) => new Promise(async (re if (poll.multiple) { if (exist.some(x => x.choice === choice)) { - return rej('already voted'); + throw new Error('already voted'); } } else if (exist.length !== 0) { - return rej('already voted'); + throw new Error('already voted'); } // Create vote @@ -36,8 +38,6 @@ export default (user: User, note: Note, choice: number) => new Promise(async (re choice: choice }); - res(); - // 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}'`); @@ -70,7 +70,7 @@ export default (user: User, note: Note, choice: number) => new Promise(async (re const profile = await UserProfiles.findOne({ userId: user.id }); // ローカルユーザーが投票した場合この投稿をWatchする - if (Users.isLocalUser(user) && profile.autoWatch) { + if (Users.isLocalUser(user) && profile!.autoWatch) { watch(user.id, note); } -}); +} diff --git a/src/services/note/reaction/create.ts b/src/services/note/reaction/create.ts index 55f9bcd084..ea2108430a 100644 --- a/src/services/note/reaction/create.ts +++ b/src/services/note/reaction/create.ts @@ -82,7 +82,7 @@ export default async (user: User, note: Note, reaction: string) => { const profile = await UserProfiles.findOne({ userId: user.id }); // ユーザーがローカルユーザーかつ自動ウォッチ設定がオンならばこの投稿をWatchする - if (Users.isLocalUser(user) && profile.autoWatch) { + if (Users.isLocalUser(user) && profile!.autoWatch) { watch(user.id, note); } @@ -91,7 +91,7 @@ export default async (user: User, note: Note, reaction: string) => { if (Users.isLocalUser(user) && note.userHost !== null) { const content = renderActivity(renderLike(user, note, reaction)); Users.findOne(note.userId).then(u => { - deliver(user, content, u.inbox); + deliver(user, content, u!.inbox); }); } //#endregion diff --git a/src/services/note/reaction/delete.ts b/src/services/note/reaction/delete.ts index 76f5ed631e..355e1c5466 100644 --- a/src/services/note/reaction/delete.ts +++ b/src/services/note/reaction/delete.ts @@ -42,7 +42,7 @@ export default async (user: User, note: Note) => { if (Users.isLocalUser(user) && (note.userHost !== null)) { const content = renderActivity(renderUndo(renderLike(user, note, exist.reaction), user)); Users.findOne(note.userId).then(u => { - deliver(user, content, u.inbox); + deliver(user, content, u!.inbox); }); } //#endregion |