pl-api: mastodon quotes support

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-09-19 22:01:36 +02:00
parent 9161b0491d
commit f308f63038
4 changed files with 55 additions and 2 deletions

View File

@ -243,6 +243,7 @@ import type {
} from './params/settings'; } from './params/settings';
import type { import type {
CreateStatusParams, CreateStatusParams,
EditInteractionPolicyParams,
EditStatusParams, EditStatusParams,
GetFavouritedByParams, GetFavouritedByParams,
GetRebloggedByParams, GetRebloggedByParams,
@ -2394,6 +2395,8 @@ class PlApiClient {
fixedParams.circle_id = params.visibility.slice(7); fixedParams.circle_id = params.visibility.slice(7);
fixedParams.visibility = 'circle'; fixedParams.visibility = 'circle';
} }
if (params.quote_id && this.#instance.api_versions.mastodon >= 7) params.quoted_status_id = params.quote_id;
else if (params.quoted_status_id && (this.#instance.api_versions.mastodon || 0) < 7) params.quote_id = params.quoted_status_id;
const input = params.preview && this.features.version.software === MITRA const input = params.preview && this.features.version.software === MITRA
? '/api/v1/statuses/preview' ? '/api/v1/statuses/preview'
@ -2592,6 +2595,17 @@ class PlApiClient {
return v.parse(statusSchema, response.json); return v.parse(statusSchema, response.json);
}, },
/**
* Revoke a quote post
* Revoke quote authorization of status `quoting_status_id`, detaching status `id`.
* @see {@link https://docs.joinmastodon.org/methods/statuses/#revoke_quote}
*/
revokeQuote: async (statusId: string, quotingStatusId: string) => {
const response = await this.request(`/api/v1/statuses/${statusId}/quotes/${quotingStatusId}/revoke`, { method: 'POST' });
return v.parse(statusSchema, response.json);
},
/** /**
* Mute a conversation * Mute a conversation
* Do not receive notifications for the thread that this status is part of. Must be a thread in which you are a participant. * Do not receive notifications for the thread that this status is part of. Must be a thread in which you are a participant.
@ -2657,6 +2671,17 @@ class PlApiClient {
return v.parse(statusSchema, response.json); return v.parse(statusSchema, response.json);
}, },
/**
* Edit a status' interaction policies
* Edit a given status to change its interaction policies. Currently, this means changing its quote approval policy.
* @see {@link https://docs.joinmastodon.org/methods/statuses/#edit_interaction_policy}
*/
editInteractionPolicy: async (statusId: string, params: EditInteractionPolicyParams) => {
const response = await this.request(`/api/v1/statuses/${statusId}`, { method: 'PUT', body: params });
return v.parse(statusSchema, response.json);
},
/** /**
* View edit history of a status * View edit history of a status
* Get all known versions of a status, including the initial and current states. * Get all known versions of a status, including the initial and current states.
@ -2759,9 +2784,14 @@ class PlApiClient {
* View quotes for a given status * View quotes for a given status
* *
* Requires features{@link Features.quotePosts}. * Requires features{@link Features.quotePosts}.
* @see {@link https://docs.joinmastodon.org/methods/statuses/#quotes}
*/ */
getStatusQuotes: async (statusId: string, params?: GetStatusQuotesParams) => getStatusQuotes: async (statusId: string, params?: GetStatusQuotesParams) =>
this.#paginatedGet(`/api/v1/pleroma/statuses/${statusId}/quotes`, { params }, statusSchema), this.#paginatedGet(
this.#instance.api_versions.mastodon >= 7 ? `/api/v1/statuses/${statusId}/quotes` : `/api/v1/pleroma/statuses/${statusId}/quotes`,
{ params },
statusSchema,
),
/** /**
* Returns the list of accounts that have disliked the status as known by the current server * Returns the list of accounts that have disliked the status as known by the current server

View File

@ -242,6 +242,7 @@ const untypedCredentialAccountSchema = v.pipe(v.any(), preprocessAccount, v.obje
hide_collections: v.fallback(v.nullable(v.boolean()), null), hide_collections: v.fallback(v.nullable(v.boolean()), null),
discoverable: v.fallback(v.optional(v.nullable(v.boolean())), undefined), discoverable: v.fallback(v.optional(v.nullable(v.boolean())), undefined),
indexable: v.fallback(v.nullable(v.boolean()), null), indexable: v.fallback(v.nullable(v.boolean()), null),
quote_policy: v.fallback(v.nullable(v.picklist(['public', 'followers', 'nobody'])), null),
show_role: v.fallback(v.optional(v.nullable(v.boolean())), undefined), show_role: v.fallback(v.optional(v.nullable(v.boolean())), undefined),
no_rich_text: v.fallback(v.optional(v.nullable(v.boolean())), undefined), no_rich_text: v.fallback(v.optional(v.nullable(v.boolean())), undefined),

View File

@ -1553,10 +1553,13 @@ const getFeatures = (instance: Instance) => {
v.software === ICESHRIMP_NET, v.software === ICESHRIMP_NET,
v.software === FRIENDICA && gte(v.version, '2023.3.0'), v.software === FRIENDICA && gte(v.version, '2023.3.0'),
v.software === SHARKEY, v.software === SHARKEY,
instance.api_versions.mastodon >= 7,
instance.api_versions['quote_posting.pleroma.pl-api'] >= 1, instance.api_versions['quote_posting.pleroma.pl-api'] >= 1,
instance.feature_quote === true, instance.feature_quote === true,
]), ]),
quoteApprovalPolicies: instance.api_versions.mastodon >= 7,
/** /**
* Ability to boost a status to a selected scope. * Ability to boost a status to a selected scope.
* @see POST /api/v1/statuses/:id/reblog * @see POST /api/v1/statuses/:id/reblog

View File

@ -86,7 +86,15 @@ interface CreateStatusOptionalParams {
* ID of the status being quoted, if any. * ID of the status being quoted, if any.
* Requires features{@link Features['quotePosts']}. * Requires features{@link Features['quotePosts']}.
*/ */
quoted_status_id?: string;
/**
* Deprecated, use `quoted_status_id` instead.
*/
quote_id?: string; quote_id?: string;
/**
* Sets who is allowed to quote the status. When omitted, the user's default setting will be used instead. Ignored if `visibility` is `private` or `direct`, in which case the policy will always be set to `nobody`.\
*/
quote_approval_policy?: 'public' | 'followers' | 'nobody';
/** /**
* If set to true, this status will be "local only" and will NOT be federated beyond the local timeline(s). If set to false (default), this status will be federated to your followers beyond the local timeline(s). * If set to true, this status will be "local only" and will NOT be federated beyond the local timeline(s). If set to false (default), this status will be federated to your followers beyond the local timeline(s).
@ -143,13 +151,23 @@ type GetFavouritedByParams = Omit<PaginationParams, 'min_id'>
/** /**
* @category Request params * @category Request params
*/ */
type EditStatusOptionalParams = Pick<CreateStatusOptionalParams, 'content_type' | 'sensitive' | 'spoiler_text' | 'language'>; type EditStatusOptionalParams = Pick<CreateStatusOptionalParams, 'content_type' | 'sensitive' | 'spoiler_text' | 'language' | 'quote_approval_policy'>;
/** /**
* @category Request params * @category Request params
*/ */
type EditStatusParams = (CreateStatusWithContent | CreateStatusWithMedia) & EditStatusOptionalParams; type EditStatusParams = (CreateStatusWithContent | CreateStatusWithMedia) & EditStatusOptionalParams;
/**
* @category Request params
*/
interface EditInteractionPolicyParams {
/**
* Sets who is allowed to quote the status. Ignored if `visibility` is `private` or `direct`, in which case the policy will always be set to `nobody`. Changing the policy does not invalidate past quotes.
*/
quote_approval_policy: ['public', 'followers', 'nobody'];
}
/** /**
* @category Request params * @category Request params
*/ */
@ -173,6 +191,7 @@ export type {
GetRebloggedByParams, GetRebloggedByParams,
GetFavouritedByParams, GetFavouritedByParams,
EditStatusParams, EditStatusParams,
EditInteractionPolicyParams,
GetStatusQuotesParams, GetStatusQuotesParams,
GetStatusReferencesParams, GetStatusReferencesParams,
GetStatusMentionedUsersParams, GetStatusMentionedUsersParams,