mirror of
https://github.com/gethomepage/homepage.git
synced 2026-09-17 09:35:50 -07:00
Fix QL Copilot thing
This commit is contained in:
@@ -15,6 +15,16 @@ const MOBILE_BUTTON_POSITIONS = {
|
||||
"bottom-right": "bottom-4 right-4",
|
||||
};
|
||||
|
||||
function parseUrl(searchString) {
|
||||
if (!/.+[.:].+/.test(searchString)) return null; // basic test for probably a url
|
||||
|
||||
try {
|
||||
return new URL(searchString.toLowerCase().startsWith("http") ? searchString : `https://${searchString}`);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getSearchResults({
|
||||
hideVisitURL,
|
||||
searchDescriptions,
|
||||
@@ -77,7 +87,7 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea
|
||||
const searchField = useRef();
|
||||
|
||||
const [currentItemIndex, setCurrentItemIndex] = useState(null);
|
||||
const [url, setUrl] = useState(null);
|
||||
const url = parseUrl(searchString);
|
||||
const [searchSuggestions, setSearchSuggestions] = useState([]);
|
||||
|
||||
const { data: widgets } = useSWR("/api/widgets");
|
||||
@@ -134,17 +144,8 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea
|
||||
function handleSearchChange(event) {
|
||||
const rawSearchString = event.target.value;
|
||||
setCurrentItemIndex(null);
|
||||
try {
|
||||
if (!/.+[.:].+/g.test(rawSearchString)) throw new Error(); // basic test for probably a url
|
||||
let urlString = rawSearchString;
|
||||
if (urlString.toLowerCase().indexOf("http") !== 0) urlString = `https://${rawSearchString}`;
|
||||
setUrl(new URL(urlString)); // basic validation
|
||||
setSearchString(rawSearchString);
|
||||
return;
|
||||
} catch (e) {
|
||||
setUrl(null);
|
||||
}
|
||||
setSearchString(rawSearchString.toLowerCase());
|
||||
// urls keep their casing, everything else is lowercased for matching
|
||||
setSearchString(parseUrl(rawSearchString) ? rawSearchString : rawSearchString.toLowerCase());
|
||||
}
|
||||
|
||||
function handleSearchKeyDown(event) {
|
||||
|
||||
@@ -46,13 +46,25 @@ function Wrapper({ servicesAndBookmarks = [], initialOpen = true } = {}) {
|
||||
const [isOpen, setSearching] = useState(initialOpen);
|
||||
|
||||
return (
|
||||
<QuickLaunch
|
||||
servicesAndBookmarks={servicesAndBookmarks}
|
||||
searchString={searchString}
|
||||
setSearchString={setSearchString}
|
||||
isOpen={isOpen}
|
||||
setSearching={setSearching}
|
||||
/>
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
data-testid="seed-key"
|
||||
onClick={() => {
|
||||
setSearchString((current) => `${current}g`);
|
||||
setSearching(true);
|
||||
}}
|
||||
>
|
||||
seed
|
||||
</button>
|
||||
<QuickLaunch
|
||||
servicesAndBookmarks={servicesAndBookmarks}
|
||||
searchString={searchString}
|
||||
setSearchString={setSearchString}
|
||||
isOpen={isOpen}
|
||||
setSearching={setSearching}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -151,6 +163,35 @@ describe("components/quicklaunch", () => {
|
||||
openSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("does not carry a previous url result into a search seeded by a keypress", async () => {
|
||||
renderWithProviders(<Wrapper />, {
|
||||
settings: {
|
||||
target: "_self",
|
||||
quicklaunch: {
|
||||
provider: "duckduckgo",
|
||||
showSearchSuggestions: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const input = screen.getByPlaceholderText("Search");
|
||||
await waitFor(() => expect(input).toHaveFocus());
|
||||
|
||||
fireEvent.change(input, { target: { value: "example.com" } });
|
||||
expect(await screen.findByText("quicklaunch.visit URL")).toBeInTheDocument();
|
||||
|
||||
fireEvent.keyDown(input, { key: "Escape" });
|
||||
await act(async () => {
|
||||
await new Promise((r) => setTimeout(r, 350));
|
||||
});
|
||||
|
||||
// reopen by "typing" a character, the way pages/index does
|
||||
fireEvent.click(screen.getByTestId("seed-key"));
|
||||
|
||||
expect(input).toHaveValue("g");
|
||||
expect(screen.queryByText("quicklaunch.visit URL")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("closes on Escape and clears the search string after the timeout", async () => {
|
||||
renderWithProviders(<Wrapper />, {
|
||||
settings: {
|
||||
|
||||
Reference in New Issue
Block a user