diff --git a/bun.lockb b/bun.lockb index d17a075..46246d8 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/onesearch/handleEnter.ts b/components/onesearch/handleEnter.ts index f3d6fdd..92d602e 100644 --- a/components/onesearch/handleEnter.ts +++ b/components/onesearch/handleEnter.ts @@ -6,14 +6,14 @@ import search from "lib/search"; export default function ( index: number, suggestion: suggestionItem[], - query: string, + _query: string, settings: settingsType, searchBoxRef: React.RefObject ) { const selected = suggestion[index]; const engine = settings.searchEngines[settings.currentSearchEngine]; const newTab = settings.searchInNewTab; - let clipboard: any; + //let clipboard: any; if (selected.type === "QUERY" || selected.type === "default") { search(selected.suggestion, engine, newTab); } else if (selected.type === "NAVIGATION" || selected.type === "default-link") { diff --git a/components/onesearch/handleNLUResult.ts b/components/onesearch/handleNLUResult.ts index 6bddeaa..2ed9577 100644 --- a/components/onesearch/handleNLUResult.ts +++ b/components/onesearch/handleNLUResult.ts @@ -14,8 +14,7 @@ export function handleNLUResult(result: any, updateSuggestion: UpdateSuggestionF getWeather(data.latitude, data.longitude).then((weather) => { console.log(weather["hourly"]); let hourIndex = findClosestDateIndex( - weather["hourly"]["time"], - weather["utc_offset_seconds"] + weather["hourly"]["time"] ); let temp = weather["hourly"]["apparent_temperature"][hourIndex]; let weatherCode = weather["hourly"]["weather_code"][hourIndex]; diff --git a/components/onesearch/onesearch.tsx b/components/onesearch/onesearch.tsx index 1587ed8..0ca2576 100644 --- a/components/onesearch/onesearch.tsx +++ b/components/onesearch/onesearch.tsx @@ -11,15 +11,18 @@ import { selectedSuggestionAtom } from "lib/state/suggestionSelection"; import { settingsAtom } from "lib/state/settings"; import PlainText from "./plainText"; import { sendError } from "lib/telemetering/sendError"; -import { NLU } from "lib/nlp/load"; import { handleNLUResult } from "./handleNLUResult"; import { useAtom, useAtomValue } from "jotai"; import i18next from "i18next"; import { useTranslation } from "react-i18next"; +import { keywordSuggestion } from "lib/onesearch/keywordSuggestion"; +import { NLUType } from "lib/nlp/load"; export default function OneSearch() { const [suggestion, setFinalSuggetsion] = useAtom(suggestionAtom); const [manager, setManager] = useState(null); + const [NLUModel, setNLUModel] = useState(); + const [NLUModelLoaded, setNLUModelLoaded] = useState(false); const lastRequestTimeRef = useRef(0); const selected = useAtomValue(selectedSuggestionAtom); const settings = useAtomValue(settingsAtom); @@ -83,20 +86,32 @@ export default function OneSearch() { }); } - const NLUModel = new NLU(); + (async function () { + const NLU = await import("lib/nlp/load"); + const mainNLUModel = new NLU.NLU(); + setNLUModel(mainNLUModel); + setNLUModelLoaded(true); + })(); useEffect(() => { - NLUModel.init().then((nlu) => { + if (NLUModel === null || NLUModel === undefined) { + return; + } + NLUModel.init().then((nlu: typeof NLUModel) => { setManager(nlu.manager); - console.log(nlu.manager); }); - }, []); + }, [NLUModelLoaded]); useEffect(() => { - cleanSuggestion("default-link", "default", "text"); + cleanSuggestion("default-link", "default", "text", "link"); if (validLink(query)) { updateSuggestion([ - { type: "default-link", suggestion: query, relevance: 3000, prompt: Go to: }, + { + type: "default-link", + suggestion: query, + relevance: 3000, + prompt: Go to: + }, { type: "default", suggestion: query, relevance: 1600 } ]); } else { @@ -109,6 +124,10 @@ export default function OneSearch() { ]); } + if (keywordSuggestion(query) !== null) { + updateSuggestion([keywordSuggestion(query)!]); + } + if (manager != null) { // @ts-ignore manager.process(query).then((result) => { @@ -147,10 +166,16 @@ export default function OneSearch() { )} ); - } else if (s.type === "NAVIGATION" || s.type === "default-link") { + } else if ( + s.type === "NAVIGATION" || + s.type === "default-link" || + s.type === "link" + ) { return ( - {s.prompt && {s.prompt}} + {s.prompt && ( + {s.prompt} + )} {s.suggestion} {devMode && ( @@ -162,7 +187,9 @@ export default function OneSearch() { } else if (s.type === "text") { return ( - {s.prompt && <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span>} + {s.prompt && ( + <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span> + )} <p>{s.suggestion}</p> {devMode && ( <span className="bottom-0 absolute text-zinc-700 dark:text-zinc-400 text-sm leading-10 h-10 right-2"> diff --git a/lib/nlp/load.ts b/lib/nlp/load.ts index b8e5d4d..b99a72d 100644 --- a/lib/nlp/load.ts +++ b/lib/nlp/load.ts @@ -10,6 +10,15 @@ import { LangEn } from "@nlpjs/lang-en-min"; import { LangZh } from "@nlpjs/lang-zh"; import * as fflate from 'fflate'; +export interface NLUType { + manager: any; + inited: boolean; + loadIntentionModel(): Promise<void>; + init(): Promise<this>; + process(lang: string, text: string): Promise<any>; +} + + export class NLU { manager: any; inited: boolean = false; diff --git a/lib/normalizeURL.ts b/lib/normalizeURL.ts index e6aa831..91404c5 100644 --- a/lib/normalizeURL.ts +++ b/lib/normalizeURL.ts @@ -1,7 +1,7 @@ export function normalizeURL(input: string): string { try { // try to create a URL object - const url = new URL(input); + const url = new URL(input, window.location.href); // if the URL is valid, return it return url.href; } catch (error) { diff --git a/lib/onesearch/keywordSuggestion.ts b/lib/onesearch/keywordSuggestion.ts new file mode 100644 index 0000000..88fc9a0 --- /dev/null +++ b/lib/onesearch/keywordSuggestion.ts @@ -0,0 +1,39 @@ +import { suggestionItem } from "global"; + +interface keywordLinkDict { + [key: string]: string; +} + +const dict_en: keywordLinkDict = { + about: "/about" +}; + +const dict_cn: keywordLinkDict = { + 关于: "/about" +}; + +export function keywordSuggestion(query: string) { + for (const keyword in dict_cn) { + if (query.includes(keyword)) { + const result: suggestionItem = { + type: "link", + suggestion: dict_cn[keyword], + prompt: keyword, + relevance: 3000 + }; + return result + } + } + for (const keyword in dict_en) { + if (query.includes(keyword)) { + const result: suggestionItem = { + type: "link", + suggestion: dict_en[keyword], + prompt: keyword, + relevance: 3000 + }; + return result + } + } + return null; +} diff --git a/lib/weather/getCurrentWeather.ts b/lib/weather/getCurrentWeather.ts index b762862..a20a330 100644 --- a/lib/weather/getCurrentWeather.ts +++ b/lib/weather/getCurrentWeather.ts @@ -14,10 +14,9 @@ export function getClosestHourTimestamp(): string { return localHourTimestamp; } -export function findClosestDateIndex(dates: string[], utc_offset_seconds: number): number { +export function findClosestDateIndex(dates: string[]): number { const now = new Date(); const nowTimestamp = now.getTime(); - const offsetMilliseconds = utc_offset_seconds * 1000; let closestIndex = -1; let closestDiff = Infinity; diff --git a/package.json b/package.json index 61666df..9f2030a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sparkhome", "private": false, - "version": "5.5.3", + "version": "5.6.0", "type": "module", "scripts": { "dev": "bun server.ts", @@ -52,6 +52,7 @@ "tailwindcss": "^3.4.4", "typescript": "^5.2.2", "vite": "^5.3.1", + "vite-plugin-chunk-split": "^0.5.0", "vite-plugin-pages": "^0.32.2", "vite-tsconfig-paths": "^4.3.2" } diff --git a/pages/about/index.tsx b/pages/about/index.tsx index 0d27763..4058bfb 100644 --- a/pages/about/index.tsx +++ b/pages/about/index.tsx @@ -44,7 +44,7 @@ export default function AboutPage() { </p> <p className="relative font-bold text-2xl mt-12">Presented By</p> - {!darkMode && <img src="/LuminaraStudio.png" className="relative md:h-56 mt-6" />} + {!darkMode && <img src="/LuminaraStudio.png" className="relative md:h-64 mt-6" />} {darkMode && <img src="/LuminaraStudioDark.png" className="relative md:h-56 mt-6" />} </AboutLayout> ); diff --git a/vite.config.ts b/vite.config.ts index 19acbc7..a5a447a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; import Pages from "vite-plugin-pages"; import tsconfigPaths from 'vite-tsconfig-paths'; +import { chunkSplitPlugin } from 'vite-plugin-chunk-split'; // https://vitejs.dev/config/ export default defineConfig({ @@ -10,6 +11,7 @@ export default defineConfig({ Pages({ dirs: "./pages/" }), - tsconfigPaths() + tsconfigPaths(), + chunkSplitPlugin() ] });