diff --git a/README.md b/README.md index 0efe25b..b99f286 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ python3 api.py ``` 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. -5. Enjoy! \ No newline at end of file +4. Enjoy! \ No newline at end of file diff --git a/app/components/Login.tsx b/app/components/Login.tsx index 146e86c..f1382a6 100644 --- a/app/components/Login.tsx +++ b/app/components/Login.tsx @@ -5,6 +5,7 @@ import { getSettings } from '../backend/database'; import Settings from './settings/Settings'; // Import the Settings component +import { importDatabase } from './settings/settingUtils'; const Login: React.FC = () => { // State to handle popup visibility @@ -23,14 +24,14 @@ const Login: React.FC = () => { // On component mount, check if there are credentials in localStorage useEffect(() => { - let savedAccountName:string|null; - let savedAccountEmail:string|null; - let savedAccountPassword:string|null; + let savedAccountName: string | null; + let savedAccountEmail: string | null; + let savedAccountPassword: string | null; if (typeof localStorage !== 'undefined') { savedAccountName = localStorage.getItem('accountName'); savedAccountEmail = localStorage.getItem('accountEmail'); savedAccountPassword = localStorage.getItem('accountPassword'); - + // If credentials are found in localStorage, log the user in if (savedAccountName && savedAccountEmail && savedAccountPassword) { setAccountName(savedAccountName); @@ -40,6 +41,14 @@ const Login: React.FC = () => { if (savedAccountName !== null && savedAccountPassword !== null) { const success = await checkCredentials(savedAccountName, savedAccountPassword); setIsLoggedIn(success); // Automatically log in + const useName = localStorage.getItem("accountName"); + const usePassword = localStorage.getItem("accountPassword"); + + if (useName && usePassword) { + await importDatabase(useName, usePassword); + } + + } }; check(); @@ -64,11 +73,19 @@ const Login: React.FC = () => { setIsLoggedIn(true); // Successful login const data = await getSettings(accountName, password) if (data) { - if (typeof localStorage !== 'undefined') { + if (typeof localStorage !== 'undefined') { localStorage.setItem("dataFromServer", data) } } 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 { alert('Incorrect credentials'); } diff --git a/app/components/settings/Settings.tsx b/app/components/settings/Settings.tsx index afe571d..28aeb87 100644 --- a/app/components/settings/Settings.tsx +++ b/app/components/settings/Settings.tsx @@ -1,7 +1,7 @@ //#region imports import React, { useState, useEffect } from 'react'; 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 ColorSetting from './ColorSettings'; import TextSettings from './TextSettings' @@ -15,8 +15,6 @@ import { changeSettings, createAccount, deleteAccount, - getSettings, - sendToDatabase } from '../../backend/database'; import ThemeDropdown from './DropDownTheme'; @@ -302,7 +300,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( useEffect(() => { const useName = localStorage.getItem("accountName"); const usePassword = localStorage.getItem("accountPassword"); - + if (useName && usePassword) { importDatabase(useName, usePassword); } @@ -314,27 +312,6 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( } }, []); // 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 useEffect(() => { // Flatten nested objects @@ -593,7 +570,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( )} ); - //#region custom --> foss + //#region custom --> foss case 'foss': return (
@@ -606,7 +583,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
); - //#region account + //#region account case 'account': return (
@@ -649,7 +626,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( />
); - //#region api + //#region api case 'api': return (
@@ -703,7 +680,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
); - //#region import export + //#region import export case 'im/export': return (
@@ -759,52 +736,51 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( //#region overall export return (
-
-
- {/* Sidebar for desktop */} -
-
    -
  • setActiveSection('general')}>General
  • -
  • setActiveSection('privacy')}>Privacy
  • -
  • setActiveSection('theme')}>Theme
  • -
  • setActiveSection('foss')}>FOSS
  • -
  • setActiveSection('account')}>Account
  • -
  • setActiveSection('api')}>API Keys
  • -
  • setActiveSection('im/export')}>Import/Export
  • -
-
+
+
+ {/* Sidebar for desktop */} +
+
    +
  • setActiveSection('general')}>General
  • +
  • setActiveSection('privacy')}>Privacy
  • +
  • setActiveSection('theme')}>Theme
  • +
  • setActiveSection('foss')}>FOSS
  • +
  • setActiveSection('account')}>Account
  • +
  • setActiveSection('api')}>API Keys
  • +
  • setActiveSection('im/export')}>Import/Export
  • +
+
-
- {/* Dropdown for selections in responsive mode */} -
-

Select a Setting

- -
-

Settings for {accountName}

- {renderSettingsContent()} - - - -
+
+ {/* Dropdown for selections in responsive mode */} +
+

Select a Setting

+
+

Settings for {accountName}

+ {renderSettingsContent()} + + + +
+
-); + ); }; diff --git a/app/components/settings/settingUtils.ts b/app/components/settings/settingUtils.ts index 885ad98..a3b3e61 100644 --- a/app/components/settings/settingUtils.ts +++ b/app/components/settings/settingUtils.ts @@ -1,11 +1,12 @@ // settingsManager.ts +import { changeSettings, getSettings } from "@/app/backend/database"; // Method to export localStorage to a JSON object export function exportSettings(): string { const settings: { [key: string]: string } = {}; // 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++) { const key = localStorage.key(i); if (key) { @@ -26,7 +27,7 @@ export function importSettings(jsonData: string): void { const parsedSettings = JSON.parse(jsonData); // Loop through parsed settings and save them in localStorage - if (typeof localStorage !== 'undefined') { + if (typeof localStorage !== 'undefined') { Object.keys(parsedSettings).forEach((key) => { localStorage.setItem(key, parsedSettings[key]); }); @@ -37,3 +38,27 @@ export function importSettings(jsonData: string): void { 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.'); + } +} diff --git a/deployment_scripts/linux/prepare-free.sh b/deployment_scripts/linux/prepare-free.sh new file mode 100755 index 0000000..3f0293c --- /dev/null +++ b/deployment_scripts/linux/prepare-free.sh @@ -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 \ No newline at end of file diff --git a/deployment_scripts/linux/prepare-nonfree.sh b/deployment_scripts/linux/prepare-nonfree.sh new file mode 100755 index 0000000..66d12ff --- /dev/null +++ b/deployment_scripts/linux/prepare-nonfree.sh @@ -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 \ No newline at end of file diff --git a/deployment_scripts/linux/root.sh b/deployment_scripts/linux/root.sh new file mode 100644 index 0000000..6278166 --- /dev/null +++ b/deployment_scripts/linux/root.sh @@ -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 \ No newline at end of file diff --git a/deployment_scripts/linux/run.sh b/deployment_scripts/linux/run.sh new file mode 100644 index 0000000..e1e490b --- /dev/null +++ b/deployment_scripts/linux/run.sh @@ -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 \ No newline at end of file