diff --git a/package.json b/package.json index 61a628c6..6c75d6df 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,9 @@ "echarts": "^5.3.0", "element-ready": "^6.2.1", "github-url-detection": "^8.1.0", + "i18next": "^23.11.5", + "i18next-browser-languagedetector": "^8.0.0", + "i18next-http-backend": "^2.5.2", "jquery": "^3.6.0", "lodash-es": "^4.17.21", "moment": "^2.30.1", @@ -37,6 +40,7 @@ "react-chat-widget": "^3.1.4", "react-dom": "^17.0.2", "react-hot-loader": "^4.13.0", + "react-i18next": "^14.1.2", "react-modal": "3.15.1", "strip-indent": "^4.0.0" }, diff --git a/src/helpers/get-message-by-locale.ts b/src/helpers/get-message-by-locale.ts deleted file mode 100644 index 0d1c20b0..00000000 --- a/src/helpers/get-message-by-locale.ts +++ /dev/null @@ -1,12 +0,0 @@ -import messages_en from '../locales/en/messages.json'; -import messages_zh_CN from '../locales/zh_CN/messages.json'; - -const messages_locale = { - en: messages_en, - zh_CN: messages_zh_CN, -}; - -export default function getMessageByLocale(key: string, locale: string) { - // @ts-ignore - return messages_locale[locale][key]['message']; -} diff --git a/src/helpers/i18n.ts b/src/helpers/i18n.ts new file mode 100644 index 00000000..b1628a6a --- /dev/null +++ b/src/helpers/i18n.ts @@ -0,0 +1,36 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import Backend from 'i18next-http-backend'; +import messages_en from '../locales/en/translation.json'; +import messages_zh_CN from '../locales/zh_CN/translation.json'; + +const language_resources = { + zh_CN: { + translation: messages_zh_CN, + }, + en: { + translation: messages_en, + }, +}; + +i18n + // detect user language + // learn more: https://github.com/i18next/i18next-browser-languageDetector + .use(Backend) + .use(LanguageDetector) + // pass the i18n instance to react-i18next. + .use(initReactI18next) + // init i18next + // for all options read: https://www.i18next.com/overview/configuration-options + .init({ + debug: false, + fallbackLng: 'en', + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + skipOnVariables: false, + }, + resources: language_resources, + }); + +export default i18n; diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json deleted file mode 100644 index f118a15f..00000000 --- a/src/locales/en/messages.json +++ /dev/null @@ -1,366 +0,0 @@ -{ - "manifest_appDescription": { - "message": "Hypertrons-crx, tracking, tracing and digging GitHub projects and developers" - }, - "manifest_appName": { - "message": "Hypertrons-crx Robot" - }, - "golbal_loading": { - "message": "Loading……" - }, - "golbal_link": { - "message": "Link" - }, - "global_error_message": { - "message": "Sorry, an error occurred while loading Hypertrons-crx extention. Error Code is: " - }, - "global_close": { - "message": "Close" - }, - "global_search": { - "message": "Search" - }, - "global_toggle_onText": { - "message": "On" - }, - "global_toggle_offText": { - "message": "Off" - }, - "global_btn_ok": { - "message": "Ok" - }, - "global_btn_disable": { - "message": "Don't show this again" - }, - "global_btn_goBack": { - "message": "Go back" - }, - "global_developer": { - "message": "Develpoer" - }, - "global_project": { - "message": "Project" - }, - "global_repo": { - "message": "Repo" - }, - "global_correlation": { - "message": "Correlation" - }, - "global_contribution": { - "message": "Contribution" - }, - "global_activity": { - "message": "Activity" - }, - "global_period": { - "message": "Period" - }, - "global_day": { - "message": "days" - }, - "global_week": { - "message": "Week" - }, - "global_month": { - "message": "Month" - }, - "global_here": { - "message": "here" - }, - "global_clickToshow": { - "message": "Click to show" - }, - "global_notificationTitle": { - "message": "Messages from the developers" - }, - "global_sendFeedback": { - "message": "Send the feedback to us." - }, - "global_error_message_404": { - "message": { - "status": "Data does not exist", - "measure": { - "text": "Possible causes:", - "tips": ["Recently created, has not been computed", "No actions in selected period, nothing to be computed"] - } - } - }, - "component_developerCollaborationNetwork_title": { - "message": "Developer Collaboration Network" - }, - "component_developerCollaborationNetwork_description": { - "message": "Developer Collaboration Network shows the collaboration between developers for a given time period. From this graph you can find other developers who are closet to a given developer." - }, - "component_developerCollaborationNetwork_description_node": { - "message": "Node: Developer, node size and shades of color indicate developer activity." - }, - "component_developerCollaborationNetwork_description_edge": { - "message": "Edge: Collaborative relationship between developers, the value of the edge indicates the closeness of the connection between developers. Edges with values smaller than 2.5 are removed from the network to make it sparse and readable." - }, - "component_activity_definition": { - "message": "Learn how we count activity" - }, - "component_activity_definition_link": { - "message": "http://oss.x-lab.info/github-insight-report-2020-en.pdf" - }, - "component_contributorsActivityEvolution_title": { - "message": "Contributor Activity Rolling Chart" - }, - "component_contributorsActivityEvolution_description_1": { - "message": "The contributor activity rolling chart shows how active a project's contributors have been over time, and is used to identify the top contributors and those whose contributions are growing rapidly. It also helps the community keep an eye on contributor attrition, which means, when a contributor's activity has not been updated for a long time, it is somewhat assumed that the contributor has been lost." - }, - "component_contributorsActivityEvolution_description_2": { - "message": "Each color corresponds to a developer, with the developer's GitHub ID on the far left and the developer's GitHub avatar and activity on the far right." - }, - "component_contributorsActivityEvolution_description_3": { - "message": "Contributors: All GitHub users who have star, fork, issue, and PR activity in the repository." - }, - "component_repoActORTrend_title": { - "message": "Activity & OpenRank Trends" - }, - "component_repoActORTrend_legend1": { - "message": "Activity" - }, - "component_repoActORTrend_legend2": { - "message": "OpenRank" - }, - "component_repoActORTrend_yName1": { - "message": "Activity" - }, - "component_repoActORTrend_yName2": { - "message": "OpenRank" - }, - "component_developerActORTrend_title": { - "message": "Activity & OpenRank Trends" - }, - "component_developerActORTrend_legend1": { - "message": "Activity" - }, - "component_developerActORTrend_legend2": { - "message": "OpenRank" - }, - "component_developerActORTrend_yName1": { - "message": "Activity" - }, - "component_developerActORTrend_yName2": { - "message": "OpenRank" - }, - "component_projectRacingBar_title": { - "message": "Contributor Activity Racing Bar" - }, - "component_projectCorrelationNetwork_title": { - "message": "Project Correlation Network" - }, - "component_projectRacingBar_description": { - "message": "This chart shows how the activity values of contributors in this repository evolve." - }, - "component_projectCorrelationNetwork_description": { - "message": "Project Correlation Network shows the correlation between projects for a given time period. From this graph you can find the projects that are related to the given project." - }, - "component_projectCorrelationNetwork_description_node": { - "message": "Node: Project, node size and shades of color indicate project activity." - }, - "component_projectCorrelationNetwork_description_edge": { - "message": "Edge: Connection between projects, the value indicates the closeness of the connection between projects. Edges with values smaller than 5 are removed from the network to make it sparse and readable." - }, - "component_mostParticipatedProjects_title": { - "message": "Most Participated Repos" - }, - "component_mostParticipatedProjects_description": { - "message": "Most Participated Repos shows the active projects of developers in a given time period. From this graph you can find out the most active repositories for a given developer." - }, - "component_mostParticipatedProjects_description_node": { - "message": "Node: Project, node size and shades of color indicate project activity." - }, - "component_mostParticipatedProjects_description_edge": { - "message": "Edge: Connection between projects, the value of the edge indicates the closeness of the connection between projects. Edges with values smaller than 5 are removed from the network to make it sparse and readable." - }, - "component_activeDeveloperCollaborationNetwork_title": { - "message": "Active Developer Collaboration Network" - }, - "component_activeDeveloperCollaborationNetwork_description": { - "message": "Active Developer Collaboration Network shows the collaboration between active developers within the project for a given time period. From this graph you can find the active developers in the given project. What's more, you can find the collaborative relationships between these developers." - }, - "component_activeDeveloperCollaborationNetwork_description_node": { - "message": "Node: Developer, node size and shades of color indicate the developer's contribution to the project's activity." - }, - "component_activeDeveloperCollaborationNetwork_description_edge": { - "message": "Edge: Collaborative relationship between developers, the value indicates the closeness of the connection between developers. Edges with values smaller than 2.5 are removed from the network to make it sparse and readable." - }, - "component_darkMode": { - "message": "Dark mode" - }, - "teachingBubble_text_headline": { - "message": "Explore Hypertrons-crx charts" - }, - "teachingBubble_text_content": { - "message": "Click here to see statistics data" - }, - "options_enable_title": { - "message": "Status" - }, - "options_enable_toolTip": { - "message": "Choose whether to enable perceptor when visiting github" - }, - "options_enable_toggle_autoCheck": { - "message": "Enable perceptor" - }, - "options_components_title": { - "message": "Select Components" - }, - "options_components_toolTip": { - "message": "You can choose which component will be shown on github's page" - }, - "options_locale_title": { - "message": "Language" - }, - "options_locale_toolTip": { - "message": "Choose the display language" - }, - "options_update_title": { - "message": "Update" - }, - "options_update_toolTip": { - "message": "Keep up to date to get more components" - }, - "options_update_toggle_autoCheck": { - "message": "Auto check updates" - }, - "options_update_btn_checkUpdate": { - "message": "Check" - }, - "options_update_checking": { - "message": "Checking for updates" - }, - "options_update_btn_updateStatusYes": { - "message": "New update availabe" - }, - "options_update_btn_updateStatusNo": { - "message": "Up to date" - }, - "options_update_btn_getUpdate": { - "message": "Get the update" - }, - "notification_title_newUpdate": { - "message": "New update available" - }, - "notification_message_newUpdate": { - "message": "Version: %v" - }, - "options_token_title": { - "message": "Set token" - }, - "options_token_dialog_title": { - "message": "Set GitHub token" - }, - "options_token_toolTip": { - "message": "GitHub token will be used to visit files of a repository" - }, - "options_token_btn_setToken": { - "message": "Set token" - }, - "options_token_btn_rmToken": { - "message": "Remove token" - }, - "options_token_dialog_message": { - "message": "Where to generate GitHub token?" - }, - "options_token_dialog_description": { - "message": "Your token will only be used to get avatar and username and hypertrons.json from any Github repositories, which needs no more scopes than basic `public_repo`. The token will be keep in local storage and will not be sent to any other domains except github.com." - }, - "options_token_dialog_checking": { - "message": "Checking" - }, - "options_token_dialog_error": { - "message": "Bad token" - }, - "options_about_title": { - "message": "About" - }, - "options_about_toolTip": { - "message": "About HyperCRX" - }, - "options_about_description": { - "message": "HyperCRX is a browser extension to get more insights into projects and developers on GitHub." - }, - "hypertrons_tab_title": { - "message": "Hypertrons Commands" - }, - "hypertrons_tab_description": { - "message": "You can use hypertrons commands here. See usage:" - }, - "hypertrons_tab_link": { - "message": "https://www.hypertrons.io/#/component/index" - }, - "header_label_activity": { - "message": "Activity" - }, - "header_label_OpenRank": { - "message": "OpenRank" - }, - "header_label_participant": { - "message": "Participants" - }, - "header_label_contributor": { - "message": "Contributors" - }, - "fork_popup_title": { - "message": "Fork Events" - }, - "star_popup_title": { - "message": "Star Events" - }, - "issue_popup_title": { - "message": "Issue Open, Close and Comment Events" - }, - "pr_popup_title": { - "message": "Open PR, PR Merge, Review Comment Events" - }, - "merged_lines_popup_title": { - "message": "Merged Addition & Deletion Code Lines" - }, - "docs_gpt_chat_widget": { - "message": "OSS-GPT Chat Bot" - }, - "OSS_GPT_subtitle": { - "message": "Ask anything about %v" - }, - "OSS_GPT_subtitle_notAvailable": { - "message": "NOT AVAILABLE for %v" - }, - "OSS_GPT_welcome": { - "message": "Hi, I'm an assistant powered by [DocsGPT](https://github.com/arc53/docsgpt) and [X-lab](https://github.com/X-lab2017). Ask me anything about %v!" - }, - "OSS_GPT_notAvailable": { - "message": "OSS-GPT currently is **NOT AVAILABLE** for %v. If you want docs support for the repository, please check [this issue](https://github.com/hypertrons/hypertrons-crx/issues/609) and make a request there :)\n\nSee [all available docs](https://oss.x-lab.info/hypercrx/docsgpt_active_docs.json)\n\nThis chat widget can also be enabled/disabled in the extension options page whenever you want." - }, - "issue_icon": { - "message": "GitHub repository issue count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "pr_icon": { - "message": "GitHub repository pr count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "fork_icon": { - "message": "GitHub repository fork count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "star_icon": { - "message": "GitHub repository star count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - - "activity_icon": { - "message": "GitHub repository activity count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "openrank_icon": { - "message": "GitHub repository openrank count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "contributors_participants_icon": { - "message": "GitHub repository contributors and participants count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "merged_lines_icon": { - "message": "GitHub repository code lines change count over time. And you can zoom in/out on the axes using the mouse scroll wheel." - }, - "OSS_GPT_errorMessage": { - "message": "Sorry, due to cost reasons, the OSS-GPT function is currently not available. Please follow [HyperCRX](https://github.com/hypertrons/hypertrons-crx) for the latest news." - } -} diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json new file mode 100644 index 00000000..cf9b6f6a --- /dev/null +++ b/src/locales/en/translation.json @@ -0,0 +1,64 @@ +{ + "global_period": "Period", + "global_day_one": "day", + "global_day_other": "days", + "global_clickToshow": "Click to show", + "component_developerCollaborationNetwork_title": "Developer Collaboration Network", + "component_developerCollaborationNetwork_description": "Developer Collaboration Network shows the collaboration between developers for a given time period. From this graph you can find other developers who are closet to a given developer.", + "component_developerCollaborationNetwork_description_node": "Node: Developer, node size and shades of color indicate developer activity.", + "component_developerCollaborationNetwork_description_edge": "Edge: Collaborative relationship between developers, the value of the edge indicates the closeness of the connection between developers. Edges with values smaller than 2.5 are removed from the network to make it sparse and readable.", + "component_repoActORTrend_title": "Activity & OpenRank Trends", + "component_repoActORTrend_legend1": "Activity", + "component_repoActORTrend_legend2": "OpenRank", + "component_repoActORTrend_yName1": "Activity", + "component_repoActORTrend_yName2": "OpenRank", + "component_developerActORTrend_title": "Activity & OpenRank Trends", + "component_developerActORTrend_legend1": "Activity", + "component_developerActORTrend_legend2": "OpenRank", + "component_developerActORTrend_yName1": "Activity", + "component_developerActORTrend_yName2": "OpenRank", + "component_projectRacingBar_title": "Contributor Activity Racing Bar", + "component_projectCorrelationNetwork_title": "Project Correlation Network", + "component_projectRacingBar_description": "This chart shows how the activity values of contributors in this repository evolve.", + "component_projectCorrelationNetwork_description": "Project Correlation Network shows the correlation between projects for a given time period. From this graph you can find the projects that are related to the given project.", + "component_projectCorrelationNetwork_description_node": "Node: Project, node size and shades of color indicate project activity.", + "component_projectCorrelationNetwork_description_edge": "Edge: Connection between projects, the value indicates the closeness of the connection between projects. Edges with values smaller than 5 are removed from the network to make it sparse and readable.", + "component_mostParticipatedProjects_title": "Most Participated Repos", + "component_mostParticipatedProjects_description": "Most Participated Repos shows the active projects of developers in a given time period. From this graph you can find out the most active repositories for a given developer.", + "component_mostParticipatedProjects_description_node": "Node: Project, node size and shades of color indicate project activity.", + "component_mostParticipatedProjects_description_edge": "Edge: Connection between projects, the value of the edge indicates the closeness of the connection between projects. Edges with values smaller than 5 are removed from the network to make it sparse and readable.", + "component_activeDeveloperCollaborationNetwork_title": "Active Developer Collaboration Network", + "component_activeDeveloperCollaborationNetwork_description": "Active Developer Collaboration Network shows the collaboration between active developers within the project for a given time period. From this graph you can find the active developers in the given project. What's more, you can find the collaborative relationships between these developers.", + "component_activeDeveloperCollaborationNetwork_description_node": "Node: Developer, node size and shades of color indicate the developer's contribution to the project's activity.", + "component_activeDeveloperCollaborationNetwork_description_edge": "Edge: Collaborative relationship between developers, the value indicates the closeness of the connection between developers. Edges with values smaller than 2.5 are removed from the network to make it sparse and readable.", + "options_components_title": "Select Components", + "options_components_toolTip": "You can choose which component will be shown on github's page", + "options_locale_title": "Language", + "options_locale_toolTip": "Choose the display language", + "options_about_title": "About", + "options_about_toolTip": "About HyperCRX", + "options_about_description": "HyperCRX is a browser extension to get more insights into projects and developers on GitHub.", + "header_label_activity": "Activity", + "header_label_OpenRank": "OpenRank", + "header_label_participant": "Participants", + "header_label_contributor": "Contributors", + "fork_popup_title": "Fork Events", + "star_popup_title": "Star Events", + "issue_popup_title": "Issue Open, Close and Comment Events", + "pr_popup_title": "Open PR, PR Merge, Review Comment Events", + "merged_lines_popup_title": "Merged Addition & Deletion Code Lines", + "OSS_GPT_subtitle": "Ask anything about {{repoName}}", + "OSS_GPT_subtitle_notAvailable": "NOT AVAILABLE for {{repoName}}", + "OSS_GPT_welcome": "Hi, I'm an assistant powered by [DocsGPT](https://github.com/arc53/docsgpt) and [X-lab](https://github.com/X-lab2017). Ask me anything about {{repoName}}!", + "OSS_GPT_notAvailable": "OSS-GPT currently is **NOT AVAILABLE** for {{repoName}}. If you want docs support for the repository, please check [this issue](https://github.com/hypertrons/hypertrons-crx/issues/609) and make a request there :)\n\nSee [all available docs](https://oss.x-lab.info/hypercrx/docsgpt_active_docs.json)\n\nThis chat widget can also be enabled/disabled in the extension options page whenever you want.", + "OSS_GPT_errorMessage": "Sorry, due to cost reasons, the OSS-GPT function is currently not available. Please follow [HyperCRX](https://github.com/hypertrons/hypertrons-crx) for the latest news.", + "icon_tip": "GitHub repository {{icon_content}} count over time. And you can zoom in/out on the axes using the mouse scroll wheel.", + "issue_icon": "issue", + "pr_icon": "pr", + "fork_icon": "fork", + "star_icon": "star", + "activity_icon": "activity", + "openrank_icon": "openrank", + "contributors_participants_icon": "contributors and participants", + "merged_lines_icon": "code lines change" +} diff --git a/src/locales/zh_CN/messages.json b/src/locales/zh_CN/messages.json deleted file mode 100644 index a02ef43e..00000000 --- a/src/locales/zh_CN/messages.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "manifest_appDescription": { - "message": "Hypertrons-crx,追踪和挖掘和洞察感兴趣的 GitHub 项目与开发者与" - }, - "manifest_appName": { - "message": "Hypertrons-crx 机器人" - }, - "golbal_loading": { - "message": "载入中......" - }, - "golbal_link": { - "message": "链接" - }, - "global_error_message": { - "message": "抱歉,Hypertrons-crx 插件加载时遇到了一点问题。错误代码为:" - }, - "global_close": { - "message": "关闭" - }, - "global_search": { - "message": "查找" - }, - "global_toggle_onText": { - "message": "开" - }, - "global_toggle_offText": { - "message": "关" - }, - "global_btn_ok": { - "message": "确定" - }, - "global_btn_disable": { - "message": "不再提示" - }, - "global_btn_goBack": { - "message": "返回" - }, - "global_developer": { - "message": "开发者" - }, - "global_project": { - "message": "项目" - }, - "global_repo": { - "message": "仓库" - }, - "global_correlation": { - "message": "关联度" - }, - "global_activity": { - "message": "活跃度" - }, - "global_contribution": { - "message": "贡献度" - }, - "global_period": { - "message": "周期" - }, - "global_day": { - "message": "天" - }, - "global_week": { - "message": "周" - }, - "global_month": { - "message": "月" - }, - "global_here": { - "message": "这里" - }, - "global_clickToshow": { - "message": "点击查看" - }, - "global_notificationTitle": { - "message": "欢迎" - }, - "global_sendFeedback": { - "message": "将您的问题反馈给我们。" - }, - "global_error_message_404": { - "message": { - "status": "对应数据不存在", - "measure": { - "text": "这可能是因为:", - "tips": ["该对象为最近创建对象,数据还未被计算", "该对象在此周期内无任何有效活动,不予计算"] - } - } - }, - "component_developerCollaborationNetwork_title": { - "message": "开发者协作网络图" - }, - "component_developerCollaborationNetwork_description": { - "message": "开发者协作网络图展示了在给定的时间段内,开发者与开发者之间的协作关系, 用于开发者关系的追踪与挖掘。从该网络图中,可以找出与该开发者联系较为紧密的其他开发者。" - }, - "component_developerCollaborationNetwork_description_node": { - "message": "节点:一个节点表示开发者,节点大小与颜色的深浅表示开发者活跃度的大小。" - }, - "component_developerCollaborationNetwork_description_edge": { - "message": "边:开发者与开发者之间的协作关系,值的大小表示开发者间联系的紧密程度。为了使网络图不至于太稠密,值小于 2.5 的边会被剪去。" - }, - "component_activity_definition": { - "message": "查看如何定义活跃度" - }, - "component_activity_definition_link": { - "message": "http://oss.x-lab.info/github-insight-report-2020.pdf" - }, - "component_contributorsActivityEvolution_title": { - "message": "项目贡献者活跃度滚榜图" - }, - "component_contributorsActivityEvolution_description_1": { - "message": "项目贡献者活跃度滚榜图展示了在给定的时间内,项目贡献者的活跃度变化情况,用于发掘项目中头部和贡献增长迅速的贡献者,并有助于项目社区关注贡献者的流失情况。当某一贡献者的活跃度长时间未更新,在一定程度上可以认为该贡献者已经流失。" - }, - "component_contributorsActivityEvolution_description_2": { - "message": "每一种颜色对应一个贡献者,最左端显示贡献者的 GitHub ID,最右端显示贡献者的 GitHub 头像和活跃度。" - }, - "component_contributorsActivityEvolution_description_3": { - "message": "贡献者:指在项目中有过 star、fork、issue,和 PR 活动的所有 GitHub 用户。" - }, - "component_repoActORTrend_title": { - "message": "活跃度与OpenRank趋势" - }, - "component_repoActORTrend_legend1": { - "message": "活跃度" - }, - "component_repoActORTrend_legend2": { - "message": "OpenRank" - }, - "component_repoActORTrend_yName1": { - "message": "活跃度" - }, - "component_repoActORTrend_yName2": { - "message": "OpenRank" - }, - "component_developerActORTrend_title": { - "message": "活跃度与OpenRank趋势" - }, - "component_developerActORTrend_legend1": { - "message": "活跃度" - }, - "component_developerActORTrend_legend2": { - "message": "OpenRank" - }, - "component_developerActORTrend_yName1": { - "message": "活跃度" - }, - "component_developerActORTrend_yName2": { - "message": "OpenRank" - }, - "component_projectRacingBar_title": { - "message": "贡献者活跃度滚榜" - }, - "component_projectCorrelationNetwork_title": { - "message": "项目关系网络图" - }, - "component_projectRacingBar_description": { - "message": "贡献者活跃度滚榜展示了项目贡献者的活跃度演化过程。" - }, - "component_projectCorrelationNetwork_description": { - "message": "项目关系网络图展示了在给定的时间段内,项目与项目之间的联结关系,用于项目间关系的追踪与挖掘。从该网络图中,可以找出与该项目有联结关系的其他项目。" - }, - "component_projectCorrelationNetwork_description_node": { - "message": "节点:一个节点表示一个项目,节点大小与颜色的深浅表示项目活跃度的大小。" - }, - "component_projectCorrelationNetwork_description_edge": { - "message": "边:表示项目与项目之间存在联结关系,值的大小表示项目间联系的紧密程度。为了使网络图不至于太稠密,值小于 5 的边会被剪去。" - }, - "component_mostParticipatedProjects_title": { - "message": "活跃仓库网络图" - }, - "component_mostParticipatedProjects_description": { - "message": "活跃仓库网络图展示了在给定的时间段内,开发者的活跃项目,用于开发者行为的追踪与挖掘。从该网络图中,可以找出该开发者在哪些项目中活跃。" - }, - "component_mostParticipatedProjects_description_node": { - "message": "节点:一个节点表示一个项目,节点大小与颜色的深浅表示开发者对该项目活跃度的贡献值。" - }, - "component_mostParticipatedProjects_description_edge": { - "message": "边:项目与项目之间的连接关系,值的大小表示项目间联系的紧密程度。为了使网络图不至于太稠密,值小于 5 的边会被剪去。" - }, - "component_activeDeveloperCollaborationNetwork_title": { - "message": "项目活跃开发者协作网络图" - }, - "component_activeDeveloperCollaborationNetwork_description": { - "message": "项目活跃开发者协作网络图展示了在给定的时间段内,项目内部活跃的开发者之间的协作关系,用于项目内部开发者关系的追踪与挖掘。从该网络图中,可以找出该项目中最活跃的开发者,及开发者之间的协作关系。" - }, - "component_activeDeveloperCollaborationNetwork_description_node": { - "message": "节点:一个节点表示一个开发者,节点大小与颜色的深浅表示开发者对项目活跃度的贡献值。" - }, - "component_activeDeveloperCollaborationNetwork_description_edge": { - "message": "边:开发者与开发者之间的连接关系,值的大小表示开发者间联系的紧密程度。为了使网络图不至于太稠密,值小于 2.5 的边会被剪去。" - }, - "component_darkMode": { - "message": "深色模式" - }, - "teachingBubble_text_headline": { - "message": "探索 Perceptor 图表" - }, - "teachingBubble_text_content": { - "message": "点击以查看统计数据" - }, - "options_enable_title": { - "message": "开关" - }, - "options_enable_toolTip": { - "message": "是否在访问github时启用perceptor" - }, - "options_enable_toggle_autoCheck": { - "message": "启用插件" - }, - "options_components_title": { - "message": "选择组件" - }, - "options_components_toolTip": { - "message": "您可以在此选择要启用的图表组件" - }, - "options_locale_title": { - "message": "语言" - }, - "options_locale_toolTip": { - "message": "选择以何种语言显示信息" - }, - "options_update_title": { - "message": "更新" - }, - "options_update_toolTip": { - "message": "始终保持插件状态为最新将为您呈现更丰富的内容" - }, - "options_update_toggle_autoCheck": { - "message": "自动检测更新" - }, - "options_update_btn_checkUpdate": { - "message": "检查更新" - }, - "options_update_checking": { - "message": "正在检查更新" - }, - "options_update_btn_updateStatusYes": { - "message": "新更新可用" - }, - "options_update_btn_updateStatusNo": { - "message": "已是最新版本" - }, - "options_update_btn_getUpdate": { - "message": "获取更新" - }, - "notification_title_newUpdate": { - "message": "新版本更新可用" - }, - "notification_message_newUpdate": { - "message": "版本号: %v" - }, - "options_token_title": { - "message": "设置 Token" - }, - "options_token_dialog_title": { - "message": "设置 GitHub token" - }, - "options_token_toolTip": { - "message": "Github 凭据将被用于 repository 文件的访问" - }, - "options_token_btn_setToken": { - "message": "设置 token" - }, - "options_token_btn_rmToken": { - "message": "移除 token" - }, - "options_token_dialog_message": { - "message": "如何获取 GitHub token?" - }, - "options_token_dialog_description": { - "message": "您的token将仅被用于获取您的头像和昵称以及从 Github 项目读取 hypertrons.json 配置文件,无需赋予除public_repo外的额外权限。该token仅存储于本地,并不会向任何 github.com 以外的服务器发送。" - }, - "options_token_dialog_checking": { - "message": "检测中" - }, - "options_token_dialog_error": { - "message": "无效的 Token" - }, - "options_about_title": { - "message": "关于" - }, - "options_about_toolTip": { - "message": "关于 HyperCRX" - }, - "options_about_description": { - "message": "HyperCRX 是一款帮助用户洞察 GitHub 上的项目和开发者的浏览器插件。" - }, - "hypertrons_tab_title": { - "message": "Hypertrons 指令" - }, - "hypertrons_tab_description": { - "message": "可在此处使用hypertrons指令,详情请见:" - }, - "hypertrons_tab_link": { - "message": "https://www.hypertrons.io/#/zh-cn/component/index" - }, - "header_label_activity": { - "message": "活跃度" - }, - "header_label_OpenRank": { - "message": "OpenRank" - }, - "header_label_participant": { - "message": "参与人数" - }, - "header_label_contributor": { - "message": "贡献人数" - }, - "fork_popup_title": { - "message": "Fork 事件" - }, - "star_popup_title": { - "message": "Star 事件" - }, - "issue_popup_title": { - "message": "Issue 创建、关闭和评论事件" - }, - "pr_popup_title": { - "message": "PR 创建、合入和 Review 评论事件" - }, - "merged_lines_popup_title": { - "message": "通过 PR 合入增加和删除的代码行数" - }, - "docs_gpt_chat_widget": { - "message": "OSS-GPT 聊天机器人" - }, - "OSS_GPT_subtitle": { - "message": "询问任何有关 %v 的问题" - }, - "OSS_GPT_subtitle_notAvailable": { - "message": "暂未支持 %v " - }, - "OSS_GPT_welcome": { - "message": "您好,我是一个由 [DocsGPT](https://github.com/arc53/docsgpt) 和 [X-lab](https://github.com/X-lab2017) 提供支持的开源项目文档问答机器人。您可以向我询问有关 %v 的任何问题!" - }, - "OSS_GPT_notAvailable": { - "message": "OSS-GPT 暂未支持 %v。如果您想使此仓库得到文档问答支持,请前往[该 issue](https://github.com/hypertrons/hypertrons-crx/issues/609) 提交需求 :)\n\n查看[所有已支持文档](https://oss.x-lab.info/hypercrx/docsgpt_active_docs.json)\n\n您也可以随时在扩展选项页面中启用/禁用此聊天小部件。" - }, - "issue_icon": { - "message": "GitHub仓库在当月的issue数" - }, - "pr_icon": { - "message": "GitHub仓库在当月的pr数" - }, - "fork_icon": { - "message": "GitHub仓库在当月的fork数" - }, - "star_icon": { - "message": "GitHub仓库在当月的star数" - }, - "activity_icon": { - "message": "GitHub仓库在当月的activity数" - }, - "openrank_icon": { - "message": "GitHub仓库在当月的openrank值" - }, - "contributors_participants_icon": { - "message": "GitHub仓库在当月的contributors和participants数" - }, - "merged_lines_icon": { - "message": "GitHub仓库在当月的代码变化量" - }, - "OSS_GPT_errorMessage": { - "message": "很抱歉,由于成本原因,目前 OSS-GPT 功能处于停用状态。请关注 [HyperCRX](https://github.com/hypertrons/hypertrons-crx) 获取最新消息。" - } -} diff --git a/src/locales/zh_CN/translation.json b/src/locales/zh_CN/translation.json new file mode 100644 index 00000000..f4181599 --- /dev/null +++ b/src/locales/zh_CN/translation.json @@ -0,0 +1,63 @@ +{ + "global_period": "周期", + "global_day": "天", + "global_clickToshow": "点击查看", + "component_developerCollaborationNetwork_title": "开发者协作网络图", + "component_developerCollaborationNetwork_description": "开发者协作网络图展示了在给定的时间段内,开发者与开发者之间的协作关系, 用于开发者关系的追踪与挖掘。从该网络图中,可以找出与该开发者联系较为紧密的其他开发者。", + "component_developerCollaborationNetwork_description_node": "节点:一个节点表示开发者,节点大小与颜色的深浅表示开发者活跃度的大小。", + "component_developerCollaborationNetwork_description_edge": "边:开发者与开发者之间的协作关系,值的大小表示开发者间联系的紧密程度。为了使网络图不至于太稠密,值小于 2.5 的边会被剪去。", + "component_repoActORTrend_title": "活跃度与OpenRank趋势", + "component_repoActORTrend_legend1": "活跃度", + "component_repoActORTrend_legend2": "OpenRank", + "component_repoActORTrend_yName1": "活跃度", + "component_repoActORTrend_yName2": "OpenRank", + "component_developerActORTrend_title": "活跃度与OpenRank趋势", + "component_developerActORTrend_legend1": "活跃度", + "component_developerActORTrend_legend2": "OpenRank", + "component_developerActORTrend_yName1": "活跃度", + "component_developerActORTrend_yName2": "OpenRank", + "component_projectRacingBar_title": "贡献者活跃度滚榜", + "component_projectCorrelationNetwork_title": "项目关系网络图", + "component_projectRacingBar_description": "贡献者活跃度滚榜展示了项目贡献者的活跃度演化过程。", + "component_projectCorrelationNetwork_description": "项目关系网络图展示了在给定的时间段内,项目与项目之间的联结关系,用于项目间关系的追踪与挖掘。从该网络图中,可以找出与该项目有联结关系的其他项目。", + "component_projectCorrelationNetwork_description_node": "节点:一个节点表示一个项目,节点大小与颜色的深浅表示项目活跃度的大小。", + "component_projectCorrelationNetwork_description_edge": "边:表示项目与项目之间存在联结关系,值的大小表示项目间联系的紧密程度。为了使网络图不至于太稠密,值小于 5 的边会被剪去。", + "component_mostParticipatedProjects_title": "活跃仓库网络图", + "component_mostParticipatedProjects_description": "活跃仓库网络图展示了在给定的时间段内,开发者的活跃项目,用于开发者行为的追踪与挖掘。从该网络图中,可以找出该开发者在哪些项目中活跃。", + "component_mostParticipatedProjects_description_node": "节点:一个节点表示一个项目,节点大小与颜色的深浅表示开发者对该项目活跃度的贡献值。", + "component_mostParticipatedProjects_description_edge": "边:项目与项目之间的连接关系,值的大小表示项目间联系的紧密程度。为了使网络图不至于太稠密,值小于 5 的边会被剪去。", + "component_activeDeveloperCollaborationNetwork_title": "项目活跃开发者协作网络图", + "component_activeDeveloperCollaborationNetwork_description": "项目活跃开发者协作网络图展示了在给定的时间段内,项目内部活跃的开发者之间的协作关系,用于项目内部开发者关系的追踪与挖掘。从该网络图中,可以找出该项目中最活跃的开发者,及开发者之间的协作关系。", + "component_activeDeveloperCollaborationNetwork_description_node": "节点:一个节点表示一个开发者,节点大小与颜色的深浅表示开发者对项目活跃度的贡献值。", + "component_activeDeveloperCollaborationNetwork_description_edge": "边:开发者与开发者之间的连接关系,值的大小表示开发者间联系的紧密程度。为了使网络图不至于太稠密,值小于 2.5 的边会被剪去。", + "options_components_title": "选择组件", + "options_components_toolTip": "您可以在此选择要启用的图表组件", + "options_locale_title": "语言", + "options_locale_toolTip": "选择以何种语言显示信息", + "options_about_title": "关于", + "options_about_toolTip": "关于 HyperCRX", + "options_about_description": "HyperCRX 是一款帮助用户洞察 GitHub 上的项目和开发者的浏览器插件。", + "header_label_activity": "活跃度", + "header_label_OpenRank": "OpenRank", + "header_label_participant": "参与人数", + "header_label_contributor": "贡献人数", + "fork_popup_title": "Fork 事件", + "star_popup_title": "Star 事件", + "issue_popup_title": "Issue 创建、关闭和评论事件", + "pr_popup_title": "PR 创建、合入和 Review 评论事件", + "merged_lines_popup_title": "通过 PR 合入增加和删除的代码行数", + "OSS_GPT_subtitle": "询问任何有关 {{repoName}} 的问题", + "OSS_GPT_subtitle_notAvailable": "暂未支持 {{repoName}} ", + "OSS_GPT_welcome": "您好,我是一个由 [DocsGPT](https://github.com/arc53/docsgpt) 和 [X-lab](https://github.com/X-lab2017) 提供支持的开源项目文档问答机器人。您可以向我询问有关 {{repoName}} 的任何问题!", + "OSS_GPT_notAvailable": "OSS-GPT 暂未支持 {{repoName}}。如果您想使此仓库得到文档问答支持,请前往[该 issue](https://github.com/hypertrons/hypertrons-crx/issues/609) 提交需求 :)\n\n查看[所有已支持文档](https://oss.x-lab.info/hypercrx/docsgpt_active_docs.json)\n\n您也可以随时在扩展选项页面中启用/禁用此聊天小部件。", + "OSS_GPT_errorMessage": "很抱歉,由于成本原因,目前 OSS-GPT 功能处于停用状态。请关注 [HyperCRX](https://github.com/hypertrons/hypertrons-crx) 获取最新消息。", + "icon_tip": "GitHub仓库在当月的{{icon_content}}", + "issue_icon": "issue数", + "pr_icon": "pr数", + "fork_icon": "fork数", + "star_icon": "star数", + "activity_icon": "activity数", + "openrank_icon": "openrank值", + "contributors_participants_icon": "contributors和participants数", + "merged_lines_icon": "代码变化量" +} diff --git a/src/pages/ContentScripts/features/developer-activity-openrank-trends/view.tsx b/src/pages/ContentScripts/features/developer-activity-openrank-trends/view.tsx index 2feda4d6..8211d2df 100644 --- a/src/pages/ContentScripts/features/developer-activity-openrank-trends/view.tsx +++ b/src/pages/ContentScripts/features/developer-activity-openrank-trends/view.tsx @@ -1,12 +1,11 @@ import React, { useState, useEffect } from 'react'; - import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import Bars from '../../../../components/Bars'; import { UserMeta } from '../../../../api/common'; - +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; const githubTheme = getGithubTheme(); const generateBarsData = (activity: any, openrank: any, updatedAt: number) => { @@ -24,12 +23,13 @@ interface Props { const View = ({ activity, openrank, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (!activity || !openrank) return null; @@ -37,14 +37,14 @@ const View = ({ activity, openrank, meta }: Props): JSX.Element | null => { return (
-

{getMessageByLocale('component_developerActORTrend_title', options.locale)}

+

{t('component_developerActORTrend_title')}

diff --git a/src/pages/ContentScripts/features/developer-networks/view.tsx b/src/pages/ContentScripts/features/developer-networks/view.tsx index 6073af06..4014683a 100644 --- a/src/pages/ContentScripts/features/developer-networks/view.tsx +++ b/src/pages/ContentScripts/features/developer-networks/view.tsx @@ -1,12 +1,11 @@ import React, { useState, useEffect } from 'react'; import ReactModal from 'react-modal'; - import Graph from '../../../../components/Graph'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import { iconDeveloperNetwork, iconRepoNetwork } from './icon-svg-path'; import './react-modal.scss'; - +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; const DEVELOPER_PERIOD = 90; const REPO_PERIOD = 90; const GRAPH_STYLE = { @@ -23,12 +22,12 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }: const [options, setOptions] = useState(defaults); const [showDeveloperNetwork, setShowDeveloperNetwork] = useState(false); const [showRepoNetwork, setShowRepoNetwork] = useState(false); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); })(); - }, []); + }, [options.locale]); return (
@@ -56,17 +55,14 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }: }} > - {getMessageByLocale('component_developerCollaborationNetwork_title', options.locale)} + {t('component_developerCollaborationNetwork_title')} @@ -92,17 +88,14 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }: }} > - {getMessageByLocale('component_mostParticipatedProjects_title', options.locale)} + {t('component_mostParticipatedProjects_title')} @@ -119,10 +112,9 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }: >
- {getMessageByLocale('component_developerCollaborationNetwork_title', options.locale)} + {t('component_developerCollaborationNetwork_title')}
- {getMessageByLocale('global_period', options.locale)}: {REPO_PERIOD}{' '} - {getMessageByLocale('global_day', options.locale)} + {t('global_period')}: {REPO_PERIOD} {t('global_day', { count: REPO_PERIOD })}
@@ -133,14 +125,10 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }:
-

