Skip to content

Commit 0fc82f6

Browse files
committed
Improve honk state tracking for titles, reduce to 25m
1 parent 8505578 commit 0fc82f6

File tree

2 files changed

+82
-53
lines changed

2 files changed

+82
-53
lines changed

cmd/goose/main.go

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
maxPRsToProcess = 200
3838
minUpdateInterval = 10 * time.Second
3939
defaultUpdateInterval = 1 * time.Minute
40+
blockedPRIconDuration = 25 * time.Minute
4041
maxRetryDelay = 2 * time.Minute
4142
maxRetries = 10
4243
minorFailureThreshold = 3
@@ -655,64 +656,92 @@ func (app *App) checkForNewlyBlockedPRs(ctx context.Context) {
655656

656657
// Check incoming PRs
657658
for i := range incoming {
658-
if incoming[i].NeedsReview {
659-
currentBlocked[incoming[i].URL] = true
660-
// Track when first blocked
661-
if blockedTime, exists := blockedTimes[incoming[i].URL]; exists {
662-
newBlockedTimes[incoming[i].URL] = blockedTime
663-
incoming[i].FirstBlockedAt = blockedTime
664-
} else if !previousBlocked[incoming[i].URL] {
665-
// Newly blocked PR
666-
newBlockedTimes[incoming[i].URL] = now
667-
incoming[i].FirstBlockedAt = now
668-
log.Printf("[BLOCKED] Setting FirstBlockedAt for incoming PR: %s #%d at %v",
669-
incoming[i].Repository, incoming[i].Number, now)
670-
671-
// Skip sound and auto-open for stale PRs when hideStaleIncoming is enabled
672-
isStale := incoming[i].UpdatedAt.Before(staleThreshold)
673-
if hideStaleIncoming && isStale {
674-
log.Printf("[BLOCKED] New incoming PR blocked (stale, skipping): %s #%d - %s",
675-
incoming[i].Repository, incoming[i].Number, incoming[i].Title)
676-
} else {
677-
log.Printf("[BLOCKED] New incoming PR blocked: %s #%d - %s",
678-
incoming[i].Repository, incoming[i].Number, incoming[i].Title)
679-
app.notifyWithSound(ctx, incoming[i], true, &playedHonk)
680-
app.tryAutoOpenPR(ctx, incoming[i], autoBrowserEnabled, startTime)
681-
}
659+
if !incoming[i].NeedsReview {
660+
continue
661+
}
662+
663+
pr := &incoming[i]
664+
currentBlocked[pr.URL] = true
665+
666+
if previousBlocked[pr.URL] {
667+
// PR was blocked before and is still blocked - preserve timestamp
668+
if blockedTime, exists := blockedTimes[pr.URL]; exists {
669+
newBlockedTimes[pr.URL] = blockedTime
670+
pr.FirstBlockedAt = blockedTime
671+
log.Printf("[BLOCKED] Preserving FirstBlockedAt for still-blocked incoming PR: %s #%d (blocked since %v, %v ago)",
672+
pr.Repository, pr.Number, blockedTime, time.Since(blockedTime))
673+
} else {
674+
// Edge case: PR was marked as blocked but timestamp is missing
675+
log.Printf("[BLOCKED] WARNING: Missing timestamp for previously blocked incoming PR: %s #%d - setting new timestamp",
676+
pr.Repository, pr.Number)
677+
newBlockedTimes[pr.URL] = now
678+
pr.FirstBlockedAt = now
679+
}
680+
} else {
681+
// PR is newly blocked (wasn't blocked in previous check)
682+
newBlockedTimes[pr.URL] = now
683+
pr.FirstBlockedAt = now
684+
log.Printf("[BLOCKED] Setting FirstBlockedAt for incoming PR: %s #%d at %v",
685+
pr.Repository, pr.Number, now)
686+
687+
// Skip sound and auto-open for stale PRs when hideStaleIncoming is enabled
688+
isStale := pr.UpdatedAt.Before(staleThreshold)
689+
if hideStaleIncoming && isStale {
690+
log.Printf("[BLOCKED] New incoming PR blocked (stale, skipping): %s #%d - %s",
691+
pr.Repository, pr.Number, pr.Title)
692+
} else {
693+
log.Printf("[BLOCKED] New incoming PR blocked: %s #%d - %s",
694+
pr.Repository, pr.Number, pr.Title)
695+
app.notifyWithSound(ctx, *pr, true, &playedHonk)
696+
app.tryAutoOpenPR(ctx, *pr, autoBrowserEnabled, startTime)
682697
}
683698
}
684699
}
685700

686701
// Check outgoing PRs
687702
for i := range outgoing {
688-
if outgoing[i].IsBlocked {
689-
currentBlocked[outgoing[i].URL] = true
690-
// Track when first blocked
691-
if blockedTime, exists := blockedTimes[outgoing[i].URL]; exists {
692-
newBlockedTimes[outgoing[i].URL] = blockedTime
693-
outgoing[i].FirstBlockedAt = blockedTime
694-
} else if !previousBlocked[outgoing[i].URL] {
695-
// Newly blocked PR
696-
newBlockedTimes[outgoing[i].URL] = now
697-
outgoing[i].FirstBlockedAt = now
698-
log.Printf("[BLOCKED] Setting FirstBlockedAt for outgoing PR: %s #%d at %v",
699-
outgoing[i].Repository, outgoing[i].Number, now)
700-
701-
// Skip sound and auto-open for stale PRs when hideStaleIncoming is enabled
702-
isStale := outgoing[i].UpdatedAt.Before(staleThreshold)
703-
if hideStaleIncoming && isStale {
704-
log.Printf("[BLOCKED] New outgoing PR blocked (stale, skipping): %s #%d - %s",
705-
outgoing[i].Repository, outgoing[i].Number, outgoing[i].Title)
706-
} else {
707-
// Add delay if we already played honk sound
708-
if playedHonk && !playedJet {
709-
time.Sleep(2 * time.Second)
710-
}
711-
log.Printf("[BLOCKED] New outgoing PR blocked: %s #%d - %s",
712-
outgoing[i].Repository, outgoing[i].Number, outgoing[i].Title)
713-
app.notifyWithSound(ctx, outgoing[i], false, &playedJet)
714-
app.tryAutoOpenPR(ctx, outgoing[i], autoBrowserEnabled, startTime)
703+
if !outgoing[i].IsBlocked {
704+
continue
705+
}
706+
707+
pr := &outgoing[i]
708+
currentBlocked[pr.URL] = true
709+
710+
if previousBlocked[pr.URL] {
711+
// PR was blocked before and is still blocked - preserve timestamp
712+
if blockedTime, exists := blockedTimes[pr.URL]; exists {
713+
newBlockedTimes[pr.URL] = blockedTime
714+
pr.FirstBlockedAt = blockedTime
715+
log.Printf("[BLOCKED] Preserving FirstBlockedAt for still-blocked outgoing PR: %s #%d (blocked since %v, %v ago)",
716+
pr.Repository, pr.Number, blockedTime, time.Since(blockedTime))
717+
} else {
718+
// Edge case: PR was marked as blocked but timestamp is missing
719+
log.Printf("[BLOCKED] WARNING: Missing timestamp for previously blocked outgoing PR: %s #%d - setting new timestamp",
720+
pr.Repository, pr.Number)
721+
newBlockedTimes[pr.URL] = now
722+
pr.FirstBlockedAt = now
723+
}
724+
} else {
725+
// PR is newly blocked (wasn't blocked in previous check)
726+
newBlockedTimes[pr.URL] = now
727+
pr.FirstBlockedAt = now
728+
log.Printf("[BLOCKED] Setting FirstBlockedAt for outgoing PR: %s #%d at %v",
729+
pr.Repository, pr.Number, now)
730+
731+
// Skip sound and auto-open for stale PRs when hideStaleIncoming is enabled
732+
isStale := pr.UpdatedAt.Before(staleThreshold)
733+
if hideStaleIncoming && isStale {
734+
log.Printf("[BLOCKED] New outgoing PR blocked (stale, skipping): %s #%d - %s",
735+
pr.Repository, pr.Number, pr.Title)
736+
} else {
737+
// Add delay if we already played honk sound
738+
if playedHonk && !playedJet {
739+
time.Sleep(2 * time.Second)
715740
}
741+
log.Printf("[BLOCKED] New outgoing PR blocked: %s #%d - %s",
742+
pr.Repository, pr.Number, pr.Title)
743+
app.notifyWithSound(ctx, *pr, false, &playedJet)
744+
app.tryAutoOpenPR(ctx, *pr, autoBrowserEnabled, startTime)
716745
}
717746
}
718747
}

cmd/goose/ui.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ func (app *App) addPRSection(ctx context.Context, prs []PR, sectionTitle string,
209209
title := fmt.Sprintf("%s #%d", sortedPRs[i].Repository, sortedPRs[i].Number)
210210
// Add bullet point or emoji for blocked PRs
211211
if sortedPRs[i].NeedsReview || sortedPRs[i].IsBlocked {
212-
// Show emoji for PRs blocked within the last hour
213-
if !sortedPRs[i].FirstBlockedAt.IsZero() && time.Since(sortedPRs[i].FirstBlockedAt) < time.Hour {
212+
// Show emoji for PRs blocked within the last 25 minutes
213+
if !sortedPRs[i].FirstBlockedAt.IsZero() && time.Since(sortedPRs[i].FirstBlockedAt) < blockedPRIconDuration {
214214
// Use party popper for outgoing PRs, goose for incoming PRs
215215
if sectionTitle == "Outgoing" {
216216
title = fmt.Sprintf("🎉 %s", title)

0 commit comments

Comments
 (0)