feat: add event fetching strategy #24
@@ -1,7 +0,0 @@
|
|||||||
use nostr::prelude::*;
|
|
||||||
|
|
||||||
/// GitWorkshop and `ngit` cover-note extension, kind 1624.
|
|
||||||
///
|
|
||||||
/// A markdown note attached to an issue, patch or PR by its author or a maintainer,
|
|
||||||
/// not part of the NIP-34 draft, read support for interop.
|
|
||||||
pub const COVER_NOTE_KIND: Kind = Kind::Custom(1624);
|
|
||||||
@@ -2,7 +2,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use nostr::prelude::*;
|
use nostr::prelude::*;
|
||||||
|
|
||||||
use crate::{COVER_NOTE_KIND, RepoAddr};
|
use crate::RepoAddr;
|
||||||
|
|
||||||
/// Kinds that make up the activity of a repository.
|
/// Kinds that make up the activity of a repository.
|
||||||
pub const ACTIVITY_KINDS: [Kind; 9] = [
|
pub const ACTIVITY_KINDS: [Kind; 9] = [
|
||||||
@@ -18,19 +18,18 @@ pub const ACTIVITY_KINDS: [Kind; 9] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/// Kinds that notify a user when they tag them via their `p` tag.
|
/// Kinds that notify a user when they tag them via their `p` tag.
|
||||||
pub const NOTIFICATION_KINDS: [Kind; 9] = [
|
pub const NOTIFICATION_KINDS: [Kind; 8] = [
|
||||||
Kind::GitIssue,
|
Kind::GitIssue,
|
||||||
Kind::GitPullRequest,
|
Kind::GitPullRequest,
|
||||||
Kind::GitPatch,
|
Kind::GitPatch,
|
||||||
Kind::GitPullRequestUpdate,
|
Kind::GitPullRequestUpdate,
|
||||||
COVER_NOTE_KIND,
|
|
||||||
Kind::GitStatusOpen,
|
Kind::GitStatusOpen,
|
||||||
Kind::GitStatusApplied,
|
Kind::GitStatusApplied,
|
||||||
Kind::GitStatusClosed,
|
Kind::GitStatusClosed,
|
||||||
Kind::GitStatusDraft,
|
Kind::GitStatusDraft,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Git root kinds that make a comment or cover note count as git activity.
|
/// Git root kinds that make a comment count as git activity.
|
||||||
const GIT_ROOT_KINDS: [Kind; 4] = [
|
const GIT_ROOT_KINDS: [Kind; 4] = [
|
||||||
Kind::GitIssue,
|
Kind::GitIssue,
|
||||||
Kind::GitPatch,
|
Kind::GitPatch,
|
||||||
@@ -44,7 +43,6 @@ pub fn is_repo_kind(kind: Kind) -> bool {
|
|||||||
|| kind == Kind::RepoState
|
|| kind == Kind::RepoState
|
||||||
|| kind == Kind::EventDeletion
|
|| kind == Kind::EventDeletion
|
||||||
|| kind == Kind::RequestToVanish
|
|| kind == Kind::RequestToVanish
|
||||||
|| kind == COVER_NOTE_KIND
|
|
||||||
|| ACTIVITY_KINDS.contains(&kind)
|
|| ACTIVITY_KINDS.contains(&kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,13 +148,7 @@ pub fn notifications(me: PublicKey) -> Vec<Filter> {
|
|||||||
/// A comment on an unrelated kind is matched too, so results must be filtered
|
/// A comment on an unrelated kind is matched too, so results must be filtered
|
||||||
/// through [`is_git_activity`] before display.
|
/// through [`is_git_activity`] before display.
|
||||||
pub fn authored_activity(me: PublicKey) -> Filter {
|
pub fn authored_activity(me: PublicKey) -> Filter {
|
||||||
Filter::new()
|
Filter::new().kinds(ACTIVITY_KINDS).author(me)
|
||||||
.kinds(
|
|
||||||
ACTIVITY_KINDS
|
|
||||||
.into_iter()
|
|
||||||
.chain(std::iter::once(COVER_NOTE_KIND)),
|
|
||||||
)
|
|
||||||
.author(me)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a kind-1111 comment targets a git root, checked via its `K` tag.
|
/// Whether a kind-1111 comment targets a git root, checked via its `K` tag.
|
||||||
@@ -165,12 +157,6 @@ fn is_git_comment(event: &Event) -> bool {
|
|||||||
&& tag_kind(event, "K").is_some_and(|kind| GIT_ROOT_KINDS.contains(&kind))
|
&& tag_kind(event, "K").is_some_and(|kind| GIT_ROOT_KINDS.contains(&kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a kind-1624 cover note targets a git root, checked via its `k` tag.
|
|
||||||
fn is_git_cover_note(event: &Event) -> bool {
|
|
||||||
event.kind == COVER_NOTE_KIND
|
|
||||||
&& tag_kind(event, "k").is_some_and(|kind| GIT_ROOT_KINDS.contains(&kind))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether a status event references a git root, checked via its `k` tag.
|
/// Whether a status event references a git root, checked via its `k` tag.
|
||||||
fn is_git_status(event: &Event) -> bool {
|
fn is_git_status(event: &Event) -> bool {
|
||||||
tag_kind(event, "k").is_some_and(|kind| GIT_ROOT_KINDS.contains(&kind))
|
tag_kind(event, "k").is_some_and(|kind| GIT_ROOT_KINDS.contains(&kind))
|
||||||
@@ -185,7 +171,7 @@ pub fn is_git_activity(event: &Event) -> bool {
|
|||||||
| Kind::GitStatusApplied
|
| Kind::GitStatusApplied
|
||||||
| Kind::GitStatusClosed
|
| Kind::GitStatusClosed
|
||||||
| Kind::GitStatusDraft => is_git_status(event),
|
| Kind::GitStatusDraft => is_git_status(event),
|
||||||
kind => kind == COVER_NOTE_KIND && is_git_cover_note(event),
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,17 +263,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn status_and_cover_note_activity_depend_on_the_lowercase_k_tag() {
|
fn status_activity_depends_on_the_lowercase_k_tag() {
|
||||||
let status = signed(
|
let status = signed(
|
||||||
&keys(1),
|
&keys(1),
|
||||||
Kind::GitStatusClosed,
|
Kind::GitStatusClosed,
|
||||||
vec![kind_tag("k", Kind::GitPullRequest)],
|
vec![kind_tag("k", Kind::GitPullRequest)],
|
||||||
);
|
);
|
||||||
let cover = signed(
|
|
||||||
&keys(1),
|
|
||||||
COVER_NOTE_KIND,
|
|
||||||
vec![kind_tag("k", Kind::GitPatch)],
|
|
||||||
);
|
|
||||||
let unrelated = signed(
|
let unrelated = signed(
|
||||||
&keys(1),
|
&keys(1),
|
||||||
Kind::GitStatusClosed,
|
Kind::GitStatusClosed,
|
||||||
@@ -295,7 +276,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert!(is_git_activity(&status));
|
assert!(is_git_activity(&status));
|
||||||
assert!(is_git_activity(&cover));
|
|
||||||
assert!(!is_git_activity(&unrelated));
|
assert!(!is_git_activity(&unrelated));
|
||||||
assert!(!is_git_activity(&signed(
|
assert!(!is_git_activity(&signed(
|
||||||
&keys(1),
|
&keys(1),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::time::Duration;
|
|||||||
use nostr::prelude::*;
|
use nostr::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{COVER_NOTE_KIND, RepoAddr, activity_subject};
|
use crate::{RepoAddr, activity_subject};
|
||||||
|
|
||||||
/// Window before `now` that an advanced cutoff retreats to.
|
/// Window before `now` that an advanced cutoff retreats to.
|
||||||
const ADVANCE_WINDOW: Duration = Duration::from_secs(3 * 24 * 60 * 60);
|
const ADVANCE_WINDOW: Duration = Duration::from_secs(3 * 24 * 60 * 60);
|
||||||
@@ -121,14 +121,11 @@ impl InboxItem {
|
|||||||
/// - patch (1617): its `e` parent patch, else itself
|
/// - patch (1617): its `e` parent patch, else itself
|
||||||
/// - NIP-22 comment (1111): uppercase `E` root pointer
|
/// - NIP-22 comment (1111): uppercase `E` root pointer
|
||||||
/// - PR update (1619): uppercase `E`
|
/// - PR update (1619): uppercase `E`
|
||||||
/// - statuses (1630-1633) / cover note (1624): NIP-10 root `e`
|
/// - statuses (1630-1633): NIP-10 root `e`
|
||||||
pub fn notification_root<L>(event: &Event, lookup: &L) -> Option<EventId>
|
pub fn notification_root<L>(event: &Event, lookup: &L) -> Option<EventId>
|
||||||
where
|
where
|
||||||
L: Fn(EventId) -> Option<Event>,
|
L: Fn(EventId) -> Option<Event>,
|
||||||
{
|
{
|
||||||
if event.kind == COVER_NOTE_KIND {
|
|
||||||
return nip10_root_id(event).map(|root| resolve_thread_root(root, lookup));
|
|
||||||
}
|
|
||||||
match event.kind {
|
match event.kind {
|
||||||
Kind::GitIssue | Kind::GitPullRequest => Some(event.id),
|
Kind::GitIssue | Kind::GitPullRequest => Some(event.id),
|
||||||
Kind::GitPatch => Some(match first_e_id(event) {
|
Kind::GitPatch => Some(match first_e_id(event) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
pub mod addr;
|
pub mod addr;
|
||||||
pub mod annotations;
|
|
||||||
pub mod deletions;
|
pub mod deletions;
|
||||||
pub mod filters;
|
pub mod filters;
|
||||||
pub mod inbox;
|
pub mod inbox;
|
||||||
@@ -8,7 +7,6 @@ pub mod state;
|
|||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
||||||
pub use addr::{RepoAddr, identifier_from_name, repo_addr};
|
pub use addr::{RepoAddr, identifier_from_name, repo_addr};
|
||||||
pub use annotations::COVER_NOTE_KIND;
|
|
||||||
pub use deletions::Deletions;
|
pub use deletions::Deletions;
|
||||||
pub use filters::{
|
pub use filters::{
|
||||||
NOTIFICATION_KINDS, authored_activity, is_git_activity, notification_comments, notifications,
|
NOTIFICATION_KINDS, authored_activity, is_git_activity, notification_comments, notifications,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use gpui::{
|
|||||||
use gpui_component::button::{Button, ButtonVariants};
|
use gpui_component::button::{Button, ButtonVariants};
|
||||||
use gpui_component::{ActiveTheme, Icon, IconName, IconNamed, Sizable, StyledExt, h_flex, v_flex};
|
use gpui_component::{ActiveTheme, Icon, IconName, IconNamed, Sizable, StyledExt, h_flex, v_flex};
|
||||||
use nostr::prelude::{Event, EventId, Kind, PublicKey, Timestamp};
|
use nostr::prelude::{Event, EventId, Kind, PublicKey, Timestamp};
|
||||||
use signed_core::{COVER_NOTE_KIND, InboxItem, InboxReadState, RepoAddr};
|
use signed_core::{InboxItem, InboxReadState, RepoAddr};
|
||||||
use signed_state::{
|
use signed_state::{
|
||||||
Backend, BackendEvent, ProfileStore, RefreshGate, RefreshRequest, RepoListStore, query_inbox,
|
Backend, BackendEvent, ProfileStore, RefreshGate, RefreshRequest, RepoListStore, query_inbox,
|
||||||
};
|
};
|
||||||
@@ -557,10 +557,6 @@ fn sub_activity(event: &Event, me: Option<PublicKey>, cx: &App) -> AnyElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn activity_phrase(kind: Kind) -> &'static str {
|
fn activity_phrase(kind: Kind) -> &'static str {
|
||||||
if kind == COVER_NOTE_KIND {
|
|
||||||
return "added a note";
|
|
||||||
}
|
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
Kind::GitIssue => "opened an issue",
|
Kind::GitIssue => "opened an issue",
|
||||||
Kind::GitPullRequest => "opened a PR",
|
Kind::GitPullRequest => "opened a PR",
|
||||||
|
|||||||
Reference in New Issue
Block a user