Compare commits

...

17 Commits

Author SHA1 Message Date
かっこかり 02a250397a
Merge 7ffb0f863b into 794cb9ffe2 2024-11-07 23:20:29 +09:00
4ster1sk 794cb9ffe2
fix(backend): followedMessageではなくdescriptionになっていたのを修正 (#14908) 2024-11-07 17:16:51 +09:00
syuilo 0b976064ca
Update CHANGELOG.md 2024-11-07 15:10:38 +09:00
4ster1sk bca690f256
fix(backend): フォロワーへのメッセージの絵文字をemojisに含めるように (#14904) 2024-11-07 15:10:10 +09:00
kakkokari-gtyih 7ffb0f863b Update Changelog 2024-11-02 19:24:31 +09:00
kakkokari-gtyih bb3019723f Update Changelog 2024-11-02 19:17:27 +09:00
kakkokari-gtyih ff4ddfbf16 Merge branch 'feat-14852' of https://github.com/kakkokari-gtyih/misskey into feat-14852 2024-11-02 19:11:31 +09:00
kakkokari-gtyih 6841fcdbe4 Revert "ux: should not show follow requests tab when have no pending sent follow req"
This reverts commit e580b92c37.
2024-11-02 19:11:28 +09:00
かっこかり 3bac094f8e
Merge branch 'develop' into feat-14852 2024-11-02 19:08:28 +09:00
kakkokari-gtyih d69e3516f4 tweak design 2024-11-02 19:07:33 +09:00
kakkokari-gtyih e694c0e163 use tabler icons 2024-10-28 16:12:39 +09:00
kakkokari-gtyih 4df765a279 refactor 2024-10-28 16:07:43 +09:00
Hazelnoot 4a47b564e1 restore missing hasPendingReceivedFollowRequest in navbar 2024-10-28 16:05:46 +09:00
Lhc_fl 849344121c fix default followreq tab 2024-10-28 16:05:21 +09:00
Lhc_fl 86bfe0236e fix default followreq tab 2024-10-28 16:05:08 +09:00
Lhc_fl e580b92c37 ux: should not show follow requests tab when have no pending sent follow req 2024-10-28 16:05:01 +09:00
Lhc_fl 0959dec291 FEAT: Allow users to view pending follow requests they sent
This commit implements the `following/requests/sent` interface firstly
implemented on Firefish, and provides a UI interface to view the pending
follow requests users sent.
2024-10-28 16:04:52 +09:00
13 changed files with 269 additions and 39 deletions

View File

@ -15,7 +15,9 @@
- どのアカウントで認証しようとしているのかがわかるように - どのアカウントで認証しようとしているのかがわかるように
- 認証するアカウントを切り替えられるように - 認証するアカウントを切り替えられるように
- Enhance: Self-XSS防止用の警告を追加 - Enhance: Self-XSS防止用の警告を追加
- Enhance: カタルーニャ語 (ca-ES) に対応 - Enhance: カタルーニャ語 (ca-ES) に対応
- Enhance: 過去に送信したフォローリクエストを確認できるように
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/663)
- Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正 - Fix: 通知の範囲指定の設定項目が必要ない通知設定でも範囲指定の設定がでている問題を修正
- Fix: Turnstileが失敗・期限切れした際にも成功扱いとなってしまう問題を修正 - Fix: Turnstileが失敗・期限切れした際にも成功扱いとなってしまう問題を修正
(Cherry-picked from https://github.com/MisskeyIO/misskey/pull/768) (Cherry-picked from https://github.com/MisskeyIO/misskey/pull/768)
@ -29,6 +31,7 @@
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように - Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588) (Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588)
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715)
- fix(backend): フォロワーへのメッセージの絵文字をemojisに含めるように
- Fix: Nested proxy requestsを検出した際にブロックするように - Fix: Nested proxy requestsを検出した際にブロックするように
[ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236) [ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236)
- Fix: 招待コードの発行可能な残り数算出に使用すべきロールポリシーの値が違う問題を修正 - Fix: 招待コードの発行可能な残り数算出に使用すべきロールポリシーの値が違う問題を修正

View File

