Merge pull request 'main' (#40) from React-Group/interstellar_ai:main into main

Reviewed-on: https://interstellardevelopment.org/code/code/sageTheDm/interstellar_ai/pulls/40
This commit is contained in:
Patrick 2024-10-07 09:11:03 +02:00
commit a0aad08f0e
16 changed files with 198 additions and 240 deletions

View file

@ -1,34 +0,0 @@
import React, { useState, useRef } from 'react'
export const AudioRecorder= () => {
const [isRecording, setIsRecording] = useState(false)
const [audioURL, setAudioURL] = useState<string | null>(null)
const mediaRecorderRef = useRef<MediaRecorder | null>(null)
const audioChunks = useRef<Blob[]>([])
const startRecording = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const mediaRecorder = new MediaRecorder(stream)
mediaRecorderRef.current = mediaRecorder
mediaRecorder.ondataavailable = (event) => {
audioChunks.current.push(event.data)
}
mediaRecorder.onstop = () => {
const audioBlob = new Blob(audioChunks.current, { type: "audio/wav" })
const url = URL.createObjectURL(audioBlob)
setAudioURL(url)
audioChunks.current = []
}
mediaRecorder.start()
setIsRecording(true)
}
const stopRecording = () => {
mediaRecorderRef.current?.stop()
setIsRecording(false)
}
}

View file

