add support deletion

This commit is contained in:
2026-08-08 13:13:30 +07:00
parent c9b8edff87
commit b3b0824e83
5 changed files with 151 additions and 30 deletions
+23 -14
View File
@@ -5,7 +5,7 @@ use std::time::Duration;
use anyhow::Error;
use gpui::{AppContext, Context, Subscription, Task};
use nostr_sdk::prelude::*;
use signed_core::{Announcement, RepoAddr, filters, repo_addr};
use signed_core::{Announcement, Deletions, RepoAddr, filters, repo_addr};
use crate::backend::{Backend, BackendEvent};
@@ -40,9 +40,12 @@ impl RepoListStore {
let subscription = cx.subscribe(&backend, |this, _backend, event, cx| {
let relevant = match event {
BackendEvent::NostrUpdate(update) => {
// Activity (patches, issues, ...) is addressed to repos via
// `a` tags, so its author isn't the repo owner; always refresh.
if filters::ACTIVITY_KINDS.contains(&update.kind) {
// Deletions may target anything we list; always refresh.
if update.kind == Kind::EventDeletion || update.kind == Kind::RequestToVanish {
true
} else if filters::ACTIVITY_KINDS.contains(&update.kind) {
// Activity (patches, issues, ...) is addressed to repos via
// `a` tags, so its author isn't the repo owner; always refresh.
true
} else {
let is_announcement = update.kind == Kind::GitRepoAnnouncement;
@@ -98,6 +101,9 @@ impl RepoListStore {
None => filters::all_announcements(),
};
backend.sync_bootstrap(filter, cx);
// Deletion requests (NIP-09/62) must be known before any
// announcement can be shown.
backend.sync_bootstrap(filters::deletions(), cx);
});
}
@@ -143,12 +149,18 @@ impl RepoListStore {
};
let events = client.database().query(filter).await?;
let deletion_events = client.database().query(filters::deletions()).await?;
let deletions = Deletions::from_events(deletion_events);
// Dedup and sort off the main thread; only the final list
// crosses back into the entity.
let mut by_repo: HashMap<RepoAddr, Announcement> = HashMap::new();
for event in events {
if deletions.is_deleted(&event) {
continue;
}
let Some(announcement) = Announcement::from_event(&event) else {
continue;
};
@@ -175,6 +187,9 @@ impl RepoListStore {
let state_filter = Filter::new().kind(Kind::RepoState);
for event in client.database().query(state_filter).await? {
if deletions.is_deleted(&event) {
continue;
}
let Some(id) = event.tags.identifier() else {
continue;
};
@@ -191,16 +206,10 @@ impl RepoListStore {
.kinds(filters::ACTIVITY_KINDS)
.since(Timestamp::now() - ACTIVITY_WINDOW);
for event in client.database().query(activity_filter).await? {
for tag in event.tags.iter() {
if tag.kind() != "a" {
continue;
}
let Some(content) = tag.content() else {
continue;
};
let Ok(addr) = Coordinate::parse(content) else {
continue;
};
if deletions.is_deleted(&event) {
continue;
}
for addr in event.tags.coordinates() {
if addr.kind != Kind::GitRepoAnnouncement {
continue;
}