2021-02-10 03:24:42 +00:00
|
|
|
const { Client } = require('discord-rpc'); // eslint-disable-line
|
2021-04-14 12:56:15 +00:00
|
|
|
import { commands, ExtensionContext, StatusBarAlignment, StatusBarItem, window, workspace, debug } from 'vscode';
|
2021-02-10 15:54:44 +00:00
|
|
|
import throttle from 'lodash-es/throttle';
|
2017-11-23 13:06:21 +00:00
|
|
|
|
2021-02-10 15:54:44 +00:00
|
|
|
import { activity } from './activity';
|
2021-02-10 03:24:42 +00:00
|
|
|
import { CLIENT_ID, CONFIG_KEYS } from './constants';
|
|
|
|
import { log, LogLevel } from './logger';
|
2021-04-14 12:56:15 +00:00
|
|
|
import { getConfig, getGit } from './util';
|
2019-08-03 12:16:17 +00:00
|
|
|
|
2018-11-10 16:39:01 +00:00
|
|
|
const statusBarIcon: StatusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
2018-11-20 04:26:48 +00:00
|
|
|
statusBarIcon.text = '$(pulse) Connecting to Discord...';
|
2017-11-23 21:14:16 +00:00
|
|
|
|
2021-02-16 20:49:53 +00:00
|
|
|
let rpc = new Client({ transport: 'ipc' });
|
2021-02-10 03:24:42 +00:00
|
|
|
const config = getConfig();
|
|
|
|
|
2021-02-10 15:54:44 +00:00
|
|
|
let state = {};
|
2021-04-10 13:17:11 +00:00
|
|
|
let idle: NodeJS.Timeout | undefined;
|
2021-02-10 19:14:27 +00:00
|
|
|
let listeners: { dispose(): any }[] = [];
|
|
|
|
|
|
|
|
export function cleanUp() {
|
|
|
|
listeners.forEach((listener) => listener.dispose());
|
|
|
|
listeners = [];
|
|
|
|
}
|
2021-02-10 15:54:44 +00:00
|
|
|
|
2021-02-10 03:24:42 +00:00
|
|
|
async function sendActivity() {
|
2021-02-10 15:54:44 +00:00
|
|
|
state = {
|
|
|
|
...(await activity(state)),
|
|
|
|
};
|
|
|
|
rpc.setActivity(state);
|
2021-02-10 03:24:42 +00:00
|
|
|
}
|
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
async function login() {
|
2021-06-23 11:05:42 +00:00
|
|
|
log(LogLevel.Info, 'Creating discord-rpc client');
|
2021-02-16 20:49:53 +00:00
|
|
|
rpc = new Client({ transport: 'ipc' });
|
|
|
|
|
2021-06-23 11:05:42 +00:00
|
|
|
rpc.on('ready', () => {
|
2021-02-10 03:24:42 +00:00
|
|
|
log(LogLevel.Info, 'Successfully connected to Discord');
|
2021-02-16 20:49:53 +00:00
|
|
|
cleanUp();
|
2021-02-10 03:24:42 +00:00
|
|
|
|
|
|
|
statusBarIcon.text = '$(globe) Connected to Discord';
|
|
|
|
statusBarIcon.tooltip = 'Connected to Discord';
|
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
void sendActivity();
|
2021-02-10 03:24:42 +00:00
|
|
|
const onChangeActiveTextEditor = window.onDidChangeActiveTextEditor(() => sendActivity());
|
2021-06-23 11:05:42 +00:00
|
|
|
const onChangeTextDocument = workspace.onDidChangeTextDocument(throttle(() => sendActivity(), 2000));
|
2021-02-10 03:24:42 +00:00
|
|
|
const onStartDebugSession = debug.onDidStartDebugSession(() => sendActivity());
|
|
|
|
const onTerminateDebugSession = debug.onDidTerminateDebugSession(() => sendActivity());
|
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
listeners.push(onChangeActiveTextEditor, onChangeTextDocument, onStartDebugSession, onTerminateDebugSession);
|
2021-02-10 03:24:42 +00:00
|
|
|
});
|
|
|
|
|
2021-06-23 11:05:42 +00:00
|
|
|
rpc.on('disconnected', async () => {
|
2021-02-16 20:49:53 +00:00
|
|
|
cleanUp();
|
|
|
|
await rpc.destroy();
|
|
|
|
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
|
|
|
statusBarIcon.command = 'discord.reconnect';
|
|
|
|
});
|
|
|
|
|
2021-02-10 03:24:42 +00:00
|
|
|
try {
|
|
|
|
await rpc.login({ clientId: CLIENT_ID });
|
|
|
|
} catch (error) {
|
|
|
|
log(LogLevel.Error, `Encountered following error while trying to login:\n${error as string}`);
|
2021-02-10 19:14:27 +00:00
|
|
|
cleanUp();
|
|
|
|
await rpc.destroy();
|
2021-02-10 03:24:42 +00:00
|
|
|
if (!config[CONFIG_KEYS.SuppressNotifications]) {
|
2021-06-23 11:05:42 +00:00
|
|
|
// @ts-ignore
|
2021-02-10 03:24:42 +00:00
|
|
|
if (error?.message?.includes('ENOENT')) void window.showErrorMessage('No Discord client detected');
|
|
|
|
else void window.showErrorMessage(`Couldn't connect to Discord via RPC: ${error as string}`);
|
|
|
|
}
|
2021-02-10 19:14:27 +00:00
|
|
|
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
|
|
|
statusBarIcon.command = 'discord.reconnect';
|
2021-02-10 03:24:42 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-07 02:53:18 +00:00
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
export async function activate(context: ExtensionContext) {
|
2021-02-10 03:24:42 +00:00
|
|
|
log(LogLevel.Info, 'Discord Presence activated');
|
2018-11-07 02:53:18 +00:00
|
|
|
|
2019-04-19 11:00:44 +00:00
|
|
|
let isWorkspaceExcluded = false;
|
2021-02-10 03:24:42 +00:00
|
|
|
for (const pattern of config[CONFIG_KEYS.WorkspaceExcludePatterns]) {
|
|
|
|
const regex = new RegExp(pattern);
|
|
|
|
const folders = workspace.workspaceFolders;
|
|
|
|
if (!folders) break;
|
|
|
|
if (folders.some((folder) => regex.test(folder.uri.fsPath))) {
|
|
|
|
isWorkspaceExcluded = true;
|
|
|
|
break;
|
2019-04-19 11:00:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
const enable = async (update = true) => {
|
|
|
|
if (update) {
|
2021-06-23 11:05:42 +00:00
|
|
|
try {
|
|
|
|
await config.update('enabled', true);
|
|
|
|
} catch {}
|
2021-02-10 19:14:27 +00:00
|
|
|
}
|
2021-06-23 11:05:42 +00:00
|
|
|
log(LogLevel.Info, 'Enable: Cleaning up old listeners');
|
2021-02-10 19:14:27 +00:00
|
|
|
cleanUp();
|
2021-02-10 03:24:42 +00:00
|
|
|
statusBarIcon.text = '$(pulse) Connecting to Discord...';
|
|
|
|
statusBarIcon.show();
|
2021-06-23 11:05:42 +00:00
|
|
|
log(LogLevel.Info, 'Enable: Attempting to recreate login');
|
|
|
|
void login();
|
2021-02-10 19:14:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const disable = async (update = true) => {
|
|
|
|
if (update) {
|
2021-06-23 11:05:42 +00:00
|
|
|
try {
|
|
|
|
await config.update('enabled', false);
|
|
|
|
} catch {}
|
2021-02-10 19:14:27 +00:00
|
|
|
}
|
2021-06-23 11:05:42 +00:00
|
|
|
log(LogLevel.Info, 'Disable: Cleaning up old listeners');
|
2021-02-10 19:14:27 +00:00
|
|
|
cleanUp();
|
2021-06-23 11:05:42 +00:00
|
|
|
void rpc?.destroy();
|
|
|
|
log(LogLevel.Info, 'Disable: Destroyed the rpc instance');
|
2021-02-10 19:14:27 +00:00
|
|
|
statusBarIcon.hide();
|
|
|
|
};
|
|
|
|
|
|
|
|
const enabler = commands.registerCommand('discord.enable', async () => {
|
2021-06-23 11:05:42 +00:00
|
|
|
await disable();
|
2021-02-10 19:14:27 +00:00
|
|
|
await enable();
|
2021-06-23 11:05:42 +00:00
|
|
|
await window.showInformationMessage('Enabled Discord Presence for this workspace');
|
2017-11-24 03:42:51 +00:00
|
|
|
});
|
2021-02-10 03:24:42 +00:00
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
const disabler = commands.registerCommand('discord.disable', async () => {
|
|
|
|
await disable();
|
2021-06-23 11:05:42 +00:00
|
|
|
await window.showInformationMessage('Disabled Discord Presence for this workspace');
|
2017-11-23 23:53:16 +00:00
|
|
|
});
|
2021-02-10 03:24:42 +00:00
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
const reconnecter = commands.registerCommand('discord.reconnect', async () => {
|
|
|
|
await disable(false);
|
|
|
|
await enable(false);
|
2019-08-03 12:16:17 +00:00
|
|
|
});
|
2021-02-10 03:24:42 +00:00
|
|
|
|
2021-02-10 19:14:27 +00:00
|
|
|
const disconnect = commands.registerCommand('discord.disconnect', async () => {
|
|
|
|
await disable(false);
|
|
|
|
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
|
|
|
statusBarIcon.command = 'discord.reconnect';
|
2021-06-23 11:05:42 +00:00
|
|
|
statusBarIcon.show();
|
2018-01-05 02:17:18 +00:00
|
|
|
});
|
2021-02-10 03:24:42 +00:00
|
|
|
|
|
|
|
context.subscriptions.push(enabler, disabler, reconnecter, disconnect);
|
|
|
|
|
|
|
|
if (!isWorkspaceExcluded && config[CONFIG_KEYS.Enabled]) {
|
2019-11-02 16:55:43 +00:00
|
|
|
statusBarIcon.show();
|
2021-02-10 19:14:27 +00:00
|
|
|
await login();
|
2019-11-02 16:55:43 +00:00
|
|
|
}
|
2020-07-16 16:25:05 +00:00
|
|
|
|
2021-04-10 13:17:11 +00:00
|
|
|
window.onDidChangeWindowState(async (windowState) => {
|
|
|
|
if (config[CONFIG_KEYS.IdleTimeout] !== 0) {
|
|
|
|
if (windowState.focused) {
|
|
|
|
if (idle) {
|
|
|
|
clearTimeout(idle);
|
|
|
|
}
|
|
|
|
|
|
|
|
await sendActivity();
|
|
|
|
} else {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
|
|
idle = setTimeout(async () => {
|
|
|
|
state = {};
|
|
|
|
await rpc.clearActivity();
|
|
|
|
}, config[CONFIG_KEYS.IdleTimeout] * 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-04-14 12:56:15 +00:00
|
|
|
await getGit();
|
2017-11-23 13:06:21 +00:00
|
|
|
}
|
|
|
|
|
2021-06-23 11:05:42 +00:00
|
|
|
export function deactivate() {
|
2021-02-10 19:14:27 +00:00
|
|
|
cleanUp();
|
2021-06-23 11:05:42 +00:00
|
|
|
void rpc.destroy();
|
2018-04-30 09:28:20 +00:00
|
|
|
}
|