@ -1,4 +1,4 @@
type ChatMessage = {
/* type ChatMessage = {
name: string;
messages: any;
timestamp: number;
@ -26,3 +26,4 @@ function removeMessageFromHistory(timestamp: number): void {
console.log(`Message not found with timestamp: ${timestamp}`);
}
}
*/

View file

@ -1,5 +1,5 @@
"use client"
import React, { use, useEffect, useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import ConversationFrontend from '../components/ConversationFrontend';
import InputFrontend from "../components/InputFrontend";
import { sendToVoiceRecognition } from "./voice_backend"
@ -61,7 +61,6 @@ const InputOutputBackend: React.FC = () => {
const [accessToken, setAccessToken] = useState("")
const postWorkerRef = useRef<Worker | null>(null)
const getWorkerRef = useRef<Worker | null>(null)
const [liveMessage, setLiveMessage] = useState("")
const [inputMessage, setInputMessage] = useState<string>("")
const [inputDisabled, setInputDisabled] = useState(false)
const [isRecording, setIsRecording] = useState(false)
@ -123,7 +122,7 @@ const InputOutputBackend: React.FC = () => {
const data = event.data
if (event.data == "error") {
setLiveMessage("error getting AI response: " + data.error)
console.log("Error getting ai message.")
} else {
console.log("Received data:", data);
editLastMessage(data.response)
@ -171,7 +170,7 @@ const InputOutputBackend: React.FC = () => {
if (postWorkerRef.current) {
addMessage("user", inputValue)
const type = localStorage.getItem('type')
var api_key: string = ""
let api_key: string = ""
if (type != null && type != 'local') {
const try_key = localStorage.getItem(type)
if (try_key) {
@ -236,7 +235,7 @@ const InputOutputBackend: React.FC = () => {
}
const handleResendClick = () => {
var temporary_message = messages[messages.length - 2]['content']
const temporary_message = messages[messages.length - 2]['content']
const updatedMessages = messages.slice(0, -2)
setMessages(updatedMessages)
endGetWorker()
@ -246,7 +245,7 @@ const InputOutputBackend: React.FC = () => {
}
const handleEditClick = () => {
let newestMessage = messages[messages.length - 2].content
const newestMessage = messages[messages.length - 2].content
setInputMessage(newestMessage)
const updatedMessages = messages.slice(0, messages.length - 2)
setMessages(updatedMessages)

View file

@ -1,5 +1,4 @@
import { Settings } from 'electron'
import React from 'react'
/* import { Settings } from 'electron'
type Message = {
role: string
@ -14,7 +13,7 @@ type Chat = {
type Data = {
chats: Chat[]
settings: Settings[]
}
} */

View file

@ -21,7 +21,7 @@ to check if the request was accepted or declined, check response.data.response,
const apiURL = new URL("http://localhost:5000/interstellar_ai/db")
apiURL.hostname = window.location.hostname;
export const sendToDatabase = async (data: any): Promise<boolean> => {
export const sendToDatabase = async (data: object): Promise<boolean> => {
try {
const response = await axios.post(apiURL.href, data);
const status = response.data.status;
@ -30,11 +30,12 @@ export const sendToDatabase = async (data: any): Promise<boolean> => {
return success;
} catch (error) {
postMessage({ status: 500, success: false });
console.log(error)
return false;
}
};
export const sendToDatabaseAndGetString = async (data: any): Promise<string> => {
export const sendToDatabaseAndGetString = async (data: object): Promise<string> => {
try {
const response = await axios.post(apiURL.href, data);
const status = response.data.status;
@ -43,6 +44,7 @@ export const sendToDatabaseAndGetString = async (data: any): Promise<string> =>
return success;
} catch (error) {
postMessage({ status: 500, success: false });
console.log(error)
return "false";
}
};
@ -99,7 +101,7 @@ export const getName = async (usernameOrEmail: string, password: string): Promis
return await sendToDatabaseAndGetString(data);
};
export const changeData = async (usernameOrEmail: string, password: string, newData: any) => {
export const changeData = async (usernameOrEmail: string, password: string, newData: object) => {
const data = {
action: "change_settings",
username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail,
@ -117,7 +119,7 @@ export const checkCredentials = async (usernameOrEmail: string, password: string
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
password,
};
var sendBack = await sendToDatabase(data);
const sendBack = await sendToDatabase(data);
if (sendBack) {
localStorage.setItem("accountEmail", await getEmail(usernameOrEmail, password))
localStorage.setItem("accountName", await getName(usernameOrEmail, password))

View file

@ -112,4 +112,6 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
}
);
ConversationFrontend.displayName = "ConversationFrontend";
export default ConversationFrontend;

View file

@ -21,7 +21,7 @@ const Documentation = () => {
We are committed to designing a visually appealing graphical user interface (GUI) that significantly enhances user experience and engagement. The GUI will prominently feature a chat function, allowing users to interact seamlessly with the AI Assistant. This conversational interface will facilitate easy communication, making it intuitive for users to ask questions and receive responses.
</p>
<p className="paragraph">
To further improve usability, we will incorporate distinct buttons that enable users to switch effortlessly between online and offline modes. This functionality ensures that users can access the AI's capabilities regardless of their internet connectivity, making the application versatile and accommodating to various user environments.
To further improve usability, we will incorporate distinct buttons that enable users to switch effortlessly between online and offline modes. This functionality ensures that users can access the AI&apos;s capabilities regardless of their internet connectivity, making the application versatile and accommodating to various user environments.
</p>
<p className="paragraph">
Additionally, the interface will provide options for users to select from a range of AI models, each tailored for specific use cases such as coding assistance, mathematical problem-solving, and language translation. This feature empowers users to choose the most suitable AI for their needs, thereby enhancing the overall effectiveness and relevance of the application.
@ -66,10 +66,10 @@ const Documentation = () => {
Our current prototype operates on a straightforward Python backend, which, while functional, relies heavily on our optimism that it will remain stable and not encounter any critical failures or data loss.
</p>
<p className="paragraph">
The existing chat system is equipped with several key features designed to enhance user interaction. Users can easily resend the AI's response, allowing for quick follow-up questions or clarifications. Additionally, the system provides the ability to edit user messages, ensuring that any mistakes can be corrected without starting the conversation anew.
The existing chat system is equipped with several key features designed to enhance user interaction. Users can easily resend the AI&apos;s response, allowing for quick follow-up questions or clarifications. Additionally, the system provides the ability to edit user messages, ensuring that any mistakes can be corrected without starting the conversation anew.
</p>
<p className="paragraph">
Furthermore, users have the option to copy the AI's responses, facilitating easy sharing or saving of information for future reference. These features aim to create a more flexible and user-friendly experience, allowing for seamless communication and interaction with the AI.
Furthermore, users have the option to copy the AI&apos;s responses, facilitating easy sharing or saving of information for future reference. These features aim to create a more flexible and user-friendly experience, allowing for seamless communication and interaction with the AI.
</p>
<p className="paragraph">
While the current setup serves as a solid foundation, we recognize the need for further improvements and enhancements to ensure reliability and robustness as we move forward in the development process.

View file

@ -12,7 +12,7 @@ const FAQ: React.FC = () => {
<div className="faq-item">
<h3>How does the AI assistant work?</h3>
<p>The assistant uses machine learning algorithms to understand your input and provide contextually relevant answers or generate content based on the task you've described.</p>
<p>The assistant uses machine learning algorithms to understand your input and provide contextually relevant answers or generate content based on the task you&apos;ve described.</p>
</div>
<div className="faq-item">
@ -32,11 +32,11 @@ const FAQ: React.FC = () => {
<div className="faq-item">
<h3>How can I provide feedback about the AI assistant?</h3>
<p>Feedback can be provided through our feedback form, available on our website. We appreciate your input and use it to improve the AI assistant's performance.</p>
<p>Feedback can be provided through our feedback form, available on our website. We appreciate your input and use it to improve the AI assistant&apos;s performance.</p>
</div>
<div className="faq-item">
<h3>Can I customize the AI assistant's responses?</h3>
<h3>Can I customize the AI assistant&apos;s responses?</h3>
<p>Customization options are limited in the current version, but we are working on features that will allow users to tailor responses to better suit their needs.</p>
</div>
@ -77,7 +77,7 @@ const FAQ: React.FC = () => {
<div className="faq-item">
<h3>How can I access previous conversations?</h3>
<p>Previous conversations can be accessed through the chat history feature available in the assistant's interface.</p>
<p>Previous conversations can be accessed through the chat history feature available in the assistant&apos;s interface.</p>
</div>
<div className="faq-item">

View file

@ -59,4 +59,6 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
}
);
InputFrontend.displayName = "InputFrontend";
export default InputFrontend;

View file

@ -55,7 +55,7 @@ const Login: React.FC = () => {
const success = await checkCredentials(accountName, password);
if (success) {
setIsLoggedIn(true); // Successful login
var data = await getData(accountName, password)
const data = await getData(accountName, password)
if (data) {
localStorage.setItem("dataFromServer", data)
}
@ -131,7 +131,7 @@ const Login: React.FC = () => {
{/* Text for creating an account */}
<p>
Don't have an account yet? Create one{' '}
Don&apos;t have an account yet? Create one{' '}
<span
style={{ color: 'blue', cursor: 'pointer' }}
onClick={toggleSignUpPopup}

View file

@ -173,10 +173,10 @@ const ModelSection: React.FC = () => {
const [radioSelection, setRadioSelection] = useState<string | null>("")
const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState('');
const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState<string | null>("");
const [isOpenSourceMode, setIsOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false")
const [isOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false")
useEffect(() => {
var temp = localStorage.getItem("activeSelectedAIFunction") || ""
const temp = localStorage.getItem("activeSelectedAIFunction") || ""
setActiveSelectedAIFunction(temp)
if (!localStorage.getItem('selectedModelDropdown')) {
localStorage.setItem("selectedModelDropdown", "Offline Fast")
@ -215,7 +215,7 @@ const ModelSection: React.FC = () => {
}, []); // Dependency array can remain empty if you only want this to run on mount
useEffect(() => {
var storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || "";
const storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || "";
if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) {
setCurrentSelectedAIFunction(storedActiveSelectedAIFunction);
}
@ -225,7 +225,7 @@ const ModelSection: React.FC = () => {
const newModel = event.target.value;
setSelectedModelDropdown(newModel);
localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly
var model = localStorage.getItem('activeSelectedAIFunction') || "Code"
const model = localStorage.getItem('activeSelectedAIFunction') || "Code"
modelClicked(model)
};
@ -287,7 +287,7 @@ const ModelSection: React.FC = () => {
const modelClicked = (model: string) => {
localStorage.setItem('activeSelectedAIFunction', model)
setActiveSelectedAIFunction(model)
var modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast'
const modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast'
const selectedAIFunction = modelDropdown as keyof typeof modelList;
localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]])
localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]])

View file

@ -6,12 +6,12 @@ interface ButtonSettingProps {
className?: string; // Optional additional classes for styling
}
const ButtonSetting: React.FC<ButtonSettingProps> = ({ label, onClick, className }) => {
const ButtonSetting: React.FC<ButtonSettingProps> = ({ label, onClick }) => {
return (
<div className="settings-option">
<button
onClick={onClick} // Call the onClick function when the button is clicked
className={className="export-button"} // Apply any additional classes
className={"export-button"} // Apply any additional classes
>
{label} {/* Display the label on the button */}
</button>

View file

@ -1,6 +1,5 @@
// ThemeDropdown.tsx
import React from 'react';
import { applyTheme, applyCustomTheme } from './theme';
const ThemeDropdown: React.FC<{
selectedTheme: string;

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { applyTheme, applyCustomTheme } from './theme';
import { applyTheme } from './theme';
import { exportSettings, importSettings } from './settingUtils'; // Import utility functions
import { getAllLocalStorageItems } from '../../backend/GetLocalStorage';
import ColorSetting from './ColorSettings';
@ -14,7 +14,6 @@ import {
changeData,
createAccount,
deleteAccount,
getData,
} from '../../backend/database';
import ThemeDropdown from './DropDownTheme';
@ -35,12 +34,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
return false; // Default to false if item is null or empty
};
interface SettingsProps {
closeSettings: () => void;
accountName: string;
handleLogout: () => void; // Add this line to accept handleLogout as a prop
}
// Active section
const [activeSection, setActiveSection] = useState(() => localStorage.getItem('activeSection') || 'general');
@ -65,7 +58,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [newName, setNewName] = useState(() => localStorage.getItem('newName') || '');
const [newEmail, setNewEmail] = useState(() => localStorage.getItem('newEmail') || '');
const [newPassword, setNewPassword] = useState(() => localStorage.getItem('newPassword') || '');
const [currentPassword, setCurrentPassword] = useState('');
// Measurement setting
const [preferredMeasurement, setPreferredMeasurement] = useState(() => localStorage.getItem('preferredMeasurement') || 'Metric');
@ -91,7 +83,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [inputBorderColor, setInputBorderColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--input-border-color').trim());
const [fontFamily, setFontFamily] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--font-family').trim());
const [fontSize, setFontSize] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--font-size').trim());
const [burgerMenu, setBurgerMenu] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [burgerMenu] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [burgerMenuBackgroundColor, setBurgerMenuBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--burger-menu-background-color').trim());
const [faqBackgroundColor, setFaqBackgroundColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--faq-background-color').trim());
const [faqHeadingColor, setFaqHeadingColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--faq-heading-color').trim());
@ -122,7 +114,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
const [openai, setOpenai] = useState(localStorage.getItem('openai') || "");
const [anthropic, setAnthropic] = useState(localStorage.getItem('anthropic') || "");
const [google, setGoogle] = useState(localStorage.getItem('google') || "");
const [myBoolean, setMyBoolean] = useState<boolean | any>(() => getItemFromLocalStorage('myBoolean'));
const [myBoolean, setMyBoolean] = useState<boolean>(() => getItemFromLocalStorage('myBoolean'));
const settings = {
userPreferences: {
@ -344,9 +336,9 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
// Function to handle updating all credentials
const handleUpdateCredentials = async () => {
var useName = localStorage.getItem("accountName")
var useEmail = localStorage.getItem("accountEmail")
var usePassword = localStorage.getItem("accountPassword")
let useName = localStorage.getItem("accountName")
let useEmail = localStorage.getItem("accountEmail")
let usePassword = localStorage.getItem("accountPassword")
if (useName && useEmail && usePassword) {
await deleteAccount(useName, usePassword)
@ -372,8 +364,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
// Function to handle account deletion
const handleDeleteAccount = async () => {
var useName = localStorage.getItem("accountName")
var usePassword = localStorage.getItem("accountPassword")
const useName = localStorage.getItem("accountName")
const usePassword = localStorage.getItem("accountPassword")
if (useName && usePassword) {
const success = await deleteAccount(useName, usePassword);
if (success) {

View file

@ -2,14 +2,14 @@
// Method to export localStorage to a JSON object
export function exportSettings(): string {
const settings: { [key: string]: any } = {};
const settings: { [key: string]: string } = {};
// Loop through all keys in localStorage and add them to the settings object
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key) {
if (key !== "accountName" && key !== "accountPassword" && key !== "accountEmail") {
settings[key] = localStorage.getItem(key);
settings[key] = localStorage.getItem(key) || "";
}
}
}

View file

@ -41,13 +41,10 @@ const LandingPage: React.FC = () => {
}
};
const [selectedTheme, setSelectedTheme] = useState<string>('');
// Apply theme based on selectedTheme and color settings
useEffect(() => {
const savedTheme = localStorage.getItem('selectedTheme');
if (savedTheme) {
setSelectedTheme(savedTheme);
switch (savedTheme) {
case 'IOMARKET':
applyIOMarketTheme();
@ -107,4 +104,3 @@ const LandingPage: React.FC = () => {
};
export default LandingPage;