discord-vscode/src/structures/Activity.ts
Crawl 0195cde103
rewrite (#101)
* rewrite: initial commit

* feat: add constants for live share

* feat: add first letter uppercase

#88

* chore: remove automatic reconnects

* chore: add troubleshooting to readme
2018-11-07 03:53:18 +01:00

174 lines
6.6 KiB
TypeScript

import {
debug,
Disposable,
env,
window,
workspace
} from 'vscode';
import { basename, sep, parse } from 'path';
import { statSync } from 'fs';
const lang = require('../data/languages.json');
const knownExtentions: { [key: string]: { image: string } } = lang.knownExtentions;
const knownLanguages: string[] = lang.knownLanguages;
interface Activity {
details?: string;
state?: string;
startTimestamp?: number | null;
largeImageKey?: string;
largeImageText?: string;
smallImageKey?: string;
smallImageText?: string;
instance?: boolean;
}
interface FileDetail {
size?: string;
totalLines?: string;
currentLine?: string;
currentColumn?: string;
}
export default class Acivity implements Disposable {
private _state: Activity | null = null;
private _config = workspace.getConfiguration('discord');
private _lastKnownFile: string = '';
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),
state: this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', this._state!.largeImageKey),
smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode'
};
}
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);
})!] || (knownLanguages.includes(window.activeTextEditor.document.languageId) ? window.activeTextEditor.document.languageId : null)
}
let previousTimestamp = null;
if (this.state && this.state.startTimestamp) previousTimestamp = this.state.startTimestamp;
this._state = {
details: this._generateDetails('detailsDebugging', 'detailsEditing', 'detailsIdle', largeImageKey),
state: this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', largeImageKey),
startTimestamp: window.activeTextEditor && previousTimestamp && workspaceElapsedTime ? previousTimestamp : window.activeTextEditor ? new Date().getTime() : null,
largeImageKey: largeImageKey ? largeImageKey.image || largeImageKey : 'txt',
largeImageText: window.activeTextEditor
? this._config.get<string>('largeImage')!.replace('{lang}', largeImageKey ? largeImageKey.image || largeImageKey : 'txt').replace('{LANG}', largeImageKey ? (largeImageKey.image || largeImageKey).toUpperCase() : 'TXT')
|| window.activeTextEditor.document.languageId.padEnd(2, '\u200b')
: this._config.get<string>('largeImageIdle'),
smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode',
smallImageText: this._config.get<string>('smallImage')!.replace('{appname}', env.appName),
instance: false
};
return this._state;
}
private _generateDetails(debugging: string, editing: string, idling: string, largeImageKey: any) {
const empty = '\u200b\u200b';
let raw = this._config.get<string>(idling);
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) {
raw = this._config.get<string>(debugging);
} else {
raw = this._config.get<string>(editing);
}
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');
if (totalLines) raw = raw!.replace('{totalline}', totalLines);
if (size) raw = raw!.replace('{filsize}', size);
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();
}
if (str.includes('{currentline}')) {
fileDetail.currentLine = (window.activeTextEditor.selection.active.line + 1).toLocaleString();
}
if (str.includes('{currentcolumn}')) {
fileDetail.currentColumn = (window.activeTextEditor.selection.active.character + 1).toLocaleString();
}
if (str.includes('{filesize}')) {
const sizes = [' bytes', 'kb', 'mb', 'gb', 'tb'];
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]}`;
}
}
return fileDetail;
}
public dispose() {
this._state = null;
this._lastKnownFile = '';
}
}