{getMessageByLocale('component_developerCollaborationNetwork_description', options.locale)}

+

{t('component_developerCollaborationNetwork_description')}

    -
  • - {getMessageByLocale('component_developerCollaborationNetwork_description_node', options.locale)} -
  • -
  • - {getMessageByLocale('component_developerCollaborationNetwork_description_edge', options.locale)} -
  • +
  • {t('component_developerCollaborationNetwork_description_node')}
  • +
  • {t('component_developerCollaborationNetwork_description_edge')}
@@ -159,10 +147,9 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }: >
- {getMessageByLocale('component_mostParticipatedProjects_title', options.locale)} + {t('component_mostParticipatedProjects_title')}
- {getMessageByLocale('global_period', options.locale)}: {DEVELOPER_PERIOD}{' '} - {getMessageByLocale('global_day', options.locale)} + {t('global_period')}: {DEVELOPER_PERIOD} {t('global_day', { count: REPO_PERIOD })}
@@ -173,10 +160,10 @@ const View = ({ currentRepo: currentDeveloper, developerNetwork, repoNetwork }:
-

{getMessageByLocale('component_mostParticipatedProjects_description', options.locale)}

+

{t('component_mostParticipatedProjects_description')}

    -
  • {getMessageByLocale('component_mostParticipatedProjects_description_node', options.locale)}
  • -
  • {getMessageByLocale('component_mostParticipatedProjects_description_edge', options.locale)}
  • +
  • {t('component_mostParticipatedProjects_description_node')}
  • +
  • {t('component_mostParticipatedProjects_description_edge')}
diff --git a/src/pages/ContentScripts/features/oss-gpt/view.tsx b/src/pages/ContentScripts/features/oss-gpt/view.tsx index cbd31e69..c008a5da 100644 --- a/src/pages/ContentScripts/features/oss-gpt/view.tsx +++ b/src/pages/ContentScripts/features/oss-gpt/view.tsx @@ -13,9 +13,9 @@ import { import { getAnswer } from './service'; import './rcw.scss'; import exists from '../../../../helpers/exists'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; - +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; interface Props { theme: 'light' | 'dark'; currentRepo: string; @@ -30,19 +30,8 @@ const UserTimeStamp: React.FC = () => { return
{moment().format('LT')}
; }; -const displayWelcome = (repoName: string, locale: string) => { - addResponseMessage(getMessageByLocale('OSS_GPT_welcome', locale).replace('%v', repoName)); - renderCustomComponent(ResponseTimeStamp, {}); -}; - -const displayNotAvailable = (repoName: string, locale: string) => { - addResponseMessage(getMessageByLocale('OSS_GPT_notAvailable', locale).replace('%v', repoName)); - renderCustomComponent(ResponseTimeStamp, {}); -}; - -// Due to cost reasons, backend is not available now. This part can be removed when the backend is restored. -const backendNotAvailable = (locale: string) => { - addResponseMessage(getMessageByLocale('OSS_GPT_errorMessage', locale)); +const displayResponseMessage = (locale: string) => { + addResponseMessage(locale); renderCustomComponent(ResponseTimeStamp, {}); }; @@ -51,12 +40,13 @@ const View = ({ theme, currentRepo, currentDocsName }: Props): JSX.Element => { const [history, setHistory] = useState<[string, string]>(['', '']); const mouseDownX = useRef(0); // X position when mouse down const rcwWidth = useRef(0); // rcw width when mouse down - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); useEffect(() => { // when repo changes @@ -64,9 +54,9 @@ const View = ({ theme, currentRepo, currentDocsName }: Props): JSX.Element => { setHistory(['', '']); // clear history if (currentDocsName) { // if docs for current repo is available - displayWelcome(currentRepo, options.locale); + displayResponseMessage(t('OSS_GPT_welcome', { repoName: currentRepo })); } else { - displayNotAvailable(currentRepo, options.locale); + displayResponseMessage(t('OSS_GPT_notAvailable', { repoName: currentRepo })); } }, [options, currentRepo, currentDocsName]); @@ -119,8 +109,8 @@ const View = ({ theme, currentRepo, currentDocsName }: Props): JSX.Element => { }, []); const subtitle = currentDocsName - ? getMessageByLocale('OSS_GPT_subtitle', options.locale).replace('%v', currentRepo) - : getMessageByLocale('OSS_GPT_subtitle_notAvailable', options.locale).replace('%v', currentRepo); + ? t('OSS_GPT_subtitle', { repoName: currentRepo }) + : t('OSS_GPT_subtitle_notAvailable', { repoName: currentRepo }); const handleNewUserMessage = async (newMessage: string) => { renderCustomComponent(UserTimeStamp, {}); @@ -130,7 +120,7 @@ const View = ({ theme, currentRepo, currentDocsName }: Props): JSX.Element => { if (currentDocsName) { const answer = await getAnswer(currentDocsName, newMessage, history); if (answer == 'error') { - backendNotAvailable(options.locale); + displayResponseMessage(t('OSS_GPT_errorMessage')); } else { addResponseMessage(answer); renderCustomComponent(ResponseTimeStamp, {}); @@ -138,7 +128,7 @@ const View = ({ theme, currentRepo, currentDocsName }: Props): JSX.Element => { setHistory([newMessage, answer]); // update history } } else { - displayNotAvailable(currentRepo, options.locale); + displayResponseMessage(t('OSS_GPT_notAvailable', { repoName: currentRepo })); } toggleMsgLoader(); diff --git a/src/pages/ContentScripts/features/repo-activity-openrank-trends/view.tsx b/src/pages/ContentScripts/features/repo-activity-openrank-trends/view.tsx index dfd1cac0..01c263bf 100644 --- a/src/pages/ContentScripts/features/repo-activity-openrank-trends/view.tsx +++ b/src/pages/ContentScripts/features/repo-activity-openrank-trends/view.tsx @@ -1,12 +1,11 @@ import React, { useState, useEffect } from 'react'; - import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import Bars from '../../../../components/Bars'; import { RepoMeta } from '../../../../api/common'; - +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; const githubTheme = getGithubTheme(); const generateBarsData = (activity: any, openrank: any, updatedAt: number) => { @@ -25,12 +24,13 @@ interface Props { const View = ({ repoName, activity, openrank, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (!activity || !openrank) return null; @@ -50,14 +50,14 @@ const View = ({ repoName, activity, openrank, meta }: Props): JSX.Element | null return (
-

{getMessageByLocale('component_repoActORTrend_title', options.locale)}

+

{t('component_repoActORTrend_title')}

{ const [speed, setSpeed] = useState(1); const [playing, setPlaying] = useState(false); const mediaControlersRef = useRef(null); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); return (
- {getMessageByLocale('component_projectRacingBar_title', options.locale)} + {t('component_projectRacingBar_title')}
{/* speed control */} @@ -85,7 +86,7 @@ const View = ({ currentRepo, repoActivityDetails }: Props): JSX.Element => {
-

{getMessageByLocale('component_projectRacingBar_description', options.locale)}

+

{t('component_projectRacingBar_description')}

diff --git a/src/pages/ContentScripts/features/repo-fork-tooltip/view.tsx b/src/pages/ContentScripts/features/repo-fork-tooltip/view.tsx index cfdc19a4..091ef5e1 100644 --- a/src/pages/ContentScripts/features/repo-fork-tooltip/view.tsx +++ b/src/pages/ContentScripts/features/repo-fork-tooltip/view.tsx @@ -1,12 +1,13 @@ import React, { useState, useEffect } from 'react'; - import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; import ForkChart from './ForkChart'; import { RepoMeta } from '../../../../api/common'; import TooltipTrigger from '../../../../components/TooltipTrigger'; +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; + const githubTheme = getGithubTheme(); interface Props { @@ -16,12 +17,13 @@ interface Props { const View = ({ forks, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (!forks) return null; @@ -35,9 +37,9 @@ const View = ({ forks, meta }: Props): JSX.Element | null => { alignItems: 'center', }} > -
{getMessageByLocale('fork_popup_title', options.locale)}
+
{t('fork_popup_title')}
- +
{ + const [options, setOptions] = useState(defaults); + const { t, i18n } = useTranslation(); + useEffect(() => { + (async function () { + setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); + })(); + }, [options.locale]); + + if (isNull(activity)) return null; + + const activityData = generateDataByMonth(activity, meta.updatedAt); + return ( + <> +
+
{t('header_label_activity')}
+ +
+ + + ); +}; + +export default ActivityView; diff --git a/src/pages/ContentScripts/features/repo-header-labels/index.tsx b/src/pages/ContentScripts/features/repo-header-labels/index.tsx index 3b058858..212eceee 100644 --- a/src/pages/ContentScripts/features/repo-header-labels/index.tsx +++ b/src/pages/ContentScripts/features/repo-header-labels/index.tsx @@ -1,10 +1,13 @@ import features from '../../../../feature-manager'; import View from './view'; +import ActivityView from './activityView'; +import OpenrankView from './openrankView'; +import ParticipantView from './participantView'; +import { NativePopover } from '../../components/NativePopover'; import elementReady from 'element-ready'; import { getRepoName, hasRepoContainerHeader, isPublicRepoWithMeta } from '../../../../helpers/get-repo-info'; import { getActivity, getOpenrank, getParticipant, getContributor } from '../../../../api/repo'; import { RepoMeta, metaStore } from '../../../../api/common'; - import React from 'react'; import { render, Container } from 'react-dom'; import $ from 'jquery'; @@ -41,6 +44,26 @@ const init = async (): Promise => { renderTo(container); await elementReady('#repository-container-header'); $('#repository-container-header').find('span.Label').after(container); + + await elementReady('#activity-header-label'); + await elementReady('#OpenRank-header-label'); + await elementReady('#participant-header-label'); + const placeholderElement = $('
').appendTo('body')[0]; + + render( + <> + + + + + + + + + + , + placeholderElement + ); }; const restore = async () => { diff --git a/src/pages/ContentScripts/features/repo-header-labels/openrankView.tsx b/src/pages/ContentScripts/features/repo-header-labels/openrankView.tsx new file mode 100644 index 00000000..56907955 --- /dev/null +++ b/src/pages/ContentScripts/features/repo-header-labels/openrankView.tsx @@ -0,0 +1,50 @@ +import getGithubTheme from '../../../../helpers/get-github-theme'; +import { isNull } from '../../../../helpers/is-null'; +import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; +import generateDataByMonth from '../../../../helpers/generate-data-by-month'; +import OpenRankChart from './OpenRankChart'; +import { RepoMeta } from '../../../../api/common'; +import React, { useState, useEffect } from 'react'; +import TooltipTrigger from '../../../../components/TooltipTrigger'; + +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; +const githubTheme = getGithubTheme(); + +interface Props { + openrank: any; + meta: RepoMeta; +} + +const OpenrankView = ({ openrank, meta }: Props): JSX.Element | null => { + const [options, setOptions] = useState(defaults); + const { t, i18n } = useTranslation(); + useEffect(() => { + (async function () { + setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); + })(); + }, [options.locale]); + + if (isNull(openrank)) return null; + + const openrankData = generateDataByMonth(openrank, meta.updatedAt); + return ( + <> +
+
{t('header_label_OpenRank')}
+ +
+ + + ); +}; + +export default OpenrankView; diff --git a/src/pages/ContentScripts/features/repo-header-labels/participantView.tsx b/src/pages/ContentScripts/features/repo-header-labels/participantView.tsx new file mode 100644 index 00000000..2066ff15 --- /dev/null +++ b/src/pages/ContentScripts/features/repo-header-labels/participantView.tsx @@ -0,0 +1,74 @@ +import getGithubTheme from '../../../../helpers/get-github-theme'; +import { isNull } from '../../../../helpers/is-null'; +import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; +import generateDataByMonth from '../../../../helpers/generate-data-by-month'; +import ParticipantChart from './ParticipantChart'; +import ContributorChart from './ContributorChart'; +import { RepoMeta } from '../../../../api/common'; +import React, { useState, useEffect } from 'react'; +import TooltipTrigger from '../../../../components/TooltipTrigger'; + +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; +const githubTheme = getGithubTheme(); + +interface Props { + participant: any; + contributor: any; + meta: RepoMeta; +} + +const ParticipantView = ({ participant, contributor, meta }: Props): JSX.Element | null => { + const [options, setOptions] = useState(defaults); + const { t, i18n } = useTranslation(); + useEffect(() => { + (async function () { + setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); + })(); + }, [options.locale]); + + if (isNull(participant) || isNull(contributor)) return null; + + const participantData = generateDataByMonth(participant, meta.updatedAt); + const contributorData = generateDataByMonth(contributor, meta.updatedAt); + + return ( + <> +
+
{t('header_label_contributor')}
+ +
+ +
+
{t('header_label_participant')}
+ +
+ + + ); +}; + +export default ParticipantView; diff --git a/src/pages/ContentScripts/features/repo-header-labels/view.tsx b/src/pages/ContentScripts/features/repo-header-labels/view.tsx index 901965d5..7020a32a 100644 --- a/src/pages/ContentScripts/features/repo-header-labels/view.tsx +++ b/src/pages/ContentScripts/features/repo-header-labels/view.tsx @@ -1,21 +1,15 @@ import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import { isNull } from '../../../../helpers/is-null'; import { numberWithCommas } from '../../../../helpers/formatter'; -import { NativePopover } from '../../components/NativePopover'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import { rocketLight, rocketDark } from './base64'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; -import ActivityChart from './ActivityChart'; -import OpenRankChart from './OpenRankChart'; -import ParticipantChart from './ParticipantChart'; -import ContributorChart from './ContributorChart'; import { RepoMeta } from '../../../../api/common'; import React, { useState, useEffect } from 'react'; -import { render } from 'react-dom'; -import $ from 'jquery'; -import TooltipTrigger from '../../../../components/TooltipTrigger'; + +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; const githubTheme = getGithubTheme(); interface Props { @@ -28,83 +22,13 @@ interface Props { const View = ({ activity, openrank, participant, contributor, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); - - useEffect(() => { - const placeholderElement = $('
').appendTo('body')[0]; - render( - <> - -
-
{getMessageByLocale('header_label_activity', options.locale)}
- -
- -
- -
-
{getMessageByLocale('header_label_OpenRank', options.locale)}
- -
- -
- -
-
{getMessageByLocale('header_label_contributor', options.locale)}
- -
- -
-
{getMessageByLocale('header_label_participant', options.locale)}
- -
- -
- , - placeholderElement - ); - }, []); + }, [options.locale]); if (isNull(activity) || isNull(openrank) || isNull(participant) || isNull(contributor)) return null; diff --git a/src/pages/ContentScripts/features/repo-issue-tooltip/view.tsx b/src/pages/ContentScripts/features/repo-issue-tooltip/view.tsx index 4242f84a..c684e4b1 100644 --- a/src/pages/ContentScripts/features/repo-issue-tooltip/view.tsx +++ b/src/pages/ContentScripts/features/repo-issue-tooltip/view.tsx @@ -1,14 +1,14 @@ import React, { useState, useEffect } from 'react'; import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import { isNull, isAllNull } from '../../../../helpers/is-null'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; import IssueChart from './IssueChart'; import { RepoMeta } from '../../../../api/common'; import TooltipTrigger from '../../../../components/TooltipTrigger'; - +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; const githubTheme = getGithubTheme(); export interface IssueDetail { @@ -33,12 +33,13 @@ const generateData = (issueDetail: IssueDetail, updatedAt: number): any => { const View = ({ currentRepo, issueDetail, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (isNull(issueDetail) || isAllNull(issueDetail)) return null; @@ -69,9 +70,9 @@ const View = ({ currentRepo, issueDetail, meta }: Props): JSX.Element | null => alignItems: 'center', }} > -
{getMessageByLocale('issue_popup_title', options.locale)}
+
{t('issue_popup_title')}
- +
{ const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); return (
- {getMessageByLocale('component_projectCorrelationNetwork_title', options.locale)} + {t('component_projectCorrelationNetwork_title')}
- {getMessageByLocale('global_period', options.locale)}: {REPO_PERIOD}{' '} - {getMessageByLocale('global_day', options.locale)} + {t('global_period')}: {REPO_PERIOD} {t('global_day', { count: REPO_PERIOD })}
@@ -45,10 +45,10 @@ const View = ({ currentRepo, repoNetwork, developerNetwork }: Props): JSX.Elemen
-

{getMessageByLocale('component_projectCorrelationNetwork_description', options.locale)}

+

{t('component_projectCorrelationNetwork_description')}

    -
  • {getMessageByLocale('component_projectCorrelationNetwork_description_node', options.locale)}
  • -
  • {getMessageByLocale('component_projectCorrelationNetwork_description_edge', options.locale)}
  • +
  • {t('component_projectCorrelationNetwork_description_node')}
  • +
  • {t('component_projectCorrelationNetwork_description_edge')}
@@ -56,10 +56,9 @@ const View = ({ currentRepo, repoNetwork, developerNetwork }: Props): JSX.Elemen
- {getMessageByLocale('component_activeDeveloperCollaborationNetwork_title', options.locale)} + {t('component_activeDeveloperCollaborationNetwork_title')}
- {getMessageByLocale('global_period', options.locale)}: {DEVELOPER_PERIOD}{' '} - {getMessageByLocale('global_day', options.locale)} + {t('global_period')}: {DEVELOPER_PERIOD} {t('global_day', { count: REPO_PERIOD })}
@@ -70,14 +69,10 @@ const View = ({ currentRepo, repoNetwork, developerNetwork }: Props): JSX.Elemen
-

{getMessageByLocale('component_activeDeveloperCollaborationNetwork_description', options.locale)}

+

{t('component_activeDeveloperCollaborationNetwork_description')}

    -
  • - {getMessageByLocale('component_activeDeveloperCollaborationNetwork_description_node', options.locale)} -
  • -
  • - {getMessageByLocale('component_activeDeveloperCollaborationNetwork_description_edge', options.locale)} -
  • +
  • {t('component_activeDeveloperCollaborationNetwork_description_node')}
  • +
  • {t('component_activeDeveloperCollaborationNetwork_description_edge')}
diff --git a/src/pages/ContentScripts/features/repo-pr-tooltip/view.tsx b/src/pages/ContentScripts/features/repo-pr-tooltip/view.tsx index 2b232f3d..6ecfd4fc 100644 --- a/src/pages/ContentScripts/features/repo-pr-tooltip/view.tsx +++ b/src/pages/ContentScripts/features/repo-pr-tooltip/view.tsx @@ -1,7 +1,5 @@ import React, { useState, useEffect } from 'react'; - import getGithubTheme from '../../../../helpers/get-github-theme'; -import getMessageByLocale from '../../../../helpers/get-message-by-locale'; import { isNull, isAllNull } from '../../../../helpers/is-null'; import optionsStorage, { HypercrxOptions, defaults } from '../../../../options-storage'; import generateDataByMonth from '../../../../helpers/generate-data-by-month'; @@ -10,6 +8,8 @@ import MergedLinesChart from './MergedLinesChart'; import { RepoMeta } from '../../../../api/common'; import TooltipTrigger from '../../../../components/TooltipTrigger'; const githubTheme = getGithubTheme(); +import { useTranslation } from 'react-i18next'; +import '../../../../helpers/i18n'; export interface PRDetail { PROpened: any; @@ -46,12 +46,13 @@ const generateMergedLinesChartData = (PRDetail: PRDetail, updatedAt: number): an const View = ({ currentRepo, PRDetail, meta }: Props): JSX.Element | null => { const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (isNull(PRDetail) || isAllNull(PRDetail)) return null; @@ -82,8 +83,8 @@ const View = ({ currentRepo, PRDetail, meta }: Props): JSX.Element | null => { alignItems: 'center', }} > -
{getMessageByLocale('pr_popup_title', options.locale)}
- +
{t('pr_popup_title')}
+
{ alignItems: 'center', }} > -
{getMessageByLocale('merged_lines_popup_title', options.locale)}
- +
{t('merged_lines_popup_title')}
+
{ const [options, setOptions] = useState(defaults); - + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setOptions(await optionsStorage.getAll()); + i18n.changeLanguage(options.locale); })(); - }, []); + }, [options.locale]); if (!stars) return null; @@ -36,9 +37,9 @@ const View = ({ stars, meta }: Props): JSX.Element | null => { alignItems: 'center', }} > -
{getMessageByLocale('star_popup_title', options.locale)}
+
{t('star_popup_title')}
- +
{ const [version, setVersion] = useState(); const [options, setOptions] = useState(); + const { t, i18n } = useTranslation(); useEffect(() => { (async function () { setVersion((await chrome.management.getSelf()).version); @@ -78,15 +79,16 @@ const Options = (): JSX.Element => { >
-

{getMessageByLocale('options_locale_title', options.locale)}

- +

{t('options_locale_title')}

+
-

{getMessageByLocale('options_locale_toolTip', options.locale)} :

+

{t('options_locale_toolTip')} :

{ await optionsStorage.set({ locale: e.target.value }); + i18n.changeLanguage(e.target.value); setOptions(await optionsStorage.getAll()); }} > @@ -108,11 +110,11 @@ const Options = (): JSX.Element => { >
-

{getMessageByLocale('options_components_title', options.locale)}

- +

{t('options_components_title')}

+
-

{getMessageByLocale('options_components_toolTip', options.locale)} :

+

{t('options_components_toolTip')} :

{importedFeatures.map((name: FeatureName) => { return buildFeatureCheckbox(name, options[`hypercrx-${name}`]); @@ -130,11 +132,11 @@ const Options = (): JSX.Element => { >
-

{getMessageByLocale('options_about_title', options.locale)}

- +

{t('options_about_title')}

+
-

{getMessageByLocale('options_about_description', options.locale)}

+

{t('options_about_description')}

GitHub:{' '}