/api/v1/conversations answered one page, never unread, its read endpoint did nothing, and DELETE was missing; each conversation cost a query per member. Now each conversation keeps its newest post (DmGroup.LastPostId, set as posts arrive, learnt once by migration _013) and pages by it as Mastodon does, and each persona's ConversationState holds what it read and what it took off its list: - unread when someone else wrote last, after what the persona read; - read marks it so, and writing in a conversation reads it; - DELETE takes it off the list until a newer message brings it back. The list reads its states, newest posts, members and accounts in a few queries per page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
25 lines
937 B
C#
25 lines
937 B
C#
using MongoDB.Entities;
|
|
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace PrivaPub.Models.Group
|
|
{
|
|
public class DmGroup : Entity
|
|
{
|
|
public string Description { get; set; }
|
|
public List<GroupMember> Members { get; set; } = new();
|
|
public string ConversationURI { get; set; }//context of the federated thread
|
|
public string ParticipantsKey { get; set; }
|
|
public string LastPostId { get; set; }//its newest post, which pages the conversations list (ConversationStates)
|
|
|
|
public DateTime CreationDate { get; set; } = DateTime.UtcNow;
|
|
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
|
public DateTime? DeletionAt { get; set; }
|
|
|
|
public static string KeyOf(IEnumerable<GroupMember> members) =>
|
|
Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(string.Join("\n",
|
|
members.Select(m => (m.IsForeign ? "remote:" : "local:") + m.AvatarId).Distinct().Order(StringComparer.Ordinal)))));
|
|
}
|
|
}
|