diff --git a/Discovery.md b/Discovery.md
index 510e849..cc91940 100644
--- a/Discovery.md
+++ b/Discovery.md
@@ -1,5 +1,5 @@
---
-app_name: "Dialogue AI"
+app_name: "Dialogue"
tagline: "An open-source ChatGPT UI alternative"
git: "https://github.com/deta/dialogue"
theme_color: "#F76705"
@@ -19,4 +19,4 @@ ported_from: "https://github.com/deiucanta/chatpad"
## Credits
-Dialogue AI is a fork of [Chatpad AI](https://github.com/deiucanta/chatpad) with modfications to make it run on Deta Space and various changes and new features like "Incognito Mode", shared chats and a reworked prompts system. It is built on top of the amazing work done by [@deiucanta](https://github.com/deiucanta) and contributors.
\ No newline at end of file
+Dialogue is a fork of [Chatpad AI](https://github.com/deiucanta/chatpad) with modfications to make it run on Deta Space and various changes and new features like "Incognito Mode", shared chats and a reworked prompts system. It is built on top of the amazing work done by [@deiucanta](https://github.com/deiucanta) and contributors.
diff --git a/README.md b/README.md
index 4644f6f..3661e9f 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-# Dialogue AI
+# Dialogue
An open-source ChatGPT UI alternative. Fork of [Chatpad AI](https://github.com/deiucanta/chatpad)
@@ -33,4 +33,4 @@ An open-source ChatGPT UI alternative. Fork of [Chatpad AI](https://github.com/d
## Credits
-Dialogue AI is a fork of [Chatpad AI](https://github.com/deiucanta/chatpad) with modfications to make it run on Deta Space and various changes and new features like "Incognito Mode", shared chats and a reworked prompts system. It is built on top of the amazing work done by [@deiucanta](https://github.com/deiucanta) and contributors.
+Dialogue is a fork of [Chatpad AI](https://github.com/deiucanta/chatpad) with modfications to make it run on Deta Space and various changes and new features like "Incognito Mode", shared chats and a reworked prompts system. It is built on top of the amazing work done by [@deiucanta](https://github.com/deiucanta) and contributors.
diff --git a/index.html b/index.html
index 2ff269e..010d68a 100644
--- a/index.html
+++ b/index.html
@@ -2,7 +2,7 @@
- Dialogue AI
+ Dialogue
([]);
+ const [spotlightActions, setSpotlightActions] = useState([]);
- useEffect(() => {
- const dataFetch = async () => {
- const res = await fetch(`/api/space/actions`)
- const items = await res.json()
- const actions = items as unknown as AppAction[]
+ useEffect(() => {
+ const dataFetch = async () => {
+ const res = await fetch(`/api/space/actions`);
+ const items = await res.json();
+ const actions = items as unknown as AppAction[];
- setSpaceAppActions(actions)
+ setSpaceAppActions(actions);
- const spotlightActionsItems = actions.map(action => ({
- title: action.title,
- description: action.instance_alias,
- icon: action.icon_url ? : ,
- onTrigger: async () => {
- try {
- if (action) {
- const titleKeys = ['title', 'name']
- const contentKeys = ['content', 'description', 'text']
-
- let payload: { [key: string]: string } = {}
- for (const input of action.input!) {
- if (titleKeys.includes(input.name)) {
- payload[input.name] = chat?.description || 'Dialogue AI Chat'
- } else if (contentKeys.includes(input.name)) {
- payload[input.name] = action.app_name === 'Minima' ? contentHtml : contentText
- } else if (input.name === 'html') {
- payload[input.name] = contentHtml
- }
- }
+ const spotlightActionsItems = actions.map((action) => ({
+ title: action.title,
+ description: action.instance_alias,
+ icon: action.icon_url ? (
+
+ ) : (
+
+ ),
+ onTrigger: async () => {
+ try {
+ if (action) {
+ const titleKeys = ["title", "name"];
+ const contentKeys = ["content", "description", "text"];
- const res = await fetch(`/api/space/actions/invoke`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({
- instanceId: action.instance_id,
- actionName: action.name,
- payload: payload
- })
- })
+ let payload: { [key: string]: string } = {};
+ for (const input of action.input!) {
+ if (titleKeys.includes(input.name)) {
+ payload[input.name] = chat?.description || "Dialogue Chat";
+ } else if (contentKeys.includes(input.name)) {
+ payload[input.name] =
+ action.app_name === "Minima" ? contentHtml : contentText;
+ } else if (input.name === "html") {
+ payload[input.name] = contentHtml;
+ }
+ }
- const invocation = await res.json()
- console.log(invocation)
- if (invocation.type === '@deta/raw') {
- navigator.clipboard.writeText(invocation.data)
- } else if (invocation.type === '@deta/detail') {
- navigator.clipboard.writeText(invocation.data.ref || invocation.data.url || invocation.data.title || invocation.data.text)
- } else {
- navigator.clipboard.writeText(JSON.stringify(invocation.data))
- }
-
- notifications.show({
- title: "Success",
- color: "green",
- message: `Action "${action.title}" invoked successfully.`,
- })
- } else {
- notifications.show({
- title: "Error",
- color: "red",
- message: "Integration not found.",
- });
- }
- } catch (error: any) {
- if (error.toJSON().message === "Network Error") {
- notifications.show({
- title: "Error",
- color: "red",
- message: "No internet connection.",
- });
- }
- const message = error.response?.data?.error?.message;
- if (message) {
- notifications.show({
- title: "Error",
- color: "red",
- message,
- });
- }
- }
+ const res = await fetch(`/api/space/actions/invoke`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
},
- }))
+ body: JSON.stringify({
+ instanceId: action.instance_id,
+ actionName: action.name,
+ payload: payload,
+ }),
+ });
- setSpotlightActions(spotlightActionsItems)
- spotlight.open()
- }
- if (open) {
- dataFetch()
- }
- }, [open])
+ const invocation = await res.json();
+ console.log(invocation);
+ if (invocation.type === "@deta/raw") {
+ navigator.clipboard.writeText(invocation.data);
+ } else if (invocation.type === "@deta/detail") {
+ navigator.clipboard.writeText(
+ invocation.data.ref ||
+ invocation.data.url ||
+ invocation.data.title ||
+ invocation.data.text
+ );
+ } else {
+ navigator.clipboard.writeText(JSON.stringify(invocation.data));
+ }
- const handleOpen = () => {
- setOpen(true)
+ notifications.show({
+ title: "Success",
+ color: "green",
+ message: `Action "${action.title}" invoked successfully.`,
+ });
+ } else {
+ notifications.show({
+ title: "Error",
+ color: "red",
+ message: "Integration not found.",
+ });
+ }
+ } catch (error: any) {
+ if (error.toJSON().message === "Network Error") {
+ notifications.show({
+ title: "Error",
+ color: "red",
+ message: "No internet connection.",
+ });
+ }
+ const message = error.response?.data?.error?.message;
+ if (message) {
+ notifications.show({
+ title: "Error",
+ color: "red",
+ message,
+ });
+ }
+ }
+ },
+ }));
+
+ setSpotlightActions(spotlightActionsItems);
+ spotlight.open();
+ };
+ if (open) {
+ dataFetch();
}
+ }, [open]);
- return (
- <>
- {cloneElement(children, { onClick: handleOpen })}
- {open && (
- }
- searchPlaceholder="Search Space App Actions..."
- shortcut={null}
- nothingFoundMessage="Nothing found..."
- onSpotlightOpen={() => setOpen(true)}
- onSpotlightClose={() => setOpen(false)}
- limit={Infinity}
- styles={{
- 'content': {
- border: '4px solid #dbdbdb88'
- },
- 'searchInput': {
- 'border-bottom': '3px solid #dbdbdb54 !important',
- }
- }}
- >
-
- )}
- {/*
+ const handleOpen = () => {
+ setOpen(true);
+ };
+
+ return (
+ <>
+ {cloneElement(children, { onClick: handleOpen })}
+ {open && (
+ }
+ searchPlaceholder="Search Space App Actions..."
+ shortcut={null}
+ nothingFoundMessage="Nothing found..."
+ onSpotlightOpen={() => setOpen(true)}
+ onSpotlightClose={() => setOpen(false)}
+ limit={Infinity}
+ styles={{
+ content: {
+ border: "4px solid #dbdbdb88",
+ },
+ searchInput: {
+ "border-bottom": "3px solid #dbdbdb54 !important",
+ },
+ }}
+ >
+ )}
+ {/*
*/}
- >
- );
+ >
+ );
}
diff --git a/src/layouts/Base.tsx b/src/layouts/Base.tsx
index 07c896a..7b3891e 100644
--- a/src/layouts/Base.tsx
+++ b/src/layouts/Base.tsx
@@ -1,28 +1,28 @@
import {
- ActionIcon,
- AppShell,
- Box,
- Burger,
- Flex,
- MediaQuery,
- Navbar,
- rem,
- ScrollArea,
- SegmentedControl,
- TextInput,
- Tooltip,
- Text,
- useMantineColorScheme,
- useMantineTheme,
- Skeleton,
- Stack,
+ ActionIcon,
+ AppShell,
+ Box,
+ Burger,
+ Flex,
+ MediaQuery,
+ Navbar,
+ rem,
+ ScrollArea,
+ SegmentedControl,
+ TextInput,
+ Tooltip,
+ Text,
+ useMantineColorScheme,
+ useMantineTheme,
+ Skeleton,
+ Stack,
} from "@mantine/core";
import {
- IconSearch,
- IconSettings,
- IconSpy,
- IconSpyOff,
- IconX,
+ IconSearch,
+ IconSettings,
+ IconSpy,
+ IconSpyOff,
+ IconX,
} from "@tabler/icons-react";
import { Link, useNavigate, useRouter } from "@tanstack/react-location";
import { Suspense, useEffect, useState } from "react";
@@ -33,326 +33,358 @@ import { CreatePromptModal } from "../components/CreatePromptModal";
import { LogoIcon } from "../components/Logo";
import { SettingsModal } from "../components/SettingsModal";
import { config } from "../utils/config";
-import { ChatContext, ChatsContext, IncognitoModeContext, PromptsContext, SettingsContext, SpaceAppActionsContext } from "../hooks/contexts";
+import {
+ ChatContext,
+ ChatsContext,
+ IncognitoModeContext,
+ PromptsContext,
+ SettingsContext,
+ SpaceAppActionsContext,
+} from "../hooks/contexts";
import { ChatHeader } from "../components/ChatHeader";
import { useLocalStorage } from "@mantine/hooks";
import { CreateChatButton } from "../components/CreateChatButton";
import { DeleteChatsModal } from "../components/DeleteChatsModal";
import React from "react";
-const Prompts = React.lazy(() => import('../components/Prompts'));
+const Prompts = React.lazy(() => import("../components/Prompts"));
export function BaseLayout({ children }: { children: React.ReactNode }) {
- const theme = useMantineTheme();
- const navigate = useNavigate();
- const router = useRouter();
+ const theme = useMantineTheme();
+ const navigate = useNavigate();
+ const router = useRouter();
- const { colorScheme, toggleColorScheme } = useMantineColorScheme();
- const chatId = useChatId();
+ const { colorScheme, toggleColorScheme } = useMantineColorScheme();
+ const chatId = useChatId();
- const [opened, setOpened] = useState(false);
- const [tab, setTab] = useState<"Chats" | "Prompts">("Chats");
- const [search, setSearch] = useState("");
+ const [opened, setOpened] = useState(false);
+ const [tab, setTab] = useState<"Chats" | "Prompts">("Chats");
+ const [search, setSearch] = useState("");
- const [incognitoMode, setIncognitoMode] = useLocalStorage({
- key: 'incognito-mode', defaultValue: false, getInitialValueInEffect: false
- });
+ const [incognitoMode, setIncognitoMode] = useLocalStorage({
+ key: "incognito-mode",
+ defaultValue: false,
+ getInitialValueInEffect: false,
+ });
- const [settings, setSettings] = useState(null);
- useEffect(() => {
- const dataFetch = async () => {
- let item = await detaDB.settings.get('general');
+ const [settings, setSettings] = useState(null);
+ useEffect(() => {
+ const dataFetch = async () => {
+ let item = await detaDB.settings.get("general");
- if (!item) {
- item = await detaDB.settings.put({
- key: "general",
- openAiModel: config.defaultModel,
- openAiApiType: config.defaultType,
- openAiApiAuth: config.defaultAuth,
- ...(config.defaultKey != '' && { openAiApiKey: config.defaultKey }),
- ...(config.defaultBase != '' && { openAiApiBase: config.defaultBase }),
- ...(config.defaultVersion != '' && { openAiApiVersion: config.defaultVersion }),
- }, 'general');
- }
+ if (!item) {
+ item = await detaDB.settings.put(
+ {
+ key: "general",
+ openAiModel: config.defaultModel,
+ openAiApiType: config.defaultType,
+ openAiApiAuth: config.defaultAuth,
+ ...(config.defaultKey != "" && { openAiApiKey: config.defaultKey }),
+ ...(config.defaultBase != "" && { openAiApiBase: config.defaultBase }),
+ ...(config.defaultVersion != "" && {
+ openAiApiVersion: config.defaultVersion,
+ }),
+ },
+ "general"
+ );
+ }
- setSettings(item as unknown as Settings);
- };
+ setSettings(item as unknown as Settings);
+ };
- dataFetch();
- }, []);
+ dataFetch();
+ }, []);
- const [spaceAppActions, setSpaceAppActions] = useState(null);
- useEffect(() => {
- const dataFetch = async () => {
- const res = await fetch(`/api/space/actions/config`)
- const config = await res.json()
+ const [spaceAppActions, setSpaceAppActions] = useState(null);
+ useEffect(() => {
+ const dataFetch = async () => {
+ const res = await fetch(`/api/space/actions/config`);
+ const config = await res.json();
- if (config.isSetup) {
- setSpaceAppActions([])
- }
- };
+ if (config.isSetup) {
+ setSpaceAppActions([]);
+ }
+ };
- dataFetch();
- }, []);
+ dataFetch();
+ }, []);
- const [chat, setChat] = useState(null);
- useEffect(() => {
- const dataFetch = async () => {
- const item = await detaDB.chats.get(chatId!);
- const fetchedChat = item as unknown as Chat
+ const [chat, setChat] = useState(null);
+ useEffect(() => {
+ const dataFetch = async () => {
+ const item = await detaDB.chats.get(chatId!);
+ const fetchedChat = item as unknown as Chat;
- setChat(fetchedChat);
+ setChat(fetchedChat);
- if (fetchedChat.private && !incognitoMode) {
- setIncognitoMode(true)
- if (colorScheme === 'light') {
- toggleColorScheme()
- }
- } else if (!(fetchedChat.private ?? false) && incognitoMode) {
- setIncognitoMode(false)
- if (colorScheme === 'dark') {
- toggleColorScheme()
- }
- }
- };
-
- if (chatId) {
- dataFetch();
- } else {
- setChat(null);
+ if (fetchedChat.private && !incognitoMode) {
+ setIncognitoMode(true);
+ if (colorScheme === "light") {
+ toggleColorScheme();
}
- }, [chatId]);
-
- const [fetchingChats, setFetchingChats] = useState(false);
- const [chats, setChats] = useState([]);
- useEffect(() => {
- const dataFetch = async () => {
- setFetchingChats(true);
- const { items } = await detaDB.chats.fetch(incognitoMode ? { private: true } : { 'private?ne': true });
-
- setChats(items as unknown as Chat[]);
- setFetchingChats(false);
- };
-
- dataFetch();
- }, [incognitoMode]);
-
- const [prompts, setPrompts] = useState([]);
- useEffect(() => {
- const dataFetch = async () => {
- const { items } = await detaDB.prompts.fetch();
-
- setPrompts(items as unknown as Prompt[]);
- };
-
- dataFetch();
- }, []);
-
- const border = `${rem(1)} solid ${
- theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]
- }`;
-
- useEffect(() => {
- setOpened(false);
- }, [router.state.location]);
-
- const handleIncognito = () => {
- const newValue = !incognitoMode
-
- // if we are in a chat that doesn't match the mode, navigate to home view
- if (chat && (chat?.private ?? false) !== newValue) {
- setChat(null)
- navigate({ to: `/`, replace: true });
+ } else if (!(fetchedChat.private ?? false) && incognitoMode) {
+ setIncognitoMode(false);
+ if (colorScheme === "dark") {
+ toggleColorScheme();
}
+ }
+ };
- setIncognitoMode(newValue)
+ if (chatId) {
+ dataFetch();
+ } else {
+ setChat(null);
+ }
+ }, [chatId]);
- const isDark = colorScheme === 'dark'
- if (newValue && !isDark) {
- toggleColorScheme()
- } else if (!newValue && isDark) {
- toggleColorScheme()
- }
+ const [fetchingChats, setFetchingChats] = useState(false);
+ const [chats, setChats] = useState([]);
+ useEffect(() => {
+ const dataFetch = async () => {
+ setFetchingChats(true);
+ const { items } = await detaDB.chats.fetch(
+ incognitoMode ? { private: true } : { "private?ne": true }
+ );
+
+ setChats(items as unknown as Chat[]);
+ setFetchingChats(false);
+ };
+
+ dataFetch();
+ }, [incognitoMode]);
+
+ const [prompts, setPrompts] = useState([]);
+ useEffect(() => {
+ const dataFetch = async () => {
+ const { items } = await detaDB.prompts.fetch();
+
+ setPrompts(items as unknown as Prompt[]);
+ };
+
+ dataFetch();
+ }, []);
+
+ const border = `${rem(1)} solid ${
+ theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]
+ }`;
+
+ useEffect(() => {
+ setOpened(false);
+ }, [router.state.location]);
+
+ const handleIncognito = () => {
+ const newValue = !incognitoMode;
+
+ // if we are in a chat that doesn't match the mode, navigate to home view
+ if (chat && (chat?.private ?? false) !== newValue) {
+ setChat(null);
+ navigate({ to: `/`, replace: true });
}
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- Dialogue AI
-
-
-
- {incognitoMode ? (
-
-
-
-
-
- ) : (
-
-
-
-
-
- )}
-
-
- ({
- [theme.fn.smallerThan('md')]: {
- marginRight: '2.5rem',
- },
- })}
- >
-
-
-
-
-
-
-
- ({
- padding: rem(4),
- background:
- theme.colorScheme === "dark"
- ? theme.colors.dark[8]
- : theme.colors.gray[1],
- borderBottom: border,
- })}
- >
- setTab(value as typeof tab)}
- data={["Chats", "Prompts"]}
- />
-
- ({
- padding: rem(4),
- background:
- theme.colorScheme === "dark"
- ? theme.colors.dark[7]
- : theme.white,
- borderBottom: border,
- })}
- >
-
- setSearch(event.currentTarget.value.toLowerCase())
- }
- sx={{ paddingInline: 4 }}
- icon={ }
- rightSection={
- !!search && (
- setSearch("")}>
- {" "}
-
- )
- }
- />
-
-
- {tab === "Chats" && (fetchingChats ? (
-
-
-
-
-
- ) : ( ))}
- {tab === "Prompts" && (
-
-
-
-
-
- }>
- setTab("Chats")} />
-
- )}
-
-
-
- {tab === "Chats" && (
- <>
- { incognitoMode && (
-
- )}
-
- {incognitoMode ? "New Private Chat" : "New Chat"}
-
- >
- )}
- {tab === "Prompts" && }
-
-
-
- }
- header={
- chat ? (
-
- ) : undefined
- }
- layout="alt"
- padding={0}
+ setIncognitoMode(newValue);
+
+ const isDark = colorScheme === "dark";
+ if (newValue && !isDark) {
+ toggleColorScheme();
+ } else if (!newValue && isDark) {
+ toggleColorScheme();
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialogue
+
+
+
+ {incognitoMode ? (
+
+
+
+
+
+ ) : (
+
+
+
+
+
+ )}
+
+
+ ({
+ [theme.fn.smallerThan("md")]: {
+ marginRight: "2.5rem",
+ },
+ })}
>
-
- setOpened((o) => !o)}
- size="sm"
- color={theme.colors.gray[6]}
- className="app-region-no-drag"
- sx={{ position: "fixed", top: 16, right: 16, zIndex: 100 }}
- />
-
- {children}
-
-
-
-
-
-
-
- );
+
+
+
+
+
+
+
+ ({
+ padding: rem(4),
+ background:
+ theme.colorScheme === "dark"
+ ? theme.colors.dark[8]
+ : theme.colors.gray[1],
+ borderBottom: border,
+ })}
+ >
+ setTab(value as typeof tab)}
+ data={["Chats", "Prompts"]}
+ />
+
+ ({
+ padding: rem(4),
+ background:
+ theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white,
+ borderBottom: border,
+ })}
+ >
+
+ setSearch(event.currentTarget.value.toLowerCase())
+ }
+ sx={{ paddingInline: 4 }}
+ icon={ }
+ rightSection={
+ !!search && (
+ setSearch("")}>
+ {" "}
+
+ )
+ }
+ />
+
+
+ {tab === "Chats" &&
+ (fetchingChats ? (
+
+
+
+
+
+ ) : (
+
+ ))}
+ {tab === "Prompts" && (
+
+
+
+
+
+ }
+ >
+ setTab("Chats")} />
+
+ )}
+
+
+
+ {tab === "Chats" && (
+ <>
+ {incognitoMode && }
+
+ {incognitoMode ? "New Private Chat" : "New Chat"}
+
+ >
+ )}
+ {tab === "Prompts" && }
+
+
+
+ }
+ header={chat ? : undefined}
+ layout="alt"
+ padding={0}
+ >
+
+ setOpened((o) => !o)}
+ size="sm"
+ color={theme.colors.gray[6]}
+ className="app-region-no-drag"
+ sx={{ position: "fixed", top: 16, right: 16, zIndex: 100 }}
+ />
+
+ {children}
+
+
+
+
+
+
+
+ );
}
diff --git a/src/layouts/Public.tsx b/src/layouts/Public.tsx
index 3dd47e5..37720c9 100644
--- a/src/layouts/Public.tsx
+++ b/src/layouts/Public.tsx
@@ -1,7 +1,4 @@
-import {
- AppShell,
- useMantineColorScheme,
-} from "@mantine/core";
+import { AppShell, useMantineColorScheme } from "@mantine/core";
import { useEffect, useState } from "react";
import { Chat } from "../db";
import { usePublicChatId } from "../hooks/useChatId";
@@ -10,52 +7,54 @@ import { ChatHeader } from "../components/ChatHeader";
import { useLocalStorage } from "@mantine/hooks";
export function PublicLayout({ children }: { children: React.ReactNode }) {
- const { colorScheme } = useMantineColorScheme();
- const chatId = usePublicChatId();
+ const { colorScheme } = useMantineColorScheme();
+ const chatId = usePublicChatId();
- const [incognitoMode, setIncognitoMode] = useLocalStorage({
- key: 'incognito-mode', defaultValue: false, getInitialValueInEffect: false
- });
+ const [incognitoMode, setIncognitoMode] = useLocalStorage({
+ key: "incognito-mode",
+ defaultValue: false,
+ getInitialValueInEffect: false,
+ });
- const [chat, setChat] = useState(null);
- useEffect(() => {
- const dataFetch = async () => {
- try {
- const res = await fetch(`/api/public/chats/${chatId}`)
- const item = await res.json()
+ const [chat, setChat] = useState(null);
+ useEffect(() => {
+ const dataFetch = async () => {
+ try {
+ const res = await fetch(`/api/public/chats/${chatId}`);
+ const item = await res.json();
- const fetchedChat = item as unknown as Chat
- setChat(fetchedChat);
+ const fetchedChat = item as unknown as Chat;
+ setChat(fetchedChat);
- document.title = fetchedChat.description ? `${fetchedChat.description} | Dialogue AI` : 'Dialogue AI'
- } catch (e) {
- console.error(e)
- }
- };
+ document.title = fetchedChat.description
+ ? `${fetchedChat.description} | Dialogue`
+ : "Dialogue";
+ } catch (e) {
+ console.error(e);
+ }
+ };
- if (chatId) {
- dataFetch();
- } else {
- setChat(null);
- }
- }, [chatId]);
+ if (chatId) {
+ dataFetch();
+ } else {
+ setChat(null);
+ }
+ }, [chatId]);
- return (
-
-
-
- ) : undefined
- }
- layout="alt"
- padding={0}
- >
- {children}
-
-
-
- );
+ return (
+
+
+ : undefined}
+ layout="alt"
+ padding={0}
+ >
+ {children}
+
+
+
+ );
}
diff --git a/src/routes/IndexRoute.tsx b/src/routes/IndexRoute.tsx
index f928ce0..0223239 100644
--- a/src/routes/IndexRoute.tsx
+++ b/src/routes/IndexRoute.tsx
@@ -1,5 +1,22 @@
-import { Container, SimpleGrid, Flex, Button, Text, useMantineTheme, Center, Box, Tooltip, ActionIcon, Card } from "@mantine/core";
-import { useChats, useIncognitoMode, usePrompts, useSettings } from "../hooks/contexts";
+import {
+ Container,
+ SimpleGrid,
+ Flex,
+ Button,
+ Text,
+ useMantineTheme,
+ Center,
+ Box,
+ Tooltip,
+ ActionIcon,
+ Card,
+} from "@mantine/core";
+import {
+ useChats,
+ useIncognitoMode,
+ usePrompts,
+ useSettings,
+} from "../hooks/contexts";
import { Welcome } from "../components/Welcome";
import { LogoIcon } from "../components/Logo";
import { CreateChatButton } from "../components/CreateChatButton";
@@ -9,120 +26,148 @@ import { notifications } from "@mantine/notifications";
import { Chat, detaDB, generateKey } from "../db";
import { useNavigate } from "@tanstack/react-location";
-
export function IndexRoute() {
- const { settings } = useSettings()
- const theme = useMantineTheme()
- const { incognitoMode } = useIncognitoMode()
- const navigate = useNavigate();
+ const { settings } = useSettings();
+ const theme = useMantineTheme();
+ const { incognitoMode } = useIncognitoMode();
+ const navigate = useNavigate();
- const { setChats } = useChats()
- const { prompts } = usePrompts()
+ const { setChats } = useChats();
+ const { prompts } = usePrompts();
- return (
- <>
-
- {prompts && prompts.length > 0 ? (
-
-
-
-
- Dialogue AI
-
-
-
- An open-source ChatGPT UI alternative
-
-
- {prompts.slice(-9).reverse().map((prompt) => (
-
-
-
- {prompt.title}
-
-
- {prompt.content || prompt.writingCharacter || prompt.writingTone || prompt.writingFormat || prompt.writingStyle || "No Instructions"}
-
-
+ return (
+ <>
+
+ {prompts && prompts.length > 0 ? (
+
+
+
+
+ Dialogue
+
+
+
+ An open-source ChatGPT UI alternative
+
+
+ {prompts
+ .slice(-9)
+ .reverse()
+ .map((prompt) => (
+
+
+
+ {prompt.title}
+
+
+ {prompt.content ||
+ prompt.writingCharacter ||
+ prompt.writingTone ||
+ prompt.writingFormat ||
+ prompt.writingStyle ||
+ "No Instructions"}
+
+
-
- {
- if (!settings?.openAiApiKey) {
- notifications.show({
- title: "Error",
- color: "red",
- message: "OpenAI API Key is not defined. Please set your API Key",
- });
- return;
- };
+
+ {
+ if (!settings?.openAiApiKey) {
+ notifications.show({
+ title: "Error",
+ color: "red",
+ message:
+ "OpenAI API Key is not defined. Please set your API Key",
+ });
+ return;
+ }
- const item = await detaDB.chats.put({
- description: prompt.title ? `New ${prompt.title} Chat` : "New Chat",
- prompt: prompt.key,
- writingInstructions: prompt.content,
- writingCharacter: prompt.writingCharacter,
- writingTone: prompt.writingTone,
- writingStyle: prompt.writingStyle,
- writingFormat: prompt.writingFormat,
- totalTokens: 0,
- createdAt: new Date().toISOString(),
- }, generateKey())
+ const item = await detaDB.chats.put(
+ {
+ description: prompt.title
+ ? `New ${prompt.title} Chat`
+ : "New Chat",
+ prompt: prompt.key,
+ writingInstructions: prompt.content,
+ writingCharacter: prompt.writingCharacter,
+ writingTone: prompt.writingTone,
+ writingStyle: prompt.writingStyle,
+ writingFormat: prompt.writingFormat,
+ totalTokens: 0,
+ createdAt: new Date().toISOString(),
+ },
+ generateKey()
+ );
- const chat = item as unknown as Chat
- setChats(current => ([...(current || []), chat]))
+ const chat = item as unknown as Chat;
+ setChats((current) => [...(current || []), chat]);
- navigate({ to: `/chats/${chat.key}` });
- }}
- >
-
-
-
-
- ))}
-
-
-
- {settings?.openAiApiKey && (
-
- {incognitoMode ? "Create a New Private Chat" : "Create a New Chat"}
-
- )}
-
- }
- >
- {settings?.openAiApiKey ? "Change OpenAI Key" : "Enter OpenAI Key"}
-
-
-
-
- ) : (
-
- )}
-
- >
- );
+ navigate({ to: `/chats/${chat.key}` });
+ }}
+ >
+
+
+
+
+ ))}
+
+
+
+ {settings?.openAiApiKey && (
+
+ {incognitoMode ? "Create a New Private Chat" : "Create a New Chat"}
+
+ )}
+
+ }
+ >
+ {settings?.openAiApiKey ? "Change OpenAI Key" : "Enter OpenAI Key"}
+
+
+
+
+ ) : (
+
+ )}
+
+ >
+ );
}