A located post's author deletes it
A located post's card had no action at all, so whoever wrote one (with this device's position) could not take it back from the app. The persona's own located card now has Delete, which asks first, without the line about other servers (a located post never left PrivaPub), and goes through /clientapi/post/delete, since the Mastodon API looks past located posts. The globe's end-to-end test deletes the post it writes this way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
eade4e399a
commit
e88f4afc45
5 files changed
+32
-8
No files matched your search
@@ -285,7 +285,7 @@ supplies:
|
||||
`/clientapi/post/nearby` and have no Mastodon actions), `StatusService` (publish, favourite, boost, bookmark, delete,
|
||||
threads, mute, block, poll votes, emoji reactions through Pleroma's `/api/v1/pleroma/statuses/:id/reactions`, joining and
|
||||
leaving remote events through `/api/privapub/v1/statuses/:id/join|leave`; located and group posts go through
|
||||
`/clientapi/post/insert`), `AccountService` (profiles, relationships, follow,
|
||||
`/clientapi/post/insert`, and a located post's author deletes it through `/clientapi/post/delete`, its card's one action), `AccountService` (profiles, relationships, follow,
|
||||
block, mute, follow requests, `/api/v2/search`, whose handles and URLs PrivaPub resolves), `ListService` (the
|
||||
persona's lists and their members; members are only accounts it follows, found with `accounts/search?following=true`),
|
||||
`FilterService` (the persona's v2 filters, their keywords and filtered posts), `DiscoveryService` (hashtags and
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace decePubClient;
|
||||
[JsonSerializable(typeof(ViewPost))]
|
||||
[JsonSerializable(typeof(List<ViewPost>))]
|
||||
[JsonSerializable(typeof(InsertPostForm))]
|
||||
[JsonSerializable(typeof(DeletePostForm))]
|
||||
[JsonSerializable(typeof(ViewReport))]
|
||||
[JsonSerializable(typeof(List<ViewReport>))]
|
||||
[JsonSerializable(typeof(DomainBlockForm))]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
quoted post (Compact) has none, since it is not an item of the feed. A CDN-fronted server's post has no point, only
|
||||
its CDN's group (data-cdn); data-post-at is when it was written, for the globe's Sun; data-uri is its ActivityPub id,
|
||||
which the e2e tests (tests/e2e) find it by. The persona's filters apply where the page says the card is (FilterIn): a
|
||||
hide filter leaves it out, a warn filter folds it behind the filter's title, a blur filter blurs its media. Located posts have no actions: PrivaPub keeps them off the Mastodon API. Nerd stats are on
|
||||
hide filter leaves it out, a warn filter folds it behind the filter's title, a blur filter blurs its media. Located posts have no Mastodon actions (PrivaPub keeps them off the Mastodon API); their author deletes them through /clientapi. Nerd stats are on
|
||||
the time, the author and its server's history, the place or the CDN, the media and the counts. *@
|
||||
@if (!IsFilteredOut)
|
||||
{
|
||||
@@ -211,10 +211,20 @@
|
||||
|
||||
@if (Post.Located)
|
||||
{
|
||||
<p class="inline-flex gap-2 items-center text-xs opacity-70">
|
||||
<i class="ion-md-locate"></i>
|
||||
<span>@Localizer["{0} km from you, shown within {1} km", Number(Post.DistanceKm), Number(Post.RangeKm)]</span>
|
||||
</p>
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs">
|
||||
<p class="inline-flex gap-2 items-center opacity-70">
|
||||
<i class="ion-md-locate"></i>
|
||||
<span>@Localizer["{0} km from you, shown within {1} km", Number(Post.DistanceKm), Number(Post.RangeKm)]</span>
|
||||
</p>
|
||||
@* its author takes it back here: it has no other action *@
|
||||
@if (IsOwn && !Compact)
|
||||
{
|
||||
<DButton Size="DSize.Xs" class="ml-auto" Disabled="IsDefaultDisabled || isActing" OnClick="Delete" data-located-delete>
|
||||
<i aria-hidden="true" class="ion-md-trash text-error"></i>
|
||||
<span>@Localizer["Delete"]</span>
|
||||
</DButton>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (status.Privapub?.Approval is "pending" or "rejected")
|
||||
@@ -949,11 +959,12 @@
|
||||
|
||||
async Task Delete()
|
||||
{
|
||||
if (!await Confirm.Ask(Localizer["Delete this post?"], Localizer["It goes from here, and the servers that have it are asked to delete it too."],
|
||||
// a located post never left PrivaPub: no server is asked
|
||||
if (!await Confirm.Ask(Localizer["Delete this post?"], Post.Located ? null : Localizer["It goes from here, and the servers that have it are asked to delete it too."],
|
||||
Localizer["Delete"], true))
|
||||
return;
|
||||
isActing = true;
|
||||
var result = await StatusService.Delete(Status.Id);
|
||||
var result = Post.Located ? await StatusService.DeleteLocated(Status.Id, CascadingState.PersonaId) : await StatusService.Delete(Status.Id);
|
||||
isActing = false;
|
||||
if (result.IsInvalid)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ public static class APIs
|
||||
public const string GET_Posts = "clientapi/post/list";
|
||||
public const string GET_Nearby = "clientapi/post/nearby";
|
||||
public const string POST_InsertPost = "clientapi/post/insert";
|
||||
public const string POST_DeletePost = "clientapi/post/delete";
|
||||
public const string GET_ModeratorReports = "clientapi/moderator/reports";
|
||||
public static string POST_M_ResolveReport(string reportId) => $"clientapi/moderator/reports/{Uri.EscapeDataString(reportId)}/resolve";
|
||||
public const string GET_AdminDomainBlocks = "clientapi/admin/domainblocks/list";
|
||||
|
||||
@@ -228,6 +228,17 @@ namespace decePubClient.Services
|
||||
return await StatusResult(response, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>Deletes the persona's own located post: through /clientapi, since the Mastodon API looks past located posts.</summary>
|
||||
public async Task<WebResult> DeleteLocated(string postId, string personaId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var response = await httpService.Post(APIs.ClientApi.POST_DeletePost, new DeletePostForm { AvatarId = personaId, PostId = postId },
|
||||
cancellationToken: cancellationToken);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
return await response.Content.ReadWebResult(response.StatusCode, localizer, cancellationToken);
|
||||
|
||||
return new WebResult();
|
||||
}
|
||||
|
||||
public async Task<Status> Get(string statusId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var response = await httpService.Get(APIs.Mastodon.GET_M_Status(statusId), cancellationToken: cancellationToken);
|
||||
|
||||
Reference in new issue
Block a user