diff --git a/components/search/search.tsx b/components/search/search.tsx index d41ff84..bea8cf0 100644 --- a/components/search/search.tsx +++ b/components/search/search.tsx @@ -1,15 +1,36 @@ -'use client'; +"use client"; import { atom, useRecoilValue } from "recoil"; import { settingsState } from "../state/settings"; import { useTranslations } from "next-intl"; +import { useState } from "react"; +import { normalizeURL } from "@/lib/normalizeURL"; +export default function Search(props: { onFocus: () => void }) { + const settings: settings = useRecoilValue(settingsState); + const t = useTranslations("Search"); + const [query, setQuery] = useState(""); -export default function Search(props: { - onFocus: () => void; -}) { - const settings = useRecoilValue(settingsState); - const t = useTranslations('Search'); let style = "default"; + + function handleKeydown(e: any) { + let URL = ""; + let url_re = + /^https?:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?:?[0-9]{0,5}\/?[-a-zA-Z0-9_.~!*'();:@&=+$,/?#\[\]%]*$/; + let domain_re = + /^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z][-a-zA-Z]{0,62})+\.?:?[0-9]{0,5}\/?[-a-zA-Z0-9_.~!*'();:@&=+$,/?#\[\]%]*$/; + let ip_re = + /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}:?[0-9]{0,5}\/?[-a-zA-Z0-9_.~!*'();:@&=+$,/?#\[\]%]*$/; + if (url_re.test(query) || domain_re.test(query) || ip_re.test(query)) { + URL = normalizeURL(query); + } else { + URL = settings.searchEngines[settings.currentSearchEngine]; + URL = URL.replace("%s", query); + } + if (e.key == "Enter") { + location.href=URL; + } + } + if (style === "default") { return ( // 祖传样式,勿动 @@ -21,8 +42,15 @@ export default function Search(props: { dark:placeholder:text-slate-400 text-slate-900 dark:text-white" id="searchBox" type="text" - placeholder={t('placeholder')} + placeholder={t("placeholder")} onFocus={props.onFocus} + onKeyDown={handleKeydown} + onChange={(e) => setQuery(e.target.value)} + autoComplete="off" + autoCorrect="off" + autoCapitalize="off" + spellCheck="false" + value={query} /> ); @@ -43,7 +71,7 @@ export default function Search(props: { } id="searchBox" type="text" - placeholder={t('placeholder')} + placeholder={t("placeholder")} onFocus={props.onFocus} /> diff --git a/global.d.ts b/global.d.ts index 7d817e5..66fa85b 100644 --- a/global.d.ts +++ b/global.d.ts @@ -1,3 +1,10 @@ type settings = { - bgBlur: boolean -}; \ No newline at end of file + version: number; + elementBackdrop: boolean; + bgBlur: boolean; + timeShowSecond: boolean; + currentSearchEngine: string; + searchEngines: { + [key: string]: string, + }; +}; diff --git a/lib/normalizeURL.ts b/lib/normalizeURL.ts new file mode 100644 index 0000000..998b3b9 --- /dev/null +++ b/lib/normalizeURL.ts @@ -0,0 +1,19 @@ +export function normalizeURL(input: string): string { + try { + // try to create a URL object + const url = new URL(input); + // if the URL is valid, return it + return url.href; + } catch (error) { + // if the URL is invalid, try to add the protocol + const withHTTP = "http://" + input; + try { + const urlWithHTTP = new URL(withHTTP); + return urlWithHTTP.href; + } catch (error) { + // if the URL is still invalid, return the original input + console.error("Invalid URL:", input); + return input; + } + } +}