[mastodon-client] Return emojis field for polls

This commit is contained in:
Laura Hausmann 2023-10-07 19:35:57 +02:00
parent 8bec41b554
commit cfd53259cb
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
5 changed files with 30 additions and 14 deletions

View file

@ -36,7 +36,10 @@ export class NoteConverter {
const noteEmoji = host.then(async host => populateEmojis( const noteEmoji = host.then(async host => populateEmojis(
note.emojis.concat(reactionEmojiNames), note.emojis.concat(reactionEmojiNames),
host, host,
)); ))
.then(noteEmoji => noteEmoji
.filter((e) => e.name.indexOf("@") === -1)
.map((e) => EmojiConverter.encode(e)));
const reactionCount = NoteReactions.countBy({ noteId: note.id }); const reactionCount = NoteReactions.countBy({ noteId: note.id });
@ -110,10 +113,7 @@ export class NoteConverter {
text: text, text: text,
created_at: note.createdAt.toISOString(), created_at: note.createdAt.toISOString(),
// Remove reaction emojis with names containing @ from the emojis list. // Remove reaction emojis with names containing @ from the emojis list.
emojis: noteEmoji emojis: noteEmoji,
.then(noteEmoji => noteEmoji
.filter((e) => e.name.indexOf("@") === -1)
.map((e) => EmojiConverter.encode(e))),
replies_count: note.repliesCount, replies_count: note.repliesCount,
reblogs_count: note.renoteCount, reblogs_count: note.renoteCount,
favourites_count: reactionCount, favourites_count: reactionCount,
@ -127,7 +127,7 @@ export class NoteConverter {
mentions: mentions, mentions: mentions,
tags: tags, tags: tags,
card: null, //FIXME card: null, //FIXME
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 => noteEmoji.then(emojis => PollConverter.encode(p, note.id, emojis))) : null,
application: null, //FIXME application: null, //FIXME
language: null, //FIXME language: null, //FIXME
pinned: isPinned, pinned: isPinned,

View file

@ -11,7 +11,7 @@ type Poll = {
} }
export class PollConverter { export class PollConverter {
public static encode(p: Poll, noteId: string): MastodonEntity.Poll { public static encode(p: Poll, noteId: string, emojis: MastodonEntity.Emoji[]): MastodonEntity.Poll {
const now = new Date(); const now = new Date();
const count = p.choices.reduce((sum, choice) => sum + choice.votes, 0); const count = p.choices.reduce((sum, choice) => sum + choice.votes, 0);
return { return {
@ -21,6 +21,7 @@ export class PollConverter {
multiple: p.multiple, multiple: p.multiple,
votes_count: count, votes_count: count,
options: p.choices.map((c) => this.encodeChoice(c)), options: p.choices.map((c) => this.encodeChoice(c)),
emojis: emojis,
voted: p.choices.some((c) => c.isVoted), voted: p.choices.some((c) => c.isVoted),
own_votes: p.choices own_votes: p.choices
.filter((c) => c.isVoted) .filter((c) => c.isVoted)

View file

@ -268,7 +268,7 @@ export function setupEndpointsStatus(router: Router): void {
async (ctx) => { async (ctx) => {
const id = convertId(ctx.params.id, IdType.IceshrimpId); const id = convertId(ctx.params.id, IdType.IceshrimpId);
const note = await NoteHelpers.getNoteOr404(id, ctx.user); const note = await NoteHelpers.getNoteOr404(id, ctx.user);
const data = await PollHelpers.getPoll(note, ctx.user); const data = await PollHelpers.getPoll(note, ctx.user, ctx.cache);
ctx.body = convertPollId(data); ctx.body = convertPollId(data);
}); });
router.post<{ Params: { id: string } }>( router.post<{ Params: { id: string } }>(
@ -286,7 +286,7 @@ export function setupEndpointsStatus(router: Router): void {
return; return;
} }
const data = await PollHelpers.voteInPoll(choices, note, ctx.user); const data = await PollHelpers.voteInPoll(choices, note, ctx.user, ctx.cache);
ctx.body = convertPollId(data); ctx.body = convertPollId(data);
}, },
); );

View file

@ -10,5 +10,6 @@ namespace MastodonEntity {
options: Array<PollOption>; options: Array<PollOption>;
voted: boolean; voted: boolean;
own_votes: Array<number>; own_votes: Array<number>;
emojis: Array<MastodonEntity.Emoji>;
}; };
} }

View file

@ -2,7 +2,7 @@ import { Note } from "@/models/entities/note.js";
import { populatePoll } from "@/models/repositories/note.js"; import { populatePoll } from "@/models/repositories/note.js";
import { PollConverter } from "@/server/api/mastodon/converters/poll.js"; import { PollConverter } from "@/server/api/mastodon/converters/poll.js";
import { ILocalUser, IRemoteUser } from "@/models/entities/user.js"; import { ILocalUser, IRemoteUser } from "@/models/entities/user.js";
import { Blockings, NoteWatchings, Polls, PollVotes, Users } from "@/models/index.js"; import { Blockings, Notes, NoteWatchings, Polls, PollVotes, Users } from "@/models/index.js";
import { genId } from "@/misc/gen-id.js"; import { genId } from "@/misc/gen-id.js";
import { publishNoteStream } from "@/services/stream.js"; import { publishNoteStream } from "@/services/stream.js";
import { createNotification } from "@/services/create-notification.js"; import { createNotification } from "@/services/create-notification.js";
@ -11,13 +11,27 @@ import { renderActivity } from "@/remote/activitypub/renderer/index.js";
import renderVote from "@/remote/activitypub/renderer/vote.js"; import renderVote from "@/remote/activitypub/renderer/vote.js";
import { Not } from "typeorm"; import { Not } from "typeorm";
import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js"; import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js";
import { populateEmojis } from "@/misc/populate-emojis.js";
import { EmojiConverter } from "@/server/api/mastodon/converters/emoji.js";
import { AccountCache, UserHelpers } from "@/server/api/mastodon/helpers/user.js";
export class PollHelpers { export class PollHelpers {
public static async getPoll(note: Note, user: ILocalUser | null): Promise<MastodonEntity.Poll> { public static async getPoll(note: Note, user: ILocalUser | null, cache: AccountCache = UserHelpers.getFreshAccountCache()): Promise<MastodonEntity.Poll> {
return populatePoll(note, user?.id ?? null).then(p => PollConverter.encode(p, note.id)); if (!await Notes.isVisibleForMe(note, user?.id ?? null))
throw new Error('Cannot encode poll not visible for user');
const noteUser = note.user ?? UserHelpers.getUserCached(note.userId, cache);
const host = Promise.resolve(noteUser).then(noteUser => noteUser.host ?? null);
const noteEmoji = await host
.then(async host => populateEmojis(note.emojis, host)
.then(noteEmoji => noteEmoji
.filter((e) => e.name.indexOf("@") === -1)
.map((e) => EmojiConverter.encode(e))));
return populatePoll(note, user?.id ?? null).then(p => PollConverter.encode(p, note.id, noteEmoji));
} }
public static async voteInPoll(choices: number[], note: Note, user: ILocalUser): Promise<MastodonEntity.Poll> { public static async voteInPoll(choices: number[], note: Note, user: ILocalUser, cache: AccountCache = UserHelpers.getFreshAccountCache()): Promise<MastodonEntity.Poll> {
if (!note.hasPoll) throw new MastoApiError(404); if (!note.hasPoll) throw new MastoApiError(404);
for (const choice of choices) { for (const choice of choices) {
@ -108,6 +122,6 @@ export class PollHelpers {
); );
} }
} }
return this.getPoll(note, user); return this.getPoll(note, user, cache);
} }
} }