mirror of
https://gitlab.com/aviortheking/code-stats-vscode.git
synced 2025-06-07 07:59:53 +00:00
183 lines
5.3 KiB
TypeScript
183 lines
5.3 KiB
TypeScript
import * as path from 'path'
|
|
import {
|
|
commands, Disposable, ExtensionContext, StatusBarAlignment, StatusBarItem,
|
|
TextDocument, TextDocumentChangeEvent, Uri,
|
|
ViewColumn, window, workspace, WorkspaceConfiguration
|
|
} from "vscode"
|
|
import { CodeStatsAPI } from "./code-stats-api"
|
|
import { ProfileProvider } from "./profile-provider"
|
|
import { Pulse } from "./pulse"
|
|
export class XpCounter {
|
|
private combinedDisposable: Disposable;
|
|
private statusBarItem: StatusBarItem;
|
|
private pulse: Pulse;
|
|
private api!: CodeStatsAPI;
|
|
private updateTimeout: any;
|
|
|
|
// wait 10s after each change in the document before sending an update
|
|
private UPDATE_DELAY = 10000;
|
|
|
|
// List of detected output languages to filter out and not send to the backend.
|
|
private filterOutLanguages: string[] = [
|
|
"arduino-output",
|
|
"code-runner-output",
|
|
"jest-snapshot",
|
|
"Diff",
|
|
"testOutput",
|
|
"Log"
|
|
]
|
|
|
|
constructor(context: ExtensionContext) {
|
|
this.pulse = new Pulse();
|
|
this.initAPI();
|
|
|
|
let subscriptions: Disposable[] = [];
|
|
|
|
this.statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
|
this.statusBarItem.command = "code-stats.profile";
|
|
|
|
subscriptions.push(workspace.registerTextDocumentContentProvider('code-stats', new ProfileProvider(context, this.api)));
|
|
|
|
subscriptions.push(commands.registerCommand("code-stats.profile", () => {
|
|
|
|
let config: WorkspaceConfiguration = workspace.getConfiguration(
|
|
"codestats"
|
|
);
|
|
|
|
if (!config) {
|
|
window.showErrorMessage('codestats.username configuration setting is missing');
|
|
return;
|
|
}
|
|
|
|
if( config.get("username") === '' ){
|
|
window.showErrorMessage('codestats.username configuration setting is missing');
|
|
return;
|
|
}
|
|
|
|
const panel = window.createWebviewPanel(
|
|
'codeStatsPanel',
|
|
'Code::Stats Profile',
|
|
ViewColumn.Two,
|
|
{
|
|
localResourceRoots: [Uri.file(path.join(context.extensionPath, 'assets'))]
|
|
}
|
|
);
|
|
|
|
workspace.openTextDocument(Uri.parse('code-stats://profile')).then((value) => {
|
|
panel.webview.html = value.getText();
|
|
});
|
|
}));
|
|
|
|
subscriptions.push(commands.registerCommand('code-stats.api-key', async () => {
|
|
// Display an input box to allow to change the API key
|
|
const response = await window.showInputBox({title: 'Enter your Code::Stats API key', placeHolder: 'xxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'})
|
|
|
|
// do nothing if nothing was entered
|
|
if (!response) {
|
|
return
|
|
}
|
|
|
|
// Fetch the configuration
|
|
const config = workspace.getConfiguration(
|
|
"codestats",
|
|
);
|
|
|
|
// Update the apiKey globally
|
|
// TODO: maybe add some sort of validation
|
|
config.update('apikey', response, true)
|
|
|
|
// Reload the API
|
|
this.initAPI()
|
|
window.showInformationMessage('API Key successfully updated!')
|
|
}))
|
|
|
|
workspace.onDidChangeTextDocument(
|
|
this.onTextDocumentChanged,
|
|
this,
|
|
subscriptions
|
|
);
|
|
workspace.onDidChangeConfiguration(this.initAPI, this, subscriptions);
|
|
this.combinedDisposable = Disposable.from(...subscriptions);
|
|
}
|
|
|
|
dispose(): void {
|
|
this.combinedDisposable.dispose();
|
|
this.statusBarItem.dispose();
|
|
}
|
|
|
|
private onTextDocumentChanged(event: TextDocumentChangeEvent): void {
|
|
this.updateXpCount(event.document, 1);
|
|
}
|
|
|
|
public updateXpCount(document: TextDocument, changeCount: number): void {
|
|
let show: boolean;
|
|
if (this.isSupportedLanguage(document.languageId)) {
|
|
this.pulse.addXP(document.languageId, changeCount);
|
|
show = true;
|
|
} else {
|
|
show = false;
|
|
}
|
|
this.updateStatusBar(show, `${this.pulse.getXP(document.languageId)}`);
|
|
|
|
// each change resets the timeout so we only send updates when there is a 10s delay in updates to the document
|
|
if (this.updateTimeout !== null) {
|
|
clearTimeout(this.updateTimeout);
|
|
}
|
|
|
|
this.updateTimeout = setTimeout(() => {
|
|
const promise = this.api.sendUpdate(this.pulse);
|
|
|
|
if (promise !== null) {
|
|
promise.then(() => {
|
|
this.updateStatusBar(
|
|
show,
|
|
`${this.pulse.getXP(document.languageId)}`
|
|
);
|
|
});
|
|
}
|
|
}, this.UPDATE_DELAY);
|
|
}
|
|
|
|
private updateStatusBar(show: boolean, changeCount: string): void {
|
|
if (!show) {
|
|
this.statusBarItem.hide();
|
|
} else {
|
|
this.statusBarItem.text = `$(pencil) C::S ${changeCount}`;
|
|
this.statusBarItem.show();
|
|
}
|
|
}
|
|
|
|
private isSupportedLanguage(language: string): boolean {
|
|
// Check if detected language is something we don't want to send to backend like the code runner output
|
|
if (this.filterOutLanguages.includes(language)) {
|
|
console.log("Filtering out " + language);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private initAPI() {
|
|
let config: WorkspaceConfiguration = workspace.getConfiguration(
|
|
"codestats"
|
|
);
|
|
if (!config) {
|
|
return;
|
|
}
|
|
|
|
const apiKey = config.get("apikey") as string;
|
|
const apiURL = config.get("apiurl") as string;
|
|
const userName = config.get("username") as string;
|
|
|
|
console.log(
|
|
`code-stats-vscode setting up:
|
|
API URL: ${apiURL}
|
|
NAME: ${userName}
|
|
KEY: ${apiKey}
|
|
`
|
|
);
|
|
|
|
if(this.api != null ) this.api.updateSettings(apiKey, apiURL, userName);
|
|
else this.api = new CodeStatsAPI(apiKey,apiURL,userName);
|
|
}
|
|
}
|