Skip to content

Commit 389f2c5

Browse files
committed
feat: search notifications
Signed-off-by: Adam Setch <[email protected]>
1 parent 4f31c3e commit 389f2c5

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

src/renderer/components/filters/SearchFilterSuggestions.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { Box, Popover, Stack, Text } from '@primer/react';
55
import { Opacity } from '../../types';
66
import { cn } from '../../utils/cn';
77
import {
8-
getAvailableSearchQualifiers,
8+
BASE_QUALIFIERS,
9+
QUALIFIERS,
910
SEARCH_DELIMITER,
1011
} from '../../utils/notifications/filters/search';
1112

@@ -27,7 +28,7 @@ export const SearchFilterSuggestions: FC<SearchFilterSuggestionsProps> = ({
2728
}
2829

2930
const lower = inputValue.toLowerCase();
30-
const base = getAvailableSearchQualifiers(isDetailedNotificationsEnabled);
31+
const base = isDetailedNotificationsEnabled ? QUALIFIERS : BASE_QUALIFIERS;
3132
const suggestions = base.filter(
3233
(q) => q.prefix.startsWith(lower) || inputValue === '',
3334
);

src/renderer/utils/notifications/filters/filter.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,34 @@ import type {
55
SubjectUser,
66
} from '../../../typesGitHub';
77
import {
8-
AUTHOR_PREFIX,
98
filterNotificationBySearchTerm,
109
hasExcludeSearchFilters,
1110
hasIncludeSearchFilters,
12-
ORG_PREFIX,
13-
REPO_PREFIX,
1411
reasonFilter,
15-
type SearchPrefix,
1612
stateFilter,
1713
subjectTypeFilter,
1814
userTypeFilter,
15+
type SearchQualifier,
16+
BASE_QUALIFIERS,
17+
DETAILED_ONLY_QUALIFIERS,
1918
} from '.';
2019

20+
21+
2122
export function filterBaseNotifications(
2223
notifications: Notification[],
2324
settings: SettingsState,
2425
): Notification[] {
2526
return notifications.filter((notification) => {
2627
let passesFilters = true;
2728

28-
passesFilters =
29-
passesFilters &&
30-
passesSearchTokenFiltersForPrefix(notification, settings, ORG_PREFIX);
31-
32-
passesFilters =
33-
passesFilters &&
34-
passesSearchTokenFiltersForPrefix(notification, settings, REPO_PREFIX);
29+
// Apply base qualifier include/exclude filters (org, repo, etc.)
30+
for (const qualifier of BASE_QUALIFIERS) {
31+
if (!passesFilters) break;
32+
passesFilters =
33+
passesFilters &&
34+
passesSearchTokenFiltersForQualifier(notification, settings, qualifier);
35+
}
3536

3637
if (subjectTypeFilter.hasFilters(settings)) {
3738
passesFilters =
@@ -86,12 +87,13 @@ export function hasAnyFiltersSet(settings: SettingsState): boolean {
8687
/**
8788
* Apply include/exclude search token logic for a specific search qualifier prefix.
8889
*/
89-
function passesSearchTokenFiltersForPrefix(
90+
function passesSearchTokenFiltersForQualifier(
9091
notification: Notification,
9192
settings: SettingsState,
92-
prefix: SearchPrefix,
93+
qualifier: SearchQualifier,
9394
): boolean {
9495
let passes = true;
96+
const prefix = qualifier.prefix;
9597

9698
if (hasIncludeSearchFilters(settings)) {
9799
const includeTokens = settings.filterIncludeSearchTokens.filter((t) =>
@@ -136,10 +138,13 @@ function passesUserFilters(
136138
);
137139
}
138140

139-
// Apply author-specific search token filters during detailed filtering
140-
passesFilters =
141-
passesFilters &&
142-
passesSearchTokenFiltersForPrefix(notification, settings, AUTHOR_PREFIX);
141+
// Apply detailed-only qualifier search token filters (e.g. author)
142+
for (const qualifier of DETAILED_ONLY_QUALIFIERS) {
143+
if (!passesFilters) break;
144+
passesFilters =
145+
passesFilters &&
146+
passesSearchTokenFiltersForQualifier(notification, settings, qualifier);
147+
}
143148

144149
return passesFilters;
145150
}

src/renderer/utils/notifications/filters/search.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@ const SEARCH_QUALIFIERS = {
2525
},
2626
} as const;
2727

28-
type SearchQualifierKey = keyof typeof SEARCH_QUALIFIERS;
29-
type SearchQualifier = (typeof SEARCH_QUALIFIERS)[SearchQualifierKey];
28+
export type SearchQualifierKey = keyof typeof SEARCH_QUALIFIERS;
29+
export type SearchQualifier = (typeof SEARCH_QUALIFIERS)[SearchQualifierKey];
3030
export type SearchPrefix = SearchQualifier['prefix'];
3131

3232
export const QUALIFIERS: readonly SearchQualifier[] = Object.values(
3333
SEARCH_QUALIFIERS,
3434
) as readonly SearchQualifier[];
3535

36+
37+
// Pre-split qualifier sets so we don't filter each time for every notification
38+
export const BASE_QUALIFIERS: readonly SearchQualifier[] = QUALIFIERS.filter(
39+
(q) => !q.requiresDetailsNotifications,
40+
);
41+
42+
export const DETAILED_ONLY_QUALIFIERS: readonly SearchQualifier[] = QUALIFIERS.filter(
43+
(q) => q.requiresDetailsNotifications,
44+
);
45+
3646
export const AUTHOR_PREFIX: SearchPrefix = SEARCH_QUALIFIERS.author.prefix;
3747
export const ORG_PREFIX: SearchPrefix = SEARCH_QUALIFIERS.org.prefix;
3848
export const REPO_PREFIX: SearchPrefix = SEARCH_QUALIFIERS.repo.prefix;

0 commit comments

Comments
 (0)