feat: settings dialog and moved theme settings to dialog from sidebar (#570)
* feat: settings dialog and moved theme settings to dialog from sidebar. * chore(locale): move some labels to settings from sidebar
This commit is contained in:
		
							parent
							
								
									836c24680b
								
							
						
					
					
						commit
						ba1dacb899
					
				|  | @ -1,10 +1,17 @@ | ||||||
| import { IconFileExport, IconMoon, IconSun } from '@tabler/icons-react'; | import { | ||||||
| import { useContext } from 'react'; |   IconFileExport, | ||||||
|  |   IconMoon, | ||||||
|  |   IconSettings, | ||||||
|  |   IconSun, | ||||||
|  | } from '@tabler/icons-react'; | ||||||
|  | import { useContext, useState } from 'react'; | ||||||
| 
 | 
 | ||||||
| import { useTranslation } from 'next-i18next'; | import { useTranslation } from 'next-i18next'; | ||||||
| 
 | 
 | ||||||
| import HomeContext from '@/pages/api/home/home.context'; | import HomeContext from '@/pages/api/home/home.context'; | ||||||
| 
 | 
 | ||||||
|  | import { SettingDialog } from '@/components/Settings/SettingDialog'; | ||||||
|  | 
 | ||||||
| import { Import } from '../../Settings/Import'; | import { Import } from '../../Settings/Import'; | ||||||
| import { Key } from '../../Settings/Key'; | import { Key } from '../../Settings/Key'; | ||||||
| import { SidebarButton } from '../../Sidebar/SidebarButton'; | import { SidebarButton } from '../../Sidebar/SidebarButton'; | ||||||
|  | @ -14,6 +21,7 @@ import { PluginKeys } from './PluginKeys'; | ||||||
| 
 | 
 | ||||||
| export const ChatbarSettings = () => { | export const ChatbarSettings = () => { | ||||||
|   const { t } = useTranslation('sidebar'); |   const { t } = useTranslation('sidebar'); | ||||||
|  |   const [isSettingDialogOpen, setIsSettingDialog] = useState<boolean>(false); | ||||||
| 
 | 
 | ||||||
|   const { |   const { | ||||||
|     state: { |     state: { | ||||||
|  | @ -49,16 +57,9 @@ export const ChatbarSettings = () => { | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|       <SidebarButton |       <SidebarButton | ||||||
|         text={lightMode === 'light' ? t('Dark mode') : t('Light mode')} |         text={t('Settings')} | ||||||
|         icon={ |         icon={<IconSettings size={18} />} | ||||||
|           lightMode === 'light' ? <IconMoon size={18} /> : <IconSun size={18} /> |         onClick={() => setIsSettingDialog(true)} | ||||||
|         } |  | ||||||
|         onClick={() => |  | ||||||
|           homeDispatch({ |  | ||||||
|             field: 'lightMode', |  | ||||||
|             value: lightMode === 'light' ? 'dark' : 'light', |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|       {!serverSideApiKeyIsSet ? ( |       {!serverSideApiKeyIsSet ? ( | ||||||
|  | @ -66,6 +67,13 @@ export const ChatbarSettings = () => { | ||||||
|       ) : null} |       ) : null} | ||||||
| 
 | 
 | ||||||
|       {!serverSidePluginKeysSet ? <PluginKeys /> : null} |       {!serverSidePluginKeysSet ? <PluginKeys /> : null} | ||||||
|  | 
 | ||||||
|  |       <SettingDialog | ||||||
|  |         open={isSettingDialogOpen} | ||||||
|  |         onClose={() => { | ||||||
|  |           setIsSettingDialog(false); | ||||||
|  |         }} | ||||||
|  |       /> | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,105 @@ | ||||||
|  | import { FC, useContext, useEffect, useReducer, useRef } from 'react'; | ||||||
|  | 
 | ||||||
|  | import { useTranslation } from 'next-i18next'; | ||||||
|  | 
 | ||||||
|  | import { useCreateReducer } from '@/hooks/useCreateReducer'; | ||||||
|  | 
 | ||||||
|  | import { getSettings, saveSettings } from '@/utils/app/settings'; | ||||||
|  | 
 | ||||||
|  | import { Settings } from '@/types/settings'; | ||||||
|  | 
 | ||||||
|  | import HomeContext from '@/pages/api/home/home.context'; | ||||||
|  | 
 | ||||||
|  | interface Props { | ||||||
|  |   open: boolean; | ||||||
|  |   onClose: () => void; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const SettingDialog: FC<Props> = ({ open, onClose }) => { | ||||||
|  |   const { t } = useTranslation('settings'); | ||||||
|  |   const settings: Settings = getSettings(); | ||||||
|  |   const { state, dispatch } = useCreateReducer<Settings>({ | ||||||
|  |     initialState: settings, | ||||||
|  |   }); | ||||||
|  |   const { dispatch: homeDispatch } = useContext(HomeContext); | ||||||
|  |   const modalRef = useRef<HTMLDivElement>(null); | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     const handleMouseDown = (e: MouseEvent) => { | ||||||
|  |       if (modalRef.current && !modalRef.current.contains(e.target as Node)) { | ||||||
|  |         window.addEventListener('mouseup', handleMouseUp); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const handleMouseUp = (e: MouseEvent) => { | ||||||
|  |       window.removeEventListener('mouseup', handleMouseUp); | ||||||
|  |       onClose(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     window.addEventListener('mousedown', handleMouseDown); | ||||||
|  | 
 | ||||||
|  |     return () => { | ||||||
|  |       window.removeEventListener('mousedown', handleMouseDown); | ||||||
|  |     }; | ||||||
|  |   }, [onClose]); | ||||||
|  | 
 | ||||||
|  |   const handleSave = () => { | ||||||
|  |     homeDispatch({ field: 'lightMode', value: state.theme }); | ||||||
|  |     saveSettings(state); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   // Render nothing if the dialog is not open.
 | ||||||
|  |   if (!open) { | ||||||
|  |     return <></>; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Render the dialog.
 | ||||||
|  |   return ( | ||||||
|  |     <div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50"> | ||||||
|  |       <div className="fixed inset-0 z-10 overflow-hidden"> | ||||||
|  |         <div className="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0"> | ||||||
|  |           <div | ||||||
|  |             className="hidden sm:inline-block sm:h-screen sm:align-middle" | ||||||
|  |             aria-hidden="true" | ||||||
|  |           /> | ||||||
|  | 
 | ||||||
|  |           <div | ||||||
|  |             ref={modalRef} | ||||||
|  |             className="dark:border-netural-400 inline-block max-h-[400px] transform overflow-y-auto rounded-lg border border-gray-300 bg-white px-4 pt-5 pb-4 text-left align-bottom shadow-xl transition-all dark:bg-[#202123] sm:my-8 sm:max-h-[600px] sm:w-full sm:max-w-lg sm:p-6 sm:align-middle" | ||||||
|  |             role="dialog" | ||||||
|  |           > | ||||||
|  |             <div className="text-lg pb-4 font-bold text-black dark:text-neutral-200"> | ||||||
|  |               {t('Settings')} | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div className="text-sm font-bold mb-2 text-black dark:text-neutral-200"> | ||||||
|  |               {t('Theme')} | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <select | ||||||
|  |               className="w-full cursor-pointer bg-transparent p-2 text-neutral-700 dark:text-neutral-200" | ||||||
|  |               value={state.theme} | ||||||
|  |               onChange={(event) => | ||||||
|  |                 dispatch({ field: 'theme', value: event.target.value }) | ||||||
|  |               } | ||||||
|  |             > | ||||||
|  |               <option value="dark">{t('Dark mode')}</option> | ||||||
|  |               <option value="light">{t('Light mode')}</option> | ||||||
|  |             </select> | ||||||
|  | 
 | ||||||
|  |             <button | ||||||
|  |               type="button" | ||||||
|  |               className="w-full px-4 py-2 mt-6 border rounded-lg shadow border-neutral-500 text-neutral-900 hover:bg-neutral-100 focus:outline-none dark:border-neutral-800 dark:border-opacity-50 dark:bg-white dark:text-black dark:hover:bg-neutral-300" | ||||||
|  |               onClick={() => { | ||||||
|  |                 handleSave(); | ||||||
|  |                 onClose(); | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               {t('Save')} | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | @ -23,6 +23,7 @@ import { | ||||||
| } from '@/utils/app/conversation'; | } from '@/utils/app/conversation'; | ||||||
| import { saveFolders } from '@/utils/app/folders'; | import { saveFolders } from '@/utils/app/folders'; | ||||||
| import { savePrompts } from '@/utils/app/prompts'; | import { savePrompts } from '@/utils/app/prompts'; | ||||||
|  | import { getSettings } from '@/utils/app/settings'; | ||||||
| 
 | 
 | ||||||
| import { Conversation } from '@/types/chat'; | import { Conversation } from '@/types/chat'; | ||||||
| import { KeyValuePair } from '@/types/data'; | import { KeyValuePair } from '@/types/data'; | ||||||
|  | @ -68,7 +69,7 @@ const Home = ({ | ||||||
|       conversations, |       conversations, | ||||||
|       selectedConversation, |       selectedConversation, | ||||||
|       prompts, |       prompts, | ||||||
|       temperature |       temperature, | ||||||
|     }, |     }, | ||||||
|     dispatch, |     dispatch, | ||||||
|   } = contextValue; |   } = contextValue; | ||||||
|  | @ -250,9 +251,12 @@ const Home = ({ | ||||||
|   // ON LOAD --------------------------------------------
 |   // ON LOAD --------------------------------------------
 | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     const theme = localStorage.getItem('theme'); |     const settings = getSettings(); | ||||||
|     if (theme) { |     if (settings.theme) { | ||||||
|       dispatch({ field: 'lightMode', value: theme as 'dark' | 'light' }); |       dispatch({ | ||||||
|  |         field: 'lightMode', | ||||||
|  |         value: settings.theme, | ||||||
|  |       }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const apiKey = localStorage.getItem('apiKey'); |     const apiKey = localStorage.getItem('apiKey'); | ||||||
|  | @ -419,6 +423,7 @@ export const getServerSideProps: GetServerSideProps = async ({ locale }) => { | ||||||
|         'sidebar', |         'sidebar', | ||||||
|         'markdown', |         'markdown', | ||||||
|         'promptbar', |         'promptbar', | ||||||
|  |         'settings', | ||||||
|       ])), |       ])), | ||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "الوضع الداكن", | ||||||
|  |   "Light mode": "الوضع الفاتح" | ||||||
|  | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "ডার্ক মোড", | ||||||
|  |   "Light mode": "লাইট মোড" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "আলাপচারিতা ইমপোর্ট", |   "Import data": "আলাপচারিতা ইমপোর্ট", | ||||||
|   "Are you sure?": "আপনি কি নিশ্চিত?", |   "Are you sure?": "আপনি কি নিশ্চিত?", | ||||||
|   "Clear conversations": "কথোপকথন পরিষ্কার করুন", |   "Clear conversations": "কথোপকথন পরিষ্কার করুন", | ||||||
|   "Export data": "আলাপচারিতা এক্সপোর্ট", |   "Export data": "আলাপচারিতা এক্সপোর্ট" | ||||||
|   "Dark mode": "ডার্ক মোড", |  | ||||||
|   "Light mode": "লাইট মোড" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Dark Mode", | ||||||
|  |   "Light mode": "Light Mode" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Konversationen importieren", |   "Import data": "Konversationen importieren", | ||||||
|   "Are you sure?": "Bist du sicher?", |   "Are you sure?": "Bist du sicher?", | ||||||
|   "Clear conversations": "Konversationen löschen", |   "Clear conversations": "Konversationen löschen", | ||||||
|   "Export data": "Konversationen exportieren", |   "Export data": "Konversationen exportieren" | ||||||
|   "Dark mode": "Dark Mode", |  | ||||||
|   "Light mode": "Light Mode" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Modo oscuro", | ||||||
|  |   "Light mode": "Modo claro" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importar conversaciones", |   "Import data": "Importar conversaciones", | ||||||
|   "Are you sure?": "¿Estás seguro?", |   "Are you sure?": "¿Estás seguro?", | ||||||
|   "Clear conversations": "Borrar conversaciones", |   "Clear conversations": "Borrar conversaciones", | ||||||
|   "Export data": "Exportar conversaciones", |   "Export data": "Exportar conversaciones" | ||||||
|   "Dark mode": "Modo oscuro", |  | ||||||
|   "Light mode": "Modo claro" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Mode sombre", | ||||||
|  |   "Light mode": "Mode clair" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importer des conversations", |   "Import data": "Importer des conversations", | ||||||
|   "Are you sure?": "Êtes-vous sûr ?", |   "Are you sure?": "Êtes-vous sûr ?", | ||||||
|   "Clear conversations": "Effacer les conversations", |   "Clear conversations": "Effacer les conversations", | ||||||
|   "Export data": "Exporter les conversations", |   "Export data": "Exporter les conversations" | ||||||
|   "Dark mode": "Mode sombre", |  | ||||||
|   "Light mode": "Mode clair" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "מצב כהה", | ||||||
|  |   "Light mode": "מצב בהיר" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "ייבוא שיחות", |   "Import data": "ייבוא שיחות", | ||||||
|   "Are you sure?": "אתה בטוח?", |   "Are you sure?": "אתה בטוח?", | ||||||
|   "Clear conversations": "ניקוי שיחות", |   "Clear conversations": "ניקוי שיחות", | ||||||
|   "Export data": "ייצוא שיחות", |   "Export data": "ייצוא שיחות" | ||||||
|   "Dark mode": "מצב כהה", |  | ||||||
|   "Light mode": "מצב בהיר" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Mode gelap", | ||||||
|  |   "Light mode": "Mode terang" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Impor percakapan", |   "Import data": "Impor percakapan", | ||||||
|   "Are you sure?": "Apakah Anda yakin?", |   "Are you sure?": "Apakah Anda yakin?", | ||||||
|   "Clear conversations": "Hapus percakapan", |   "Clear conversations": "Hapus percakapan", | ||||||
|   "Export data": "Ekspor percakapan", |   "Export data": "Ekspor percakapan" | ||||||
|   "Dark mode": "Mode gelap", |  | ||||||
|   "Light mode": "Mode terang" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Modalità scura", | ||||||
|  |   "Light mode": "Modalità chiara" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importa dati", |   "Import data": "Importa dati", | ||||||
|   "Are you sure?": "Sei sicuro?", |   "Are you sure?": "Sei sicuro?", | ||||||
|   "Clear conversations": "Elimina conversazioni", |   "Clear conversations": "Elimina conversazioni", | ||||||
|   "Export data": "Esporta dati", |   "Export data": "Esporta dati" | ||||||
|   "Dark mode": "Modalità scura", |  | ||||||
|   "Light mode": "Modalità chiara" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | { | ||||||
|  |   "Settings": "設定", | ||||||
|  |   "Theme": "テーマ", | ||||||
|  |   "Save": "保存", | ||||||
|  |   "Dark mode": "ダークモード", | ||||||
|  |   "Light mode": "ライトモード" | ||||||
|  | } | ||||||
|  | @ -9,5 +9,6 @@ | ||||||
|   "Clear conversations": " 会話をクリア", |   "Clear conversations": " 会話をクリア", | ||||||
|   "Export data": "会話履歴をエクスポート", |   "Export data": "会話履歴をエクスポート", | ||||||
|   "Dark mode": "ダークモード", |   "Dark mode": "ダークモード", | ||||||
|   "Light mode": "ライトモード" |   "Light mode": "ライトモード", | ||||||
|  |   "Settings": "設定" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "다크 모드", | ||||||
|  |   "Light mode": "라이트 모드" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "대화 가져오기", |   "Import data": "대화 가져오기", | ||||||
|   "Are you sure?": "확실합니까?", |   "Are you sure?": "확실합니까?", | ||||||
|   "Clear conversations": "대화 지우기", |   "Clear conversations": "대화 지우기", | ||||||
|   "Export data": "대화 내보내기", |   "Export data": "대화 내보내기" | ||||||
|   "Dark mode": "다크 모드", |  | ||||||
|   "Light mode": "라이트 모드" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Tryb ciemny", | ||||||
|  |   "Light mode": "Tryb jasny" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Import rozmów", |   "Import data": "Import rozmów", | ||||||
|   "Are you sure?": "Czy jesteś pewien?", |   "Are you sure?": "Czy jesteś pewien?", | ||||||
|   "Clear conversations": "Usuń rozmowy", |   "Clear conversations": "Usuń rozmowy", | ||||||
|   "Export data": "Eksport rozmów", |   "Export data": "Eksport rozmów" | ||||||
|   "Dark mode": "Tryb ciemny", |  | ||||||
|   "Light mode": "Tryb jasny" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Modo escuro", | ||||||
|  |   "Light mode": "Modo claro" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importar conversas", |   "Import data": "Importar conversas", | ||||||
|   "Are you sure?": "Tem certeza?", |   "Are you sure?": "Tem certeza?", | ||||||
|   "Clear conversations": "Apagar conversas", |   "Clear conversations": "Apagar conversas", | ||||||
|   "Export data": "Exportar conversas", |   "Export data": "Exportar conversas" | ||||||
|   "Dark mode": "Modo escuro", |  | ||||||
|   "Light mode": "Modo claro" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Modul întunecat", | ||||||
|  |   "Light mode": "Modul de golire" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importați conversații", |   "Import data": "Importați conversații", | ||||||
|   "Are you sure?": "Esti sigur?", |   "Are you sure?": "Esti sigur?", | ||||||
|   "Clear conversations": "Ștergeți conversațiile", |   "Clear conversations": "Ștergeți conversațiile", | ||||||
|   "Export data": "Exportați conversații", |   "Export data": "Exportați conversații" | ||||||
|   "Dark mode": "Modul întunecat", |  | ||||||
|   "Light mode": "Modul de golire" |  | ||||||
| } | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Темный режим", | ||||||
|  |   "Light mode": "Светлый режим" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Импортировать чаты", |   "Import data": "Импортировать чаты", | ||||||
|   "Are you sure?": "Вы уверены?", |   "Are you sure?": "Вы уверены?", | ||||||
|   "Clear conversations": "Удалить чаты", |   "Clear conversations": "Удалить чаты", | ||||||
|   "Export data": "Экспортировать чаты", |   "Export data": "Экспортировать чаты" | ||||||
|   "Dark mode": "Темный режим", |  | ||||||
|   "Light mode": "Светлый режим" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "අඳුරු මාදිලිය", | ||||||
|  |   "Light mode": "ආලෝක මාදිලිය" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "සංවාද ආයාත කරන්න", |   "Import data": "සංවාද ආයාත කරන්න", | ||||||
|   "Are you sure?": "ඔබට විශ්වාස ද?", |   "Are you sure?": "ඔබට විශ්වාස ද?", | ||||||
|   "Clear conversations": "සංවාද මකන්න", |   "Clear conversations": "සංවාද මකන්න", | ||||||
|   "Export data": "සංවාද නිර්යාත කරන්න", |   "Export data": "සංවාද නිර්යාත කරන්න" | ||||||
|   "Dark mode": "අඳුරු මාදිලිය", |  | ||||||
|   "Light mode": "ආලෝක මාදිලිය" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Mörkt läge", | ||||||
|  |   "Light mode": "Ljust läge" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Importera konversationer", |   "Import data": "Importera konversationer", | ||||||
|   "Are you sure?": "Är du säker?", |   "Are you sure?": "Är du säker?", | ||||||
|   "Clear conversations": "Radera konversationer", |   "Clear conversations": "Radera konversationer", | ||||||
|   "Export data": "Exportera konversationer", |   "Export data": "Exportera konversationer" | ||||||
|   "Dark mode": "Mörkt läge", |  | ||||||
|   "Light mode": "Ljust läge" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "డార్క్ మోడ్", | ||||||
|  |   "Light mode": "లైట్ మోడ్" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "సంభాషణలు దిగుమతి చేయండి", |   "Import data": "సంభాషణలు దిగుమతి చేయండి", | ||||||
|   "Are you sure?": "మీరు ఖచ్చితంగా ఉన్నారా?", |   "Are you sure?": "మీరు ఖచ్చితంగా ఉన్నారా?", | ||||||
|   "Clear conversations": "సంభాషణలు తొలగించు", |   "Clear conversations": "సంభాషణలు తొలగించు", | ||||||
|   "Export data": "సంభాషణలు ఎగుమతి చేయండి", |   "Export data": "సంభాషణలు ఎగుమతి చేయండి" | ||||||
|   "Dark mode": "డార్క్ మోడ్", |  | ||||||
|   "Light mode": "లైట్ మోడ్" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "Chế độ tối", | ||||||
|  |   "Light mode": "Chế độ sáng" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "Nhập dữ liệu hội thoại", |   "Import data": "Nhập dữ liệu hội thoại", | ||||||
|   "Are you sure?": "Bạn chắc chắn chứ?", |   "Are you sure?": "Bạn chắc chắn chứ?", | ||||||
|   "Clear conversations": "Xoá các đoạn hội thoại", |   "Clear conversations": "Xoá các đoạn hội thoại", | ||||||
|   "Export data": "Xuất dữ liệu hội thoại", |   "Export data": "Xuất dữ liệu hội thoại" | ||||||
|   "Dark mode": "Chế độ tối", |  | ||||||
|   "Light mode": "Chế độ sáng" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | { | ||||||
|  |   "Dark mode": "深色模式", | ||||||
|  |   "Light mode": "浅色模式" | ||||||
|  | } | ||||||
|  | @ -7,7 +7,5 @@ | ||||||
|   "Import data": "导入对话", |   "Import data": "导入对话", | ||||||
|   "Are you sure?": "确定吗?", |   "Are you sure?": "确定吗?", | ||||||
|   "Clear conversations": "清空对话", |   "Clear conversations": "清空对话", | ||||||
|   "Export data": "导出对话", |   "Export data": "导出对话" | ||||||
|   "Dark mode": "深色模式", |  | ||||||
|   "Light mode": "浅色模式" |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | export interface Settings { | ||||||
|  |   theme: 'light' | 'dark'; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,23 @@ | ||||||
|  | import { Settings } from '@/types/settings'; | ||||||
|  | 
 | ||||||
|  | const STORAGE_KEY = 'settings'; | ||||||
|  | 
 | ||||||
|  | export const getSettings = (): Settings => { | ||||||
|  |   let settings: Settings = { | ||||||
|  |     theme: 'dark', | ||||||
|  |   }; | ||||||
|  |   const settingsJson = localStorage.getItem(STORAGE_KEY); | ||||||
|  |   if (settingsJson) { | ||||||
|  |     try { | ||||||
|  |       let savedSettings = JSON.parse(settingsJson) as Settings; | ||||||
|  |       settings = Object.assign(settings, savedSettings); | ||||||
|  |     } catch (e) { | ||||||
|  |       console.error(e); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return settings; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const saveSettings = (settings: Settings) => { | ||||||
|  |   localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); | ||||||
|  | }; | ||||||
		Loading…
	
		Reference in New Issue