diff --git a/CHANGELOG.md b/CHANGELOG.md index 6171569604..d06efad1ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Enhance: フォロー/フォロー解除したときに過去分のHTLにも含まれる投稿が反映されるように - Enhance: ローカリゼーションの更新 - Enhance: 依存関係の更新 +- Enhance: すでにフォローしたすべての人の返信をTLに追加できるように ### Client - Enhance: TLの返信表示オプションを記憶するように diff --git a/locales/index.d.ts b/locales/index.d.ts index 11be41235a..d31ac0a9b2 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1135,6 +1135,10 @@ export interface Locale { "fileAttachedOnly": string; "showRepliesToOthersInTimeline": string; "hideRepliesToOthersInTimeline": string; + "showRepliesToOthersInTimelineAll": string; + "hideRepliesToOthersInTimelineAll": string; + "confirmShowRepliesAll": string; + "confirmHideRepliesAll": string; "externalServices": string; "impressum": string; "impressumUrl": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 11b0833928..a63c698bb9 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1132,6 +1132,10 @@ mutualFollow: "相互フォロー" fileAttachedOnly: "ファイル付きのみ" showRepliesToOthersInTimeline: "TLに他の人への返信を含める" hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない" +showRepliesToOthersInTimelineAll: "TLに現在フォロー中の人全員の返信を含めるようにする" +hideRepliesToOthersInTimelineAll: "TLに現在フォロー中の人全員の返信を含めないようにする" +confirmShowRepliesAll: "この操作は元の戻せません。本当にTLに現在フォロー中の人全員の返信を含めるようにしますか" +confirmHideRepliesAll: "この操作は元の戻せません。本当にTLに現在フォロー中の人全員の返信を含めないようにしますか" externalServices: "外部サービス" impressum: "運営者情報" impressumUrl: "運営者情報URL" diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index f234a2637d..ab0e4c6273 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -165,6 +165,7 @@ import * as ep___federation_stats from './endpoints/federation/stats.js'; import * as ep___following_create from './endpoints/following/create.js'; import * as ep___following_delete from './endpoints/following/delete.js'; import * as ep___following_update from './endpoints/following/update.js'; +import * as ep___following_update_all from './endpoints/following/update-all.js'; import * as ep___following_invalidate from './endpoints/following/invalidate.js'; import * as ep___following_requests_accept from './endpoints/following/requests/accept.js'; import * as ep___following_requests_cancel from './endpoints/following/requests/cancel.js'; @@ -520,6 +521,7 @@ const $federation_stats: Provider = { provide: 'ep:federation/stats', useClass: const $following_create: Provider = { provide: 'ep:following/create', useClass: ep___following_create.default }; const $following_delete: Provider = { provide: 'ep:following/delete', useClass: ep___following_delete.default }; const $following_update: Provider = { provide: 'ep:following/update', useClass: ep___following_update.default }; +const $following_update_all: Provider = { provide: 'ep:following/update-all', useClass: ep___following_update_all.default }; const $following_invalidate: Provider = { provide: 'ep:following/invalidate', useClass: ep___following_invalidate.default }; const $following_requests_accept: Provider = { provide: 'ep:following/requests/accept', useClass: ep___following_requests_accept.default }; const $following_requests_cancel: Provider = { provide: 'ep:following/requests/cancel', useClass: ep___following_requests_cancel.default }; @@ -879,6 +881,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $following_create, $following_delete, $following_update, + $following_update_all, $following_invalidate, $following_requests_accept, $following_requests_cancel, @@ -1232,6 +1235,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $following_create, $following_delete, $following_update, + $following_update_all, $following_invalidate, $following_requests_accept, $following_requests_cancel, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 8d34edca9d..79e62672fa 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -165,6 +165,7 @@ import * as ep___federation_stats from './endpoints/federation/stats.js'; import * as ep___following_create from './endpoints/following/create.js'; import * as ep___following_delete from './endpoints/following/delete.js'; import * as ep___following_update from './endpoints/following/update.js'; +import * as ep___following_update_all from './endpoints/following/update-all.js'; import * as ep___following_invalidate from './endpoints/following/invalidate.js'; import * as ep___following_requests_accept from './endpoints/following/requests/accept.js'; import * as ep___following_requests_cancel from './endpoints/following/requests/cancel.js'; @@ -518,6 +519,7 @@ const eps = [ ['following/create', ep___following_create], ['following/delete', ep___following_delete], ['following/update', ep___following_update], + ['following/update-all', ep___following_update_all], ['following/invalidate', ep___following_invalidate], ['following/requests/accept', ep___following_requests_accept], ['following/requests/cancel', ep___following_requests_cancel], diff --git a/packages/backend/src/server/api/endpoints/following/update-all.ts b/packages/backend/src/server/api/endpoints/following/update-all.ts new file mode 100644 index 0000000000..28734cfdbd --- /dev/null +++ b/packages/backend/src/server/api/endpoints/following/update-all.ts @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * 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 { FollowingsRepository } from '@/models/_.js'; +import { UserEntityService } from '@/core/entities/UserEntityService.js'; +import { UserFollowingService } from '@/core/UserFollowingService.js'; +import { DI } from '@/di-symbols.js'; +import { GetterService } from '@/server/api/GetterService.js'; +import { ApiError } from '../../error.js'; + +export const meta = { + tags: ['following', 'users'], + + limit: { + duration: ms('1hour'), + max: 10, + }, + + requireCredential: true, + + kind: 'write:following', +} as const; + +export const paramDef = { + type: 'object', + properties: { + notify: { type: 'string', enum: ['normal', 'none'] }, + withReplies: { type: 'boolean' }, + }, +} as const; + +@Injectable() +export default class extends Endpoint { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.followingsRepository) + private followingsRepository: FollowingsRepository, + ) { + super(meta, paramDef, async (ps, me) => { + await this.followingsRepository.update({ + followerId: me.id, + }, { + notify: ps.notify != null ? (ps.notify === 'none' ? null : ps.notify) : undefined, + withReplies: ps.withReplies != null ? ps.withReplies : undefined, + }); + + return; + }); + } +} diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 30443fded6..f186cf2ae3 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -30,6 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.showFixedPostForm }} {{ i18n.ts.showFixedPostFormInChannel }} {{ i18n.ts.withRepliesByDefaultForNewlyFollowed }} + {{ i18n.ts.showRepliesToOthersInTimelineAll }} + {{ i18n.ts.hideRepliesToOthersInTimelineAll }} @@ -332,6 +334,15 @@ async function setPinnedList() { defaultStore.set('pinnedUserLists', [list]); } +async function updateRepliesAll(withReplies: boolean) { + const { canceled } = os.confirm({ + type: 'warning', + text: withReplies ? i18n.ts.confirmShowRepliesAll : i18n.ts.confirmHideRepliesAll, + }); + if (canceled) return; + await os.api('following/update-all', { withReplies }); +} + function removePinnedList() { defaultStore.set('pinnedUserLists', []); }