[backend] Return isRenoted status in Notes.pack instead of requesting it individually

This commit is contained in:
Laura Hausmann 2023-11-20 23:48:27 +01:00
parent efde111779
commit a6fa393359
Signed by: zotan
GPG key ID: D044E84C5BE01605
5 changed files with 49 additions and 9 deletions

View file

@ -10,6 +10,7 @@ import {
Followings,
Polls,
Channels,
Notes,
} from "../index.js";
import type { Packed } from "@/misc/schema.js";
import { nyaize } from "@/misc/nyaize.js";
@ -95,6 +96,19 @@ async function populateMyReaction(
return undefined;
}
async function populateIsRenoted(
note: Note,
meId: User["id"],
_hint_?: {
myRenotes: Map<Note["id"], boolean>;
},
) {
return _hint_?.myRenotes
? _hint_.myRenotes.get(note.id) ? true : undefined
: Notes.exist({ where: { renoteId: note.id, userId: meId } })
.then(res => res ? true : undefined);
}
export const NoteRepository = db.getRepository(Note).extend({
async isVisibleForMe(note: Note, meId: User["id"] | null): Promise<boolean> {
// This code must always be synchronized with the checks in generateVisibilityQuery.
@ -156,6 +170,7 @@ export const NoteRepository = db.getRepository(Note).extend({
detail?: boolean;
_hint_?: {
myReactions: Map<Note["id"], NoteReaction | null>;
myRenotes: Map<Note["id"], boolean>;
};
},
): Promise<Packed<"Note">> {
@ -240,6 +255,7 @@ export const NoteRepository = db.getRepository(Note).extend({
...(meId
? {
myReaction: populateMyReaction(note, meId, options?._hint_),
isRenoted: populateIsRenoted(note, meId, options?._hint_)
}
: {}),
@ -290,6 +306,7 @@ export const NoteRepository = db.getRepository(Note).extend({
detail?: boolean;
_hint_?: {
myReactions: Map<Note["id"], NoteReaction | null>;
myRenotes: Map<Note["id"], boolean>;
};
},
): Promise<Packed<"Note"> | undefined> {
@ -311,6 +328,7 @@ export const NoteRepository = db.getRepository(Note).extend({
const meId = me ? me.id : null;
const myReactionsMap = new Map<Note["id"], NoteReaction | null>();
const myRenotesMap = new Map<Note["id"], boolean>();
if (meId) {
const renoteIds = notes
.filter((n) => n.renoteId != null)
@ -320,12 +338,22 @@ export const NoteRepository = db.getRepository(Note).extend({
userId: meId,
noteId: In(targets),
});
const myRenotes = await Notes.createQueryBuilder('note')
.select('note.renoteId')
.where('note.userId = :meId', { meId })
.andWhere('note.renoteId IN (:...targets)', { targets })
.getMany();
for (const target of targets) {
myReactionsMap.set(
target,
myReactions.find((reaction) => reaction.noteId === target) || null,
);
myRenotesMap.set(
target,
!!myRenotes.find(p => p.renoteId == target),
);
}
}
@ -337,6 +365,7 @@ export const NoteRepository = db.getRepository(Note).extend({
...options,
_hint_: {
myReactions: myReactionsMap,
myRenotes: myRenotesMap
},
}),
),

View file

@ -22,6 +22,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
options: {
_hintForEachNotes_?: {
myReactions: Map<Note["id"], NoteReaction | null>;
myRenotes: Map<Note["id"], boolean>;
};
},
): Promise<Packed<"Notification">> {
@ -153,6 +154,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
.map((x) => x.note!);
const noteIds = notes.map((n) => n.id);
const myReactionsMap = new Map<Note["id"], NoteReaction | null>();
const myRenotesMap = new Map<Note["id"], boolean>();
const renoteIds = notes
.filter((n) => n.renoteId != null)
.map((n) => n.renoteId!);
@ -161,12 +163,22 @@ export const NotificationRepository = db.getRepository(Notification).extend({
userId: meId,
noteId: In(targets),
});
const myRenotes = await Notes.createQueryBuilder('note')
.select('note.renoteId')
.where('note.userId = :meId', { meId })
.andWhere('note.renoteId IN array[:...targets]', { targets })
.getMany();
for (const target of targets) {
myReactionsMap.set(
target,
myReactions.find((reaction) => reaction.noteId === target) || null,
);
myRenotesMap.set(
target,
!!myRenotes.find(p => p.renoteId == target),
);
}
await prefetchEmojis(aggregateNoteEmojis(notes));
@ -176,6 +188,7 @@ export const NotificationRepository = db.getRepository(Notification).extend({
this.pack(x, {
_hintForEachNotes_: {
myReactions: myReactionsMap,
myRenotes: myRenotesMap
},
}).catch((e) => null),
),

View file

@ -190,11 +190,15 @@ export const packedNoteSchema = {
optional: true,
nullable: false,
},
myReaction: {
type: "object",
optional: true,
nullable: true,
},
isRenoted: {
type: "boolean",
optional: true,
nullable: true,
}
},
} as const;

View file

@ -70,14 +70,7 @@ useTooltip(buttonRef, async (showing) => {
);
});
let hasRenotedBefore = $ref(false);
os.api("notes/renotes", {
noteId: props.note.id,
userId: $i.id,
limit: 1,
}).then((res) => {
hasRenotedBefore = res.length > 0;
});
let hasRenotedBefore = $ref(props.note.isRenoted ?? false);
const renote = (viaKeyboard = false, ev?: MouseEvent) => {
pleaseLogin();

View file

@ -151,6 +151,7 @@ export type Note = {
localOnly?: boolean;
channel?: Channel["id"];
myReaction?: string;
isRenoted?: boolean;
reactions: Record<string, number>;
renoteCount: number;
repliesCount: number;