fix: support multiple search results within a single summary in HypaV3 modal

This commit is contained in:
Bo26fhmC5M
2025-01-22 23:49:22 +09:00
parent 22e4b3d07c
commit 2d22e9da5c

View File

@@ -53,6 +53,10 @@
interface SearchResult { interface SearchResult {
element: HTMLElement; element: HTMLElement;
matchType: "chatMemo" | "summary"; matchType: "chatMemo" | "summary";
summaryPosition?: {
start: number;
end: number;
};
} }
interface SearchUI { interface SearchUI {
@@ -177,66 +181,69 @@
summaryUIStates.forEach((summaryUI) => { summaryUIStates.forEach((summaryUI) => {
const textAreaText = summaryUI.originalRef.value?.toLowerCase(); const textAreaText = summaryUI.originalRef.value?.toLowerCase();
if (textAreaText.includes(normalizedQuery)) { let pos = -1;
while (
(pos = textAreaText.indexOf(normalizedQuery, pos + 1)) !== -1
) {
results.push({ results.push({
element: summaryUI.originalRef as HTMLTextAreaElement, element: summaryUI.originalRef as HTMLTextAreaElement,
matchType: "summary", matchType: "summary",
summaryPosition: {
start: pos,
end: pos + normalizedQuery.length,
},
}); });
} }
}); });
} }
searchUIState.results = results; searchUIState.results = results;
searchUIState.currentIndex = -1;
} }
// Rotate search results if (searchUIState.results.length === 0) return;
if (searchUIState.results.length > 0) {
searchUIState.currentIndex =
(searchUIState.currentIndex + 1) % searchUIState.results.length;
const currentResult = searchUIState.results[searchUIState.currentIndex]; // Move to next result
searchUIState.currentIndex =
(searchUIState.currentIndex + 1) % searchUIState.results.length;
// Scroll to element const result = searchUIState.results[searchUIState.currentIndex];
currentResult.element.scrollIntoView({
behavior: "instant",
block: "center",
});
if (currentResult.matchType === "chatMemo") { // Scroll to element
// Simulate focus effect result.element.scrollIntoView({
currentResult.element.classList.add("ring-2", "ring-zinc-500"); behavior: "instant",
block: "center",
});
// Remove focus effect after a short delay if (result.matchType === "chatMemo") {
window.setTimeout(() => { // Highlight chatMemo result
currentResult.element.classList.remove("ring-2", "ring-zinc-500"); result.element.classList.add("ring-2", "ring-zinc-500");
}, 1000);
} else {
const textarea = currentResult.element as HTMLTextAreaElement;
const startIndex = textarea.value
.toLowerCase()
.indexOf(normalizedQuery);
const lineHeight = parseInt(
window.getComputedStyle(textarea).lineHeight,
10
);
if (startIndex !== -1) { // Remove highlight after a short delay
// Select query window.setTimeout(() => {
textarea.setSelectionRange( result.element.classList.remove("ring-2", "ring-zinc-500");
startIndex, }, 1000);
startIndex + normalizedQuery.length } else {
); // Handle summary text selection
const textarea = result.element as HTMLTextAreaElement;
// Scroll to the bottom // Make readonly temporarily
textarea.scrollTop = textarea.scrollHeight; textarea.readOnly = true;
textarea.blur(); // Collapse selection // Select query
textarea.focus(); // This scrolls the textarea textarea.setSelectionRange(
result.summaryPosition.start,
result.summaryPosition.end
);
searchUIState.ref.focus(); // Restore focus to search bar textarea.scrollTop = textarea.scrollHeight; // Scroll to the bottom
} textarea.blur(); // Collapse selection
} textarea.focus(); // This scrolls the textarea
// Highlight textarea
window.setTimeout(() => {
searchUIState.ref.focus(); // Restore focus to search bar
textarea.readOnly = false; // Remove readonly after focus moved
}, 300);
} }
} }
} }
@@ -842,7 +849,7 @@
{#if searchUIState.results.length > 0} {#if searchUIState.results.length > 0}
<span <span
class="absolute right-3 top-1/2 -translate-y-1/2 px-1.5 sm:py-3 py-1 sm:py-2 rounded text-sm font-semibold text-zinc-100 bg-zinc-700/65" class="absolute right-3 top-1/2 -translate-y-1/2 px-1.5 sm:px-3 py-1 sm:py-2 rounded text-sm font-semibold text-zinc-100 bg-zinc-700/65"
> >
{searchUIState.currentIndex + 1}/{searchUIState.results {searchUIState.currentIndex + 1}/{searchUIState.results
.length} .length}