diff --git a/CHANGELOG.md b/CHANGELOG.md index 330ad97c6..2521396b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ You should also include the user name that made the change. --> +## 13.7.3 (2023/02/23) + +### Note +13.7.0以前から直接このバージョンにアップデートする場合は全ての通知が削除**されません。** + +### Improvements + +### Bugfixes +- Client: 「キャッシュを削除」した後、ローカルのカスタム絵文字が表示されなくなるされなくなる問題を修正 +- Client: 通知設定画面で以前からグループの招待を有効化していた場合、通知の表示に失敗する問題の修正 +- Client: 通知設定画面に古いトグルが残っていた問題を修正 + ## 13.7.2 (2023/02/23) ### Note diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 48d8a40de..a8322d7b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,7 +83,7 @@ An actual domain will be assigned so you can test the federation. - The title must be in the format `Release: x.y.z`. - `x.y.z` is the new version you are trying to release. 3. Deploy and perform a simple QA check. Also verify that the tests passed. -4. Merge it. +4. Merge it. (Do not squash commit) 5. Create a [release of GitHub](https://github.com/misskey-dev/misskey/releases) - The target branch must be `master` - The tag name must be the version @@ -278,9 +278,10 @@ SQLでは配列のインデックスは**1始まり**。 ### null IN nullが含まれる可能性のあるカラムにINするときは、そのままだとおかしくなるのでORなどでnullのハンドリングをしよう。 -### `undefined`にご用心 -MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。 -MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください +### enumの削除は気をつける +enumの列挙の内容の削除は、その値をもつレコードを全て削除しないといけない + +削除が重たかったり不可能だったりする場合は、削除しないでおく ### Migration作成方法 packages/backendで: diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 3faab4500..5ba5f6476 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1846,6 +1846,7 @@ _notification: pollEnded: "アンケートが終了" receiveFollowRequest: "フォロー申請を受け取った" followRequestAccepted: "フォローが受理された" + achievementEarned: "実績の獲得" app: "連携アプリからの通知" _actions: diff --git a/package.json b/package.json index b0501eb02..ad6f0f71d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "13.7.2", + "version": "13.7.3", "codename": "nasubi", "repository": { "type": "git", diff --git a/packages/backend/migration/1676434944993-drop-group.js b/packages/backend/migration/1676434944993-drop-group.js index df4a3b683..0f2966433 100644 --- a/packages/backend/migration/1676434944993-drop-group.js +++ b/packages/backend/migration/1676434944993-drop-group.js @@ -11,19 +11,11 @@ export class dropGroup1676434944993 { await queryRunner.query(`CREATE TYPE "public"."antenna_src_enum" AS ENUM('home', 'all', 'users', 'list')`); await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "public"."antenna_src_enum" USING "src"::"text"::"public"."antenna_src_enum"`); await queryRunner.query(`DROP TYPE "public"."antenna_src_enum_old"`); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`); - await queryRunner.query(`CREATE TYPE "public"."notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app')`); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum" USING "type"::"text"::"public"."notification_type_enum"`); - await queryRunner.query(`DROP TYPE "public"."notification_type_enum_old"`); await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes" SET DEFAULT '["follow","receiveFollowRequest"]'`); } async down(queryRunner) { await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes" SET DEFAULT '["follow", "receiveFollowRequest", "groupInvited"]'`); - await queryRunner.query(`CREATE TYPE "public"."notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'achievementEarned', 'app')`); - await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum_old" USING "type"::"text"::"public"."notification_type_enum_old"`); - await queryRunner.query(`DROP TYPE "public"."notification_type_enum"`); - await queryRunner.query(`ALTER TYPE "public"."notification_type_enum_old" RENAME TO "notification_type_enum"`); await queryRunner.query(`CREATE TYPE "public"."antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list', 'group')`); await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "public"."antenna_src_enum_old" USING "src"::"text"::"public"."antenna_src_enum_old"`); await queryRunner.query(`DROP TYPE "public"."antenna_src_enum"`); diff --git a/packages/backend/src/core/entities/NotificationEntityService.ts b/packages/backend/src/core/entities/NotificationEntityService.ts index 34ff52ede..33c76c693 100644 --- a/packages/backend/src/core/entities/NotificationEntityService.ts +++ b/packages/backend/src/core/entities/NotificationEntityService.ts @@ -94,13 +94,6 @@ export class NotificationEntityService implements OnModuleInit { }), reaction: notification.reaction, } : {}), - ...(notification.type === 'pollVote' ? { // TODO: そのうち消す - note: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, { - detail: true, - _hint_: options._hintForEachNotes_, - }), - choice: notification.choice, - } : {}), ...(notification.type === 'pollEnded' ? { note: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, { detail: true, diff --git a/packages/backend/src/models/entities/Notification.ts b/packages/backend/src/models/entities/Notification.ts index 105f0d040..51117efba 100644 --- a/packages/backend/src/models/entities/Notification.ts +++ b/packages/backend/src/models/entities/Notification.ts @@ -1,5 +1,5 @@ import { Entity, Index, JoinColumn, ManyToOne, Column, PrimaryColumn } from 'typeorm'; -import { notificationTypes } from '@/types.js'; +import { notificationTypes, obsoleteNotificationTypes } from '@/types.js'; import { id } from '../id.js'; import { User } from './User.js'; import { Note } from './Note.js'; @@ -58,7 +58,6 @@ export class Notification { * renote - 投稿がRenoteされた * quote - 投稿が引用Renoteされた * reaction - 投稿にリアクションされた - * pollVote - 投稿のアンケートに投票された (廃止) * pollEnded - 自分のアンケートもしくは自分が投票したアンケートが終了した * receiveFollowRequest - フォローリクエストされた * followRequestAccepted - 自分の送ったフォローリクエストが承認された @@ -67,7 +66,10 @@ export class Notification { */ @Index() @Column('enum', { - enum: notificationTypes, + enum: [ + ...notificationTypes, + ...obsoleteNotificationTypes, + ], comment: 'The type of the Notification.', }) public type: typeof notificationTypes[number]; diff --git a/packages/backend/src/models/entities/UserProfile.ts b/packages/backend/src/models/entities/UserProfile.ts index 3d35b4cb5..60c1c55de 100644 --- a/packages/backend/src/models/entities/UserProfile.ts +++ b/packages/backend/src/models/entities/UserProfile.ts @@ -1,5 +1,5 @@ import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm'; -import { ffVisibility, notificationTypes } from '@/types.js'; +import { obsoleteNotificationTypes, ffVisibility, notificationTypes } from '@/types.js'; import { id } from '../id.js'; import { User } from './User.js'; import { Page } from './Page.js'; @@ -205,7 +205,7 @@ export class UserProfile { enum: [ ...notificationTypes, // マイグレーションで削除が困難なので古いenumは残しておく - 'groupInvited', + ...obsoleteNotificationTypes, ], array: true, default: [], diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts index 706e0d208..e3897d38b 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications.ts @@ -1,7 +1,7 @@ import { Brackets } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; import type { UsersRepository, FollowingsRepository, MutingsRepository, UserProfilesRepository, NotificationsRepository } from '@/models/index.js'; -import { notificationTypes } from '@/types.js'; +import { obsoleteNotificationTypes, notificationTypes } from '@/types.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { QueryService } from '@/core/QueryService.js'; import { NoteReadService } from '@/core/NoteReadService.js'; @@ -41,11 +41,12 @@ export const paramDef = { following: { type: 'boolean', default: false }, unreadOnly: { type: 'boolean', default: false }, markAsRead: { type: 'boolean', default: true }, + // 後方互換のため、廃止された通知タイプも受け付ける includeTypes: { type: 'array', items: { - type: 'string', enum: notificationTypes, + type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes], } }, excludeTypes: { type: 'array', items: { - type: 'string', enum: notificationTypes, + type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes], } }, }, required: [], @@ -84,6 +85,10 @@ export default class extends Endpoint { if (notificationTypes.every(type => ps.excludeTypes?.includes(type))) { return []; } + + const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][]; + const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][]; + const followingQuery = this.followingsRepository.createQueryBuilder('following') .select('following.followeeId') .where('following.followerId = :followerId', { followerId: me.id }); @@ -143,10 +148,10 @@ export default class extends Endpoint { query.setParameters(followingQuery.getParameters()); } - if (ps.includeTypes && ps.includeTypes.length > 0) { - query.andWhere('notification.type IN (:...includeTypes)', { includeTypes: ps.includeTypes }); - } else if (ps.excludeTypes && ps.excludeTypes.length > 0) { - query.andWhere('notification.type NOT IN (:...excludeTypes)', { excludeTypes: ps.excludeTypes }); + if (includeTypes && includeTypes.length > 0) { + query.andWhere('notification.type IN (:...includeTypes)', { includeTypes }); + } else if (excludeTypes && excludeTypes.length > 0) { + query.andWhere('notification.type NOT IN (:...excludeTypes)', { excludeTypes }); } if (ps.unreadOnly) { diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 8ac65a021..7c6a1e519 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -1,4 +1,5 @@ -export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const; +export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const; +export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const; export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const; diff --git a/packages/frontend/src/components/MkNotificationSettingWindow.vue b/packages/frontend/src/components/MkNotificationSettingWindow.vue index 2d8d30e33..f6d0e5681 100644 --- a/packages/frontend/src/components/MkNotificationSettingWindow.vue +++ b/packages/frontend/src/components/MkNotificationSettingWindow.vue @@ -6,7 +6,7 @@ :with-ok-button="true" :ok-button-disabled="false" @ok="ok()" - @close="dialog.close()" + @close="dialog?.close()" @closed="emit('closed')" > @@ -25,7 +25,7 @@ {{ i18n.ts.disableAll }} {{ i18n.ts.enableAll }} - {{ i18n.t(`_notification._types.${ntype}`) }} + {{ i18n.t(`_notification._types.${ntype}`) }} @@ -33,14 +33,16 @@ diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue index 37ce7635a..93b1c3705 100644 --- a/packages/frontend/src/components/MkNotifications.vue +++ b/packages/frontend/src/components/MkNotifications.vue @@ -18,7 +18,6 @@