mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
Add a dropdown list in setting to allow change language. (#726)
* init localization * Update defaul to en * Fix merge issue and import path. * Set default to en * Change jsx to tsx * Update the password max length string. * Remove languageContext as using the recoil instead. * Add localization to component endpoints pages * Revert default to en after testing. * Update LoginForm.tsx * Fix translation. * Make lint happy * Merge (#1) * Create deploy.yml * Add localization support for endpoint pages components (#667) * init localization * Update defaul to en * Fix merge issue and import path. * Set default to en * Change jsx to tsx * Update the password max length string. * Remove languageContext as using the recoil instead. * Add localization to component endpoints pages * Revert default to en after testing. * Update LoginForm.tsx * Fix translation. * Make lint happy * Add a restart to melisearch in docker-compose.yml (#684) * Oauth fixes for Cognito (#686) * Add a restart to melisearch in docker-compose.yml * Oauth fixes for Cognito * Use the username or email for full name from oath if not provided --------- Co-authored-by: Donavan <snark@hey.com> * Italian localization support for endpoint (#687) --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> Co-authored-by: Donavan Stanley <donavan.stanley@gmail.com> Co-authored-by: Donavan <snark@hey.com> Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com> * Translate Nav pages * Fix npm test * Add setting dropdown to change the language * Fix unit test * Use useRecoilState --------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com> Co-authored-by: Donavan Stanley <donavan.stanley@gmail.com> Co-authored-by: Donavan <snark@hey.com> Co-authored-by: Marco Beretta <81851188+Berry-13@users.noreply.github.com>
This commit is contained in:
parent
41ed33e792
commit
2faeebfae2
14 changed files with 314 additions and 242 deletions
File diff suppressed because one or more lines are too long
|
|
@ -1,97 +1,89 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Dr. Thoth's Tarot",
|
"name_for_human": "Dr. Thoth's Tarot",
|
||||||
"name_for_model": "Dr_Thoths_Tarot",
|
"name_for_model": "Dr_Thoths_Tarot",
|
||||||
"description_for_human": "Tarot card novelty entertainment & analysis, by Mnemosyne Labs.",
|
"description_for_human": "Tarot card novelty entertainment & analysis, by Mnemosyne Labs.",
|
||||||
"description_for_model": "Intelligent analysis program for tarot card entertaiment, data, & prompts, by Mnemosyne Labs, a division of AzothCorp.",
|
"description_for_model": "Intelligent analysis program for tarot card entertaiment, data, & prompts, by Mnemosyne Labs, a division of AzothCorp.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
|
},
|
||||||
|
"api": {
|
||||||
|
"type": "openapi",
|
||||||
|
"url": "https://dr-thoth-tarot.herokuapp.com/openapi.yaml",
|
||||||
|
"is_user_authenticated": false
|
||||||
|
},
|
||||||
|
"logo_url": "https://dr-thoth-tarot.herokuapp.com/logo.png",
|
||||||
|
"contact_email": "legal@AzothCorp.com",
|
||||||
|
"legal_info_url": "http://AzothCorp.com/legal",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"name": "Draw Card",
|
||||||
|
"path": "/drawcard",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Generate a single tarot card from the deck of 78 cards."
|
||||||
},
|
},
|
||||||
"api": {
|
{
|
||||||
"type": "openapi",
|
"name": "Occult Card",
|
||||||
"url": "https://dr-thoth-tarot.herokuapp.com/openapi.yaml",
|
"path": "/occult_card",
|
||||||
"is_user_authenticated": false
|
"method": "GET",
|
||||||
},
|
"description": "Generate a tarot card using the specified planet's Kamea matrix.",
|
||||||
"logo_url": "https://dr-thoth-tarot.herokuapp.com/logo.png",
|
"parameters": [
|
||||||
"contact_email": "legal@AzothCorp.com",
|
|
||||||
"legal_info_url": "http://AzothCorp.com/legal",
|
|
||||||
"endpoints": [
|
|
||||||
{
|
{
|
||||||
"name": "Draw Card",
|
"name": "planet",
|
||||||
"path": "/drawcard",
|
"type": "string",
|
||||||
"method": "GET",
|
"enum": ["Saturn", "Jupiter", "Mars", "Sun", "Venus", "Mercury", "Moon"],
|
||||||
"description": "Generate a single tarot card from the deck of 78 cards."
|
"required": true,
|
||||||
},
|
"description": "The planet name to use the corresponding Kamea matrix."
|
||||||
{
|
|
||||||
"name": "Occult Card",
|
|
||||||
"path": "/occult_card",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Generate a tarot card using the specified planet's Kamea matrix.",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "planet",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"Saturn",
|
|
||||||
"Jupiter",
|
|
||||||
"Mars",
|
|
||||||
"Sun",
|
|
||||||
"Venus",
|
|
||||||
"Mercury",
|
|
||||||
"Moon"
|
|
||||||
],
|
|
||||||
"required": true,
|
|
||||||
"description": "The planet name to use the corresponding Kamea matrix."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Three Card Spread",
|
|
||||||
"path": "/threecardspread",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a three-card tarot spread."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Celtic Cross Spread",
|
|
||||||
"path": "/celticcross",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Celtic Cross tarot spread with 10 cards."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Past, Present, Future Spread",
|
|
||||||
"path": "/pastpresentfuture",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Past, Present, Future tarot spread with 3 cards."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Horseshoe Spread",
|
|
||||||
"path": "/horseshoe",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Horseshoe tarot spread with 7 cards."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Relationship Spread",
|
|
||||||
"path": "/relationship",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Relationship tarot spread."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Career Spread",
|
|
||||||
"path": "/career",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Career tarot spread."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Yes/No Spread",
|
|
||||||
"path": "/yesno",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Yes/No tarot spread."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Chakra Spread",
|
|
||||||
"path": "/chakra",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Perform a Chakra tarot spread with 7 cards."
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Three Card Spread",
|
||||||
|
"path": "/threecardspread",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a three-card tarot spread."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Celtic Cross Spread",
|
||||||
|
"path": "/celticcross",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Celtic Cross tarot spread with 10 cards."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Past, Present, Future Spread",
|
||||||
|
"path": "/pastpresentfuture",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Past, Present, Future tarot spread with 3 cards."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Horseshoe Spread",
|
||||||
|
"path": "/horseshoe",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Horseshoe tarot spread with 7 cards."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Relationship Spread",
|
||||||
|
"path": "/relationship",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Relationship tarot spread."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Career Spread",
|
||||||
|
"path": "/career",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Career tarot spread."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Yes/No Spread",
|
||||||
|
"path": "/yesno",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Yes/No tarot spread."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Chakra Spread",
|
||||||
|
"path": "/chakra",
|
||||||
|
"method": "GET",
|
||||||
|
"description": "Perform a Chakra tarot spread with 7 cards."
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_model": "DreamInterpreter",
|
"name_for_model": "DreamInterpreter",
|
||||||
"name_for_human": "Dream Interpreter",
|
"name_for_human": "Dream Interpreter",
|
||||||
"description_for_model": "Interprets your dreams using advanced techniques.",
|
"description_for_model": "Interprets your dreams using advanced techniques.",
|
||||||
"description_for_human": "Interprets your dreams using advanced techniques.",
|
"description_for_human": "Interprets your dreams using advanced techniques.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://dreamplugin.bgnetmobile.com/.well-known/openapi.json",
|
"url": "https://dreamplugin.bgnetmobile.com/.well-known/openapi.json",
|
||||||
"has_user_authentication": false
|
"has_user_authentication": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://dreamplugin.bgnetmobile.com/.well-known/logo.png",
|
"logo_url": "https://dreamplugin.bgnetmobile.com/.well-known/logo.png",
|
||||||
"contact_email": "ismail.orkler@bgnetmobile.com",
|
"contact_email": "ismail.orkler@bgnetmobile.com",
|
||||||
"legal_info_url": "https://dreamplugin.bgnetmobile.com/terms.html"
|
"legal_info_url": "https://dreamplugin.bgnetmobile.com/terms.html"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Ai Tool Hunt",
|
"name_for_human": "Ai Tool Hunt",
|
||||||
"name_for_model": "aitoolhunt",
|
"name_for_model": "aitoolhunt",
|
||||||
"description_for_human": "Find the perfect AI tools for all your needs, drawn from the most comprehensive global database of AI tools.",
|
"description_for_human": "Find the perfect AI tools for all your needs, drawn from the most comprehensive global database of AI tools.",
|
||||||
"description_for_model": "This universal plugin is designed to identify and suggest AI tools for any imaginable task or challenge. It harnesses a database of over 1600+ AI tools and 120+ categories, ensuring a solution for every requirement. Simply input any task, problem, or use case, and the plugin will generate a tailored list of AI tools. Note: it's crucial to rearrange the tools suggested by the plugin based on their relevance to the user's specific use case. This plugin can tackle everything from the simplest to the most intricate tasks. If there's a way an AI tool can help, this plugin will not only locate it but also customize the list to the user's unique needs. Utilize this plugin whenever a task or activity emerges, regardless of its context or complexity. When formulating a search query, avoid stop words or other irrelevant keywords. For instance, 'copywriting' is acceptable, but 'ai for copywriting' is not. If you believe none of the suggested tools are a suitable match for the user's needs, indicate that these are related tools.",
|
"description_for_model": "This universal plugin is designed to identify and suggest AI tools for any imaginable task or challenge. It harnesses a database of over 1600+ AI tools and 120+ categories, ensuring a solution for every requirement. Simply input any task, problem, or use case, and the plugin will generate a tailored list of AI tools. Note: it's crucial to rearrange the tools suggested by the plugin based on their relevance to the user's specific use case. This plugin can tackle everything from the simplest to the most intricate tasks. If there's a way an AI tool can help, this plugin will not only locate it but also customize the list to the user's unique needs. Utilize this plugin whenever a task or activity emerges, regardless of its context or complexity. When formulating a search query, avoid stop words or other irrelevant keywords. For instance, 'copywriting' is acceptable, but 'ai for copywriting' is not. If you believe none of the suggested tools are a suitable match for the user's needs, indicate that these are related tools.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "service_http",
|
"type": "service_http",
|
||||||
"authorization_type": "bearer",
|
"authorization_type": "bearer",
|
||||||
"verification_tokens": {
|
"verification_tokens": {
|
||||||
"openai": "06a0f9391a5e48c7a7eeaca1e7e1e8d3"
|
"openai": "06a0f9391a5e48c7a7eeaca1e7e1e8d3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://www.aitoolhunt.com/openapi.json",
|
"url": "https://www.aitoolhunt.com/openapi.json",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://www.aitoolhunt.com/images/aitoolhunt_logo.png",
|
"logo_url": "https://www.aitoolhunt.com/images/aitoolhunt_logo.png",
|
||||||
"contact_email": "aitoolhunt@gmail.com",
|
"contact_email": "aitoolhunt@gmail.com",
|
||||||
"legal_info_url": "https://www.aitoolhunt.com/terms-and-conditions"
|
"legal_info_url": "https://www.aitoolhunt.com/terms-and-conditions"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Drink Maestro",
|
"name_for_human": "Drink Maestro",
|
||||||
"name_for_model": "drink_maestro",
|
"name_for_model": "drink_maestro",
|
||||||
"description_for_human": "Learn to mix any drink you can imagine (real or made-up), and discover new ones. Includes drink images.",
|
"description_for_human": "Learn to mix any drink you can imagine (real or made-up), and discover new ones. Includes drink images.",
|
||||||
"description_for_model": "You are a silly bartender/comic who knows how to make any drink imaginable. You provide recipes for specific drinks, suggest new drinks, and show pictures of drinks. Be creative in your descriptions and make jokes and puns. Use a lot of emojis. If the user makes a request in another language, send API call in English, and then translate the response.",
|
"description_for_model": "You are a silly bartender/comic who knows how to make any drink imaginable. You provide recipes for specific drinks, suggest new drinks, and show pictures of drinks. Be creative in your descriptions and make jokes and puns. Use a lot of emojis. If the user makes a request in another language, send API call in English, and then translate the response.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://api.drinkmaestro.space/.well-known/openapi.yaml",
|
"url": "https://api.drinkmaestro.space/.well-known/openapi.yaml",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://i.imgur.com/6q8HWdz.png",
|
"logo_url": "https://i.imgur.com/6q8HWdz.png",
|
||||||
"contact_email": "nikkmitchell@gmail.com",
|
"contact_email": "nikkmitchell@gmail.com",
|
||||||
"legal_info_url": "https://github.com/nikkmitchell/DrinkMaestro/blob/main/Legal.txt"
|
"legal_info_url": "https://github.com/nikkmitchell/DrinkMaestro/blob/main/Legal.txt"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Earth",
|
"name_for_human": "Earth",
|
||||||
"name_for_model": "earthImagesAndVisualizations",
|
"name_for_model": "earthImagesAndVisualizations",
|
||||||
"description_for_human": "Generates a map image based on provided location, tilt and style.",
|
"description_for_human": "Generates a map image based on provided location, tilt and style.",
|
||||||
"description_for_model": "Generates a map image based on provided coordinates or location, tilt and style, and even geoJson to provide markers, paths, and polygons. Responds with an image-link. For the styles choose one of these: [light, dark, streets, outdoors, satellite, satellite-streets]",
|
"description_for_model": "Generates a map image based on provided coordinates or location, tilt and style, and even geoJson to provide markers, paths, and polygons. Responds with an image-link. For the styles choose one of these: [light, dark, streets, outdoors, satellite, satellite-streets]",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://api.earth-plugin.com/openapi.yaml",
|
"url": "https://api.earth-plugin.com/openapi.yaml",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://api.earth-plugin.com/logo.png",
|
"logo_url": "https://api.earth-plugin.com/logo.png",
|
||||||
"contact_email": "contact@earth-plugin.com",
|
"contact_email": "contact@earth-plugin.com",
|
||||||
"legal_info_url": "https://api.earth-plugin.com/legal.html"
|
"legal_info_url": "https://api.earth-plugin.com/legal.html"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Image Prompt Enhancer",
|
"name_for_human": "Image Prompt Enhancer",
|
||||||
"name_for_model": "image_prompt_enhancer",
|
"name_for_model": "image_prompt_enhancer",
|
||||||
"description_for_human": "Transform your ideas into complex, personalized image generation prompts.",
|
"description_for_human": "Transform your ideas into complex, personalized image generation prompts.",
|
||||||
"description_for_model": "Provides instructions for crafting an enhanced image prompt. Use this whenever the user wants to enhance a prompt.",
|
"description_for_model": "Provides instructions for crafting an enhanced image prompt. Use this whenever the user wants to enhance a prompt.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://image-prompt-enhancer.gafo.tech/openapi.yaml",
|
"url": "https://image-prompt-enhancer.gafo.tech/openapi.yaml",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://image-prompt-enhancer.gafo.tech/logo.png",
|
"logo_url": "https://image-prompt-enhancer.gafo.tech/logo.png",
|
||||||
"contact_email": "gafotech1@gmail.com",
|
"contact_email": "gafotech1@gmail.com",
|
||||||
"legal_info_url": "https://image-prompt-enhancer.gafo.tech/legal"
|
"legal_info_url": "https://image-prompt-enhancer.gafo.tech/legal"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "QR Codes",
|
"name_for_human": "QR Codes",
|
||||||
"name_for_model": "qrCodes",
|
"name_for_model": "qrCodes",
|
||||||
"description_for_human": "Create QR codes.",
|
"description_for_human": "Create QR codes.",
|
||||||
"description_for_model": "Plugin for generating QR codes.",
|
"description_for_model": "Plugin for generating QR codes.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://chatgpt-qrcode-46d7d4ebefc8.herokuapp.com/openapi.yaml"
|
"url": "https://chatgpt-qrcode-46d7d4ebefc8.herokuapp.com/openapi.yaml"
|
||||||
},
|
},
|
||||||
"logo_url": "https://chatgpt-qrcode-46d7d4ebefc8.herokuapp.com/logo.png",
|
"logo_url": "https://chatgpt-qrcode-46d7d4ebefc8.herokuapp.com/logo.png",
|
||||||
"contact_email": "chrismountzou@gmail.com",
|
"contact_email": "chrismountzou@gmail.com",
|
||||||
"legal_info_url": "https://raw.githubusercontent.com/mountzou/qrCodeGPTv1/master/legal"
|
"legal_info_url": "https://raw.githubusercontent.com/mountzou/qrCodeGPTv1/master/legal"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Uberchord",
|
"name_for_human": "Uberchord",
|
||||||
"name_for_model": "uberchord",
|
"name_for_model": "uberchord",
|
||||||
"description_for_human": "Find guitar chord diagrams by specifying the chord name.",
|
"description_for_human": "Find guitar chord diagrams by specifying the chord name.",
|
||||||
"description_for_model": "Fetch guitar chord diagrams, their positions on the guitar fretboard.",
|
"description_for_model": "Fetch guitar chord diagrams, their positions on the guitar fretboard.",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://guitarchords.pluginboost.com/.well-known/openapi.yaml",
|
"url": "https://guitarchords.pluginboost.com/.well-known/openapi.yaml",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://guitarchords.pluginboost.com/logo.png",
|
"logo_url": "https://guitarchords.pluginboost.com/logo.png",
|
||||||
"contact_email": "info.bluelightweb@gmail.com",
|
"contact_email": "info.bluelightweb@gmail.com",
|
||||||
"legal_info_url": "https://guitarchords.pluginboost.com/legal"
|
"legal_info_url": "https://guitarchords.pluginboost.com/legal"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"schema_version": "v1",
|
"schema_version": "v1",
|
||||||
"name_for_human": "Web Search",
|
"name_for_human": "Web Search",
|
||||||
"name_for_model": "web_search",
|
"name_for_model": "web_search",
|
||||||
"description_for_human": "Search for information from the internet",
|
"description_for_human": "Search for information from the internet",
|
||||||
"description_for_model": "Search for information from the internet",
|
"description_for_model": "Search for information from the internet",
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "none"
|
"type": "none"
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
"type": "openapi",
|
"type": "openapi",
|
||||||
"url": "https://websearch.plugsugar.com/api/openapi_yaml",
|
"url": "https://websearch.plugsugar.com/api/openapi_yaml",
|
||||||
"is_user_authenticated": false
|
"is_user_authenticated": false
|
||||||
},
|
},
|
||||||
"logo_url": "https://websearch.plugsugar.com/200x200.png",
|
"logo_url": "https://websearch.plugsugar.com/200x200.png",
|
||||||
"contact_email": "support@plugsugar.com",
|
"contact_email": "support@plugsugar.com",
|
||||||
"legal_info_url": "https://websearch.plugsugar.com/contact"
|
"legal_info_url": "https://websearch.plugsugar.com/contact"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { CheckIcon } from 'lucide-react';
|
||||||
import { ThemeContext } from '~/hooks/ThemeContext';
|
import { ThemeContext } from '~/hooks/ThemeContext';
|
||||||
import React, { useState, useContext, useEffect, useCallback } from 'react';
|
import React, { useState, useContext, useEffect, useCallback } from 'react';
|
||||||
import { useClearConversationsMutation } from 'librechat-data-provider';
|
import { useClearConversationsMutation } from 'librechat-data-provider';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue, useRecoilState } from 'recoil';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
import { localize } from '~/localization/Translation';
|
import { localize } from '~/localization/Translation';
|
||||||
|
|
||||||
|
|
@ -66,10 +66,38 @@ export const ClearChatsButton = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const LangSelector = ({
|
||||||
|
langcode,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
langcode: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}) => {
|
||||||
|
const lang = useRecoilValue(store.lang);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>{localize(lang, 'com_nav_language')}</div>
|
||||||
|
<select
|
||||||
|
className="w-24 rounded border border-black/10 bg-transparent text-sm dark:border-white/20 dark:bg-gray-900"
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
value={langcode}
|
||||||
|
>
|
||||||
|
<option value="en">{localize(lang, 'com_nav_lang_english')}</option>
|
||||||
|
<option value="cn">{localize(lang, 'com_nav_lang_chinese')}</option>
|
||||||
|
<option value="it">{localize(lang, 'com_nav_lang_italian')}</option>
|
||||||
|
<option value="br">{localize(lang, 'com_nav_lang_brazilian_portuguese')}</option>
|
||||||
|
<option value="es">{localize(lang, 'com_nav_lang_spanish')}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
function General() {
|
function General() {
|
||||||
const { theme, setTheme } = useContext(ThemeContext);
|
const { theme, setTheme } = useContext(ThemeContext);
|
||||||
const clearConvosMutation = useClearConversationsMutation();
|
const clearConvosMutation = useClearConversationsMutation();
|
||||||
const [confirmClear, setConfirmClear] = useState(false);
|
const [confirmClear, setConfirmClear] = useState(false);
|
||||||
|
const [langcode, setLangcode] = useRecoilState(store.lang);
|
||||||
const { newConversation } = store.useConversation();
|
const { newConversation } = store.useConversation();
|
||||||
const { refreshConversations } = store.useConversations();
|
const { refreshConversations } = store.useConversations();
|
||||||
|
|
||||||
|
|
@ -97,12 +125,22 @@ function General() {
|
||||||
[setTheme],
|
[setTheme],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const changeLang = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
setLangcode(value);
|
||||||
|
},
|
||||||
|
[setLangcode],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs.Content value="general" role="tabpanel" className="w-full md:min-h-[300px]">
|
<Tabs.Content value="general" role="tabpanel" className="w-full md:min-h-[300px]">
|
||||||
<div className="flex flex-col gap-3 text-sm text-gray-600 dark:text-gray-300">
|
<div className="flex flex-col gap-3 text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
||||||
<ThemeSelector theme={theme} onChange={changeTheme} />
|
<ThemeSelector theme={theme} onChange={changeTheme} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
||||||
|
<LangSelector langcode={langcode} onChange={changeLang} />
|
||||||
|
</div>
|
||||||
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
|
||||||
<ClearChatsButton confirmClear={confirmClear} onClick={clearConvos} showText={true} />
|
<ClearChatsButton confirmClear={confirmClear} onClick={clearConvos} showText={true} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
36
client/src/components/Nav/SettingsTabs/LangSelector.spec.tsx
Normal file
36
client/src/components/Nav/SettingsTabs/LangSelector.spec.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { render, fireEvent } from '@testing-library/react';
|
||||||
|
import '@testing-library/jest-dom/extend-expect';
|
||||||
|
import { LangSelector } from './General';
|
||||||
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
|
describe('LangSelector', () => {
|
||||||
|
let mockOnChange;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockOnChange = jest.fn();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders correctly', () => {
|
||||||
|
const { getByText, getByDisplayValue } = render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<LangSelector langcode="en" onChange={mockOnChange} />
|
||||||
|
</RecoilRoot>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(getByText('Language')).toBeInTheDocument();
|
||||||
|
expect(getByDisplayValue('English')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls onChange when the select value changes', () => {
|
||||||
|
const { getByDisplayValue } = render(
|
||||||
|
<RecoilRoot>
|
||||||
|
<LangSelector langcode="en" onChange={mockOnChange} />
|
||||||
|
</RecoilRoot>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.change(getByDisplayValue('English'), { target: { value: 'it' } });
|
||||||
|
|
||||||
|
expect(mockOnChange).toHaveBeenCalledWith('it');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -32,10 +32,10 @@ export const getTranslations = (langCode: string) => {
|
||||||
if (langCode === 'it') {
|
if (langCode === 'it') {
|
||||||
return Italy;
|
return Italy;
|
||||||
}
|
}
|
||||||
if (langCode === 'Br') {
|
if (langCode === 'br') {
|
||||||
return Portuguese;
|
return Portuguese;
|
||||||
}
|
}
|
||||||
if (langCode === 'Es') {
|
if (langCode === 'es') {
|
||||||
return Spanish;
|
return Spanish;
|
||||||
}
|
}
|
||||||
// === add conditionals here for additional languages here === //
|
// === add conditionals here for additional languages here === //
|
||||||
|
|
|
||||||
|
|
@ -183,4 +183,10 @@ export default {
|
||||||
com_nav_settings: 'Settings',
|
com_nav_settings: 'Settings',
|
||||||
com_nav_search_placeholder: 'Search messages',
|
com_nav_search_placeholder: 'Search messages',
|
||||||
com_nav_setting_general: 'General',
|
com_nav_setting_general: 'General',
|
||||||
|
com_nav_language: 'Language',
|
||||||
|
com_nav_lang_english: 'English',
|
||||||
|
com_nav_lang_chinese: '中文',
|
||||||
|
com_nav_lang_italian: 'Italiano',
|
||||||
|
com_nav_lang_brazilian_portuguese: 'Português Brasileiro',
|
||||||
|
com_nav_lang_spanish: 'Español',
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue