Skip to content

Commit

Permalink
Refactor: refactor content scripts and load remote config from repo f…
Browse files Browse the repository at this point in the history
…ile (#93)

* refactor: refactor content scripts

Signed-off-by: LinHaiming <lhming23@outlook.com>

* feat: load config from github

Signed-off-by: LinHaiming <lhming23@outlook.com>
  • Loading branch information
heming6666 authored Apr 13, 2021
1 parent 3412eda commit ccd27c5
Show file tree
Hide file tree
Showing 21 changed files with 503 additions and 333 deletions.
118 changes: 115 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@fluentui/react": "^7.121.1",
"@hot-loader/react-dom": "^16.13.0",
"@octokit/core": "^3.4.0",
"@types/chrome": "0.0.104",
"@types/react": "^17.0.2",
"copy-to-clipboard": "^3.3.1",
Expand Down
13 changes: 13 additions & 0 deletions src/api/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Octokit } from "@octokit/core";

export const getConfigFromGithub = async (owner: string, repo: string) => {
const octokit = new Octokit();
try {
const response = await octokit.request('GET /repos/{owner}/{repo}/contents/.github/hypertrons.json', { owner, repo });
const res = response.data as any;
res.content = Buffer.from(res.content, 'base64').toString('ascii');
return JSON.parse(res.content)["hypertrons-crx"];
} catch (error: unknown) {
return {};
}
}
10 changes: 0 additions & 10 deletions src/components/PerceptorLayout/index.tsx

This file was deleted.

98 changes: 98 additions & 0 deletions src/pages/Content/DeveloperNetwork.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from 'react';
import { render } from 'react-dom';
import $ from 'jquery';
import * as pageDetect from 'github-url-detection';
import { Stack, Separator, DetailsList, SelectionMode, Link } from 'office-ui-fabric-react';
import ForceNetwork from '../../components/Network/ForceNetwork';
import { getGraphData } from '../../api/index';
import { getMessageI18n } from '../../utils/utils';
import PerceptorBase from './PerceptorBase';

interface DeveloperNetworkViewProps {
id: string;
title: string;
data: any;
}
const DeveloperNetworkView: React.FC<DeveloperNetworkViewProps> = ({ id, title, data }) => {
const list = data.nodes.slice(0, 5);
const columns = [
{
key: 'column1',
name: getMessageI18n(`global_${id}`),
fieldName: 'name',
minWidth: 100,
maxWidth: 200,
isResizable: true,
onRender: (item: any) => (
<Link href={'https://github.com/' + item.name} >
{item.name}
</Link>
),
},
{ key: 'column2', name: getMessageI18n('global_activity'), fieldName: 'value', minWidth: 100, maxWidth: 200, isResizable: true },
];
return (
<div className="hypertrons-crx-border mt-4">
<p className="hypertrons-crx-title">{title}</p>
<Stack horizontal>
<Stack.Item className='verticalStackItemStyle'>
<DetailsList
items={list}
columns={columns}
selectionMode={SelectionMode.none}
/>
</Stack.Item>
<Stack.Item className='verticalSeparatorStyle'>
<Separator vertical />
</Stack.Item>
<Stack.Item className='verticalStackItemStyle'>
<ForceNetwork
data={data}
/>
</Stack.Item>
</Stack>
</div>
)
};

export default class DeveloperNetwork extends PerceptorBase {
constructor() {
super();
this.include = [
pageDetect.isUserProfileMainTab
];
}

public async run(): Promise<void> {
const pinnedReposDiv = $('.js-pinned-items-reorder-container').parent();
const DeveloperNetworkDiv = document.createElement('div');
DeveloperNetworkDiv.id = 'developer-network';
DeveloperNetworkDiv.style.width = "100%";
const developerLogin = $('.p-nickname.vcard-username.d-block').text().trim();
try {
const developerGraphData = await getGraphData(`https://hypertrons.oss-cn-shanghai.aliyuncs.com/actor/${developerLogin}.json`);
developerGraphData.nodes.forEach((node: any) => {
if (node.name === developerLogin) {
node['itemStyle'] = {
color: '#fb8532'
};
}
});

render(
<div>
< DeveloperNetworkView
id='developer'
data={developerGraphData}
title={getMessageI18n('component_developerCollabrationNetwork_title')}
/>
</div>,
DeveloperNetworkDiv,
);
pinnedReposDiv.before(DeveloperNetworkDiv);
} catch (error) {
this.logger.error('developerNetwork', error);
return;
}
}
}
71 changes: 71 additions & 0 deletions src/pages/Content/Perceptor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import $ from 'jquery';
import elementReady from 'element-ready';
import { utils, isRepo } from 'github-url-detection';
import { loadSettings, mergeSettings } from '../../utils/settings'
import { getConfigFromGithub } from '../../api/github';
import { Inject } from '../../utils/utils';
import PerceptorBase from './PerceptorBase';
import PerceptorTab from './PerceptorTab';
import PerceptorLayout from './PerceptorLayout';
import DeveloperNetwork from './DeveloperNetwork';
import ProjectNetwork from './ProjectNetwork';

@Inject([
PerceptorTab,
PerceptorLayout,
DeveloperNetwork,
ProjectNetwork
])
class Perceptor extends PerceptorBase {
public static features: Map<string, any> = new Map();
public settings: any;

public async run(): Promise<void> {
// wait until <body> element is ready
await elementReady('body', { waitForChildren: false });
this.logger.info('body element is ready.');

this.logger.info('creating perceptor div ...');
const perceptorDiv = document.createElement('div');
perceptorDiv.id = 'perceptor';
$('#js-repo-pjax-container').prepend(perceptorDiv);

await this.checkSettings();

// run every features
Perceptor.features.forEach(async (feature, name) => {
this.logger.info('trying to load ', name)
if (this.settings.toJson()[name] === false) {
this.logger.info(name, 'is disabled');
return;
}
if (feature.include.every((c: () => any) => !c())) {
return;
}
try {
this.logger.info('running ', name)
await feature.run();
} catch (error: unknown) {
this.logger.error(name, error)
}
}, this)
}

private async checkSettings(): Promise<void> {
this.logger.info('loading settings ...');
if (isRepo()) {
this.logger.info('Detected that this is a repo page, trying to load configuration file from the repo ...');
const owner = utils.getRepositoryInfo(window.location)!.owner;
const repo = utils.getRepositoryInfo(window.location)!.name;
const configFromGithub = await getConfigFromGithub(owner, repo);
this.logger.info('The configurations are: ', configFromGithub);
this.settings = await mergeSettings(configFromGithub);
} else {
this.settings = await loadSettings();
}
}

}

export default Perceptor;

Loading

0 comments on commit ccd27c5

Please sign in to comment.