forked from React-Group/interstellar_ai
		
	Merge pull request 'Merge pull request 'main' (#36) from React-Group/interstellar_ai:main into main' (#97) from sageTheDm/interstellar_ai:main into main
Reviewed-on: https://interstellardevelopment.org/code/code/React-Group/interstellar_ai/pulls/97
This commit is contained in:
		
						commit
						5067f76bbf
					
				
					 3 changed files with 89 additions and 95 deletions
				
			
		|  | @ -1,6 +1,7 @@ | ||||||
| import React, { useEffect, useState } from 'react'; | "use client"; | ||||||
|  | import React, { useState, useEffect } from 'react'; | ||||||
| 
 | 
 | ||||||
| // Sample modelList definition; replace this with your actual modelList
 | // Define all models that should be available.
 | ||||||
| const modelList = { | const modelList = { | ||||||
|   'Offline Fast': { |   'Offline Fast': { | ||||||
|     model_type: 'local', |     model_type: 'local', | ||||||
|  | @ -168,54 +169,62 @@ const selectedAIFunction = [ | ||||||
| 
 | 
 | ||||||
| const ModelSection: React.FC = () => { | const ModelSection: React.FC = () => { | ||||||
|   // Initialize state with value from localStorage or default to ''
 |   // Initialize state with value from localStorage or default to ''
 | ||||||
|   const [selectedModelDropdown, setSelectedModelDropdown] = useState<ModelKeys>('Offline Fast'); |   const [selectedModelDropdown, setSelectedModelDropdown] = useState(''); | ||||||
|   const [radioSelection, setRadioSelection] = useState<string | null>(""); |   const [radioSelection, setRadioSelection] = useState<string | null>("") | ||||||
|   const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(''); |   const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(''); | ||||||
|   const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState<string | null>(""); |   const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState<string | null>(""); | ||||||
|   const [isOpenSourceMode, setIsOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false") |   const [isOpenSourceMode, setIsOpenSourceMode] = useState(localStorage.getItem('openSourceMode') || "false") | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     // Load initial values from localStorage
 |     var temp = localStorage.getItem("activeSelectedAIFunction") || "" | ||||||
|     const temp = localStorage.getItem("activeSelectedAIFunction") || ""; |     setActiveSelectedAIFunction(temp) | ||||||
|     setActiveSelectedAIFunction(temp); |  | ||||||
| 
 |  | ||||||
|     // Check if localStorage keys exist, else set defaults
 |  | ||||||
|     if (!localStorage.getItem('selectedModelDropdown')) { |     if (!localStorage.getItem('selectedModelDropdown')) { | ||||||
|       localStorage.setItem("selectedModelDropdown", "Offline Fast"); |       localStorage.setItem("selectedModelDropdown", "Offline Fast") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Set the dropdown and selected AI function from localStorage
 |     if (!localStorage.getItem("activeSelectedAIFunction")) { | ||||||
|     const storedSelectedModel = localStorage.getItem('selectedModelDropdown') as ModelKeys; |       setActiveSelectedAIFunction('Code') | ||||||
|     const storedActiveFunction = localStorage.getItem("activeSelectedAIFunction") || 'Code'; |       localStorage.setItem('activeSelectedAIFunction', 'Code') | ||||||
| 
 |     } | ||||||
|     setSelectedModelDropdown(storedSelectedModel); |  | ||||||
|     setCurrentSelectedAIFunction(storedActiveFunction); |  | ||||||
| 
 | 
 | ||||||
|     if (!localStorage.getItem("model")) { |     if (!localStorage.getItem("model")) { | ||||||
|       localStorage.setItem("model", 'starcoder2'); |       localStorage.setItem("model", 'starcoder2') | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (!localStorage.getItem("radioSelection")) { |     if (!localStorage.getItem("radioSelection")) { | ||||||
|       localStorage.setItem("radioSelection", 'None'); |       localStorage.setItem("radioSelection", 'None') | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Load radio selection from localStorage
 |     if (!localStorage.getItem("type")) { | ||||||
|     setRadioSelection(localStorage.getItem('radioSelection') || ''); |       localStorage.setItem("type", 'local') | ||||||
|   }, []); |     } | ||||||
| 
 | 
 | ||||||
|   const filteredModels = Object.keys(modelList).filter(model => modelList[model as ModelKeys]); |     const handleStorageChange = () => { | ||||||
|  |       setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // Update immediately when localStorage changes
 | ||||||
|  |     window.addEventListener('storage', handleStorageChange); | ||||||
|  | 
 | ||||||
|  |     setRadioSelection(localStorage.getItem('radioSelection') || ''); | ||||||
|  |     setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); | ||||||
|  |     // Cleanup listener on component unmount
 | ||||||
|  |     return () => { | ||||||
|  |       window.removeEventListener('storage', handleStorageChange); | ||||||
|  |     }; | ||||||
|  |   }, []); // Dependency array can remain empty if you only want this to run on mount
 | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     var storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || ""; | ||||||
|  |     if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) { | ||||||
|  |       setCurrentSelectedAIFunction(storedActiveSelectedAIFunction); | ||||||
|  |     } | ||||||
|  |   }, [activeSelectedAIFunction]); | ||||||
| 
 | 
 | ||||||
|   const handleModelChange = (event: React.ChangeEvent<HTMLSelectElement>) => { |   const handleModelChange = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||||||
|     const selectedModel = event.target.value as ModelKeys; |     const newModel = event.target.value; | ||||||
|     setSelectedModelDropdown(selectedModel); |     setSelectedModelDropdown(newModel); | ||||||
|     localStorage.setItem('selectedModelDropdown', selectedModel); |     localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly
 | ||||||
| 
 |  | ||||||
|     // Update model and type in local storage
 |  | ||||||
|     const modelType = modelList[selectedModel].model_type; |  | ||||||
|     const model = modelList[selectedModel][activeSelectedAIFunction as keyof typeof modelList[typeof selectedModel]]; |  | ||||||
| 
 |  | ||||||
|     localStorage.setItem('model', model); |  | ||||||
|     localStorage.setItem('type', modelType); |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Determine the filtered models based on current radioSelection
 |   // Determine the filtered models based on current radioSelection
 | ||||||
|  | @ -274,21 +283,12 @@ const ModelSection: React.FC = () => { | ||||||
|     modelDropdown.offlineNonFoss.includes(model) || modelDropdown.offlineFoss.includes(model); |     modelDropdown.offlineNonFoss.includes(model) || modelDropdown.offlineFoss.includes(model); | ||||||
| 
 | 
 | ||||||
|   const modelClicked = (model: string) => { |   const modelClicked = (model: string) => { | ||||||
|     const selectedAIFunction = currentSelectedAIFunction as keyof typeof modelList; |     localStorage.setItem('activeSelectedAIFunction', model) | ||||||
| 
 |     setActiveSelectedAIFunction(model) | ||||||
|     if (modelList[selectedModelDropdown] && modelList[selectedModelDropdown][model as keyof typeof modelList[typeof selectedModelDropdown]]) { |     const selectedAIFunction = selectedModelDropdown as keyof typeof modelList; | ||||||
|       const newModel = modelList[selectedModelDropdown][model as keyof typeof modelList[typeof selectedModelDropdown]]; |     localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]]) | ||||||
|       const modelType = modelList[selectedModelDropdown]['model_type' as keyof typeof modelList[typeof selectedModelDropdown]]; |     localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]]) | ||||||
| 
 |  | ||||||
|       localStorage.setItem('activeSelectedAIFunction', model); |  | ||||||
|       setActiveSelectedAIFunction(model); |  | ||||||
|       localStorage.setItem('model', newModel); |  | ||||||
|       localStorage.setItem('type', modelType); |  | ||||||
|       setCurrentSelectedAIFunction(model); // Ensure to set current function when model is clicked
 |  | ||||||
|     } else { |  | ||||||
|       console.error(`Model ${model} not found for function ${selectedModelDropdown}`); |  | ||||||
|   } |   } | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="model-background"> |     <div className="model-background"> | ||||||
|  | @ -311,9 +311,8 @@ const ModelSection: React.FC = () => { | ||||||
| 
 | 
 | ||||||
|         {/* Model Grid with Cards */} |         {/* Model Grid with Cards */} | ||||||
|         <div className="grid"> |         <div className="grid"> | ||||||
|           {Object.keys(modelList[selectedModelDropdown]) |           {selectedAIFunction.map( | ||||||
|             .filter((key) => key !== 'model_type') // Exclude model_type from display
 |             (displayedCategory) => ( | ||||||
|             .map((displayedCategory) => ( |  | ||||||
|               <button |               <button | ||||||
|                 key={displayedCategory} |                 key={displayedCategory} | ||||||
|                 className={`${displayedCategory.toLowerCase()}-model model-box ${currentSelectedAIFunction === displayedCategory ? 'selected' : ''}`} |                 className={`${displayedCategory.toLowerCase()}-model model-box ${currentSelectedAIFunction === displayedCategory ? 'selected' : ''}`} | ||||||
|  | @ -324,8 +323,8 @@ const ModelSection: React.FC = () => { | ||||||
|                   {isOfflineModel(selectedModelDropdown) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} |                   {isOfflineModel(selectedModelDropdown) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} | ||||||
|                 </div> |                 </div> | ||||||
|               </button> |               </button> | ||||||
|             )) |             ) | ||||||
|           } |           )} | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| import React, { useEffect } from 'react'; | // PrivacySettings.tsx
 | ||||||
|  | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| interface PrivacySettingsProps { | interface PrivacySettingsProps { | ||||||
|   selectedOption: string; // The currently selected option
 |   selectedOption: string; // The currently selected option
 | ||||||
|  | @ -7,42 +8,39 @@ interface PrivacySettingsProps { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const PrivacySettings: React.FC<PrivacySettingsProps> = ({ selectedOption, handleRadioChange, openSourceMode }) => { | const PrivacySettings: React.FC<PrivacySettingsProps> = ({ selectedOption, handleRadioChange, openSourceMode }) => { | ||||||
|    |  | ||||||
|   // Set default option based on openSourceMode if no option is selected
 |  | ||||||
|   useEffect(() => { |  | ||||||
|     if (!selectedOption) { |  | ||||||
|       handleRadioChange(openSourceMode ? 'Offline (FOSS)' : 'None'); |  | ||||||
|     } |  | ||||||
|   }, [selectedOption, handleRadioChange, openSourceMode]); |  | ||||||
| 
 |  | ||||||
|   // Define your options
 |  | ||||||
|   const options = [ |  | ||||||
|     { value: 'Online', label: 'Online' }, |  | ||||||
|     { value: 'Offline', label: 'Offline' }, |  | ||||||
|     { value: 'None', label: 'None' }, |  | ||||||
|     { value: 'Offline (FOSS)', label: 'Offline (FOSS)' }, |  | ||||||
|     { value: 'Online (FOSS)', label: 'Online (FOSS)' }, |  | ||||||
|     { value: 'None (FOSS)', label: 'None (FOSS)' }, |  | ||||||
|   ]; |  | ||||||
| 
 |  | ||||||
|   return ( |   return ( | ||||||
|  |     <> | ||||||
|  |       {/* AI Mode Radio Options */} | ||||||
|       <div className="settings-option"> |       <div className="settings-option"> | ||||||
|       <p>Select Privacy Mode:</p> |         <p>Disable Options:</p> | ||||||
|       {options.map((option) => ( |         <div className="slider"> | ||||||
|         <div key={option.value}> |           {/* Offline */} | ||||||
|           <label> |           <div | ||||||
|             <input |             className={`slider-option ${selectedOption === 'Offline' ? 'active' : ''}`} | ||||||
|               type="radio" |             onClick={() => handleRadioChange('Offline')} // Allow selection only if not in open-source mode
 | ||||||
|               value={option.value} |           > | ||||||
|               checked={selectedOption === option.value} |             Offline tools{openSourceMode ? ' (FOSS)' : ''} | ||||||
|               onChange={() => handleRadioChange(option.value)} |  | ||||||
|               disabled={openSourceMode && !option.label.includes('(FOSS)') && selectedOption !== option.value} // Disable non-FOSS options if FOSS is selected
 |  | ||||||
|             /> |  | ||||||
|             {option.label} |  | ||||||
|           </label> |  | ||||||
|           </div> |           </div> | ||||||
|       ))} | 
 | ||||||
|  |           {/* Online */} | ||||||
|  |           <div | ||||||
|  |             className={`slider-option ${selectedOption === 'Online' ? 'active' : ''}`} | ||||||
|  |             onClick={() => handleRadioChange('Online')} | ||||||
|  |           > | ||||||
|  |             Online tools{openSourceMode ? ' (FOSS)' : ''} | ||||||
|           </div> |           </div> | ||||||
|  | 
 | ||||||
|  |           {/* None */} | ||||||
|  |           <div | ||||||
|  |             className={`slider-option ${selectedOption === 'None' ? 'active' : ''}`} | ||||||
|  |             onClick={() => handleRadioChange('None')} | ||||||
|  |           > | ||||||
|  |             None{openSourceMode ? ' (FOSS)' : ''} | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <br /> | ||||||
|  |       </div> | ||||||
|  |     </> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,14 +56,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|   const [timeZone, setTimeZone] = useState(() => localStorage.getItem('timeZone') || 'GMT'); |   const [timeZone, setTimeZone] = useState(() => localStorage.getItem('timeZone') || 'GMT'); | ||||||
| 
 | 
 | ||||||
|   // Online AI and chat history settings
 |   // Online AI and chat history settings
 | ||||||
|   const [selectedOption, setSelectedOption] = useState(() => { |   const [selectedOption, setSelectedOption] = useState('Offline'); // Default to 'Offline'
 | ||||||
|     // Check if openSourceMode exists in localStorage
 |  | ||||||
|     const openSourceMode = localStorage.getItem("openSourceMode"); |  | ||||||
| 
 |  | ||||||
|     // If it exists and is "true", set selectedOption to None (Foss), otherwise set it to None
 |  | ||||||
|     return openSourceMode === "true" ? "None (FOSS)" : "None"; |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   const [disableChatHistory, setDisableChatHistory] = useState(() => getItemFromLocalStorage('disableChatHistory')); |   const [disableChatHistory, setDisableChatHistory] = useState(() => getItemFromLocalStorage('disableChatHistory')); | ||||||
|   const [disableAIMemory, setDisableAIMemory] = useState(() => getItemFromLocalStorage('disableAIMemory')); |   const [disableAIMemory, setDisableAIMemory] = useState(() => getItemFromLocalStorage('disableAIMemory')); | ||||||
|   const [openSourceMode, setOpenSourceMode] = useState(() => getItemFromLocalStorage('openSourceMode')); |   const [openSourceMode, setOpenSourceMode] = useState(() => getItemFromLocalStorage('openSourceMode')); | ||||||
|  | @ -112,6 +105,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|   const [closeButtonHoverColor, setCloseButtonHoverColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--close-button-hover-color').trim()); |   const [closeButtonHoverColor, setCloseButtonHoverColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--close-button-hover-color').trim()); | ||||||
|   const [applyButtonColor, setApplyButtonColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--apply-button-color').trim()); |   const [applyButtonColor, setApplyButtonColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--apply-button-color').trim()); | ||||||
|   const [applyButtonHoverColor, setApplyButtonHoverColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--apply-button-hover-color').trim()); |   const [applyButtonHoverColor, setApplyButtonHoverColor] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--apply-button-hover-color').trim()); | ||||||
|  | 
 | ||||||
|   // Per default a purple color gradient
 |   // Per default a purple color gradient
 | ||||||
|   const [primaryColor, setPrimaryColor] = useState(localStorage.getItem("primaryColor") || "#dc8add"); |   const [primaryColor, setPrimaryColor] = useState(localStorage.getItem("primaryColor") || "#dc8add"); | ||||||
|   const [secondaryColor, setSecondaryColor] = useState(localStorage.getItem("secondaryColor") || "#c061cb"); |   const [secondaryColor, setSecondaryColor] = useState(localStorage.getItem("secondaryColor") || "#c061cb"); | ||||||
|  | @ -123,6 +117,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|   const [selectedTheme, setSelectedTheme] = useState<string>(''); |   const [selectedTheme, setSelectedTheme] = useState<string>(''); | ||||||
| 
 | 
 | ||||||
|   // API Keys
 |   // API Keys
 | ||||||
|  | 
 | ||||||
|   const [mistral, setMistral] = useState(localStorage.getItem('mistral') || ""); |   const [mistral, setMistral] = useState(localStorage.getItem('mistral') || ""); | ||||||
|   const [openai, setOpenai] = useState(localStorage.getItem('openai') || ""); |   const [openai, setOpenai] = useState(localStorage.getItem('openai') || ""); | ||||||
|   const [anthropic, setAnthropic] = useState(localStorage.getItem('anthropic') || ""); |   const [anthropic, setAnthropic] = useState(localStorage.getItem('anthropic') || ""); | ||||||
|  | @ -455,6 +450,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|         return ( |         return ( | ||||||
|           <div className="settings-section"> |           <div className="settings-section"> | ||||||
|             <h2>Privacy Settings</h2> |             <h2>Privacy Settings</h2> | ||||||
|  | 
 | ||||||
|             <PrivacySettings |             <PrivacySettings | ||||||
|               selectedOption={selectedOption} |               selectedOption={selectedOption} | ||||||
|               handleRadioChange={handleRadioChange} |               handleRadioChange={handleRadioChange} | ||||||
|  | @ -576,6 +572,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|             <TextSettings |             <TextSettings | ||||||
|               label="New Name" |               label="New Name" | ||||||
|               value={newName} |               value={newName} | ||||||
|  |               type='text' | ||||||
|               setValue={setNewName} |               setValue={setNewName} | ||||||
|               placeholder={localStorage.getItem("accountName") || "Current Name"} // Show current name or a default
 |               placeholder={localStorage.getItem("accountName") || "Current Name"} // Show current name or a default
 | ||||||
|             /> |             /> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue