a fork of iceshrimp.net but a tweaked frontend to my personal liking. waow
fediverse social-media social iceshrimp fedi
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[backend/api] Correctly render replies/renotes/quotes (ISH-205)

+82 -14
+44 -3
Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs
··· 11 11 { 12 12 public async Task<NoteResponse> RenderOne(Note note, User? localUser, NoteRendererDto? data = null) 13 13 { 14 + var res = await RenderBaseInternal(note, localUser, data); 15 + 16 + var renote = note.Renote is { IsPureRenote: true } ? await RenderRenote(note.Renote, localUser, data) : null; 17 + var quote = note.Renote is { IsPureRenote: false } ? await RenderBase(note.Renote, localUser, data) : null; 18 + var reply = note.Reply != null ? await RenderBase(note.Reply, localUser, data) : null; 19 + 20 + res.Renote = renote; 21 + res.RenoteId = note.RenoteId; 22 + res.Quote = quote; 23 + res.QuoteId = note.RenoteId; 24 + res.Reply = reply; 25 + res.ReplyId = note.ReplyId; 26 + 27 + return res; 28 + } 29 + 30 + private async Task<NoteWithQuote> RenderRenote(Note note, User? localUser, NoteRendererDto? data = null) 31 + { 32 + var res = await RenderBaseInternal(note, localUser, data); 33 + var quote = note.Renote is { IsPureRenote: false } ? await RenderBase(note.Renote, localUser, data) : null; 34 + 35 + res.Quote = quote; 36 + res.QuoteId = note.RenoteId; 37 + 38 + return res; 39 + } 40 + 41 + private async Task<NoteBase> RenderBase(Note note, User? localUser, NoteRendererDto? data = null) 42 + => await RenderBaseInternal(note, localUser, data); 43 + 44 + private async Task<NoteResponse> RenderBaseInternal(Note note, User? localUser, NoteRendererDto? data = null) 45 + { 14 46 var user = (data?.Users ?? await GetUsers([note])).First(p => p.Id == note.User.Id); 15 47 var attachments = (data?.Attachments ?? await GetAttachments([note])).Where(p => note.FileIds.Contains(p.Id)); 16 48 var reactions = (data?.Reactions ?? await GetReactions([note], localUser)).Where(p => p.NoteId == note.Id); ··· 87 119 return res; 88 120 } 89 121 122 + private static List<Note> GetAllNotes(IEnumerable<Note> notes) 123 + { 124 + return notes.SelectMany<Note, Note?>(p => [p, p.Reply, p.Renote, p.Renote?.Renote]) 125 + .OfType<Note>() 126 + .Distinct() 127 + .ToList(); 128 + } 129 + 90 130 public async Task<IEnumerable<NoteResponse>> RenderMany(IEnumerable<Note> notes, User? user) 91 131 { 92 132 var notesList = notes.ToList(); 133 + var allNotes = GetAllNotes(notesList); 93 134 var data = new NoteRendererDto 94 135 { 95 - Users = await GetUsers(notesList), 96 - Attachments = await GetAttachments(notesList), 97 - Reactions = await GetReactions(notesList, user) 136 + Users = await GetUsers(allNotes), 137 + Attachments = await GetAttachments(allNotes), 138 + Reactions = await GetReactions(allNotes, user) 98 139 }; 99 140 100 141 return await notesList.Select(p => RenderOne(p, user, data)).AwaitAllAsync();
+8 -6
Iceshrimp.Backend/Controllers/Schemas/NoteResponse.cs
··· 3 3 4 4 namespace Iceshrimp.Backend.Controllers.Schemas; 5 5 6 - public class NoteResponse : NoteBase 6 + public class NoteResponse : NoteWithQuote 7 7 { 8 - [J("reply")] public NoteBase? Reply { get; set; } 9 - [J("renote")] public NoteRenote? Renote { get; set; } 10 - [J("quote")] public NoteBase? Quote { get; set; } 8 + [J("reply")] public NoteBase? Reply { get; set; } 9 + [J("replyId")] public string? ReplyId { get; set; } 10 + [J("renote")] public NoteWithQuote? Renote { get; set; } 11 + [J("renoteId")] public string? RenoteId { get; set; } 11 12 } 12 13 13 - public class NoteRenote : NoteBase 14 + public class NoteWithQuote : NoteBase 14 15 { 15 - [J("quote")] public NoteBase? Quote { get; set; } 16 + [J("quote")] public NoteBase? Quote { get; set; } 17 + [J("quoteId")] public string? QuoteId { get; set; } 16 18 } 17 19 18 20 public class NoteBase
+3 -1
Iceshrimp.Backend/Core/Database/Tables/Note.cs
··· 280 280 (Visibility == NoteVisibility.Followers && 281 281 (User.IsFollowedBy(user) || ReplyUserId == user.Id)); 282 282 283 - public Note WithPrecomputedVisibilities(bool reply, bool renote) 283 + public Note WithPrecomputedVisibilities(bool reply, bool renote, bool renoteRenote) 284 284 { 285 285 if (Reply != null) 286 286 PrecomputedIsReplyVisible = reply; 287 287 if (Renote != null) 288 288 PrecomputedIsRenoteVisible = renote; 289 + if (Renote?.Renote != null) 290 + Renote.PrecomputedIsRenoteVisible = renoteRenote; 289 291 290 292 return this; 291 293 }
+2 -2
Iceshrimp.Backend/Core/Database/Tables/Notification.cs
··· 126 126 [StringLength(32)] 127 127 public string Id { get; set; } = null!; 128 128 129 - public Notification WithPrecomputedNoteVisibilities(bool reply, bool renote) 129 + public Notification WithPrecomputedNoteVisibilities(bool reply, bool renote, bool renoteRenote) 130 130 { 131 - Note = Note?.WithPrecomputedVisibilities(reply, renote); 131 + Note = Note?.WithPrecomputedVisibilities(reply, renote, renoteRenote); 132 132 return this; 133 133 } 134 134 }
+25 -2
Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs
··· 225 225 { 226 226 return query.Select(p => p.WithPrecomputedVisibilities(p.Reply != null && p.Reply.IsVisibleFor(user), 227 227 p.Renote != null && 228 - p.Renote.IsVisibleFor(user))); 228 + p.Renote.IsVisibleFor(user), 229 + p.Renote != null && 230 + p.Renote.Renote != null && 231 + p.Renote.Renote.IsVisibleFor(user))); 229 232 } 230 233 231 234 public static IQueryable<Notification> PrecomputeNoteVisibilities(this IQueryable<Notification> query, User user) ··· 235 238 p.Note.Reply.IsVisibleFor(user), 236 239 p.Note != null && 237 240 p.Note.Renote != null && 238 - p.Note.Renote.IsVisibleFor(user))); 241 + p.Note.Renote.IsVisibleFor(user), 242 + p.Note != null && 243 + p.Note.Renote != null && 244 + p.Note.Renote.Renote != null && 245 + p.Note.Renote.Renote.IsVisibleFor(user))); 239 246 } 240 247 241 248 public static IQueryable<User> PrecomputeRelationshipData(this IQueryable<User> query, User user) ··· 251 258 return query.Where(note => !note.User.IsBlocking(user) && !note.User.IsBlockedBy(user)) 252 259 .Where(note => note.Renote == null || 253 260 (!note.Renote.User.IsBlockedBy(user) && !note.Renote.User.IsBlocking(user))) 261 + .Where(note => note.Renote == null || 262 + note.Renote.Renote == null || 263 + (!note.Renote.Renote.User.IsBlockedBy(user) && 264 + !note.Renote.Renote.User.IsBlocking(user))) 254 265 .Where(note => note.Reply == null || 255 266 (!note.Reply.User.IsBlockedBy(user) && !note.Reply.User.IsBlocking(user))); 256 267 } ··· 275 286 (note.Renote == null || 276 287 (!note.Renote.User.IsBlockedBy(user) && 277 288 !note.Renote.User.IsBlocking(user))) && 289 + (note.Renote == null || 290 + note.Renote.Renote == null || 291 + (!note.Renote.Renote.User.IsBlockedBy(user) && 292 + !note.Renote.Renote.User.IsBlocking(user))) && 278 293 (note.Reply == null || 279 294 (!note.Reply.User.IsBlockedBy(user) && 280 295 !note.Reply.User.IsBlocking(user)))))); ··· 286 301 287 302 return query.Where(note => !note.User.IsMuting(user)) 288 303 .Where(note => note.Renote == null || !note.Renote.User.IsMuting(user)) 304 + .Where(note => note.Renote == null || 305 + note.Renote.Renote == null || 306 + !note.Renote.Renote.User.IsMuting(user)) 289 307 .Where(note => note.Reply == null || !note.Reply.User.IsMuting(user)); 290 308 } 291 309 ··· 315 333 note.Reply = null; 316 334 if (!(note.PrecomputedIsRenoteVisible ?? false)) 317 335 note.Renote = null; 336 + if (note.Renote?.Renote != null && !(note.Renote.PrecomputedIsRenoteVisible ?? false)) 337 + note.Renote.Renote = null; 318 338 319 339 return note; 320 340 } ··· 332 352 note.Reply = null; 333 353 if (!(note.PrecomputedIsRenoteVisible ?? false)) 334 354 note.Renote = null; 355 + if (note.Renote?.Renote != null && !(note.Renote.PrecomputedIsRenoteVisible ?? false)) 356 + note.Renote.Renote = null; 335 357 336 358 return source; 337 359 } ··· 444 466 { 445 467 return query.Include(p => p.User.UserProfile) 446 468 .Include(p => p.Renote.User.UserProfile) 469 + .Include(p => p.Renote.Renote.User.UserProfile) 447 470 .Include(p => p.Reply.User.UserProfile); 448 471 } 449 472