Update language files and fix UI issues
This commit is contained in:
		
							parent
							
								
									d9ce1e2d2c
								
							
						
					
					
						commit
						502759fae6
					
				| @ -2,6 +2,7 @@ | |||||||
|     "save": "Save", |     "save": "Save", | ||||||
|     "saved": "Saved", |     "saved": "Saved", | ||||||
|     "cancel": "Cancel", |     "cancel": "Cancel", | ||||||
|  |     "retry": "Retry", | ||||||
|     "share": { |     "share": { | ||||||
|         "tooltip": { |         "tooltip": { | ||||||
|             "share": "Share" |             "share": "Share" | ||||||
| @ -41,5 +42,8 @@ | |||||||
|     "saveAndSubmit": "Save & Submit", |     "saveAndSubmit": "Save & Submit", | ||||||
|     "editMessage": { |     "editMessage": { | ||||||
|         "placeholder": "Type a message..." |         "placeholder": "Type a message..." | ||||||
|     } |     }, | ||||||
|  |     "submit": "Submit", | ||||||
|  |     "noData": "No data", | ||||||
|  |     "noHistory": "No chat history" | ||||||
| } | } | ||||||
| @ -1 +0,0 @@ | |||||||
| {} |  | ||||||
| @ -8,6 +8,8 @@ | |||||||
|     "error": "Error", |     "error": "Error", | ||||||
|     "somethingWentWrong": "Something went wrong", |     "somethingWentWrong": "Something went wrong", | ||||||
|     "validationSelectModel": "Please select a model to continue", |     "validationSelectModel": "Please select a model to continue", | ||||||
|  |     "deleteHistoryConfirmation": "Are you sure you want to delete this history?", | ||||||
|  |     "editHistoryTitle": "Enter a new title", | ||||||
|     "generalSettings": { |     "generalSettings": { | ||||||
|         "title": "General Settings", |         "title": "General Settings", | ||||||
|         "heading": "Web UI Settings", |         "heading": "Web UI Settings", | ||||||
| @ -16,6 +18,10 @@ | |||||||
|                 "label": "Speech Recognition Language", |                 "label": "Speech Recognition Language", | ||||||
|                 "placeholder": "Select a language" |                 "placeholder": "Select a language" | ||||||
|             }, |             }, | ||||||
|  |             "language": { | ||||||
|  |                 "label": "Language", | ||||||
|  |                 "placeholder": "Select a language" | ||||||
|  |             }, | ||||||
|             "darkMode": { |             "darkMode": { | ||||||
|                 "label": "Change Theme", |                 "label": "Change Theme", | ||||||
|                 "options": { |                 "options": { | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								src/assets/locale/en/playground.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/assets/locale/en/playground.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  |     "ollamaState": { | ||||||
|  |         "searching": "Searching for Your Ollama 🦙", | ||||||
|  |         "running": "Ollama is running 🦙", | ||||||
|  |         "notRunning": "Unable to connect to Ollama 🦙" | ||||||
|  |     }, | ||||||
|  |     "formError": { | ||||||
|  |         "noModel": "Please select a model", | ||||||
|  |         "noEmbeddingModel": "Please set an embedding model on the Settings > Ollama page" | ||||||
|  |     }, | ||||||
|  |     "form": { | ||||||
|  |         "textarea": { | ||||||
|  |             "placeholder": "Type a message..." | ||||||
|  |         }, | ||||||
|  |         "webSearch": { | ||||||
|  |             "on": "On", | ||||||
|  |             "off": "Off" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "tooltip": { | ||||||
|  |         "searchInternet": "Search Internet", | ||||||
|  |         "speechToText": "Speech to Text", | ||||||
|  |         "uploadImage": "Upload Image", | ||||||
|  |         "stopStreaming": "Stop Streaming" | ||||||
|  |     }, | ||||||
|  |     "sendWhenEnter": "Send when Enter pressed" | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								src/assets/locale/ml/common.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/assets/locale/ml/common.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | { | ||||||
|  |     "save": "സേവ് ചെയ്യുക", | ||||||
|  |     "saved": "സംരക്ഷിച്ചു", | ||||||
|  |     "cancel": "റദ്ദാക്കുക", | ||||||
|  |     "retry": "വീണ്ടും ശ്രമിക്കുക", | ||||||
|  |     "share": { | ||||||
|  |         "tooltip": { | ||||||
|  |             "share": "പങ്കിടുക" | ||||||
|  |         }, | ||||||
|  |         "modal": { | ||||||
|  |             "title": "ചാറ്റ് ലിങ്ക് പങ്കിടുക" | ||||||
|  |         }, | ||||||
|  |         "form": { | ||||||
|  |             "defaultValue": { | ||||||
|  |                 "name": "അജ്ഞാതന്", | ||||||
|  |                 "title": "പേരില്ലാത്ത ചാറ്റ്" | ||||||
|  |             }, | ||||||
|  |             "title": { | ||||||
|  |                 "label": "ചാറ്റ് തലക്കെട്ട്", | ||||||
|  |                 "placeholder": "ചാറ്റ് തലക്കെട്ട് നല്കുക", | ||||||
|  |                 "required": "ചാറ്റ് തലക്കെട്ട് ആവശ്യമാണ്" | ||||||
|  |             }, | ||||||
|  |             "name": { | ||||||
|  |                 "label": "നിങ്ങളുടെ പേര്", | ||||||
|  |                 "placeholder": "നിങ്ങളുടെ പേര് നല്കുക", | ||||||
|  |                 "required": "നിങ്ങളുടെ പേര് ആവശ്യമാണ്" | ||||||
|  |             }, | ||||||
|  |             "btn": { | ||||||
|  |                 "save": "ലിങ്ക് ജനറേറ്റ് ചെയ്യുക", | ||||||
|  |                 "saving": "ലിങ്ക് ജനറേറ്റ് ചെയ്യുന്നു..." | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "notification": { | ||||||
|  |             "successGenerate": "ലിങ്ക് ക്ലിപ്ബോര്ഡിലേക്ക് പകര്ത്തി", | ||||||
|  |             "failGenerate": "ലിങ്ക് ജനറേറ്റ് ചെയ്യുന്നതില് പരാജയപ്പെട്ടു" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "copyToClipboard": "ക്ലിപ്ബോര്ഡിലേക്ക് പകര്ത്തുക", | ||||||
|  |     "webSearch": "വെബ് തിരയുന്നു", | ||||||
|  |     "regenerate": "വീണ്ടും ജനറേറ്റ് ചെയ്യുക", | ||||||
|  |     "edit": "എഡിറ്റ് ചെയ്യുക", | ||||||
|  |     "saveAndSubmit": "സേവ് ചെയ്ത് സമര്പ്പിക്കുക", | ||||||
|  |     "editMessage": { | ||||||
|  |         "placeholder": "ഒരു സന്ദേശം ടൈപ്പ് ചെയ്യുക..." | ||||||
|  |     }, | ||||||
|  |     "submit": "സമർപ്പിക്കുക", | ||||||
|  |     "noData": "ഡാറ്റ ലഭ്യമല്ല", | ||||||
|  |     "noHistory": "ചാറ്റ് ചരിത്രം ലഭ്യമല്ല" | ||||||
|  | } | ||||||
							
								
								
									
										215
									
								
								src/assets/locale/ml/option.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								src/assets/locale/ml/option.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,215 @@ | |||||||
|  | { | ||||||
|  |     "newChat": "പുതിയ ചാറ്റ്", | ||||||
|  |     "selectAModel": "ഒരു മോഡല് തിരഞ്ഞെടുക്കുക", | ||||||
|  |     "selectAPrompt": "ഒരു പ്രോംപ്റ്റ് തിരഞ്ഞെടുക്കുക", | ||||||
|  |     "githubRepository": "ഗിറ്റ്ഹബ് റെപ്പോസിറ്ററി", | ||||||
|  |     "settings": "ക്രമീകരണങ്ങള്", | ||||||
|  |     "sidebarTitle": "ചാറ്റ് ചരിത്രം", | ||||||
|  |     "error": "പിശക്", | ||||||
|  |     "somethingWentWrong": "എന്തോ തെറ്റായി", | ||||||
|  |     "deleteHistoryConfirmation": "നിങ്ങളുടെ ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ?", | ||||||
|  |     "editHistoryTitle": "ചാറ്റ് title എഡിറ്റുചെയ്യുക", | ||||||
|  |     "validationSelectModel": "തുടരുന്നതിന് ഒരു മോഡല് തിരഞ്ഞെടുക്കുക", | ||||||
|  |     "generalSettings": { | ||||||
|  |         "title": "പൊതുവായ ക്രമീകരണങ്ങള്", | ||||||
|  |         "heading": "വെബ് UI ക്രമീകരണങ്ങള്", | ||||||
|  |         "settings": { | ||||||
|  |             "speechRecognitionLang": { | ||||||
|  |                 "label": "സംഭാഷണ തിരിച്ചറിയല് ഭാഷ", | ||||||
|  |                 "placeholder": "ഒരു ഭാഷ തിരഞ്ഞെടുക്കുക" | ||||||
|  |             }, | ||||||
|  |             "language": { | ||||||
|  |                 "label": "ഭാഷ", | ||||||
|  |                 "placeholder": "ഒരു ഭാഷ തിരഞ്ഞെടുക്കുക" | ||||||
|  |             }, | ||||||
|  |             "darkMode": { | ||||||
|  |                 "label": "തീം മാറ്റുക", | ||||||
|  |                 "options": { | ||||||
|  |                     "light": "ലൈറ്റ്", | ||||||
|  |                     "dark": "ഡാര്ക്ക്" | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "searchMode": { | ||||||
|  |                 "label": "സാധാരണ ഇന്റർനെറ്റ് അന്വേഷണം നടത്തുക" | ||||||
|  |             }, | ||||||
|  |             "deleteChatHistory": { | ||||||
|  |                 "label": "ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കുക", | ||||||
|  |                 "button": "ഇല്ലാതാക്കുക", | ||||||
|  |                 "confirm": "നിങ്ങളുടെ ചാറ്റ് ചരിത്രം ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ? ഈ പ്രവർത്തനം പിന്നീട് പിൻവലിക്കാനാകില്ല." | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "manageModels": { | ||||||
|  |         "title": "മോഡലുകള് കൈകാര്യം ചെയ്യുക", | ||||||
|  |         "addBtn": "പുതിയ മോഡല് ചേര്ക്കുക", | ||||||
|  |         "columns": { | ||||||
|  |             "name": "പേര്", | ||||||
|  |             "digest": "ഡൈജസ്റ്റ്", | ||||||
|  |             "modifiedAt": "അവസാനമായി പരിഷ്കരിച്ചത്", | ||||||
|  |             "size": "വലുപ്പം", | ||||||
|  |             "actions": "പ്രവർത്തനങ്ങൾ" | ||||||
|  |         }, | ||||||
|  |         "expandedColumns": { | ||||||
|  |             "parentModel": "പാരന്റ് മോഡല്", | ||||||
|  |             "format": "ഫോര്മാറ്റ്", | ||||||
|  |             "family": "കുടുംബം", | ||||||
|  |             "parameterSize": "പാരാമീറ്റര് വലുപ്പം", | ||||||
|  |             "quantizationLevel": "ക്വാണ്ടൈസേഷന് ലെവല്" | ||||||
|  |         }, | ||||||
|  |         "tooltip": { | ||||||
|  |             "delete": "മോഡല് ഇല്ലാതാക്കുക", | ||||||
|  |             "repull": "മോഡല് വീണ്ടും ലഭ്യമാക്കുക" | ||||||
|  |         }, | ||||||
|  |         "confirm": { | ||||||
|  |             "delete": "ഈ മോഡല് ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ?", | ||||||
|  |             "repull": "ഈ മോഡല് വീണ്ടും ലഭ്യമാക്കണമെന്ന് തീർച്ചയാണോ?" | ||||||
|  |         }, | ||||||
|  |         "modal": { | ||||||
|  |             "title": "പുതിയ മോഡല് ചേര്ക്കുക", | ||||||
|  |             "placeholder": "മോഡല് പേര് നല്കുക", | ||||||
|  |             "pull": "മോഡല് ലഭ്യമാക്കുക" | ||||||
|  |         }, | ||||||
|  |         "notification": { | ||||||
|  |             "pullModel": "മോഡല് ലഭ്യമാക്കുന്നു", | ||||||
|  |             "pullModelDescription": "{{modelName}} മോഡല് ലഭ്യമാക്കുന്നു. കൂടുതല് വിവരങ്ങള്ക്കായി എക്സ്റ്റെന്ഷന് ഐക്കണ് പരിശോധിക്കുക.", | ||||||
|  |             "success": "വിജയം", | ||||||
|  |             "error": "പിശക്", | ||||||
|  |             "successDescription": "മോഡല് വിജയകരമായി ലഭ്യമാക്കി", | ||||||
|  |             "successDeleteDescription": "മോഡല് വിജയകരമായി ഇല്ലാതാക്കി", | ||||||
|  |             "someError": "എന്തോ തെറ്റായി. ദയവായി പിന്നീട് വീണ്ടും ശ്രമിക്കുക" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "managePrompts": { | ||||||
|  |         "title": "പ്രോംപ്റ്റുകള് കൈകാര്യം ചെയ്യുക", | ||||||
|  |         "addBtn": "പുതിയ പ്രോംപ്റ്റ് ചേര്ക്കുക", | ||||||
|  |         "columns": { | ||||||
|  |             "title": "തലക്കെട്ട്", | ||||||
|  |             "prompt": "പ്രോംപ്റ്റ്", | ||||||
|  |             "type": "പ്രോംപ്റ്റ് തരം", | ||||||
|  |             "actions": "പ്രവർത്തനങ്ങൾ" | ||||||
|  |         }, | ||||||
|  |         "systemPrompt": "സിസ്റ്റം പ്രോംപ്റ്റ്", | ||||||
|  |         "quickPrompt": "വേഗത്തിലുള്ള പ്രോംപ്റ്റ്", | ||||||
|  |         "tooltip": { | ||||||
|  |             "delete": "പ്രോംപ്റ്റ് ഇല്ലാതാക്കുക", | ||||||
|  |             "edit": "പ്രോംപ്റ്റ് എഡിറ്റുചെയ്യുക" | ||||||
|  |         }, | ||||||
|  |         "confirm": { | ||||||
|  |             "delete": "ഈ പ്രോംപ്റ്റ് ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ? ഈ പ്രവർത്തനം പിന്നീട് പിൻവലിക്കാനാകില്ല." | ||||||
|  |         }, | ||||||
|  |         "modal": { | ||||||
|  |             "addTitle": "പുതിയ പ്രോംപ്റ്റ് ചേര്ക്കുക", | ||||||
|  |             "editTitle": "പ്രോംപ്റ്റ് എഡിറ്റുചെയ്യുക" | ||||||
|  |         }, | ||||||
|  |         "form": { | ||||||
|  |             "title": { | ||||||
|  |                 "label": "തലക്കെട്ട്", | ||||||
|  |                 "placeholder": "എന്റെ അതുല്യമായ പ്രോംപ്റ്റ്", | ||||||
|  |                 "required": "ദയവായി ഒരു തലക്കെട്ട് നല്കുക" | ||||||
|  |             }, | ||||||
|  |             "prompt": { | ||||||
|  |                 "label": "പ്രോംപ്റ്റ്", | ||||||
|  |                 "placeholder": "പ്രോംപ്റ്റ് നല്കുക", | ||||||
|  |                 "required": "ദയവായി ഒരു പ്രോംപ്റ്റ് നല്കുക", | ||||||
|  |                 "help": "നിങ്ങള്ക്ക് {key} എന്ന രീതിയില് പ്രോംപ്റ്റില് വേരിയബിളുകള് ഉപയോഗിക്കാവുന്നതാണ്." | ||||||
|  |             }, | ||||||
|  |             "isSystem": { | ||||||
|  |                 "label": "സിസ്റ്റം പ്രോംപ്റ്റ് ആണോ" | ||||||
|  |             }, | ||||||
|  |             "btnSave": { | ||||||
|  |                 "saving": "പ്രോംപ്റ്റ് ചേര്ക്കുന്നു...", | ||||||
|  |                 "save": "പ്രോംപ്റ്റ് ചേര്ക്കുക" | ||||||
|  |             }, | ||||||
|  |             "btnEdit": { | ||||||
|  |                 "saving": "പ്രോംപ്റ്റ് അപ്ഡേറ്റ് ചെയ്യുന്നു...", | ||||||
|  |                 "save": "പ്രോംപ്റ്റ് അപ്ഡേറ്റ് ചെയ്യുക" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "notification": { | ||||||
|  |             "addSuccess": "പ്രോംപ്റ്റ് ചേർത്തു", | ||||||
|  |             "addSuccessDesc": "പ്രോംപ്റ്റ് വിജയകരമായി ചേർത്തു", | ||||||
|  |             "error": "പിശക്", | ||||||
|  |             "someError": "എന്തോ തെറ്റായി. ദയവായി പിന്നീട് വീണ്ടും ശ്രമിക്കുക", | ||||||
|  |             "updatedSuccess": "പ്രോംപ്റ്റ് അപ്ഡേറ്റ് ചെയ്തു", | ||||||
|  |             "updatedSuccessDesc": "പ്രോംപ്റ്റ് വിജയകരമായി അപ്ഡേറ്റ് ചെയ്തു", | ||||||
|  |             "deletedSuccess": "പ്രോംപ്റ്റ് ഇല്ലാതാക്കി", | ||||||
|  |             "deletedSuccessDesc": "പ്രോംപ്റ്റ് വിജയകരമായി ഇല്ലാതാക്കി" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "manageShare": { | ||||||
|  |         "title": "പങ്കിടുന്നത് കൈകാര്യം ചെയ്യുക", | ||||||
|  |         "heading": "പേജ് പങ്കിടാനുള്ള URL കോൺഫിഗർ ചെയ്യുക", | ||||||
|  |         "form": { | ||||||
|  |             "url": { | ||||||
|  |                 "label": "പേജ് പങ്കിടാനുള്ള URL", | ||||||
|  |                 "placeholder": "പേജ് പങ്കിടാനുള്ള URL നല്കുക", | ||||||
|  |                 "required": "ദയവായി നിങ്ങളുടെ പേജ് പങ്കിടാനുള്ള URL നല്കുക!", | ||||||
|  |                 "help": "സ്വകാര്യതക്കായി, നിങ്ങള്ക്ക് സ്വന്തമായി പേജ് പങ്കിടുന്ന സൗകര്യം ഹോസ്റ്റ് ചെയ്യാനും അവിടെയുള്ള URL ഇവിടെ നല്കാനും കഴിയും. <anchor>കൂടുതല് അറിയുക</anchor>." | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "webshare": { | ||||||
|  |             "heading": "വെബ് പങ്കിടല്", | ||||||
|  |             "columns": { | ||||||
|  |                 "title": "തലക്കെട്ട്", | ||||||
|  |                 "url": "URL", | ||||||
|  |                 "actions": "പ്രവർത്തനങ്ങൾ" | ||||||
|  |             }, | ||||||
|  |             "tooltip": { | ||||||
|  |                 "delete": "പങ്കിടല് ഇല്ലാതാക്കുക" | ||||||
|  |             }, | ||||||
|  |             "confirm": { | ||||||
|  |                 "delete": "ഈ പങ്കിടല് ഇല്ലാതാക്കണമെന്ന് തീർച്ചയാണോ? ഈ പ്രവർത്തനം പിന്നീട് പിൻവലിക്കാനാകില്ല." | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "notification": { | ||||||
|  |             "pageShareSuccess": "പേജ് പങ്കിടാനുള്ള URL വിജയകരമായി അപ്ഡേറ്റ് ചെയ്തു", | ||||||
|  |             "someError": "എന്തോ തെറ്റായി. ദയവായി പിന്നീട് വീണ്ടും ശ്രമിക്കുക", | ||||||
|  |             "webShareDeleteSuccess": "വെബ് പങ്കിടല് വിജയകരമായി ഇല്ലാതാക്കി" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "ollamaSettings": { | ||||||
|  |         "title": "ഒല്ലാമാ ക്രമീകരണങ്ങള്", | ||||||
|  |         "heading": "ഒല്ലാമാ കോൺഫിഗർ ചെയ്യുക", | ||||||
|  |         "settings": { | ||||||
|  |             "ollamaUrl": { | ||||||
|  |                 "label": "ഒല്ലാമാ URL", | ||||||
|  |                 "placeholder": "ഒല്ലാമാ URL നല്കുക" | ||||||
|  |             }, | ||||||
|  |             "ragSettings": { | ||||||
|  |                 "label": "RAG ക്രമീകരണങ്ങള്", | ||||||
|  |                 "model": { | ||||||
|  |                     "label": "എംബെഡിംഗ് മോഡല്", | ||||||
|  |                     "required": "ദയവായി ഒരു മോഡല് തിരഞ്ഞെടുക്കുക", | ||||||
|  |                     "help": "`nomic-embed-text` പോലുള്ള എംബെഡിംഗ് മോഡലുകള് ഉപയോഗിക്കുന്നത് വളരെ നന്നായിരിക്കും.", | ||||||
|  |                     "placeholder": "ഒരു മോഡല് തിരഞ്ഞെടുക്കുക" | ||||||
|  |                 }, | ||||||
|  |                 "chunkSize": { | ||||||
|  |                     "label": "ചങ്ക് വലുപ്പം", | ||||||
|  |                     "placeholder": "ചങ്ക് വലുപ്പം നല്കുക", | ||||||
|  |                     "required": "ദയവായി ചങ്ക് വലുപ്പം നല്കുക" | ||||||
|  |                 }, | ||||||
|  |                 "chunkOverlap": { | ||||||
|  |                     "label": "ചങ്ക് ഓവര്ലാപ്പ്", | ||||||
|  |                     "placeholder": "ചങ്ക് ഓവര്ലാപ്പ് നല്കുക", | ||||||
|  |                     "required": "ദയവായി ചങ്ക് ഓവര്ലാപ്പ് നല്കുക" | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             "prompt": { | ||||||
|  |                 "label": "RAG പ്രോംപ്റ്റ് കോൺഫിഗർ ചെയ്യുക", | ||||||
|  |                 "option1": "സാധാരണ", | ||||||
|  |                 "option2": "വെബ്", | ||||||
|  |                 "alert": "സിസ്റ്റം പ്രോംപ്റ്റ് ഇവിടെ കോൺഫിഗർ ചെയ്യുന്നത് പഴയൗഖികമായി. ദയവായി പ്രോംപ്റ്റുകള് ചേര്ക്കാനോ എഡിറ്റുചെയ്യാനോ മാനേജ് പ്രോംപ്റ്റ്സ് സെക്ഷന് ഉപയോഗിക്കുക. ഈ സെക്ഷന് ഭാവിയില് നീക്കം ചെയ്യപ്പെടും.", | ||||||
|  |                 "systemPrompt": "സിസ്റ്റം പ്രോംപ്റ്റ്", | ||||||
|  |                 "systemPromptPlaceholder": "സിസ്റ്റം പ്രോംപ്റ്റ് നല്കുക", | ||||||
|  |                 "webSearchPrompt": "വെബ് തിരയല് പ്രോംപ്റ്റ്", | ||||||
|  |                 "webSearchPromptHelp": "പ്രോംപ്റ്റില് നിന്ന് `{search_results}` നീക്കം ചെയ്യരുത്.", | ||||||
|  |                 "webSearchPromptError": "ദയവായി ഒരു വെബ് തിരയല് പ്രോംപ്റ്റ് നല്കുക", | ||||||
|  |                 "webSearchPromptPlaceholder": "വെബ് തിരയല് പ്രോംപ്റ്റ് നല്കുക", | ||||||
|  |                 "webSearchFollowUpPrompt": "വെബ് തിരയല് തുടര്പ്രോംപ്റ്റ്", | ||||||
|  |                 "webSearchFollowUpPromptHelp": "പ്രോംപ്റ്റില് നിന്ന് `{chat_history}` യും `{question}` യും നീക്കം ചെയ്യരുത്.", | ||||||
|  |                 "webSearchFollowUpPromptError": "ദയവായി നിങ്ങളുടെ വെബ് തിരയല് തുടര്പ്രോംപ്റ്റ് നല്കുക!", | ||||||
|  |                 "webSearchFollowUpPromptPlaceholder": "നിങ്ങളുടെ വെബ് തിരയല് തുടര്പ്രോംപ്റ്റ്" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								src/assets/locale/ml/playground.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/assets/locale/ml/playground.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | { | ||||||
|  |     "ollamaState": { | ||||||
|  |         "searching": "നിങ്ങളുടെ ഒല്ലാമയ്ക്കായി തിരയുന്നു 🦙", | ||||||
|  |         "running": "ഒല്ലാമ പ്രവര്ത്തിക്കുന്നു 🦙", | ||||||
|  |         "notRunning": "ഒല്ലാമയുമായി ബന്ധിപ്പിക്കാന് കഴിയുന്നില്ല 🦙" | ||||||
|  |     }, | ||||||
|  |     "formError": { | ||||||
|  |         "noModel": "ദയവായി ഒരു മോഡല് തിരഞ്ഞെടുക്കുക", | ||||||
|  |         "noEmbeddingModel": "ക്രമീകരണങ്ങള് > ഒല്ലാമ പേജിലുള്ള എംബെഡിംഗ് മോഡല് സജ്ജീകരിക്കുക" | ||||||
|  |     }, | ||||||
|  |     "form": { | ||||||
|  |         "textarea": { | ||||||
|  |             "placeholder": "ഒരു സന്ദേശം ടൈപ്പ് ചെയ്യുക..." | ||||||
|  |         }, | ||||||
|  |         "webSearch": { | ||||||
|  |             "on": "ഓണ്", | ||||||
|  |             "off": "ഓഫ്" | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     "tooltip": { | ||||||
|  |         "searchInternet": "ഇന്റര്നെറ്റ് തിരയുക", | ||||||
|  |         "speechToText": "സംഭാഷണം ടെക്സ്റ്റായി", | ||||||
|  |         "uploadImage": "ഇമേജ് അപ്ലോഡ് ചെയ്യുക", | ||||||
|  |         "stopStreaming": "സ്ട്രീമിംഗ് നിർത്തുക" | ||||||
|  |     }, | ||||||
|  |     "sendWhenEnter": "എന്റര് അമര്ത്തുമ്പോള് അയയ്ക്കുക" | ||||||
|  | } | ||||||
| @ -26,7 +26,7 @@ const LinkComponent = (item: { | |||||||
|           item.current === item.href |           item.current === item.href | ||||||
|             ? "bg-gray-100 text-gray-600 dark:bg-[#262626] dark:text-white" |             ? "bg-gray-100 text-gray-600 dark:bg-[#262626] dark:text-white" | ||||||
|             : "text-gray-700 hover:text-gray-600 hover:bg-gray-100 dark:text-gray-200 dark:hover:text-white dark:hover:bg-[#262626]", |             : "text-gray-700 hover:text-gray-600 hover:bg-gray-100 dark:text-gray-200 dark:hover:text-white dark:hover:bg-[#262626]", | ||||||
|           "group flex gap-x-3 rounded-md py-2 pl-2 pr-3 text-sm leading-6 font-semibold" |           "group flex gap-x-3 rounded-md py-2 pl-2 pr-3 text-sm font-semibold" | ||||||
|         )}> |         )}> | ||||||
|         <item.icon |         <item.icon | ||||||
|           className={classNames( |           className={classNames( | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ dayjs.extend(relativeTime) | |||||||
| export const ModelsBody = () => { | export const ModelsBody = () => { | ||||||
|   const queryClient = useQueryClient() |   const queryClient = useQueryClient() | ||||||
|   const [open, setOpen] = useState(false) |   const [open, setOpen] = useState(false) | ||||||
|   const { t } = useTranslation("option") |   const { t } = useTranslation(["option", "common"]) | ||||||
| 
 | 
 | ||||||
|   const form = useForm({ |   const form = useForm({ | ||||||
|     initialValues: { |     initialValues: { | ||||||
| @ -188,9 +188,13 @@ export const ModelsBody = () => { | |||||||
|                     } |                     } | ||||||
|                   ]} |                   ]} | ||||||
|                   dataSource={[record.details]} |                   dataSource={[record.details]} | ||||||
|  |                   locale={{ | ||||||
|  |                     emptyText: t("common:noData") | ||||||
|  |                   }} | ||||||
|                 /> |                 /> | ||||||
|               ), |               ), | ||||||
|               defaultExpandAllRows: false |               defaultExpandAllRows: false, | ||||||
|  |                | ||||||
|             }} |             }} | ||||||
|             bordered |             bordered | ||||||
|             dataSource={data} |             dataSource={data} | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { useQuery } from "@tanstack/react-query" | import { useQuery } from "@tanstack/react-query" | ||||||
| import { RotateCcw } from "lucide-react" | import { RotateCcw } from "lucide-react" | ||||||
| import { useEffect, useState } from "react" | import { useEffect, useState } from "react" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
| import { | import { | ||||||
|   getOllamaURL, |   getOllamaURL, | ||||||
|   isOllamaRunning, |   isOllamaRunning, | ||||||
| @ -9,6 +10,7 @@ import { | |||||||
| 
 | 
 | ||||||
| export const PlaygroundEmpty = () => { | export const PlaygroundEmpty = () => { | ||||||
|   const [ollamaURL, setOllamaURL] = useState<string>("") |   const [ollamaURL, setOllamaURL] = useState<string>("") | ||||||
|  |   const { t } = useTranslation(["playground", "common"]) | ||||||
|   const { |   const { | ||||||
|     data: ollamaInfo, |     data: ollamaInfo, | ||||||
|     status: ollamaStatus, |     status: ollamaStatus, | ||||||
| @ -40,7 +42,7 @@ export const PlaygroundEmpty = () => { | |||||||
|           <div className="inline-flex items-center space-x-2"> |           <div className="inline-flex items-center space-x-2"> | ||||||
|             <div className="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div> |             <div className="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div> | ||||||
|             <p className="dark:text-gray-400 text-gray-900"> |             <p className="dark:text-gray-400 text-gray-900"> | ||||||
|               Searching for Your Ollama 🦙 |               {t("ollamaState.searching")} | ||||||
|             </p> |             </p> | ||||||
|           </div> |           </div> | ||||||
|         )} |         )} | ||||||
| @ -49,7 +51,7 @@ export const PlaygroundEmpty = () => { | |||||||
|             <div className="inline-flex  items-center space-x-2"> |             <div className="inline-flex  items-center space-x-2"> | ||||||
|               <div className="w-3 h-3 bg-green-500 rounded-full"></div> |               <div className="w-3 h-3 bg-green-500 rounded-full"></div> | ||||||
|               <p className="dark:text-gray-400 text-gray-900"> |               <p className="dark:text-gray-400 text-gray-900"> | ||||||
|                 Ollama is running 🦙 |                 {t("ollamaState.running")} | ||||||
|               </p> |               </p> | ||||||
|             </div> |             </div> | ||||||
|           ) : ( |           ) : ( | ||||||
| @ -57,7 +59,7 @@ export const PlaygroundEmpty = () => { | |||||||
|               <div className="inline-flex  space-x-2"> |               <div className="inline-flex  space-x-2"> | ||||||
|                 <div className="w-3 h-3 bg-red-500 rounded-full"></div> |                 <div className="w-3 h-3 bg-red-500 rounded-full"></div> | ||||||
|                 <p className="dark:text-gray-400 text-gray-900"> |                 <p className="dark:text-gray-400 text-gray-900"> | ||||||
|                   Unable to connect to Ollama 🦙 |                   {t("ollamaState.notRunning")} | ||||||
|                 </p> |                 </p> | ||||||
|               </div> |               </div> | ||||||
| 
 | 
 | ||||||
| @ -75,7 +77,7 @@ export const PlaygroundEmpty = () => { | |||||||
|                 }} |                 }} | ||||||
|                 className="inline-flex mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> |                 className="inline-flex mt-4 items-center rounded-md border border-transparent bg-black px-2 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50 "> | ||||||
|                 <RotateCcw className="h-4 w-4 mr-3" /> |                 <RotateCcw className="h-4 w-4 mr-3" /> | ||||||
|                 Retry |                 {t("common:retry")} | ||||||
|               </button> |               </button> | ||||||
|             </div> |             </div> | ||||||
|           ) |           ) | ||||||
|  | |||||||
| @ -11,12 +11,14 @@ import { useWebUI } from "~/store/webui" | |||||||
| import { defaultEmbeddingModelForRag } from "~/services/ollama" | import { defaultEmbeddingModelForRag } from "~/services/ollama" | ||||||
| import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react" | import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react" | ||||||
| import { getVariable } from "~/utils/select-varaible" | import { getVariable } from "~/utils/select-varaible" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
| 
 | 
 | ||||||
| type Props = { | type Props = { | ||||||
|   dropedFile: File | undefined |   dropedFile: File | undefined | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const PlaygroundForm = ({ dropedFile }: Props) => { | export const PlaygroundForm = ({ dropedFile }: Props) => { | ||||||
|  |   const { t } = useTranslation(["playground", "common"]) | ||||||
|   const inputRef = React.useRef<HTMLInputElement>(null) |   const inputRef = React.useRef<HTMLInputElement>(null) | ||||||
|   const [typing, setTyping] = React.useState<boolean>(false) |   const [typing, setTyping] = React.useState<boolean>(false) | ||||||
|   const { |   const { | ||||||
| @ -117,13 +119,13 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|   const handleKeyDown = (e: React.KeyboardEvent) => { |   const handleKeyDown = (e: React.KeyboardEvent) => { | ||||||
|     if (e.key === "Process" || e.key === "229" ) return |     if (e.key === "Process" || e.key === "229") return | ||||||
|     if ( |     if ( | ||||||
|       !typing && |       !typing && | ||||||
|       e.key === "Enter" && |       e.key === "Enter" && | ||||||
|       !e.shiftKey && |       !e.shiftKey && | ||||||
|       !isSending && |       !isSending && | ||||||
|       sendWhenEnter  |       sendWhenEnter | ||||||
|     ) { |     ) { | ||||||
|       e.preventDefault() |       e.preventDefault() | ||||||
|       form.onSubmit(async (value) => { |       form.onSubmit(async (value) => { | ||||||
| @ -131,16 +133,13 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|           return |           return | ||||||
|         } |         } | ||||||
|         if (!selectedModel || selectedModel.length === 0) { |         if (!selectedModel || selectedModel.length === 0) { | ||||||
|           form.setFieldError("message", "Please select a model") |           form.setFieldError("message", t("formError.noModel")) | ||||||
|           return |           return | ||||||
|         } |         } | ||||||
|         if (webSearch) { |         if (webSearch) { | ||||||
|           const defaultEM = await defaultEmbeddingModelForRag() |           const defaultEM = await defaultEmbeddingModelForRag() | ||||||
|           if (!defaultEM) { |           if (!defaultEM) { | ||||||
|             form.setFieldError( |             form.setFieldError("message", t("formError.noEmbeddingModel")) | ||||||
|               "message", |  | ||||||
|               "Please set an embedding model on the Settings > Ollama page" |  | ||||||
|             ) |  | ||||||
|             return |             return | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -181,16 +180,13 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|           <form |           <form | ||||||
|             onSubmit={form.onSubmit(async (value) => { |             onSubmit={form.onSubmit(async (value) => { | ||||||
|               if (!selectedModel || selectedModel.length === 0) { |               if (!selectedModel || selectedModel.length === 0) { | ||||||
|                 form.setFieldError("message", "Please select a model") |                 form.setFieldError("message", t("formError.noModel")) | ||||||
|                 return |                 return | ||||||
|               } |               } | ||||||
|               if (webSearch) { |               if (webSearch) { | ||||||
|                 const defaultEM = await defaultEmbeddingModelForRag() |                 const defaultEM = await defaultEmbeddingModelForRag() | ||||||
|                 if (!defaultEM) { |                 if (!defaultEM) { | ||||||
|                   form.setFieldError( |                   form.setFieldError("message", t("formError.noEmbeddingModel")) | ||||||
|                     "message", |  | ||||||
|                     "Please set an embedding model on the Settings > Ollama page" |  | ||||||
|                   ) |  | ||||||
|                   return |                   return | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
| @ -223,12 +219,12 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|                 rows={1} |                 rows={1} | ||||||
|                 style={{ minHeight: "60px" }} |                 style={{ minHeight: "60px" }} | ||||||
|                 tabIndex={0} |                 tabIndex={0} | ||||||
|                 placeholder="Type a message..." |                 placeholder={t("form.textarea.placeholder")} | ||||||
|                 {...form.getInputProps("message")} |                 {...form.getInputProps("message")} | ||||||
|               /> |               /> | ||||||
|               <div className="mt-4 flex justify-between items-center"> |               <div className="mt-4 flex justify-between items-center"> | ||||||
|                 <div className="flex"> |                 <div className="flex"> | ||||||
|                   <Tooltip title="Search Internet"> |                   <Tooltip title={t("tooltip.searchInternet")}> | ||||||
|                     <div className="inline-flex items-center gap-2"> |                     <div className="inline-flex items-center gap-2"> | ||||||
|                       <svg |                       <svg | ||||||
|                         xmlns="http://www.w3.org/2000/svg" |                         xmlns="http://www.w3.org/2000/svg" | ||||||
| @ -246,14 +242,14 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|                       <Switch |                       <Switch | ||||||
|                         value={webSearch} |                         value={webSearch} | ||||||
|                         onChange={(e) => setWebSearch(e)} |                         onChange={(e) => setWebSearch(e)} | ||||||
|                         checkedChildren="On" |                         checkedChildren={t("form.webSearch.on")} | ||||||
|                         unCheckedChildren="Off" |                         unCheckedChildren={t("form.webSearch.off")} | ||||||
|                       /> |                       /> | ||||||
|                     </div> |                     </div> | ||||||
|                   </Tooltip> |                   </Tooltip> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div className="flex !justify-end gap-3"> |                 <div className="flex !justify-end gap-3"> | ||||||
|                   <Tooltip title="Voice Message"> |                   <Tooltip title={t("tooltip.speechToText")}> | ||||||
|                     <button |                     <button | ||||||
|                       type="button" |                       type="button" | ||||||
|                       onClick={() => { |                       onClick={() => { | ||||||
| @ -277,7 +273,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|                       )} |                       )} | ||||||
|                     </button> |                     </button> | ||||||
|                   </Tooltip> |                   </Tooltip> | ||||||
|                   <Tooltip title="Upload Image"> |                   <Tooltip title={t("tooltip.uploadImage")}> | ||||||
|                     <button |                     <button | ||||||
|                       type="button" |                       type="button" | ||||||
|                       onClick={() => { |                       onClick={() => { | ||||||
| @ -319,7 +315,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|                                 onChange={(e) => |                                 onChange={(e) => | ||||||
|                                   setSendWhenEnter(e.target.checked) |                                   setSendWhenEnter(e.target.checked) | ||||||
|                                 }> |                                 }> | ||||||
|                                 Send when Enter pressed |                                 {t("sendWhenEnter")} | ||||||
|                               </Checkbox> |                               </Checkbox> | ||||||
|                             ) |                             ) | ||||||
|                           } |                           } | ||||||
| @ -340,11 +336,11 @@ export const PlaygroundForm = ({ dropedFile }: Props) => { | |||||||
|                             <path d="M20 4v7a4 4 0 01-4 4H4"></path> |                             <path d="M20 4v7a4 4 0 01-4 4H4"></path> | ||||||
|                           </svg> |                           </svg> | ||||||
|                         ) : null} |                         ) : null} | ||||||
|                         Submit |                         {t("common:submit")} | ||||||
|                       </div> |                       </div> | ||||||
|                     </Dropdown.Button> |                     </Dropdown.Button> | ||||||
|                   ) : ( |                   ) : ( | ||||||
|                     <Tooltip title="Stop Streaming"> |                     <Tooltip title={t("tooltip.stopStreaming")}> | ||||||
|                       <button |                       <button | ||||||
|                         type="button" |                         type="button" | ||||||
|                         onClick={stopStreamingRequest} |                         onClick={stopStreamingRequest} | ||||||
|  | |||||||
| @ -7,7 +7,8 @@ import { | |||||||
|   Modal, |   Modal, | ||||||
|   Input, |   Input, | ||||||
|   Form, |   Form, | ||||||
|   Switch |   Switch, | ||||||
|  |   Empty | ||||||
| } from "antd" | } from "antd" | ||||||
| import { Trash2, Pen, Computer, Zap } from "lucide-react" | import { Trash2, Pen, Computer, Zap } from "lucide-react" | ||||||
| import { useState } from "react" | import { useState } from "react" | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ import { SUPPORTED_LANGUAGES } from "~/utils/supporetd-languages" | |||||||
| import { MoonIcon, SunIcon } from "lucide-react" | import { MoonIcon, SunIcon } from "lucide-react" | ||||||
| import { SearchModeSettings } from "./search-mode" | import { SearchModeSettings } from "./search-mode" | ||||||
| import { useTranslation } from "react-i18next" | import { useTranslation } from "react-i18next" | ||||||
|  | import { useI18n } from "@/hooks/useI18n" | ||||||
| 
 | 
 | ||||||
| export const SettingOther = () => { | export const SettingOther = () => { | ||||||
|   const { clearChat, speechToTextLanguage, setSpeechToTextLanguage } = |   const { clearChat, speechToTextLanguage, setSpeechToTextLanguage } = | ||||||
| @ -16,6 +17,11 @@ export const SettingOther = () => { | |||||||
| 
 | 
 | ||||||
|   const { mode, toggleDarkMode } = useDarkMode() |   const { mode, toggleDarkMode } = useDarkMode() | ||||||
|   const { t } = useTranslation("option") |   const { t } = useTranslation("option") | ||||||
|  |   const { | ||||||
|  |     changeLocale, | ||||||
|  |     locale, | ||||||
|  |     supportLanguage | ||||||
|  |   }= useI18n() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
| @ -46,6 +52,26 @@ export const SettingOther = () => { | |||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|       </div> |       </div> | ||||||
|  |       <div className="flex flex-row justify-between"> | ||||||
|  |         <span className="text-gray-500   dark:text-neutral-50"> | ||||||
|  |           {t("generalSettings.settings.language.label")} | ||||||
|  |         </span> | ||||||
|  | 
 | ||||||
|  |         <Select | ||||||
|  |           placeholder={t("generalSettings.settings.language.placeholder")} | ||||||
|  |           allowClear | ||||||
|  |           showSearch | ||||||
|  |           options={supportLanguage} | ||||||
|  |           value={locale} | ||||||
|  |           filterOption={(input, option) => | ||||||
|  |             option!.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 || | ||||||
|  |             option!.value.toLowerCase().indexOf(input.toLowerCase()) >= 0 | ||||||
|  |           } | ||||||
|  |           onChange={(value) => { | ||||||
|  |             changeLocale(value) | ||||||
|  |           }} | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|       <div className="flex flex-row justify-between"> |       <div className="flex flex-row justify-between"> | ||||||
|         <span className="text-gray-500 dark:text-neutral-50 "> |         <span className="text-gray-500 dark:text-neutral-50 "> | ||||||
|           {t("generalSettings.settings.darkMode.label")} |           {t("generalSettings.settings.darkMode.label")} | ||||||
|  | |||||||
| @ -8,9 +8,9 @@ import { | |||||||
| } from "~/libs/db" | } from "~/libs/db" | ||||||
| import { Empty, Skeleton } from "antd" | import { Empty, Skeleton } from "antd" | ||||||
| import { useMessageOption } from "~/hooks/useMessageOption" | import { useMessageOption } from "~/hooks/useMessageOption" | ||||||
| import { useState } from "react" |  | ||||||
| import { PencilIcon, Trash2 } from "lucide-react" | import { PencilIcon, Trash2 } from "lucide-react" | ||||||
| import { useNavigate } from "react-router-dom" | import { useNavigate } from "react-router-dom" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
| 
 | 
 | ||||||
| type Props = { | type Props = { | ||||||
|   onClose: () => void |   onClose: () => void | ||||||
| @ -19,6 +19,7 @@ type Props = { | |||||||
| export const Sidebar = ({ onClose }: Props) => { | export const Sidebar = ({ onClose }: Props) => { | ||||||
|   const { setMessages, setHistory, setHistoryId, historyId, clearChat } = |   const { setMessages, setHistory, setHistoryId, historyId, clearChat } = | ||||||
|     useMessageOption() |     useMessageOption() | ||||||
|  |   const { t } = useTranslation(["option", "common"]) | ||||||
|   const client = useQueryClient() |   const client = useQueryClient() | ||||||
|   const navigate = useNavigate() |   const navigate = useNavigate() | ||||||
| 
 | 
 | ||||||
| @ -60,7 +61,7 @@ export const Sidebar = ({ onClose }: Props) => { | |||||||
|     <div className="overflow-y-auto z-99"> |     <div className="overflow-y-auto z-99"> | ||||||
|       {status === "success" && chatHistories.length === 0 && ( |       {status === "success" && chatHistories.length === 0 && ( | ||||||
|         <div className="flex justify-center items-center mt-20 overflow-hidden"> |         <div className="flex justify-center items-center mt-20 overflow-hidden"> | ||||||
|           <Empty description="No history yet" /> |           <Empty description={t("common:noHistory")} /> | ||||||
|         </div> |         </div> | ||||||
|       )} |       )} | ||||||
|       {status === "pending" && ( |       {status === "pending" && ( | ||||||
| @ -95,7 +96,7 @@ export const Sidebar = ({ onClose }: Props) => { | |||||||
|               <div className="flex flex-row gap-3"> |               <div className="flex flex-row gap-3"> | ||||||
|                 <button |                 <button | ||||||
|                   onClick={() => { |                   onClick={() => { | ||||||
|                     const newTitle = prompt("Enter new title", chat.title) |                     const newTitle = prompt(t("editHistoryTitle"), chat.title) | ||||||
| 
 | 
 | ||||||
|                     if (newTitle) { |                     if (newTitle) { | ||||||
|                       editHistory({ id: chat.id, title: newTitle }) |                       editHistory({ id: chat.id, title: newTitle }) | ||||||
| @ -107,10 +108,7 @@ export const Sidebar = ({ onClose }: Props) => { | |||||||
| 
 | 
 | ||||||
|                 <button |                 <button | ||||||
|                   onClick={() => { |                   onClick={() => { | ||||||
|                     if ( |                     if (!confirm(t("deleteHistoryConfirmation"))) return | ||||||
|                       !confirm("Are you sure you want to delete this history?") |  | ||||||
|                     ) |  | ||||||
|                       return |  | ||||||
|                     deleteHistory(chat.id) |                     deleteHistory(chat.id) | ||||||
|                   }} |                   }} | ||||||
|                   className="text-red-500 dark:text-red-400 opacity-80"> |                   className="text-red-500 dark:text-red-400 opacity-80"> | ||||||
|  | |||||||
| @ -86,26 +86,27 @@ export default defineBackground({ | |||||||
|         }) |         }) | ||||||
|       } else if (message.type === "pull_model") { |       } else if (message.type === "pull_model") { | ||||||
|         const ollamaURL = await getOllamaURL() |         const ollamaURL = await getOllamaURL() | ||||||
|    | 
 | ||||||
|         const isRunning = await isOllamaRunning() |         const isRunning = await isOllamaRunning() | ||||||
|    | 
 | ||||||
|         if (!isRunning) { |         if (!isRunning) { | ||||||
|           chrome.action.setBadgeText({ text: "E" }) |           chrome.action.setBadgeText({ text: "E" }) | ||||||
|           chrome.action.setBadgeBackgroundColor({ color: "#FF0000" }) |           chrome.action.setBadgeBackgroundColor({ color: "#FF0000" }) | ||||||
|           chrome.action.setTitle({ title: "Ollama is not running" }) |           chrome.action.setTitle({ title: "Ollama is not running" | ||||||
|  |          }) | ||||||
|           setTimeout(() => { |           setTimeout(() => { | ||||||
|             clearBadge() |             clearBadge() | ||||||
|           }, 5000) |           }, 5000) | ||||||
|         } |         } | ||||||
|    | 
 | ||||||
|         await streamDownload(ollamaURL, message.modelName) |         await streamDownload(ollamaURL, message.modelName) | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|    | 
 | ||||||
|     chrome.action.onClicked.addListener((tab) => { |     chrome.action.onClicked.addListener((tab) => { | ||||||
|       chrome.tabs.create({ url: chrome.runtime.getURL("options.html") }) |       chrome.tabs.create({ url: chrome.runtime.getURL("options.html") }) | ||||||
|     }) |     }) | ||||||
|    | 
 | ||||||
|     chrome.commands.onCommand.addListener((command) => { |     chrome.commands.onCommand.addListener((command) => { | ||||||
|       switch (command) { |       switch (command) { | ||||||
|         case "execute_side_panel": |         case "execute_side_panel": | ||||||
| @ -120,13 +121,13 @@ export default defineBackground({ | |||||||
|           break |           break | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|    | 
 | ||||||
|     chrome.contextMenus.create({ |     chrome.contextMenus.create({ | ||||||
|       id: "open-side-panel-pa", |       id: "open-side-panel-pa", | ||||||
|       title: "Open Side Panel to Chat", |       title: browser.i18n.getMessage("openSidePanelToChat"), | ||||||
|       contexts: ["all"] |       contexts: ["all"] | ||||||
|     }) |     }) | ||||||
|    | 
 | ||||||
|     chrome.contextMenus.onClicked.addListener((info, tab) => { |     chrome.contextMenus.onClicked.addListener((info, tab) => { | ||||||
|       if (info.menuItemId === "open-side-panel-pa") { |       if (info.menuItemId === "open-side-panel-pa") { | ||||||
|         chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => { |         chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => { | ||||||
|  | |||||||
| @ -3,21 +3,32 @@ import { MemoryRouter } from "react-router-dom" | |||||||
| import { ToastContainer } from "react-toastify" | import { ToastContainer } from "react-toastify" | ||||||
| import "react-toastify/dist/ReactToastify.css" | import "react-toastify/dist/ReactToastify.css" | ||||||
| const queryClient = new QueryClient() | const queryClient = new QueryClient() | ||||||
| import { ConfigProvider, theme } from "antd" | import { ConfigProvider, Empty, theme } from "antd" | ||||||
| import { StyleProvider } from "@ant-design/cssinjs" | import { StyleProvider } from "@ant-design/cssinjs" | ||||||
| import { useDarkMode } from "~/hooks/useDarkmode" | import { useDarkMode } from "~/hooks/useDarkmode" | ||||||
| import { OptionRouting } from "~/routes" | import { OptionRouting } from "~/routes" | ||||||
| import "~/i18n" | import "~/i18n" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
| 
 | 
 | ||||||
| function IndexOption() { | function IndexOption() { | ||||||
|   const { mode } = useDarkMode() |   const { mode } = useDarkMode() | ||||||
|  |   const { t } = useTranslation() | ||||||
|   return ( |   return ( | ||||||
|     <MemoryRouter> |     <MemoryRouter> | ||||||
|       <ConfigProvider |       <ConfigProvider | ||||||
|         theme={{ |         theme={{ | ||||||
|           algorithm: |           algorithm: | ||||||
|             mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm |             mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm | ||||||
|         }}> |         }} | ||||||
|  |         renderEmpty={() => ( | ||||||
|  |           <Empty | ||||||
|  |             imageStyle={{ | ||||||
|  |               height: 60 | ||||||
|  |             }} | ||||||
|  |             description={t("common:noData")} | ||||||
|  |           /> | ||||||
|  |         )} | ||||||
|  |         > | ||||||
|         <StyleProvider hashPriority="high"> |         <StyleProvider hashPriority="high"> | ||||||
|           <QueryClientProvider client={queryClient}> |           <QueryClientProvider client={queryClient}> | ||||||
|             <OptionRouting /> |             <OptionRouting /> | ||||||
|  | |||||||
| @ -4,13 +4,15 @@ import { SidepanelRouting } from "~/routes" | |||||||
| import { ToastContainer } from "react-toastify" | import { ToastContainer } from "react-toastify" | ||||||
| import "react-toastify/dist/ReactToastify.css" | import "react-toastify/dist/ReactToastify.css" | ||||||
| const queryClient = new QueryClient() | const queryClient = new QueryClient() | ||||||
| import { ConfigProvider, theme } from "antd" | import { ConfigProvider, Empty, theme } from "antd" | ||||||
| import { StyleProvider } from "@ant-design/cssinjs" | import { StyleProvider } from "@ant-design/cssinjs" | ||||||
| import { useDarkMode } from "~/hooks/useDarkmode" | import { useDarkMode } from "~/hooks/useDarkmode" | ||||||
| import "~/i18n" | import "~/i18n" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
| 
 | 
 | ||||||
| function IndexSidepanel() { | function IndexSidepanel() { | ||||||
|   const { mode } = useDarkMode() |   const { mode } = useDarkMode() | ||||||
|  |   const { t } = useTranslation() | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <MemoryRouter> |     <MemoryRouter> | ||||||
| @ -18,7 +20,16 @@ function IndexSidepanel() { | |||||||
|         theme={{ |         theme={{ | ||||||
|           algorithm: |           algorithm: | ||||||
|             mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm |             mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm | ||||||
|         }}> |         }} | ||||||
|  |         renderEmpty={() => ( | ||||||
|  |           <Empty | ||||||
|  |             imageStyle={{ | ||||||
|  |               height: 60 | ||||||
|  |             }} | ||||||
|  |             description={t("common:noData")} | ||||||
|  |           /> | ||||||
|  |         )} | ||||||
|  |         > | ||||||
|         <StyleProvider hashPriority="high"> |         <StyleProvider hashPriority="high"> | ||||||
|           <QueryClientProvider client={queryClient}> |           <QueryClientProvider client={queryClient}> | ||||||
|             <SidepanelRouting /> |             <SidepanelRouting /> | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								src/hooks/useI18n.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/hooks/useI18n.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | import { supportLanguage } from "@/i18n/support-language" | ||||||
|  | import { useState } from "react" | ||||||
|  | import { useTranslation } from "react-i18next" | ||||||
|  | 
 | ||||||
|  | export const useI18n = () => { | ||||||
|  |   const { i18n } = useTranslation() | ||||||
|  |   const [locale, setLocale] = useState<string>( | ||||||
|  |     localStorage.getItem("i18nextLng") || "en" | ||||||
|  |   ) | ||||||
|  | 
 | ||||||
|  |   const changeLocale = (lang: string) => { | ||||||
|  |     setLocale(lang) | ||||||
|  |     i18n.changeLanguage(lang) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return { locale, changeLocale, supportLanguage } | ||||||
|  | } | ||||||
| @ -2,6 +2,7 @@ import i18n from "i18next"; | |||||||
| import LanguageDetector from "i18next-browser-languagedetector"; | import LanguageDetector from "i18next-browser-languagedetector"; | ||||||
| import { initReactI18next } from "react-i18next"; | import { initReactI18next } from "react-i18next"; | ||||||
| import { en } from "./lang/en"; | import { en } from "./lang/en"; | ||||||
|  | import { ml } from "./lang/ml"; | ||||||
| 
 | 
 | ||||||
| i18n | i18n | ||||||
|     .use(LanguageDetector) |     .use(LanguageDetector) | ||||||
| @ -9,7 +10,8 @@ i18n | |||||||
|     .init({ |     .init({ | ||||||
|         debug: true, |         debug: true, | ||||||
|         resources: { |         resources: { | ||||||
|             en: en |             en: en, | ||||||
|  |             ml: ml | ||||||
|         }, |         }, | ||||||
|         fallbackLng: "en", |         fallbackLng: "en", | ||||||
|         lng: localStorage.getItem("i18nextLng") || "en", |         lng: localStorage.getItem("i18nextLng") || "en", | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| import option from "@/assets/locale/en/option.json"; | import option from "@/assets/locale/en/option.json"; | ||||||
| import optionPlayground from "@/assets/locale/en/option-playground.json"; | import playground from "@/assets/locale/en/playground.json"; | ||||||
| import common from "@/assets/locale/en/common.json"; | import common from "@/assets/locale/en/common.json"; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const en = { | export const en = { | ||||||
|     option, |     option, | ||||||
|     optionPlayground, |     playground, | ||||||
|     common |     common | ||||||
| } | } | ||||||
							
								
								
									
										10
									
								
								src/i18n/lang/ml.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/i18n/lang/ml.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | import option from "@/assets/locale/ml/option.json"; | ||||||
|  | import playground from "@/assets/locale/ml/playground.json"; | ||||||
|  | import common from "@/assets/locale/ml/common.json"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export const ml = { | ||||||
|  |     option, | ||||||
|  |     playground, | ||||||
|  |     common | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								src/i18n/support-language.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/i18n/support-language.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | // Please add new language code to supportLanguage array
 | ||||||
|  | export const supportLanguage = [ | ||||||
|  |     { | ||||||
|  |         label: "English", | ||||||
|  |         value: "en" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         label: "മലയാളം", | ||||||
|  |         value: "ml" | ||||||
|  |     } | ||||||
|  | ] | ||||||
| @ -4,5 +4,8 @@ | |||||||
|     }, |     }, | ||||||
|     "extDescription": { |     "extDescription": { | ||||||
|         "message": "Use your locally running AI models to assist you in your web browsing." |         "message": "Use your locally running AI models to assist you in your web browsing." | ||||||
|  |     }, | ||||||
|  |     "openSidePanelToChat": { | ||||||
|  |         "message": "Open Side Panel to Chat" | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										11
									
								
								src/public/_locales/ml/messages.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/public/_locales/ml/messages.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  |     "extName": { | ||||||
|  |         "message": "പേജ് അസിസ്റ്റ് - പ്രാദേശികമായി പ്രവര്ത്തിക്കുന്ന AI മോഡലുകള്ക്കുള്ള വെബ് UI" | ||||||
|  |     }, | ||||||
|  |     "extDescription": { | ||||||
|  |         "message": "നിങ്ങളുടെ പ്രാദേശികമായി പ്രവര്ത്തിക്കുന്ന AI മോഡലുകള് വെബ് ബ്രൗസിംഗില് നിങ്ങളെ സഹായിക്കുന്നതിന് ഉപയോഗിക്കുക." | ||||||
|  |     }, | ||||||
|  |     "openSidePanelToChat": { | ||||||
|  |         "message": "ചാറ്റ് ചെയ്യാന് സൈഡ് പാനല് തുറക്കുക" | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user