mirror of
https://github.com/mikenikles/github1s.git
synced 2021-09-10 00:06:44 +03:00
feat: add eslint add fix indent
This commit is contained in:
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Tab indentation
|
||||
[*]
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# The indent size used in the `package.json` file cannot be changed
|
||||
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
|
||||
[{*.yml,*.yaml,*.json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
3
.eslintignore
Normal file
3
.eslintignore
Normal file
@@ -0,0 +1,3 @@
|
||||
**/node_modules/**
|
||||
**/lib/vscode/**
|
||||
**/dist/**
|
||||
65
.eslintrc.json
Normal file
65
.eslintrc.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"jsdoc"
|
||||
],
|
||||
"rules": {
|
||||
"constructor-super": "warn",
|
||||
"curly": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"no-buffer-constructor": "warn",
|
||||
"no-caller": "warn",
|
||||
"no-debugger": "warn",
|
||||
"no-duplicate-case": "warn",
|
||||
"no-duplicate-imports": "warn",
|
||||
"no-eval": "warn",
|
||||
"no-extra-semi": "warn",
|
||||
"no-new-wrappers": "warn",
|
||||
"no-redeclare": "off",
|
||||
"no-sparse-arrays": "warn",
|
||||
"no-throw-literal": "warn",
|
||||
"no-unsafe-finally": "warn",
|
||||
"no-unused-labels": "warn",
|
||||
"no-restricted-globals": [
|
||||
"warn",
|
||||
"name",
|
||||
"length",
|
||||
"event",
|
||||
"closed",
|
||||
"external",
|
||||
"status",
|
||||
"origin",
|
||||
"orientation",
|
||||
"context"
|
||||
], // non-complete list of globals that are easy to access unintentionally
|
||||
"no-var": "warn",
|
||||
"jsdoc/no-types": "warn",
|
||||
"semi": "off",
|
||||
"@typescript-eslint/semi": "warn",
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"warn",
|
||||
{
|
||||
"selector": "class",
|
||||
"format": [
|
||||
"PascalCase"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.js"
|
||||
],
|
||||
"rules": {
|
||||
"jsdoc/no-types": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -7,63 +7,63 @@ import * as vscode from 'vscode';
|
||||
import { fetch, RequestError, RequestRateLimitError, RequestInvalidTokenError, RequestNotFoundError, throttledReportNetworkError } from './util/fetch';
|
||||
|
||||
interface UriState {
|
||||
owner: string;
|
||||
repo: string;
|
||||
branch: string;
|
||||
path: string;
|
||||
};
|
||||
owner: string;
|
||||
repo: string;
|
||||
branch: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
const parseUri = (uri: vscode.Uri): UriState => {
|
||||
const [owner, repo, branch] = (uri.authority || '').split('+').filter(Boolean);
|
||||
return {
|
||||
owner,
|
||||
repo,
|
||||
branch,
|
||||
path: uri.path,
|
||||
};
|
||||
const [owner, repo, branch] = (uri.authority || '').split('+').filter(Boolean);
|
||||
return {
|
||||
owner,
|
||||
repo,
|
||||
branch,
|
||||
path: uri.path,
|
||||
};
|
||||
};
|
||||
|
||||
const handleRequestError = (error: RequestError) => {
|
||||
if (error instanceof RequestRateLimitError) {
|
||||
if (!error.token) {
|
||||
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Offer an OAuth Token.');
|
||||
}
|
||||
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Change Another OAuth Token.');
|
||||
}
|
||||
if (error instanceof RequestInvalidTokenError) {
|
||||
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
|
||||
}
|
||||
if (error instanceof RequestNotFoundError) {
|
||||
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
|
||||
}
|
||||
if (error instanceof RequestNotFoundError) {
|
||||
throw vscode.FileSystemError.FileNotFound('GitHub Resource Not Found');
|
||||
}
|
||||
throw vscode.FileSystemError.Unavailable(error.message || 'Unknown Error Occurred When Request To GitHub');
|
||||
if (error instanceof RequestRateLimitError) {
|
||||
if (!error.token) {
|
||||
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Offer an OAuth Token.');
|
||||
}
|
||||
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Change Another OAuth Token.');
|
||||
}
|
||||
if (error instanceof RequestInvalidTokenError) {
|
||||
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
|
||||
}
|
||||
if (error instanceof RequestNotFoundError) {
|
||||
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
|
||||
}
|
||||
if (error instanceof RequestNotFoundError) {
|
||||
throw vscode.FileSystemError.FileNotFound('GitHub Resource Not Found');
|
||||
}
|
||||
throw vscode.FileSystemError.Unavailable(error.message || 'Unknown Error Occurred When Request To GitHub');
|
||||
};
|
||||
|
||||
export const readGitHubDirectory = (uri: vscode.Uri) => {
|
||||
const state: UriState = parseUri(uri);
|
||||
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/trees/${state.branch}${state.path.replace(/^\//, ':')}`)
|
||||
.catch(handleRequestError)
|
||||
const state: UriState = parseUri(uri);
|
||||
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/trees/${state.branch}${state.path.replace(/^\//, ':')}`)
|
||||
.catch(handleRequestError);
|
||||
};
|
||||
|
||||
export const readGitHubFile = (uri: vscode.Uri, fileSha: string) => {
|
||||
const state: UriState = parseUri(uri);
|
||||
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/blobs/${fileSha}`)
|
||||
.catch(handleRequestError);
|
||||
const state: UriState = parseUri(uri);
|
||||
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/blobs/${fileSha}`)
|
||||
.catch(handleRequestError);
|
||||
};
|
||||
|
||||
export const validateToken = (token: string) => {
|
||||
const authHeaders = token ? { Authorization: `token ${token}` } : {};
|
||||
return self.fetch(`https://api.github.com`, { headers: { ...authHeaders } }).then(response => ({
|
||||
token: !!token, // if the token is not empty
|
||||
valid: response.status !== 401 ? true : false, // if the request is valid
|
||||
limit: +response.headers.get('X-RateLimit-Limit') || 0, // limit count
|
||||
remaining: +response.headers.get('X-RateLimit-Remaining') || 0, // remains request count
|
||||
reset: +response.headers.get('X-RateLimit-Reset') || 0, // reset time
|
||||
})).catch(() => {
|
||||
throttledReportNetworkError();
|
||||
throw new RequestError('Request Failed, Maybe an Network Error', token);
|
||||
});
|
||||
const authHeaders = token ? { Authorization: `token ${token}` } : {};
|
||||
return self.fetch(`https://api.github.com`, { headers: { ...authHeaders } }).then(response => ({
|
||||
token: !!token, // if the token is not empty
|
||||
valid: response.status !== 401 ? true : false, // if the request is valid
|
||||
limit: +response.headers.get('X-RateLimit-Limit') || 0, // limit count
|
||||
remaining: +response.headers.get('X-RateLimit-Remaining') || 0, // remains request count
|
||||
reset: +response.headers.get('X-RateLimit-Reset') || 0, // reset time
|
||||
})).catch(() => {
|
||||
throttledReportNetworkError();
|
||||
throw new RequestError('Request Failed, Maybe an Network Error', token);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -8,55 +8,59 @@ import { getExtensionContext } from './util';
|
||||
import { validateToken } from './api';
|
||||
|
||||
export const commandValidateToken = (silent: boolean = false) => {
|
||||
const context = getExtensionContext();
|
||||
const oAuthToken = context.globalState.get('github-oauth-token') as string || '';
|
||||
return validateToken(oAuthToken).then(tokenStatus => {
|
||||
if (!silent) {
|
||||
const remaining = tokenStatus.remaining;
|
||||
if (!oAuthToken) {
|
||||
if (remaining > 0) {
|
||||
vscode.window.showWarningMessage(`You haven\'t set a GitHub OAuth Token yet, and you can have ${remaining} requests in the current rate limit window.`);
|
||||
} else {
|
||||
vscode.window.showWarningMessage('You haven\'t set a GitHub OAuth Token yet, and the rate limit is exceeded.');
|
||||
}
|
||||
} else if (!tokenStatus.valid) {
|
||||
vscode.window.showErrorMessage('Current GitHub OAuth Token is invalid.');
|
||||
} else if (tokenStatus.valid && tokenStatus.remaining > 0) {
|
||||
vscode.window.showInformationMessage(`Current GitHub OAuth Token is OK, and you can have ${remaining} requests in the current rate limit window.`);
|
||||
} else if (tokenStatus.valid && tokenStatus.remaining <= 0) {
|
||||
vscode.window.showWarningMessage('Current GitHub OAuth Token is Valid, but the rate limit is exceeded.');
|
||||
}
|
||||
}
|
||||
return tokenStatus;
|
||||
});
|
||||
const context = getExtensionContext();
|
||||
const oAuthToken = context.globalState.get('github-oauth-token') as string || '';
|
||||
return validateToken(oAuthToken).then(tokenStatus => {
|
||||
if (!silent) {
|
||||
const remaining = tokenStatus.remaining;
|
||||
if (!oAuthToken) {
|
||||
if (remaining > 0) {
|
||||
vscode.window.showWarningMessage(`You haven\'t set a GitHub OAuth Token yet, and you can have ${remaining} requests in the current rate limit window.`);
|
||||
} else {
|
||||
vscode.window.showWarningMessage('You haven\'t set a GitHub OAuth Token yet, and the rate limit is exceeded.');
|
||||
}
|
||||
} else if (!tokenStatus.valid) {
|
||||
vscode.window.showErrorMessage('Current GitHub OAuth Token is invalid.');
|
||||
} else if (tokenStatus.valid && tokenStatus.remaining > 0) {
|
||||
vscode.window.showInformationMessage(`Current GitHub OAuth Token is OK, and you can have ${remaining} requests in the current rate limit window.`);
|
||||
} else if (tokenStatus.valid && tokenStatus.remaining <= 0) {
|
||||
vscode.window.showWarningMessage('Current GitHub OAuth Token is Valid, but the rate limit is exceeded.');
|
||||
}
|
||||
}
|
||||
return tokenStatus;
|
||||
});
|
||||
};
|
||||
|
||||
export const commandUpdateToken = (silent: boolean = false) => {
|
||||
return vscode.window.showInputBox({
|
||||
placeHolder: 'Please input the GitHub OAuth Token',
|
||||
}).then(token => {
|
||||
if (!token) return;
|
||||
return getExtensionContext()!.globalState.update('github-oauth-token', token || '').then(() => {
|
||||
// we don't need wait validate, so we don't `return`
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!silent) {
|
||||
if (!tokenStatus.valid) vscode.window.showErrorMessage('GitHub OAuth Token have updated, but it is invalid.')
|
||||
else if (tokenStatus.remaining <= 0) vscode.window.showWarningMessage('GitHub OAuth Token have updated, but the rate limit is exceeded.');
|
||||
else vscode.window.showInformationMessage('GitHub OAuth Token have updated.');
|
||||
}
|
||||
tokenStatus.valid && tokenStatus.remaining > 0 && vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
|
||||
});
|
||||
});
|
||||
});
|
||||
return vscode.window.showInputBox({
|
||||
placeHolder: 'Please input the GitHub OAuth Token',
|
||||
}).then(token => {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
return getExtensionContext()!.globalState.update('github-oauth-token', token || '').then(() => {
|
||||
// we don't need wait validate, so we don't `return`
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!silent) {
|
||||
if (!tokenStatus.valid) {vscode.window.showErrorMessage('GitHub OAuth Token have updated, but it is invalid.');}
|
||||
else if (tokenStatus.remaining <= 0) {vscode.window.showWarningMessage('GitHub OAuth Token have updated, but the rate limit is exceeded.');}
|
||||
else {
|
||||
vscode.window.showInformationMessage('GitHub OAuth Token have updated.');
|
||||
}
|
||||
}
|
||||
tokenStatus.valid && tokenStatus.remaining > 0 && vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const commandClearToken = (silent: boolean = false) => {
|
||||
return vscode.window.showWarningMessage('Would you want to clear the saved GitHub OAuth Token?', { modal: true }, 'Confirm').then(choose => {
|
||||
if (choose === 'Confirm') {
|
||||
return getExtensionContext()!.globalState.update('github-oauth-token', '').then(() => {
|
||||
!silent && vscode.window.showInformationMessage('You have cleared the saved GitHb OAuth Token.');
|
||||
}).then(() => true);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return vscode.window.showWarningMessage('Would you want to clear the saved GitHub OAuth Token?', { modal: true }, 'Confirm').then(choose => {
|
||||
if (choose === 'Confirm') {
|
||||
return getExtensionContext()!.globalState.update('github-oauth-token', '').then(() => {
|
||||
!silent && vscode.window.showInformationMessage('You have cleared the saved GitHb OAuth Token.');
|
||||
}).then(() => true);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -10,12 +10,12 @@ import { setExtensionContext } from './util';
|
||||
import { commandUpdateToken, commandValidateToken, commandClearToken } from './commands';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
setExtensionContext(context);
|
||||
context.subscriptions.push(new GitHub1sFS());
|
||||
setExtensionContext(context);
|
||||
context.subscriptions.push(new GitHub1sFS());
|
||||
|
||||
context.subscriptions.push(vscode.window.registerWebviewViewProvider(SettingsView.viewType, new SettingsView()));
|
||||
context.subscriptions.push(vscode.window.registerWebviewViewProvider(SettingsView.viewType, new SettingsView()));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('github1s.validate-token', commandValidateToken));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('github1s.validate-token', commandValidateToken));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('github1s.update-token', commandUpdateToken));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('github1s.clear-token', commandClearToken));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
workspace,
|
||||
Disposable,
|
||||
FileSystemProvider,
|
||||
FileSystemError,
|
||||
Event,
|
||||
EventEmitter,
|
||||
FileChangeEvent,
|
||||
FileStat,
|
||||
FileType,
|
||||
Uri,
|
||||
workspace,
|
||||
Disposable,
|
||||
FileSystemProvider,
|
||||
FileSystemError,
|
||||
Event,
|
||||
EventEmitter,
|
||||
FileChangeEvent,
|
||||
FileStat,
|
||||
FileType,
|
||||
Uri,
|
||||
} from 'vscode';
|
||||
import { noop, dirname, reuseable, b64DecodeUnicode} from './util';
|
||||
import { readGitHubDirectory, readGitHubFile } from './api';
|
||||
@@ -62,24 +62,24 @@ export class Directory implements FileStat {
|
||||
export type Entry = File | Directory;
|
||||
|
||||
export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
static scheme = 'github1s';
|
||||
private readonly disposable: Disposable;
|
||||
private _emitter = new EventEmitter<FileChangeEvent[]>();
|
||||
private root: Directory = null;
|
||||
static scheme = 'github1s';
|
||||
private readonly disposable: Disposable;
|
||||
private _emitter = new EventEmitter<FileChangeEvent[]>();
|
||||
private root: Directory = null;
|
||||
|
||||
onDidChangeFile: Event<FileChangeEvent[]> = this._emitter.event;
|
||||
onDidChangeFile: Event<FileChangeEvent[]> = this._emitter.event;
|
||||
|
||||
constructor() {
|
||||
this.disposable = Disposable.from(
|
||||
constructor() {
|
||||
this.disposable = Disposable.from(
|
||||
workspace.registerFileSystemProvider(GitHub1sFS.scheme, this, { isCaseSensitive: true, isReadonly: true }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.disposable?.dispose();
|
||||
}
|
||||
dispose() {
|
||||
this.disposable?.dispose();
|
||||
}
|
||||
|
||||
// --- lookup
|
||||
// --- lookup
|
||||
private async _lookup(uri: Uri, silent: false): Promise<Entry>;
|
||||
private async _lookup(uri: Uri, silent: boolean): Promise<Entry | undefined>;
|
||||
private async _lookup(uri: Uri, silent: boolean): Promise<Entry | undefined> {
|
||||
@@ -110,9 +110,9 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
if (entry instanceof Directory) {
|
||||
return entry;
|
||||
}
|
||||
if (!silent) {
|
||||
throw FileSystemError.FileNotADirectory(uri);
|
||||
}
|
||||
if (!silent) {
|
||||
throw FileSystemError.FileNotADirectory(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private async _lookupAsFile(uri: Uri, silent: boolean): Promise<File> {
|
||||
@@ -120,9 +120,9 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
if (entry instanceof File) {
|
||||
return entry;
|
||||
}
|
||||
if (!silent) {
|
||||
throw FileSystemError.FileIsADirectory(uri);
|
||||
}
|
||||
if (!silent) {
|
||||
throw FileSystemError.FileIsADirectory(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private _lookupParentDirectory(uri: Uri): Promise<Directory> {
|
||||
@@ -130,16 +130,18 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
return this._lookupAsDirectory(_dirname, false);
|
||||
}
|
||||
|
||||
watch(uri: Uri, options: { recursive: boolean; excludes: string[]; }): Disposable {
|
||||
return new Disposable(noop);
|
||||
}
|
||||
watch(uri: Uri, options: { recursive: boolean; excludes: string[]; }): Disposable {
|
||||
return new Disposable(noop);
|
||||
}
|
||||
|
||||
stat(uri: Uri): FileStat | Thenable<FileStat> {
|
||||
return this._lookup(uri, false);
|
||||
}
|
||||
stat(uri: Uri): FileStat | Thenable<FileStat> {
|
||||
return this._lookup(uri, false);
|
||||
}
|
||||
|
||||
readDirectory = reuseable((uri: Uri): [string, FileType][] | Thenable<[string, FileType][]> => {
|
||||
if (!uri.authority) throw FileSystemError.FileNotFound(uri);
|
||||
readDirectory = reuseable((uri: Uri): [string, FileType][] | Thenable<[string, FileType][]> => {
|
||||
if (!uri.authority) {
|
||||
throw FileSystemError.FileNotFound(uri);
|
||||
}
|
||||
return this._lookupAsDirectory(uri, false).then(parent => {
|
||||
if (parent.entries !== null) {
|
||||
const res = Array.from(parent.entries.values())
|
||||
@@ -161,10 +163,12 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
});
|
||||
});
|
||||
});
|
||||
}, (uri: Uri) => uri.toString());
|
||||
}, (uri: Uri) => uri.toString());
|
||||
|
||||
readFile = reuseable((uri: Uri): Uint8Array | Thenable<Uint8Array> => {
|
||||
if (!uri.authority) throw FileSystemError.FileNotFound(uri);
|
||||
if (!uri.authority) {
|
||||
throw FileSystemError.FileNotFound(uri);
|
||||
}
|
||||
return this._lookupAsFile(uri, false).then(file => {
|
||||
if (file.data !== null) {
|
||||
return file.data;
|
||||
@@ -175,26 +179,26 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
|
||||
file.data = encoder.encode(b64DecodeUnicode(blob.content));
|
||||
return file.data;
|
||||
});
|
||||
})
|
||||
}, (uri: Uri) => uri.toString());
|
||||
});
|
||||
}, (uri: Uri) => uri.toString());
|
||||
|
||||
createDirectory(uri: Uri): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
createDirectory(uri: Uri): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
writeFile(uri: Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
writeFile(uri: Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
delete(uri: Uri, options: { recursive: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
delete(uri: Uri, options: { recursive: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
copy?(source: Uri, destination: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
copy?(source: Uri, destination: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,361 +9,367 @@ import { commandClearToken } from './commands';
|
||||
import { validateToken } from './api';
|
||||
|
||||
interface WebviewState {
|
||||
token?: string;
|
||||
pageType?: 'EDIT' | 'PREVIEW';
|
||||
valid?: boolean;
|
||||
validating?: boolean;
|
||||
};
|
||||
token?: string;
|
||||
pageType?: 'EDIT' | 'PREVIEW';
|
||||
valid?: boolean;
|
||||
validating?: boolean;
|
||||
}
|
||||
|
||||
export class SettingsView implements vscode.WebviewViewProvider {
|
||||
public static readonly viewType = 'github1s-settings';
|
||||
private readonly _extensionContext: vscode.ExtensionContext;
|
||||
private _webviewView: vscode.WebviewView;
|
||||
public static readonly viewType = 'github1s-settings';
|
||||
private readonly _extensionContext: vscode.ExtensionContext;
|
||||
private _webviewView: vscode.WebviewView;
|
||||
|
||||
constructor() {
|
||||
this._extensionContext = getExtensionContext();
|
||||
}
|
||||
constructor() {
|
||||
this._extensionContext = getExtensionContext();
|
||||
}
|
||||
|
||||
resolveWebviewView(
|
||||
webviewView: vscode.WebviewView,
|
||||
context: vscode.WebviewViewResolveContext<unknown>,
|
||||
token: vscode.CancellationToken
|
||||
): void | Thenable<void> {
|
||||
this._webviewView = webviewView;
|
||||
webviewView.webview.options = getWebviewOptions(this._extensionContext.extensionUri);
|
||||
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
|
||||
resolveWebviewView(
|
||||
webviewView: vscode.WebviewView,
|
||||
context: vscode.WebviewViewResolveContext<unknown>,
|
||||
token: vscode.CancellationToken
|
||||
): void | Thenable<void> {
|
||||
this._webviewView = webviewView;
|
||||
webviewView.webview.options = getWebviewOptions(this._extensionContext.extensionUri);
|
||||
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
|
||||
|
||||
webviewView.webview.onDidReceiveMessage(data => {
|
||||
switch(data.type) {
|
||||
case 'validate-token':
|
||||
this.handleValidateToken(data.payload);
|
||||
break;
|
||||
case 'update-token':
|
||||
this.handleUpdateToken(data.payload);
|
||||
break;
|
||||
case 'clear-token':
|
||||
commandClearToken().then(cleared => {
|
||||
cleared && this.updateWebviewState({token: '', pageType: 'EDIT', valid: false, validating: false });
|
||||
})
|
||||
break;
|
||||
case 'welcome-page':
|
||||
vscode.commands.executeCommand('workbench.action.showWelcomePage');
|
||||
break;
|
||||
default:
|
||||
const oauthToken = this._extensionContext.globalState.get('github-oauth-token') as string|| '';
|
||||
(oauthToken ? validateToken(oauthToken).then(data => (data.valid && data.remaining > 0)) : Promise.resolve(false)).then(isValid => {
|
||||
this.updateWebviewState({ token: oauthToken, pageType: oauthToken ? 'PREVIEW' : 'EDIT', valid: isValid, validating: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
webviewView.webview.onDidReceiveMessage(data => {
|
||||
switch(data.type) {
|
||||
case 'validate-token':
|
||||
this.handleValidateToken(data.payload);
|
||||
break;
|
||||
case 'update-token':
|
||||
this.handleUpdateToken(data.payload);
|
||||
break;
|
||||
case 'clear-token':
|
||||
commandClearToken().then(cleared => {
|
||||
cleared && this.updateWebviewState({token: '', pageType: 'EDIT', valid: false, validating: false });
|
||||
});
|
||||
break;
|
||||
case 'welcome-page':
|
||||
vscode.commands.executeCommand('workbench.action.showWelcomePage');
|
||||
break;
|
||||
default:
|
||||
const oauthToken = this._extensionContext.globalState.get('github-oauth-token') as string|| '';
|
||||
(oauthToken ? validateToken(oauthToken).then(data => (data.valid && data.remaining > 0)) : Promise.resolve(false)).then(isValid => {
|
||||
this.updateWebviewState({ token: oauthToken, pageType: oauthToken ? 'PREVIEW' : 'EDIT', valid: isValid, validating: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateWebviewState(state: WebviewState) {
|
||||
this._webviewView.webview.postMessage({ type: 'update-state', payload: state });
|
||||
}
|
||||
updateWebviewState(state: WebviewState) {
|
||||
this._webviewView.webview.postMessage({ type: 'update-state', payload: state });
|
||||
}
|
||||
|
||||
handleValidateToken(token: string) {
|
||||
this.updateWebviewState({ validating: true });
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!tokenStatus.valid) vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
|
||||
else if (tokenStatus.remaining <= 0) vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
|
||||
else vscode.window.showInformationMessage('This GitHub OAuth Token is OK.');
|
||||
this.updateWebviewState({ valid: tokenStatus.valid && tokenStatus.remaining > 0, validating: false });
|
||||
}).catch(() => this.updateWebviewState({ valid: false, validating: false }));
|
||||
}
|
||||
handleValidateToken(token: string) {
|
||||
this.updateWebviewState({ validating: true });
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!tokenStatus.valid) {
|
||||
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
|
||||
} else if (tokenStatus.remaining <= 0) {
|
||||
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
|
||||
} else {
|
||||
vscode.window.showInformationMessage('This GitHub OAuth Token is OK.');
|
||||
}
|
||||
this.updateWebviewState({ valid: tokenStatus.valid && tokenStatus.remaining > 0, validating: false });
|
||||
}).catch(() => this.updateWebviewState({ valid: false, validating: false }));
|
||||
}
|
||||
|
||||
handleUpdateToken(token: string) {
|
||||
if (!token) return;
|
||||
this.updateWebviewState({ validating: true });
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!tokenStatus.valid) {
|
||||
this.updateWebviewState({ pageType: 'EDIT', validating: false });
|
||||
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
|
||||
} else if (tokenStatus.remaining <= 0) {
|
||||
this.updateWebviewState({ pageType: 'EDIT', validating: false });
|
||||
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
|
||||
} else {
|
||||
this.updateWebviewState({ token, valid: true, pageType: 'PREVIEW', validating: false })
|
||||
this._extensionContext.globalState.update('github-oauth-token', token || '').then(() => {
|
||||
vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
|
||||
});
|
||||
}
|
||||
}).catch(() => this.updateWebviewState({ token, validating: false }));
|
||||
}
|
||||
handleUpdateToken(token: string) {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
this.updateWebviewState({ validating: true });
|
||||
validateToken(token).then(tokenStatus => {
|
||||
if (!tokenStatus.valid) {
|
||||
this.updateWebviewState({ pageType: 'EDIT', validating: false });
|
||||
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
|
||||
} else if (tokenStatus.remaining <= 0) {
|
||||
this.updateWebviewState({ pageType: 'EDIT', validating: false });
|
||||
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
|
||||
} else {
|
||||
this.updateWebviewState({ token, valid: true, pageType: 'PREVIEW', validating: false });
|
||||
this._extensionContext.globalState.update('github-oauth-token', token || '').then(() => {
|
||||
vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
|
||||
});
|
||||
}
|
||||
}).catch(() => this.updateWebviewState({ token, validating: false }));
|
||||
}
|
||||
|
||||
_getHtmlForWebview(webview): string {
|
||||
const nonce = getNonce();
|
||||
_getHtmlForWebview(webview): string {
|
||||
const nonce = getNonce();
|
||||
|
||||
return `
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${nonce}'; script-src 'nonce-${nonce}';">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>GitHub1s Settings</title>
|
||||
<style nonce="${nonce}">
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${nonce}'; script-src 'nonce-${nonce}';">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>GitHub1s Settings</title>
|
||||
<style nonce="${nonce}">
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
box-sizing: border-box;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6, p, ol, ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: transparent;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
border: none;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
font-family: var(--vscode-font-family);
|
||||
color: var(--vscode-input-foreground);
|
||||
outline-color: var(--vscode-input-border);
|
||||
background-color: var(--vscode-input-background);
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
border: none;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
font-family: var(--vscode-font-family);
|
||||
color: var(--vscode-input-foreground);
|
||||
outline-color: var(--vscode-input-border);
|
||||
background-color: var(--vscode-input-background);
|
||||
}
|
||||
|
||||
button {
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: 26px;
|
||||
margin-bottom: 10px;
|
||||
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
|
||||
text-align: center;
|
||||
outline: 1px solid transparent;
|
||||
outline-offset: 2px !important;
|
||||
color: var(--vscode-button-foreground);
|
||||
background: var(--vscode-button-background);
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: 26px;
|
||||
margin-bottom: 10px;
|
||||
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
|
||||
text-align: center;
|
||||
outline: 1px solid transparent;
|
||||
outline-offset: 2px !important;
|
||||
color: var(--vscode-button-foreground);
|
||||
background: var(--vscode-button-background);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
cursor: pointer;
|
||||
background: var(--vscode-button-hoverBackground);
|
||||
cursor: pointer;
|
||||
background: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline-color: var(--vscode-focusBorder);
|
||||
outline-color: var(--vscode-focusBorder);
|
||||
}
|
||||
|
||||
button.secondary {
|
||||
color: var(--vscode-button-secondaryForeground);
|
||||
background: var(--vscode-button-secondaryBackground);
|
||||
color: var(--vscode-button-secondaryForeground);
|
||||
background: var(--vscode-button-secondaryBackground);
|
||||
}
|
||||
|
||||
button.secondary:hover {
|
||||
background: var(--vscode-button-secondaryHoverBackground);
|
||||
background: var(--vscode-button-secondaryHoverBackground);
|
||||
}
|
||||
|
||||
.loading-page {
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
margin: 60px auto;
|
||||
text-align: center;
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
margin: 60px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-page span {
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
margin-right: 4px;
|
||||
display: inline-block;
|
||||
background:#2b6298;
|
||||
animation: loading 1.2s infinite ease-in-out;
|
||||
-webkit-animation: loading 1.2s infinite ease-in-out;
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
margin-right: 4px;
|
||||
display: inline-block;
|
||||
background:#2b6298;
|
||||
animation: loading 1.2s infinite ease-in-out;
|
||||
-webkit-animation: loading 1.2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.loading-page >span:nth-child(2) {
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s;
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s;
|
||||
}
|
||||
|
||||
.loading-page >span:nth-child(3) {
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s;
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s;
|
||||
}
|
||||
|
||||
.loading-page >span:nth-child(4) {
|
||||
-webkit-animation-delay: -0.8s;
|
||||
animation-delay: -0.8s;
|
||||
-webkit-animation-delay: -0.8s;
|
||||
animation-delay: -0.8s;
|
||||
}
|
||||
|
||||
.loading-page >span:nth-child(5) {
|
||||
-webkit-animation-delay: -0.7s;
|
||||
animation-delay: -0.7s;
|
||||
-webkit-animation-delay: -0.7s;
|
||||
animation-delay: -0.7s;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% { transform: scaleY(0.4); }
|
||||
25% { transform: scaleY(1.0); }
|
||||
50% { transform: scaleY(0.4); }
|
||||
75% { transform: scaleY(0.4); }
|
||||
100% { transform: scaleY(0.4); }
|
||||
0% { transform: scaleY(0.4); }
|
||||
25% { transform: scaleY(1.0); }
|
||||
50% { transform: scaleY(0.4); }
|
||||
75% { transform: scaleY(0.4); }
|
||||
100% { transform: scaleY(0.4); }
|
||||
}
|
||||
|
||||
.preview-page, .edit-page {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.container .token-invalid {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.description div {
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.description div:last-child {
|
||||
margin-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.token-link {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loading-page">
|
||||
<span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="container edit-page">
|
||||
<div class="page-title">Set OAuth Token</div>
|
||||
<div class="description">
|
||||
<div>For unauthenticated requests, the rate limit of GitHub allows for up to 60 requests per hour.</div>
|
||||
<div>For API requests using Authentication, you can make up to 5,000 requests per hour.</div>
|
||||
</div>
|
||||
<div class="token-link">
|
||||
<a href="https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s" target="_blank">
|
||||
Generate New OAuth Token
|
||||
</a>
|
||||
</div>
|
||||
<div><input id="token-input" name="token" autocomplete="off" /></div>
|
||||
<div><button id="save-button">Save</button></div>
|
||||
<div><button id="preview-button">Cancel</button></div>
|
||||
</div>
|
||||
<div class="container preview-page">
|
||||
<div class="page-title">You have authenticated</div>
|
||||
<div class="description">
|
||||
<div class="token-status">
|
||||
Current OAuth Token is <span class="token-status-text"> ...</span>.
|
||||
</div>
|
||||
<div id="token-text"></div>
|
||||
</div>
|
||||
<div><button id="welcome-button">Detail</button></div>
|
||||
<div><button id="validate-button">Validate</button></div>
|
||||
<div><button id="edit-button">Edit</button></div>
|
||||
<div><button id="clear-button">Clear</button></div>
|
||||
</div>
|
||||
<script nonce="${nonce}">
|
||||
<div class="loading-page">
|
||||
<span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="container edit-page">
|
||||
<div class="page-title">Set OAuth Token</div>
|
||||
<div class="description">
|
||||
<div>For unauthenticated requests, the rate limit of GitHub allows for up to 60 requests per hour.</div>
|
||||
<div>For API requests using Authentication, you can make up to 5,000 requests per hour.</div>
|
||||
</div>
|
||||
<div class="token-link">
|
||||
<a href="https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s" target="_blank">
|
||||
Generate New OAuth Token
|
||||
</a>
|
||||
</div>
|
||||
<div><input id="token-input" name="token" autocomplete="off" /></div>
|
||||
<div><button id="save-button">Save</button></div>
|
||||
<div><button id="preview-button">Cancel</button></div>
|
||||
</div>
|
||||
<div class="container preview-page">
|
||||
<div class="page-title">You have authenticated</div>
|
||||
<div class="description">
|
||||
<div class="token-status">
|
||||
Current OAuth Token is <span class="token-status-text"> ...</span>.
|
||||
</div>
|
||||
<div id="token-text"></div>
|
||||
</div>
|
||||
<div><button id="welcome-button">Detail</button></div>
|
||||
<div><button id="validate-button">Validate</button></div>
|
||||
<div><button id="edit-button">Edit</button></div>
|
||||
<div><button id="clear-button">Clear</button></div>
|
||||
</div>
|
||||
<script nonce="${nonce}">
|
||||
(function () {
|
||||
const vscode = acquireVsCodeApi();
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
const updateState = (state) => {
|
||||
const prevState = vscode.getState();
|
||||
vscode.setState({ ...prevState, ...state });
|
||||
updatePage();
|
||||
};
|
||||
const updateState = (state) => {
|
||||
const prevState = vscode.getState();
|
||||
vscode.setState({ ...prevState, ...state });
|
||||
updatePage();
|
||||
};
|
||||
|
||||
window.addEventListener('message', ({ data }) => {
|
||||
if (data && data.type === 'update-state') {
|
||||
updateState(data.payload);
|
||||
}
|
||||
});
|
||||
vscode.postMessage({ type: 'initialization', payload: null });
|
||||
window.addEventListener('message', ({ data }) => {
|
||||
if (data && data.type === 'update-state') {
|
||||
updateState(data.payload);
|
||||
}
|
||||
});
|
||||
vscode.postMessage({ type: 'initialization', payload: null });
|
||||
|
||||
const delegate = (element, selector, eventName, handler) => {
|
||||
if (!element) return null;
|
||||
element.addEventListener(eventName, function (event) {
|
||||
const children = element.querySelectorAll(selector);
|
||||
for (let i = 0, len = children.length; i < len; i++) {
|
||||
if (children[i] === event.target) {
|
||||
handler.call(this, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const delegate = (element, selector, eventName, handler) => {
|
||||
if (!element) return null;
|
||||
element.addEventListener(eventName, function (event) {
|
||||
const children = element.querySelectorAll(selector);
|
||||
for (let i = 0, len = children.length; i < len; i++) {
|
||||
if (children[i] === event.target) {
|
||||
handler.call(this, event);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
delegate(document.body, '#save-button', 'click', () => {
|
||||
const tokenInput = document.getElementById('token-input');
|
||||
vscode.postMessage({ type: 'update-token', payload: tokenInput ? tokenInput.value : '' });
|
||||
});
|
||||
delegate(document.body, '#save-button', 'click', () => {
|
||||
const tokenInput = document.getElementById('token-input');
|
||||
vscode.postMessage({ type: 'update-token', payload: tokenInput ? tokenInput.value : '' });
|
||||
});
|
||||
|
||||
delegate(document.body, '#preview-button', 'click', () => {
|
||||
updateState({ pageType: 'PREVIEW' });
|
||||
});
|
||||
delegate(document.body, '#preview-button', 'click', () => {
|
||||
updateState({ pageType: 'PREVIEW' });
|
||||
});
|
||||
|
||||
delegate(document.body, '#validate-button', 'click', () => {
|
||||
const state = vscode.getState();
|
||||
vscode.postMessage({ type: 'validate-token', payload: state ? state.token : '' });
|
||||
});
|
||||
delegate(document.body, '#validate-button', 'click', () => {
|
||||
const state = vscode.getState();
|
||||
vscode.postMessage({ type: 'validate-token', payload: state ? state.token : '' });
|
||||
});
|
||||
|
||||
delegate(document.body, '#edit-button', 'click', () => {
|
||||
updateState({ pageType: 'EDIT' });
|
||||
});
|
||||
delegate(document.body, '#edit-button', 'click', () => {
|
||||
updateState({ pageType: 'EDIT' });
|
||||
});
|
||||
|
||||
delegate(document.body, '#clear-button', 'click', () => {
|
||||
vscode.postMessage({ type: 'clear-token' });
|
||||
});
|
||||
delegate(document.body, '#clear-button', 'click', () => {
|
||||
vscode.postMessage({ type: 'clear-token' });
|
||||
});
|
||||
|
||||
delegate(document.body, '#welcome-button', 'click', () => {
|
||||
vscode.postMessage({ type: 'welcome-page' });
|
||||
});
|
||||
delegate(document.body, '#welcome-button', 'click', () => {
|
||||
vscode.postMessage({ type: 'welcome-page' });
|
||||
});
|
||||
|
||||
const updatePage = () => {
|
||||
const { token, pageType, valid, validating } = vscode.getState() || { token: '', preview: 'EDIT', valid: true, validating: true };
|
||||
if (validating) {
|
||||
document.querySelector('.loading-page').style.display = 'block';
|
||||
document.querySelector('.preview-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
const updatePage = () => {
|
||||
const { token, pageType, valid, validating } = vscode.getState() || { token: '', preview: 'EDIT', valid: true, validating: true };
|
||||
if (validating) {
|
||||
document.querySelector('.loading-page').style.display = 'block';
|
||||
document.querySelector('.preview-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
if (pageType === 'EDIT') {
|
||||
document.querySelector('.loading-page').style.display = 'none';
|
||||
document.querySelector('.preview-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'block';
|
||||
document.querySelector('#preview-button').style.display = (token ? 'block' : 'none');
|
||||
return;
|
||||
}
|
||||
if (pageType === 'EDIT') {
|
||||
document.querySelector('.loading-page').style.display = 'none';
|
||||
document.querySelector('.preview-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'block';
|
||||
document.querySelector('#preview-button').style.display = (token ? 'block' : 'none');
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector('.loading-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'none';
|
||||
document.querySelector('.preview-page').style.display = 'block';
|
||||
document.querySelector('.container .token-status .token-status-text').innerText = (valid ? ' VALID' : ' INVALID');
|
||||
document.querySelector('#token-text').innerText = token.slice(0, 7) + token.slice(7).replace(/./g, '*');
|
||||
document.querySelector('#token-text').style.color = (valid ? '#73c991' : '#f88070');
|
||||
};
|
||||
document.querySelector('.loading-page').style.display = 'none';
|
||||
document.querySelector('.edit-page').style.display = 'none';
|
||||
document.querySelector('.preview-page').style.display = 'block';
|
||||
document.querySelector('.container .token-status .token-status-text').innerText = (valid ? ' VALID' : ' INVALID');
|
||||
document.querySelector('#token-text').innerText = token.slice(0, 7) + token.slice(7).replace(/./g, '*');
|
||||
document.querySelector('#token-text').style.color = (valid ? '#73c991' : '#f88070');
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import * as vscode from 'vscode';
|
||||
let extensionContext: vscode.ExtensionContext | null = null;
|
||||
|
||||
export const setExtensionContext = (_extensionContext: vscode.ExtensionContext) => {
|
||||
extensionContext = _extensionContext;
|
||||
extensionContext = _extensionContext;
|
||||
};
|
||||
|
||||
export const getExtensionContext = (): vscode.ExtensionContext | null => {
|
||||
return extensionContext;
|
||||
return extensionContext;
|
||||
};
|
||||
|
||||
@@ -8,72 +8,72 @@ import { throttle } from './func';
|
||||
import { getExtensionContext } from './context';
|
||||
|
||||
const getGitHubAuthToken = (): string => {
|
||||
const context = getExtensionContext();
|
||||
return context?.globalState.get('github-oauth-token') || '';
|
||||
const context = getExtensionContext();
|
||||
return context?.globalState.get('github-oauth-token') || '';
|
||||
};
|
||||
|
||||
export class RequestError extends Error {
|
||||
constructor(message: string, public token: string) {
|
||||
super(message);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
constructor(message: string, public token: string) {
|
||||
super(message);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
(<any>Object).setPrototypeOf(this, RequestError.prototype);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestNotFoundError extends RequestError {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
(<any>Object).setPrototypeOf(this, RequestNotFoundError.prototype);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestRateLimitError extends RequestError {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
(<any>Object).setPrototypeOf(this, RequestRateLimitError.prototype);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class RequestInvalidTokenError extends RequestError {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
constructor(message: string, token: string) {
|
||||
super(message, token);
|
||||
if (typeof (<any>Object).setPrototypeOf === 'function') {
|
||||
(<any>Object).setPrototypeOf(this, RequestInvalidTokenError.prototype);
|
||||
}RequestInvalidTokenError
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// only report network error once in 5 seconds
|
||||
export const throttledReportNetworkError = throttle(() => vscode.window.showErrorMessage('Request Failed, Maybe an Network Error'), 5000);
|
||||
|
||||
export const fetch = (url: string, options?: RequestInit) => {
|
||||
const token = getGitHubAuthToken();
|
||||
const authHeaders = token ? { Authorization: `token ${token}` } : {};
|
||||
const customHeaders = (options && 'headers' in options ? options.headers : {})
|
||||
const token = getGitHubAuthToken();
|
||||
const authHeaders = token ? { Authorization: `token ${token}` } : {};
|
||||
const customHeaders = (options && 'headers' in options ? options.headers : {});
|
||||
|
||||
return self.fetch(url, { mode: 'cors', ...options, headers: { ...authHeaders, ...customHeaders } })
|
||||
.catch(() => {
|
||||
throttledReportNetworkError();
|
||||
throw new RequestError('Request Failed, Maybe an Network Error', token);
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status < 400) {
|
||||
return response.json();
|
||||
}
|
||||
if (response.status === 403) {
|
||||
return response.json().then(data => { throw new RequestRateLimitError(data.message, token); });
|
||||
}
|
||||
if (response.status === 401) {
|
||||
return response.json().then(data => { throw new RequestInvalidTokenError(data.message, token); });
|
||||
}
|
||||
if (response.status === 404) {
|
||||
throw new RequestNotFoundError('Not Found', token);
|
||||
}
|
||||
throw new RequestError(`GitHub1s: Request got HTTP ${response.status} response`, token);
|
||||
});
|
||||
return self.fetch(url, { mode: 'cors', ...options, headers: { ...authHeaders, ...customHeaders } })
|
||||
.catch(() => {
|
||||
throttledReportNetworkError();
|
||||
throw new RequestError('Request Failed, Maybe an Network Error', token);
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status < 400) {
|
||||
return response.json();
|
||||
}
|
||||
if (response.status === 403) {
|
||||
return response.json().then(data => { throw new RequestRateLimitError(data.message, token); });
|
||||
}
|
||||
if (response.status === 401) {
|
||||
return response.json().then(data => { throw new RequestInvalidTokenError(data.message, token); });
|
||||
}
|
||||
if (response.status === 404) {
|
||||
throw new RequestNotFoundError('Not Found', token);
|
||||
}
|
||||
throw new RequestError(`GitHub1s: Request got HTTP ${response.status} response`, token);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -11,25 +11,27 @@ const defaultComputeCacheKey = (...args) => jsonStableStringify([...args]);
|
||||
// reuse previous promise when a request call
|
||||
// and previous request not completed
|
||||
export const reuseable = (func, computeCacheKey = defaultComputeCacheKey) => {
|
||||
const cache = new Map<string, Promise<any>>();
|
||||
const cache = new Map<string, Promise<any>>();
|
||||
|
||||
return function (...args: any[]): Promise<any> {
|
||||
const key = computeCacheKey(...args);
|
||||
if (cache.has(key)) {
|
||||
return cache.get(key);
|
||||
}
|
||||
return function (...args: any[]): Promise<any> {
|
||||
const key = computeCacheKey(...args);
|
||||
if (cache.has(key)) {
|
||||
return cache.get(key);
|
||||
}
|
||||
|
||||
const promise = func.call(this, ...args);
|
||||
cache.set(key, promise);
|
||||
return pFinally(promise, () => cache.delete(key));
|
||||
};
|
||||
const promise = func.call(this, ...args);
|
||||
cache.set(key, promise);
|
||||
return pFinally(promise, () => cache.delete(key));
|
||||
};
|
||||
};
|
||||
|
||||
export const throttle = (func: Function, interval: number) => {
|
||||
let timer = null;
|
||||
return function(...args: any[]): any {
|
||||
if (timer) return;
|
||||
func.call(this, ...args);
|
||||
timer = setTimeout(() => (timer = null), interval);
|
||||
}
|
||||
let timer = null;
|
||||
return function(...args: any[]): any {
|
||||
if (timer) {
|
||||
return;
|
||||
}
|
||||
func.call(this, ...args);
|
||||
timer = setTimeout(() => (timer = null), interval);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,51 +11,51 @@ export { getExtensionContext, setExtensionContext } from './context';
|
||||
export const noop = () => { };
|
||||
|
||||
export const trimStart = (str: string, chars: string = ' '): string => {
|
||||
let index = 0;
|
||||
while (chars.indexOf(str[index]) !== -1) {
|
||||
index++;
|
||||
}
|
||||
return str.slice(index);
|
||||
let index = 0;
|
||||
while (chars.indexOf(str[index]) !== -1) {
|
||||
index++;
|
||||
}
|
||||
return str.slice(index);
|
||||
};
|
||||
|
||||
export const trimEnd = (str: string, chars: string = ' '): string => {
|
||||
let length = str.length;
|
||||
while (length && chars.indexOf(str[length - 1]) !== -1) {
|
||||
length--;
|
||||
}
|
||||
return str.slice(0, length);
|
||||
let length = str.length;
|
||||
while (length && chars.indexOf(str[length - 1]) !== -1) {
|
||||
length--;
|
||||
}
|
||||
return str.slice(0, length);
|
||||
};
|
||||
|
||||
export const joinPath = (...segments: string[]): string => {
|
||||
if (!segments.length) {
|
||||
return '';
|
||||
}
|
||||
if (!segments.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return segments.reduce((prev, segment) => {
|
||||
return trimEnd(prev, '/') + '/' + trimStart(segment, '/');
|
||||
});
|
||||
return segments.reduce((prev, segment) => {
|
||||
return trimEnd(prev, '/') + '/' + trimStart(segment, '/');
|
||||
});
|
||||
};
|
||||
|
||||
export const dirname = (path: string): string => {
|
||||
const trimmedPath = trimEnd(path, '/');
|
||||
return trimmedPath.substr(0, trimmedPath.lastIndexOf('/')) || '';
|
||||
}
|
||||
const trimmedPath = trimEnd(path, '/');
|
||||
return trimmedPath.substr(0, trimmedPath.lastIndexOf('/')) || '';
|
||||
};
|
||||
|
||||
export const uniqueId = (id => () => id++)(1);
|
||||
|
||||
export const prop = (obj: object, path: (string | number)[] = []): any => {
|
||||
let cur = obj;
|
||||
path.forEach(key => (cur = (cur ? cur[key] : undefined)));
|
||||
return cur;
|
||||
let cur = obj;
|
||||
path.forEach(key => (cur = (cur ? cur[key] : undefined)));
|
||||
return cur;
|
||||
};
|
||||
|
||||
export const getNonce = (): string => {
|
||||
let text: string = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
let text: string = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
export const getWebviewOptions = (extensionUri: vscode.Uri): vscode.WebviewOptions => {
|
||||
@@ -68,9 +68,9 @@ export const getWebviewOptions = (extensionUri: vscode.Uri): vscode.WebviewOptio
|
||||
};
|
||||
|
||||
export const b64DecodeUnicode = (str) => {
|
||||
// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
|
||||
// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
|
||||
// Going backwards: from bytestream, to percent-encoding, to original string.
|
||||
return decodeURIComponent(atob(str).split('').map(function(c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
};
|
||||
|
||||
10
package.json
10
package.json
@@ -8,9 +8,14 @@
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^4.15.0",
|
||||
"@typescript-eslint/parser": "^4.15.0",
|
||||
"chokidar": "^3.5.1",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-plugin-jsdoc": "^31.6.1",
|
||||
"fs-extra": "^9.1.0",
|
||||
"serve-handler": "^6.1.3"
|
||||
"serve-handler": "^6.1.3",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "./scripts/postinstall.sh",
|
||||
@@ -20,7 +25,8 @@
|
||||
"hash": "./scripts/hash.sh",
|
||||
"package": "./scripts/package.sh",
|
||||
"watch": "./scripts/watch.sh",
|
||||
"serve": "node ./scripts/serve-dist.js"
|
||||
"serve": "node ./scripts/serve-dist.js",
|
||||
"eslint": "eslint --ext .ts --ext .js ./src/vs ./extensions"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
||||
@@ -55,6 +55,6 @@
|
||||
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
|
||||
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/static/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
|
||||
require(['vs/code/browser/workbench/workbench'], function() {});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
<script>
|
||||
fetch('/{STATIC_FOLDER}/configure/extensions.json').then(response => response.text()).then(extensionsJson => {
|
||||
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
|
||||
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/{STATIC_FOLDER}/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
|
||||
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/{STATIC_FOLDER}/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
|
||||
require(['vs/code/browser/workbench/workbench'], function() {});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -56,6 +56,6 @@
|
||||
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
|
||||
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/static/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
|
||||
require(['vs/code/browser/workbench/workbench'], function() {});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -7,14 +7,14 @@ export IS_BUILD="true"
|
||||
|
||||
# execute all necessary tasks
|
||||
function main() {
|
||||
rm -rf "${APP_ROOT}/dist"
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./build/sync-code.sh
|
||||
./build/build-vscode.sh
|
||||
./build/build-github1s-extensions.sh
|
||||
./package.sh
|
||||
rm -rf "${APP_ROOT}/dist"
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./build/sync-code.sh
|
||||
./build/build-vscode.sh
|
||||
./build/build-github1s-extensions.sh
|
||||
./package.sh
|
||||
|
||||
echo "all build done!"
|
||||
echo "all build done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -5,9 +5,9 @@ cd "$(dirname "${0}")/../.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
cd "${APP_ROOT}/extensions/github1s"
|
||||
yarn build
|
||||
echo "build github1s-extensions done!"
|
||||
cd "${APP_ROOT}/extensions/github1s"
|
||||
yarn build
|
||||
echo "build github1s-extensions done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -6,15 +6,15 @@ APP_ROOT=$(pwd)
|
||||
|
||||
# build vscode source and vscode builtin extensions
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
rsync -a resources/gulp-github1s.js lib/vscode
|
||||
cd lib/vscode
|
||||
cd ${APP_ROOT}
|
||||
rsync -a resources/gulp-github1s.js lib/vscode
|
||||
cd lib/vscode
|
||||
|
||||
yarn gulp compile-build
|
||||
yarn gulp optimize --gulpfile ./gulp-github1s.js
|
||||
yarn gulp minify --gulpfile ./gulp-github1s.js
|
||||
yarn gulp compile-build
|
||||
yarn gulp optimize --gulpfile ./gulp-github1s.js
|
||||
yarn gulp minify --gulpfile ./gulp-github1s.js
|
||||
|
||||
echo "build vscode done!"
|
||||
echo "build vscode done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -6,8 +6,8 @@ APP_ROOT=$(pwd)
|
||||
|
||||
# sync src/* to vscode
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
rsync -a src/ lib/vscode/src
|
||||
cd ${APP_ROOT}
|
||||
rsync -a src/ lib/vscode/src
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -6,9 +6,9 @@ APP_ROOT=$(pwd)
|
||||
|
||||
# execute all necessary tasks
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
rm -rf dist extensions/github1s/dist
|
||||
echo "remove dist"
|
||||
cd ${APP_ROOT}
|
||||
rm -rf dist extensions/github1s/dist
|
||||
echo "remove dist"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -6,10 +6,10 @@ APP_ROOT=$(pwd)
|
||||
|
||||
# execute all necessary tasks
|
||||
function main() {
|
||||
./scripts/clean-build.sh
|
||||
cd ${APP_ROOT}
|
||||
rm -rf node_modules lib extensions/github1s/node_modules
|
||||
echo "clean all"
|
||||
./scripts/clean-build.sh
|
||||
cd ${APP_ROOT}
|
||||
rm -rf node_modules lib extensions/github1s/node_modules
|
||||
echo "clean all"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -9,9 +9,9 @@ SHORT_COMMIT_ID=${COMMIT_ID:0:7}
|
||||
STATIC_FOLDER_NAME="static-${SHORT_COMMIT_ID-unknown}"
|
||||
|
||||
if [ -e "${APP_ROOT}/dist/static" ]; then
|
||||
mv "${APP_ROOT}/dist/static" "${APP_ROOT}/dist/${STATIC_FOLDER_NAME}"
|
||||
sed "s/{STATIC_FOLDER}/${STATIC_FOLDER_NAME}/" "${APP_ROOT}/resources/index-hash.html" > "${APP_ROOT}/dist/index.html"
|
||||
echo "hash static files done"
|
||||
mv "${APP_ROOT}/dist/static" "${APP_ROOT}/dist/${STATIC_FOLDER_NAME}"
|
||||
sed "s/{STATIC_FOLDER}/${STATIC_FOLDER_NAME}/" "${APP_ROOT}/resources/index-hash.html" > "${APP_ROOT}/dist/index.html"
|
||||
echo "hash static files done"
|
||||
else
|
||||
echo "Please build github1s first"
|
||||
echo "Please build github1s first"
|
||||
fi
|
||||
|
||||
@@ -5,14 +5,14 @@ cd "$(dirname "${0}")/.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./package/copy-vscode.sh
|
||||
./package/copy-extensions.sh
|
||||
./package/copy-node_modules.sh
|
||||
./package/copy-resources.sh
|
||||
node ./package/generate-config.js
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./package/copy-vscode.sh
|
||||
./package/copy-extensions.sh
|
||||
./package/copy-node_modules.sh
|
||||
./package/copy-resources.sh
|
||||
node ./package/generate-config.js
|
||||
|
||||
echo "all copy done!"
|
||||
echo "all copy done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -8,21 +8,21 @@ const TARGET_DIR = path.join(APP_ROOT, 'dist/static/extensions');
|
||||
const enableExtensions = require(path.join(APP_ROOT, 'resources/builtin-extensions.json')) || [];
|
||||
|
||||
const main = () => {
|
||||
fs.ensureDirSync(TARGET_DIR);
|
||||
fs.ensureDirSync(TARGET_DIR);
|
||||
|
||||
enableExtensions.forEach(extension => {
|
||||
fs.copySync(
|
||||
path.join(APP_ROOT, 'lib/vscode', extension.path),
|
||||
path.join(TARGET_DIR, path.basename(extension.path)),
|
||||
{ filter: src => !src.includes('node_modules') }
|
||||
);
|
||||
});
|
||||
enableExtensions.forEach(extension => {
|
||||
fs.copySync(
|
||||
path.join(APP_ROOT, 'lib/vscode', extension.path),
|
||||
path.join(TARGET_DIR, path.basename(extension.path)),
|
||||
{ filter: src => !src.includes('node_modules') }
|
||||
);
|
||||
});
|
||||
|
||||
fs.copySync(
|
||||
path.join(APP_ROOT, 'extensions/github1s'),
|
||||
path.join(TARGET_DIR, 'github1s'),
|
||||
{ filter: src => !src.includes('node_modules') }
|
||||
);
|
||||
fs.copySync(
|
||||
path.join(APP_ROOT, 'extensions/github1s'),
|
||||
path.join(TARGET_DIR, 'github1s'),
|
||||
{ filter: src => !src.includes('node_modules') }
|
||||
);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
@@ -5,21 +5,21 @@ cd "$(dirname "${0}")/../.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function ensureBuiltinExtensitions() {
|
||||
cd "${APP_ROOT}/lib/vscode"
|
||||
if [ ! -e "extensions/emmet/dist/browser" ]
|
||||
then
|
||||
echo "compile vscode builtin extensions..."
|
||||
yarn gulp compile-web
|
||||
fi
|
||||
cd "${APP_ROOT}/lib/vscode"
|
||||
if [ ! -e "extensions/emmet/dist/browser" ]
|
||||
then
|
||||
echo "compile vscode builtin extensions..."
|
||||
yarn gulp compile-web
|
||||
fi
|
||||
}
|
||||
|
||||
function main() {
|
||||
ensureBuiltinExtensitions
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static/extensions
|
||||
node scripts/package/copy-extensions.js
|
||||
ensureBuiltinExtensitions
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static/extensions
|
||||
node scripts/package/copy-extensions.js
|
||||
|
||||
echo "copy vscode builtin extensions done!"
|
||||
echo "copy vscode builtin extensions done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -5,16 +5,16 @@ cd "$(dirname "${0}")/../.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static/node_modules
|
||||
dependencies=(vscode-textmate vscode-oniguruma xterm xterm-addon-search xterm-addon-unicode11 xterm-addon-webgl tas-client-umd iconv-lite-umd jschardet)
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static/node_modules
|
||||
dependencies=(vscode-textmate vscode-oniguruma xterm xterm-addon-search xterm-addon-unicode11 xterm-addon-webgl tas-client-umd iconv-lite-umd jschardet)
|
||||
|
||||
for dependency in ${dependencies[@]};
|
||||
do
|
||||
rsync -a --del lib/vscode/node_modules/${dependency} dist/static/node_modules
|
||||
done
|
||||
for dependency in ${dependencies[@]};
|
||||
do
|
||||
rsync -a --del lib/vscode/node_modules/${dependency} dist/static/node_modules
|
||||
done
|
||||
|
||||
echo "copy necessary node_modules done!"
|
||||
echo "copy necessary node_modules done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -5,18 +5,18 @@ cd "$(dirname "${0}")/../.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist
|
||||
if [ "${IS_BUILD-}" ];
|
||||
then
|
||||
cp resources/index.html dist/index.html
|
||||
else
|
||||
cp resources/index-dev.html dist/index.html
|
||||
fi
|
||||
cp resources/favicon.ico dist
|
||||
cp resources/manifest.json dist
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist
|
||||
if [ "${IS_BUILD-}" ];
|
||||
then
|
||||
cp resources/index.html dist/index.html
|
||||
else
|
||||
cp resources/index-dev.html dist/index.html
|
||||
fi
|
||||
cp resources/favicon.ico dist
|
||||
cp resources/manifest.json dist
|
||||
|
||||
echo "copy resources done!"
|
||||
echo "copy resources done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -5,11 +5,11 @@ cd "$(dirname "${0}")/../.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static
|
||||
rsync -a --del lib/vscode/out-vscode-min/ dist/static/vscode
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p dist/static
|
||||
rsync -a --del lib/vscode/out-vscode-min/ dist/static/vscode
|
||||
|
||||
echo "copy vscode done!"
|
||||
echo "copy vscode done!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -19,44 +19,44 @@ const isWebExtension = (manifest) => {
|
||||
};
|
||||
|
||||
const getExtensionData = (absolutePath) => {
|
||||
try {
|
||||
const packageJSONPath = path.join(absolutePath, 'package.json');
|
||||
if (!fs.existsSync(packageJSONPath)) {
|
||||
return null;
|
||||
}
|
||||
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8'));
|
||||
if (!isWebExtension(packageJSON)) {
|
||||
return null;
|
||||
}
|
||||
const children = fs.readdirSync(absolutePath);
|
||||
const packageNLSPath = children.filter(child => child === 'package.nls.json')[0];
|
||||
const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(absolutePath, packageNLSPath)).toString()) : undefined;
|
||||
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
|
||||
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
|
||||
const extensionFolder = path.basename(absolutePath);
|
||||
try {
|
||||
const packageJSONPath = path.join(absolutePath, 'package.json');
|
||||
if (!fs.existsSync(packageJSONPath)) {
|
||||
return null;
|
||||
}
|
||||
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8'));
|
||||
if (!isWebExtension(packageJSON)) {
|
||||
return null;
|
||||
}
|
||||
const children = fs.readdirSync(absolutePath);
|
||||
const packageNLSPath = children.filter(child => child === 'package.nls.json')[0];
|
||||
const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(absolutePath, packageNLSPath)).toString()) : undefined;
|
||||
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
|
||||
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
|
||||
const extensionFolder = path.basename(absolutePath);
|
||||
|
||||
return {
|
||||
extensionPath: extensionFolder,
|
||||
packageJSON,
|
||||
packageNLS,
|
||||
readmePath: readme ? path.join(extensionFolder, readme) : undefined,
|
||||
changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
extensionPath: extensionFolder,
|
||||
packageJSON,
|
||||
packageNLS,
|
||||
readmePath: readme ? path.join(extensionFolder, readme) : undefined,
|
||||
changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const scanBuiltinExtensions = () => {
|
||||
return enableExtensions.map(item => getExtensionData(path.join(VSCODE_PATH, item.path))).filter(Boolean);
|
||||
return enableExtensions.map(item => getExtensionData(path.join(VSCODE_PATH, item.path))).filter(Boolean);
|
||||
};
|
||||
|
||||
const main = () => {
|
||||
const CONFIGURE_PATH = path.join(APP_ROOT, 'dist/static/configure');
|
||||
const extensions = [...scanBuiltinExtensions(), getExtensionData(path.join(APP_ROOT, 'extensions/github1s'))];
|
||||
const CONFIGURE_PATH = path.join(APP_ROOT, 'dist/static/configure');
|
||||
const extensions = [...scanBuiltinExtensions(), getExtensionData(path.join(APP_ROOT, 'extensions/github1s'))];
|
||||
|
||||
fs.ensureDirSync(CONFIGURE_PATH);
|
||||
fs.writeFileSync(path.join(CONFIGURE_PATH, 'extensions.json'), JSON.stringify(extensions));
|
||||
fs.ensureDirSync(CONFIGURE_PATH);
|
||||
fs.writeFileSync(path.join(CONFIGURE_PATH, 'extensions.json'), JSON.stringify(extensions));
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
@@ -5,17 +5,17 @@ cd "$(dirname "${0}")/.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function main() {
|
||||
# install github1s extension dependencies
|
||||
cd ${APP_ROOT}/extensions/github1s
|
||||
yarn ${CI+--frozen-lockfile}
|
||||
# install github1s extension dependencies
|
||||
cd ${APP_ROOT}/extensions/github1s
|
||||
yarn ${CI+--frozen-lockfile}
|
||||
|
||||
# clone vscode and install dependencies
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p lib
|
||||
cd lib
|
||||
git clone --depth 1 -b 1.52.1 https://github.com/microsoft/vscode.git vscode
|
||||
cd vscode
|
||||
yarn ${CI+--frozen-lockfile}
|
||||
# clone vscode and install dependencies
|
||||
cd ${APP_ROOT}
|
||||
mkdir -p lib
|
||||
cd lib
|
||||
git clone --depth 1 -b 1.52.1 https://github.com/microsoft/vscode.git vscode
|
||||
cd vscode
|
||||
yarn ${CI+--frozen-lockfile}
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -10,13 +10,13 @@ const APP_ROOT = path.join(__dirname, '..');
|
||||
const options = { public: path.join(APP_ROOT, 'dist'), cleanUrls: false, };
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
const urlObj = url.parse(request.url);
|
||||
return fs.access(path.join(APP_ROOT, 'dist', urlObj.pathname), fs.constants.F_OK, (error) => {
|
||||
if (!error) return handler(request, response, options);
|
||||
return handler(request, response, { rewrites: [{ source: '*', destination: '/index.html' }], ...options });
|
||||
});
|
||||
const urlObj = url.parse(request.url);
|
||||
return fs.access(path.join(APP_ROOT, 'dist', urlObj.pathname), fs.constants.F_OK, (error) => {
|
||||
if (!error) return handler(request, response, options);
|
||||
return handler(request, response, { rewrites: [{ source: '*', destination: '/index.html' }], ...options });
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(5000, () => {
|
||||
console.log('Running GitHub1s at http://localhost:5000');
|
||||
console.log('Running GitHub1s at http://localhost:5000');
|
||||
});
|
||||
|
||||
@@ -5,48 +5,48 @@ cd "$(dirname "${0}")/.."
|
||||
APP_ROOT=$(pwd)
|
||||
|
||||
function watch_vscode() {
|
||||
cd ${APP_ROOT}/lib/vscode
|
||||
yarn watch 2>&1 > /dev/null &
|
||||
echo "watching vscode"
|
||||
cd ${APP_ROOT}/lib/vscode
|
||||
yarn watch 2>&1 > /dev/null &
|
||||
echo "watching vscode"
|
||||
}
|
||||
|
||||
function watch_github1s() {
|
||||
cd ${APP_ROOT}/scripts/watch
|
||||
node watch-src.js 2>&1 > /dev/null &
|
||||
echo "watching github1s"
|
||||
cd ${APP_ROOT}/scripts/watch
|
||||
node watch-src.js 2>&1 > /dev/null &
|
||||
echo "watching github1s"
|
||||
}
|
||||
|
||||
function watch_github1s_extension() {
|
||||
cd ${APP_ROOT}/extensions/github1s
|
||||
yarn dev 2>&1 > /dev/null &
|
||||
echo "watching github1s_extensions"
|
||||
cd ${APP_ROOT}/extensions/github1s
|
||||
yarn dev 2>&1 > /dev/null &
|
||||
echo "watching github1s_extensions"
|
||||
}
|
||||
|
||||
function watch_dist() {
|
||||
cd ${APP_ROOT}/scripts/watch
|
||||
node watch-dist.js
|
||||
echo "auto sync to dist"
|
||||
cd ${APP_ROOT}/scripts/watch
|
||||
node watch-dist.js
|
||||
echo "auto sync to dist"
|
||||
}
|
||||
|
||||
# execute all necessary tasks
|
||||
function main() {
|
||||
rm -rf "${APP_ROOT}/dist"
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./package/copy-resources.sh
|
||||
./package/copy-node_modules.sh
|
||||
./package/copy-extensions.sh
|
||||
node ./package/generate-config.js
|
||||
watch_vscode
|
||||
watch_github1s
|
||||
watch_github1s_extension
|
||||
rm -rf "${APP_ROOT}/dist"
|
||||
cd "${APP_ROOT}/scripts"
|
||||
./package/copy-resources.sh
|
||||
./package/copy-node_modules.sh
|
||||
./package/copy-extensions.sh
|
||||
node ./package/generate-config.js
|
||||
watch_vscode
|
||||
watch_github1s
|
||||
watch_github1s_extension
|
||||
|
||||
echo 'please waiting...'
|
||||
while [ ! -e "${APP_ROOT}/lib/vscode/out" ]
|
||||
do
|
||||
echo "waiting for vsocde build..."
|
||||
sleep 3
|
||||
done
|
||||
watch_dist
|
||||
echo 'please waiting...'
|
||||
while [ ! -e "${APP_ROOT}/lib/vscode/out" ]
|
||||
do
|
||||
echo "waiting for vsocde build..."
|
||||
sleep 3
|
||||
done
|
||||
watch_dist
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -9,48 +9,48 @@ const util = require('util');
|
||||
const APP_ROOT = path.join(__dirname, '../..');
|
||||
|
||||
const debounce = (func, delay) => {
|
||||
let timer = null;
|
||||
let lastResult = null;
|
||||
return function () {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
lastResult = func.apply(this, Array.prototype.slice.call(arguments, 0));
|
||||
}, delay);
|
||||
return lastResult;
|
||||
};
|
||||
let timer = null;
|
||||
let lastResult = null;
|
||||
return function () {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
lastResult = func.apply(this, Array.prototype.slice.call(arguments, 0));
|
||||
}, delay);
|
||||
return lastResult;
|
||||
};
|
||||
};
|
||||
|
||||
const autoSyncVscodeOut = async () => {
|
||||
const SOURCE = path.join(APP_ROOT, 'lib/vscode/out');
|
||||
const TARGET = path.join(APP_ROOT, 'dist/static/vscode');
|
||||
|
||||
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
|
||||
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
console.log(`sync ${path}`);
|
||||
}, 300));
|
||||
const SOURCE = path.join(APP_ROOT, 'lib/vscode/out');
|
||||
const TARGET = path.join(APP_ROOT, 'dist/static/vscode');
|
||||
|
||||
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
|
||||
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
console.log(`sync ${path}`);
|
||||
}, 300));
|
||||
};
|
||||
|
||||
const autoSyncGitHub1sExtension = async () => {
|
||||
const SOURCE = path.join(APP_ROOT, 'extensions/github1s');
|
||||
const TARGET = path.join(APP_ROOT, 'dist/static/extensions/github1s');
|
||||
const SOURCE = path.join(APP_ROOT, 'extensions/github1s');
|
||||
const TARGET = path.join(APP_ROOT, 'dist/static/extensions/github1s');
|
||||
|
||||
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
|
||||
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
console.log(`sync ${path}`);
|
||||
}, 300));
|
||||
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
console.log(`sync ${path}`);
|
||||
}, 300));
|
||||
};
|
||||
|
||||
const main = () => {
|
||||
fs.ensureDirSync(path.join(APP_ROOT, 'dist/static'))
|
||||
fs.ensureDirSync(path.join(APP_ROOT, 'dist/static'))
|
||||
|
||||
autoSyncVscodeOut();
|
||||
autoSyncGitHub1sExtension();
|
||||
autoSyncVscodeOut();
|
||||
autoSyncGitHub1sExtension();
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
@@ -7,13 +7,13 @@ const cp = require('child_process');
|
||||
const APP_ROOT = path.join(__dirname, '../..');
|
||||
|
||||
const main = () => {
|
||||
const SOURCE = path.join(APP_ROOT, 'src');
|
||||
const TARGET = path.join(APP_ROOT, 'lib/vscode/src');
|
||||
const watcher = chokidar.watch(SOURCE);
|
||||
const SOURCE = path.join(APP_ROOT, 'src');
|
||||
const TARGET = path.join(APP_ROOT, 'lib/vscode/src');
|
||||
const watcher = chokidar.watch(SOURCE);
|
||||
|
||||
watcher.on('all', () => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
});
|
||||
watcher.on('all', () => {
|
||||
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
|
||||
});
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
@@ -398,12 +398,12 @@ class WindowIndicator implements IWindowIndicator {
|
||||
}
|
||||
|
||||
(function () {
|
||||
const route = parseGitHubUrl(window.location.href);
|
||||
const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = {
|
||||
folderUri: URI.from({ scheme: "github1s", path: '/', authority: `${route.owner}+${route.repo}+${route.branch}` }),
|
||||
staticExtensions: [],
|
||||
enableSyncByDefault: false,
|
||||
webWorkerExtensionHostIframeSrc: document.getElementById('vscode-extension-host-iframe-src')?.getAttribute('data-settings') as string,
|
||||
const route = parseGitHubUrl(window.location.href);
|
||||
const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = {
|
||||
folderUri: URI.from({ scheme: "github1s", path: '/', authority: `${route.owner}+${route.repo}+${route.branch}` }),
|
||||
staticExtensions: [],
|
||||
enableSyncByDefault: false,
|
||||
webWorkerExtensionHostIframeSrc: document.getElementById('vscode-extension-host-iframe-src')?.getAttribute('data-settings') as string,
|
||||
};
|
||||
|
||||
// Revive static extension locations
|
||||
|
||||
@@ -4,28 +4,28 @@
|
||||
*/
|
||||
|
||||
interface GitHubRouteState {
|
||||
owner: string;
|
||||
repo: string;
|
||||
type: string;
|
||||
branch: string;
|
||||
path: string;
|
||||
search: string;
|
||||
hash: string;
|
||||
owner: string;
|
||||
repo: string;
|
||||
type: string;
|
||||
branch: string;
|
||||
path: string;
|
||||
search: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export const parseGitHubUrl = (url: string): GitHubRouteState => {
|
||||
const urlObj = new window.URL(url);
|
||||
const parts = urlObj.pathname.split('/').filter(Boolean);
|
||||
const hasFileType = ['tree', 'blob'].includes(parts[2]);
|
||||
const hasBranchName = hasFileType && parts[3];
|
||||
const urlObj = new window.URL(url);
|
||||
const parts = urlObj.pathname.split('/').filter(Boolean);
|
||||
const hasFileType = ['tree', 'blob'].includes(parts[2]);
|
||||
const hasBranchName = hasFileType && parts[3];
|
||||
|
||||
return {
|
||||
owner: parts[0] || 'conwnet',
|
||||
repo: parts[1] || 'github1s',
|
||||
type: (hasFileType ? parts[2] : 'tree').toLowerCase(),
|
||||
branch: hasBranchName ? parts[3] : 'HEAD',
|
||||
path: '/' + (hasBranchName ? parts.slice(4).join('/') : ''),
|
||||
search: urlObj.search || '',
|
||||
hash: urlObj.hash || ''
|
||||
};
|
||||
return {
|
||||
owner: parts[0] || 'conwnet',
|
||||
repo: parts[1] || 'github1s',
|
||||
type: (hasFileType ? parts[2] : 'tree').toLowerCase(),
|
||||
branch: hasBranchName ? parts[3] : 'HEAD',
|
||||
path: '/' + (hasBranchName ? parts.slice(4).join('/') : ''),
|
||||
search: urlObj.search || '',
|
||||
hash: urlObj.hash || ''
|
||||
};
|
||||
};
|
||||
|
||||
@@ -569,7 +569,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
ignoreOrientationForPreviousAndNextKey: true
|
||||
}));
|
||||
|
||||
// modify-by-github1s, hide home-bar-icon-badge
|
||||
// modify-by-github1s, hide home-bar-icon-badge
|
||||
// const homeBarIconBadge = document.createElement('div');
|
||||
// homeBarIconBadge.classList.add('home-bar-icon-badge');
|
||||
// this.homeBarContainer.appendChild(homeBarIconBadge);
|
||||
|
||||
@@ -229,23 +229,23 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible template values:
|
||||
*
|
||||
* {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorShort}: e.g. myFile.txt
|
||||
* {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder
|
||||
* {activeFolderMedium}: e.g. myFolder/myFileFolder
|
||||
* {activeFolderShort}: e.g. myFileFolder
|
||||
* {rootName}: e.g. myFolder1, myFolder2, myFolder3
|
||||
* {rootPath}: e.g. /Users/Development
|
||||
* {folderName}: e.g. myFolder
|
||||
* {folderPath}: e.g. /Users/Development/myFolder
|
||||
* {appName}: e.g. VS Code
|
||||
* {remoteName}: e.g. SSH
|
||||
* {dirty}: indicator
|
||||
* {separator}: conditional separator
|
||||
*/
|
||||
* Possible template values:
|
||||
*
|
||||
* {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorShort}: e.g. myFile.txt
|
||||
* {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder
|
||||
* {activeFolderMedium}: e.g. myFolder/myFileFolder
|
||||
* {activeFolderShort}: e.g. myFileFolder
|
||||
* {rootName}: e.g. myFolder1, myFolder2, myFolder3
|
||||
* {rootPath}: e.g. /Users/Development
|
||||
* {folderName}: e.g. myFolder
|
||||
* {folderPath}: e.g. /Users/Development/myFolder
|
||||
* {appName}: e.g. VS Code
|
||||
* {remoteName}: e.g. SSH
|
||||
* {dirty}: indicator
|
||||
* {separator}: conditional separator
|
||||
*/
|
||||
private doGetWindowTitle(): string {
|
||||
const editor = this.editorService.activeEditor;
|
||||
const workspace = this.contextService.getWorkspace();
|
||||
@@ -291,7 +291,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
const remoteName = this.labelService.getHostLabel(Schemas.vscodeRemote, this.environmentService.remoteAuthority);
|
||||
const separator = this.configurationService.getValue<string>('window.titleSeparator');
|
||||
const titleTemplate = this.configurationService.getValue<string>('window.title');
|
||||
const [owner, repo] = (folderName || '').split('+');
|
||||
const [owner, repo] = (folderName || '').split('+');
|
||||
|
||||
return template(titleTemplate, {
|
||||
activeEditorShort,
|
||||
|
||||
@@ -233,7 +233,7 @@ export class ExplorerView extends ViewPane {
|
||||
const currentFolderUri = workspace.folders?.[0].uri;
|
||||
const textContent = (currentFolderUri && currentFolderUri.scheme === 'github1s' && currentFolderUri.authority)
|
||||
? currentFolderUri.authority.split('+').slice(0, 2).join('/')
|
||||
: this.name;
|
||||
: this.name;
|
||||
titleElement.textContent = textContent;
|
||||
titleElement.title = title;
|
||||
titleElement.setAttribute('aria-label', nls.localize('explorerSection', "Explorer Section: {0}", this.name));
|
||||
@@ -583,9 +583,9 @@ export class ExplorerView extends ViewPane {
|
||||
// General methods
|
||||
|
||||
/**
|
||||
* Refresh the contents of the explorer to get up to date data from the disk about the file structure.
|
||||
* If the item is passed we refresh only that level of the tree, otherwise we do a full refresh.
|
||||
*/
|
||||
* Refresh the contents of the explorer to get up to date data from the disk about the file structure.
|
||||
* If the item is passed we refresh only that level of the tree, otherwise we do a full refresh.
|
||||
*/
|
||||
refresh(recursive: boolean, item?: ExplorerItem, cancelEditing: boolean = true): Promise<void> {
|
||||
if (!this.tree || !this.isBodyVisible() || (item && !this.tree.hasNode(item))) {
|
||||
// Tree node doesn't exist yet
|
||||
|
||||
@@ -213,9 +213,9 @@ export async function readAuthenticationTrustedDomains(accessor: ServicesAccesso
|
||||
|
||||
// modify by vscode
|
||||
const github1sDefaultTrustedDomains = [
|
||||
'*.github.com',
|
||||
'*.microsoft.com',
|
||||
'*.github1s.com',
|
||||
'*.github.com',
|
||||
'*.microsoft.com',
|
||||
'*.github1s.com',
|
||||
];
|
||||
|
||||
export function readStaticTrustedDomains(accessor: ServicesAccessor): IStaticTrustedDomains {
|
||||
|
||||
@@ -18,32 +18,32 @@
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .text-warning {
|
||||
color: #cca700;
|
||||
color: #cca700;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .text-error {
|
||||
color: #f48771;
|
||||
color: #f48771;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .text-success {
|
||||
color: #89d185
|
||||
color: #89d185
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .refresh-button {
|
||||
vertical-align: bottom;
|
||||
cursor: pointer;
|
||||
vertical-align: bottom;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:hover {
|
||||
color: #3794ff;
|
||||
color: #3794ff;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:hover {
|
||||
color: #3794ff;
|
||||
color: #3794ff;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:active {
|
||||
color: #094771;
|
||||
color: #094771;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content .welcomePage .row {
|
||||
|
||||
@@ -139,7 +139,7 @@ export class WelcomePageContribution implements IWorkbenchContribution {
|
||||
|
||||
private registerListeners() {
|
||||
this.editorService.onDidActiveEditorChange(() => this.doUpdateWindowUrl());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function isWelcomePageEnabled(configurationService: IConfigurationService, contextService: IWorkspaceContextService) {
|
||||
@@ -401,10 +401,12 @@ class WelcomePage extends Disposable {
|
||||
container.querySelector('.create-new-token')?.addEventListener('click', () => window?.open('https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s'));
|
||||
container.querySelector('.update-oauth-token')?.addEventListener('click', () => this.commandService.executeCommand('github1s.update-token').then(() => this.refreshGitHubTokenStatus(container)));
|
||||
container.querySelector('.clear-oauth-token')?.addEventListener('click', () => this.commandService.executeCommand('github1s.clear-token').then(() => this.refreshGitHubTokenStatus(container)));
|
||||
};
|
||||
}
|
||||
|
||||
updateElementText(element: HTMLElement, text: string | number, type?: 'SUCCESS' | 'WARNING' | 'ERROR') {
|
||||
if (!element) return;
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
element.innerText = `${text}`;
|
||||
element.classList.remove('text-warning', 'text-error', 'text-success');
|
||||
if (type === 'SUCCESS') {
|
||||
@@ -417,7 +419,7 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
getGitHubTokenStatus() {
|
||||
return this.commandService.executeCommand('github1s.validate-token', true);
|
||||
return this.commandService.executeCommand('github1s.validate-token', true);
|
||||
}
|
||||
|
||||
refreshGitHubTokenStatus(container: HTMLElement) {
|
||||
@@ -445,15 +447,19 @@ class WelcomePage extends Disposable {
|
||||
}
|
||||
|
||||
const textType = (value: number) => {
|
||||
if (value <= 0) return 'ERROR';
|
||||
if (value > 99) return 'SUCCESS';
|
||||
return 'WARNING';
|
||||
}
|
||||
if (value <= 0) {
|
||||
return 'ERROR';
|
||||
}
|
||||
if (value > 99) {
|
||||
return 'SUCCESS';
|
||||
}
|
||||
return 'WARNING';
|
||||
};
|
||||
this.updateElementText(limitElement, tokenStatus.limit, textType(+tokenStatus.limit));
|
||||
this.updateElementText(remainingElement, tokenStatus.remaining, textType(+tokenStatus.remaining));
|
||||
this.updateElementText(resetElement, tokenStatus.reset);
|
||||
this.updateElementText(timerElement, Math.max(tokenStatus.reset - Math.ceil(Date.now() / 1000), 0));
|
||||
|
||||
|
||||
if (!tokenStatus.token) {
|
||||
this.updateElementText(statusElement, 'Unauthorized', 'WARNING');
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,7 @@ const colorThemeSettingEnumDescriptions: string[] = [];
|
||||
const colorThemeSettingSchema: IConfigurationPropertySchema = {
|
||||
type: 'string',
|
||||
description: nls.localize('colorTheme', "Specifies the color theme used in the workbench."),
|
||||
// modify-by-github1s, default dark theme
|
||||
// modify-by-github1s, default dark theme
|
||||
default: DEFAULT_THEME_DARK_SETTING_VALUE,
|
||||
enum: colorThemeSettingEnum,
|
||||
enumDescriptions: colorThemeSettingEnumDescriptions,
|
||||
|
||||
Reference in New Issue
Block a user