Feature/v2/embed pdf (#4437)

Switched to Embed pdf for viewer

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: James Brunton <[email protected]>
This commit is contained in:
Reece Browne
2025-09-19 15:35:51 +01:00
committed by GitHub
co-authored by Copilot James Brunton
parent f29bbfd15b
commit 065bb46c1e
27 changed files with 2730 additions and 728 deletions
@@ -0,0 +1,71 @@
import { useEffect, useState } from 'react';
import { useSearch } from '@embedpdf/plugin-search/react';
import { useViewer } from '../../contexts/ViewerContext';
interface SearchResult {
pageIndex: number;
rects: Array<{
origin: { x: number; y: number };
size: { width: number; height: number };
}>;
}
/**
* SearchAPIBridge manages search state and provides search functionality.
* Listens for search result changes from EmbedPDF and maintains local state.
*/
export function SearchAPIBridge() {
const { provides: search } = useSearch();
const { registerBridge } = useViewer();
const [localState, setLocalState] = useState({
results: null as SearchResult[] | null,
activeIndex: 0
});
// Subscribe to search result changes from EmbedPDF
useEffect(() => {
if (!search) return;
const unsubscribe = search.onSearchResultStateChange?.((state: any) => {
const newState = {
results: state?.results || null,
activeIndex: (state?.activeResultIndex || 0) + 1 // Convert to 1-based index
};
setLocalState(prevState => {
// Only update if state actually changed
if (prevState.results !== newState.results || prevState.activeIndex !== newState.activeIndex) {
return newState;
}
return prevState;
});
});
return unsubscribe;
}, [search]);
// Register bridge whenever search API or state changes
useEffect(() => {
if (search) {
registerBridge('search', {
state: localState,
api: {
search: async (query: string) => {
search.startSearch();
return search.searchAllPages(query);
},
clear: () => {
search.stopSearch();
setLocalState({ results: null, activeIndex: 0 });
},
next: () => search.nextResult(),
previous: () => search.previousResult(),
goToResult: (index: number) => search.goToResult(index),
}
});
}
}, [search, localState]);
return null;
}