Skip to content

Commit

Permalink
Merge pull request #436 from conwnet/master
Browse files Browse the repository at this point in the history
release 0.9.0
  • Loading branch information
conwnet authored Aug 14, 2022
2 parents 6bb61e5 + 57c5972 commit 50f8f4d
Show file tree
Hide file tree
Showing 29 changed files with 1,228 additions and 691 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ The continued development and maintenance of GitHub1s is made possible by these
- [Github Web IDE](https://chrome.google.com/webstore/detail/adjiklnjodbiaioggfpbpkhbfcnhgkfe) ([zvizvi/Github-Web-IDE](https://github.com/zvizvi/Github-Web-IDE))
- [shortcut to github1s](https://chrome.google.com/webstore/detail/shortcut-to-github1s/gfcdbodapcbfckbfpmgeldfkkgjknceo) ([katsuhisa91/github1s-shortcut](https://github.com/katsuhisa91/github1s-shortcut))
- [Github1s Shortut - Open source](https://github.com/Fauzdar1/Github1s)
- [⚡️ 1s to GitHub1s!](https://github.com/holazz/webext-github1s)

### Firefox Extensions

Expand Down
13 changes: 7 additions & 6 deletions api/vscode-unpkg/index.js → api/vscode-unpkg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
* @author netcon
*/

const got = require('got');
const url = require('url');
import got from 'got';
import * as url from 'url';
import type { VercelRequest, VercelResponse } from '@vercel/node';

module.exports = async (req, res) => {
const pathname = new url.parse(req.url || '').pathname || '';
module.exports = async (req: VercelRequest, res: VercelResponse) => {
const pathname = url.parse(req.url || '').pathname || '';
const matches = pathname.match(/^\/api\/vscode-unpkg\/([^/]+)\/(.*)/);

if (!matches) {
Expand All @@ -19,12 +20,12 @@ module.exports = async (req, res) => {
const restPartsPath = matches[2];
const requestUrl = `https://${publisher}.vscode-unpkg.net/${publisher}/${restPartsPath}`;
const response = await got(requestUrl).catch((error) => {
return error.response || { statusCode: 500, headers: {}, body: error.message };
return error.response || { statusCode: 500, headers: {}, rawBody: Buffer.from(error.message) };
});

res.status(response.statusCode);
['cache-control', 'content-type'].forEach((headerKey) => {
response.headers[headerKey] && res.setHeader(headerKey, response.headers[headerKey]);
});
return res.send(response.body);
return res.send(response.rawBody);
};
3 changes: 3 additions & 0 deletions api/vscode-unpkg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"private": true,
"dependencies": {
"got": "^11.8.5"
},
"devDependencies": {
"@vercel/node": "^2.5.7"
}
}
561 changes: 561 additions & 0 deletions api/vscode-unpkg/yarn.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions extensions/github1s/assets/pages/github1s-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const TokenDetailPage = ({ token, onEditClick, ...props }) => {
return postMessage('validate-token', token).then((tokenStatus) => {
setValidating(false);
setTokenStatus(tokenStatus);
return tokenStatus;
});
}, []);

Expand Down
5 changes: 5 additions & 0 deletions extensions/github1s/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
]
},
"commands": [
{
"command": "github1s.commands.openRepository",
"title": "Open Repository...",
"category": "GitHub1s"
},
{
"command": "github1s.commands.checkoutTo",
"title": "Checkout to...",
Expand Down
29 changes: 29 additions & 0 deletions extensions/github1s/src/adapters/github1s/parse-path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { parsePath } from 'history';
import { PageType, RouterState } from '@/adapters/types';
import { GitHub1sDataSource } from './data-source';
import * as queryString from 'query-string';

const parseTreeUrl = async (path: string): Promise<RouterState> => {
const pathParts = parsePath(path).pathname!.split('/').filter(Boolean);
Expand Down Expand Up @@ -81,13 +82,39 @@ const parsePullUrl = async (path: string): Promise<RouterState> => {
};
};

const parseSearchUrl = async (path: string): Promise<RouterState> => {
const { pathname, search } = parsePath(path);
const pathParts = pathname!.split('/').filter(Boolean);
const [owner, repo, _pageType] = pathParts;
const queryOptions = queryString.parse(search || '');
const query = typeof queryOptions.q === 'string' ? queryOptions.q : '';
const isRegex = queryOptions.regex === 'yes';
const isCaseSensitive = queryOptions.case === 'yes';
const matchWholeWord = queryOptions.whole === 'yes';
const filesToInclude = typeof queryOptions['files-to-include'] === 'string' ? queryOptions['files-to-include'] : '';
const filesToExclude = typeof queryOptions['files-to-exclude'] === 'string' ? queryOptions['files-to-exclude'] : '';

return {
repo: `${owner}/${repo}`,
pageType: PageType.Search,
ref: 'HEAD',
query,
isRegex,
isCaseSensitive,
matchWholeWord,
filesToInclude,
filesToExclude,
};
};

const PAGE_TYPE_MAP = {
tree: PageType.Tree,
blob: PageType.Blob,
pulls: PageType.CodeReviewList,
pull: PageType.CodeReview,
commit: PageType.Commit,
commits: PageType.CommitList,
search: PageType.Search,
};

export const parseGitHubPath = async (path: string): Promise<RouterState> => {
Expand All @@ -110,6 +137,8 @@ export const parseGitHubPath = async (path: string): Promise<RouterState> => {
return parseCommitUrl(path);
case PageType.CommitList:
return parseCommitsUrl(path);
case PageType.Search:
return parseSearchUrl(path);
}
}

Expand Down
14 changes: 13 additions & 1 deletion extensions/github1s/src/adapters/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ export enum PageType {
// e.g. https://github.com/conwnet/github1s/blame/master/.gitignore
FileBlame = 'FileBlame',

// show search result
Search = 'Search',

// branches, tags, wiki, gist should be on the way
Unknown = 'Unknown',
}
Expand All @@ -328,7 +331,16 @@ export type RouterState = { repo: string; ref: string } & (
| { pageType: PageType.Commit; commitSha: string } // for commit detail page
| { pageType: PageType.CodeReviewList } // for code review list page
| { pageType: PageType.CodeReview; codeReviewId: string }
); // for code review detail page
| {
pageType: PageType.Search;
query?: string;
isRegex?: boolean;
isCaseSensitive?: boolean;
matchWholeWord?: boolean;
filesToInclude?: string;
filesToExclude?: string;
}
);

export class RouterParser {
// parse giving path (starts with '/', may includes search and hash) to Router state,
Expand Down
55 changes: 54 additions & 1 deletion extensions/github1s/src/commands/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import * as vscode from 'vscode';
import router from '@/router';
import { relativeTimeTo } from '@/helpers/date';
import { getRecentRepositories, removeRecentRepository } from '@/helpers/context';
import { adapterManager } from '@/adapters';

export const commandOpenOnOfficialPage = async () => {
const location = (await router.getHistory()).location;
Expand All @@ -25,13 +28,63 @@ export const commandOpenGitpod = () => {
});
};

const repoPickItemButtons = [{ iconPath: new vscode.ThemeIcon('close') }];

const getRecentRepoPickItems = () =>
getRecentRepositories().map((record) => ({
label: record.name,
description: relativeTimeTo(record.timestamp),
buttons: repoPickItemButtons,
}));

export const commandOpenRepository = async () => {
const quickPick = vscode.window.createQuickPick();
const manualInputItem = { label: '' };
let recentRepoPickItems = getRecentRepoPickItems();

const updatePickerItems = () => {
if (manualInputItem.label) {
return (quickPick.items = [...recentRepoPickItems, manualInputItem]);
}
return (quickPick.items = recentRepoPickItems);
};

quickPick.placeholder = 'Select to open...';
updatePickerItems();

quickPick.show();
quickPick.onDidTriggerItemButton(async (event) => {
if (event.button === repoPickItemButtons[0]) {
await removeRecentRepository(event.item.label);
recentRepoPickItems = getRecentRepoPickItems();
updatePickerItems();
}
});

quickPick.onDidChangeValue((value) => {
manualInputItem.label = value ? `Open ${value}...` : '';
updatePickerItems();
});

quickPick.onDidAccept(async () => {
const choice = quickPick.activeItems[0];
const repository = choice === manualInputItem ? quickPick.value : choice.label;
const tagetLink = vscode.Uri.parse((await router.href()) || '').with({
path: await (await router.resolveParser()).buildTreePath(repository),
});
vscode.commands.executeCommand('vscode.open', tagetLink);
quickPick.hide();
});
};

export const registerGlobalCommands = (context: vscode.ExtensionContext) => {
return context.subscriptions.push(
vscode.commands.registerCommand('github1s.commands.openOnGitHub', commandOpenOnOfficialPage),
vscode.commands.registerCommand('github1s.commands.openOnGitLab', commandOpenOnOfficialPage),
vscode.commands.registerCommand('github1s.commands.openOnBitbucket', commandOpenOnOfficialPage),
vscode.commands.registerCommand('github1s.commands.openOnNpm', commandOpenOnOfficialPage),
vscode.commands.registerCommand('github1s.commands.openOnOfficialPage', commandOpenOnOfficialPage),
vscode.commands.registerCommand('github1s.commands.openOnGitPod', commandOpenGitpod)
vscode.commands.registerCommand('github1s.commands.openOnGitPod', commandOpenGitpod),
vscode.commands.registerCommand('github1s.commands.openRepository', commandOpenRepository)
);
};
5 changes: 4 additions & 1 deletion extensions/github1s/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import { registerEventListeners } from '@/listeners';
import { registerVSCodeProviders } from '@/providers';
import { registerGitHub1sCommands } from '@/commands';
import { updateSourceControlChanges } from '@/changes';
import { setExtensionContext } from '@/helpers/context';
import { adapterManager, registerAdapters } from '@/adapters';
import { addRecentRepositories, setExtensionContext } from '@/helpers/context';

const browserUrlManager = {
href: () => vscode.commands.executeCommand('github1s.commands.vscode.getBrowserUrl') as Promise<string>,
Expand Down Expand Up @@ -74,5 +74,8 @@ const initialVSCodeState = async () => {
vscode.commands.executeCommand('github1s.views.commitList.focus');
} else if ([PageType.CodeReview, PageType.Commit].includes(routerState.pageType)) {
vscode.commands.executeCommand('workbench.scm.focus');
} else if (routerState.pageType === PageType.Search) {
vscode.commands.executeCommand('workbench.action.findInFiles', routerState);
}
routerState.repo && addRecentRepositories(routerState.repo);
};
17 changes: 17 additions & 0 deletions extensions/github1s/src/helpers/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,20 @@ export const getExtensionContext = (): vscode.ExtensionContext => {

return extensionContext;
};

const RECENT_REPOSITORIES = 'github1s-recent-repositories';
export const getRecentRepositories = (): { name: string; timestamp: number }[] => {
return getExtensionContext().globalState.get(RECENT_REPOSITORIES) || [];
};

export const addRecentRepositories = (name: string, timestamp = 0) => {
const currentRecord = { name, timestamp: timestamp || Date.now() };
const restRecords = getRecentRepositories().filter((record) => record.name !== name);
const newRecords = [currentRecord, ...restRecords.slice(0, 49)]; // max to 50 records
return getExtensionContext().globalState.update(RECENT_REPOSITORIES, newRecords);
};

export const removeRecentRepository = (name: string) => {
const newRecords = getRecentRepositories().filter((record) => record.name !== name);
return getExtensionContext().globalState.update(RECENT_REPOSITORIES, newRecords);
};
10 changes: 8 additions & 2 deletions extensions/github1s/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class Router extends EventEmitter<RouterState> {
private _parser: RouterParser | null = null;
// ensure router has been initialized
private _barrier: Barrier = new Barrier();
private _manager: UrlManager | null = null;

public static getInstance() {
if (Router.instance) {
Expand All @@ -34,8 +35,9 @@ export class Router extends EventEmitter<RouterState> {

// initialize the router with current url in browser
async initialize(urlManager: UrlManager) {
this._manager = urlManager;
this._parser = await adapterManager.getCurrentAdapter().resolveRouterParser();
const { path: pathname, query, fragment } = vscode.Uri.parse(await urlManager.href());
const { path: pathname, query, fragment } = vscode.Uri.parse(await this._manager.href());
const path = pathname + (query ? `?${query}` : '') + (fragment ? `#${fragment}` : '');

this._state = await this._parser.parsePath(path);
Expand All @@ -46,7 +48,7 @@ export class Router extends EventEmitter<RouterState> {
const targetPath = `${location.pathname}${location.search}${location.hash}`;
const routerParser = await adapterManager.getCurrentAdapter().resolveRouterParser();

urlManager[action === Action.Push ? 'push' : 'replace'](targetPath);
this._manager?.[action === Action.Push ? 'push' : 'replace'](targetPath);
this._state = await routerParser.parsePath(targetPath);
super.notifyListeners(this._state, prevState);
});
Expand Down Expand Up @@ -94,6 +96,10 @@ export class Router extends EventEmitter<RouterState> {
await this._barrier.wait();
return this._parser!;
}

public async href(): Promise<string | undefined> {
return this._manager?.href();
}
}

export default Router.getInstance();
Loading

1 comment on commit 50f8f4d

@vercel
Copy link

@vercel vercel bot commented on 50f8f4d Aug 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.