Files
khoj/src/interface/web/app/common/utils.ts
sabaimran a89160e2f7 Add support for converting an attached doc and chatting with it
- Document is first converted in the chatinputarea, then sent to the chat component. From there, it's sent in the chat API body and then processed by the backend
- We couldn't directly use a UploadFile type in the backend API because we'd have to convert the api type to a multipart form. This would require other client side migrations without uniform benefit, which is why we do it in this two-phase process. This also gives us capacity to repurpose the moe generic interface down the road.
2024-11-07 16:06:37 -08:00

99 lines
2.7 KiB
TypeScript

import { useEffect, useState } from "react";
import useSWR from "swr";
export interface LocationData {
city?: string;
region?: string;
country?: string;
countryCode?: string;
timezone: string;
}
const locationFetcher = () =>
window
.fetch("https://ipapi.co/json")
.then((res) => res.json())
.catch((err) => console.log(err));
export const toTitleCase = (str: string) =>
str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase());
export function welcomeConsole() {
console.log(
`%c %s`,
"font-family:monospace",
`
__ __ __ __ ______ __ _____ __
/\\ \\/ / /\\ \\_\\ \\ /\\ __ \\ /\\ \\ /\\ __ \\ /\\ \\
\\ \\ _"-. \\ \\ __ \\ \\ \\ \\/\\ \\ _\\_\\ \\ \\ \\ __ \\ \\ \\ \\
\\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\ \\_____\\ /\\_____\\ \\ \\_\\ \\_\\ \\ \\_\\
\\/_/\\/_/ \\/_/\\/_/ \\/_____/ \\/_____/ \\/_/\\/_/ \\/_/
Greetings traveller,
I am ✨Khoj✨, your open-source, personal AI copilot.
See my source code at https://github.com/khoj-ai/khoj
Read my operating manual at https://docs.khoj.dev
`,
);
}
export function useIPLocationData() {
const { data: locationData, error: locationDataError } = useSWR<LocationData>(
"/api/ip",
locationFetcher,
{ revalidateOnFocus: false },
);
if (locationDataError || !locationData) return;
return locationData;
}
export function useIsMobileWidth() {
const [isMobileWidth, setIsMobileWidth] = useState(false);
useEffect(() => {
const handleResize = () => {
if (window.innerWidth <= 768) {
setIsMobileWidth(true);
} else {
setIsMobileWidth(false);
}
};
handleResize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return isMobileWidth;
}
export const convertBytesToText = (fileSize: number) => {
if (fileSize < 1024) {
return `${fileSize} B`;
} else if (fileSize < 1024 * 1024) {
return `${(fileSize / 1024).toFixed(2)} KB`;
} else {
return `${(fileSize / (1024 * 1024)).toFixed(2)} MB`;
}
};
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}