diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2024-10-14 15:52:02 +0000 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2024-10-14 15:52:02 +0000 |
| commit | b15f25758a2b33aa9b9136f005c805617a2f650a (patch) | |
| tree | 1c9c375ab2743a339ee8b8b7b80a7839fd3e4434 | |
| parent | merge: try to avoid `insert` races in `FederatedInstanceService` (!683) (diff) | |
| parent | restore missing hasPendingReceivedFollowRequest in navbar (diff) | |
| download | sharkey-b15f25758a2b33aa9b9136f005c805617a2f650a.tar.gz sharkey-b15f25758a2b33aa9b9136f005c805617a2f650a.tar.bz2 sharkey-b15f25758a2b33aa9b9136f005c805617a2f650a.zip | |
merge: feat: Allow users to view pending follow requests they sent (!663)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663
Approved-by: Hazelnoot <acomputerdog@gmail.com>
Approved-by: Marie <github@yuugi.dev>
| -rw-r--r-- | locales/en-US.yml | 1 | ||||
| -rw-r--r-- | packages/backend/src/core/entities/UserEntityService.ts | 8 | ||||
| -rw-r--r-- | packages/backend/src/models/json-schema/user.ts | 4 | ||||
| -rw-r--r-- | packages/backend/src/server/api/EndpointsModule.ts | 3 | ||||
| -rw-r--r-- | packages/backend/src/server/api/endpoints.ts | 2 | ||||
| -rw-r--r-- | packages/backend/src/server/api/endpoints/following/requests/sent.ts | 77 | ||||
| -rw-r--r-- | packages/backend/test/e2e/users.ts | 4 | ||||
| -rw-r--r-- | packages/frontend/src/navbar.ts | 2 | ||||
| -rw-r--r-- | packages/frontend/src/pages/follow-requests.vue | 92 | ||||
| -rw-r--r-- | packages/misskey-js/etc/misskey-js.api.md | 8 | ||||
| -rw-r--r-- | packages/misskey-js/src/autogen/apiClientJSDoc.ts | 11 | ||||
| -rw-r--r-- | packages/misskey-js/src/autogen/endpoint.ts | 4 | ||||
| -rw-r--r-- | packages/misskey-js/src/autogen/entities.ts | 2 | ||||
| -rw-r--r-- | packages/misskey-js/src/autogen/types.ts | 73 |
14 files changed, 257 insertions, 34 deletions
diff --git a/locales/en-US.yml b/locales/en-US.yml index 70c06ab326..2fb4700fcf 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -111,6 +111,7 @@ followRequest: "Send follow request" followRequests: "Follow requests" unfollow: "Unfollow" followRequestPending: "Follow request pending" +pendingFollowRequests: "Pending follow requests" enterEmoji: "Enter an emoji" renote: "Boost" unrenote: "Remove boost" diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index d465e2cd4c..fc66f7a507 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -375,6 +375,13 @@ export class UserEntityService implements OnModuleInit { } @bindThis + public async getHasPendingSentFollowRequest(userId: MiUser['id']): Promise<boolean> { + return this.followRequestsRepository.existsBy({ + followerId: userId, + }); + } + + @bindThis public getOnlineStatus(user: MiUser): 'unknown' | 'online' | 'active' | 'offline' { if (user.hideOnlineStatus) return 'unknown'; if (user.lastActiveDate == null) return 'unknown'; @@ -642,6 +649,7 @@ export class UserEntityService implements OnModuleInit { hasUnreadChannel: false, // 後方互換性のため hasUnreadNotification: notificationsInfo?.hasUnread, // 後方互換性のため hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), + hasPendingSentFollowRequest: this.getHasPendingSentFollowRequest(user.id), unreadNotificationsCount: notificationsInfo?.unreadCount, mutedWords: profile!.mutedWords, hardMutedWords: profile!.hardMutedWords, diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts index 24b6c50e93..0eef413759 100644 --- a/packages/backend/src/models/json-schema/user.ts +++ b/packages/backend/src/models/json-schema/user.ts @@ -578,6 +578,10 @@ export const packedMeDetailedOnlySchema = { type: 'boolean', nullable: false, optional: false, }, + hasPendingSentFollowRequest: { + type: 'boolean', + nullable: false, optional: false, + }, unreadNotificationsCount: { type: 'number', nullable: false, optional: false, diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index c90a23d7b5..8434e7e8e3 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -189,6 +189,7 @@ 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'; import * as ep___following_requests_list from './endpoints/following/requests/list.js'; +import * as ep___following_requests_sent from './endpoints/following/requests/sent.js'; import * as ep___following_requests_reject from './endpoints/following/requests/reject.js'; import * as ep___gallery_featured from './endpoints/gallery/featured.js'; import * as ep___gallery_popular from './endpoints/gallery/popular.js'; @@ -586,6 +587,7 @@ const $following_invalidate: Provider = { provide: 'ep:following/invalidate', us 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_list: Provider = { provide: 'ep:following/requests/list', useClass: ep___following_requests_list.default }; +const $following_requests_sent: Provider = { provide: 'ep:following/requests/sent', useClass: ep___following_requests_sent.default }; const $following_requests_reject: Provider = { provide: 'ep:following/requests/reject', useClass: ep___following_requests_reject.default }; const $gallery_featured: Provider = { provide: 'ep:gallery/featured', useClass: ep___gallery_featured.default }; const $gallery_popular: Provider = { provide: 'ep:gallery/popular', useClass: ep___gallery_popular.default }; @@ -987,6 +989,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__ $following_requests_accept, $following_requests_cancel, $following_requests_list, + $following_requests_sent, $following_requests_reject, $gallery_featured, $gallery_popular, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index e93e57f907..bb5c71d78c 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -195,6 +195,7 @@ 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'; import * as ep___following_requests_list from './endpoints/following/requests/list.js'; +import * as ep___following_requests_sent from './endpoints/following/requests/sent.js'; import * as ep___following_requests_reject from './endpoints/following/requests/reject.js'; import * as ep___gallery_featured from './endpoints/gallery/featured.js'; import * as ep___gallery_popular from './endpoints/gallery/popular.js'; @@ -590,6 +591,7 @@ const eps = [ ['following/requests/accept', ep___following_requests_accept], ['following/requests/cancel', ep___following_requests_cancel], ['following/requests/list', ep___following_requests_list], + ['following/requests/sent', ep___following_requests_sent], ['following/requests/reject', ep___following_requests_reject], ['gallery/featured', ep___gallery_featured], ['gallery/popular', ep___gallery_popular], diff --git a/packages/backend/src/server/api/endpoints/following/requests/sent.ts b/packages/backend/src/server/api/endpoints/following/requests/sent.ts new file mode 100644 index 0000000000..6325f01bb8 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/following/requests/sent.ts @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Inject, Injectable } from '@nestjs/common'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { QueryService } from '@/core/QueryService.js'; +import type { FollowRequestsRepository } from '@/models/_.js'; +import { FollowRequestEntityService } from '@/core/entities/FollowRequestEntityService.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['following', 'account'], + + requireCredential: true, + + kind: 'read:following', + + res: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + follower: { + type: 'object', + optional: false, nullable: false, + ref: 'UserLite', + }, + followee: { + type: 'object', + optional: false, nullable: false, + ref: 'UserLite', + }, + }, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + sinceId: { type: 'string', format: 'misskey:id' }, + untilId: { type: 'string', format: 'misskey:id' }, + limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, + }, + required: [], +} as const; + +@Injectable() +export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export + constructor( + @Inject(DI.followRequestsRepository) + private followRequestsRepository: FollowRequestsRepository, + + private followRequestEntityService: FollowRequestEntityService, + private queryService: QueryService, + ) { + super(meta, paramDef, async (ps, me) => { + const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId) + .andWhere('request.followerId = :meId', { meId: me.id }); + + const requests = await query + .limit(ps.limit) + .getMany(); + + return await this.followRequestEntityService.packMany(requests, me); + }); + } +} diff --git a/packages/backend/test/e2e/users.ts b/packages/backend/test/e2e/users.ts index eb56f7bebf..e5057d0489 100644 --- a/packages/backend/test/e2e/users.ts +++ b/packages/backend/test/e2e/users.ts @@ -7,9 +7,9 @@ process.env.NODE_ENV = 'test'; import * as assert from 'assert'; import { inspect } from 'node:util'; -import { DEFAULT_POLICIES } from '@/core/RoleService.js'; import { api, post, role, signup, successfulApiCall, uploadFile } from '../utils.js'; import type * as misskey from 'misskey-js'; +import { DEFAULT_POLICIES } from '@/core/RoleService.js'; describe('ユーザー', () => { // エンティティとしてのユーザーを主眼においたテストを記述する @@ -139,6 +139,7 @@ describe('ユーザー', () => { hasUnreadNotification: user.hasUnreadNotification, unreadNotificationsCount: user.unreadNotificationsCount, hasPendingReceivedFollowRequest: user.hasPendingReceivedFollowRequest, + hasPendingSentFollowRequest: user.hasPendingSentFollowRequest, unreadAnnouncements: user.unreadAnnouncements, mutedWords: user.mutedWords, hardMutedWords: user.hardMutedWords, @@ -378,6 +379,7 @@ describe('ユーザー', () => { assert.strictEqual(response.hasUnreadNotification, false); assert.strictEqual(response.unreadNotificationsCount, 0); assert.strictEqual(response.hasPendingReceivedFollowRequest, false); + assert.strictEqual(response.hasPendingSentFollowRequest, false); assert.deepStrictEqual(response.unreadAnnouncements, []); assert.deepStrictEqual(response.mutedWords, []); assert.deepStrictEqual(response.mutedInstances, []); diff --git a/packages/frontend/src/navbar.ts b/packages/frontend/src/navbar.ts index b6385b5ad2..e545b8ff73 100644 --- a/packages/frontend/src/navbar.ts +++ b/packages/frontend/src/navbar.ts @@ -41,7 +41,7 @@ export const navbarItemDef = reactive({ followRequests: { title: i18n.ts.followRequests, icon: 'ti ti-user-plus', - show: computed(() => $i != null && $i.isLocked), + show: computed(() => $i != null && ($i.isLocked || $i.hasPendingReceivedFollowRequest || $i.hasPendingSentFollowRequest)), indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest), to: '/my/follow-requests', }, diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue index d50887b2e9..400dfdbe6d 100644 --- a/packages/frontend/src/pages/follow-requests.vue +++ b/packages/frontend/src/pages/follow-requests.vue @@ -5,39 +5,43 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkStickyContainer> - <template #header><MkPageHeader/></template> + <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> <MkSpacer :contentMax="800"> - <MkPagination ref="paginationComponent" :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" class="_ghost"/> - <div>{{ i18n.ts.noFollowRequests }}</div> - </div> - </template> - <template #default="{items}"> - <div class="mk-follow-requests"> - <div v-for="req in items" :key="req.id" class="user _panel"> - <MkAvatar class="avatar" :user="req.follower" indicator link preview/> - <div class="body"> - <div class="name"> - <MkA v-user-preview="req.follower.id" class="name" :to="userPage(req.follower)"><MkUserName :user="req.follower"/></MkA> - <p class="acct">@{{ acct(req.follower) }}</p> - </div> - <div class="commands"> - <MkButton class="command" rounded primary @click="accept(req.follower)"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> - <MkButton class="command" rounded danger @click="reject(req.follower)"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> + <MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs"> + <div :key="tab" class="_gaps"> + <MkPagination ref="paginationComponent" :pagination="pagination"> + <template #empty> + <div class="_fullinfo"> + <img :src="infoImageUrl" class="_ghost"/> + <div>{{ i18n.ts.noFollowRequests }}</div> + </div> + </template> + <template #default="{items}"> + <div class="mk-follow-requests"> + <div v-for="req in items" :key="req.id" class="user _panel"> + <MkAvatar class="avatar" :user="displayUser(req)" indicator link preview/> + <div class="body"> + <div class="name"> + <MkA v-user-preview="displayUser(req).id" class="name" :to="userPage(displayUser(req))"><MkUserName :user="displayUser(req)"/></MkA> + <p class="acct">@{{ acct(displayUser(req)) }}</p> + </div> + <div v-if="tab === 'list'" class="commands"> + <MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> + <MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> + </div> + </div> </div> </div> - </div> - </div> - </template> - </MkPagination> + </template> + </MkPagination> + </div> + </MkHorizontalSwipe> </MkSpacer> </MkStickyContainer> </template> <script lang="ts" setup> -import { shallowRef, computed } from 'vue'; +import { shallowRef, computed, ref } from 'vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; import { userPage, acct } from '@/filters/user.js'; @@ -45,29 +49,53 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { infoImageUrl } from '@/instance.js'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; +import { $i } from '@/account'; const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>(); -const pagination = { - endpoint: 'following/requests/list' as const, - limit: 10, -}; +const pagination = computed(() => tab.value === 'list' + ? { + endpoint: 'following/requests/list' as const, + limit: 10, + } + : { + endpoint: 'following/requests/sent' as const, + limit: 10, + }, +); function accept(user) { misskeyApi('following/requests/accept', { userId: user.id }).then(() => { - paginationComponent.value.reload(); + paginationComponent.value?.reload(); }); } function reject(user) { misskeyApi('following/requests/reject', { userId: user.id }).then(() => { - paginationComponent.value.reload(); + paginationComponent.value?.reload(); }); } +function displayUser(req) { + return tab.value === 'list' ? req.follower : req.followee; +} + const headerActions = computed(() => []); -const headerTabs = computed(() => []); +const headerTabs = computed(() => [ + { + key: 'list', + title: i18n.ts.followRequests, + icon: 'ph-envelope ph-bold ph-lg', + }, { + key: 'sent', + title: i18n.ts.pendingFollowRequests, + icon: 'ph-paper-plane-tilt ph-bold ph-lg', + }, +]); + +const tab = ref($i?.isLocked || !$i.hasPendingSentFollowRequest ? 'list' : 'sent'); definePageMetadata(() => ({ title: i18n.ts.followRequests, diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md index d2a82f4901..b85bbd4421 100644 --- a/packages/misskey-js/etc/misskey-js.api.md +++ b/packages/misskey-js/etc/misskey-js.api.md @@ -1502,6 +1502,8 @@ declare namespace entities { FollowingRequestsCancelResponse, FollowingRequestsListRequest, FollowingRequestsListResponse, + FollowingRequestsSentRequest, + FollowingRequestsSentResponse, FollowingRequestsRejectRequest, GalleryFeaturedRequest, GalleryFeaturedResponse, @@ -2024,6 +2026,12 @@ type FollowingRequestsListResponse = operations['following___requests___list'][' type FollowingRequestsRejectRequest = operations['following___requests___reject']['requestBody']['content']['application/json']; // @public (undocumented) +type FollowingRequestsSentRequest = operations['following___requests___sent']['requestBody']['content']['application/json']; + +// @public (undocumented) +type FollowingRequestsSentResponse = operations['following___requests___sent']['responses']['200']['content']['application/json']; + +// @public (undocumented) type FollowingUpdateAllRequest = operations['following___update-all']['requestBody']['content']['application/json']; // @public (undocumented) diff --git a/packages/misskey-js/src/autogen/apiClientJSDoc.ts b/packages/misskey-js/src/autogen/apiClientJSDoc.ts index 20e3a6e545..9a3d2849b9 100644 --- a/packages/misskey-js/src/autogen/apiClientJSDoc.ts +++ b/packages/misskey-js/src/autogen/apiClientJSDoc.ts @@ -2032,6 +2032,17 @@ declare module '../api.js' { /** * No description provided. * + * **Credential required**: *Yes* / **Permission**: *read:following* + */ + request<E extends 'following/requests/sent', P extends Endpoints[E]['req']>( + endpoint: E, + params: P, + credential?: string | null, + ): Promise<SwitchCaseResponseType<E, P>>; + + /** + * No description provided. + * * **Credential required**: *Yes* / **Permission**: *write:following* */ request<E extends 'following/requests/reject', P extends Endpoints[E]['req']>( diff --git a/packages/misskey-js/src/autogen/endpoint.ts b/packages/misskey-js/src/autogen/endpoint.ts index 2652f40cf9..95c75d2b52 100644 --- a/packages/misskey-js/src/autogen/endpoint.ts +++ b/packages/misskey-js/src/autogen/endpoint.ts @@ -280,6 +280,8 @@ import type { FollowingRequestsCancelResponse, FollowingRequestsListRequest, FollowingRequestsListResponse, + FollowingRequestsSentRequest, + FollowingRequestsSentResponse, FollowingRequestsRejectRequest, GalleryFeaturedRequest, GalleryFeaturedResponse, @@ -774,6 +776,7 @@ export type Endpoints = { 'following/requests/accept': { req: FollowingRequestsAcceptRequest; res: EmptyResponse }; 'following/requests/cancel': { req: FollowingRequestsCancelRequest; res: FollowingRequestsCancelResponse }; 'following/requests/list': { req: FollowingRequestsListRequest; res: FollowingRequestsListResponse }; + 'following/requests/sent': { req: FollowingRequestsSentRequest; res: FollowingRequestsSentResponse }; 'following/requests/reject': { req: FollowingRequestsRejectRequest; res: EmptyResponse }; 'gallery/featured': { req: GalleryFeaturedRequest; res: GalleryFeaturedResponse }; 'gallery/popular': { req: EmptyRequest; res: GalleryPopularResponse }; @@ -1170,6 +1173,7 @@ export const endpointReqTypes: Record<keyof Endpoints, 'application/json' | 'mul 'following/requests/accept': 'application/json', 'following/requests/cancel': 'application/json', 'following/requests/list': 'application/json', + 'following/requests/sent': 'application/json', 'following/requests/reject': 'application/json', 'gallery/featured': 'application/json', 'gallery/popular': 'application/json', diff --git a/packages/misskey-js/src/autogen/entities.ts b/packages/misskey-js/src/autogen/entities.ts index fc14551f3f..a0b6bce63c 100644 --- a/packages/misskey-js/src/autogen/entities.ts +++ b/packages/misskey-js/src/autogen/entities.ts @@ -283,6 +283,8 @@ export type FollowingRequestsCancelRequest = operations['following___requests___ export type FollowingRequestsCancelResponse = operations['following___requests___cancel']['responses']['200']['content']['application/json']; export type FollowingRequestsListRequest = operations['following___requests___list']['requestBody']['content']['application/json']; export type FollowingRequestsListResponse = operations['following___requests___list']['responses']['200']['content']['application/json']; +export type FollowingRequestsSentRequest = operations['following___requests___sent']['requestBody']['content']['application/json']; +export type FollowingRequestsSentResponse = operations['following___requests___sent']['responses']['200']['content']['application/json']; export type FollowingRequestsRejectRequest = operations['following___requests___reject']['requestBody']['content']['application/json']; export type GalleryFeaturedRequest = operations['gallery___featured']['requestBody']['content']['application/json']; export type GalleryFeaturedResponse = operations['gallery___featured']['responses']['200']['content']['application/json']; diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index 0453fd0a36..4bebaf8d9a 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -1770,6 +1770,15 @@ export type paths = { */ post: operations['following___requests___list']; }; + '/following/requests/sent': { + /** + * following/requests/sent + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:following* + */ + post: operations['following___requests___sent']; + }; '/following/requests/reject': { /** * following/requests/reject @@ -3962,6 +3971,7 @@ export type components = { hasUnreadChannel: boolean; hasUnreadNotification: boolean; hasPendingReceivedFollowRequest: boolean; + hasPendingSentFollowRequest: boolean; unreadNotificationsCount: number; mutedWords: string[][]; hardMutedWords: string[][]; @@ -16245,6 +16255,69 @@ export type operations = { }; }; /** + * following/requests/sent + * @description No description provided. + * + * **Credential required**: *Yes* / **Permission**: *read:following* + */ + following___requests___sent: { + requestBody: { + content: { + 'application/json': { + /** Format: misskey:id */ + sinceId?: string; + /** Format: misskey:id */ + untilId?: string; + /** @default 10 */ + limit?: number; + }; + }; + }; + responses: { + /** @description OK (with results) */ + 200: { + content: { + 'application/json': { + /** Format: id */ + id: string; + follower: components['schemas']['UserLite']; + followee: components['schemas']['UserLite']; + }[]; + }; + }; + /** @description Client error */ + 400: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Authentication error */ + 401: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Forbidden error */ + 403: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description I'm Ai */ + 418: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + /** @description Internal server error */ + 500: { + content: { + 'application/json': components['schemas']['Error']; + }; + }; + }; + }; + /** * following/requests/reject * @description No description provided. * |