diff --git a/src/client/components/note.vue b/src/client/components/note.vue index 6e513a4b2..1136781ca 100644 --- a/src/client/components/note.vue +++ b/src/client/components/note.vue @@ -278,6 +278,9 @@ export default Vue.extend({ (this as any).$root.api('promo/read', { noteId: this.appearNote.id }); + this.$root.stream.send('readNotification', { + id: notification.id + }); this.hideThisNote = true; }, diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue index cdb61f51d..3be09b4ae 100644 --- a/src/client/components/post-form.vue +++ b/src/client/components/post-form.vue @@ -67,6 +67,7 @@ import extractMentions from '../../misc/extract-mentions'; import getAcct from '../../misc/acct/render'; import { formatTimeString } from '../../misc/format-time-string'; import { selectDriveFile } from '../scripts/select-drive-file'; +import { noteVisibilities } from '../../types' export default Vue.extend({ components: { @@ -405,7 +406,7 @@ export default Vue.extend({ }, applyVisibility(v: string) { - this.visibility = ['public', 'home', 'followers', 'specified'].includes(v) ? v : 'public'; // v11互換性のため + this.visibility = (noteVisibilities as unknown as string[]).includes(v) ? v : 'public'; // v11互換性のため }, addVisibleUser() { diff --git a/src/models/entities/note.ts b/src/models/entities/note.ts index 79b6b5ab7..196be1e35 100644 --- a/src/models/entities/note.ts +++ b/src/models/entities/note.ts @@ -2,6 +2,8 @@ import { Entity, Index, JoinColumn, Column, PrimaryColumn, ManyToOne } from 'typ import { User } from './user'; import { DriveFile } from './drive-file'; import { id } from '../id'; +import { noteVisibilities } from '../../types'; + @Entity() @Index('IDX_NOTE_TAGS', { synchronize: false }) @@ -102,8 +104,8 @@ export class Note { * followers ... フォロワーのみ * specified ... visibleUserIds で指定したユーザーのみ */ - @Column('enum', { enum: ['public', 'home', 'followers', 'specified'] }) - public visibility: 'public' | 'home' | 'followers' | 'specified'; + @Column('enum', { enum: noteVisibilities }) + public visibility: typeof noteVisibilities[number]; @Index({ unique: true }) @Column('varchar', { diff --git a/src/models/entities/notification.ts b/src/models/entities/notification.ts index 565645a5d..988fdb341 100644 --- a/src/models/entities/notification.ts +++ b/src/models/entities/notification.ts @@ -5,6 +5,7 @@ import { Note } from './note'; import { FollowRequest } from './follow-request'; import { UserGroupInvitation } from './user-group-invitation'; import { AccessToken } from './access-token'; +import { notificationTypes } from '../../types'; @Entity() export class Notification { @@ -66,10 +67,10 @@ export class Notification { */ @Index() @Column('enum', { - enum: ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app'], + enum: notificationTypes, comment: 'The type of the Notification.' }) - public type: 'follow' | 'mention' | 'reply' | 'renote' | 'quote' | 'reaction' | 'pollVote' | 'receiveFollowRequest' | 'followRequestAccepted' | 'groupInvited' | 'app'; + public type: typeof notificationTypes[number]; /** * 通知が読まれたかどうか diff --git a/src/models/entities/poll.ts b/src/models/entities/poll.ts index 6bb67163a..e3bbb1c3f 100644 --- a/src/models/entities/poll.ts +++ b/src/models/entities/poll.ts @@ -2,6 +2,7 @@ import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'type import { id } from '../id'; import { Note } from './note'; import { User } from './user'; +import { noteVisibilities } from '../../types'; @Entity() export class Poll { @@ -34,10 +35,10 @@ export class Poll { //#region Denormalized fields @Column('enum', { - enum: ['public', 'home', 'followers', 'specified'], + enum: noteVisibilities, comment: '[Denormalized]' }) - public noteVisibility: 'public' | 'home' | 'followers' | 'specified'; + public noteVisibility: typeof noteVisibilities[number]; @Index() @Column({ diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts index b484c43c5..40f43d6c1 100644 --- a/src/models/repositories/notification.ts +++ b/src/models/repositories/notification.ts @@ -19,6 +19,7 @@ export class NotificationRepository extends Repository { id: notification.id, createdAt: notification.createdAt.toISOString(), type: notification.type, + isRead: notification.isRead, userId: notification.notifierId, user: notification.notifierId ? Users.pack(notification.notifier || notification.notifierId) : null, ...(notification.type === 'mention' ? { diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts index 9a2e17a71..db6772beb 100644 --- a/src/server/api/endpoints/i/notifications.ts +++ b/src/server/api/endpoints/i/notifications.ts @@ -4,6 +4,7 @@ import { readNotification } from '../../common/read-notification'; import define from '../../define'; import { makePaginationQuery } from '../../common/make-pagination-query'; import { Notifications, Followings, Mutings, Users } from '../../../../models'; +import { notificationTypes } from '../../../../types'; export const meta = { desc: { @@ -42,12 +43,12 @@ export const meta = { }, includeTypes: { - validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted'])), + validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])), default: [] as string[] }, excludeTypes: { - validator: $.optional.arr($.str.or(['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted'])), + validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])), default: [] as string[] } }, diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts index cccf138ad..5076dad82 100644 --- a/src/server/api/endpoints/notes/create.ts +++ b/src/server/api/endpoints/notes/create.ts @@ -11,6 +11,7 @@ import { Users, DriveFiles, Notes } from '../../../../models'; import { DriveFile } from '../../../../models/entities/drive-file'; import { Note } from '../../../../models/entities/note'; import { DB_MAX_NOTE_TEXT_LENGTH } from '../../../../misc/hard-limits'; +import { noteVisibilities } from '../../../../types'; let maxNoteTextLength = 500; @@ -38,7 +39,7 @@ export const meta = { params: { visibility: { - validator: $.optional.str.or(['public', 'home', 'followers', 'specified']), + validator: $.optional.str.or(noteVisibilities as unknown as string[]), default: 'public', desc: { 'ja-JP': '投稿の公開範囲' diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 000000000..30a62412a --- /dev/null +++ b/src/types.ts @@ -0,0 +1,3 @@ +export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'app'] as const; + +export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;