13 changed files with 938 additions and 764 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
/** |
||||
* Service class for handling event search operations |
||||
* AI-NOTE: 2025-01-24 - Extracted from EventSearch component for better separation of concerns |
||||
*/ |
||||
export class EventSearchService { |
||||
/** |
||||
* Determines the search type from a query string |
||||
*/ |
||||
getSearchType(query: string): { type: string; term: string } | null { |
||||
const lowerQuery = query.toLowerCase(); |
||||
|
||||
if (lowerQuery.startsWith("d:")) { |
||||
const dTag = query.slice(2).trim().toLowerCase(); |
||||
return dTag ? { type: "d", term: dTag } : null; |
||||
} |
||||
|
||||
if (lowerQuery.startsWith("t:")) { |
||||
const searchTerm = query.slice(2).trim(); |
||||
return searchTerm ? { type: "t", term: searchTerm } : null; |
||||
} |
||||
|
||||
if (lowerQuery.startsWith("n:")) { |
||||
const searchTerm = query.slice(2).trim(); |
||||
return searchTerm ? { type: "n", term: searchTerm } : null; |
||||
} |
||||
|
||||
if (query.includes("@")) { |
||||
return { type: "nip05", term: query }; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Checks if a search value matches the current event |
||||
*/ |
||||
isCurrentEventMatch(searchValue: string, event: any, relays: string[]): boolean { |
||||
const currentEventId = event.id; |
||||
let currentNaddr = null; |
||||
let currentNevent = null; |
||||
let currentNpub = null; |
||||
let currentNprofile = null; |
||||
|
||||
try { |
||||
const { neventEncode, naddrEncode, nprofileEncode } = require("$lib/utils"); |
||||
const { getMatchingTags, toNpub } = require("$lib/utils/nostrUtils"); |
||||
|
||||
currentNevent = neventEncode(event, relays); |
||||
} catch {} |
||||
|
||||
try { |
||||
const { naddrEncode } = require("$lib/utils"); |
||||
const { getMatchingTags } = require("$lib/utils/nostrUtils"); |
||||
|
||||
currentNaddr = getMatchingTags(event, "d")[0]?.[1] |
||||
? naddrEncode(event, relays) |
||||
: null; |
||||
} catch {} |
||||
|
||||
try { |
||||
const { toNpub } = require("$lib/utils/nostrUtils"); |
||||
currentNpub = event.kind === 0 ? toNpub(event.pubkey) : null; |
||||
} catch {} |
||||
|
||||
if ( |
||||
searchValue && |
||||
searchValue.startsWith("nprofile1") && |
||||
event.kind === 0 |
||||
) { |
||||
try { |
||||
const { nprofileEncode } = require("$lib/utils"); |
||||
currentNprofile = nprofileEncode(event.pubkey, relays); |
||||
} catch {} |
||||
} |
||||
|
||||
return ( |
||||
searchValue === currentEventId || |
||||
(currentNaddr && searchValue === currentNaddr) || |
||||
(currentNevent && searchValue === currentNevent) || |
||||
(currentNpub && searchValue === currentNpub) || |
||||
(currentNprofile && searchValue === currentNprofile) |
||||
); |
||||
} |
||||
} |
||||
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
/** |
||||
* Service class for managing search state operations |
||||
* AI-NOTE: 2025-01-24 - Extracted from EventSearch component for better separation of concerns |
||||
*/ |
||||
export class SearchStateManager { |
||||
/** |
||||
* Updates the search state with new values |
||||
*/ |
||||
updateSearchState( |
||||
state: { |
||||
searching: boolean; |
||||
searchCompleted: boolean; |
||||
searchResultCount: number | null; |
||||
searchResultType: string | null; |
||||
}, |
||||
onLoadingChange?: (loading: boolean) => void |
||||
): void { |
||||
if (onLoadingChange) { |
||||
onLoadingChange(state.searching); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Resets all search state to initial values |
||||
*/ |
||||
resetSearchState( |
||||
callbacks: { |
||||
onSearchResults: (events: any[], secondOrder: any[], tTagEvents: any[], eventIds: Set<string>, addresses: Set<string>) => void; |
||||
cleanupSearch: () => void; |
||||
clearTimeout: () => void; |
||||
} |
||||
): void { |
||||
callbacks.cleanupSearch(); |
||||
callbacks.onSearchResults([], [], [], new Set(), new Set()); |
||||
callbacks.clearTimeout(); |
||||
} |
||||
|
||||
/** |
||||
* Handles search errors with consistent error handling |
||||
*/ |
||||
handleSearchError( |
||||
error: unknown, |
||||
defaultMessage: string, |
||||
callbacks: { |
||||
setLocalError: (error: string | null) => void; |
||||
cleanupSearch: () => void; |
||||
updateSearchState: (state: any) => void; |
||||
resetProcessingFlags: () => void; |
||||
} |
||||
): void { |
||||
const errorMessage = error instanceof Error ? error.message : defaultMessage; |
||||
callbacks.setLocalError(errorMessage); |
||||
callbacks.cleanupSearch(); |
||||
callbacks.updateSearchState({ |
||||
searching: false, |
||||
searchCompleted: false, |
||||
searchResultCount: null, |
||||
searchResultType: null |
||||
}); |
||||
callbacks.resetProcessingFlags(); |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
/** |
||||
* Utility class for formatting search result messages |
||||
* AI-NOTE: 2025-01-24 - Extracted from EventSearch component for better separation of concerns |
||||
*/ |
||||
export class SearchResultFormatter { |
||||
/** |
||||
* Formats a result message based on search count and type |
||||
*/ |
||||
formatResultMessage(searchResultCount: number | null, searchResultType: string | null): string { |
||||
if (searchResultCount === 0) { |
||||
return "Search completed. No results found."; |
||||
} |
||||
|
||||
const typeLabel = |
||||
searchResultType === "n" |
||||
? "profile" |
||||
: searchResultType === "nip05" |
||||
? "NIP-05 address" |
||||
: "event"; |
||||
const countLabel = searchResultType === "n" ? "profiles" : "events"; |
||||
|
||||
return searchResultCount === 1 |
||||
? `Search completed. Found 1 ${typeLabel}.` |
||||
: `Search completed. Found ${searchResultCount} ${countLabel}.`; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue