[mastodon-client] POST /statuses/:id/pin, /statuses/:id/unpin

This commit is contained in:
Laura Hausmann 2023-09-29 16:55:02 +02:00
parent 464c5425fc
commit a0cf791e53
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 76 additions and 17 deletions

View file

@ -9,7 +9,7 @@ import { VisibilityConverter } from "@/server/api/mastodon/converters/visibility
import { escapeMFM } from "@/server/api/mastodon/converters/mfm.js"; import { escapeMFM } from "@/server/api/mastodon/converters/mfm.js";
import { populateEmojis } from "@/misc/populate-emojis.js"; import { populateEmojis } from "@/misc/populate-emojis.js";
import { EmojiConverter } from "@/server/api/mastodon/converters/emoji.js"; import { EmojiConverter } from "@/server/api/mastodon/converters/emoji.js";
import { DriveFiles, NoteFavorites, NoteReactions, Notes, NoteThreadMutings } from "@/models/index.js"; import { DriveFiles, NoteFavorites, NoteReactions, Notes, NoteThreadMutings, UserNotePinings } from "@/models/index.js";
import { decodeReaction } from "@/misc/reaction-lib.js"; import { decodeReaction } from "@/misc/reaction-lib.js";
import { MentionConverter } from "@/server/api/mastodon/converters/mention.js"; import { MentionConverter } from "@/server/api/mastodon/converters/mention.js";
import { PollConverter } from "@/server/api/mastodon/converters/poll.js"; import { PollConverter } from "@/server/api/mastodon/converters/poll.js";
@ -86,6 +86,10 @@ export class NoteConverter {
: note.text; : note.text;
}); });
const isPinned = user && note.userId === user.id
? UserNotePinings.exist({ where: {userId: user.id, noteId: note.id } })
: false;
// noinspection ES6MissingAwait // noinspection ES6MissingAwait
return await awaitAll({ return await awaitAll({
id: note.id, id: note.id,
@ -119,7 +123,7 @@ export class NoteConverter {
poll: note.hasPoll ? populatePoll(note, user?.id ?? null).then(p => PollConverter.encode(p, note.id)) : null, poll: note.hasPoll ? populatePoll(note, user?.id ?? null).then(p => PollConverter.encode(p, note.id)) : null,
application: null, //FIXME application: null, //FIXME
language: null, //FIXME language: null, //FIXME
pinned: null, //FIXME pinned: isPinned,
// Use emojis list to provide URLs for emoji reactions. // Use emojis list to provide URLs for emoji reactions.
reactions: [], //FIXME: this.mapReactions(n.emojis, n.reactions, n.myReaction), reactions: [], //FIXME: this.mapReactions(n.emojis, n.reactions, n.myReaction),
bookmarked: isBookmarked, bookmarked: isBookmarked,

View file

@ -512,14 +512,26 @@ export function apiStatusMastodon(router: Router): void {
router.post<{ Params: { id: string } }>( router.post<{ Params: { id: string } }>(
"/v1/statuses/:id/pin", "/v1/statuses/:id/pin",
async (ctx) => { async (ctx) => {
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
const accessTokens = ctx.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try { try {
const data = await client.pinStatus( const auth = await authenticate(ctx.headers.authorization, null);
convertId(ctx.params.id, IdType.IceshrimpId), const user = auth[0] ?? null;
);
ctx.body = convertStatus(data.data); if (!user) {
ctx.status = 401;
return;
}
const id = convertId(ctx.params.id, IdType.IceshrimpId);
const note = await getNote(id, user).catch(_ => null);
if (note === null) {
ctx.status = 404;
return;
}
ctx.body = await NoteHelpers.pinNote(note, user)
.then(p => NoteConverter.encode(p, user))
.then(p => convertStatus(p));
} catch (e: any) { } catch (e: any) {
console.error(e); console.error(e);
ctx.status = 401; ctx.status = 401;
@ -531,14 +543,26 @@ export function apiStatusMastodon(router: Router): void {
router.post<{ Params: { id: string } }>( router.post<{ Params: { id: string } }>(
"/v1/statuses/:id/unpin", "/v1/statuses/:id/unpin",
async (ctx) => { async (ctx) => {
const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
const accessTokens = ctx.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try { try {
const data = await client.unpinStatus( const auth = await authenticate(ctx.headers.authorization, null);
convertId(ctx.params.id, IdType.IceshrimpId), const user = auth[0] ?? null;
);
ctx.body = convertStatus(data.data); if (!user) {
ctx.status = 401;
return;
}
const id = convertId(ctx.params.id, IdType.IceshrimpId);
const note = await getNote(id, user).catch(_ => null);
if (note === null) {
ctx.status = 404;
return;
}
ctx.body = await NoteHelpers.unpinNote(note, user)
.then(p => NoteConverter.encode(p, user))
.then(p => convertStatus(p));
} catch (e: any) { } catch (e: any) {
console.error(e); console.error(e);
ctx.status = 401; ctx.status = 401;

View file

@ -1,5 +1,5 @@
import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js"; import { makePaginationQuery } from "@/server/api/common/make-pagination-query.js";
import { Metas, NoteFavorites, NoteReactions, Notes, Users } from "@/models/index.js"; import { Metas, NoteFavorites, NoteReactions, Notes, UserNotePinings, Users } from "@/models/index.js";
import { generateVisibilityQuery } from "@/server/api/common/generate-visibility-query.js"; import { generateVisibilityQuery } from "@/server/api/common/generate-visibility-query.js";
import { generateMutedUserQuery } from "@/server/api/common/generate-muted-user-query.js"; import { generateMutedUserQuery } from "@/server/api/common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "@/server/api/common/generate-block-query.js"; import { generateBlockedUserQuery } from "@/server/api/common/generate-block-query.js";
@ -14,6 +14,7 @@ import { genId } from "@/misc/gen-id.js";
import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js"; import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js";
import { UserConverter } from "@/server/api/mastodon/converters/user.js"; import { UserConverter } from "@/server/api/mastodon/converters/user.js";
import { AccountCache, LinkPaginationObject, UserHelpers } from "@/server/api/mastodon/helpers/user.js"; import { AccountCache, LinkPaginationObject, UserHelpers } from "@/server/api/mastodon/helpers/user.js";
import { addPinned, removePinned } from "@/services/i/pin.js";
export class NoteHelpers { export class NoteHelpers {
public static async getDefaultReaction(): Promise<string> { public static async getDefaultReaction(): Promise<string> {
@ -81,6 +82,36 @@ export class NoteHelpers {
.then(_ => note); .then(_ => note);
} }
public static async pinNote(note: Note, user: ILocalUser): Promise<Note> {
const pinned = await UserNotePinings.exist({
where: {
userId: user.id,
noteId: note.id
}
});
if (!pinned) {
await addPinned(user, note.id);
}
return note;
}
public static async unpinNote(note: Note, user: ILocalUser): Promise<Note> {
const pinned = await UserNotePinings.exist({
where: {
userId: user.id,
noteId: note.id
}
});
if (pinned) {
await removePinned(user, note.id);
}
return note;
}
public static async getNoteFavoritedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40): Promise<LinkPaginationObject<User[]>> { public static async getNoteFavoritedBy(note: Note, maxId: string | undefined, sinceId: string | undefined, minId: string | undefined, limit: number = 40): Promise<LinkPaginationObject<User[]>> {
if (limit > 80) limit = 80; if (limit > 80) limit = 80;
const query = PaginationHelpers.makePaginationQuery( const query = PaginationHelpers.makePaginationQuery(