mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 12:12:54 +01:00
web: add full support for highlighting results in notes search
This commit is contained in:
committed by
Abdullah Atta
parent
4aab23b117
commit
23de5d2229
@@ -475,6 +475,7 @@ export function Editor(props: EditorProps) {
|
||||
);
|
||||
const setEditorSaveState = useEditorStore((store) => store.setSaveState);
|
||||
useScrollToBlock(session);
|
||||
useScrollToSearchResult(session);
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoSaveToast.show) {
|
||||
@@ -837,6 +838,25 @@ function useScrollToBlock(session: EditorSession) {
|
||||
}, [session.id, session.type, blockId]);
|
||||
}
|
||||
|
||||
function useScrollToSearchResult(session: EditorSession) {
|
||||
const index = useEditorStore(
|
||||
(store) => store.getSession(session.id)?.activeSearchResultIndex
|
||||
);
|
||||
useEffect(() => {
|
||||
if (index === undefined) return;
|
||||
const scrollContainer = document.getElementById(
|
||||
`editorScroll_${session.id}`
|
||||
);
|
||||
const elements = scrollContainer?.getElementsByTagName("nn-search-result");
|
||||
setTimeout(() =>
|
||||
elements?.item(index)?.scrollIntoView({ block: "center" })
|
||||
);
|
||||
useEditorStore.getState().updateSession(session.id, [session.type], {
|
||||
activeSearchResultIndex: undefined
|
||||
});
|
||||
}, [session.id, session.type, index]);
|
||||
}
|
||||
|
||||
function isFile(e: DragEvent) {
|
||||
return (
|
||||
e.dataTransfer &&
|
||||
|
||||
@@ -27,7 +27,7 @@ import { ChevronDown, ChevronRight } from "../icons";
|
||||
|
||||
type SearchResultProps = {
|
||||
item: HighlightedResult;
|
||||
match?: Match[];
|
||||
matchIndex?: number;
|
||||
depth: number;
|
||||
isExpandable: boolean;
|
||||
isExpanded: boolean;
|
||||
@@ -36,23 +36,43 @@ type SearchResultProps = {
|
||||
};
|
||||
|
||||
function SearchResult(props: SearchResultProps) {
|
||||
const { item, match, collapse, depth, expand, isExpandable, isExpanded } =
|
||||
props;
|
||||
const {
|
||||
item,
|
||||
matchIndex,
|
||||
collapse,
|
||||
depth,
|
||||
expand,
|
||||
isExpandable,
|
||||
isExpanded
|
||||
} = props;
|
||||
|
||||
const isOpened = useEditorStore((store) => store.isNoteOpen(item.id));
|
||||
const match = matchIndex !== undefined ? item.content[matchIndex] : undefined;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
isFocused={isOpened}
|
||||
isCompact={!match}
|
||||
item={item}
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
let activeIndex = 0;
|
||||
for (let i = 0; i <= (matchIndex || 0) - 1; ++i) {
|
||||
activeIndex += item.content[i].length;
|
||||
}
|
||||
useEditorStore
|
||||
.getState()
|
||||
.openSession(item.id, { considerPinnedTab: true })
|
||||
}
|
||||
.openSession(item.id, {
|
||||
rawContent: item.rawContent,
|
||||
force: true,
|
||||
activeSearchResultIndex: activeIndex
|
||||
});
|
||||
}}
|
||||
onMiddleClick={() =>
|
||||
useEditorStore.getState().openSession(item.id, { openInNewTab: true })
|
||||
useEditorStore.getState().openSession(item.id, {
|
||||
openInNewTab: true,
|
||||
rawContent: item.rawContent,
|
||||
force: true
|
||||
})
|
||||
}
|
||||
title={
|
||||
<Flex sx={{ alignItems: "center", gap: "small" }}>
|
||||
|
||||
@@ -83,6 +83,10 @@ export type BaseEditorSession = {
|
||||
* The id of block to scroll to after opening the session successfully.
|
||||
*/
|
||||
activeBlockId?: string;
|
||||
/**
|
||||
* The index of search result to scroll to after opening the session successfully.
|
||||
*/
|
||||
activeSearchResultIndex?: number;
|
||||
};
|
||||
|
||||
export type LockedEditorSession = BaseEditorSession & {
|
||||
@@ -660,10 +664,8 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
activeBlockId?: string;
|
||||
silent?: boolean;
|
||||
openInNewTab?: boolean;
|
||||
/**
|
||||
* Should be true if we want to open a new tab when the active tab is pinned
|
||||
*/
|
||||
considerPinnedTab?: boolean;
|
||||
rawContent?: string;
|
||||
activeSearchResultIndex?: number;
|
||||
} = {}
|
||||
): Promise<void> => {
|
||||
const {
|
||||
@@ -787,6 +789,7 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
id: sessionId,
|
||||
content,
|
||||
activeBlockId: options.activeBlockId,
|
||||
activeSearchResultIndex: options.activeSearchResultIndex,
|
||||
tabId
|
||||
},
|
||||
options.silent
|
||||
@@ -803,10 +806,14 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
type: "readonly",
|
||||
note,
|
||||
id: sessionId,
|
||||
content,
|
||||
content:
|
||||
options.rawContent && content
|
||||
? { data: options.rawContent, type: content.type }
|
||||
: content,
|
||||
color: colors[0]?.fromId,
|
||||
tags,
|
||||
activeBlockId: options.activeBlockId,
|
||||
activeSearchResultIndex: options.activeSearchResultIndex,
|
||||
tabId
|
||||
},
|
||||
options.silent
|
||||
@@ -822,8 +829,12 @@ class EditorStore extends BaseStore<EditorStore> {
|
||||
attachmentsLength,
|
||||
tags,
|
||||
color: colors[0]?.fromId,
|
||||
content,
|
||||
content:
|
||||
options.rawContent && content
|
||||
? { ...content, data: options.rawContent }
|
||||
: content,
|
||||
activeBlockId: options.activeBlockId,
|
||||
activeSearchResultIndex: options.activeSearchResultIndex,
|
||||
tabId
|
||||
},
|
||||
options.silent
|
||||
|
||||
@@ -41,7 +41,7 @@ function Home() {
|
||||
const treeRef = useRef<
|
||||
VirtualizedTreeHandle<{
|
||||
item: HighlightedResult;
|
||||
match?: Match[];
|
||||
matchIndex?: number;
|
||||
}>
|
||||
>(null);
|
||||
const notes = useStore((store) => store.notes);
|
||||
@@ -124,7 +124,7 @@ function Home() {
|
||||
getChildNodes={async (parent) => {
|
||||
const nodes: TreeNode<{
|
||||
item: HighlightedResult;
|
||||
match?: Match[];
|
||||
matchIndex?: number;
|
||||
}>[] = [];
|
||||
if (parent.id === "root") {
|
||||
for (let i = 0; i < filteredItems.length; ++i) {
|
||||
@@ -140,13 +140,16 @@ function Home() {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let i = 0;
|
||||
for (const match of parent.data.item.content || []) {
|
||||
for (
|
||||
let i = 0;
|
||||
i < (parent.data.item.content.length || 0);
|
||||
++i
|
||||
) {
|
||||
nodes.push({
|
||||
data: { item: parent.data.item, match },
|
||||
data: { item: parent.data.item, matchIndex: i },
|
||||
depth: parent.depth + 1,
|
||||
parentId: parent.id,
|
||||
id: parent.id + i++,
|
||||
id: parent.id + i,
|
||||
hasChildren: false
|
||||
});
|
||||
}
|
||||
@@ -159,7 +162,7 @@ function Home() {
|
||||
depth={node.depth}
|
||||
isExpandable={node.hasChildren}
|
||||
item={node.data.item}
|
||||
match={node.data.match}
|
||||
matchIndex={node.data.matchIndex}
|
||||
isExpanded={expanded}
|
||||
collapse={collapse}
|
||||
expand={expand}
|
||||
|
||||
Reference in New Issue
Block a user