buttons should work with summary and grid view

This commit is contained in:
Josh Hawkins 2025-11-03 14:59:05 -06:00
parent 8ed13c0b08
commit a6d4ce02c5

View File

@ -80,6 +80,15 @@ export default function SearchView({
}); });
const navigate = useNavigate(); const navigate = useNavigate();
const { data: exploreEvents } = useSWR<SearchResult[]>(
(!searchFilter || Object.keys(searchFilter).length === 0) &&
!searchTerm &&
defaultView === "summary"
? ["events/explore", { limit: isMobileOnly ? 5 : 10 }]
: null,
{ revalidateOnFocus: true },
);
// grid // grid
const gridClassName = cn( const gridClassName = cn(
@ -202,20 +211,24 @@ export default function SearchView({
], ],
); );
// remove duplicate event ids
const uniqueResults = useMemo(() => {
return searchResults?.filter(
(value, index, self) =>
index === self.findIndex((v) => v.id === value.id),
);
}, [searchResults]);
// detail // detail
const [searchDetail, setSearchDetail] = useState<SearchResult>(); const [searchDetail, setSearchDetail] = useState<SearchResult>();
const [page, setPage] = useState<SearchTab>("snapshot"); const [page, setPage] = useState<SearchTab>("snapshot");
// remove duplicate event ids
const uniqueResults = useMemo(() => {
if (!searchResults) return [];
const results = searchResults.filter(
(value, index, self) =>
index === self.findIndex((v) => v.id === value.id),
);
return results;
}, [searchResults]);
// search interaction // search interaction
const [selectedObjects, setSelectedObjects] = useState<string[]>([]); const [selectedObjects, setSelectedObjects] = useState<string[]>([]);
@ -285,17 +298,23 @@ export default function SearchView({
// update search detail when results change // update search detail when results change
useEffect(() => { useEffect(() => {
if (searchDetail && searchResults) { if (searchDetail) {
const flattenedResults = searchResults.flat(); const results =
const updatedSearchDetail = flattenedResults.find( defaultView === "summary" ? exploreEvents : searchResults?.flat();
(result) => result.id === searchDetail.id, if (results) {
); const updatedSearchDetail = results.find(
(result) => result.id === searchDetail.id,
);
if (updatedSearchDetail && !isEqual(updatedSearchDetail, searchDetail)) { if (
setSearchDetail(updatedSearchDetail); updatedSearchDetail &&
!isEqual(updatedSearchDetail, searchDetail)
) {
setSearchDetail(updatedSearchDetail);
}
} }
} }
}, [searchResults, searchDetail]); }, [searchResults, exploreEvents, searchDetail, defaultView]);
const hasExistingSearch = useMemo( const hasExistingSearch = useMemo(
() => searchResults != undefined || searchFilter != undefined, () => searchResults != undefined || searchFilter != undefined,
@ -306,13 +325,49 @@ export default function SearchView({
const [inputFocused, setInputFocused] = useState(false); const [inputFocused, setInputFocused] = useState(false);
const goToPrevious = useCallback(() => {
const results =
exploreEvents && defaultView === "summary"
? exploreEvents.filter((event) => event.label === searchDetail?.label)
: uniqueResults;
if (results && results.length > 0) {
const currentIndex = searchDetail
? results.findIndex((result) => result.id === searchDetail.id)
: -1;
const newIndex =
currentIndex === -1
? results.length - 1
: (currentIndex - 1 + results.length) % results.length;
setSearchDetail(results[newIndex]);
}
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
const goToNext = useCallback(() => {
const results =
exploreEvents && defaultView === "summary"
? exploreEvents.filter((event) => event.label === searchDetail?.label)
: uniqueResults;
if (results && results.length > 0) {
const currentIndex = searchDetail
? results.findIndex((result) => result.id === searchDetail.id)
: -1;
const newIndex =
currentIndex === -1 ? 0 : (currentIndex + 1) % results.length;
setSearchDetail(results[newIndex]);
}
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
const onKeyboardShortcut = useCallback( const onKeyboardShortcut = useCallback(
(key: string | null, modifiers: KeyModifiers) => { (key: string | null, modifiers: KeyModifiers) => {
if (inputFocused) { if (inputFocused) {
return false; return false;
} }
if (!modifiers.down || !uniqueResults) { if (!modifiers.down || (!uniqueResults && !exploreEvents)) {
return true; return true;
} }
@ -327,43 +382,23 @@ export default function SearchView({
setSelectedObjects([]); setSelectedObjects([]);
return true; return true;
case "ArrowLeft": case "ArrowLeft":
if (uniqueResults.length > 0) { goToPrevious();
const currentIndex = searchDetail
? uniqueResults.findIndex(
(result) => result.id === searchDetail.id,
)
: -1;
const newIndex =
currentIndex === -1
? uniqueResults.length - 1
: (currentIndex - 1 + uniqueResults.length) %
uniqueResults.length;
setSearchDetail(uniqueResults[newIndex]);
}
return true; return true;
case "ArrowRight": case "ArrowRight":
if (uniqueResults.length > 0) { goToNext();
const currentIndex = searchDetail
? uniqueResults.findIndex(
(result) => result.id === searchDetail.id,
)
: -1;
const newIndex =
currentIndex === -1
? 0
: (currentIndex + 1) % uniqueResults.length;
setSearchDetail(uniqueResults[newIndex]);
}
return true; return true;
} }
return false; return false;
}, },
[uniqueResults, inputFocused, onSelectAllObjects, searchDetail], [
uniqueResults,
exploreEvents,
inputFocused,
onSelectAllObjects,
goToPrevious,
goToNext,
],
); );
useKeyboardListener( useKeyboardListener(
@ -469,16 +504,22 @@ export default function SearchView({
return ( return (
<div className="flex size-full flex-col pt-2 md:py-2"> <div className="flex size-full flex-col pt-2 md:py-2">
<Toaster closeButton={true} /> <Toaster closeButton={true} />
<SearchDetailDialog <div className="relative">
search={searchDetail} {searchDetail && (
page={page} <SearchDetailDialog
setSearch={setSearchDetail} search={searchDetail}
setSearchPage={setPage} page={page}
setSimilarity={ setSearch={setSearchDetail}
searchDetail && (() => setSimilaritySearch(searchDetail)) setSearchPage={setPage}
} setSimilarity={
setInputFocused={setInputFocused} searchDetail && (() => setSimilaritySearch(searchDetail))
/> }
setInputFocused={setInputFocused}
onPrevious={goToPrevious}
onNext={goToNext}
/>
)}
</div>
<div <div
className={cn( className={cn(