From 10f095378bc53947682d9432e9d6941c1d309274 Mon Sep 17 00:00:00 2001 From: Lam Tang Date: Tue, 26 Sep 2023 20:35:39 +0800 Subject: [PATCH] feat: media player controllers for contributor activity racing bar (#744) * refactor: use forwardRef and useImperativeHandle to control child component * feat: add player buttons (only UI) * feat: add speed controller (only UI) * refactor: abstract and encapsulate the 'loadAvatars' related operations into a React custom hook * refactor: to get an echarts option through a function call * feat: player buttons that support long press event * fix: container doesn't has width before appeded to the DOM tree * feat: media player controllers for racing bars * chore: improve the interaction * chore: filter bars to improve performance in large community * style: improve UI in dark theme * chore: remove unused import sentence * fix: only cache successful extracted color --------- Co-authored-by: Zi1l <1260497933@qq.com> --- INSTALLATION.md | 4 +- INSTALLATION.zh-CN.md | 6 +- README.md | 10 +- README.zh-CN.md | 26 +- package.json | 1 + scripts/bump-version.cjs | 27 +- src/locales/en/messages.json | 3 - src/locales/zh_CN/messages.json | 3 - .../AvatarColorStore.ts | 15 +- .../repo-activity-racing-bar/PlayerButton.tsx | 58 +++ .../repo-activity-racing-bar/RacingBar.tsx | 383 ++++++++---------- .../SpeedController.tsx | 39 ++ .../features/repo-activity-racing-bar/data.ts | 170 ++++++++ .../repo-activity-racing-bar/index.tsx | 13 +- .../useLoadedAvatars.ts | 19 + .../repo-activity-racing-bar/view.tsx | 74 +++- src/pages/ContentScripts/index.scss | 19 - yarn.lock | 2 +- 18 files changed, 551 insertions(+), 321 deletions(-) create mode 100644 src/pages/ContentScripts/features/repo-activity-racing-bar/PlayerButton.tsx create mode 100644 src/pages/ContentScripts/features/repo-activity-racing-bar/SpeedController.tsx create mode 100644 src/pages/ContentScripts/features/repo-activity-racing-bar/data.ts create mode 100644 src/pages/ContentScripts/features/repo-activity-racing-bar/useLoadedAvatars.ts diff --git a/INSTALLATION.md b/INSTALLATION.md index 9b894d44..b2c0820d 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -8,7 +8,7 @@ We welcome users to install and try our Hypertrons Chrome Extension. If you have ### Chrome / Edge -1. Install our extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc) or [Edge Extensions Home](https://microsoftedge.microsoft.com/addons/detail/hypercrx/lbbajaehiibofpconjgdjonmkidpcome?hl=zh-CN) +1. Install our extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc) or [Edge Extensions Home](https://microsoftedge.microsoft.com/addons/detail/hypercrx/lbbajaehiibofpconjgdjonmkidpcome?hl=zh-CN) [Chrome] Visit [Chrome Web Store](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc),and click **[Add to Chrome]**. @@ -46,7 +46,6 @@ We welcome users to install and try our Hypertrons Chrome Extension. If you have - 3. You can change configuration of hypertrons-crx by visiting the setting page: @@ -74,7 +73,6 @@ We welcome users to install and try our Hypertrons Chrome Extension. If you have
- ## Install from released package The latest release can be found on this page https://github.com/hypertrons/hypertrons-crx/releases , where `hypertrons.crx` and `hypertrons.zip` are available under `Assets`. Currently, the extension can be installed to multiple browsers that use the chromium kernel. Some common ones are listed as follows: diff --git a/INSTALLATION.zh-CN.md b/INSTALLATION.zh-CN.md index c34075c1..0ba8f78f 100644 --- a/INSTALLATION.zh-CN.md +++ b/INSTALLATION.zh-CN.md @@ -12,7 +12,7 @@ Hypertrons-crx 现已登陆 [Chrome 网上应用商店](https://chrome.google.co ### Chrome 浏览器 / Edge 浏览器 -1. 安装Hypertrons-crx插件 +1. 安装 Hypertrons-crx 插件 [Chrome]点击 [此链接](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc) 访问 “Hypercrx” 扩展程序主页,点击 “添加至 Chrome” ,并确认。 @@ -50,9 +50,6 @@ Hypertrons-crx 现已登陆 [Chrome 网上应用商店](https://chrome.google.co - - - 3. 如需对插件进行设置,请点击以下按钮,可以进入到插件设置页面。在设置页面,您可以更改相关配置。 @@ -80,7 +77,6 @@ Hypertrons-crx 现已登陆 [Chrome 网上应用商店](https://chrome.google.co
- ## 手动下载安装包 您可以在[这里](https://github.com/hypertrons/hypertrons-crx/releases)下载最新的安装包。 当前版本支持 Chromium 内核浏览器,如: diff --git a/README.md b/README.md index b265ad55..b585caa4 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,6 @@ You can find these dashboards in: - ### Project Related @@ -93,8 +92,7 @@ You can find these dashboards in: -
- + - **Project Correlation Network**: 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. @@ -104,7 +102,6 @@ You can find these dashboards in: - **Repo Details**: Trends of Activity, OpenRank, Participants, Fork Events, Star Events, Open Issue Events, Issue Comment Events, Open PR Events, PR Merge Events, Review Comment Events, Merged Addition & Deletion Code Lines. - ### Developer Related @@ -133,9 +130,7 @@ You can find these dashboards in: /> -
- - + - **Developer Collaboration Network**: Developer Collaboration Network shows the collaboration between developers for a given time period. From this graph you can find other developers who are closest to a given developer. - **Developer's Most Participated Repos**: Developer's 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. @@ -151,6 +146,7 @@ OSS-GPT is an open source project document answering robot integrated with [Docs ## Contributing Please read [CONTRIBUTING](./CONTRIBUTING.md) if you are new here or not familiar with the basic rules of Git/GitHub world. + ### Requirements 1. node >= 18 diff --git a/README.zh-CN.md b/README.zh-CN.md index 004ec0a8..dabdc09e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -16,15 +16,15 @@ Language : [English](./README.md) | 中文 ## 安装与使用 📢 -Chrome [前往Chrome商店安装插件](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc) +Chrome [前往 Chrome 商店安装插件](https://chrome.google.com/webstore/detail/hypercrx/ijchfbpdgeljmhnhokmekkecpbdkgabc) -Edge [前往Edge商店安装插件](https://microsoftedge.microsoft.com/addons/detail/hypercrx/lbbajaehiibofpconjgdjonmkidpcome) +Edge [前往 Edge 商店安装插件](https://microsoftedge.microsoft.com/addons/detail/hypercrx/lbbajaehiibofpconjgdjonmkidpcome) 获取更多信息,请查阅[安装指南](./INSTALLATION.zh-CN.md)。 ## 数据来源 -`Hypercrx`呈现的所有数据都由[OpenDigger](https://github.com/X-lab2017/open-digger)产生。OpenDigger是一个聚焦于开源分析的开源项目。数据会在每个月第二天更新。 +`Hypercrx`呈现的所有数据都由[OpenDigger](https://github.com/X-lab2017/open-digger)产生。OpenDigger 是一个聚焦于开源分析的开源项目。数据会在每个月第二天更新。 ## 可视化看板 🔥🔥🔥 @@ -94,16 +94,15 @@ Language : [English](./README.md) | 中文 - - + - **项目关系网络图**: 项目关系网络图展示了在给定的时间段内,项目与项目之间的联结关系,**_用于项目间关系的追踪与挖掘_**。从该网络图中,可以找出与该项目有联结关系的其他项目。 - **项目活跃开发者协作网络图**: 项目活跃开发者协作网络图展示了在给定的时间段内,项目内部活跃的开发者之间的协作关系,**_用于项目内部开发者关系的追踪与挖掘_**。从该网络图中,可以找出该项目中最活跃的开发者,及开发者之间的协作关系。 -- **项目活跃度&OpenRank趋势图**:项目活跃度和OpenRank趋势图显示了项目成立至今的活跃度和OpenRank这两个指标的变化。您可以利用鼠标或触控板在图表内缩放和拖拽,此外,您还可以点击Legend按钮来控制图例的显示和隐藏。 +- **项目活跃度&OpenRank 趋势图**:项目活跃度和 OpenRank 趋势图显示了项目成立至今的活跃度和 OpenRank 这两个指标的变化。您可以利用鼠标或触控板在图表内缩放和拖拽,此外,您还可以点击 Legend 按钮来控制图例的显示和隐藏。 -- **仓库详情**: 显示了以下统计指标的历史值。活跃度、OpenRank、参与人数、Fork事件、Star事件、Issue创建事件、Issue评论事件、PR创建事件、PR合入事件、Review评论事件、通过PR合入增加和删除的代码行数。 +- **仓库详情**: 显示了以下统计指标的历史值。活跃度、OpenRank、参与人数、Fork 事件、Star 事件、Issue 创建事件、Issue 评论事件、PR 创建事件、PR 合入事件、Review 评论事件、通过 PR 合入增加和删除的代码行数。 ### 开发者关系挖掘 @@ -133,17 +132,15 @@ Language : [English](./README.md) | 中文 /> - - + - -- **开发者协作网络图**: 开发者协作网络图展示了在给定的时间段内,开发者与开发者之间的协作关系, ***用于开发者关系的追踪与挖掘***。从该网络图中,可以找出与指定开发者联系较为紧密的其他开发者。 -- **活跃仓库网络图**: 活跃仓库网络图展示了在给定的时间段内,开发者的活跃项目,***用于开发者行为的追踪与挖掘***。从该网络图中,可以找出该开发者在哪些项目中活跃。 -- **开发者活跃度&OpenRank趋势图**:开发者活跃度和OpenRank趋势图显示了项目成立至今的活跃度和OpenRank这两个指标的变化。您可以利用鼠标或触控板在图表内缩放和拖拽,此外,您还可以点击Legend按钮来控制图例的显示和隐藏。 +- **开发者协作网络图**: 开发者协作网络图展示了在给定的时间段内,开发者与开发者之间的协作关系, **_用于开发者关系的追踪与挖掘_**。从该网络图中,可以找出与指定开发者联系较为紧密的其他开发者。 +- **活跃仓库网络图**: 活跃仓库网络图展示了在给定的时间段内,开发者的活跃项目,**_用于开发者行为的追踪与挖掘_**。从该网络图中,可以找出该开发者在哪些项目中活跃。 +- **开发者活跃度&OpenRank 趋势图**:开发者活跃度和 OpenRank 趋势图显示了项目成立至今的活跃度和 OpenRank 这两个指标的变化。您可以利用鼠标或触控板在图表内缩放和拖拽,此外,您还可以点击 Legend 按钮来控制图例的显示和隐藏。 ## OSS-GPT -OSS-GPT是集成了[DocsGPT](https://github.com/arc53/docsgpt)能力的开源项目文档问答机器人。对已经支持的项目,只需打开对应的项目仓库主页,即可询问有关于该仓库的任何问题。你可以通过[issue#609](https://github.com/hypertrons/hypertrons-crx/issues/609)以使你的开源项目获得OSS-GPT的支持。 +OSS-GPT 是集成了[DocsGPT](https://github.com/arc53/docsgpt)能力的开源项目文档问答机器人。对已经支持的项目,只需打开对应的项目仓库主页,即可询问有关于该仓库的任何问题。你可以通过[issue#609](https://github.com/hypertrons/hypertrons-crx/issues/609)以使你的开源项目获得 OSS-GPT 的支持。 = 16.14 2. yarn + ### 快速开始 1. git clone https://github.com/hypertrons/hypertrons-crx diff --git a/package.json b/package.json index f2e2dff4..c08a7286 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "update-version": "node scripts/bump-version.cjs" }, "dependencies": { + "@ant-design/icons": "^5.2.6", "@fluentui/react": "^8.62.0", "@fluentui/react-hooks": "^8.3.13", "@hot-loader/react-dom": "^17.0.2", diff --git a/scripts/bump-version.cjs b/scripts/bump-version.cjs index c28ced5d..89200f31 100644 --- a/scripts/bump-version.cjs +++ b/scripts/bump-version.cjs @@ -1,14 +1,15 @@ // according to https://github.com/TriPSs/conventional-changelog-action#pre-commit-hook // this script should be a CommonJS module -const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/i +const semver = + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/i; -function validate({version}) { +function validate({ version }) { // validate if the given version conforms semver return String(version).match(semver) === null; } -function compare({oldVersion, newVersion}) { +function compare({ oldVersion, newVersion }) { // compare oldVersion and newVersion number // return -1 if oldVersion is greater; // 0 if two versions are equal; @@ -32,8 +33,10 @@ async function bump({ version, deploy }) { // update package.json const pkgPath = 'package.json'; const pkg = await readJson(pkgPath); - if (compare({oldVersion: pkg.version, newVersion: version}) <= 0) { - throw new Error('Input version number is not greater than the current version number!'); + if (compare({ oldVersion: pkg.version, newVersion: version }) <= 0) { + throw new Error( + 'Input version number is not greater than the current version number!' + ); } pkg.version = version; writeJson(pkgPath, pkg); @@ -46,8 +49,15 @@ async function bump({ version, deploy }) { update_info.chrome.latest_version = version; update_info.edge.latest_version = version; } - if (compare({oldVersion: update_info.develop.latest_version, newVersion: version}) <= 0) { - throw new Error('Input version number is not greater than the current version number!'); + if ( + compare({ + oldVersion: update_info.develop.latest_version, + newVersion: version, + }) <= 0 + ) { + throw new Error( + 'Input version number is not greater than the current version number!' + ); } update_info.develop.latest_version = version; writeJson(infoPath, update_info); @@ -58,7 +68,7 @@ module.exports = { bump }; try { const [nodePath, scriptPath, versionNumber, ...otherArgs] = process.argv; if (versionNumber !== undefined) { - if (validate({version: versionNumber})) { + if (validate({ version: versionNumber })) { // version number is not valid throw new Error('Input version number is valid'); } @@ -69,4 +79,3 @@ try { return -1; } return 0; - diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index 81136a96..ca230938 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -155,9 +155,6 @@ "component_projectCorrelationNetwork_title": { "message": "Project Correlation Network" }, - "component_projectRacingBar_ReplayButton": { - "message": "Replay" - }, "component_projectRacingBar_description": { "message": "This chart shows how the activity values of contributors in this repository evolve." }, diff --git a/src/locales/zh_CN/messages.json b/src/locales/zh_CN/messages.json index 95a2e690..de70b5f6 100644 --- a/src/locales/zh_CN/messages.json +++ b/src/locales/zh_CN/messages.json @@ -155,9 +155,6 @@ "component_projectCorrelationNetwork_title": { "message": "项目关系网络图" }, - "component_projectRacingBar_ReplayButton": { - "message": "重播" - }, "component_projectRacingBar_description": { "message": "贡献者活跃度滚榜展示了项目贡献者的活跃度演化过程。" }, diff --git a/src/pages/ContentScripts/features/repo-activity-racing-bar/AvatarColorStore.ts b/src/pages/ContentScripts/features/repo-activity-racing-bar/AvatarColorStore.ts index b7c5401f..bcaf16d0 100644 --- a/src/pages/ContentScripts/features/repo-activity-racing-bar/AvatarColorStore.ts +++ b/src/pages/ContentScripts/features/repo-activity-racing-bar/AvatarColorStore.ts @@ -56,6 +56,13 @@ class AvatarColorStore { (rgb: RGB) => `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})` ); }); + // Store the updated cache entry with the unique key. + await chrome.storage.local.set({ + [cacheKey]: { + colors, + lastUpdated: now, + }, + }); } catch (error) { console.error( `Cannot extract colors of the avatar of ${loginId}, error info: `, @@ -64,14 +71,6 @@ class AvatarColorStore { colors = Array(COLOR_COUNT).fill('rgb(255, 255, 255)'); } - // Store the updated cache entry with the unique key. - await chrome.storage.local.set({ - [cacheKey]: { - colors, - lastUpdated: now, - }, - }); - return colors; } diff --git a/src/pages/ContentScripts/features/repo-activity-racing-bar/PlayerButton.tsx b/src/pages/ContentScripts/features/repo-activity-racing-bar/PlayerButton.tsx new file mode 100644 index 00000000..12411548 --- /dev/null +++ b/src/pages/ContentScripts/features/repo-activity-racing-bar/PlayerButton.tsx @@ -0,0 +1,58 @@ +import React, { useRef } from 'react'; +import { Button, Tooltip } from 'antd'; + +interface PlayerButtonProps { + tooltip?: string; + icon: JSX.Element; + onClick?: () => void; + onLongPress?: () => void; +} + +export const PlayerButton = ({ + tooltip, + icon, + onClick, + onLongPress, +}: PlayerButtonProps): JSX.Element => { + const pressingRef = useRef(false); + const longPressDetectedRef = useRef(false); + const timerRef = useRef(); + + const handleMouseDown = () => { + pressingRef.current = true; + timerRef.current = setTimeout(() => { + if (pressingRef.current) { + longPressDetectedRef.current = true; + onLongPress?.(); + } + }, 1000); + }; + + const handleMouseUp = () => { + clearTimeout(timerRef.current!); + pressingRef.current = false; + + if (longPressDetectedRef.current) { + longPressDetectedRef.current = false; + return; + } + + onClick?.(); + }; + + return ( + + + + {/* speed control */} + { + setSpeed(speed); + }} + /> + + {/* 3 buttons */} + + {/* last month | earliest month */} + } + onClick={mediaControlersRef.current?.previous} + onLongPress={mediaControlersRef.current?.earliest} + /> + {/* play | pause */} + : } + onClick={() => { + if (playing) { + mediaControlersRef.current?.pause(); + } else { + mediaControlersRef.current?.play(); + } + }} + /> + {/* next month | latest month */} + } + onClick={mediaControlersRef.current?.next} + onLongPress={mediaControlersRef.current?.latest} + /> + +
diff --git a/src/pages/ContentScripts/index.scss b/src/pages/ContentScripts/index.scss index 94d33c3e..3862433e 100644 --- a/src/pages/ContentScripts/index.scss +++ b/src/pages/ContentScripts/index.scss @@ -109,22 +109,3 @@ -ms-user-select: none; /* IE10+/Edge */ user-select: none; /* Standard */ } - -.replay-button { - display: inline-block; - text-align: center; - text-decoration: none; - border-radius: 4px; - cursor: pointer; - padding: 3px 12px; - font-size: 12px; - line-height: 20px; - font-weight: var(--base-text-weight-medium, 500); - color: var(--button-default-fgColor-rest, var(--color-btn-text)); - background-color: var(--button-default-bgColor-rest, var(--color-btn-bg)); - border-color: var(--button-default-borderColor-rest, var(--color-btn-border)); - box-shadow: var(--button-default-shadow-resting, var(--color-btn-shadow)), - var(--button-default-shadow-inset, var(--color-btn-inset-shadow)); - transition: 80ms cubic-bezier(0.33, 1, 0.68, 1); - transition-property: color, background-color, box-shadow, border-color; -} diff --git a/yarn.lock b/yarn.lock index 2cb96cd8..188b1cb3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,7 +35,7 @@ resolved "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz#4b2f65a17d4d32b526baa6414aca2117382bf8da" integrity sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g== -"@ant-design/icons@^5.2.2": +"@ant-design/icons@^5.2.2", "@ant-design/icons@^5.2.6": version "5.2.6" resolved "https://registry.npmjs.org/@ant-design/icons/-/icons-5.2.6.tgz#2d4a9a37f531eb2a20cebec01d6fb69cf593900d" integrity sha512-4wn0WShF43TrggskBJPRqCD0fcHbzTYjnaoskdiJrVHg86yxoZ8ZUqsXvyn4WUqehRiFKnaclOhqk9w4Ui2KVw==