R4 the client catches up: follow requests, followers, downvotes, dismissing, filtering a post, quote policies, statistics in detail
Build / Build (push) Successful in 1m8s

Follow requests answered on the persona's own profile and from the Notifications tab; its followers and the accounts it
follows listed there, a follower removed (asked first). Downvotes on threadiverse posts, after the public-vote notice.
A notification dismissed from its line. "Filter this post" from a card's menu, and the Filters page showing the posts a
filter holds. Who may quote the persona's own posts, and revoking a quote of one. Statistics: a server in detail with
"describe again", the ledger's events, the server's own days. The composer deletes an upload taken out before posting.
MediaType.Documents goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-17 04:02:20 +02:00
1 parent b731d8c8c0
commit b8d7858acb
25 files changed
+1543 -61

No files matched your search

+31 -4
View File
@@ -6,7 +6,9 @@
@* An account as the current persona sees it (/api/v1/accounts/{id}): its header, bio and fields, its counts, what it is
to the persona (following, followed by, requested, blocked, muted) with the actions that change it, and its posts,
page by page, as posts only, posts and replies, or media. A remote account's profile comes from what PrivaPub knows,
never from its server directly. *@
never from its server directly. On the persona's own profile its counts open its followers and the accounts it follows
(AccountListDialog: PrivaPub lists them to the persona alone, so another profile keeps plain counts), and the follow
requests waiting for it show above its posts. *@
<section class="block relative w-full h-full neo-inset neo-xs rounded-xl">
<div class="flex flex-col gap-4 p-4 md:p-5 w-full h-full absolute overflow-y-auto">
@@ -142,13 +144,34 @@
</dl>
}
<div class="flex flex-wrap gap-4 px-4 py-3 text-sm tabular-nums">
<div class="flex flex-wrap items-center gap-4 px-4 py-3 text-sm tabular-nums">
<span><b>@account.StatusesCount</b> @Localizer["posts"]</span>
<span><b>@account.FollowingCount</b> @Localizer["following"]</span>
<span><b>@account.FollowersCount</b> @Localizer["followers"]</span>
@if (IsOwn)
{
<button type="button" class="link link-hover touch-target" @onclick="() => showAccounts = false" data-profile-following>
<b>@account.FollowingCount</b> @Localizer["following"]
</button>
<button type="button" class="link link-hover touch-target" @onclick="() => showAccounts = true" data-profile-followers>
<b>@account.FollowersCount</b> @Localizer["followers"]
</button>
}
else
{
<span><b>@account.FollowingCount</b> @Localizer["following"]</span>
<span><b>@account.FollowersCount</b> @Localizer["followers"]</span>
}
</div>
</article>
@if (IsOwn)
{
@if (showAccounts is { } followers)
{
<AccountListDialog AccountId="@account.Id" Followers="followers" OnClosed="@(() => showAccounts = null)" OnRemoved="FollowerRemoved" />
}
<FollowRequestsPanel HideWhenEmpty="true" ShowHeading="true" />
}
<DTabs Active="(int)tab" ActiveChanged="SelectTab" Variant="DTabsVariant.Box" Size="DSize.Sm" ContentClass="hidden">
<DTab><Header><span class="capitalize">@Localizer["posts"]</span></Header></DTab>
<DTab><Header>@Localizer["Posts and replies"]</Header></DTab>
@@ -212,6 +235,8 @@
bool isLoadingMore;
bool isListMenuOpen;
bool isReporting;
// the persona's own followers (true) or the accounts it follows (false), while that list is open
bool? showAccounts;
List<MastodonList> allLists = [];
HashSet<string> inLists = [];
@@ -359,6 +384,8 @@
});
}
void FollowerRemoved(Account follower) => account.FollowersCount = Math.Max(0, account.FollowersCount - 1);
void Remove(FeedPost post)
{
posts.RemoveAll(p => p.Key == post.Key);