reorganize signed_core into method-based APIs
This commit is contained in:
@@ -11,7 +11,7 @@ use nostr::nips::nip19::Nip19Coordinate;
|
||||
use nostr_connect::prelude::*;
|
||||
use nostr_sdk::client::SyncSummary;
|
||||
use nostr_sdk::prelude::*;
|
||||
use signed_core::{Announcement, RepoAddr, build_state, filters, identifier_from_name, repo_addr};
|
||||
use signed_core::{Announcement, Filters, RepoAddr, RepoState, filters};
|
||||
use signed_nostr::{SignedAuthUrlHandler, UniversalSigner, Update};
|
||||
|
||||
use crate::git_store::repo_mirror_path;
|
||||
@@ -388,7 +388,7 @@ impl Backend {
|
||||
return Task::ready(Err(anyhow!("Sign in to create a repository")));
|
||||
};
|
||||
|
||||
let repo_id = identifier_from_name(&name);
|
||||
let repo_id = RepoAddr::identifier_from_name(&name);
|
||||
|
||||
if repo_id.is_empty() || repo_id.len() > 100 {
|
||||
return Task::ready(Err(anyhow!(
|
||||
@@ -563,7 +563,7 @@ impl Backend {
|
||||
return Task::ready(Err(anyhow!("Sign in to publish a repository")));
|
||||
};
|
||||
|
||||
let repo_id = identifier_from_name(&name);
|
||||
let repo_id = RepoAddr::identifier_from_name(&name);
|
||||
|
||||
if repo_id.is_empty() || repo_id.len() > 100 {
|
||||
return Task::ready(Err(anyhow!(
|
||||
@@ -694,8 +694,8 @@ impl Backend {
|
||||
|
||||
// Record the ngit-compatible `nostr.repo` marker,
|
||||
// so the next scan detects the repository instead of offering to publish it again.
|
||||
let coordinate = repo_addr(event.pubkey, repo_id.clone());
|
||||
match Nip19Coordinate::new(coordinate, servers.clone()).to_bech32() {
|
||||
let coordinate = RepoAddr::new(event.pubkey, repo_id.clone());
|
||||
match Nip19Coordinate::new(coordinate.into(), servers.clone()).to_bech32() {
|
||||
Ok(naddr) => {
|
||||
let path = path.clone();
|
||||
cx.background_spawn(async move {
|
||||
@@ -876,7 +876,7 @@ impl Backend {
|
||||
let Some(public_key) = self.current_user else {
|
||||
return Task::ready(Err(anyhow!("Sign in to delete a repository")));
|
||||
};
|
||||
if public_key != addr.public_key {
|
||||
if public_key != addr.public_key() {
|
||||
return Task::ready(Err(anyhow!("Only the repository owner can delete it")));
|
||||
}
|
||||
|
||||
@@ -888,9 +888,9 @@ impl Backend {
|
||||
let db = client.database();
|
||||
let mut events = Vec::new();
|
||||
for filter in [
|
||||
filters::announcement(&addr),
|
||||
filters::state(&addr),
|
||||
filters::activity(&addr),
|
||||
addr.announcement_filter(),
|
||||
addr.state_filter(),
|
||||
addr.activity_filter(),
|
||||
] {
|
||||
events.extend(db.query(filter).await?);
|
||||
}
|
||||
@@ -914,7 +914,7 @@ impl Backend {
|
||||
let result = async {
|
||||
sync_bootstrap_only(
|
||||
&client,
|
||||
filters::grasp_list(public_key),
|
||||
Filters::grasp_list(public_key),
|
||||
SyncOptions::default(),
|
||||
)
|
||||
.await?;
|
||||
@@ -961,8 +961,8 @@ impl Backend {
|
||||
let me = self.current_user;
|
||||
|
||||
if let Some(me) = me {
|
||||
self.subscribe_bootstrap(filters::notifications(me), cx);
|
||||
self.subscribe_bootstrap(vec![filters::authored_activity(me)], cx);
|
||||
self.subscribe_bootstrap(Filters::notifications(me), cx);
|
||||
self.subscribe_bootstrap(vec![Filters::authored_activity(me)], cx);
|
||||
|
||||
let relays: HashSet<RelayUrl> = RepoListStore::global(cx)
|
||||
.read(cx)
|
||||
@@ -973,8 +973,8 @@ impl Backend {
|
||||
|
||||
if !relays.is_empty() {
|
||||
let relays: Vec<RelayUrl> = relays.into_iter().collect();
|
||||
self.connect_repo_relays(relays.clone(), filters::notifications(me), cx);
|
||||
self.connect_repo_relays(relays, vec![filters::authored_activity(me)], cx);
|
||||
self.connect_repo_relays(relays.clone(), Filters::notifications(me), cx);
|
||||
self.connect_repo_relays(relays, vec![Filters::authored_activity(me)], cx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1357,7 +1357,7 @@ pub async fn user_grasp_list_servers(
|
||||
) -> Result<Vec<RelayUrl>, Error> {
|
||||
let events: Vec<Event> = client
|
||||
.database()
|
||||
.query(filters::grasp_list(user))
|
||||
.query(Filters::grasp_list(user))
|
||||
.await?
|
||||
.into_iter()
|
||||
.collect();
|
||||
@@ -1517,7 +1517,7 @@ async fn sign_state_event(
|
||||
last_created_at + 1
|
||||
};
|
||||
|
||||
let event = build_state(repo_id, refs, head)
|
||||
let event = RepoState::build(repo_id, refs, head)
|
||||
.custom_created_at(Timestamp::from_secs(created_at))
|
||||
.finalize_async(signer)
|
||||
.await
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use anyhow::Error;
|
||||
use gpui::{AppContext, Context, Task};
|
||||
use nostr_sdk::prelude::*;
|
||||
use signed_core::{Deletions, InboxItem, InboxReadState, filters, inbox};
|
||||
use signed_core::{Deletions, Filters, InboxItem, InboxReadState, GitEvent, inbox};
|
||||
|
||||
use crate::backend::Backend;
|
||||
|
||||
@@ -97,7 +97,7 @@ pub async fn query_inbox(
|
||||
me: PublicKey,
|
||||
state: &InboxReadState,
|
||||
) -> Result<(Vec<InboxItem>, usize), Error> {
|
||||
let deletion_events = client.database().query(filters::deletions()).await?;
|
||||
let deletion_events = client.database().query(Filters::deletions()).await?;
|
||||
let deletions = Deletions::from_events(deletion_events);
|
||||
|
||||
let (notification_events, mut by_id) = fetch_notifications(client, me, &deletions).await?;
|
||||
@@ -105,10 +105,10 @@ pub async fn query_inbox(
|
||||
let mut activity = Vec::new();
|
||||
for event in client
|
||||
.database()
|
||||
.query(filters::authored_activity(me))
|
||||
.query(Filters::authored_activity(me))
|
||||
.await?
|
||||
{
|
||||
if deletions.is_deleted(&event) || !filters::is_git_activity(&event) {
|
||||
if deletions.is_deleted(&event) || !event.is_git_activity() {
|
||||
continue;
|
||||
}
|
||||
by_id.entry(event.id).or_insert_with(|| event.clone());
|
||||
@@ -169,7 +169,7 @@ async fn fetch_notifications(
|
||||
let mut notifications: Vec<Event> = Vec::new();
|
||||
let mut by_id: HashMap<EventId, Event> = HashMap::new();
|
||||
|
||||
for filter in filters::notifications(me) {
|
||||
for filter in Filters::notifications(me) {
|
||||
for event in client.database().query(filter).await? {
|
||||
if deletions.is_deleted(&event) {
|
||||
continue;
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::Error;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, SharedString, Task};
|
||||
use signed_core::{Announcement, RepoAddr, repo_addr};
|
||||
use signed_core::{Announcement, RepoAddr};
|
||||
use signed_git::{LocalRepo, Nip34Binding, find_git_repos};
|
||||
|
||||
struct GlobalLocalReposStore(Entity<LocalReposStore>);
|
||||
@@ -113,7 +113,7 @@ pub fn local_repo_addr(repo: &LocalRepo) -> Option<RepoAddr> {
|
||||
let owner = binding.owner?;
|
||||
let identifier = binding.identifier.as_deref()?;
|
||||
|
||||
Some(repo_addr(owner, identifier))
|
||||
Some(RepoAddr::new(owner, identifier))
|
||||
}
|
||||
|
||||
/// A scanned repository resolved against the known announcements.
|
||||
|
||||
@@ -9,7 +9,8 @@ use nostr::event::IntoEventBuilder;
|
||||
use nostr_sdk::prelude::*;
|
||||
use settings::{EventFetchingStrategy, SettingsStore};
|
||||
use signed_core::{
|
||||
Announcement, Deletions, RepoAddr, RepoStatus, filters, parse_state, pull_request_patches,
|
||||
Announcement, Deletions, Filters, GitEvent, PullRequest, RepoAddr, RepoState, RepoStatus,
|
||||
filters,
|
||||
};
|
||||
use signed_git::Nip34Binding;
|
||||
use signed_nostr::UniversalSigner;
|
||||
@@ -210,8 +211,8 @@ impl RepoStore {
|
||||
let deletion =
|
||||
update.kind == Kind::EventDeletion || update.kind == Kind::RequestToVanish;
|
||||
|
||||
let coordinate = update.coordinate.as_ref() == Some(addr);
|
||||
let author = update.author == addr.public_key;
|
||||
let coordinate = update.coordinate.as_ref() == Some(addr.coordinate());
|
||||
let author = update.author == addr.public_key();
|
||||
|
||||
let authored = (update.kind == Kind::GitRepoAnnouncement
|
||||
|| update.kind == Kind::RepoState)
|
||||
@@ -251,12 +252,12 @@ impl RepoStore {
|
||||
let mut filters = vec![
|
||||
Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.author(addr.public_key)
|
||||
.identifier(addr.identifier.clone()),
|
||||
filters::activity(addr),
|
||||
.author(addr.public_key())
|
||||
.identifier(addr.identifier()),
|
||||
addr.activity_filter(),
|
||||
];
|
||||
// Deletion requests, NIP-09/62, must be known before any event is shown.
|
||||
filters.extend(filters::deletions_for_repo(addr));
|
||||
filters.extend(addr.deletion_filters());
|
||||
filters
|
||||
}
|
||||
|
||||
@@ -290,8 +291,8 @@ impl RepoStore {
|
||||
let mut pubkeys = maintainers.to_vec();
|
||||
// NIP-34 events tag the announcement author,
|
||||
// which may not be a maintainer for subordinate forks.
|
||||
if !pubkeys.contains(&addr.public_key) {
|
||||
pubkeys.push(addr.public_key);
|
||||
if !pubkeys.contains(&addr.public_key()) {
|
||||
pubkeys.push(addr.public_key());
|
||||
}
|
||||
|
||||
vec![
|
||||
@@ -299,16 +300,16 @@ impl RepoStore {
|
||||
Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.authors(pubkeys.clone())
|
||||
.identifier(addr.identifier.clone()),
|
||||
.identifier(addr.identifier()),
|
||||
// Activity tagging a maintainer, resolved to their read relays.
|
||||
Filter::new()
|
||||
.kinds(filters::ACTIVITY_KINDS)
|
||||
.coordinate(addr)
|
||||
.coordinate(addr.coordinate())
|
||||
.pubkeys(pubkeys.clone()),
|
||||
// Activity authored by a maintainer, resolved to their write relays.
|
||||
Filter::new()
|
||||
.kinds(filters::ACTIVITY_KINDS)
|
||||
.coordinate(addr)
|
||||
.coordinate(addr.coordinate())
|
||||
.authors(pubkeys.clone()),
|
||||
// Deletions authored by a maintainer.
|
||||
Filter::new()
|
||||
@@ -377,10 +378,10 @@ impl RepoStore {
|
||||
let work = cx.background_spawn(async move {
|
||||
let (announcements, states, activity, deletion_events) = async {
|
||||
let db = client.database();
|
||||
let announcements = db.query(filters::announcement(&addr)).await?;
|
||||
let states = db.query(filters::state(&addr)).await?;
|
||||
let activity = db.query(filters::activity(&addr)).await?;
|
||||
let deletion_events = db.query(filters::deletions()).await?;
|
||||
let announcements = db.query(addr.announcement_filter()).await?;
|
||||
let states = db.query(addr.state_filter()).await?;
|
||||
let activity = db.query(addr.activity_filter()).await?;
|
||||
let deletion_events = db.query(Filters::deletions()).await?;
|
||||
|
||||
Ok::<_, Error>((announcements, states, activity, deletion_events))
|
||||
}
|
||||
@@ -397,7 +398,7 @@ impl RepoStore {
|
||||
.and_then(Announcement::from_event);
|
||||
|
||||
let all_states = states.into_iter().filter(|e| !deletions.is_deleted(e));
|
||||
let state = utils::latest(all_states).map(|state| parse_state(&state));
|
||||
let state = utils::latest(all_states).map(|state| RepoState::parse(&state));
|
||||
|
||||
let (mut issues, mut patches, mut pull_requests, mut statuses, mut comments) =
|
||||
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
|
||||
@@ -425,7 +426,7 @@ impl RepoStore {
|
||||
.chain(&pull_requests)
|
||||
.map(|e| e.id);
|
||||
|
||||
for filter in filters::comments_for(roots) {
|
||||
for filter in Filters::comments_for(roots) {
|
||||
for event in db.query(filter).await? {
|
||||
if seen_comments.insert(event.id) {
|
||||
comments.push(event);
|
||||
@@ -443,7 +444,7 @@ impl RepoStore {
|
||||
.map(|e| e.id);
|
||||
|
||||
for root in roots {
|
||||
for event in db.query(filters::statuses_for([root])).await? {
|
||||
for event in db.query(Filters::statuses_for([root])).await? {
|
||||
if seen_statuses.insert(event.id) {
|
||||
statuses.push(event);
|
||||
}
|
||||
@@ -516,7 +517,7 @@ impl RepoStore {
|
||||
|
||||
let head_changed = state
|
||||
.as_ref()
|
||||
.is_some_and(|(_, head)| this.head.as_deref() != head.as_deref());
|
||||
.is_some_and(|state| this.head.as_deref() != state.head.as_deref());
|
||||
|
||||
let changed = first_pass
|
||||
|| (!keep_hint && this.announcement != announcement)
|
||||
@@ -549,8 +550,8 @@ impl RepoStore {
|
||||
|
||||
this.sync_maintainer_relays(&maintainers, cx);
|
||||
|
||||
if let Some((_, head)) = state {
|
||||
this.head = head;
|
||||
if let Some(state) = state {
|
||||
this.head = state.head;
|
||||
}
|
||||
|
||||
this.issues = issues;
|
||||
@@ -579,8 +580,8 @@ impl RepoStore {
|
||||
if !new_roots.is_empty() {
|
||||
this.root_fetches.extend(new_roots.iter().copied());
|
||||
|
||||
let mut root_filters = filters::comments_for(new_roots.clone());
|
||||
root_filters.push(filters::statuses_for(new_roots.iter().copied()));
|
||||
let mut root_filters = Filters::comments_for(new_roots.clone());
|
||||
root_filters.push(Filters::statuses_for(new_roots.iter().copied()));
|
||||
|
||||
let announced: Vec<RelayUrl> = this.repo_relays.iter().cloned().collect();
|
||||
let backend = Backend::global(cx);
|
||||
@@ -621,7 +622,7 @@ impl RepoStore {
|
||||
pub fn is_author(&self, user: &PublicKey) -> bool {
|
||||
self.addr
|
||||
.as_ref()
|
||||
.is_some_and(|addr| &addr.public_key == user)
|
||||
.is_some_and(|addr| addr.public_key() == *user)
|
||||
}
|
||||
|
||||
pub fn open_issue(&mut self, subject: Option<String>, content: String, cx: &mut Context<Self>) {
|
||||
@@ -631,7 +632,7 @@ impl RepoStore {
|
||||
};
|
||||
|
||||
let builder = GitIssue {
|
||||
repository: addr,
|
||||
repository: addr.into(),
|
||||
content,
|
||||
subject,
|
||||
labels: Vec::new(),
|
||||
@@ -644,7 +645,7 @@ impl RepoStore {
|
||||
pub fn comments_of(&self, root: &EventId) -> impl Iterator<Item = &Event> {
|
||||
self.comments
|
||||
.iter()
|
||||
.filter(move |e| signed_core::references_root(e, root))
|
||||
.filter(move |e| e.references_root(root))
|
||||
}
|
||||
|
||||
/// Comment on a root event, an issue or PR, per NIP-34, kind 1111.
|
||||
@@ -745,9 +746,9 @@ impl RepoStore {
|
||||
// The author's npub names their GRASP-06 namespace, `/prs/...`.
|
||||
let author_npub = user.to_bech32().unwrap();
|
||||
|
||||
let owner = addr.public_key;
|
||||
let owner = addr.public_key();
|
||||
let euc = self.announcement.as_ref().and_then(|a| a.euc.clone());
|
||||
let repo_id = addr.identifier.clone();
|
||||
let repo_id = addr.identifier().to_owned();
|
||||
let base_npub = owner.to_bech32().unwrap();
|
||||
let push_relays = self
|
||||
.announcement
|
||||
@@ -857,7 +858,7 @@ impl RepoStore {
|
||||
let clone = pr_clone_urls(prs_urls, base_clone);
|
||||
|
||||
let builder = GitPullRequest {
|
||||
repository: addr.clone(),
|
||||
repository: addr.clone().into(),
|
||||
content: description,
|
||||
subject,
|
||||
labels: Vec::new(),
|
||||
@@ -1069,7 +1070,8 @@ impl RepoStore {
|
||||
// The first revision patch replies to the original root patch, NIP-34.
|
||||
// Use the PR's `e` tag, or the oldest patch of the linked set if the PR has none.
|
||||
let root_patch_id = root.tags.event_ids().next().or_else(|| {
|
||||
pull_request_patches(root, self.patches.iter())
|
||||
PullRequest::new(root)
|
||||
.patches(self.patches.iter())
|
||||
.first()
|
||||
.map(|p| p.id)
|
||||
});
|
||||
@@ -1079,7 +1081,7 @@ impl RepoStore {
|
||||
return;
|
||||
};
|
||||
|
||||
let owner = addr.public_key;
|
||||
let owner = addr.public_key();
|
||||
let euc = self.announcement.as_ref().and_then(|a| a.euc.clone());
|
||||
let root = root.clone();
|
||||
|
||||
@@ -1110,7 +1112,7 @@ impl RepoStore {
|
||||
|
||||
let builder = {
|
||||
let builder = GitPullRequestUpdate {
|
||||
repository: addr.clone(),
|
||||
repository: addr.clone().into(),
|
||||
pull_request_event: root.id,
|
||||
pull_request_author: root.pubkey,
|
||||
current_commit,
|
||||
@@ -1182,9 +1184,9 @@ impl RepoStore {
|
||||
|
||||
let builder = EventBuilder::new(status.kind(), "").tags([
|
||||
root_ref,
|
||||
Tag::public_key(addr.public_key),
|
||||
Tag::public_key(addr.public_key()),
|
||||
Tag::public_key(root.pubkey),
|
||||
Tag::coordinate(addr, None),
|
||||
Tag::coordinate(addr.clone().into(), None),
|
||||
]);
|
||||
|
||||
self.publish(builder, cx);
|
||||
@@ -1479,7 +1481,7 @@ fn resolve_statuses(
|
||||
.map(|root| {
|
||||
let events = by_root.get(&root.id).map(Vec::as_slice).unwrap_or(&[]);
|
||||
let status =
|
||||
signed_core::resolve_status(events.iter().copied(), &root.pubkey, maintainers);
|
||||
signed_core::RepoStatus::resolve(events.iter().copied(), &root.pubkey, maintainers);
|
||||
(root.id, status)
|
||||
})
|
||||
.collect()
|
||||
@@ -1518,7 +1520,10 @@ async fn publish_patch_series(
|
||||
));
|
||||
};
|
||||
|
||||
let mut tags = vec![Tag::coordinate(addr.clone(), None), Tag::public_key(owner)];
|
||||
let mut tags = vec![
|
||||
Tag::coordinate(addr.clone().into(), None),
|
||||
Tag::public_key(owner),
|
||||
];
|
||||
|
||||
if ix == 0 {
|
||||
if let Ok(tag) = Tag::parse(["t", first_marker]) {
|
||||
@@ -1586,11 +1591,13 @@ fn comment_builder(
|
||||
CommentBuilder::new(content, parent_target)
|
||||
.root(root_target)
|
||||
.into_event_builder()
|
||||
.tags([Tag::coordinate(addr.clone(), None)])
|
||||
.tags([Tag::coordinate(addr.clone().into(), None)])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use signed_core::GitEvent;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use nostr_sdk::prelude::*;
|
||||
@@ -1612,7 +1619,7 @@ mod tests {
|
||||
let root = EventBuilder::new(Kind::GitIssue, "issue body")
|
||||
.finalize(&keys)
|
||||
.expect("signed event");
|
||||
let addr = Coordinate::new(Kind::GitRepoAnnouncement, root.pubkey).identifier("my-repo");
|
||||
let addr = signed_core::RepoAddr::new(root.pubkey, "my-repo");
|
||||
let relay = RelayUrl::parse("wss://relay.example.com").expect("valid relay URL");
|
||||
|
||||
let event = comment_builder(&root, None, Some(&relay), &addr, "hi".into())
|
||||
@@ -1639,14 +1646,14 @@ mod tests {
|
||||
assert_eq!(e.as_slice()[1], root.id.to_hex());
|
||||
|
||||
// Signed's own `references_root` must keep matching the comment.
|
||||
assert!(signed_core::references_root(&event, &root.id));
|
||||
assert!(event.references_root(&root.id));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maintainer_filters_name_owner_and_maintainers() {
|
||||
let owner = Keys::generate().public_key();
|
||||
let maintainer = Keys::generate().public_key();
|
||||
let addr = Coordinate::new(Kind::GitRepoAnnouncement, owner).identifier("my-repo");
|
||||
let addr = signed_core::RepoAddr::new(owner, "my-repo");
|
||||
|
||||
// The owner is not among the maintainers, as on a subordinate fork.
|
||||
let filters = RepoStore::maintainer_filters(&addr, &[maintainer]);
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::time::Duration;
|
||||
use anyhow::Error;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription};
|
||||
use nostr_sdk::prelude::*;
|
||||
use signed_core::{Announcement, Deletions, RepoAddr, filters, repo_addr};
|
||||
use signed_core::{Announcement, Deletions, Filters, RepoAddr, filters};
|
||||
|
||||
use crate::backend::{Backend, BackendEvent};
|
||||
use crate::refresh::{RefreshGate, RefreshRequest};
|
||||
@@ -115,10 +115,10 @@ impl RepoListStore {
|
||||
backend.update(cx, |backend, cx| {
|
||||
backend.sync_bootstraps(
|
||||
vec![
|
||||
filters::all_announcements(),
|
||||
filters::all_states(),
|
||||
Filters::all_announcements(),
|
||||
Filters::all_states(),
|
||||
// Deletion requests, NIP-09/62, must be known before any announcement is shown.
|
||||
filters::deletions(),
|
||||
Filters::deletions(),
|
||||
],
|
||||
cx,
|
||||
);
|
||||
@@ -144,7 +144,7 @@ impl RepoListStore {
|
||||
self.state_synced_repos.insert(addr.clone());
|
||||
|
||||
backend.update(cx, |backend, cx| {
|
||||
backend.connect_repo_relays(relays, vec![filters::state(&addr)], cx);
|
||||
backend.connect_repo_relays(relays, vec![addr.state_filter()], cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -168,10 +168,10 @@ impl RepoListStore {
|
||||
let client = backend.read(cx).client();
|
||||
|
||||
let work = cx.background_spawn(async move {
|
||||
let filter = filters::all_announcements();
|
||||
let filter = Filters::all_announcements();
|
||||
let events = client.database().query(filter).await?;
|
||||
|
||||
let deletion_events = client.database().query(filters::deletions()).await?;
|
||||
let deletion_events = client.database().query(Filters::deletions()).await?;
|
||||
let deletions = Deletions::from_events(deletion_events);
|
||||
|
||||
// Dedup and sort off the main thread.
|
||||
@@ -213,7 +213,7 @@ impl RepoListStore {
|
||||
let Some(id) = event.tags.identifier() else {
|
||||
continue;
|
||||
};
|
||||
let addr = repo_addr(event.pubkey, id);
|
||||
let addr = RepoAddr::new(event.pubkey, id);
|
||||
let Some(entry) = last_activity.get_mut(&addr) else {
|
||||
continue;
|
||||
};
|
||||
@@ -230,10 +230,11 @@ impl RepoListStore {
|
||||
if deletions.is_deleted(&event) {
|
||||
continue;
|
||||
}
|
||||
for addr in event.tags.coordinates() {
|
||||
if addr.kind != Kind::GitRepoAnnouncement {
|
||||
for coordinate in event.tags.coordinates() {
|
||||
if coordinate.kind != Kind::GitRepoAnnouncement {
|
||||
continue;
|
||||
}
|
||||
let addr = RepoAddr::from(coordinate.clone());
|
||||
let Some(entry) = last_activity.get_mut(&addr) else {
|
||||
continue;
|
||||
};
|
||||
@@ -251,12 +252,13 @@ impl RepoListStore {
|
||||
if deletions.is_deleted(&event) {
|
||||
continue;
|
||||
}
|
||||
for addr in event.tags.coordinates() {
|
||||
if addr.kind != Kind::GitRepoAnnouncement || !last_activity.contains_key(&addr)
|
||||
for coordinate in event.tags.coordinates() {
|
||||
if coordinate.kind != Kind::GitRepoAnnouncement
|
||||
|| !last_activity.contains_key(&RepoAddr::from(coordinate.clone()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let entry = counts.entry(addr).or_default();
|
||||
let entry = counts.entry(RepoAddr::from(coordinate)).or_default();
|
||||
match event.kind {
|
||||
Kind::GitIssue => entry.issues += 1,
|
||||
Kind::GitPullRequest => entry.pull_requests += 1,
|
||||
|
||||
Reference in New Issue
Block a user