Merge branch 'main' into main
This commit is contained in:
commit
157f4a2351
10 changed files with 859 additions and 664 deletions
|
@ -176,7 +176,7 @@ const InputOutputBackend: React.FC = () => {
|
|||
}
|
||||
}
|
||||
setInputMessage("")
|
||||
postWorkerRef.current.postMessage({ messages: [...messages, { role: "user", content: inputValue }], ai_model: localStorage.getItem('model'), model_type: type, access_token: accessToken, api_key: api_key })
|
||||
postWorkerRef.current.postMessage({ messages: [...messages, { role: "user", content: inputValue }], ai_model: "llama3.2", model_type: type, access_token: accessToken, api_key: api_key })
|
||||
startGetWorker()
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,11 @@ const InputOutputBackend: React.FC = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleStopClick = () => {
|
||||
endGetWorker()
|
||||
getNewToken()
|
||||
}
|
||||
|
||||
const handleResendClick = () => {
|
||||
var temporary_message = messages[messages.length - 2]['content']
|
||||
const updatedMessages = messages.slice(0, -2)
|
||||
|
@ -272,6 +277,7 @@ const InputOutputBackend: React.FC = () => {
|
|||
<ConversationFrontend
|
||||
ref={conversationRef}
|
||||
messages={messages}
|
||||
onStopClick={handleStopClick}
|
||||
onResendClick={handleResendClick}
|
||||
onEditClick={handleEditClick}
|
||||
onCopyClick={handleCopyClick}
|
||||
|
|
|
@ -31,6 +31,19 @@ export const sendToDatabase = async (data: any): Promise<boolean> => {
|
|||
}
|
||||
};
|
||||
|
||||
export const sendToDatabaseAndGetString = async (data: any): Promise<string> => {
|
||||
try {
|
||||
const response = await axios.post("http://localhost:5000/interstellar_ai/db", data);
|
||||
const status = response.data.status;
|
||||
const success = response.data.response;
|
||||
postMessage({ status, success });
|
||||
return success;
|
||||
} catch (error) {
|
||||
postMessage({ status: 500, success: false });
|
||||
return "false";
|
||||
}
|
||||
};
|
||||
|
||||
// Functions for each action
|
||||
export const createAccount = async (username: string, email: string, password: string) => {
|
||||
const data = {
|
||||
|
@ -60,7 +73,27 @@ export const getData = async (usernameOrEmail: string, password: string) => {
|
|||
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
|
||||
password,
|
||||
};
|
||||
return await sendToDatabase(data);
|
||||
return await sendToDatabaseAndGetString(data);
|
||||
};
|
||||
|
||||
export const getEmail = async (usernameOrEmail: string, password: string): Promise<string> => {
|
||||
const data = {
|
||||
action: "get_email",
|
||||
username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail,
|
||||
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
|
||||
password,
|
||||
};
|
||||
return await sendToDatabaseAndGetString(data);
|
||||
};
|
||||
|
||||
export const getName = async (usernameOrEmail: string, password: string): Promise<string> => {
|
||||
const data = {
|
||||
action: "get_name",
|
||||
username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail,
|
||||
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
|
||||
password,
|
||||
};
|
||||
return await sendToDatabaseAndGetString(data);
|
||||
};
|
||||
|
||||
export const changeData = async (usernameOrEmail: string, password: string, newData: any) => {
|
||||
|
@ -81,7 +114,13 @@ export const checkCredentials = async (usernameOrEmail: string, password: string
|
|||
email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined,
|
||||
password,
|
||||
};
|
||||
return await sendToDatabase(data);
|
||||
var sendBack = await sendToDatabase(data);
|
||||
if (sendBack) {
|
||||
localStorage.setItem("accountEmail", await getEmail(usernameOrEmail, password))
|
||||
localStorage.setItem("accountName", await getName(usernameOrEmail, password))
|
||||
localStorage.setItem("accountPassword", password)
|
||||
}
|
||||
return sendBack
|
||||
};
|
||||
|
||||
export const deleteAccount = async (usernameOrEmail: string, password: string) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ForwardedRef, useEffect, useRef } from 'react';
|
||||
import React, { ForwardedRef, useState, useEffect, useRef } from 'react';
|
||||
|
||||
type Message = {
|
||||
role: string
|
||||
|
@ -7,6 +7,7 @@ type Message = {
|
|||
|
||||
interface ConversationProps {
|
||||
messages: Message[];
|
||||
onStopClick: () => void;
|
||||
onResendClick: () => void;
|
||||
onEditClick: () => void;
|
||||
onCopyClick: () => void;
|
||||
|
@ -14,13 +15,45 @@ interface ConversationProps {
|
|||
}
|
||||
|
||||
const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>(
|
||||
({ messages, onResendClick, onEditClick, onCopyClick, isClicked }, ref: ForwardedRef<HTMLDivElement>) => {
|
||||
|
||||
const messagesEndRef = useRef<HTMLDivElement | null>(null)
|
||||
({ messages, onStopClick, onResendClick, onEditClick, onCopyClick, isClicked }, ref: ForwardedRef<HTMLDivElement>) => {
|
||||
const [isScrolling, setIsScrolling] = useState(true);
|
||||
const messagesEndRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
messagesEndRef.current?.scrollIntoView()
|
||||
}, [messages])
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
console.log('End of messages reached');
|
||||
setIsScrolling(true);
|
||||
} else {
|
||||
console.log('End of messages not reached');
|
||||
setIsScrolling(false);
|
||||
}
|
||||
},
|
||||
{
|
||||
root: document.querySelector('.output'),
|
||||
threshold: 1.0, // Ensure the whole element is visible
|
||||
}
|
||||
);
|
||||
|
||||
const endOfMessages = messagesEndRef.current;
|
||||
if (endOfMessages) {
|
||||
observer.observe(endOfMessages);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (endOfMessages) {
|
||||
observer.unobserve(endOfMessages);
|
||||
}
|
||||
};
|
||||
}, [messages]);
|
||||
|
||||
// Scroll to bottom when new messages arrive
|
||||
useEffect(() => {
|
||||
if (isScrolling) {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}, [messages, isScrolling]);
|
||||
|
||||
return (
|
||||
<div className="output" ref={ref}>
|
||||
|
@ -40,22 +73,37 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
|
|||
})}
|
||||
|
||||
<div className="button-container">
|
||||
<button type="button" onClick={onResendClick}>
|
||||
<img src="/img/resend.svg" alt="resend" />
|
||||
</button>
|
||||
<button type="button" onClick={onEditClick}>
|
||||
<img src="/img/edit.svg" alt="edit" />
|
||||
</button>
|
||||
<button type="button" onClick={onCopyClick}>
|
||||
<img src="/img/copy.svg" alt="copy" />
|
||||
</button>
|
||||
<p id="copiedText" style={{ opacity: isClicked ? "1" : "0", transition: "all 0.3s ease-in-out" }}>Copied!</p>
|
||||
<div className="tooltip">
|
||||
<button type="button" onClick={onStopClick}>
|
||||
<img src="/img/resend.svg" alt="stop" />
|
||||
</button>
|
||||
<span className="tooltiptext">Stop</span>
|
||||
</div>
|
||||
<div className="tooltip">
|
||||
<button type="button" onClick={onResendClick}>
|
||||
<img src="/img/resend.svg" alt="resend" />
|
||||
</button>
|
||||
<span className="tooltiptext">Resend</span>
|
||||
</div>
|
||||
<div className="tooltip">
|
||||
<button type="button" onClick={onEditClick}>
|
||||
<img src="/img/edit.svg" alt="edit" />
|
||||
</button>
|
||||
<span className="tooltiptext">Edit</span>
|
||||
</div>
|
||||
<div className="tooltip">
|
||||
<button type="button" onClick={onCopyClick}>
|
||||
<img src="/img/copy.svg" alt="copy" />
|
||||
</button>
|
||||
<span className="tooltiptext">{isClicked?"Copied!": "Copy" }</span>
|
||||
</div>
|
||||
</div>
|
||||
<div ref={messagesEndRef} />
|
||||
<div className={"endOfMessages"} ref={messagesEndRef} style={{height:"10px"}}/>
|
||||
</div>
|
||||
<button id="scrollToBottom" disabled={isScrolling?true:false} style={{visibility: isScrolling?"hidden":"visible"}} onClick={()=> setIsScrolling(true)}>Down</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default ConversationFrontend;
|
||||
|
|
|
@ -50,25 +50,11 @@ const Login: React.FC = () => {
|
|||
|
||||
// Function to handle login
|
||||
const handleLogin = async () => {
|
||||
const savedAccountEmail = localStorage.getItem('accountEmail');
|
||||
const savedAccountPassword = localStorage.getItem('accountPassword');
|
||||
const savedAccountName = localStorage.getItem('accountName');
|
||||
|
||||
// Check if savedAccountName or savedAccountEmail is not null before passing to checkCredentials
|
||||
var accountIdentifier = savedAccountName || savedAccountEmail;
|
||||
if (!accountIdentifier) {
|
||||
accountIdentifier = accountName
|
||||
}
|
||||
|
||||
if (accountIdentifier && password) {
|
||||
const success = await checkCredentials(accountIdentifier, password);
|
||||
if (accountName && password) {
|
||||
const success = await checkCredentials(accountName, password);
|
||||
if (success) {
|
||||
setIsLoggedIn(true); // Successful login
|
||||
setShowLoginPopup(false); // Close the login popup
|
||||
// Save credentials to localStorage (optional in case of changes)
|
||||
localStorage.setItem('accountName', savedAccountName || accountName);
|
||||
localStorage.setItem('accountEmail', savedAccountEmail || email);
|
||||
localStorage.setItem('accountPassword', savedAccountPassword || password);
|
||||
} else {
|
||||
alert('Incorrect credentials');
|
||||
}
|
||||
|
|
|
@ -37,11 +37,8 @@ const PrivacySettings: React.FC<PrivacySettingsProps> = ({ selectedOption, handl
|
|||
>
|
||||
None{openSourceMode ? ' (FOSS)' : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<p>
|
||||
After changing the preferred settings, please reload the website so it can update itself properly.
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
|||
/* Output Section */
|
||||
.output {
|
||||
scroll-behavior: smooth;
|
||||
grid-column: 2;
|
||||
grid-row: 1 / 4;
|
||||
background-color: var(--output-background-color);
|
||||
|
@ -13,6 +14,7 @@
|
|||
overflow-y: auto;
|
||||
width: calc(100% - 2em); /* Corrected calculation for width */
|
||||
height: 86dvh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#conversation {
|
||||
|
@ -20,7 +22,7 @@
|
|||
flex-direction: column;
|
||||
padding-left: 10px;
|
||||
overflow-y: auto;
|
||||
max-height: 80vh;
|
||||
height: 80vh;
|
||||
background-color: var(--output-background-color);
|
||||
border-radius: 10px;
|
||||
scroll-behavior: smooth;
|
||||
|
@ -72,9 +74,71 @@
|
|||
width: 20px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tooltip .tooltiptext {
|
||||
visibility: hidden;
|
||||
background-color: var(--user-message-background-color);
|
||||
color: var(--text-color);
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
font-size: calc(var(--font-size)*0.8);
|
||||
|
||||
/* Position the tooltip */
|
||||
position: absolute;
|
||||
top: 125%;
|
||||
/* Adjusts tooltip to be below the button */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
/* Center the tooltip */
|
||||
white-space: nowrap;
|
||||
/* Prevent line breaks */
|
||||
|
||||
/* Add smooth transition */
|
||||
opacity: 0;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.tooltip .tooltiptext::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
/* Arrow on top of tooltip */
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent var(--user-message-background-color) transparent;
|
||||
}
|
||||
|
||||
/* Show the tooltip on hover */
|
||||
.tooltip:hover .tooltiptext {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#copiedText{
|
||||
margin-top: 1em;
|
||||
cursor:default;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#scrollToBottom{
|
||||
scroll-behavior: smooth;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
margin: auto;
|
||||
border-radius: 100%;
|
||||
bottom: 16dvh;
|
||||
left: 50%;
|
||||
translate: -25px;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue