diff --git a/frontend/src/App.vue b/frontend/src/App.vue index e4d898e..65a1301 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -9,6 +9,8 @@ import { useSocketStore } from 'src/stores/websocketStore'; import { BtNotify, NotifyDefinedType } from '@bytetrade/ui'; import { bus, BUS_EVENT } from 'src/utils/bus'; import { useUserStore } from 'src/stores/user'; +import { i18n } from 'src/boot/i18n'; +import { supportLanguages } from 'src/i18n'; // import { testSatisfies } from 'src/utils/version'; export default { @@ -17,6 +19,24 @@ export default { const websocketStore = useSocketStore(); const userStore = useUserStore(); + let terminusLanguage = ''; + let terminusLanguageInfo: any = document.querySelector( + 'meta[name="terminus-language"]' + ); + if (terminusLanguageInfo && terminusLanguageInfo.content) { + terminusLanguage = terminusLanguageInfo.content; + } else { + terminusLanguage = navigator.language; + } + + console.log(navigator.language); + + if (terminusLanguage) { + if (supportLanguages.find((e) => e.value == terminusLanguage)) { + i18n.global.locale.value = terminusLanguage as any; + } + } + onMounted(async () => { await appStore.prefetch(); if (!appStore.isPublic) { diff --git a/frontend/src/i18n/en-US/index.ts b/frontend/src/i18n/en-US/index.ts index 476ff7c..35676c3 100644 --- a/frontend/src/i18n/en-US/index.ts +++ b/frontend/src/i18n/en-US/index.ts @@ -4,7 +4,7 @@ export default { base: { failed: 'Action failed', - success: 'Action was successful', + success: 'Action successful', application: 'Application', extensions: 'Categories', time: 'Time', @@ -24,7 +24,7 @@ export default { category: 'Category', submitter: 'Submitter', documents: 'Documents', - see_all: 'See All', + see_all: 'See all', more: 'More' }, main: { @@ -32,7 +32,7 @@ export default { productivity: 'Productivity', utilities: 'Utilities', entertainment: 'Entertainment', - social_network: 'Social Network', + social_network: 'Social network', blockchain: 'Blockchain', recommendation: 'Recommendation', recommend: 'Recommend', @@ -41,7 +41,7 @@ export default { my_terminus: 'My Terminus', terminus: 'Terminus', terminus_market: 'Terminus Market', - install_terminus_os: 'Install TerminusOS' + install_terminus_os: 'Install Terminus' }, app: { get: 'Get', @@ -61,144 +61,142 @@ export default { updating: 'Updating' }, detail: { - require_memory: 'Require Memory', - require_disk: 'Require Disk', - require_cpu: 'Require CPU', - require_gpu: 'Require GPU', - about_this_type: 'ABOUT THIS {type}', - whats_new: 'WHATS NEW', - required_permissions: 'REQUIRED PERMISSIONS', - readme: 'README', - information: 'INFORMATION', - get_support: 'Get Support', + require_memory: 'Required memory', + require_disk: 'Required disk', + require_cpu: 'Required CPU', + require_gpu: 'Required GPU', + about_this_type: 'About this {type}', + whats_new: "What's new", + required_permissions: 'Required permissions', + readme: 'Readme', + information: 'Information', + get_support: 'Get support', website: 'Website', - app_version: 'App Version', + app_version: 'App version', compatibility: 'Compatibility', platforms: 'Platforms', - source_code: 'Source Code', + source_code: 'Source code', public: 'Public', legal: 'Legal', license: 'License', - chart_version: 'Chart Version', - version_history: 'Version History', - get_a_client: 'GET A CLIENT', - dependency: 'DEPENDENCY', - reference_app: 'REFERENCE APP', - see_all_version: 'See all version', + chart_version: 'Chart version', + version_history: 'Version history', + get_a_client: 'Get a client', + dependency: 'Dependency', + reference_app: 'Reference apps', + see_all_version: 'See all versions', download: 'Download', - no_version_history_desc: 'The application has no version history.' + no_version_history_desc: 'The application has no version history' }, permission: { files: 'Files', - files_not_store_label: 'This app will not store any files on Termius.', - files_access_user_data_label: 'Requires permission to access User Data.', + files_not_store_label: 'This app does not store any files on Terminus', + files_access_user_data_label: 'Permission required to access user data', files_access_user_data_desc: 'Allow this app to read and write files in the following directories:', - file_store_data_folder_label: 'Requires permission to access Data folder.', + file_store_data_folder_label: + 'Permission required to access the Data folder', file_store_data_folder_desc: - 'Allow this app to store persistent files in app-specific directories.', + 'Allow this app to store persistent files in app-specific directories', file_store_cache_folder_label: - 'Requires permission to access Cache folder.', + 'Permission required to access the Cache folder', file_store_cache_folder_desc: - 'Allow this app to store cache files in app-specific directories.', + 'Allow this app to store cache files in app-specific directories', internet: 'Internet', - internet_label: 'Full network access while installing and running.', + internet_label: + 'Full network access required during installing and operation', internet_desc: - 'Allow this app to connect to, download from, and upload data to the Internet while installing and running.', + 'Allow this app to connect to, download from, and upload data to the Internet while installing and operation', notifications: 'Notifications', - notifications_label: 'Permission to send you notifications.', + notifications_label: 'Permission required to send you notifications', notifications_desc: - 'Allow this app to send you notifications, such as Terminus Messages, SMS, Emails, Third-party IM Messages. These can be configured in Settings.', + 'Allow this app to send notifications, including Terminus Messages, SMS, Emails, and Third-party IM Messages. You can configure these preferences in Settings.', analytics: 'Analytics', analytics_label: - 'This app uses built-in tools to collect metrics you need for website analytics.', + 'This app uses built-in tools to collect metrics you need for website analytics', analytics_desc: - "It will not collect your visitors' personal information, and all web data will be anonymized and stored locally on your Terminus.", + 'No personal information is collected, and all web data is anonymized and stored locally on your Terminus', websocket: 'Websocket', websocket_label: - 'Permission to use WebSocket for a two-way interactive communication between browser and Terminus.', + 'Permission required to use WebSocket for a two-way interactive communication between browser and Terminus', websocket_desc: - 'Allow this app to send content to the webpage in your browser via WebSocket protocol.', + 'Allow this app to send content to the webpage in your browser via WebSocket', secret: 'Secret', secret_label: - 'Create and manage application configuration and secrets using Vault.', + 'Create and manage application configuration and secrets using Vault', secret_desc: - 'Vault is a Terminus secret management platform for storing, managing, and syncing sensitive information, such as API keys, database credentials, and environment variables.', - knowledgebase: 'Knowledgebase', + "Vault is Terminus's secret management app for storing, managing, and syncing sensitive information such as API keys, database credentials, and environment variables", + knowledgebase: 'Knowledge base', knowledgebase_label: - 'Permission to use the data in your local knowledge base.', + 'Permission required to access your local knowledge base', knowledgebase_desc: - 'Allow this app to use your personal data stored in Terminus local knowledge base, such as articles from subscribed RSS feeds and PDFs uploaded to Wise.', - search_label: 'This app supports Terminus full-text search engine.', - relational_database: 'Relational Database', + 'Allows this app to use your personal data stored in Terminus local knowledge base', + search_label: "This app supports Terminus's full-text search engine", + relational_database: 'Relational database', relational_database_label: 'This app uses PostgreSQL as its relational database', relational_database_desc: 'PostgreSQL is provided by Terminus Middleware Service.', - document_database: 'Document Database', + document_database: 'Document database', document_database_label: 'This app uses MongoDB as its document database', document_database_desc: 'MongoDB is provided by Terminus Middleware Service.', - key_value_database: 'Key-Value Database', - key_value_database_label: 'This app uses Redis as its Key-Value database', + key_value_database: 'Key-value database', + key_value_database_label: 'This app uses Redis as its Key-value database', key_value_database_desc: 'Redis is provided by Terminus Middleware Service.', cluster_app_label: - 'This app will be installed at cluster level, and shared by all users in the same Terminus cluster.', + 'This app will be installed at the cluster level, and shared by all users in the same Terminus cluster', entrance: 'Entrance', entrance_visibility_label: - 'Number of different visibility entrances for this app: {desktopSize} visible, {backendSize} invisible.', + 'Number of different visibility entrances for this app: {desktopSize} visible and {backendSize} invisible', entrance_visibility_desc_first: - "The visible entrance allows you to access the app's UI webpage through the Terminus desktop.", + "The visible entrance allows you to access the app's webpage through Desktop", entrance_visibility_desc_second: 'The invisible entrance typically operates in the backend and is used for the app to interact with other apps.', entrance_auth_level_label: - 'Number of different auth Level entrances for this app: {publicSize} public, {privateSize} private.', + 'Number of entrances of different auth levels: {publicSize} public, {privateSize} private', entrance_auth_level_desc: - 'Public entrance is accessible to anyone on the Internet, whereas private entrance requires activation of Tailscale for access.', + 'A public entrance is accessible to anyone on the Internet. A private entrance requires activation of Tailscale for access.', entrance_two_factor_label: 'These entrances require Two-Factor Authentication to access: {twoFactor}' }, error: { - network_error: 'Network error, please try again later', + network_error: 'Network error. Please try again later.', unknown_error: 'Unknown error', failed_get_user_role: 'Failed to get user role', - only_be_installed_by_the_admin: - 'This app can only be installed by the Admin.', + only_be_installed_by_the_admin: 'This app can only be installed by Admin', not_admin_role_install_middleware: - 'This is a middleware, please contact your Terminus Admin to install.', + 'Middleware component. Contact your Terminus Admin to install.', not_admin_role_install_cluster_app: - 'This is a cluster app, please contact your Terminus Admin to install.', - failed_to_get_os_version: 'Failed to get Terminus Version', - app_is_not_compatible_terminus_os: - 'This app isn’t compatible with your Terminus OS.', + 'Cluster app. Contact your Terminus Admin to install.', + failed_to_get_os_version: 'Failed to get Terminus version', + app_is_not_compatible_terminus_os: 'Incompatible with your Terminus', failed_to_get_user_resource: 'Failed to get user resource', - user_not_enough_cpu: 'Not enough required CPU on your quota.', - user_not_enough_memory: 'Not enough required memory on your quota.', + user_not_enough_cpu: 'Insufficient CPU on your quota', + user_not_enough_memory: 'Insufficient memory on your quota', failed_to_get_system_resource: 'Failed to get system resource', - need_to_install_dependent_app_first: 'Need to install dependent app first.', - terminus_not_enough_cpu: 'Not enough required CPU on Terminus cluster.', - terminus_not_enough_memory: - 'Not enough required memory on Terminus cluster.', - terminus_not_enough_disk: 'Not enough required disk on Terminus cluster.', - terminus_not_enough_gpu: 'Not enough required GPU on Terminus cluster.', - operation_preform_failure: 'operation preform failure', + need_to_install_dependent_app_first: 'Need to install dependent app first', + terminus_not_enough_cpu: 'Insufficient CPU on the Terminus cluster', + terminus_not_enough_memory: 'Insufficient memory on the Terminus cluster', + terminus_not_enough_disk: 'Insufficient disk on the Terminus cluster', + terminus_not_enough_gpu: 'Insufficient GPU on the Terminus cluster', + operation_preform_failure: 'Operation faied', cluster_not_support_platform: - 'This [app/recommend/model] does not support your Terminus OS platform architecture.' + 'This [app/recommend/model] does not support your Terminus platform' }, my: { market: 'Market', custom: 'Custom', unable_to_install_app: 'Unable to install app', - update_all: 'Update All', - available_updates: 'Available Updates', - everything_up_to_date: 'Congrats, everything is up to date!', - no_upload_chart_tips: 'You haven’t uploaded any custom chart yet.', - no_installed_app_tips: 'You haven’t installed anything yet.', - no_logs: 'There are no installation logs here.', - sure_to_uninstall_the_app: - 'Are you sure you want to uninstall the application {title}?', - upload_custom_chart: 'Upload Custom Chart', + update_all: 'Update all', + available_updates: 'Available updates', + everything_up_to_date: 'Congratulations! Everything is up to date.', + no_upload_chart_tips: "You haven't uploaded any custom charts yet", + no_installed_app_tips: 'You haven’t installed anything yet', + no_logs: 'No installation logs available', + sure_to_uninstall_the_app: "Are you sure to uninstall '{title}'?", + upload_custom_chart: 'Upload custom chart', logs: 'Logs' } }; diff --git a/frontend/src/i18n/index.ts b/frontend/src/i18n/index.ts index 975c9c7..bca9240 100644 --- a/frontend/src/i18n/index.ts +++ b/frontend/src/i18n/index.ts @@ -1,7 +1,14 @@ import enUS from './en-US'; +import zhCN from './zh-CN'; export default { - 'en-US': enUS + 'en-US': enUS, + 'zh-CN': zhCN }; export const defaultLanguage = 'en-US'; + +export const supportLanguages = [ + { value: 'en-US', label: 'English', enable: true }, + { value: 'zh-CN', label: '简体中文', enable: true } +]; diff --git a/frontend/src/i18n/zh-CN/index.ts b/frontend/src/i18n/zh-CN/index.ts new file mode 100644 index 0000000..745fc58 --- /dev/null +++ b/frontend/src/i18n/zh-CN/index.ts @@ -0,0 +1,183 @@ +// This is just an example, +// so you can safely delete all default props below + +export default { + base: { + failed: '操作失败', + success: '操作成功', + application: '应用', + extensions: '类别', + time: '时间', + type: '类型', + title: '标题', + version: '版本', + operations: '操作', + result: '结果', + status: '状态', + name: '名称', + message: '消息', + scope: '范围', + cluster_app: '集群应用', + developer: '开发者', + language: '语言', + search: '搜索', + category: '类别', + submitter: '提交者', + documents: '文档', + see_all: '查看全部', + more: '更多' + }, + main: { + discover: '发现', + productivity: '效率', + utilities: '实用工具', + entertainment: '娱乐', + social_network: '社交网络', + blockchain: '区块链', + recommendation: '推荐', + recommend: '推荐', + models: '模型', + large_language_model: '大语言模型', + my_terminus: '我的 Terminus', + terminus: 'Terminus', + terminus_market: 'Terminus 市场', + install_terminus_os: '安装 Terminus' + }, + app: { + get: '获取', + install: '安装', + installed: '已安装', + suspend: '暂停', + cancel: '取消', + load: '加载', + unload: '卸载', + resume: '恢复', + installing: '正在安装', + update: '更新', + running: '运行中', + open: '打开', + uninstalling: '正在卸载', + uninstall: '卸载', + updating: '正在更新' + }, + detail: { + require_memory: '所需内存', + require_disk: '所需磁盘空间', + require_cpu: '所需 CPU', + require_gpu: '所需 GPU', + about_this_type: '关于此{type}', + whats_new: '新功能', + required_permissions: '所需权限', + readme: 'Readme', + information: '信息', + get_support: '获取支持', + website: '网站', + app_version: '应用版本', + compatibility: '兼容性', + platforms: '平台', + source_code: '源代码', + public: '公开', + legal: '法律', + license: '许可证', + chart_version: 'Chart 版本', + version_history: '版本历史', + get_a_client: '获取客户端', + dependency: '依赖项', + reference_app: '参考应用', + see_all_version: '查看所有版本', + download: '下载', + no_version_history_desc: '该应用没有版本历史记录' + }, + permission: { + files: '文件', + files_not_store_label: '此应用不会在 Terminus 上存储任何文件', + files_access_user_data_label: '访问用户数据', + files_access_user_data_desc: '允许此应用读取和写入以下目录中的文件:', + file_store_data_folder_label: '访问 Data 文件夹', + file_store_data_folder_desc: '允许此应用在特定应用的目录中持久化存储文件', + file_store_cache_folder_label: '访问 Cache 文件夹', + file_store_cache_folder_desc: '允许此应用在特定应用目录中存储缓存文件', + internet: '互联网', + internet_label: '安装和运行期间需要完全网络访问权限', + internet_desc: '允许此应用在安装和运行期间连接、下载和上传数据到互联网', + notifications: '通知', + notifications_label: '发送通知的权限', + notifications_desc: + '允许此应用发送通知,包括 Terminus 消息、短信、电子邮件和第三方即时通讯消息。您可以在设置中配置这些偏好。', + analytics: '分析', + analytics_label: '此应用使用内置工具收集您需要的网站分析指标', + analytics_desc: + '不收集任何个人信息,所有网页数据均为匿名并存储在 Terminus 本地', + websocket: 'Websocket', + websocket_label: + '允许使用 WebSocket 进行浏览器和 Terminus 之间双向交互通信', + websocket_desc: '允许此应用通过 WebSocket 向您浏览器中的网页发送内容', + secret: '密钥', + secret_label: '使用 Vault 创建和管理应用配置和密钥', + secret_desc: + 'Vault 是 Terminus 的密钥管理应用,用于存储、管理和同步敏感信息,如 API 密钥、数据库凭证和环境变量等', + knowledgebase: '知识库', + knowledgebase_label: '访问本地知识库', + knowledgebase_desc: + '允许此应用使用您在 Terminus 本地知识库中存储的个人数据', + search_label: '此应用支持 Terminus 的全文搜索引擎', + relational_database: '关系数据库', + relational_database_label: '此应用程序使用 PostgreSQL 作为其关系数据库。', + relational_database_desc: 'PostgreSQL 由 Terminus 中间件服务提供。', + document_database: '文档数据库', + document_database_label: '此应用使用 MongoDB 作为文档数据库。', + document_database_desc: 'MongoDB 由 Terminus 中间件服务提供。', + key_value_database: '键值数据库', + key_value_database_label: '此应用使用 Redis 作为其键值数据库。', + key_value_database_desc: 'Redis 由 Terminus 中间件服务提供。', + cluster_app_label: '集群级别应用,由同一 Terminus 集群中的所有用户共享', + entrance: '入口', + entrance_visibility_label: + '此应用不同可见性入口的数量:{desktopSize} 个可见,{backendSize} 个不可见', + entrance_visibility_desc_first: '可见入口允许您通过桌面访问应用的页面', + entrance_visibility_desc_second: + '不可见入口通常在后台运行,用于应用与其他应用交互', + entrance_auth_level_label: + '不同认证级别的入口数量:{publicSize} 个公开,{privateSize} 个私有', + entrance_auth_level_desc: + '公开入口可供互联网上的任何人访问。私有入口需要激活 Tailscale 才能访问。', + entrance_two_factor_label: '这些入口需要双因素认证才能访问:{twoFactor}' + }, + error: { + network_error: '网络错误。请稍后重试。', + unknown_error: '未知错误', + failed_get_user_role: '获取用户角色失败', + only_be_installed_by_the_admin: '此应用程序只能由管理员安装', + not_admin_role_install_middleware: + '中间件组件。请联系您的 Terminus 管理员安装。', + not_admin_role_install_cluster_app: + '集群应用。请联系您的 Terminus 管理员安装。', + failed_to_get_os_version: '获取 Terminus 版本失败', + app_is_not_compatible_terminus_os: '与您的 Terminus 不兼容', + failed_to_get_user_resource: '获取用户资源失败', + user_not_enough_cpu: '配额 CPU 不足', + user_not_enough_memory: '配额内存不足', + failed_to_get_system_resource: '获取系统资源失败', + need_to_install_dependent_app_first: '需要先安装依赖应用', + terminus_not_enough_cpu: 'Terminus 集群 CPU 不足', + terminus_not_enough_memory: 'Terminus 集群内存不足', + terminus_not_enough_disk: 'Terminus 集群磁盘空间不足', + terminus_not_enough_gpu: 'Terminus 集群 GPU 不足', + operation_preform_failure: '操作失败', + cluster_not_support_platform: '此应用/推荐/大模型不支持当前 Terminus 平台' + }, + my: { + market: '市场', + custom: '自定义', + unable_to_install_app: '无法安装应用', + update_all: '全部更新', + available_updates: '可用更新', + everything_up_to_date: '恭喜!所有应用已是最新版本。', + no_upload_chart_tips: '您尚未上传任何自定义 chart 文件', + no_installed_app_tips: '您尚未安装任何内容', + no_logs: '无可用的安装日志', + sure_to_uninstall_the_app: '您确定要卸载“{title}”吗?', + upload_custom_chart: '上传自定义 chart', + logs: '日志' + } +}; diff --git a/frontend/src/index.template.html b/frontend/src/index.template.html index 41bdc2f..798a468 100644 --- a/frontend/src/index.template.html +++ b/frontend/src/index.template.html @@ -10,7 +10,6 @@ > <%= productName %> - diff --git a/frontend/src/pages/recommend/RecommendPage.vue b/frontend/src/pages/recommend/RecommendPage.vue index cb86294..24ec95b 100644 --- a/frontend/src/pages/recommend/RecommendPage.vue +++ b/frontend/src/pages/recommend/RecommendPage.vue @@ -119,7 +119,7 @@ async function fetchData(showLoading = false) { } }) .finally(() => { - latestLoading.value = false; + pageLoading.value = false; }); }