2018-11-10 16:39:01 +00:00
|
|
|
import { statSync } from 'fs';
|
|
|
|
import { basename, parse, sep } from 'path';
|
2018-11-07 02:53:18 +00:00
|
|
|
import {
|
|
|
|
debug,
|
|
|
|
Disposable,
|
|
|
|
env,
|
|
|
|
window,
|
|
|
|
workspace
|
2018-11-13 02:40:24 +00:00
|
|
|
} from 'vscode'; // tslint:disable-line
|
2018-12-01 04:18:35 +00:00
|
|
|
import * as vsls from 'vsls/vscode';
|
2018-11-13 02:40:24 +00:00
|
|
|
const lang = require('../data/languages.json'); // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
const knownExtentions: { [key: string]: { image: string } } = lang.knownExtentions;
|
|
|
|
const knownLanguages: string[] = lang.knownLanguages;
|
|
|
|
|
2018-11-10 16:39:01 +00:00
|
|
|
const empty = '\u200b\u200b';
|
|
|
|
const sizes = [' bytes', 'kb', 'mb', 'gb', 'tb'];
|
|
|
|
|
|
|
|
interface State {
|
2018-11-07 02:53:18 +00:00
|
|
|
details?: string;
|
|
|
|
state?: string;
|
|
|
|
startTimestamp?: number | null;
|
|
|
|
largeImageKey?: string;
|
|
|
|
largeImageText?: string;
|
|
|
|
smallImageKey?: string;
|
|
|
|
smallImageText?: string;
|
2018-12-01 04:18:35 +00:00
|
|
|
partyId?: string;
|
|
|
|
partySize?: number;
|
|
|
|
partyMax?: number;
|
|
|
|
matchSecret?: string;
|
|
|
|
joinSecret?: string;
|
|
|
|
spectateSecret?: string;
|
2018-11-07 02:53:18 +00:00
|
|
|
instance?: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface FileDetail {
|
|
|
|
size?: string;
|
|
|
|
totalLines?: string;
|
|
|
|
currentLine?: string;
|
|
|
|
currentColumn?: string;
|
|
|
|
}
|
|
|
|
|
2018-11-10 16:39:01 +00:00
|
|
|
export default class Activity implements Disposable {
|
2018-11-13 02:40:24 +00:00
|
|
|
private _state: State | null = null; // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
|
2018-11-13 02:40:24 +00:00
|
|
|
private readonly _config = workspace.getConfiguration('discord'); // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
|
2018-11-13 02:40:24 +00:00
|
|
|
private _lastKnownFile: string = ''; // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
|
|
|
|
public get state() {
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public generate(workspaceElapsedTime: boolean = false) {
|
|
|
|
let largeImageKey: any = 'vscode-big';
|
|
|
|
if (window.activeTextEditor) {
|
|
|
|
if (window.activeTextEditor.document.fileName === this._lastKnownFile) {
|
|
|
|
return this._state = {
|
|
|
|
...this._state,
|
|
|
|
details: this._generateDetails('detailsDebugging', 'detailsEditing', 'detailsIdle', this._state!.largeImageKey),
|
2018-11-10 16:39:01 +00:00
|
|
|
smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode',
|
|
|
|
state: this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', this._state!.largeImageKey)
|
2018-11-07 02:53:18 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
this._lastKnownFile = window.activeTextEditor.document.fileName;
|
|
|
|
const filename = basename(window.activeTextEditor.document.fileName);
|
|
|
|
largeImageKey = knownExtentions[Object.keys(knownExtentions).find(key => {
|
|
|
|
if (key.startsWith('.') && filename.endsWith(key)) return true;
|
|
|
|
const match = key.match(/^\/(.*)\/([mgiy]+)$/);
|
|
|
|
if (!match) return false;
|
|
|
|
const regex = new RegExp(match[1], match[2]);
|
|
|
|
return regex.test(filename);
|
2018-11-10 16:39:01 +00:00
|
|
|
})!] || (knownLanguages.includes(window.activeTextEditor.document.languageId) ? window.activeTextEditor.document.languageId : null);
|
2018-11-07 02:53:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let previousTimestamp = null;
|
2018-12-01 16:49:26 +00:00
|
|
|
if (this._state && this._state.startTimestamp) previousTimestamp = this._state.startTimestamp;
|
2018-11-07 02:53:18 +00:00
|
|
|
|
|
|
|
this._state = {
|
2018-12-01 04:18:35 +00:00
|
|
|
...this._state,
|
2018-11-07 02:53:18 +00:00
|
|
|
details: this._generateDetails('detailsDebugging', 'detailsEditing', 'detailsIdle', largeImageKey),
|
|
|
|
startTimestamp: window.activeTextEditor && previousTimestamp && workspaceElapsedTime ? previousTimestamp : window.activeTextEditor ? new Date().getTime() : null,
|
2018-11-10 16:39:01 +00:00
|
|
|
state: this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', largeImageKey),
|
2018-11-07 02:53:18 +00:00
|
|
|
largeImageKey: largeImageKey ? largeImageKey.image || largeImageKey : 'txt',
|
|
|
|
largeImageText: window.activeTextEditor
|
2018-11-08 05:31:29 +00:00
|
|
|
? this._config.get<string>('largeImage')!
|
|
|
|
.replace('{lang}', largeImageKey ? largeImageKey.image || largeImageKey : 'txt')
|
|
|
|
.replace('{Lang}', largeImageKey ? (largeImageKey.image || largeImageKey).toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase()) : 'Txt')
|
|
|
|
.replace('{LANG}', largeImageKey ? (largeImageKey.image || largeImageKey).toUpperCase() : 'TXT')
|
2018-11-07 02:53:18 +00:00
|
|
|
|| window.activeTextEditor.document.languageId.padEnd(2, '\u200b')
|
|
|
|
: this._config.get<string>('largeImageIdle'),
|
|
|
|
smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode',
|
2018-12-01 04:18:35 +00:00
|
|
|
smallImageText: this._config.get<string>('smallImage')!.replace('{appname}', env.appName)
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async allowSpectate() {
|
|
|
|
const liveshare = await vsls.getApi();
|
|
|
|
if (!liveshare) return;
|
2018-12-01 16:49:26 +00:00
|
|
|
const join = await liveshare.share({ suppressNotification: true, access: vsls.Access.ReadOnly });
|
2018-12-01 04:18:35 +00:00
|
|
|
this._state = {
|
|
|
|
...this._state,
|
|
|
|
spectateSecret: join ? Buffer.from(join.toString()).toString('base64') : undefined,
|
|
|
|
instance: true
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async disableSpectate() {
|
|
|
|
const liveshare = await vsls.getApi();
|
|
|
|
if (!liveshare) return;
|
|
|
|
await liveshare.end();
|
|
|
|
this._state = {
|
|
|
|
...this._state,
|
|
|
|
spectateSecret: undefined,
|
|
|
|
instance: false
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async allowJoinRequests() {
|
|
|
|
const liveshare = await vsls.getApi();
|
|
|
|
if (!liveshare) return;
|
2018-12-01 16:49:26 +00:00
|
|
|
const join = await liveshare.share({ suppressNotification: true });
|
2018-12-01 04:18:35 +00:00
|
|
|
this._state = {
|
2018-12-01 16:49:26 +00:00
|
|
|
...this._state,
|
2018-12-01 04:18:35 +00:00
|
|
|
partyId: join ? join.query : undefined,
|
|
|
|
partySize: 1,
|
|
|
|
partyMax: 5,
|
|
|
|
joinSecret: join ? Buffer.from(join.toString()).toString('base64') : undefined,
|
|
|
|
instance: true
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async disableJoinRequests() {
|
|
|
|
const liveshare = await vsls.getApi();
|
|
|
|
if (!liveshare) return;
|
|
|
|
await liveshare.end();
|
|
|
|
this._state = {
|
|
|
|
...this._state,
|
|
|
|
partyId: undefined,
|
|
|
|
partySize: undefined,
|
|
|
|
partyMax: undefined,
|
|
|
|
joinSecret: undefined,
|
2018-11-07 02:53:18 +00:00
|
|
|
instance: false
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
2018-12-01 04:18:35 +00:00
|
|
|
public changePartyId(id?: string) {
|
|
|
|
if (!this._state) return;
|
|
|
|
this._state = {
|
2018-12-01 16:49:26 +00:00
|
|
|
...this._state,
|
2018-12-01 04:18:35 +00:00
|
|
|
partyId: id,
|
2018-12-01 16:49:26 +00:00
|
|
|
partySize: this._state.partySize ? this._state.partySize + 1 : 1,
|
2018-12-01 04:18:35 +00:00
|
|
|
partyMax: id ? 5 : undefined
|
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
2018-12-01 16:46:58 +00:00
|
|
|
public increasePartySize(size?: number) {
|
|
|
|
if (!this._state) return;
|
2018-12-01 04:18:35 +00:00
|
|
|
if (this.state && this._state.partySize === 5) return;
|
|
|
|
this._state = {
|
|
|
|
...this._state,
|
2018-12-01 16:46:58 +00:00
|
|
|
partySize: this._state.partySize ? this._state.partySize + 1 : size
|
2018-12-01 04:18:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
2018-12-01 16:46:58 +00:00
|
|
|
public decreasePartySize(size?: number) {
|
|
|
|
if (!this._state) return;
|
2018-12-01 04:18:35 +00:00
|
|
|
if (this.state && this._state.partySize === 1) return;
|
|
|
|
this._state = {
|
|
|
|
...this._state,
|
2018-12-01 16:46:58 +00:00
|
|
|
partySize: this._state.partySize ? this._state.partySize - 1 : size
|
2018-12-01 04:18:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return this._state;
|
|
|
|
}
|
|
|
|
|
2018-11-10 16:39:01 +00:00
|
|
|
public dispose() {
|
|
|
|
this._state = null;
|
|
|
|
this._lastKnownFile = '';
|
|
|
|
}
|
|
|
|
|
2018-11-07 02:53:18 +00:00
|
|
|
private _generateDetails(debugging: string, editing: string, idling: string, largeImageKey: any) {
|
2018-11-10 16:39:01 +00:00
|
|
|
let raw: string = this._config.get<string>(idling)!.replace('{null}', empty);
|
2018-11-07 02:53:18 +00:00
|
|
|
let filename = null;
|
|
|
|
let dirname = null;
|
|
|
|
let checkState = false;
|
|
|
|
let workspaceFolder = null;
|
|
|
|
let fullDirname = null;
|
|
|
|
if (window.activeTextEditor) {
|
|
|
|
filename = basename(window.activeTextEditor.document.fileName);
|
|
|
|
|
|
|
|
const { dir } = parse(window.activeTextEditor.document.fileName);
|
|
|
|
const split = dir.split(sep);
|
|
|
|
dirname = split[split.length - 1];
|
|
|
|
|
|
|
|
checkState = Boolean(workspace.getWorkspaceFolder(window.activeTextEditor.document.uri));
|
|
|
|
|
|
|
|
workspaceFolder = checkState ? workspace.getWorkspaceFolder(window.activeTextEditor.document.uri) : null;
|
|
|
|
|
|
|
|
if (workspaceFolder) {
|
|
|
|
const { name } = workspaceFolder;
|
|
|
|
const relativePath = workspace.asRelativePath(window.activeTextEditor.document.fileName).split(sep);
|
|
|
|
relativePath.splice(-1, 1);
|
|
|
|
fullDirname = `${name}${sep}${relativePath.join(sep)}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debug.activeDebugSession) {
|
2018-11-10 16:39:01 +00:00
|
|
|
raw = this._config.get<string>(debugging)!;
|
2018-11-07 02:53:18 +00:00
|
|
|
} else {
|
2018-11-10 16:39:01 +00:00
|
|
|
raw = this._config.get<string>(editing)!;
|
2018-11-07 02:53:18 +00:00
|
|
|
}
|
2018-11-10 16:39:01 +00:00
|
|
|
|
2018-11-07 02:53:18 +00:00
|
|
|
const { totalLines, size, currentLine, currentColumn } = this._generateFileDetails(raw);
|
|
|
|
raw = raw!
|
|
|
|
.replace('{null}', empty)
|
|
|
|
.replace('{filename}', filename)
|
|
|
|
.replace('{dirname}', dirname)
|
|
|
|
.replace('{fulldirname}', fullDirname!)
|
|
|
|
.replace('{workspace}', checkState && workspaceFolder ? workspaceFolder.name : this._config.get<string>('lowerDetailsNotFound')!.replace('{null}', empty))
|
|
|
|
.replace('{lang}', largeImageKey ? largeImageKey.image || largeImageKey : 'txt')
|
|
|
|
.replace('{Lang}', largeImageKey ? (largeImageKey.image || largeImageKey).toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase()) : 'Txt')
|
|
|
|
.replace('{LANG}', largeImageKey ? (largeImageKey.image || largeImageKey).toUpperCase() : 'TXT');
|
2018-11-08 05:31:29 +00:00
|
|
|
if (totalLines) raw = raw!.replace('{totallines}', totalLines);
|
|
|
|
if (size) raw = raw!.replace('{filesize}', size);
|
2018-11-07 02:53:18 +00:00
|
|
|
if (currentLine) raw = raw!.replace('{currentline}', currentLine);
|
|
|
|
if (currentColumn) raw = raw!.replace('{currentcolumn}', currentColumn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return raw;
|
|
|
|
}
|
|
|
|
|
|
|
|
private _generateFileDetails(str?: string) {
|
|
|
|
const fileDetail: FileDetail = {};
|
|
|
|
if (!str) return fileDetail;
|
|
|
|
|
|
|
|
if (window.activeTextEditor) {
|
|
|
|
if (str.includes('{totallines}')) {
|
|
|
|
fileDetail.totalLines = window.activeTextEditor.document.lineCount.toLocaleString();
|
|
|
|
}
|
2018-11-10 16:39:01 +00:00
|
|
|
|
2018-11-07 02:53:18 +00:00
|
|
|
if (str.includes('{currentline}')) {
|
2018-12-01 04:25:48 +00:00
|
|
|
fileDetail.currentLine = (window.activeTextEditor.selection.active.line + 1).toLocaleString(); // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
}
|
2018-11-10 16:39:01 +00:00
|
|
|
|
2018-11-07 02:53:18 +00:00
|
|
|
if (str.includes('{currentcolumn}')) {
|
2018-12-01 04:25:48 +00:00
|
|
|
fileDetail.currentColumn = (window.activeTextEditor.selection.active.character + 1).toLocaleString(); // tslint:disable-line
|
2018-11-07 02:53:18 +00:00
|
|
|
}
|
2018-11-10 16:39:01 +00:00
|
|
|
|
2018-11-07 02:53:18 +00:00
|
|
|
if (str.includes('{filesize}')) {
|
|
|
|
let currentDivision = 0;
|
|
|
|
let { size } = statSync(window.activeTextEditor.document.fileName);
|
|
|
|
const originalSize = size;
|
|
|
|
if (originalSize > 1000) {
|
|
|
|
size /= 1000;
|
|
|
|
currentDivision++;
|
|
|
|
while (size > 1000) {
|
|
|
|
currentDivision++;
|
|
|
|
size /= 1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fileDetail.size = `${originalSize > 1000 ? size.toFixed(2) : size}${sizes[currentDivision]}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-10 16:39:01 +00:00
|
|
|
return fileDetail;
|
2018-11-07 02:53:18 +00:00
|
|
|
}
|
|
|
|
}
|