forked from FoundKeyGang/FoundKey
Modify social timeline to exclude convos with only 1 person I like
This is an attempt at introducing filtering of replies in timeline in the style of Mastodon or Pleroma's "only replies directed at me or someone I follow". Currently one way this surely fails is that self-replies by someone I follow in a conversation solely with someone I don't follow will pass this filter, and I will see a conversation I don't want to see. This probably needs more testing to verify that it's doing what's expected of it.
This commit is contained in:
parent
b74c924f66
commit
191b2692d2
6 changed files with 14 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
|||
import { Brackets, SelectQueryBuilder } from 'typeorm';
|
||||
import { User } from '@/models/entities/user.js';
|
||||
|
||||
export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User, 'id' | 'showTimelineReplies'> | null) {
|
||||
export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User, 'id' | 'showTimelineReplies'> | null, followingQuery: SelectQueryBuilder<any> | null) {
|
||||
if (me == null) {
|
||||
q.andWhere(new Brackets(qb => { qb
|
||||
.where('note.replyId IS NULL') // 返信ではない
|
||||
|
@ -14,6 +14,7 @@ export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User,
|
|||
q.andWhere(new Brackets(qb => { qb
|
||||
.where('note.replyId IS NULL') // 返信ではない
|
||||
.orWhere('note.replyUserId = :meId', { meId: me.id }) // 返信だけど自分のノートへの返信
|
||||
.orWhere('note.mentions && array[:meId]::varchar[]', { meId: me.id })
|
||||
.orWhere(new Brackets(qb => { qb // 返信だけど自分の行った返信
|
||||
.where('note.replyId IS NOT NULL')
|
||||
.andWhere('note.userId = :meId', { meId: me.id });
|
||||
|
@ -22,6 +23,12 @@ export function generateRepliesQuery(q: SelectQueryBuilder<any>, me?: Pick<User,
|
|||
.where('note.replyId IS NOT NULL')
|
||||
.andWhere('note.replyUserId = note.userId');
|
||||
}));
|
||||
if (followingQuery !== null) {
|
||||
qb.orWhere(new Brackets(qb => { qb
|
||||
.where(`note.mentions && array(${ followingQuery.getQuery() })`)
|
||||
.setParameters(followingQuery.getParameters())
|
||||
}))
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
.leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar')
|
||||
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
|
||||
|
||||
generateRepliesQuery(query, user);
|
||||
generateRepliesQuery(query, user, null);
|
||||
if (user) {
|
||||
generateMutedUserQuery(query, user);
|
||||
generateMutedNoteQuery(query, user);
|
||||
|
|
|
@ -89,7 +89,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
.setParameters(followingQuery.getParameters());
|
||||
|
||||
generateChannelQuery(query, user);
|
||||
generateRepliesQuery(query, user);
|
||||
generateRepliesQuery(query, user, followingQuery);
|
||||
generateVisibilityQuery(query, user);
|
||||
generateMutedUserQuery(query, user);
|
||||
generateMutedNoteQuery(query, user);
|
||||
|
|
|
@ -82,7 +82,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
.leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner');
|
||||
|
||||
generateChannelQuery(query, user);
|
||||
generateRepliesQuery(query, user);
|
||||
generateRepliesQuery(query, user, null);
|
||||
generateVisibilityQuery(query, user);
|
||||
if (user) generateMutedUserQuery(query, user);
|
||||
if (user) generateMutedNoteQuery(query, user);
|
||||
|
|
|
@ -81,7 +81,7 @@ export default define(meta, paramDef, async (ps, user) => {
|
|||
.setParameters(followingQuery.getParameters());
|
||||
|
||||
generateChannelQuery(query, user);
|
||||
generateRepliesQuery(query, user);
|
||||
generateRepliesQuery(query, user, followingQuery);
|
||||
generateVisibilityQuery(query, user);
|
||||
generateMutedUserQuery(query, user);
|
||||
generateMutedNoteQuery(query, user);
|
||||
|
|
|
@ -40,11 +40,8 @@ export default class extends Channel {
|
|||
// Ignore notes from instances the user has muted
|
||||
if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return;
|
||||
|
||||
// 関係ない返信は除外
|
||||
if (note.reply && !this.user!.showTimelineReplies) {
|
||||
const reply = note.reply;
|
||||
// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
|
||||
if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
|
||||
if (note.reply && note.mentions && !this.user!.showTimelineReplies) {
|
||||
if (!note.mentions.includes(this.user!.id) && !note.mentions.some((user: string) => this.following.has(user))) return;
|
||||
}
|
||||
|
||||
// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
||||
|
|
Loading…
Reference in a new issue