すべてのフォロー中の人のwithRepliesを変える機能 (#12049)

* feat: endpoint to update all following

* feat(frontend): change show replies for all

* docs(changelog): すでにフォローしたすべての人の返信をTLに追加できるように

* fix: cancel not working
This commit is contained in:
anatawa12 2023-10-21 18:39:19 +09:00 committed by GitHub
parent 12fe09c6e7
commit 722584bf72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 0 deletions

View file

@ -22,6 +22,7 @@
- Enhance: フォロー/フォロー解除したときに過去分のHTLにも含まれる投稿が反映されるように - Enhance: フォロー/フォロー解除したときに過去分のHTLにも含まれる投稿が反映されるように
- Enhance: ローカリゼーションの更新 - Enhance: ローカリゼーションの更新
- Enhance: 依存関係の更新 - Enhance: 依存関係の更新
- Enhance: すでにフォローしたすべての人の返信をTLに追加できるように
### Client ### Client
- Enhance: TLの返信表示オプションを記憶するように - Enhance: TLの返信表示オプションを記憶するように

4
locales/index.d.ts vendored
View file

@ -1135,6 +1135,10 @@ export interface Locale {
"fileAttachedOnly": string; "fileAttachedOnly": string;
"showRepliesToOthersInTimeline": string; "showRepliesToOthersInTimeline": string;
"hideRepliesToOthersInTimeline": string; "hideRepliesToOthersInTimeline": string;
"showRepliesToOthersInTimelineAll": string;
"hideRepliesToOthersInTimelineAll": string;
"confirmShowRepliesAll": string;
"confirmHideRepliesAll": string;
"externalServices": string; "externalServices": string;
"impressum": string; "impressum": string;
"impressumUrl": string; "impressumUrl": string;

View file

@ -1132,6 +1132,10 @@ mutualFollow: "相互フォロー"
fileAttachedOnly: "ファイル付きのみ" fileAttachedOnly: "ファイル付きのみ"
showRepliesToOthersInTimeline: "TLに他の人への返信を含める" showRepliesToOthersInTimeline: "TLに他の人への返信を含める"
hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない" hideRepliesToOthersInTimeline: "TLに他の人への返信を含めない"
showRepliesToOthersInTimelineAll: "TLに現在フォロー中の人全員の返信を含めるようにする"
hideRepliesToOthersInTimelineAll: "TLに現在フォロー中の人全員の返信を含めないようにする"
confirmShowRepliesAll: "この操作は元の戻せません。本当にTLに現在フォロー中の人全員の返信を含めるようにしますか"
confirmHideRepliesAll: "この操作は元の戻せません。本当にTLに現在フォロー中の人全員の返信を含めないようにしますか"
externalServices: "外部サービス" externalServices: "外部サービス"
impressum: "運営者情報" impressum: "運営者情報"
impressumUrl: "運営者情報URL" impressumUrl: "運営者情報URL"

View file

@ -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_create from './endpoints/following/create.js';
import * as ep___following_delete from './endpoints/following/delete.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 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_invalidate from './endpoints/following/invalidate.js';
import * as ep___following_requests_accept from './endpoints/following/requests/accept.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'; 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_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_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: 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_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_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 }; 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_create,
$following_delete, $following_delete,
$following_update, $following_update,
$following_update_all,
$following_invalidate, $following_invalidate,
$following_requests_accept, $following_requests_accept,
$following_requests_cancel, $following_requests_cancel,
@ -1232,6 +1235,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$following_create, $following_create,
$following_delete, $following_delete,
$following_update, $following_update,
$following_update_all,
$following_invalidate, $following_invalidate,
$following_requests_accept, $following_requests_accept,
$following_requests_cancel, $following_requests_cancel,

View file

@ -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_create from './endpoints/following/create.js';
import * as ep___following_delete from './endpoints/following/delete.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 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_invalidate from './endpoints/following/invalidate.js';
import * as ep___following_requests_accept from './endpoints/following/requests/accept.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'; import * as ep___following_requests_cancel from './endpoints/following/requests/cancel.js';
@ -518,6 +519,7 @@ const eps = [
['following/create', ep___following_create], ['following/create', ep___following_create],
['following/delete', ep___following_delete], ['following/delete', ep___following_delete],
['following/update', ep___following_update], ['following/update', ep___following_update],
['following/update-all', ep___following_update_all],
['following/invalidate', ep___following_invalidate], ['following/invalidate', ep___following_invalidate],
['following/requests/accept', ep___following_requests_accept], ['following/requests/accept', ep___following_requests_accept],
['following/requests/cancel', ep___following_requests_cancel], ['following/requests/cancel', ep___following_requests_cancel],

View file

@ -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<typeof meta, typeof paramDef> { // 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;
});
}
}

View file

@ -30,6 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="showFixedPostForm">{{ i18n.ts.showFixedPostForm }}</MkSwitch> <MkSwitch v-model="showFixedPostForm">{{ i18n.ts.showFixedPostForm }}</MkSwitch>
<MkSwitch v-model="showFixedPostFormInChannel">{{ i18n.ts.showFixedPostFormInChannel }}</MkSwitch> <MkSwitch v-model="showFixedPostFormInChannel">{{ i18n.ts.showFixedPostFormInChannel }}</MkSwitch>
<MkSwitch v-model="defaultWithReplies">{{ i18n.ts.withRepliesByDefaultForNewlyFollowed }}</MkSwitch> <MkSwitch v-model="defaultWithReplies">{{ i18n.ts.withRepliesByDefaultForNewlyFollowed }}</MkSwitch>
<MkButton danger @click="updateRepliesAll(true)"><i class="ti ti-messages"></i> {{ i18n.ts.showRepliesToOthersInTimelineAll }}</MkButton>
<MkButton danger @click="updateRepliesAll(false)"><i class="ti ti-messages-off"></i> {{ i18n.ts.hideRepliesToOthersInTimelineAll }}</MkButton>
<MkFolder> <MkFolder>
<template #label>{{ i18n.ts.pinnedList }}</template> <template #label>{{ i18n.ts.pinnedList }}</template>
<!-- 複数ピン止め管理できるようにしたいけどめんどいので一旦ひとつのみ --> <!-- 複数ピン止め管理できるようにしたいけどめんどいので一旦ひとつのみ -->
@ -332,6 +334,15 @@ async function setPinnedList() {
defaultStore.set('pinnedUserLists', [list]); 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() { function removePinnedList() {
defaultStore.set('pinnedUserLists', []); defaultStore.set('pinnedUserLists', []);
} }