Notifications in groups, and what is unread

The Notifications tab reads grouped notifications (/api/v2/notifications):
likes and boosts of one post, or follows of one hour, are one card naming
both accounts of a pair, or the newest and how many others, with their
avatars. A notification the stream tells joins its group and waits on top.
The tab's badge counts what is unread; opening the tab moves the
notifications marker to the newest shown, which reads it on PrivaPub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-05 04:35:23 +02:00
1 parent 963565b316
commit a4d9831691
11 files changed
+263 -12

No files matched your search

+20 -1
View File
@@ -34,8 +34,18 @@
@if (Post.Notification is { } notification)
{
<p class="inline-flex flex-wrap items-center gap-2 min-w-0 text-xs">
<p class="inline-flex flex-wrap items-center gap-2 min-w-0 text-xs" data-notification="@notification.Type" data-count="@Post.GroupCount">
<i aria-hidden="true" class="@NotificationIcon(notification.Type)"></i>
@if (Post.GroupAccounts.Count > 1)
{
<span class="flex" aria-hidden="true">
@foreach (var account in Post.GroupAccounts.Take(4))
{
@* alt="": the names are in the text next to them. *@
<img alt="" class="h-5 w-5 -ml-2 first:ml-0 rounded-full object-cover ring-2 ring-base-100" src="@(account.Avatar ?? "imgs/icon-192.png")" title="@account.Name" />
}
</span>
}
<span>@NotificationText(notification)</span>
<span class="opacity-60" title="@NerdRow.Time(notification.CreatedAt)">@notification.CreatedAt.GetPassedTime(Localizer)</span>
</p>
@@ -663,8 +673,17 @@
string NotificationText(Notification notification)
{
var name = notification.Account?.Name;
var others = Post.GroupCount - 1;
// two are both named; more are the newest and a count
var second = others == 1 && Post.GroupAccounts.Count > 1 ? Post.GroupAccounts[1].Name : null;
return notification.Type switch
{
"favourite" when second is not null => Localizer["{0} and {1} favourited your post", name, second],
"reblog" when second is not null => Localizer["{0} and {1} boosted your post", name, second],
"follow" when second is not null => Localizer["{0} and {1} followed you", name, second],
"favourite" when others > 0 => Localizer["{0} and {1} others favourited your post", name, others],
"reblog" when others > 0 => Localizer["{0} and {1} others boosted your post", name, others],
"follow" when others > 0 => Localizer["{0} and {1} others followed you", name, others],
"favourite" => Localizer["{0} favourited your post", name],
"reblog" => Localizer["{0} boosted your post", name],
"mention" => Localizer["{0} mentioned you", name],
+6
View File
@@ -14,6 +14,10 @@
<Header>
<i class="@type.GetTimelineTypeIcon()" aria-hidden="true"></i>
<span class="@(type == Filter.TimelineType ? null : "hidden xl:inline")">@TabName(type)</span>
@if (type is TimelineType.Notifications && UnreadNotifications > 0)
{
<DBadge Size="DSize.Xs" Color="DColor.Primary" title="@Localizer["{0} unread", UnreadNotifications]" data-unread>@UnreadNotifications</DBadge>
}
</Header>
</DTab>
}
@@ -92,6 +96,8 @@
[Parameter, EditorRequired] public FeedFilter Filter { get; set; }
[Parameter] public List<ViewGroup> Groups { get; set; } = [];
[Parameter] public List<MastodonList> Lists { get; set; } = [];
/// <summary>Groups of notifications newer than the persona's marker; a badge on the Notifications tab.</summary>
[Parameter] public int UnreadNotifications { get; set; }
[Parameter] public IEnumerable<NerdRow> Stats { get; set; } = [];
[Parameter] public bool IsComposing { get; set; }
[Parameter] public EventCallback OnCompose { get; set; }