@ -187,6 +187,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_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';
import * as ep___following_requests_list from './endpoints/following/requests/list.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___following_requests_reject from './endpoints/following/requests/reject.js';
import * as ep___gallery_featured from './endpoints/gallery/featured.js'; import * as ep___gallery_featured from './endpoints/gallery/featured.js';
import * as ep___gallery_popular from './endpoints/gallery/popular.js'; import * as ep___gallery_popular from './endpoints/gallery/popular.js';
@ -574,6 +575,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_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 };
const $following_requests_list: Provider = { provide: 'ep:following/requests/list', useClass: ep___following_requests_list.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 $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_featured: Provider = { provide: 'ep:gallery/featured', useClass: ep___gallery_featured.default };
const $gallery_popular: Provider = { provide: 'ep:gallery/popular', useClass: ep___gallery_popular.default }; const $gallery_popular: Provider = { provide: 'ep:gallery/popular', useClass: ep___gallery_popular.default };
@ -965,6 +967,7 @@ const $reversi_verify: Provider = { provide: 'ep:reversi/verify', useClass: ep__
$following_requests_accept, $following_requests_accept,
$following_requests_cancel, $following_requests_cancel,
$following_requests_list, $following_requests_list,
$following_requests_sent,
$following_requests_reject, $following_requests_reject,
$gallery_featured, $gallery_featured,
$gallery_popular, $gallery_popular,

View File

@ -193,6 +193,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_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';
import * as ep___following_requests_list from './endpoints/following/requests/list.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___following_requests_reject from './endpoints/following/requests/reject.js';
import * as ep___gallery_featured from './endpoints/gallery/featured.js'; import * as ep___gallery_featured from './endpoints/gallery/featured.js';
import * as ep___gallery_popular from './endpoints/gallery/popular.js'; import * as ep___gallery_popular from './endpoints/gallery/popular.js';
@ -578,6 +579,7 @@ const eps = [
['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],
['following/requests/list', ep___following_requests_list], ['following/requests/list', ep___following_requests_list],
['following/requests/sent', ep___following_requests_sent],
['following/requests/reject', ep___following_requests_reject], ['following/requests/reject', ep___following_requests_reject],
['gallery/featured', ep___gallery_featured], ['gallery/featured', ep___gallery_featured],
['gallery/popular', ep___gallery_popular], ['gallery/popular', ep___gallery_popular],

View File

@ -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);
});
}
}

View File

@ -465,6 +465,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
const newName = updates.name === undefined ? user.name : updates.name; const newName = updates.name === undefined ? user.name : updates.name;
const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description; const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description;
const newFields = profileUpdates.fields === undefined ? profile.fields : profileUpdates.fields; const newFields = profileUpdates.fields === undefined ? profile.fields : profileUpdates.fields;
const newFollowedMessage = profileUpdates.followedMessage === undefined ? profile.followedMessage : profileUpdates.followedMessage;
if (newName != null) { if (newName != null) {
let hasProhibitedWords = false; let hasProhibitedWords = false;
@ -494,6 +495,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
]); ]);
} }
if (newFollowedMessage != null) {
const tokens = mfm.parse(newFollowedMessage);
emojis = emojis.concat(extractCustomEmojisFromMfm(tokens));
}
updates.emojis = emojis; updates.emojis = emojis;
updates.tags = tags; updates.tags = tags;

View File

