summaryrefslogtreecommitdiff
path: root/src/server/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api')
-rw-r--r--src/server/api/common/generate-muted-note-thread-query.ts17
-rw-r--r--src/server/api/endpoints/notes/mentions.ts2
-rw-r--r--src/server/api/endpoints/notes/state.ts28
-rw-r--r--src/server/api/endpoints/notes/thread-muting/create.ts54
-rw-r--r--src/server/api/endpoints/notes/thread-muting/delete.ts40
5 files changed, 134 insertions, 7 deletions
diff --git a/src/server/api/common/generate-muted-note-thread-query.ts b/src/server/api/common/generate-muted-note-thread-query.ts
new file mode 100644
index 0000000000..7e2cbd498b
--- /dev/null
+++ b/src/server/api/common/generate-muted-note-thread-query.ts
@@ -0,0 +1,17 @@
+import { User } from '@/models/entities/user';
+import { NoteThreadMutings } from '@/models/index';
+import { Brackets, SelectQueryBuilder } from 'typeorm';
+
+export function generateMutedNoteThreadQuery(q: SelectQueryBuilder<any>, me: { id: User['id'] }) {
+ const mutedQuery = NoteThreadMutings.createQueryBuilder('threadMuted')
+ .select('threadMuted.threadId')
+ .where('threadMuted.userId = :userId', { userId: me.id });
+
+ q.andWhere(`note.id NOT IN (${ mutedQuery.getQuery() })`);
+ q.andWhere(new Brackets(qb => { qb
+ .where(`note.threadId IS NULL`)
+ .orWhere(`note.threadId NOT IN (${ mutedQuery.getQuery() })`);
+ }));
+
+ q.setParameters(mutedQuery.getParameters());
+}
diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts
index 74f7911bfe..ffaebd6c95 100644
--- a/src/server/api/endpoints/notes/mentions.ts
+++ b/src/server/api/endpoints/notes/mentions.ts
@@ -8,6 +8,7 @@ import { generateMutedUserQuery } from '../../common/generate-muted-user-query';
import { makePaginationQuery } from '../../common/make-pagination-query';
import { Brackets } from 'typeorm';
import { generateBlockedUserQuery } from '../../common/generate-block-query';
+import { generateMutedNoteThreadQuery } from '../../common/generate-muted-note-thread-query';
export const meta = {
tags: ['notes'],
@@ -67,6 +68,7 @@ export default define(meta, async (ps, user) => {
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
+ generateMutedNoteThreadQuery(query, user);
generateBlockedUserQuery(query, user);
if (ps.visibility) {
diff --git a/src/server/api/endpoints/notes/state.ts b/src/server/api/endpoints/notes/state.ts
index 489902435d..b3913a5e79 100644
--- a/src/server/api/endpoints/notes/state.ts
+++ b/src/server/api/endpoints/notes/state.ts
@@ -1,7 +1,7 @@
import $ from 'cafy';
import { ID } from '@/misc/cafy-id';
import define from '../../define';
-import { NoteFavorites, NoteWatchings } from '@/models/index';
+import { NoteFavorites, Notes, NoteThreadMutings, NoteWatchings } from '@/models/index';
export const meta = {
tags: ['notes'],
@@ -25,31 +25,45 @@ export const meta = {
isWatching: {
type: 'boolean' as const,
optional: false as const, nullable: false as const
- }
+ },
+ isMutedThread: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const
+ },
}
}
};
export default define(meta, async (ps, user) => {
- const [favorite, watching] = await Promise.all([
+ const note = await Notes.findOneOrFail(ps.noteId);
+
+ const [favorite, watching, threadMuting] = await Promise.all([
NoteFavorites.count({
where: {
userId: user.id,
- noteId: ps.noteId
+ noteId: note.id,
},
take: 1
}),
NoteWatchings.count({
where: {
userId: user.id,
- noteId: ps.noteId
+ noteId: note.id,
},
take: 1
- })
+ }),
+ NoteThreadMutings.count({
+ where: {
+ userId: user.id,
+ threadId: note.threadId || note.id,
+ },
+ take: 1
+ }),
]);
return {
isFavorited: favorite !== 0,
- isWatching: watching !== 0
+ isWatching: watching !== 0,
+ isMutedThread: threadMuting !== 0,
};
});
diff --git a/src/server/api/endpoints/notes/thread-muting/create.ts b/src/server/api/endpoints/notes/thread-muting/create.ts
new file mode 100644
index 0000000000..2010d54331
--- /dev/null
+++ b/src/server/api/endpoints/notes/thread-muting/create.ts
@@ -0,0 +1,54 @@
+import $ from 'cafy';
+import { ID } from '@/misc/cafy-id';
+import define from '../../../define';
+import { getNote } from '../../../common/getters';
+import { ApiError } from '../../../error';
+import { Notes, NoteThreadMutings } from '@/models';
+import { genId } from '@/misc/gen-id';
+import readNote from '@/services/note/read';
+
+export const meta = {
+ tags: ['notes'],
+
+ requireCredential: true as const,
+
+ kind: 'write:account',
+
+ params: {
+ noteId: {
+ validator: $.type(ID),
+ }
+ },
+
+ errors: {
+ noSuchNote: {
+ message: 'No such note.',
+ code: 'NO_SUCH_NOTE',
+ id: '5ff67ada-ed3b-2e71-8e87-a1a421e177d2'
+ }
+ }
+};
+
+export default define(meta, async (ps, user) => {
+ const note = await getNote(ps.noteId).catch(e => {
+ if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
+ throw e;
+ });
+
+ const mutedNotes = await Notes.find({
+ where: [{
+ id: note.threadId || note.id,
+ }, {
+ threadId: note.threadId || note.id,
+ }],
+ });
+
+ await readNote(user.id, mutedNotes);
+
+ await NoteThreadMutings.insert({
+ id: genId(),
+ createdAt: new Date(),
+ threadId: note.threadId || note.id,
+ userId: user.id,
+ });
+});
diff --git a/src/server/api/endpoints/notes/thread-muting/delete.ts b/src/server/api/endpoints/notes/thread-muting/delete.ts
new file mode 100644
index 0000000000..05d5691870
--- /dev/null
+++ b/src/server/api/endpoints/notes/thread-muting/delete.ts
@@ -0,0 +1,40 @@
+import $ from 'cafy';
+import { ID } from '@/misc/cafy-id';
+import define from '../../../define';
+import { getNote } from '../../../common/getters';
+import { ApiError } from '../../../error';
+import { NoteThreadMutings } from '@/models';
+
+export const meta = {
+ tags: ['notes'],
+
+ requireCredential: true as const,
+
+ kind: 'write:account',
+
+ params: {
+ noteId: {
+ validator: $.type(ID),
+ }
+ },
+
+ errors: {
+ noSuchNote: {
+ message: 'No such note.',
+ code: 'NO_SUCH_NOTE',
+ id: 'bddd57ac-ceb3-b29d-4334-86ea5fae481a'
+ }
+ }
+};
+
+export default define(meta, async (ps, user) => {
+ const note = await getNote(ps.noteId).catch(e => {
+ if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
+ throw e;
+ });
+
+ await NoteThreadMutings.delete({
+ threadId: note.threadId || note.id,
+ userId: user.id,
+ });
+});