diff --git a/package.json b/package.json index 2615ac4..2d23d63 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "scripts": { "prebuild": "yarn lint", "build": "webpack --mode production", - "lint": "eslint src --ext .ts" + "lint": "eslint src --ext .ts", + "lint:fix": "eslint src --ext .ts --fix" }, "activationEvents": [ "*" @@ -196,6 +197,9 @@ "clean-webpack-plugin": "^3.0.0", "eslint": "^6.4.0", "eslint-config-marine": "^5.0.0", + "eslint-config-prettier": "^6.3.0", + "eslint-plugin-prettier": "^3.1.1", + "prettier": "^1.18.2", "terser-webpack-plugin": "^2.1.0", "ts-loader": "^6.1.2", "typescript": "^3.6.3", @@ -206,6 +210,6 @@ "vscode": "^1.38.0" }, "eslintConfig": { - "extends": "marine/node" + "extends": "marine/prettier/node" } } diff --git a/src/client/RPCClient.ts b/src/client/RPCClient.ts index 928d66a..f5fbf6c 100644 --- a/src/client/RPCClient.ts +++ b/src/client/RPCClient.ts @@ -30,6 +30,7 @@ export default class RPCClient implements Disposable { public async setActivity(workspaceElapsedTime = false) { if (!this._rpc) return; const activity = await this._activity.generate(workspaceElapsedTime); + if (!activity) return; Logger.log('Sending activity to Discord.'); this._rpc.setActivity(activity); } @@ -70,7 +71,7 @@ export default class RPCClient implements Disposable { this.statusBarIcon.tooltip = 'Connected to Discord'; // @ts-ignore - setTimeout(() => this.statusBarIcon.text = '$(globe)', 5000); + setTimeout(() => (this.statusBarIcon.text = '$(globe)'), 5000); if (activityTimer) clearInterval(activityTimer); await this.setActivity(); @@ -101,13 +102,18 @@ export default class RPCClient implements Disposable { // Same here, this is a real nasty race condition that happens inside the discord-rpc module currently // To circumvent this we need to timeout sending the subscribe events to the discord client setTimeout(() => { - this._rpc.subscribe('ACTIVITY_JOIN_REQUEST', async ({ user }: { user: { username: string; discriminator: string } }) => - window.showInformationMessage(`${user.username}#${user.discriminator} wants to join your session`, { title: 'Accept' }, { title: 'Decline' }) - // eslint-disable-next-line - .then(async (val: { title: string } | undefined) => { - if (val && val.title === 'Accept') await this._rpc.sendJoinInvite(user); // eslint-disable-line - else await this._rpc.closeJoinRequest(user); - })); + this._rpc.subscribe( + 'ACTIVITY_JOIN_REQUEST', + async ({ user }: { user: { username: string; discriminator: string } }) => { + const val = await window.showInformationMessage( + `${user.username}#${user.discriminator} wants to join your session`, + { title: 'Accept' }, + { title: 'Decline' }, + ); + if (val && val.title === 'Accept') await this._rpc.sendJoinInvite(user); + else await this._rpc.closeJoinRequest(user); + }, + ); }, 1000); setTimeout(() => { this._rpc.subscribe('ACTIVITY_JOIN', async ({ secret }: { secret: string }) => { diff --git a/src/constants.ts b/src/constants.ts index 08233b4..f59efd4 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,5 +4,5 @@ export const VSLS_EXTENSION_ID = 'ms-vsliveshare.vsliveshare'; export const LIVE_SHARE_COMMANDS = { START: 'liveshare.start', END: 'liveshare.end', - JOIN: 'liveshare.join' + JOIN: 'liveshare.join', }; diff --git a/src/extension.ts b/src/extension.ts index 64a0d33..d4e51c5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -96,7 +96,16 @@ export async function activate(context: ExtensionContext) { await rpc.disableJoinRequests(); }); - context.subscriptions.push(enabler, disabler, reconnecter, disconnect, allowSpectate, disableSpectate, allowJoinRequests, disableJoinRequests); + context.subscriptions.push( + enabler, + disabler, + reconnecter, + disconnect, + allowSpectate, + disableSpectate, + allowJoinRequests, + disableJoinRequests, + ); } export async function deactivate() { diff --git a/src/structures/Activity.ts b/src/structures/Activity.ts index b6a6808..c792321 100644 --- a/src/structures/Activity.ts +++ b/src/structures/Activity.ts @@ -48,23 +48,43 @@ export default class Activity implements Disposable { let largeImageKey: any = 'vscode-big'; if (window.activeTextEditor) { if (window.activeTextEditor.document.languageId === 'Log') return this._state; - if (window.activeTextEditor.document.fileName === this._lastKnownFile) { - return this._state = { + if (this._state && window.activeTextEditor.document.fileName === this._lastKnownFile) { + return (this._state = { ...this._state, - details: await this._generateDetails('detailsDebugging', 'detailsEditing', 'detailsIdle', this._state!.largeImageKey), - smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode', - state: await this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', this._state!.largeImageKey) - }; + details: await this._generateDetails( + 'detailsDebugging', + 'detailsEditing', + 'detailsIdle', + this._state.largeImageKey, + ), + smallImageKey: debug.activeDebugSession + ? 'debug' + : env.appName.includes('Insiders') + ? 'vscode-insiders' + : 'vscode', + state: await this._generateDetails( + 'lowerDetailsDebugging', + 'lowerDetailsEditing', + 'lowerDetailsIdle', + this._state.largeImageKey, + ), + }); } this._lastKnownFile = window.activeTextEditor.document.fileName; const filename = basename(window.activeTextEditor.document.fileName); - largeImageKey = knownExtentions[Object.keys(knownExtentions).find(key => { - if (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); + largeImageKey = + knownExtentions[ + Object.keys(knownExtentions).find(key => { + if (filename.endsWith(key)) return true; + const match = /^\/(.*)\/([mgiy]+)$/.exec(key); + 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; @@ -73,18 +93,38 @@ export default class Activity implements Disposable { this._state = { ...this._state, details: await this._generateDetails('detailsDebugging', 'detailsEditing', 'detailsIdle', largeImageKey), - startTimestamp: window.activeTextEditor && previousTimestamp && workspaceElapsedTime ? previousTimestamp : window.activeTextEditor ? new Date().getTime() : null, - state: await this._generateDetails('lowerDetailsDebugging', 'lowerDetailsEditing', 'lowerDetailsIdle', largeImageKey), + startTimestamp: + window.activeTextEditor && previousTimestamp && workspaceElapsedTime + ? previousTimestamp + : window.activeTextEditor + ? new Date().getTime() + : null, + state: await this._generateDetails( + 'lowerDetailsDebugging', + 'lowerDetailsEditing', + 'lowerDetailsIdle', + largeImageKey, + ), largeImageKey: largeImageKey ? largeImageKey.image || largeImageKey : 'txt', largeImageText: window.activeTextEditor - ? this._config.get('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') || - window.activeTextEditor.document.languageId.padEnd(2, '\u200b') + ? this._config + .get('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') || + window.activeTextEditor.document.languageId.padEnd(2, '\u200b') : this._config.get('largeImageIdle'), - smallImageKey: debug.activeDebugSession ? 'debug' : env.appName.includes('Insiders') ? 'vscode-insiders' : 'vscode', - smallImageText: this._config.get('smallImage')!.replace('{appname}', env.appName) + smallImageKey: debug.activeDebugSession + ? 'debug' + : env.appName.includes('Insiders') + ? 'vscode-insiders' + : 'vscode', + smallImageText: this._config.get('smallImage')!.replace('{appname}', env.appName), }; return this._state; @@ -98,7 +138,7 @@ export default class Activity implements Disposable { this._state = { ...this._state, spectateSecret: join ? Buffer.from(join.toString()).toString('base64') : undefined, - instance: true + instance: true, }; return this._state; @@ -127,7 +167,7 @@ export default class Activity implements Disposable { partySize: 1, partyMax: 5, joinSecret: join ? Buffer.from(join.toString()).toString('base64') : undefined, - instance: true + instance: true, }; return this._state; @@ -163,7 +203,7 @@ export default class Activity implements Disposable { partyId: id, partySize: this._state.partySize ? this._state.partySize + 1 : 1, partyMax: 5, - instance: true + instance: true, }; return this._state; @@ -174,7 +214,7 @@ export default class Activity implements Disposable { if (this.state && this._state.partySize === 5) return; this._state = { ...this._state, - partySize: this._state.partySize ? this._state.partySize + 1 : size + partySize: this._state.partySize ? this._state.partySize + 1 : size, }; return this._state; @@ -185,7 +225,7 @@ export default class Activity implements Disposable { if (this.state && this._state.partySize === 1) return; this._state = { ...this._state, - partySize: this._state.partySize ? this._state.partySize - 1 : size + partySize: this._state.partySize ? this._state.partySize - 1 : size, }; return this._state; @@ -228,19 +268,29 @@ export default class Activity implements Disposable { } const { totalLines, size, currentLine, currentColumn } = await this._generateFileDetails(raw); - raw = raw! + raw = raw .replace('{null}', empty) .replace('{filename}', filename) .replace('{dirname}', dirname) .replace('{fulldirname}', fullDirname!) - .replace('{workspace}', checkState && workspaceFolder ? workspaceFolder.name : this._config.get('lowerDetailsNotFound')!.replace('{null}', empty)) + .replace( + '{workspace}', + checkState && workspaceFolder + ? workspaceFolder.name + : this._config.get('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).toLowerCase().replace(/^\w/, (c: string) => c.toUpperCase()) + : 'Txt', + ) .replace('{LANG}', largeImageKey ? (largeImageKey.image || largeImageKey).toUpperCase() : 'TXT'); - if (totalLines) raw = raw!.replace('{totallines}', totalLines); - if (size) raw = raw!.replace('{filesize}', size); - if (currentLine) raw = raw!.replace('{currentline}', currentLine); - if (currentColumn) raw = raw!.replace('{currentcolumn}', currentColumn); + if (totalLines) raw = raw.replace('{totallines}', totalLines); + if (size) raw = raw.replace('{filesize}', size); + if (currentLine) raw = raw.replace('{currentline}', currentLine); + if (currentColumn) raw = raw.replace('{currentcolumn}', currentColumn); } return raw; diff --git a/webpack.config.js b/webpack.config.js index f2018b0..0071508 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,3 @@ -'use strict'; - const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); @@ -8,18 +6,16 @@ module.exports = { entry: './src/extension.ts', output: { filename: 'extension.js', - libraryTarget: 'commonjs2' + libraryTarget: 'commonjs2', }, devtool: 'source-map', externals: { - vscode: 'commonjs vscode' + vscode: 'commonjs vscode', }, resolve: { - extensions: ['.ts', '.js', '.json'] + extensions: ['.ts', '.js', '.json'], }, - plugins: [ - new CleanWebpackPlugin() - ], + plugins: [new CleanWebpackPlugin()], optimization: { minimizer: [ new TerserPlugin({ @@ -30,16 +26,18 @@ module.exports = { ecma: 8, mangle: false, keep_classnames: true, - keep_fnames: true - } - }) - ] + keep_fnames: true, + }, + }), + ], }, module: { - rules: [{ - test: /\.ts$/, - use: 'ts-loader', - exclude: /node_modules/ - }] - } + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, }; diff --git a/yarn.lock b/yarn.lock index b711b01..2e3f662 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1156,6 +1156,20 @@ eslint-config-marine@^5.0.0: eslint-config-aqua "^7.0.1" eslint-plugin-promise "^4.2.1" +eslint-config-prettier@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.3.0.tgz#e73b48e59dc49d950843f3eb96d519e2248286a3" + integrity sha512-EWaGjlDAZRzVFveh2Jsglcere2KK5CJBhkNSa1xs3KfMUGdRiT7lG089eqPdvlzWHpAqaekubOsOMu8W8Yk71A== + dependencies: + get-stdin "^6.0.0" + +eslint-plugin-prettier@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" + integrity sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-plugin-promise@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" @@ -1359,6 +1373,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -1549,6 +1568,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -2792,6 +2816,18 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" + integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"