Files
FrozenFriendsYume/packages/backend/built/server/api/common/inject-featured.js
T
2026-07-26 18:25:37 +09:00

38 lines
1.7 KiB
JavaScript

import rndstr from "rndstr";
import { Notes, UserProfiles, NoteReactions } from "../../../models/index.js";
import { generateMutedUserQuery } from "./generate-muted-user-query.js";
import { generateBlockedUserQuery } from "./generate-block-query.js";
// TODO: リアクション、Renote、返信などをしたノートは除外する
export async function injectFeatured(timeline, user) {
if (timeline.length < 5) return;
if (user) {
const profile = await UserProfiles.findOneByOrFail({
userId: user.id
});
if (!profile.injectFeaturedNote) return;
}
const max = 30;
const day = 1000 * 60 * 60 * 24 * 3; // 3日前まで
const query = Notes.createQueryBuilder("note").addSelect("note.score").where("note.userHost IS NULL").andWhere("note.score > 0").andWhere("note.createdAt > :date", {
date: new Date(Date.now() - day)
}).andWhere(`note.visibility = 'public'`).innerJoinAndSelect("note.user", "user");
if (user) {
query.andWhere("note.userId != :userId", {
userId: user.id
});
generateMutedUserQuery(query, user);
generateBlockedUserQuery(query, user);
const reactionQuery = NoteReactions.createQueryBuilder("reaction").select("reaction.noteId").where("reaction.userId = :userId", {
userId: user.id
});
query.andWhere(`note.id NOT IN (${reactionQuery.getQuery()})`);
}
const notes = await query.orderBy("note.score", "DESC").take(max).getMany();
if (notes.length === 0) return;
// Pick random one
const featured = notes[Math.floor(Math.random() * notes.length)];
featured._featuredId_ = rndstr("a-z0-9", 8);
// Inject featured
timeline.splice(3, 0, featured);
}