@ -91,7 +91,10 @@ async function onClick() {
text: i18n.tsx.unfollowConfirm({ name: props.user.name || props.user.username }), text: i18n.tsx.unfollowConfirm({ name: props.user.name || props.user.username }),
}); });
if (canceled) return; if (canceled) {
wait.value = false;
return;
}
await misskeyApi('following/delete', { await misskeyApi('following/delete', {
userId: props.user.id, userId: props.user.id,
@ -125,7 +128,10 @@ async function onClick() {
}); });
hasPendingFollowRequestFromYou.value = true; hasPendingFollowRequestFromYou.value = true;
if ($i == null) return; if ($i == null) {
wait.value = false;
return;
}
claimAchievement('following1'); claimAchievement('following1');

View File

@ -40,7 +40,6 @@ export const navbarItemDef = reactive({
followRequests: { followRequests: {
title: i18n.ts.followRequests, title: i18n.ts.followRequests,
icon: 'ti ti-user-plus', icon: 'ti ti-user-plus',
show: computed(() => $i != null && $i.isLocked),
indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest), indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest),
to: '/my/follow-requests', to: '/my/follow-requests',
}, },

View File

@ -5,69 +5,107 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<MkStickyContainer> <MkStickyContainer>
<template #header><MkPageHeader/></template> <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :contentMax="800"> <MkSpacer :contentMax="800">
<MkPagination ref="paginationComponent" :pagination="pagination"> <MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs">
<template #empty> <div :key="tab" class="_gaps">
<div class="_fullinfo"> <MkPagination ref="paginationComponent" :pagination="pagination">
<img :src="infoImageUrl" class="_ghost"/> <template #empty>
<div>{{ i18n.ts.noFollowRequests }}</div> <div class="_fullinfo">
</div> <img :src="infoImageUrl" class="_ghost"/>
</template> <div>{{ i18n.ts.noFollowRequests }}</div>
<template #default="{items}"> </div>
<div class="mk-follow-requests"> </template>
<div v-for="req in items" :key="req.id" class="user _panel"> <template #default="{items}">
<MkAvatar class="avatar" :user="req.follower" indicator link preview/> <div class="mk-follow-requests">
<div class="body"> <div v-for="req in items" :key="req.id" class="user _panel">
<div class="name"> <MkAvatar class="avatar" :user="displayUser(req)" indicator link preview/>
<MkA v-user-preview="req.follower.id" class="name" :to="userPage(req.follower)"><MkUserName :user="req.follower"/></MkA> <div class="body">
<p class="acct">@{{ acct(req.follower) }}</p> <div class="name">
</div> <MkA v-user-preview="displayUser(req).id" class="name" :to="userPage(displayUser(req))"><MkUserName :user="displayUser(req)"/></MkA>
<div class="commands"> <p class="acct">@{{ acct(displayUser(req)) }}</p>
<MkButton class="command" rounded primary @click="accept(req.follower)"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> </div>
<MkButton class="command" rounded danger @click="reject(req.follower)"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> <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 v-else class="commands">
<MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.cancel }}</MkButton>
</div>
</div>
</div> </div>
</div> </div>
</div> </template>
</div> </MkPagination>
</template> </div>
</MkPagination> </MkHorizontalSwipe>
</MkSpacer> </MkSpacer>
</MkStickyContainer> </MkStickyContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { shallowRef, computed } from 'vue'; import * as Misskey from 'misskey-js';
import { shallowRef, computed, ref } from 'vue';
import MkPagination from '@/components/MkPagination.vue'; import MkPagination from '@/components/MkPagination.vue';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import { userPage, acct } from '@/filters/user.js'; import { userPage, acct } from '@/filters/user.js';
import { misskeyApi } from '@/scripts/misskey-api.js'; import * as os from '@/os.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js'; import { definePageMetadata } from '@/scripts/page-metadata.js';
import { infoImageUrl } from '@/instance.js'; import { infoImageUrl } from '@/instance.js';
import { $i } from '@/account.js';
import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue';
const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>(); const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
const pagination = { const pagination = computed(() => tab.value === 'list'
endpoint: 'following/requests/list' as const, ? {
limit: 10, endpoint: 'following/requests/list' as const,
}; limit: 10,
}
: {
endpoint: 'following/requests/sent' as const,
limit: 10,
},
);
function accept(user) { function accept(user: Misskey.entities.UserLite) {
misskeyApi('following/requests/accept', { userId: user.id }).then(() => { os.apiWithDialog('following/requests/accept', { userId: user.id }).then(() => {
paginationComponent.value?.reload(); paginationComponent.value?.reload();
}); });
} }
function reject(user) { function reject(user: Misskey.entities.UserLite) {
misskeyApi('following/requests/reject', { userId: user.id }).then(() => { os.apiWithDialog('following/requests/reject', { userId: user.id }).then(() => {
paginationComponent.value?.reload(); paginationComponent.value?.reload();
}); });
} }
function cancel(user: Misskey.entities.UserLite) {
os.apiWithDialog('following/requests/cancel', { userId: user.id }).then(() => {
paginationComponent.value?.reload();
});
}
function displayUser(req) {
return tab.value === 'list' ? req.follower : req.followee;
}
const headerActions = computed(() => []); const headerActions = computed(() => []);
const headerTabs = computed(() => []); const headerTabs = computed(() => [
{
key: 'list',
title: i18n.ts.followRequests,
icon: 'ti ti-mail',
}, {
key: 'sent',
title: i18n.ts.followRequestPending,
icon: 'ti ti-send',
},
]);
const tab = ref($i?.isLocked ? 'list' : 'sent');
definePageMetadata(() => ({ definePageMetadata(() => ({
title: i18n.ts.followRequests, title: i18n.ts.followRequests,

View File

@ -1504,6 +1504,8 @@ declare namespace entities {
FollowingRequestsCancelResponse, FollowingRequestsCancelResponse,
FollowingRequestsListRequest, FollowingRequestsListRequest,
FollowingRequestsListResponse, FollowingRequestsListResponse,
FollowingRequestsSentRequest,
FollowingRequestsSentResponse,
FollowingRequestsRejectRequest, FollowingRequestsRejectRequest,
GalleryFeaturedRequest, GalleryFeaturedRequest,
GalleryFeaturedResponse, GalleryFeaturedResponse,
@ -2018,6 +2020,12 @@ type FollowingRequestsListResponse = operations['following___requests___list']['
// @public (undocumented) // @public (undocumented)
type FollowingRequestsRejectRequest = operations['following___requests___reject']['requestBody']['content']['application/json']; 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) // @public (undocumented)
type FollowingUpdateAllRequest = operations['following___update-all']['requestBody']['content']['application/json']; type FollowingUpdateAllRequest = operations['following___update-all']['requestBody']['content']['application/json'];

View File

@ -2008,6 +2008,17 @@ declare module '../api.js' {
credential?: string | null, credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>; ): Promise<SwitchCaseResponseType<E, P>>;
/**
* 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. * No description provided.
* *

View File

@ -279,6 +279,8 @@ import type {
FollowingRequestsCancelResponse, FollowingRequestsCancelResponse,
FollowingRequestsListRequest, FollowingRequestsListRequest,
FollowingRequestsListResponse, FollowingRequestsListResponse,
FollowingRequestsSentRequest,
FollowingRequestsSentResponse,
FollowingRequestsRejectRequest, FollowingRequestsRejectRequest,
GalleryFeaturedRequest, GalleryFeaturedRequest,
GalleryFeaturedResponse, GalleryFeaturedResponse,
@ -761,6 +763,7 @@ export type Endpoints = {
'following/requests/accept': { req: FollowingRequestsAcceptRequest; res: EmptyResponse }; 'following/requests/accept': { req: FollowingRequestsAcceptRequest; res: EmptyResponse };
'following/requests/cancel': { req: FollowingRequestsCancelRequest; res: FollowingRequestsCancelResponse }; 'following/requests/cancel': { req: FollowingRequestsCancelRequest; res: FollowingRequestsCancelResponse };
'following/requests/list': { req: FollowingRequestsListRequest; res: FollowingRequestsListResponse }; 'following/requests/list': { req: FollowingRequestsListRequest; res: FollowingRequestsListResponse };
'following/requests/sent': { req: FollowingRequestsSentRequest; res: FollowingRequestsSentResponse };
'following/requests/reject': { req: FollowingRequestsRejectRequest; res: EmptyResponse }; 'following/requests/reject': { req: FollowingRequestsRejectRequest; res: EmptyResponse };
'gallery/featured': { req: GalleryFeaturedRequest; res: GalleryFeaturedResponse }; 'gallery/featured': { req: GalleryFeaturedRequest; res: GalleryFeaturedResponse };
'gallery/popular': { req: EmptyRequest; res: GalleryPopularResponse }; 'gallery/popular': { req: EmptyRequest; res: GalleryPopularResponse };

View File

@ -282,6 +282,8 @@ export type FollowingRequestsCancelRequest = operations['following___requests___
export type FollowingRequestsCancelResponse = operations['following___requests___cancel']['responses']['200']['content']['application/json']; 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 FollowingRequestsListRequest = operations['following___requests___list']['requestBody']['content']['application/json'];
export type FollowingRequestsListResponse = operations['following___requests___list']['responses']['200']['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 FollowingRequestsRejectRequest = operations['following___requests___reject']['requestBody']['content']['application/json'];
export type GalleryFeaturedRequest = operations['gallery___featured']['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']; export type GalleryFeaturedResponse = operations['gallery___featured']['responses']['200']['content']['application/json'];

View File

@ -1753,6 +1753,15 @@ export type paths = {
*/ */
post: operations['following___requests___list']; 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': {
/** /**
* following/requests/reject * following/requests/reject
@ -16040,6 +16049,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 * following/requests/reject
* @description No description provided. * @description No description provided.