Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/pages/ContentScripts/features/perceptor-layout/gitee-index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import $ from 'jquery';
import { createRoot } from 'react-dom/client';
import features from '../../../../feature-manager';
import isPerceptor from '../../../../helpers/is-perceptor';
import View from './view';
import isGitee from '../../../../helpers/is-gitee';

const featureId = features.getFeatureID(import.meta.url);

const renderTo = (container: any) => {
createRoot(container).render(<View />);
};

const init = async (): Promise<void> => {
const uiContainer = $('.site-content > .ui.container');
uiContainer.empty();

// create the new one: the percepter container
const percepterContainer = document.createElement('div');
percepterContainer.id = featureId;

uiContainer.append(percepterContainer);

renderTo(percepterContainer);
};

features.add(featureId, {
asLongAs: [isGitee, isPerceptor],
awaitDomReady: false,
init,
});
76 changes: 76 additions & 0 deletions src/pages/ContentScripts/features/perceptor-tab/gitee-index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import elementReady from 'element-ready';
import iconSvgPath from './icon-svg-path';
import features from '../../../../feature-manager';
import isPerceptor from '../../../../helpers/is-perceptor';
import { isPublicRepo } from '../../../../helpers/get-gitee-repo-info';
import isGitee from '../../../../helpers/is-gitee';

const featureId = features.getFeatureID(import.meta.url);

const addPerceptorTab = async (): Promise<void | false> => {
// Wait for the secondary navigation menu to load
const menuContainer = await elementReady('.ui.secondary.pointing.menu', { waitForChildren: false });
if (!menuContainer) {
return false;
}

// Create the Perceptor tab based on the pipeline tab
const pipelineTab = await elementReady('a.item[href*="/gitee_go"]', { waitForChildren: false });
if (!pipelineTab) {
return false;
}

const perceptorTab = pipelineTab.cloneNode(true) as HTMLAnchorElement;
perceptorTab.classList.remove('active');
const perceptorHref = `${location.pathname}?redirect=perceptor`;
perceptorTab.href = perceptorHref;
perceptorTab.id = featureId;

// Replace the icon and text
const iconElement = perceptorTab.querySelector('i.iconfont') as HTMLElement;
if (iconElement) {
iconElement.className = 'iconfont';
iconElement.innerHTML = `<svg width="16" height="16" viewBox="0 0 16 16" style="margin-right: 4px">${iconSvgPath}</svg>`;
}

// Clear existing text nodes
perceptorTab.childNodes.forEach((node) => {
if (node.nodeType === Node.TEXT_NODE) {
node.remove();
}
});

// Add new text node
const textNode = document.createTextNode('\nPerceptor\n');
iconElement?.after(textNode);

// Add the Perceptor tab before the service dropdown
const serviceDropdown = menuContainer.querySelector('.git-project-service');
if (!serviceDropdown) {
console.error('Failed to find the service dropdown');
return false;
}
serviceDropdown.parentElement?.before(perceptorTab);
};

const updatePerceptorTabHighlighting = async (): Promise<void> => {
const perceptorTab = document.getElementById(featureId) as HTMLAnchorElement;
if (!perceptorTab) return;

const allTabs = document.querySelectorAll('.ui.secondary.pointing.menu a.item');
allTabs.forEach((tab) => tab.classList.remove('active'));
perceptorTab.classList.add('active');
};

const init = async (): Promise<void> => {
await addPerceptorTab();
if (isPerceptor()) {
await updatePerceptorTabHighlighting();
}
};

