diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-03-05 11:28:36 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-03-05 11:28:36 +0000 |
| commit | 0e493c455a0345c206dd1c5b0dfb5322b8a4e3e9 (patch) | |
| tree | 105517fc7a592e469a0f72667f9b364895052287 /src/lib/client.rs | |
| parent | 2f2819cc2365be07fedfd35ab3654b3607e29e76 (diff) | |
feat(labels): fetch and apply NIP-32 kind-1985 label events
- Add KIND_LABEL (kind 1985) constant to git_events.rs
- Add get_labels() merging inline t-tags with external kind-1985 events,
gating each on author-or-maintainer permission
- Extend get_fetch_filters() to request kind-1985 events for all known
issue and proposal IDs
- Track label event counts in FetchReport (field + Display + consolidation)
- Update issue_list.rs and list.rs to fetch label events from cache and
pass them through get_labels() instead of reading t-tags inline
Diffstat (limited to 'src/lib/client.rs')
| -rw-r--r-- | src/lib/client.rs | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 8501a1f..94a173f 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -56,9 +56,9 @@ use crate::{ | |||
| 56 | get_dirs, | 56 | get_dirs, |
| 57 | git::{Repo, RepoActions, get_git_config_item}, | 57 | git::{Repo, RepoActions, get_git_config_item}, |
| 58 | git_events::{ | 58 | git_events::{ |
| 59 | KIND_COMMENT, KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, KIND_USER_GRASP_LIST, | 59 | KIND_COMMENT, KIND_LABEL, KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, |
| 60 | event_is_cover_letter, event_is_patch_set_root, event_is_revision_root, | 60 | KIND_USER_GRASP_LIST, event_is_cover_letter, event_is_patch_set_root, |
| 61 | event_is_valid_pr_or_pr_update, status_kinds, | 61 | event_is_revision_root, event_is_valid_pr_or_pr_update, status_kinds, |
| 62 | }, | 62 | }, |
| 63 | login::{get_likely_logged_in_user, user::get_user_ref_from_cache}, | 63 | login::{get_likely_logged_in_user, user::get_user_ref_from_cache}, |
| 64 | repo_ref::{RepoRef, normalize_grasp_server_url}, | 64 | repo_ref::{RepoRef, normalize_grasp_server_url}, |
| @@ -1998,6 +1998,8 @@ async fn process_fetched_events( | |||
| 1998 | } | 1998 | } |
| 1999 | } else if event.kind.eq(&KIND_COMMENT) { | 1999 | } else if event.kind.eq(&KIND_COMMENT) { |
| 2000 | report.comments.insert(event.id); | 2000 | report.comments.insert(event.id); |
| 2001 | } else if event.kind.eq(&KIND_LABEL) { | ||
| 2002 | report.labels.insert(event.id); | ||
| 2001 | } else if [Kind::RelayList, Kind::Metadata, KIND_USER_GRASP_LIST].contains(&event.kind) | 2003 | } else if [Kind::RelayList, Kind::Metadata, KIND_USER_GRASP_LIST].contains(&event.kind) |
| 2002 | { | 2004 | { |
| 2003 | if request.missing_contributor_profiles.contains(&event.pubkey) { | 2005 | if request.missing_contributor_profiles.contains(&event.pubkey) { |
| @@ -2121,6 +2123,9 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo | |||
| 2121 | for c in relay_report.comments { | 2123 | for c in relay_report.comments { |
| 2122 | report.comments.insert(c); | 2124 | report.comments.insert(c); |
| 2123 | } | 2125 | } |
| 2126 | for c in relay_report.labels { | ||
| 2127 | report.labels.insert(c); | ||
| 2128 | } | ||
| 2124 | report.deletions += relay_report.deletions; | 2129 | report.deletions += relay_report.deletions; |
| 2125 | for c in relay_report.contributor_profiles { | 2130 | for c in relay_report.contributor_profiles { |
| 2126 | report.contributor_profiles.insert(c); | 2131 | report.contributor_profiles.insert(c); |
| @@ -2245,6 +2250,24 @@ pub fn get_fetch_filters( | |||
| 2245 | ] | 2250 | ] |
| 2246 | } | 2251 | } |
| 2247 | }, | 2252 | }, |
| 2253 | // Fetch NIP-32 kind-1985 label events for issues and proposals. | ||
| 2254 | // Label events reference the target via a lowercase `e` tag. | ||
| 2255 | { | ||
| 2256 | let all_root_ids: HashSet<EventId> = issue_ids | ||
| 2257 | .iter() | ||
| 2258 | .chain(proposal_ids.iter()) | ||
| 2259 | .copied() | ||
| 2260 | .collect(); | ||
| 2261 | if all_root_ids.is_empty() { | ||
| 2262 | vec![] | ||
| 2263 | } else { | ||
| 2264 | vec![ | ||
| 2265 | nostr::Filter::default() | ||
| 2266 | .events(all_root_ids) | ||
| 2267 | .kind(KIND_LABEL), | ||
| 2268 | ] | ||
| 2269 | } | ||
| 2270 | }, | ||
| 2248 | // Request kind-5 deletions for state events and repo announcements by | 2271 | // Request kind-5 deletions for state events and repo announcements by |
| 2249 | // their event ID (#e tag), as per NIP-09. The #a-tagged filter above | 2272 | // their event ID (#e tag), as per NIP-09. The #a-tagged filter above |
| 2250 | // covers addressable-event deletions; this covers the specific event IDs | 2273 | // covers addressable-event deletions; this covers the specific event IDs |
| @@ -2333,6 +2356,8 @@ pub struct FetchReport { | |||
| 2333 | issue_statuses: HashSet<EventId>, | 2356 | issue_statuses: HashSet<EventId>, |
| 2334 | /// NIP-22 kind-1111 comments against issues, patches, and PRs. | 2357 | /// NIP-22 kind-1111 comments against issues, patches, and PRs. |
| 2335 | comments: HashSet<EventId>, | 2358 | comments: HashSet<EventId>, |
| 2359 | /// NIP-32 kind-1985 label events for issues and proposals. | ||
| 2360 | labels: HashSet<EventId>, | ||
| 2336 | /// Count of kind-5 deletion events received (for display purposes). | 2361 | /// Count of kind-5 deletion events received (for display purposes). |
| 2337 | deletions: u32, | 2362 | deletions: u32, |
| 2338 | contributor_profiles: HashSet<PublicKey>, | 2363 | contributor_profiles: HashSet<PublicKey>, |
| @@ -2421,6 +2446,13 @@ impl Display for FetchReport { | |||
| 2421 | if self.comments.len() > 1 { "s" } else { "" }, | 2446 | if self.comments.len() > 1 { "s" } else { "" }, |
| 2422 | )); | 2447 | )); |
| 2423 | } | 2448 | } |
| 2449 | if !self.labels.is_empty() { | ||
| 2450 | display_items.push(format!( | ||
| 2451 | "{} label{}", | ||
| 2452 | self.labels.len(), | ||
| 2453 | if self.labels.len() > 1 { "s" } else { "" }, | ||
| 2454 | )); | ||
| 2455 | } | ||
| 2424 | if self.deletions > 0 { | 2456 | if self.deletions > 0 { |
| 2425 | display_items.push(format!( | 2457 | display_items.push(format!( |
| 2426 | "{} deletion{}", | 2458 | "{} deletion{}", |