Merge branch 'main' into main

This commit is contained in:
Patrick 2024-10-09 13:31:44 +02:00
commit 219b301d62
8 changed files with 164 additions and 81 deletions

View file

@ -40,7 +40,8 @@ python3 api.py
``` ```
3. In the main project folder, you will run: 3. In the main project folder, you will run:
``` ```
npm run dev npm run build
npm start
npx electron .
``` ```
4. Open http://localhost:3000/ in your browser. 4. Enjoy!
5. Enjoy!

View file

@ -5,6 +5,7 @@ import {
getSettings getSettings
} from '../backend/database'; } from '../backend/database';
import Settings from './settings/Settings'; // Import the Settings component import Settings from './settings/Settings'; // Import the Settings component
import { importDatabase } from './settings/settingUtils';
const Login: React.FC = () => { const Login: React.FC = () => {
// State to handle popup visibility // State to handle popup visibility
@ -23,14 +24,14 @@ const Login: React.FC = () => {
// On component mount, check if there are credentials in localStorage // On component mount, check if there are credentials in localStorage
useEffect(() => { useEffect(() => {
let savedAccountName:string|null; let savedAccountName: string | null;
let savedAccountEmail:string|null; let savedAccountEmail: string | null;
let savedAccountPassword:string|null; let savedAccountPassword: string | null;
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
savedAccountName = localStorage.getItem('accountName'); savedAccountName = localStorage.getItem('accountName');
savedAccountEmail = localStorage.getItem('accountEmail'); savedAccountEmail = localStorage.getItem('accountEmail');
savedAccountPassword = localStorage.getItem('accountPassword'); savedAccountPassword = localStorage.getItem('accountPassword');
// If credentials are found in localStorage, log the user in // If credentials are found in localStorage, log the user in
if (savedAccountName && savedAccountEmail && savedAccountPassword) { if (savedAccountName && savedAccountEmail && savedAccountPassword) {
setAccountName(savedAccountName); setAccountName(savedAccountName);
@ -40,6 +41,14 @@ const Login: React.FC = () => {
if (savedAccountName !== null && savedAccountPassword !== null) { if (savedAccountName !== null && savedAccountPassword !== null) {
const success = await checkCredentials(savedAccountName, savedAccountPassword); const success = await checkCredentials(savedAccountName, savedAccountPassword);
setIsLoggedIn(success); // Automatically log in setIsLoggedIn(success); // Automatically log in
const useName = localStorage.getItem("accountName");
const usePassword = localStorage.getItem("accountPassword");
if (useName && usePassword) {
await importDatabase(useName, usePassword);
}
} }
}; };
check(); check();
@ -64,11 +73,19 @@ const Login: React.FC = () => {
setIsLoggedIn(true); // Successful login setIsLoggedIn(true); // Successful login
const data = await getSettings(accountName, password) const data = await getSettings(accountName, password)
if (data) { if (data) {
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
localStorage.setItem("dataFromServer", data) localStorage.setItem("dataFromServer", data)
} }
} }
setShowLoginPopup(false); // Close the login popup setShowLoginPopup(false); // Close the login popup
const useName = localStorage.getItem("accountName");
const usePassword = localStorage.getItem("accountPassword");
if (useName && usePassword) {
await importDatabase(useName, usePassword);
}
window.location.reload();
} else { } else {
alert('Incorrect credentials'); alert('Incorrect credentials');
} }

View file

@ -1,7 +1,7 @@
//#region imports //#region imports
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { applyTheme } from './theme'; import { applyTheme } from './theme';
import { exportSettings, importSettings } from './settingUtils'; // Import utility functions import { exportSettings, importSettings, sendToDatabase, importDatabase } from './settingUtils'; // Import utility functions
import { getAllLocalStorageItems } from '../../backend/GetLocalStorage'; import { getAllLocalStorageItems } from '../../backend/GetLocalStorage';
import ColorSetting from './ColorSettings'; import ColorSetting from './ColorSettings';
import TextSettings from './TextSettings' import TextSettings from './TextSettings'
@ -15,8 +15,6 @@ import {
changeSettings, changeSettings,
createAccount, createAccount,
deleteAccount, deleteAccount,
getSettings,
sendToDatabase
} from '../../backend/database'; } from '../../backend/database';
import ThemeDropdown from './DropDownTheme'; import ThemeDropdown from './DropDownTheme';
@ -302,7 +300,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
useEffect(() => { useEffect(() => {
const useName = localStorage.getItem("accountName"); const useName = localStorage.getItem("accountName");
const usePassword = localStorage.getItem("accountPassword"); const usePassword = localStorage.getItem("accountPassword");
if (useName && usePassword) { if (useName && usePassword) {
importDatabase(useName, usePassword); importDatabase(useName, usePassword);
} }
@ -314,27 +312,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
} }
}, []); // Runs only once when the component mounts }, []); // Runs only once when the component mounts
const importDatabase = async (useName: string, usePassword: string) => {
const databaseSettings = await getSettings(useName, usePassword);
// Ensure user settings exist before flattening and storing
if (typeof databaseSettings == 'object' && databaseSettings) {
JSON.stringify(importSettings(databaseSettings), null, 2); // Pass only the current user's settings
} else {
console.error('Database settings are not in the expected format.');
}
}
const sendToDatabase = async () => {
let useName = localStorage.getItem("accountName")
let usePassword = localStorage.getItem("accountPassword")
if (useName && usePassword) {
if (await changeSettings(useName, usePassword, JSON.parse(exportSettings()))) {
alert('Data has been transferred')
}
}
};
// Effect hooks to update localStorage whenever any state changes // Effect hooks to update localStorage whenever any state changes
useEffect(() => { useEffect(() => {
// Flatten nested objects // Flatten nested objects
@ -593,7 +570,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
)} )}
</div> </div>
); );
//#region custom --> foss //#region custom --> foss
case 'foss': case 'foss':
return ( return (
<div className="settings-section"> <div className="settings-section">
@ -606,7 +583,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
</div> </div>
); );
//#region account //#region account
case 'account': case 'account':
return ( return (
<div className="settings-section"> <div className="settings-section">
@ -649,7 +626,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
/> />
</div> </div>
); );
//#region api //#region api
case 'api': case 'api':
return ( return (
<div className="settings-section"> <div className="settings-section">
@ -703,7 +680,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
</div> </div>
</div> </div>
); );
//#region import export //#region import export
case 'im/export': case 'im/export':
return ( return (
<div className="settings-section"> <div className="settings-section">
@ -759,52 +736,51 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
//#region overall export //#region overall export
return ( return (
<div className="popup-overlay"> <div className="popup-overlay">
<div className="settings-content"> <div className="settings-content">
<div className="settings-container"> <div className="settings-container">
{/* Sidebar for desktop */} {/* Sidebar for desktop */}
<div className="sidebar"> <div className="sidebar">
<ul> <ul>
<li onClick={() => setActiveSection('general')}>General</li> <li onClick={() => setActiveSection('general')}>General</li>
<li onClick={() => setActiveSection('privacy')}>Privacy</li> <li onClick={() => setActiveSection('privacy')}>Privacy</li>
<li onClick={() => setActiveSection('theme')}>Theme</li> <li onClick={() => setActiveSection('theme')}>Theme</li>
<li onClick={() => setActiveSection('foss')}>FOSS</li> <li onClick={() => setActiveSection('foss')}>FOSS</li>
<li onClick={() => setActiveSection('account')}>Account</li> <li onClick={() => setActiveSection('account')}>Account</li>
<li onClick={() => setActiveSection('api')}>API Keys</li> <li onClick={() => setActiveSection('api')}>API Keys</li>
<li onClick={() => setActiveSection('im/export')}>Import/Export</li> <li onClick={() => setActiveSection('im/export')}>Import/Export</li>
</ul> </ul>
</div> </div>
<div className="settings-main"> <div className="settings-main">
{/* Dropdown for selections in responsive mode */} {/* Dropdown for selections in responsive mode */}
<div className="settings-option dropdown"> <div className="settings-option dropdown">
<div className="dropdown-header"><h2>Select a Setting</h2></div> <div className="dropdown-header"><h2>Select a Setting</h2></div>
<select onChange={(e) => setActiveSection(e.target.value)} value={activeSection}> <select onChange={(e) => setActiveSection(e.target.value)} value={activeSection}>
<option value="general">General</option> <option value="general">General</option>
<option value="privacy">Privacy</option> <option value="privacy">Privacy</option>
<option value="theme">Theme</option> <option value="theme">Theme</option>
<option value="foss">FOSS</option> <option value="foss">FOSS</option>
<option value="account">Account</option> <option value="account">Account</option>
<option value="api">API Keys</option> <option value="api">API Keys</option>
<option value="im/export">Import/Export</option> <option value="im/export">Import/Export</option>
</select> </select>
</div>
<h2>Settings for {accountName}</h2>
{renderSettingsContent()}
<button className="close-popup" onClick={closeSettings}>Close</button>
<button className="apply" onClick={async () => {
getAllLocalStorageItems();
closeSettings();
sendToDatabase();
window.location.reload();
}}>
Apply
</button>
</div>
</div> </div>
<h2>Settings for {accountName}</h2>
{renderSettingsContent()}
<button className="close-popup" onClick={closeSettings}>Close</button>
<button className="apply" onClick={async () => {
getAllLocalStorageItems();
closeSettings();
sendToDatabase();
}}>
Apply
</button>
</div>
</div> </div>
</div>
</div> </div>
); );
}; };

View file

@ -1,11 +1,12 @@
// settingsManager.ts // settingsManager.ts
import { changeSettings, getSettings } from "@/app/backend/database";
// Method to export localStorage to a JSON object // Method to export localStorage to a JSON object
export function exportSettings(): string { export function exportSettings(): string {
const settings: { [key: string]: string } = {}; const settings: { [key: string]: string } = {};
// Loop through all keys in localStorage and add them to the settings object // Loop through all keys in localStorage and add them to the settings object
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
for (let i = 0; i < localStorage.length; i++) { for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i); const key = localStorage.key(i);
if (key) { if (key) {
@ -26,7 +27,7 @@ export function importSettings(jsonData: string): void {
const parsedSettings = JSON.parse(jsonData); const parsedSettings = JSON.parse(jsonData);
// Loop through parsed settings and save them in localStorage // Loop through parsed settings and save them in localStorage
if (typeof localStorage !== 'undefined') { if (typeof localStorage !== 'undefined') {
Object.keys(parsedSettings).forEach((key) => { Object.keys(parsedSettings).forEach((key) => {
localStorage.setItem(key, parsedSettings[key]); localStorage.setItem(key, parsedSettings[key]);
}); });
@ -37,3 +38,27 @@ export function importSettings(jsonData: string): void {
console.error("Invalid JSON data:", error); console.error("Invalid JSON data:", error);
} }
} }
export const sendToDatabase = async () => {
let useName = localStorage.getItem("accountName")
let usePassword = localStorage.getItem("accountPassword")
if (useName && usePassword) {
let result = await changeSettings(useName, usePassword, JSON.parse(exportSettings()))
if (result == true) {
alert('Data has been transferred')
window.location.reload();
}
}
window.location.reload();
};
export const importDatabase = async (useName: string, usePassword: string) => {
const databaseSettings = await getSettings(useName, usePassword);
// Ensure user settings exist before flattening and storing
if (typeof databaseSettings == 'object' && databaseSettings) {
importSettings(JSON.stringify(databaseSettings, null, 2)); // Pass only the current user's settings
} else {
console.error('Database settings are not in the expected format.');
}
}

View file

@ -0,0 +1,22 @@
#!/bin/bash
chmod +x root.sh
pkexec ./root.sh
npm install
npm run build
cd py
python3 -m venv venv
source venv/bin/activate
python3 -m pip install -r requirements.txt
ollama pull qwen2-math:1.5b
ollama pull starcoder2
ollama pull llama3.2
ollama pull wizard-math
ollama pull starcoder2:7b
ollama pull llama3.1
cd ..
chmod +x run.sh

View file

@ -0,0 +1,22 @@
#!/bin/bash
chmod +x root.sh
pkexec ./root.sh
npm install
npm run build
cd py
python3 -m venv venv
source venv/bin/activate
python3 -m pip install -r requirements.txt
ollama pull qwen2-math:1.5b
ollama pull qwen2.5-coder:1.5b
ollama pull phi3.5
ollama pull mathstral
ollama pull qwen2.5-coder
ollama pull qwen2.5
cd ..
chmod +x run.sh

View file

@ -0,0 +1,7 @@
#!/bin/bash
apt install npm nodejs python3-full -y
if ! ollama; then
curl -fsSL https://ollama.com/install.sh | sh
fi
systemctl enable ollama --now

View file

@ -0,0 +1,13 @@
#!/bin/bash
cd py
python api.py &
pid_py=$!
npm start &
pid_node=$!
npx electron .
kill $pid_py
kill $pid_node