@@ -83,73 +76,35 @@ const Page = () => {
-
- {topics.map((t, i) => (
-
setActiveTopic(t.key)}
- >
- {t.display}
-
- ))}
-
-
- {loading ? (
-
- ) : (
-
- {discover &&
- discover?.map((item, i) => (
-
-

-
-
- {item.title.slice(0, 100)}...
-
-
- {item.content.slice(0, 100)}...
-
+
+ {discover &&
+ discover?.map((item, i) => (
+
+

+
+
+ {item.title.slice(0, 100)}...
-
- ))}
-
- )}
+
+ {item.content.slice(0, 100)}...
+
+
+
+ ))}
+
>
);
diff --git a/src/app/globals.css b/src/app/globals.css
index 6bdc1a8..f75daca 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -11,11 +11,3 @@
display: none;
}
}
-
-@media screen and (-webkit-min-device-pixel-ratio: 0) {
- select,
- textarea,
- input {
- font-size: 16px !important;
- }
-}
diff --git a/src/app/manifest.ts b/src/app/manifest.ts
deleted file mode 100644
index 792e752..0000000
--- a/src/app/manifest.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { MetadataRoute } from 'next';
-
-export default function manifest(): MetadataRoute.Manifest {
- return {
- name: 'Perplexica - Chat with the internet',
- short_name: 'Perplexica',
- description:
- 'Perplexica is an AI powered chatbot that is connected to the internet.',
- start_url: '/',
- display: 'standalone',
- background_color: '#0a0a0a',
- theme_color: '#0a0a0a',
- screenshots: [
- {
- src: '/screenshots/p1.png',
- form_factor: 'wide',
- sizes: '2560x1600',
- },
- {
- src: '/screenshots/p2.png',
- form_factor: 'wide',
- sizes: '2560x1600',
- },
- {
- src: '/screenshots/p1_small.png',
- form_factor: 'narrow',
- sizes: '828x1792',
- },
- {
- src: '/screenshots/p2_small.png',
- form_factor: 'narrow',
- sizes: '828x1792',
- },
- ],
- icons: [
- {
- src: '/icon-50.png',
- sizes: '50x50',
- type: 'image/png' as const,
- },
- {
- src: '/icon-100.png',
- sizes: '100x100',
- type: 'image/png',
- },
- {
- src: '/icon.png',
- sizes: '440x440',
- type: 'image/png',
- purpose: 'any',
- },
- ],
- };
-}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 25981b5..e18aca9 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,5 +1,4 @@
import ChatWindow from '@/components/ChatWindow';
-import { ChatProvider } from '@/lib/hooks/useChat';
import { Metadata } from 'next';
import { Suspense } from 'react';
@@ -12,9 +11,7 @@ const Home = () => {
return (
-
-
-
+
);
diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx
index 6fb8255..8eee9a4 100644
--- a/src/app/settings/page.tsx
+++ b/src/app/settings/page.tsx
@@ -7,7 +7,6 @@ import { Switch } from '@headlessui/react';
import ThemeSwitcher from '@/components/theme/Switcher';
import { ImagesIcon, VideoIcon } from 'lucide-react';
import Link from 'next/link';
-import { PROVIDER_METADATA } from '@/lib/providers';
interface SettingsType {
chatModelProviders: {
@@ -21,10 +20,7 @@ interface SettingsType {
anthropicApiKey: string;
geminiApiKey: string;
ollamaApiUrl: string;
- ollamaApiKey: string;
- lmStudioApiUrl: string;
deepseekApiKey: string;
- aimlApiKey: string;
customOpenaiApiKey: string;
customOpenaiApiUrl: string;
customOpenaiModelName: string;
@@ -145,17 +141,15 @@ const Page = () => {
const [selectedEmbeddingModel, setSelectedEmbeddingModel] = useState<
string | null
>(null);
- const [isLoading, setIsLoading] = useState(true);
+ const [isLoading, setIsLoading] = useState(false);
const [automaticImageSearch, setAutomaticImageSearch] = useState(false);
const [automaticVideoSearch, setAutomaticVideoSearch] = useState(false);
const [systemInstructions, setSystemInstructions] = useState
('');
- const [measureUnit, setMeasureUnit] = useState<'Imperial' | 'Metric'>(
- 'Metric',
- );
const [savingStates, setSavingStates] = useState>({});
useEffect(() => {
const fetchConfig = async () => {
+ setIsLoading(true);
const res = await fetch(`/api/config`, {
headers: {
'Content-Type': 'application/json',
@@ -214,10 +208,6 @@ const Page = () => {
setSystemInstructions(localStorage.getItem('systemInstructions')!);
- setMeasureUnit(
- localStorage.getItem('measureUnit')! as 'Imperial' | 'Metric',
- );
-
setIsLoading(false);
};
@@ -376,8 +366,6 @@ const Page = () => {
localStorage.setItem('embeddingModel', value);
} else if (key === 'systemInstructions') {
localStorage.setItem('systemInstructions', value);
- } else if (key === 'measureUnit') {
- localStorage.setItem('measureUnit', value.toString());
}
} catch (err) {
console.error('Failed to save:', err);
@@ -426,35 +414,13 @@ const Page = () => {
) : (
config && (
-
+
-
-
- Measurement Units
-
-
@@ -548,7 +514,7 @@ const Page = () => {
-
-
- Ollama API Key (Can be left blank)
-
-
{
- setConfig((prev) => ({
- ...prev!,
- ollamaApiKey: e.target.value,
- }));
- }}
- onSave={(value) => saveConfig('ollamaApiKey', value)}
- />
-
-
GROQ API Key
@@ -913,44 +858,6 @@ const Page = () => {
onSave={(value) => saveConfig('deepseekApiKey', value)}
/>
-
-
-
- AI/ML API Key
-
-
{
- setConfig((prev) => ({
- ...prev!,
- aimlApiKey: e.target.value,
- }));
- }}
- onSave={(value) => saveConfig('aimlApiKey', value)}
- />
-
-
-
-
- LM Studio API URL
-
-
{
- setConfig((prev) => ({
- ...prev!,
- lmStudioApiUrl: e.target.value,
- }));
- }}
- onSave={(value) => saveConfig('lmStudioApiUrl', value)}
- />
-
diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx
index a5d8cf9..0cf125b 100644
--- a/src/components/Chat.tsx
+++ b/src/components/Chat.tsx
@@ -5,11 +5,28 @@ import MessageInput from './MessageInput';
import { File, Message } from './ChatWindow';
import MessageBox from './MessageBox';
import MessageBoxLoading from './MessageBoxLoading';
-import { useChat } from '@/lib/hooks/useChat';
-
-const Chat = () => {
- const { messages, loading, messageAppeared } = useChat();
+const Chat = ({
+ loading,
+ messages,
+ sendMessage,
+ messageAppeared,
+ rewrite,
+ fileIds,
+ setFileIds,
+ files,
+ setFiles,
+}: {
+ messages: Message[];
+ sendMessage: (message: string) => void;
+ loading: boolean;
+ messageAppeared: boolean;
+ rewrite: (messageId: string) => void;
+ fileIds: string[];
+ setFileIds: (fileIds: string[]) => void;
+ files: File[];
+ setFiles: (files: File[]) => void;
+}) => {
const [dividerWidth, setDividerWidth] = useState(0);
const dividerRef = useRef