features.add(featureId, {
asLongAs: [isGitee, isPublicRepo],
awaitDomReady: false,
init,
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { avatarColorStore } from './AvatarColorStore';
import getGithubTheme from '../../../../helpers/get-github-theme';

import type { BarSeriesOption, EChartsOption } from 'echarts';
import { orderBy, take } from 'lodash-es';

const theme = getGithubTheme();
import isGithub from '../../../../helpers/is-github';
const theme = isGithub() ? getGithubTheme() : 'light';
const DARK_TEXT_COLOR = 'rgba(230, 237, 243, 0.9)';

export interface RepoActivityDetails {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import $ from 'jquery';
import features from '../../../../feature-manager';
import isPerceptor from '../../../../helpers/is-perceptor';
import { getRepoName, isPublicRepoWithMeta } from '../../../../helpers/get-gitee-repo-info';
import { getActivityDetails } from '../../../../api/repo';
import View from './view';
import DataNotFound from '../repo-networks/DataNotFound';
import { RepoActivityDetails } from './data';
import { createRoot } from 'react-dom/client';
import { getPlatform } from '../../../../helpers/get-platform';
import isGitee from '../../../../helpers/is-gitee';
const featureId = features.getFeatureID(import.meta.url);
let repoName: string;
let repoActivityDetails: RepoActivityDetails;
let platform: string;
let width = '80%';
const getData = async () => {
repoActivityDetails = await getActivityDetails(platform, repoName);
};

const renderTo = (container: any) => {
const root = createRoot(container);
if (!repoActivityDetails) {
root.render(<DataNotFound />);
return;
}
root.render(<View currentRepo={repoName} width={width} repoActivityDetails={repoActivityDetails} />);
};

const init = async (): Promise<void> => {
platform = getPlatform();
repoName = getRepoName();
await getData();
const container = document.createElement('div');
container.id = featureId;
// append before render so that the container has computed width
$('#hypercrx-perceptor-slot-repo-activity-racing-bar').append(container);
renderTo(container);
};

const restore = async () => {
// Clicking another repo link in one repo will trigger a turbo:visit,
// so in a restoration visit we should be careful of the current repo.
if (repoName !== getRepoName()) {
repoName = getRepoName();
}
// rerender the chart or it will be empty
renderTo($(`#${featureId}`)[0]);
};

features.add(featureId, {
asLongAs: [isGitee, isPerceptor, isPublicRepoWithMeta],
awaitDomReady: false,
init,
restore,
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const featureId = features.getFeatureID(import.meta.url);
let repoName: string;
let repoActivityDetails: RepoActivityDetails;
let platform: string;
let width = '100%';
const getData = async () => {
repoActivityDetails = await getActivityDetails(platform, repoName);
};
Expand All @@ -24,7 +25,7 @@ const renderTo = (container: any) => {
root.render(<DataNotFound />);
return;
}
root.render(<View currentRepo={repoName} repoActivityDetails={repoActivityDetails} />);
root.render(<View currentRepo={repoName} width={width} repoActivityDetails={repoActivityDetails} />);
};

const init = async (): Promise<void> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import { useTranslation } from 'react-i18next';
import '../../../../helpers/i18n';
interface Props {
currentRepo: string;
width: string;
repoActivityDetails: RepoActivityDetails;
}

const View = ({ currentRepo, repoActivityDetails }: Props): JSX.Element => {
const View = ({ currentRepo, width, repoActivityDetails }: Props): JSX.Element => {
const [options, setOptions] = useState<HypercrxOptions>(defaults);
const [speed, setSpeed] = useState<number>(1);
const [playing, setPlaying] = useState<boolean>(false);
Expand All @@ -28,8 +29,8 @@ const View = ({ currentRepo, repoActivityDetails }: Props): JSX.Element => {
}, [options.locale]);

return (
<div>
<div className="hypertrons-crx-border hypertrons-crx-container">
<div style={{ display: 'flex', justifyContent: 'center' }}>
<div className="hypertrons-crx-border hypertrons-crx-container" style={{ width: width }}>
<div className="hypertrons-crx-title">
<span>{t('component_projectRacingBar_title')}</span>
<div className="hypertrons-crx-title-extra developer-tab">
Expand Down
24 changes: 24 additions & 0 deletions src/pages/ContentScripts/index.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
:root {
--borderColor-default: #d1d9e0;
--bgColor-inset: var(--bgColor-muted);
--bgColor-muted: #f6f8fa;
--fgColor-default: #1f2328;
}
.hypertrons-crx-container {
margin-top: 24px !important;
overflow: auto;
Expand Down Expand Up @@ -165,3 +171,21 @@
display: inline-block;
margin-left: 4px;
}

.flex-items-center {
align-items: center !important;
}

@media (min-width: 768px) {
.col-md-8 {
width: 66.66666664% !important;
}
}
.col-12 {
width: 100%;
}
@media (min-width: 768px) {
.col-md-4 {
width: 33.33333332% !important;
}
}
3 changes: 3 additions & 0 deletions src/pages/ContentScripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import './features/repo-star-tooltip';
import './features/repo-pr-tooltip';
import './features/repo-issue-tooltip';
import './features/perceptor-tab';
import './features/perceptor-tab/gitee-index.tsx';
import './features/perceptor-layout';
import './features/perceptor-layout/gitee-index.tsx';
import './features/repo-networks';
import './features/developer-networks';
import './features/oss-gpt';
import './features/repo-activity-racing-bar';
import './features/repo-activity-racing-bar/gitee-index.tsx';
import './features/developer-hovercard-info';
import './features/repo-sidebar-labels';
import './features/fast-pr';
Loading