From 5ede9ddfaad9138d8cc128a5a007a7e7520c7c44 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Thu, 23 Oct 2025 20:35:37 +0900 Subject: [PATCH] appview: add `issue_reopen` event Change-Id: uzqrtsqqqqluurqlvvurtwwzukpwxxmp both issue close and reopen are handled by `NewIssueState` handler. this works because passed `issue` obj is already holding the newest issue state. Signed-off-by: Seongmin Lee --- appview/indexer/notifier.go | 2 +- appview/issues/issues.go | 6 +++--- appview/models/notifications.go | 5 +++++ appview/notify/db/db.go | 10 ++++++++-- appview/notify/merged_notifier.go | 4 ++-- appview/notify/notifier.go | 4 ++-- appview/notify/posthog/notifier.go | 10 ++++++++-- .../pages/templates/notifications/fragments/item.html | 2 ++ 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/appview/indexer/notifier.go b/appview/indexer/notifier.go index 89d37944..205952fd 100644 --- a/appview/indexer/notifier.go +++ b/appview/indexer/notifier.go @@ -19,7 +19,7 @@ func (ix *Indexer) NewIssue(ctx context.Context, issue *models.Issue) { } } -func (ix *Indexer) NewIssueClosed(ctx context.Context, issue *models.Issue) { +func (ix *Indexer) NewIssueState(ctx context.Context, issue *models.Issue) { l := log.FromContext(ctx).With("notifier", "indexer", "issue", issue) l.Debug("updating an issue") err := ix.Issues.Index(ctx, *issue) diff --git a/appview/issues/issues.go b/appview/issues/issues.go index 49054c5d..af71d751 100644 --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -309,7 +309,7 @@ func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) { issue.Open = false // notify about the issue closure - rp.notifier.NewIssueClosed(r.Context(), issue) + rp.notifier.NewIssueState(r.Context(), issue) rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) return @@ -358,8 +358,8 @@ func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) { // change the issue state (this will pass down to the notifiers) issue.Open = true - // // notify about the issue reopen - // rp.notifier.NewIssueReopen(r.Context(), issue) + // notify about the issue reopen + rp.notifier.NewIssueState(r.Context(), issue) rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) return diff --git a/appview/models/notifications.go b/appview/models/notifications.go index fe4c8a72..daef7fb1 100644 --- a/appview/models/notifications.go +++ b/appview/models/notifications.go @@ -17,6 +17,7 @@ const ( NotificationTypeFollowed NotificationType = "followed" NotificationTypePullMerged NotificationType = "pull_merged" NotificationTypeIssueClosed NotificationType = "issue_closed" + NotificationTypeIssueReopen NotificationType = "issue_reopen" NotificationTypePullClosed NotificationType = "pull_closed" ) @@ -47,6 +48,8 @@ func (n *Notification) Icon() string { return "message-square" case NotificationTypeIssueClosed: return "ban" + case NotificationTypeIssueReopen: + return "circle-dot" case NotificationTypePullCreated: return "git-pull-request-create" case NotificationTypePullCommented: @@ -93,6 +96,8 @@ func (prefs *NotificationPreferences) ShouldNotify(t NotificationType) bool { return prefs.IssueCommented case NotificationTypeIssueClosed: return prefs.IssueClosed + case NotificationTypeIssueReopen: + return prefs.IssueCreated // smae pref for now case NotificationTypePullCreated: return prefs.PullCreated case NotificationTypePullCommented: diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go index 62efc857..0db77394 100644 --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -283,7 +283,7 @@ func (n *databaseNotifier) NewString(ctx context.Context, string *models.String) // no-op } -func (n *databaseNotifier) NewIssueClosed(ctx context.Context, issue *models.Issue) { +func (n *databaseNotifier) NewIssueState(ctx context.Context, issue *models.Issue) { // build up the recipients list: // - repo owner // - repo collaborators @@ -303,12 +303,18 @@ func (n *databaseNotifier) NewIssueClosed(ctx context.Context, issue *models.Iss } actorDid := syntax.DID(issue.Repo.Did) - eventType := models.NotificationTypeIssueClosed entityType := "pull" entityId := issue.AtUri().String() repoId := &issue.Repo.Id issueId := &issue.Id var pullId *int64 + var eventType models.NotificationType + + if issue.Open { + eventType = models.NotificationTypeIssueReopen + } else { + eventType = models.NotificationTypeIssueClosed + } n.notifyEvent( actorDid, diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go index ab9f7784..54c05f63 100644 --- a/appview/notify/merged_notifier.go +++ b/appview/notify/merged_notifier.go @@ -61,8 +61,8 @@ func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment *models.Is m.fanout("NewIssueComment", ctx, comment) } -func (m *mergedNotifier) NewIssueClosed(ctx context.Context, issue *models.Issue) { - m.fanout("NewIssueClosed", ctx, issue) +func (m *mergedNotifier) NewIssueState(ctx context.Context, issue *models.Issue) { + m.fanout("NewIssueState", ctx, issue) } func (m *mergedNotifier) DeleteIssue(ctx context.Context, issue *models.Issue) { diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go index a319c05d..31dca33d 100644 --- a/appview/notify/notifier.go +++ b/appview/notify/notifier.go @@ -14,7 +14,7 @@ type Notifier interface { NewIssue(ctx context.Context, issue *models.Issue) NewIssueComment(ctx context.Context, comment *models.IssueComment) - NewIssueClosed(ctx context.Context, issue *models.Issue) + NewIssueState(ctx context.Context, issue *models.Issue) DeleteIssue(ctx context.Context, issue *models.Issue) NewFollow(ctx context.Context, follow *models.Follow) @@ -44,7 +44,7 @@ func (m *BaseNotifier) DeleteStar(ctx context.Context, star *models.Star) {} func (m *BaseNotifier) NewIssue(ctx context.Context, issue *models.Issue) {} func (m *BaseNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment) {} -func (m *BaseNotifier) NewIssueClosed(ctx context.Context, issue *models.Issue) {} +func (m *BaseNotifier) NewIssueState(ctx context.Context, issue *models.Issue) {} func (m *BaseNotifier) DeleteIssue(ctx context.Context, issue *models.Issue) {} func (m *BaseNotifier) NewFollow(ctx context.Context, follow *models.Follow) {} diff --git a/appview/notify/posthog/notifier.go b/appview/notify/posthog/notifier.go index c6547c83..528cef00 100644 --- a/appview/notify/posthog/notifier.go +++ b/appview/notify/posthog/notifier.go @@ -190,10 +190,16 @@ func (n *posthogNotifier) NewIssueComment(ctx context.Context, comment *models.I } } -func (n *posthogNotifier) NewIssueClosed(ctx context.Context, issue *models.Issue) { +func (n *posthogNotifier) NewIssueState(ctx context.Context, issue *models.Issue) { + var event string + if issue.Open { + event = "issue_reopen" + } else { + event = "issue_closed" + } err := n.client.Enqueue(posthog.Capture{ DistinctId: issue.Did, - Event: "issue_closed", + Event: event, Properties: posthog.Properties{ "repo_at": issue.RepoAt.String(), "issue_id": issue.IssueId, diff --git a/appview/pages/templates/notifications/fragments/item.html b/appview/pages/templates/notifications/fragments/item.html index ef936dfb..302336c1 100644 --- a/appview/pages/templates/notifications/fragments/item.html +++ b/appview/pages/templates/notifications/fragments/item.html @@ -40,6 +40,8 @@ commented on an issue {{ else if eq .Type "issue_closed" }} closed an issue + {{ else if eq .Type "issue_reopen" }} + reopened an issue {{ else if eq .Type "pull_created" }} created a pull request {{ else if eq .Type "pull_commented" }} -- 2.43.0