diff --git a/.github/ISSUE_TEMPLATE/02_feature-request.yml b/.github/ISSUE_TEMPLATE/02_feature-request.yml index 762d623f1aae..8d7b0b2539e9 100644 --- a/.github/ISSUE_TEMPLATE/02_feature-request.yml +++ b/.github/ISSUE_TEMPLATE/02_feature-request.yml @@ -15,7 +15,6 @@ body: description: Describe the specific problem or need you think this feature will solve, and who it will help. validations: required: true - - type: checkboxes attributes: label: Do you want to implement this feature yourself? diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7c1539e34aec..db899ba386be 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: env: - REGISTRY_IMAGE: taichanne30/nadesuki + REGISTRY_IMAGE: misskey/misskey TAGS: | type=edge type=ref,event=pr diff --git a/CHANGELOG_NADE.md b/CHANGELOG_NADE.md deleted file mode 100644 index 6aeb256a1c7b..000000000000 --- a/CHANGELOG_NADE.md +++ /dev/null @@ -1,167 +0,0 @@ -オリジナルのMisskeyの変更履歴は[CHANGELOG](CHANGELOG.md)をご覧ください。 - - -## nade 1.5.6 -### Client -- Fix: マージミスによる存在しない変数が呼ばれる問題を修正 -- 2024.7.0マージに伴うコーディングスタイルの調整 - -## nade 1.5.5 -### Server -- Fix: DBフォールバックが大量に遡ると取得漏れを起こしてしまう問題を修正した際、sinceIdによる取得を壊してしまったので修正 - -## nade 1.5.4 -そんなものはなかった - -## nade 1.5.3 -### Client -- Fix: ローカルのみをデッキから選択した時に反映されない問題の修正 - -## nade 1.5.2 -### Server -- Fix: そもそもDBフォールバックが大量に遡ると取得漏れを起こしてしまう問題を修正 - -## nade 1.5.1 -### Server -- Fix: ローカルのみに絞り込んだ際、DBにフォールバックすると正しい結果とならないのを修正 - -## nade 1.5.0 -### General -- ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを廃止 -- ホーム、ソーシャルtlにてローカルのみに絞り込める機能を追加 - -## nade 1.4.7 -### General -- 2024.2.0の適用に伴いフォークに関するコードも微修正しました -- [メンションの最大数をロールごとに設定可能にする misskey-dev/misskey#13343](https://github.com/misskey-dev/misskey/pull/13343) を導入 - -### Client -### Server - -## nade 1.4.7 -### General -- 2023.12.2の適用に伴いフォークに関するコードも微修正しました - -### Client -### Server - -## nade 1.4.6 -### General - -### Client -- CWを開閉するボタンのサイズを小さくしました - - CWは閲覧注意を意味し、コンテンツを見えなくするもので画面の占有率を下げるため。 -### Server -- fix: localHomeTimeline(ローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプション、以降ローカルホームと呼称します)にて自分の投稿が反映されない問題を修正 - -## nade 1.4.4 & 1.4.5 -2023/10/25日時点でMisskey 2023.11.0-betaに含まれるTL系の修正、並びにアバターデコレーションをチェリーピックしました - -## nade 1.4.3 -### Server -- リストTLもDBへのフォールバックに対応させました - -## nade 1.4.2 -### Server -- DBフォールバックの方法を本家Misskeyに揃えました - -## nade 1.4.0 & 1.4.1 -### Server -- タイムラインがRedisにキャッシュされていない際にDBから取得します。 - -## nade 1.3.5 & nade 1.3.6 -### NOTE -nade 1.3.5 is not working -### General -- Misskey 2023.9.1対応のための軽微な修正 - -## nade 1.3.3 & nade 1.3.4 -### General -- Misskey 2023.9.0対応のための軽微な修正 - -## nade 1.3.1 & nade 1.3.2 -### General -- 新着ノート通知機能 - - 取り込みが不足していたので色々追加 - -## nade 1.3.1 -### General -- 新着ノート通知機能 - - 設定→通知にある「ノート通知」から、自分が新着ノート通知を有効にしているユーザー一覧を見ることができます。 - --> 導入し忘れていたので導入 -## nade 1.3.0 -### General -[隠れ家様の実装を一部輸入させて頂きました(ちゃんとcherry-pick)](https://github.com/hideki0403/misskey.yukineko.me) -- feat: ファイル名をランダム化できるように - - 設定の「ドライブ」または「プライバシー」からONにできます。 - - ONにすると、ファイルのアップロード時にファイル名がランダムな文字列になります。 -- 新着ノート通知機能 - - ユーザーがノートを投稿した際に通知を受け取れる機能 - - ユーザーのプロフィールページのメニュー(・・・)にある「ノート通知を有効にする」から有効にできます。 - - -## nade 1.2.4 -### General -### Client - -### Server -- Fix: ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを有効にした際にページネーションが働かない - -### General - -### Client -### Server - -## nade 1.2.4 -### General -### Client - -### Server -- Fix: ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを有効にした際にページネーションが働かない -## nade 1.2.2 -### General -- ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを追加 -### Client - -### Server -- Fix: ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを有効にした際にローカルでないユーザーも表示されてしまう (再Fix) - -## nade 1.2.1 -### General -- ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを追加 -### Client - -### Server -- Fix: ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを有効にした際にローカルでないユーザーも表示されてしまう - -## nade 1.2.0 -### General -- ローカルタイムラインにローカルのフォロー中ユーザーの投稿範囲がホーム以下のノートも表示するオプションを追加 -### Client - -### Server - -## nade 1.1.1 -### General -- Dockerイメージにてjemallocを利用するように変更 -- バージョン表記をmisskey-nade1.1.1のようにハイフン形式を使うように変更 - -## nade 1.1.0 -### General - -### Client -- Enhance: ノート検索にローカルのみ検索可能なオプションの追加 - -### Server -- Fix: ノート検索 `notes/search` にてhostを指定した際に検索結果に反映されるように - -## nade 1.0.0 -- Just fork diff --git a/COPYING b/COPYING index 14826a87e4f9..6a5f3ca1d598 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ Unless otherwise stated this repository is -Copyright © 2014-2024 syuilo and contributers +Copyright © 2014-2024 syuilo and contributors And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE. diff --git a/DIFFERENCE.md b/DIFFERENCE.md deleted file mode 100644 index 765b59ea91be..000000000000 --- a/DIFFERENCE.md +++ /dev/null @@ -1,20 +0,0 @@ -## Nadesskeyと通常のMisskeyとの違い -Nadesskeyは基本的に通常のMisskeyへ機能をマージすることを目指しているため、大きな使い勝手はバニラMisskeyと変わらない事が特徴です。 -通常のMisskeyのベータ相当の機能が先行して取り込まれることがあります。 - -### 独自の機能 -- ホームTL、ソーシャルTLでローカルのみに絞り込めるオプションの追加 - - 廃止済のLTLにフォロー中ローカルユーザの全ての投稿を表示することが可能なオプションと同様、ローカルユーザと交流しつつ連合のユーザとも交流しやすくなる狙いがあります。 -- ~~LTLにフォロー中ローカルユーザの全ての投稿を表示することが可能なオプション~~ (廃止済) - - クライアント設定→全般 より 「ローカルタイムラインにローカルのパブリック未満のノートを表示する 」を設定することで変更できます - - ※この機能にはローカルユーザと交流しつつ連合のユーザとも交流しやすくなる狙いがあります -- ~~ファイル名のランダム化~~ - - ~~設定の「ドライブ」または「プライバシー」からONにできます。~~ - ~~ONにすると、ファイルのアップロード時にファイル名がランダムな文字列になります。~~ - - ~~Thanks [隠れ家](https://github.com/hideki0403/misskey.yukineko.me/blob/master-kakurega/DIFFERENCE.md)~~ - - Misskey標準で同等機能が実装されたため廃止しました(https://github.com/misskey-dev/misskey/pull/13688) -### 改変箇所 -- CWの開閉ボタンのサイズを小さくしました -- [隠れ家](https://github.com/hideki0403/misskey.yukineko.me/blob/master-kakurega/DIFFERENCE.md)をベースにした通知機能 - - フォローしていないユーザの通知も受け取ることが可能です - - 設定→通知 内の「ノート通知」より通知を有効にしているユーザの一覧が確認可能です diff --git a/README.md b/README.md index e4084b64a22c..92e8fef6396e 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,7 @@ become a patron -## Diff of this fork -[Changelog of this fork](CHANGELOG_NADE) + ## Thanks diff --git a/locales/en-US.yml b/locales/en-US.yml index 9b0598cb63e1..fe2bb08074fa 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -980,7 +980,6 @@ cannotUploadBecauseInappropriate: "This file could not be uploaded because parts cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity." cannotUploadBecauseExceedsFileSizeLimit: "This file cannot be uploaded as it exceeds the file size limit." beta: "Beta" -originalFeature: "Nadesskey" enableAutoSensitive: "Automatic marking as sensitive" enableAutoSensitiveDescription: "Allows automatic detection and marking of sensitive media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide." activeEmailValidationDescription: "Enables stricter validation of email addresses, which includes checking for disposable addresses and by whether it can actually be communicated with. When unchecked, only the format of the email is validated." diff --git a/locales/index.d.ts b/locales/index.d.ts index 6f443a810b63..91d36a14a627 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -3936,10 +3936,6 @@ export interface Locale extends ILocale { * ベータ */ "beta": string; - /** - * Nadesskey - */ - "originalFeature": string; /** * 自動センシティブ判定 */ @@ -4384,18 +4380,6 @@ export interface Locale extends ILocale { * 常に広告を表示する */ "forceShowAds": string; - /** - * ノート通知 - */ - "noteNotification": string; - /** - * ノート通知を有効にする - */ - "noteSubscribe": string; - /** - * ノート通知を無効にする - */ - "noteUnsubscribe": string; /** * メモを追加 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index e44a5820b241..b493183974cc 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -980,7 +980,6 @@ cannotUploadBecauseInappropriate: "不適切な内容を含む可能性がある cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。" cannotUploadBecauseExceedsFileSizeLimit: "ファイルサイズの制限を超えているためアップロードできません。" beta: "ベータ" -originalFeature: "Nadesskey" enableAutoSensitive: "自動センシティブ判定" enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにセンシティブフラグを設定します。この機能をオフにしても、サーバーによっては自動で設定されることがあります。" activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。" @@ -1092,9 +1091,6 @@ accountMoved: "このユーザーは新しいアカウントに移行しまし accountMovedShort: "このアカウントは移行されています" operationForbidden: "この操作はできません" forceShowAds: "常に広告を表示する" -noteNotification: "ノート通知" -noteSubscribe: "ノート通知を有効にする" -noteUnsubscribe: "ノート通知を無効にする" addMemo: "メモを追加" editMemo: "メモを編集" reactionsList: "リアクション一覧" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 0e6cf4afafd4..98045b43aca5 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -980,7 +980,6 @@ cannotUploadBecauseInappropriate: "きわどい内容を含むかもしれへん cannotUploadBecauseNoFreeSpace: "ドライブがもうパンパンやからアップロードできへんわ。" cannotUploadBecauseExceedsFileSizeLimit: "ファイルが思うたよりも大きいさかいアップロードできへんでこれ。" beta: "ベータ" -originalFeature: "Nadesskey" enableAutoSensitive: "自動できわどいか判断する" enableAutoSensitiveDescription: "使える時は、機械学習を使って自動でメディアにNSFWフラグを設定するで。この機能をオフにしても、サーバーによっては自動で設定されることがあるで。" activeEmailValidationDescription: "ユーザーのメアドのバリデーションを、捨てアドかどうかとか、ちゃんと通信できるかとかを見るで。切ったら単に文字列として合っとるかどうかだけ見るわ。" diff --git a/package.json b/package.json index ae93cea2b0db..1b8b1cc33e1e 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "misskey", - "version": "2024.8.0-nade.1.5.6.alpha.0", + "version": "2024.8.0-alpha.0", "codename": "nasubi", "repository": { "type": "git", - "url": "https://github.com/nadesuki/nadesskey.git" + "url": "https://github.com/misskey-dev/misskey.git" }, "packageManager": "pnpm@9.6.0", "workspaces": [ diff --git a/packages/backend/assets/tabler-badges/bell.png b/packages/backend/assets/tabler-badges/bell.png index 8d5eb6e543d6..ab3b2a110f66 100644 Binary files a/packages/backend/assets/tabler-badges/bell.png and b/packages/backend/assets/tabler-badges/bell.png differ diff --git a/packages/backend/migration/1682932943132-note-notification.js b/packages/backend/migration/1682932943132-note-notification.js deleted file mode 100644 index 93b259ce68a8..000000000000 --- a/packages/backend/migration/1682932943132-note-notification.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - - -export class NoteNotification1682932943132 { - name = 'NoteNotification1682932943132' - - async up(queryRunner) { - await queryRunner.query(`CREATE TABLE "note_notification" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "targetUserId" character varying(32) NOT NULL, CONSTRAINT "PK_02dd5dcc82f04263ad78720dccc" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE INDEX "IDX_2d0b2c0212af304221fe1abd94" ON "note_notification" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_73b01aaac615137c472f410a99" ON "note_notification" ("targetUserId") `); - await queryRunner.query(`ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum" RENAME TO "user_profile_mutingnotificationtypes_enum_old"`); - await queryRunner.query(`CREATE TYPE "public"."user_profile_mutingnotificationtypes_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'note', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app', 'pollVote', 'groupInvited')`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" TYPE "public"."user_profile_mutingnotificationtypes_enum"[] USING "mutingNotificationTypes"::"text"::"public"."user_profile_mutingnotificationtypes_enum"[]`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" SET DEFAULT '{}'`); - await queryRunner.query(`DROP TYPE "public"."user_profile_mutingnotificationtypes_enum_old"`); - await queryRunner.query(`ALTER TABLE "note_notification" ADD CONSTRAINT "FK_2d0b2c0212af304221fe1abd940" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "note_notification" ADD CONSTRAINT "FK_73b01aaac615137c472f410a996" FOREIGN KEY ("targetUserId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - async down(queryRunner) { - await queryRunner.query(`ALTER TABLE "note_notification" DROP CONSTRAINT "FK_73b01aaac615137c472f410a996"`); - await queryRunner.query(`ALTER TABLE "note_notification" DROP CONSTRAINT "FK_2d0b2c0212af304221fe1abd940"`); - await queryRunner.query(`CREATE TYPE "public"."user_profile_mutingnotificationtypes_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'achievementEarned', 'app')`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" TYPE "public"."user_profile_mutingnotificationtypes_enum_old"[] USING "mutingNotificationTypes"::"text"::"public"."user_profile_mutingnotificationtypes_enum_old"[]`); - await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "mutingNotificationTypes" SET DEFAULT '{}'`); - await queryRunner.query(`DROP TYPE "public"."user_profile_mutingnotificationtypes_enum"`); - await queryRunner.query(`ALTER TYPE "public"."user_profile_mutingnotificationtypes_enum_old" RENAME TO "user_profile_mutingnotificationtypes_enum"`); - await queryRunner.query(`DROP INDEX "public"."IDX_73b01aaac615137c472f410a99"`); - await queryRunner.query(`DROP INDEX "public"."IDX_2d0b2c0212af304221fe1abd94"`); - await queryRunner.query(`DROP TABLE "note_notification"`); - } -} diff --git a/packages/backend/migration/1697814583291-delete-created-at.js b/packages/backend/migration/1697814583291-delete-created-at.js deleted file mode 100644 index d925c9f3dd7f..000000000000 --- a/packages/backend/migration/1697814583291-delete-created-at.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - - -export class DeleteCreatedAt1697814583291 { - name = 'DeleteCreatedAt1697814583291' - - async up(queryRunner) { - await queryRunner.query(`ALTER TABLE "note_notification" DROP COLUMN "createdAt"`); - } - - async down(queryRunner) { - await queryRunner.query(`ALTER TABLE "note_notification" ADD "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL`); - } -} diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index 661831af5fcd..c9427bbeb7bd 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -45,7 +45,6 @@ import { NoteDeleteService } from './NoteDeleteService.js'; import { NotePiningService } from './NotePiningService.js'; import { NoteReadService } from './NoteReadService.js'; import { NotificationService } from './NotificationService.js'; -import { NoteNotificationService } from './NoteNotificationService.js'; import { PollService } from './PollService.js'; import { PushNotificationService } from './PushNotificationService.js'; import { QueryService } from './QueryService.js'; @@ -117,7 +116,6 @@ import { RenoteMutingEntityService } from './entities/RenoteMutingEntityService. import { NoteEntityService } from './entities/NoteEntityService.js'; import { NoteFavoriteEntityService } from './entities/NoteFavoriteEntityService.js'; import { NoteReactionEntityService } from './entities/NoteReactionEntityService.js'; -import { NoteNotificationEntityService } from './entities/NoteNotificationEntityService.js'; import { NotificationEntityService } from './entities/NotificationEntityService.js'; import { PageEntityService } from './entities/PageEntityService.js'; import { PageLikeEntityService } from './entities/PageLikeEntityService.js'; @@ -189,7 +187,6 @@ const $NoteDeleteService: Provider = { provide: 'NoteDeleteService', useExisting const $NotePiningService: Provider = { provide: 'NotePiningService', useExisting: NotePiningService }; const $NoteReadService: Provider = { provide: 'NoteReadService', useExisting: NoteReadService }; const $NotificationService: Provider = { provide: 'NotificationService', useExisting: NotificationService }; -const $NoteNotificationService: Provider = { provide: 'NoteNotificationService', useExisting: NoteNotificationService }; const $PollService: Provider = { provide: 'PollService', useExisting: PollService }; const $ProxyAccountService: Provider = { provide: 'ProxyAccountService', useExisting: ProxyAccountService }; const $PushNotificationService: Provider = { provide: 'PushNotificationService', useExisting: PushNotificationService }; @@ -265,7 +262,6 @@ const $RenoteMutingEntityService: Provider = { provide: 'RenoteMutingEntityServi const $NoteEntityService: Provider = { provide: 'NoteEntityService', useExisting: NoteEntityService }; const $NoteFavoriteEntityService: Provider = { provide: 'NoteFavoriteEntityService', useExisting: NoteFavoriteEntityService }; const $NoteReactionEntityService: Provider = { provide: 'NoteReactionEntityService', useExisting: NoteReactionEntityService }; -const $NoteNotificationEntityService: Provider = { provide: 'NoteNotificationEntityService', useExisting: NoteNotificationEntityService }; const $NotificationEntityService: Provider = { provide: 'NotificationEntityService', useExisting: NotificationEntityService }; const $PageEntityService: Provider = { provide: 'PageEntityService', useExisting: PageEntityService }; const $PageLikeEntityService: Provider = { provide: 'PageLikeEntityService', useExisting: PageLikeEntityService }; @@ -339,7 +335,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting NotePiningService, NoteReadService, NotificationService, - NoteNotificationService, PollService, ProxyAccountService, PushNotificationService, @@ -415,7 +410,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting NoteEntityService, NoteFavoriteEntityService, NoteReactionEntityService, - NoteNotificationEntityService, NotificationEntityService, PageEntityService, PageLikeEntityService, @@ -485,7 +479,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $NotePiningService, $NoteReadService, $NotificationService, - $NoteNotificationService, $PollService, $ProxyAccountService, $PushNotificationService, @@ -561,7 +554,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $NoteEntityService, $NoteFavoriteEntityService, $NoteReactionEntityService, - $NoteNotificationEntityService, $NotificationEntityService, $PageEntityService, $PageLikeEntityService, @@ -632,7 +624,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting NotePiningService, NoteReadService, NotificationService, - NoteNotificationService, PollService, ProxyAccountService, PushNotificationService, @@ -707,7 +698,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting NoteEntityService, NoteFavoriteEntityService, NoteReactionEntityService, - NoteNotificationEntityService, NotificationEntityService, PageEntityService, PageLikeEntityService, @@ -777,7 +767,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $NotePiningService, $NoteReadService, $NotificationService, - $NoteNotificationService, $PollService, $ProxyAccountService, $PushNotificationService, @@ -852,7 +841,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $NoteEntityService, $NoteFavoriteEntityService, $NoteReactionEntityService, - $NoteNotificationEntityService, $NotificationEntityService, $PageEntityService, $PageLikeEntityService, diff --git a/packages/backend/src/core/FanoutTimelineEndpointService.ts b/packages/backend/src/core/FanoutTimelineEndpointService.ts index e4ff2b0a9f62..b05af99c5e5e 100644 --- a/packages/backend/src/core/FanoutTimelineEndpointService.ts +++ b/packages/backend/src/core/FanoutTimelineEndpointService.ts @@ -63,18 +63,12 @@ export class FanoutTimelineEndpointService { const redisResult = await this.fanoutTimelineService.getMulti(ps.redisTimelines, ps.untilId, ps.sinceId); - // 取得したredisResultのうち、2つ以上ソースがあり、1つでも空であればDBにフォールバックする - let shouldFallbackToDb = ps.useDbFallback && (redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); - - // 取得したresultの中で最古のIDのうち、最も新しいものを取得 - const thresholdId = redisResult.map(ids => ids[0]).sort()[0]; - // TODO: いい感じにgetMulti内でソート済だからuniqするときにredisResultが全てソート済なのを利用して再ソートを避けたい const redisResultIds = Array.from(new Set(redisResult.flat(1))).sort(idCompare); - let noteIds = redisResultIds.filter(id => id >= thresholdId).slice(0, ps.limit); + let noteIds = redisResultIds.slice(0, ps.limit); const oldestNoteId = ascending ? redisResultIds[0] : redisResultIds[redisResultIds.length - 1]; - shouldFallbackToDb = shouldFallbackToDb || noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId; + const shouldFallbackToDb = noteIds.length === 0 || ps.sinceId != null && ps.sinceId < oldestNoteId; if (!shouldFallbackToDb) { let filter = ps.noteFilter ?? (_note => true); diff --git a/packages/backend/src/core/FanoutTimelineService.ts b/packages/backend/src/core/FanoutTimelineService.ts index aef4ced2556a..f6dabfadcd6d 100644 --- a/packages/backend/src/core/FanoutTimelineService.ts +++ b/packages/backend/src/core/FanoutTimelineService.ts @@ -14,9 +14,9 @@ export type FanoutTimelineName = | `homeTimeline:${string}` | `homeTimelineWithFiles:${string}` // only notes with files are included // local timeline - | 'localTimeline' // replies are not included - | 'localTimelineWithFiles' // only non-reply notes with files are included - | 'localTimelineWithReplies' // only replies are included + | `localTimeline` // replies are not included + | `localTimelineWithFiles` // only non-reply notes with files are included + | `localTimelineWithReplies` // only replies are included | `localTimelineWithReplyTo:${string}` // Only replies to specific local user are included. Parameter is reply user id. // antenna diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index df32773a057f..87aa70713e61 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -10,7 +10,6 @@ import type { MiChannel } from '@/models/Channel.js'; import type { MiUser } from '@/models/User.js'; import type { MiUserProfile } from '@/models/UserProfile.js'; import type { MiNote } from '@/models/Note.js'; -import type { MiNoteNotification } from '@/models/NoteNotification.js'; import type { MiAntenna } from '@/models/Antenna.js'; import type { MiDriveFile } from '@/models/DriveFile.js'; import type { MiDriveFolder } from '@/models/DriveFolder.js'; @@ -239,8 +238,6 @@ export interface InternalEventTypes { antennaCreated: MiAntenna; antennaDeleted: MiAntenna; antennaUpdated: MiAntenna; - noteNotificationCreated: MiNoteNotification; - noteNotificationDeleted: MiNoteNotification; avatarDecorationCreated: MiAvatarDecoration; avatarDecorationDeleted: MiAvatarDecoration; avatarDecorationUpdated: MiAvatarDecoration; diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 673e49c97b67..1d8d2483228a 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -41,7 +41,6 @@ import { NotificationService } from '@/core/NotificationService.js'; import { UserWebhookService } from '@/core/UserWebhookService.js'; import { HashtagService } from '@/core/HashtagService.js'; import { AntennaService } from '@/core/AntennaService.js'; -import { NoteNotificationService } from '@/core/NoteNotificationService.js'; import { QueueService } from '@/core/QueueService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -205,7 +204,6 @@ export class NoteCreateService implements OnApplicationShutdown { private federatedInstanceService: FederatedInstanceService, private hashtagService: HashtagService, private antennaService: AntennaService, - private noteNotificationService: NoteNotificationService, private webhookService: UserWebhookService, private featuredService: FeaturedService, private remoteUserResolveService: RemoteUserResolveService, @@ -536,7 +534,6 @@ export class NoteCreateService implements OnApplicationShutdown { this.pushToTl(note, user); this.antennaService.addNoteToAntennas(note, user); - this.noteNotificationService.sendNotificationToSubscriber(note, user); if (data.reply) { this.saveReply(data.reply, note); diff --git a/packages/backend/src/core/NoteNotificationService.ts b/packages/backend/src/core/NoteNotificationService.ts deleted file mode 100644 index 8c81a2080e69..000000000000 --- a/packages/backend/src/core/NoteNotificationService.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; -import type { MiNoteNotification } from '@/models/NoteNotification.js'; -import type { MiUser } from '@/models/User.js'; -import type { MiNote } from '@/models/Note.js'; -import { NotificationService } from '@/core/NotificationService.js'; -import { DI } from '@/di-symbols.js'; -import type { NoteNotificationsRepository } from '@/models/_.js'; -import { bindThis } from '@/decorators.js'; -import type { GlobalEvents } from '@/core/GlobalEventService.js'; -import type { OnApplicationShutdown } from '@nestjs/common'; - -@Injectable() -export class NoteNotificationService implements OnApplicationShutdown { - private targetUsersFetched: boolean; - private targetUsers: MiNoteNotification[]; - - constructor( - @Inject(DI.redisForSub) - private redisForSub: Redis.Redis, - - @Inject(DI.noteNotificationsRepository) - private noteNotificationsRepository: NoteNotificationsRepository, - - private notificationService: NotificationService, - ) { - this.targetUsersFetched = false; - this.targetUsers = []; - - this.redisForSub.on('message', this.onRedisMessage); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined) { - this.redisForSub.off('message', this.onRedisMessage); - } - - @bindThis - private async onRedisMessage(_: string, data: string): Promise { - const obj = JSON.parse(data); - - if (obj.channel === 'internal') { - const { type, body } = obj.message as GlobalEvents['internal']['payload']; - switch (type) { - case 'noteNotificationCreated': - // TODO: typecheck回避(WIP)、きれいに書く - this.targetUsers.push({ ...body, targetUser: body.targetUser as MiUser, user: body.user as MiUser }); - break; - case 'noteNotificationDeleted': - this.targetUsers = this.targetUsers.filter(a => a.id !== body.id); - break; - default: - break; - } - } - } - - @bindThis - public async sendNotificationToSubscriber(note: MiNote, noteUser: { id: MiUser['id']; username: string; host: string | null; }): Promise { - if (!['public', 'home'].includes(note.visibility)) return; - - const targetUsers = await this.getTargetUsers(); - const matchedTargets = Array.from(targetUsers.filter(x => x.targetUserId === noteUser.id)); - - matchedTargets.forEach(x => { - this.notificationService.createNotification(x.userId, 'note', { - noteId: note.id, - }, noteUser.id); - }); - } - - @bindThis - public async getTargetUsers() { - if (!this.targetUsersFetched) { - this.targetUsers = await this.noteNotificationsRepository.find(); - this.targetUsersFetched = true; - } - - return this.targetUsers; - } -} diff --git a/packages/backend/src/core/RedisTimelineService.ts b/packages/backend/src/core/RedisTimelineService.ts deleted file mode 100644 index 94541759cc08..000000000000 --- a/packages/backend/src/core/RedisTimelineService.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and other misskey contributors - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import * as Redis from 'ioredis'; -import { DI } from '@/di-symbols.js'; -import { bindThis } from '@/decorators.js'; -import { IdService } from '@/core/IdService.js'; - -@Injectable() -export class RedisTimelineService { - constructor( - @Inject(DI.redisForTimelines) - private redisForTimelines: Redis.Redis, - - private idService: IdService, - ) { - } - - @bindThis - public push(tl: string, id: string, maxlen: number, pipeline: Redis.ChainableCommander) { - // リモートから遅れて届いた(もしくは後から追加された)投稿日時が古い投稿が追加されるとページネーション時に問題を引き起こすため、 - // 3分以内に投稿されたものでない場合、Redisにある最古のIDより新しい場合のみ追加する - if (this.idService.parse(id).date.getTime() > Date.now() - 1000 * 60 * 3) { - pipeline.lpush('list:' + tl, id); - if (Math.random() < 0.1) { // 10%の確率でトリム - pipeline.ltrim('list:' + tl, 0, maxlen - 1); - } - } else { - // 末尾のIDを取得 - this.redisForTimelines.lindex('list:' + tl, -1).then(lastId => { - if (lastId == null || (this.idService.parse(id).date.getTime() > this.idService.parse(lastId).date.getTime())) { - this.redisForTimelines.lpush('list:' + tl, id); - } else { - Promise.resolve(); - } - }); - } - } - - @bindThis - public get(name: string, untilId?: string | null, sinceId?: string | null) { - if (untilId && sinceId) { - return this.redisForTimelines.lrange('list:' + name, 0, -1) - .then(ids => ids.filter(id => id < untilId && id > sinceId).sort((a, b) => a > b ? -1 : 1)); - } else if (untilId) { - return this.redisForTimelines.lrange('list:' + name, 0, -1) - .then(ids => ids.filter(id => id < untilId).sort((a, b) => a > b ? -1 : 1)); - } else if (sinceId) { - return this.redisForTimelines.lrange('list:' + name, 0, -1) - .then(ids => ids.filter(id => id > sinceId).sort((a, b) => a < b ? -1 : 1)); - } else { - return this.redisForTimelines.lrange('list:' + name, 0, -1) - .then(ids => ids.sort((a, b) => a > b ? -1 : 1)); - } - } - - @bindThis - public getMulti(name: string[], untilId?: string | null, sinceId?: string | null): Promise { - const pipeline = this.redisForTimelines.pipeline(); - for (const n of name) { - pipeline.lrange('list:' + n, 0, -1); - } - return pipeline.exec().then(res => { - if (res == null) return []; - const tls = res.map(r => r[1] as string[]); - return tls.map(ids => - (untilId && sinceId) - ? ids.filter(id => id < untilId && id > sinceId).sort((a, b) => a > b ? -1 : 1) - : untilId - ? ids.filter(id => id < untilId).sort((a, b) => a > b ? -1 : 1) - : sinceId - ? ids.filter(id => id > sinceId).sort((a, b) => a < b ? -1 : 1) - : ids.sort((a, b) => a > b ? -1 : 1), - ); - }); - } -} diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index 3ae35205c8f0..edfc47037523 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -29,8 +29,6 @@ type Q = { op: '<=', k: K, v: number } | { op: 'is null', k: K} | { op: 'is not null', k: K} | - { op: 'is null', k: K} | - { op: 'is not null', k: K} | { op: 'and', qs: Q[] } | { op: 'or', qs: Q[] } | { op: 'not', q: Q }; diff --git a/packages/backend/src/core/entities/NoteNotificationEntityService.ts b/packages/backend/src/core/entities/NoteNotificationEntityService.ts deleted file mode 100644 index afbe56a6d1ea..000000000000 --- a/packages/backend/src/core/entities/NoteNotificationEntityService.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; - -import type { NoteNotificationsRepository } from '@/models/_.js'; -import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { Packed } from '@/misc/json-schema.js'; -import type { } from '@/models/Blocking.js'; -import type { MiUser } from '@/models/User.js'; -import type { MiNoteNotification } from '@/models/NoteNotification.js'; -import { bindThis } from '@/decorators.js'; -import { IdService } from '@/core/IdService.js'; -import { UserEntityService } from './UserEntityService.js'; - -@Injectable() -export class NoteNotificationEntityService { - constructor( - @Inject(DI.noteNotificationsRepository) - private noteNotificationsRepository: NoteNotificationsRepository, - - private userEntityService: UserEntityService, - private idService: IdService, - ) { - } - - @bindThis - public async pack( - src: MiNoteNotification['id'] | MiNoteNotification, - me?: { id: MiUser['id'] } | null | undefined, - ): Promise> { - const target = typeof src === 'object' ? src : await this.noteNotificationsRepository.findOneByOrFail({ id: src }); - - return await awaitAll({ - id: target.id, - createdAt: this.idService.parse(target.id).date.toISOString(), - userId: target.targetUserId, - user: this.userEntityService.pack(target.targetUserId, me, { schema: 'UserDetailed' }), - }); - } - - @bindThis - public packMany( - targets: any[], - me: { id: MiUser['id'] }, - ) { - return Promise.all(targets.map(x => this.pack(x, me))); - } -} diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 8f64dad22c12..9bf568bc9088 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -38,7 +38,6 @@ import type { UserProfilesRepository, UserSecurityKeysRepository, UsersRepository, - NoteNotificationsRepository, } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { RoleService } from '@/core/RoleService.js'; @@ -79,7 +78,6 @@ export type UserRelation = { isBlocked: boolean isMuted: boolean isRenoteMuted: boolean - isNoteSubscribing: boolean } @Injectable() @@ -124,9 +122,6 @@ export class UserEntityService implements OnModuleInit { @Inject(DI.renoteMutingsRepository) private renoteMutingsRepository: RenoteMutingsRepository, - @Inject(DI.noteNotificationsRepository) - private noteNotificationsRepository: NoteNotificationsRepository, - @Inject(DI.noteUnreadsRepository) private noteUnreadsRepository: NoteUnreadsRepository, @@ -176,7 +171,6 @@ export class UserEntityService implements OnModuleInit { isBlocked, isMuted, isRenoteMuted, - isNoteSubscribing, ] = await Promise.all([ this.followingsRepository.findOneBy({ followerId: me, @@ -224,12 +218,6 @@ export class UserEntityService implements OnModuleInit { muteeId: target, }, }), - this.noteNotificationsRepository.exist({ - where: { - userId: me, - targetUserId: target, - }, - }), ]); return { @@ -243,7 +231,6 @@ export class UserEntityService implements OnModuleInit { isBlocked, isMuted, isRenoteMuted, - isNoteSubscribing, }; } @@ -258,7 +245,6 @@ export class UserEntityService implements OnModuleInit { blockees, muters, renoteMuters, - noteSubscriptions, ] = await Promise.all([ this.followingsRepository.findBy({ followerId: me }) .then(f => new Map(f.map(it => [it.followeeId, it]))), @@ -297,11 +283,6 @@ export class UserEntityService implements OnModuleInit { .where('m.muterId = :me', { me }) .getRawMany<{ m_muteeId: string }>() .then(it => it.map(it => it.m_muteeId)), - this.noteNotificationsRepository.createQueryBuilder('n') - .select('n.targetUserId') - .where('n.userId = :me', { me }) - .getRawMany<{ n_targetUserId: string }>() - .then(it => it.map(it => it.n_targetUserId)), ]); return new Map( @@ -321,7 +302,6 @@ export class UserEntityService implements OnModuleInit { isBlocked: blockees.includes(target), isMuted: muters.includes(target), isRenoteMuted: renoteMuters.includes(target), - isNoteSubscribing: noteSubscriptions.includes(target), }, ]; }), @@ -653,11 +633,8 @@ export class UserEntityService implements OnModuleInit { isBlocked: relation.isBlocked, isMuted: relation.isMuted, isRenoteMuted: relation.isRenoteMuted, + notify: relation.following?.notify ?? 'none', withReplies: relation.following?.withReplies ?? false, - isNoteSubscribing: relation.isNoteSubscribing, - //純正Misskeyとの互換性を持たせるため - //純正通知: https://github.com/misskey-dev/misskey/commit/e3f151e2307e4c0d7b9cdfc7deba2ff028adce03 - notify: relation.isNoteSubscribing === false ? 'none' : 'normal', } : {}), } as Promiseable>; diff --git a/packages/backend/src/di-symbols.ts b/packages/backend/src/di-symbols.ts index 9cf1c4454890..271082b4ff35 100644 --- a/packages/backend/src/di-symbols.ts +++ b/packages/backend/src/di-symbols.ts @@ -20,7 +20,6 @@ export const DI = { appsRepository: Symbol('appsRepository'), avatarDecorationsRepository: Symbol('avatarDecorationsRepository'), noteFavoritesRepository: Symbol('noteFavoritesRepository'), - noteNotificationsRepository: Symbol('noteNotificationsRepository'), noteThreadMutingsRepository: Symbol('noteThreadMutingsRepository'), noteReactionsRepository: Symbol('noteReactionsRepository'), noteUnreadsRepository: Symbol('noteUnreadsRepository'), diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index 52a3c6070819..a721b8663c3c 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -16,7 +16,6 @@ import { packedNoteSchema } from '@/models/json-schema/note.js'; import { packedUserListSchema } from '@/models/json-schema/user-list.js'; import { packedAppSchema } from '@/models/json-schema/app.js'; import { packedNotificationSchema } from '@/models/json-schema/notification.js'; -import { packedNoteNotificationSchema } from '@/models/json-schema/note-notification.js'; import { packedDriveFileSchema } from '@/models/json-schema/drive-file.js'; import { packedDriveFolderSchema } from '@/models/json-schema/drive-folder.js'; import { packedFollowingSchema } from '@/models/json-schema/following.js'; @@ -77,7 +76,6 @@ export const refs = { Note: packedNoteSchema, NoteReaction: packedNoteReactionSchema, NoteFavorite: packedNoteFavoriteSchema, - NoteNotification: packedNoteNotificationSchema, Notification: packedNotificationSchema, DriveFile: packedDriveFileSchema, DriveFolder: packedDriveFolderSchema, diff --git a/packages/backend/src/models/NoteNotification.ts b/packages/backend/src/models/NoteNotification.ts deleted file mode 100644 index 467d746260dc..000000000000 --- a/packages/backend/src/models/NoteNotification.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Entity, Index, JoinColumn, Column, ManyToOne, PrimaryColumn } from 'typeorm'; -import { id } from './util/id.js'; -import { MiUser } from './User.js'; - -@Entity('note_notification') -export class MiNoteNotification { - @PrimaryColumn(id()) - public id: string; - - @Index() - @Column(id()) - public userId: MiUser['id']; - - @ManyToOne(type => MiUser, { - onDelete: 'CASCADE', - }) - @JoinColumn() - public user: MiUser | null; - - @Index() - @Column(id()) - public targetUserId: MiUser['id']; - - @ManyToOne(type => MiUser, { - onDelete: 'CASCADE', - }) - @JoinColumn() - public targetUser: MiUser | null; -} diff --git a/packages/backend/src/models/RepositoryModule.ts b/packages/backend/src/models/RepositoryModule.ts index e41667960ebc..ea0f88babaa7 100644 --- a/packages/backend/src/models/RepositoryModule.ts +++ b/packages/backend/src/models/RepositoryModule.ts @@ -6,7 +6,6 @@ import type { Provider } from '@nestjs/common'; import { Module } from '@nestjs/common'; import { DI } from '@/di-symbols.js'; - import { MiAbuseReportNotificationRecipient, MiAbuseUserReport, @@ -42,7 +41,6 @@ import { MiMuting, MiNote, MiNoteFavorite, - MiNoteNotification, MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, @@ -143,12 +141,6 @@ const $noteUnreadsRepository: Provider = { inject: [DI.db], }; -const $noteNotificationsRepository: Provider = { - provide: DI.noteNotificationsRepository, - useFactory: (db: DataSource) => db.getRepository(MiNoteNotification).extend(miRepository as MiRepository), - inject: [DI.db], -}; - const $pollsRepository: Provider = { provide: DI.pollsRepository, useFactory: (db: DataSource) => db.getRepository(MiPoll).extend(miRepository as MiRepository), @@ -516,7 +508,6 @@ const $reversiGamesRepository: Provider = { $noteThreadMutingsRepository, $noteReactionsRepository, $noteUnreadsRepository, - $noteNotificationsRepository, $pollsRepository, $pollVotesRepository, $userProfilesRepository, @@ -588,7 +579,6 @@ const $reversiGamesRepository: Provider = { $noteThreadMutingsRepository, $noteReactionsRepository, $noteUnreadsRepository, - $noteNotificationsRepository, $pollsRepository, $pollVotesRepository, $userProfilesRepository, diff --git a/packages/backend/src/models/_.ts b/packages/backend/src/models/_.ts index 1adaf323cd23..c72bdaa72726 100644 --- a/packages/backend/src/models/_.ts +++ b/packages/backend/src/models/_.ts @@ -44,7 +44,6 @@ import { MiNoteFavorite } from '@/models/NoteFavorite.js'; import { MiNoteReaction } from '@/models/NoteReaction.js'; import { MiNoteThreadMuting } from '@/models/NoteThreadMuting.js'; import { MiNoteUnread } from '@/models/NoteUnread.js'; -import { MiNoteNotification } from '@/models/NoteNotification.js'; import { MiPage } from '@/models/Page.js'; import { MiPageLike } from '@/models/PageLike.js'; import { MiPasswordResetRequest } from '@/models/PasswordResetRequest.js'; @@ -160,7 +159,6 @@ export { MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, - MiNoteNotification, MiPage, MiPageLike, MiPasswordResetRequest, @@ -229,7 +227,6 @@ export type MutingsRepository = Repository & MiRepository; export type RenoteMutingsRepository = Repository & MiRepository; export type NotesRepository = Repository & MiRepository; export type NoteFavoritesRepository = Repository & MiRepository; -export type NoteNotificationsRepository = Repository & MiRepository; export type NoteReactionsRepository = Repository & MiRepository; export type NoteThreadMutingsRepository = Repository & MiRepository; export type NoteUnreadsRepository = Repository & MiRepository; diff --git a/packages/backend/src/models/json-schema/note-notification.ts b/packages/backend/src/models/json-schema/note-notification.ts deleted file mode 100644 index 7ec753e5e6a1..000000000000 --- a/packages/backend/src/models/json-schema/note-notification.ts +++ /dev/null @@ -1,32 +0,0 @@ - -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export const packedNoteNotificationSchema = { - type: 'object', - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - example: 'xxxxxxxxxx', - }, - createdAt: { - type: 'string', - optional: false, nullable: false, - format: 'date-time', - }, - userId: { - type: 'string', - optional: false, nullable: false, - format: 'id', - }, - user: { - type: 'object', - optional: false, nullable: false, - ref: 'UserDetailed', - }, - }, -} as const; diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 01448b2ef7ef..947a9317d7a6 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -416,10 +416,6 @@ export const packedUserDetailedNotMeOnlySchema = { nullable: false, optional: true, enum: ['normal', 'none'], }, - isNoteSubscribing: { - type: 'boolean', - nullable: false, optional: true, - }, withReplies: { type: 'boolean', nullable: false, optional: true, diff --git a/packages/backend/src/postgres.ts b/packages/backend/src/postgres.ts index 0899181e40ec..251a03c303a7 100644 --- a/packages/backend/src/postgres.ts +++ b/packages/backend/src/postgres.ts @@ -43,7 +43,6 @@ import { MiNoteFavorite } from '@/models/NoteFavorite.js'; import { MiNoteReaction } from '@/models/NoteReaction.js'; import { MiNoteThreadMuting } from '@/models/NoteThreadMuting.js'; import { MiNoteUnread } from '@/models/NoteUnread.js'; -import { MiNoteNotification } from '@/models/NoteNotification.js'; import { MiPage } from '@/models/Page.js'; import { MiPageLike } from '@/models/PageLike.js'; import { MiPasswordResetRequest } from '@/models/PasswordResetRequest.js'; @@ -158,7 +157,6 @@ export const entities = [ MiNoteReaction, MiNoteThreadMuting, MiNoteUnread, - MiNoteNotification, MiPage, MiPageLike, MiGalleryPost, diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 0d5112446e50..41576bedaae7 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -272,9 +272,6 @@ import * as ep___mute_list from './endpoints/mute/list.js'; import * as ep___renoteMute_create from './endpoints/renote-mute/create.js'; import * as ep___renoteMute_delete from './endpoints/renote-mute/delete.js'; import * as ep___renoteMute_list from './endpoints/renote-mute/list.js'; -import * as ep___noteNotification_create from './endpoints/note-notification/create.js'; -import * as ep___noteNotification_delete from './endpoints/note-notification/delete.js'; -import * as ep___noteNotification_list from './endpoints/note-notification/list.js'; import * as ep___my_apps from './endpoints/my/apps.js'; import * as ep___notes from './endpoints/notes.js'; import * as ep___notes_children from './endpoints/notes/children.js'; @@ -658,9 +655,6 @@ const $mute_list: Provider = { provide: 'ep:mute/list', useClass: ep___mute_list const $renoteMute_create: Provider = { provide: 'ep:renote-mute/create', useClass: ep___renoteMute_create.default }; const $renoteMute_delete: Provider = { provide: 'ep:renote-mute/delete', useClass: ep___renoteMute_delete.default }; const $renoteMute_list: Provider = { provide: 'ep:renote-mute/list', useClass: ep___renoteMute_list.default }; -const $noteNotification_list: Provider = { provide: 'ep:note-notification/list', useClass: ep___noteNotification_list.default }; -const $noteNotification_create: Provider = { provide: 'ep:note-notification/create', useClass: ep___noteNotification_create.default }; -const $noteNotification_delete: Provider = { provide: 'ep:note-notification/delete', useClass: ep___noteNotification_delete.default }; const $my_apps: Provider = { provide: 'ep:my/apps', useClass: ep___my_apps.default }; const $notes: Provider = { provide: 'ep:notes', useClass: ep___notes.default }; const $notes_children: Provider = { provide: 'ep:notes/children', useClass: ep___notes_children.default }; @@ -1048,9 +1042,6 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ $renoteMute_create, $renoteMute_delete, $renoteMute_list, - $noteNotification_create, - $noteNotification_delete, - $noteNotification_list, $my_apps, $notes, $notes_children, @@ -1432,9 +1423,6 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ $renoteMute_create, $renoteMute_delete, $renoteMute_list, - $noteNotification_create, - $noteNotification_delete, - $noteNotification_list, $my_apps, $notes, $notes_children, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index ffb5a2834bbf..3dfb7fdad4c2 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -278,9 +278,6 @@ import * as ep___mute_list from './endpoints/mute/list.js'; import * as ep___renoteMute_create from './endpoints/renote-mute/create.js'; import * as ep___renoteMute_delete from './endpoints/renote-mute/delete.js'; import * as ep___renoteMute_list from './endpoints/renote-mute/list.js'; -import * as ep___noteNotification_create from './endpoints/note-notification/create.js'; -import * as ep___noteNotification_delete from './endpoints/note-notification/delete.js'; -import * as ep___noteNotification_list from './endpoints/note-notification/list.js'; import * as ep___my_apps from './endpoints/my/apps.js'; import * as ep___notes from './endpoints/notes.js'; import * as ep___notes_children from './endpoints/notes/children.js'; @@ -662,9 +659,6 @@ const eps = [ ['renote-mute/create', ep___renoteMute_create], ['renote-mute/delete', ep___renoteMute_delete], ['renote-mute/list', ep___renoteMute_list], - ['note-notification/create', ep___noteNotification_create], - ['note-notification/delete', ep___noteNotification_delete], - ['note-notification/list', ep___noteNotification_list], ['my/apps', ep___my_apps], ['notes', ep___notes], ['notes/children', ep___notes_children], diff --git a/packages/backend/src/server/api/endpoints/following/update.ts b/packages/backend/src/server/api/endpoints/following/update.ts index 7c491e0ca1f8..d62cf210ede0 100644 --- a/packages/backend/src/server/api/endpoints/following/update.ts +++ b/packages/backend/src/server/api/endpoints/following/update.ts @@ -6,12 +6,9 @@ import ms from 'ms'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { FollowingsRepository, NoteNotificationsRepository } from '@/models/_.js'; +import type { FollowingsRepository } from '@/models/_.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { UserFollowingService } from '@/core/UserFollowingService.js'; -import { IdService } from '@/core/IdService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { UserBlockingService } from '@/core/UserBlockingService.js'; import { DI } from '@/di-symbols.js'; import { GetterService } from '@/server/api/GetterService.js'; import { ApiError } from '../../error.js'; @@ -46,30 +43,6 @@ export const meta = { code: 'NOT_FOLLOWING', id: 'b8dc75cf-1cb5-46c9-b14b-5f1ffbd782c9', }, - - alreadySubscribing: { - message: 'You are already subscribing that user.', - code: 'ALREADY_SUBSCRIBING', - id: 'd27c40c9-549b-4590-8df1-871da27076cf', - }, - - alreadyUnsubscribed: { - message: 'You are already unsubscribed that user.', - code: 'ALREADY_UNSUBSCRIBED', - id: '158fca64-5c92-4b22-b8b1-93dbe4bcfe60', - }, - - blocking: { - message: 'You are blocking that user.', - code: 'BLOCKING', - id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9', - }, - - blocked: { - message: 'You are blocked by that user.', - code: 'BLOCKED', - id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0', - }, }, res: { @@ -94,15 +67,10 @@ export default class extends Endpoint { // eslint- constructor( @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, - @Inject(DI.noteNotificationsRepository) - private noteNotificationRepository: NoteNotificationsRepository, private userEntityService: UserEntityService, private getterService: GetterService, private userFollowingService: UserFollowingService, - private userBlockingService: UserBlockingService, - private idService: IdService, - private globalEventService: GlobalEventService, ) { super(meta, paramDef, async (ps, me) => { const follower = me; @@ -112,78 +80,28 @@ export default class extends Endpoint { // eslint- throw new ApiError(meta.errors.followeeIsYourself); } - // Get target user - const target = await this.getterService.getUser(ps.userId).catch(err => { + // Get followee + const followee = await this.getterService.getUser(ps.userId).catch(err => { if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); throw err; }); - // Find and update followingsRepository + // Check not following const exist = await this.followingsRepository.findOneBy({ followerId: follower.id, - followeeId: target.id, + followeeId: followee.id, }); - if (exist) { - await this.followingsRepository.update({ - id: exist.id, - }, { - notify: ps.notify != null ? (ps.notify === 'none' ? null : ps.notify) : undefined, - withReplies: ps.withReplies ?? undefined, - }); + if (exist == null) { + throw new ApiError(meta.errors.notFollowing); } - // To subscribe - if (ps.notify === 'normal') { - // Check if already subscribing - const exist = await this.noteNotificationRepository.findOneBy({ - userId: me.id, - targetUserId: target.id, - }); - - if (exist != null) { - throw new ApiError(meta.errors.alreadySubscribing); - } - - // Check if blocking - if (await this.userBlockingService.checkBlocked(me.id, target.id)) { - throw new ApiError(meta.errors.blocking); - } - - // Check if blocked - if (await this.userBlockingService.checkBlocked(target.id, me.id)) { - throw new ApiError(meta.errors.blocked); - } - - // Create - const noteNotification = await this.noteNotificationRepository.insert({ - id: this.idService.gen(), - userId: me.id, - targetUserId: target.id, - }).then(x => this.noteNotificationRepository.findOneByOrFail(x.identifiers[0])); - - // Publish event - this.globalEventService.publishInternalEvent('noteNotificationCreated', noteNotification); - } else { - // Check if already unsubscribed - const noteNotification = await this.noteNotificationRepository.findOneBy({ - userId: me.id, - targetUserId: target.id, - }); - - if (!noteNotification) { - throw new ApiError(meta.errors.alreadyUnsubscribed); - } - - // Delete - await this.noteNotificationRepository.delete({ - userId: me.id, - targetUserId: target.id, - }); - - // Publish event - this.globalEventService.publishInternalEvent('noteNotificationDeleted', noteNotification); - } + await this.followingsRepository.update({ + id: exist.id, + }, { + notify: ps.notify != null ? (ps.notify === 'none' ? null : ps.notify) : undefined, + withReplies: ps.withReplies != null ? ps.withReplies : undefined, + }); return await this.userEntityService.pack(follower.id, me); }); diff --git a/packages/backend/src/server/api/endpoints/note-notification/create.ts b/packages/backend/src/server/api/endpoints/note-notification/create.ts deleted file mode 100644 index 7bf88c03397a..000000000000 --- a/packages/backend/src/server/api/endpoints/note-notification/create.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { NoteNotificationsRepository } from '@/models/_.js'; -import { IdService } from '@/core/IdService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { UserBlockingService } from '@/core/UserBlockingService.js'; -import { DI } from '@/di-symbols.js'; -import { GetterService } from '@/server/api/GetterService.js'; -import { ApiError } from '../../error.js'; - -export const meta = { - tags: ['users'], - - limit: { - duration: ms('1hour'), - max: 100, - }, - - requireCredential: true, - requireAdmin: false, - kind: 'write:account', - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5', - }, - - subscribeYourself: { - message: 'Can\'t subscribe yourself.', - code: 'CANT_SUBSCRIBE_YOURSELF', - id: '1d1ad949-15cc-4896-803d-3410f716f88b', - }, - - alreadySubscribing: { - message: 'You are already subscribing that user.', - code: 'ALREADY_SUBSCRIBING', - id: 'd27c40c9-549b-4590-8df1-871da27076cf', - }, - - blocking: { - message: 'You are blocking that user.', - code: 'BLOCKING', - id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9', - }, - - blocked: { - message: 'You are blocked by that user.', - code: 'BLOCKED', - id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.noteNotificationsRepository) - private noteNotificationRepository: NoteNotificationsRepository, - - private getterService: GetterService, - private userBlockingService: UserBlockingService, - private idService: IdService, - private globalEventService: GlobalEventService, - ) { - super(meta, paramDef, async (ps, me) => { - // 自分自身 - if (me.id === ps.userId) { - throw new ApiError(meta.errors.subscribeYourself); - } - - // Get target user - const target = await this.getterService.getUser(ps.userId).catch(err => { - if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw err; - }); - - // Check if already subscribing - const exist = await this.noteNotificationRepository.findOneBy({ - userId: me.id, - targetUserId: target.id, - }); - - if (exist != null) { - throw new ApiError(meta.errors.alreadySubscribing); - } - - // Check if blocking - if (await this.userBlockingService.checkBlocked(me.id, target.id)) { - throw new ApiError(meta.errors.blocking); - } - - // Check if blocked - if (await this.userBlockingService.checkBlocked(target.id, me.id)) { - throw new ApiError(meta.errors.blocked); - } - - // Create - const noteNotification = await this.noteNotificationRepository.insert({ - id: this.idService.gen(), - userId: me.id, - targetUserId: target.id, - }).then(x => this.noteNotificationRepository.findOneByOrFail(x.identifiers[0])); - - // Publish event - this.globalEventService.publishInternalEvent('noteNotificationCreated', noteNotification); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/note-notification/delete.ts b/packages/backend/src/server/api/endpoints/note-notification/delete.ts deleted file mode 100644 index c309043e7363..000000000000 --- a/packages/backend/src/server/api/endpoints/note-notification/delete.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import ms from 'ms'; -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { NoteNotificationsRepository } from '@/models/_.js'; -import { DI } from '@/di-symbols.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { GetterService } from '@/server/api/GetterService.js'; -import { ApiError } from '../../error.js'; - -export const meta = { - tags: ['users'], - - limit: { - duration: ms('1hour'), - max: 100, - }, - - requireCredential: true, - kind: 'write:account', - - errors: { - noSuchUser: { - message: 'No such user.', - code: 'NO_SUCH_USER', - id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5', - }, - - unsubscribeYourself: { - message: 'Can\'t unsubscribe yourself.', - code: 'CANT_UNSUBSCRIBE_YOURSELF', - id: '079e2610-d53a-41a8-a15a-ed60a178d9a8', - }, - - alreadyUnsubscribed: { - message: 'You are already unsubscribed that user.', - code: 'ALREADY_UNSUBSCRIBED', - id: '158fca64-5c92-4b22-b8b1-93dbe4bcfe60', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - userId: { type: 'string', format: 'misskey:id' }, - }, - required: ['userId'], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.noteNotificationsRepository) - private noteNotificationRepository: NoteNotificationsRepository, - - private getterService: GetterService, - private globalEventService: GlobalEventService, - ) { - super(meta, paramDef, async (ps, me) => { - // 自分自身 - if (me.id === ps.userId) { - throw new ApiError(meta.errors.unsubscribeYourself); - } - - // Get target user - const target = await this.getterService.getUser(ps.userId).catch(err => { - if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); - throw err; - }); - - // Check if already unsubscribed - const noteNotification = await this.noteNotificationRepository.findOneBy({ - userId: me.id, - targetUserId: target.id, - }); - - if (!noteNotification) { - throw new ApiError(meta.errors.alreadyUnsubscribed); - } - - // Delete - await this.noteNotificationRepository.delete({ - userId: me.id, - targetUserId: target.id, - }); - - // Publish event - this.globalEventService.publishInternalEvent('noteNotificationDeleted', noteNotification); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/note-notification/list.ts b/packages/backend/src/server/api/endpoints/note-notification/list.ts deleted file mode 100644 index 0ba7b59861c0..000000000000 --- a/packages/backend/src/server/api/endpoints/note-notification/list.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-FileCopyrightText: yukineko and tai-cat - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Inject, Injectable } from '@nestjs/common'; -import { Endpoint } from '@/server/api/endpoint-base.js'; -import type { NoteNotificationsRepository } from '@/models/_.js'; -import { QueryService } from '@/core/QueryService.js'; -import { NoteNotificationEntityService } from '@/core/entities/NoteNotificationEntityService.js'; -import { DI } from '@/di-symbols.js'; - -export const meta = { - tags: ['users'], - - requireCredential: true, - kind: 'write:account', - - res: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - ref: 'NoteNotification', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - limit: { type: 'integer', minimum: 1, maximum: 100, default: 30 }, - sinceId: { type: 'string', format: 'misskey:id' }, - untilId: { type: 'string', format: 'misskey:id' }, - }, - required: [], -} as const; - -// eslint-disable-next-line import/no-default-export -@Injectable() -export default class extends Endpoint { - constructor( - @Inject(DI.noteNotificationsRepository) - private noteNotificationsRepository: NoteNotificationsRepository, - - private noteNotificationEntityService: NoteNotificationEntityService, - private queryService: QueryService, - ) { - super(meta, paramDef, async (ps, me) => { - const query = this.queryService.makePaginationQuery(this.noteNotificationsRepository.createQueryBuilder('notification'), ps.sinceId, ps.untilId) - .andWhere('notification.userId = :meId', { meId: me.id }); - - const targets = await query - .take(ps.limit) - .getMany(); - - return await this.noteNotificationEntityService.packMany(targets, me); - }); - } -} diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index f191b2d7c4a9..2a2c6599427d 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -47,7 +47,7 @@ export const meta = { bothWithRepliesAndWithFiles: { message: 'Specifying both withReplies and withFiles is not supported', code: 'BOTH_WITH_REPLIES_AND_WITH_FILES', - id: 'dfaa3eb7-8002-4cb7-bcc4-1095df46656f', + id: 'dfaa3eb7-8002-4cb7-bcc4-1095df46656f' }, }, } as const; @@ -67,7 +67,6 @@ export const paramDef = { withFiles: { type: 'boolean', default: false }, withRenotes: { type: 'boolean', default: true }, withReplies: { type: 'boolean', default: false }, - onlyLocal: { type: 'boolean', default: false }, }, required: [], } as const; @@ -114,7 +113,6 @@ export default class extends Endpoint { // eslint- includeLocalRenotes: ps.includeLocalRenotes, withFiles: ps.withFiles, withReplies: ps.withReplies, - onlyLocal: ps.onlyLocal, }, me); process.nextTick(() => { @@ -161,15 +159,11 @@ export default class extends Endpoint { // eslint- useDbFallback: serverSettings.enableFanoutTimelineDbFallback, alwaysIncludeMyNotes: true, excludePureRenotes: !ps.withRenotes, - noteFilter: (note) => { + noteFilter: note => { if (note.reply && note.reply.visibility === 'followers') { if (!Object.hasOwn(followings, note.reply.userId) && note.reply.userId !== me.id) return false; } - if (ps.onlyLocal && note.user?.host != null ) { - return false; - } - return true; }, dbFallback: async (untilId, sinceId, limit) => await this.getFromDb({ @@ -181,7 +175,6 @@ export default class extends Endpoint { // eslint- includeLocalRenotes: ps.includeLocalRenotes, withFiles: ps.withFiles, withReplies: ps.withReplies, - onlyLocal: ps.onlyLocal, }, me), }); @@ -202,7 +195,6 @@ export default class extends Endpoint { // eslint- includeLocalRenotes: boolean, withFiles: boolean, withReplies: boolean, - onlyLocal: boolean, }, me: MiLocalUser) { const followees = await this.userFollowingService.getFollowees(me.id); const followingChannels = await this.channelFollowingsRepository.find({ @@ -289,10 +281,6 @@ export default class extends Endpoint { // eslint- if (ps.withFiles) { query.andWhere('note.fileIds != \'{}\''); } - - if (ps.onlyLocal) { - query.andWhere('note.userHost IS NULL'); - } //#endregion return await query.limit(ps.limit).getMany(); diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 23fdf3269331..c9b43b535937 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -49,7 +49,6 @@ export const paramDef = { includeLocalRenotes: { type: 'boolean', default: true }, withFiles: { type: 'boolean', default: false }, withRenotes: { type: 'boolean', default: true }, - onlyLocal: { type: 'boolean', default: false }, }, required: [], } as const; @@ -88,7 +87,6 @@ export default class extends Endpoint { // eslint- includeLocalRenotes: ps.includeLocalRenotes, withFiles: ps.withFiles, withRenotes: ps.withRenotes, - onlyLocal: ps.onlyLocal, }, me); process.nextTick(() => { @@ -119,10 +117,6 @@ export default class extends Endpoint { // eslint- if (!Object.hasOwn(followings, note.reply.userId) && note.reply.userId !== me.id) return false; } - if (ps.onlyLocal && note.user?.host != null ) { - return false; - } - return true; }, dbFallback: async (untilId, sinceId, limit) => await this.getFromDb({ @@ -134,7 +128,6 @@ export default class extends Endpoint { // eslint- includeLocalRenotes: ps.includeLocalRenotes, withFiles: ps.withFiles, withRenotes: ps.withRenotes, - onlyLocal: ps.onlyLocal, }, me), }); @@ -146,7 +139,7 @@ export default class extends Endpoint { // eslint- }); } - private async getFromDb(ps: { untilId: string | null; sinceId: string | null; limit: number; includeMyRenotes: boolean; includeRenotedMyNotes: boolean; includeLocalRenotes: boolean; withFiles: boolean; withRenotes: boolean; onlyLocal: boolean; }, me: MiLocalUser) { + private async getFromDb(ps: { untilId: string | null; sinceId: string | null; limit: number; includeMyRenotes: boolean; includeRenotedMyNotes: boolean; includeLocalRenotes: boolean; withFiles: boolean; withRenotes: boolean; }, me: MiLocalUser) { const followees = await this.userFollowingService.getFollowees(me.id); const followingChannels = await this.channelFollowingsRepository.find({ where: { @@ -248,10 +241,6 @@ export default class extends Endpoint { // eslint- if (ps.withRenotes === false) { query.andWhere('note.renoteId IS NULL'); } - - if (ps.onlyLocal) { - query.andWhere('note.userHost IS NULL'); - } //#endregion return await query.limit(ps.limit).getMany(); diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index e3831f22a7aa..61fd7599322a 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -102,7 +102,6 @@ describe('ユーザー', () => { isBlocking: user.isBlocking ?? false, isBlocked: user.isBlocked ?? false, isMuted: user.isMuted ?? false, - isNoteSubscribing: user.isNoteSubscribing ?? false, isRenoteMuted: user.isRenoteMuted ?? false, notify: user.notify ?? 'none', withReplies: user.withReplies ?? false, diff --git a/packages/frontend/src/components/MkCwButton.vue b/packages/frontend/src/components/MkCwButton.vue index 0a1b2d941b06..b5f6e78b6c71 100644 --- a/packages/frontend/src/components/MkCwButton.vue +++ b/packages/frontend/src/components/MkCwButton.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only --> diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue index a0ba94fbc1fa..70db6a510964 100644 --- a/packages/frontend/src/pages/settings/notifications.vue +++ b/packages/frontend/src/pages/settings/notifications.vue @@ -26,7 +26,6 @@ SPDX-License-Identifier: AGPL-3.0-only - {{ i18n.ts.noteNotification }}
{{ i18n.ts.markAsReadAllNotifications }} diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 13db852e6a4e..d418be624ef2 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -43,10 +43,6 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.makeExplorable }} - - - -
@@ -103,7 +99,6 @@ const defaultNoteVisibility = computed(defaultStore.makeGetterSetter('defaultNot const defaultNoteLocalOnly = computed(defaultStore.makeGetterSetter('defaultNoteLocalOnly')); const rememberNoteVisibility = computed(defaultStore.makeGetterSetter('rememberNoteVisibility')); const keepCw = computed(defaultStore.makeGetterSetter('keepCw')); -const keepOriginalFilename = computed(defaultStore.makeGetterSetter('keepOriginalFilename')); function save() { misskeyApi('i/update', { diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 1aaebad710a4..32f6dd0e5a6c 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -23,7 +23,6 @@ SPDX-License-Identifier: AGPL-3.0-only :withRenotes="withRenotes" :withReplies="withReplies" :onlyFiles="onlyFiles" - :onlyLocal="onlyLocal" :sound="true" @queue="queueUpdated" /> @@ -53,7 +52,7 @@ import { deviceKind } from '@/scripts/device-kind.js'; import { deepMerge } from '@/scripts/merge.js'; import { MenuItem } from '@/types/menu.js'; import { miLocalStorage } from '@/local-storage.js'; -import { availableBasicTimelines, hasWithReplies, isAvailableBasicTimeline, isBasicTimeline, basicTimelineIconClass, hasLocalOnly } from '@/timelines.js'; +import { availableBasicTimelines, hasWithReplies, isAvailableBasicTimeline, isBasicTimeline, basicTimelineIconClass } from '@/timelines.js'; provide('shouldOmitHeaderTitle', true); @@ -115,11 +114,6 @@ const withSensitive = computed({ set: (x) => saveTlFilter('withSensitive', x), }); -const onlyLocal = computed({ - get: () => defaultStore.reactiveState.tl.value.filter.onlyLocal, - set: (x) => saveTlFilter('onlyLocal', x), -}); - watch(src, () => { queue.value = 0; }); @@ -266,11 +260,7 @@ const headerActions = computed(() => { text: i18n.ts.fileAttachedOnly, ref: onlyFiles, disabled: isBasicTimeline(src.value) && hasWithReplies(src.value) ? withReplies : false, - }, isBasicTimeline(src.value) && hasLocalOnly(src.value) ? { - type: 'switch', - text: i18n.ts.localOnly, - ref: onlyLocal, - } : undefined], ev.currentTarget ?? ev.target); + }], ev.currentTarget ?? ev.target); }, }, ]; diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 0f3bd361391f..437314074a0c 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -132,10 +132,6 @@ export const defaultStore = markRaw(new Storage('base', { where: 'account', default: [] as string[], }, - showLocalTimelineBelowPublic: { - where: 'account', - default: false, - }, menu: { where: 'deviceAccount', @@ -194,7 +190,6 @@ export const defaultStore = markRaw(new Storage('base', { withRenotes: true, withSensitive: true, onlyFiles: false, - onlyLocal: false, }, }, }, diff --git a/packages/frontend/src/timelines.ts b/packages/frontend/src/timelines.ts index 47dcd10b1aee..94eda3545e1f 100644 --- a/packages/frontend/src/timelines.ts +++ b/packages/frontend/src/timelines.ts @@ -54,7 +54,3 @@ export function availableBasicTimelines(): BasicTimelineType[] { export function hasWithReplies(timeline: BasicTimelineType | undefined | null): boolean { return timeline === 'local' || timeline === 'social'; } - -export function hasLocalOnly(timeline: BasicTimelineType | undefined | null): boolean { - return timeline === 'home' || timeline === 'social'; -} diff --git a/packages/frontend/src/ui/deck/deck-store.ts b/packages/frontend/src/ui/deck/deck-store.ts index 14cfa284e77a..eb587554b97c 100644 --- a/packages/frontend/src/ui/deck/deck-store.ts +++ b/packages/frontend/src/ui/deck/deck-store.ts @@ -50,7 +50,6 @@ export type Column = { withRenotes?: boolean; withReplies?: boolean; onlyFiles?: boolean; - onlyLocal?: boolean; soundSetting: SoundStore; }; diff --git a/packages/frontend/src/ui/deck/tl-column.vue b/packages/frontend/src/ui/deck/tl-column.vue index 765fa9c99d0d..e210ee7b7a2c 100644 --- a/packages/frontend/src/ui/deck/tl-column.vue +++ b/packages/frontend/src/ui/deck/tl-column.vue @@ -20,12 +20,11 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -39,7 +38,7 @@ import type { MenuItem } from '@/types/menu.js'; import MkTimeline from '@/components/MkTimeline.vue'; import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; -import { hasWithReplies, isAvailableBasicTimeline, basicTimelineIconClass, hasLocalOnly } from '@/timelines.js'; +import { hasWithReplies, isAvailableBasicTimeline, basicTimelineIconClass } from '@/timelines.js'; import { instance } from '@/instance.js'; import { SoundStore } from '@/store.js'; import { soundSettingsButton } from '@/ui/deck/tl-note-notification.js'; @@ -56,7 +55,6 @@ const soundSetting = ref(props.column.soundSetting ?? { type: null, const withRenotes = ref(props.column.withRenotes ?? true); const withReplies = ref(props.column.withReplies ?? false); const onlyFiles = ref(props.column.onlyFiles ?? false); -const onlyLocal = ref(props.column.onlyLocal ?? false); watch(withRenotes, v => { updateColumn(props.column.id, { @@ -76,12 +74,6 @@ watch(onlyFiles, v => { }); }); -watch(onlyLocal, v => { - updateColumn(props.column.id, { - onlyLocal: v, - }); -}); - watch(soundSetting, v => { updateColumn(props.column.id, { soundSetting: v }); }); @@ -143,11 +135,7 @@ const menu = computed(() => [{ text: i18n.ts.fileAttachedOnly, ref: onlyFiles, disabled: hasWithReplies(props.column.tl) ? withReplies : false, -}, hasLocalOnly(props.column.tl) ? { - type: 'switch', - text: i18n.ts.localOnly, - ref: onlyLocal, -} : undefined]); +}]);