refactor: finish rewrite

This commit is contained in:
iCrawl 2021-02-10 16:54:44 +01:00
parent c7f09da1ab
commit 1ccacced7f
No known key found for this signature in database
GPG key ID: 1AB888B16355FBB2
7 changed files with 133 additions and 61 deletions

View file

@ -1,34 +1,53 @@
# Discord Presence
> Update your discord status with the newly added rich presence.
> Update your discord status with a rich presence.
<div align="center">
<p>
<a href="https://marketplace.visualstudio.com/items?itemName=icrawl.discord-vscode">
<img src="https://vsmarketplacebadge.apphb.com/version/icrawl.discord-vscode.svg" alt="VS Code Marketplace">
<img alt="Visual Studio Marketplace Version" src="https://img.shields.io/visual-studio-marketplace/v/icrawl.discord-vscode?label=Visual%20Studio%20Marketplace">
</a>
<a href="https://marketplace.visualstudio.com/items?itemName=icrawl.discord-vscode">
<img alt="Visual Studio Marketplace Downloads" src="https://img.shields.io/visual-studio-marketplace/d/icrawl.discord-vscode">
</a>
<a href="https://marketplace.visualstudio.com/items?itemName=icrawl.discord-vscode">
<img alt="Visual Studio Marketplace Rating" src="https://img.shields.io/visual-studio-marketplace/r/icrawl.discord-vscode">
</a>
<a href="https://discord.gg/cZSWqAF">
<img src="https://canary.discordapp.com/api/guilds/424963290989461514/embed.png" alt="Discord server">
</a>
</p>
<p>
<a href="https://open-vsx.org/extension/icrawl/discord-vscode">
<img alt="Open VSX Version" src="https://img.shields.io/open-vsx/v/icrawl/discord-vscode?label=OpenVSX%20Marketplace">
</a>
<a href="https://open-vsx.org/extension/icrawl/discord-vscode">
<img alt="Open VSX Downloads" src="https://img.shields.io/open-vsx/dt/icrawl/discord-vscode">
</a>
<a href="https://open-vsx.org/extension/icrawl/discord-vscode">
<img alt="Open VSX Rating" src="https://img.shields.io/open-vsx/rating/icrawl/discord-vscode">
</a>
</p>
</div>
## Features
- Shows what you are editing in VSCode with no bullsh\*t involved
- Support for over 130 of the most popular languages
- Shows what you are editing in VSCode
- Support for over 140 of the most popular languages
- Enable/Disable Rich Presence for individual workspaces (enabled by default)
- Custom string support
- Respects Discords 15sec limit when it comes to updating your status
- Stable or Insiders build detection
- Debug mode detection
- Easily manually reconnect to Discord
- VSCode Live Share support
## Troubleshooting
### Can't connect to Discord? Check those:
**Windows:** Do not run your VSCode or Discord as admin, there is no reason to and it just further complicates everything down the line.
**Linux:** Discord versions installed using `flatpak` or `snap` need modifications in order to support IPC. In order to avoid this (and as Discord itself suggests) you should download it from [discord.com](https://discord.com/download)
References:
https://github.com/flathub/com.discordapp.Discord/issues/29
https://github.com/iCrawl/discord-vscode/issues/77#issuecomment-435622205
https://github.com/iCrawl/discord-vscode/issues/85#issuecomment-417895483

42
package-lock.json generated
View file

@ -11,10 +11,12 @@
"bufferutil": "^4.0.3",
"dayjs": "^1.10.4",
"discord-rpc": "^3.1.4",
"lodash-es": "^4.17.20",
"tslib": "^2.1.0",
"utf-8-validate": "^5.0.4"
},
"devDependencies": {
"@types/lodash-es": "^4.17.4",
"@types/node": "^14.14.25",
"@types/vscode": "^1.53.0",
"@typescript-eslint/eslint-plugin": "^4.15.0",
@ -195,6 +197,21 @@
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
"dev": true
},
"node_modules/@types/lodash": {
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
"dev": true
},
"node_modules/@types/lodash-es": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.4.tgz",
"integrity": "sha512-BBz79DCJbD2CVYZH67MBeHZRX++HF+5p8Mo5MzjZi64Wac39S3diedJYHZtScbRVf4DjZyN6LzA0SB0zy+HSSQ==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -1963,6 +1980,11 @@
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"node_modules/lodash-es": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz",
"integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA=="
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -3317,6 +3339,21 @@
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
"dev": true
},
"@types/lodash": {
"version": "4.14.168",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
"dev": true
},
"@types/lodash-es": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.4.tgz",
"integrity": "sha512-BBz79DCJbD2CVYZH67MBeHZRX++HF+5p8Mo5MzjZi64Wac39S3diedJYHZtScbRVf4DjZyN6LzA0SB0zy+HSSQ==",
"dev": true,
"requires": {
"@types/lodash": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -4780,6 +4817,11 @@
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"lodash-es": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz",
"integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA=="
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",

View file

@ -2,7 +2,7 @@
"name": "discord-vscode",
"displayName": "Discord Presence",
"version": "5.0.0",
"description": "Update your discord status with the newly added rich presence.",
"description": "Update your discord status with a rich presence.",
"private": true,
"author": {
"name": "iCrawl",
@ -62,67 +62,62 @@
"default": true,
"description": "Controls if the Discord Presence should show across all workspaces"
},
"discord.details_idling": {
"discord.detailsIdling": {
"type": "string",
"default": "Idling",
"description": "Custom string for the details section of the rich presence when idling\n\t- '{empty}' will be replaced with an empty space."
},
"discord.details_editing": {
"discord.detailsEditing": {
"type": "string",
"default": "Editing {file_name}",
"description": "Custom string for the details section of the rich presence\n\t- '{empty}' will be replaced with an empty space.\n\t- '{file_name}' will be replaced with the current file name.\n\t- '{dir_name}' will get replaced with the folder name that has the current file.\n\t- '{full_dir_name}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{workspace_folder}' will be replaced with the currently accessed workspace folder, if any.\n\t- '{workspace_and_folder} will be replaced with the currently accessed workspace and workspace folder like this: 'Workspace - WorkspaceFolder'\n\t- '{current_column}' will get replaced with the current column of the current line.\n\t- '{current_line}' will get replaced with the current line number.\n\t- '{total_lines}' will get replaced with the total line number.\n\t- '{file_size}' will get replaced with the current file's size.\n\t- '{git_repo_name}' will be replaced with the active Git repository name (from the git URL)\n\t- '{git_branch}' will be replaced with the current active branch name."
},
"discord.details_debugging": {
"discord.detailsDebugging": {
"type": "string",
"default": "Debugging {file_name}",
"description": "Custom string for the details section of the rich presence when debugging\n\t- '{empty}' will be replaced with an empty space.\n\t- '{file_name}' will be replaced with the current file name.\n\t- '{dir_name}' will get replaced with the folder name that has the current file.\n\t- '{full_dir_name}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{workspace_folder}' will be replaced with the currently accessed workspace folder, if any.\n\t- '{workspace_and_folder} will be replaced with the currently accessed workspace and workspace folder like this: 'Workspace - WorkspaceFolder'\n\t- '{current_column}' will get replaced with the current column of the current line.\n\t- '{current_line}' will get replaced with the current line number.\n\t- '{total_lines}' will get replaced with the total line number.\n\t- '{file_size}' will get replaced with the current file's size.\n\t- '{git_repo_name}' will be replaced with the active Git repository name (from the git URL)\n\t- '{git_branch}' will be replaced with the current active branch name."
},
"discord.lower_details_idling": {
"discord.lowerDetailsIdling": {
"type": "string",
"default": "Idling",
"description": "Custom string for the state section of the rich presence when idling\n\t- '{empty}' will be replaced with an empty space."
},
"discord.lower_details_editing": {
"discord.lowerDetailsEditing": {
"type": "string",
"default": "Workspace: {workspace}",
"description": "Custom string for the state section of the rich presence\n\t- '{empty}' will be replaced with an empty space.\n\t- '{file_name}' will be replaced with the current file name.\n\t- '{dir_name}' will get replaced with the folder name that has the current file.\n\t- '{full_dir_name}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{workspace_folder}' will be replaced with the currently accessed workspace folder, if any.\n\t- '{workspace_and_folder} will be replaced with the currently accessed workspace and workspace folder like this: 'Workspace - WorkspaceFolder'\n\t- '{current_column}' will get replaced with the current column of the current line.\n\t- '{current_line}' will get replaced with the current line number.\n\t- '{total_lines}' will get replaced with the total line number.\n\t- '{file_size}' will get replaced with the current file's size.\n\t- '{git_repo_name}' will be replaced with the active Git repository name (from the git URL)\n\t- '{git_branch}' will be replaced with the current active branch name."
},
"discord.lower_details_debugging": {
"discord.lowerDetailsDebugging": {
"type": "string",
"default": "Debugging: {workspace}",
"description": "Custom string for the state section of the rich presence when debugging\n\t- '{empty}' will be replaced with an empty space.\n\t- '{file_name}' will be replaced with the current file name.\n\t- '{dir_name}' will get replaced with the folder name that has the current file.\n\t- '{full_dir_name}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{workspace_folder}' will be replaced with the currently accessed workspace folder, if any.\n\t- '{workspace_and_folder} will be replaced with the currently accessed workspace and workspace folder like this: 'Workspace - WorkspaceFolder'\n\t- '{current_column}' will get replaced with the current column of the current line.\n\t- '{current_line}' will get replaced with the current line number.\n\t- '{total_lines}' will get replaced with the total line number.\n\t- '{file_size}' will get replaced with the current file's size.\n\t- '{git_repo_name}' will be replaced with the active Git repository name (from the git URL)\n\t- '{git_branch}' will be replaced with the current active branch name."
},
"discord.lower_details_no_workspace_found": {
"discord.lowerDetailsNoWorkspaceFound": {
"type": "string",
"default": "No workspace.",
"description": "Custom string for the state section of the rich presence when no workspace is found.\nIf set to '{empty}', this will be an empty space.\n\t- '{current_line}' will get replaced with the current line number.\n\t- '{total_lines}' will get replaced with the total line number.\n\t- '{file_size}' will get replaced with the current file's size."
},
"discord.large_image_idling": {
"discord.largeImageIdling": {
"type": "string",
"default": "Idling",
"description": "Custom string for the largeImageText section of the rich presence when idling"
},
"discord.large_image": {
"discord.largeImage": {
"type": "string",
"default": "Editing a {LANG} file",
"description": "Custom string for the largeImageText section of the rich presence.\n\t- '{lang}' will be replaced with the lowercased language ID\n\t- '{LANG}' will be replaced with the uppercased language ID"
},
"discord.small_image": {
"discord.smallImage": {
"type": "string",
"default": "{app_name}",
"description": "Custom string for the smallImageText section of the rich presence\n\t- '{app_name}' will get replaced with the current Visual Studio Code version."
},
"discord.suppress_notifications": {
"discord.suppressNotifications": {
"type": "boolean",
"default": false,
"description": "Decides if error messages are shown to the user"
},
"discord.workspace_elapsed_time": {
"type": "boolean",
"default": true,
"description": "Decides whether to display elapsed time for a workspace or a single file"
},
"discord.workspace_exclude_patterns": {
"discord.workspaceExcludePatterns": {
"type": "array",
"items": {
"type": "string"
@ -162,10 +157,12 @@
"bufferutil": "^4.0.3",
"dayjs": "^1.10.4",
"discord-rpc": "^3.1.4",
"lodash-es": "^4.17.20",
"tslib": "^2.1.0",
"utf-8-validate": "^5.0.4"
},
"devDependencies": {
"@types/lodash-es": "^4.17.4",
"@types/node": "^14.14.25",
"@types/vscode": "^1.53.0",
"@typescript-eslint/eslint-plugin": "^4.15.0",

View file

@ -8,6 +8,8 @@ import {
FILE_SIZES,
IDLE_IMAGE_KEY,
REPLACE_KEYS,
UNKNOWN_GIT_BRANCH,
UNKNOWN_GIT_REPO_NAME,
VSCODE_IMAGE_KEY,
VSCODE_INSIDERS_IMAGE_KEY,
} from './constants';
@ -16,7 +18,7 @@ import { log, LogLevel } from './logger';
import { getConfig, resolveFileIcon, toLower, toTitle, toUpper } from './util';
interface ActivityPayload {
details: string;
details?: string;
state?: string;
startTimestamp?: number | null;
largeImageKey?: string;
@ -32,7 +34,7 @@ interface ActivityPayload {
instance?: boolean;
}
export async function activity() {
export async function activity(previous: ActivityPayload = {}) {
const config = getConfig();
const appName = env.appName;
@ -49,7 +51,7 @@ export async function activity() {
CONFIG_KEYS.LowerDetailsEditing,
CONFIG_KEYS.LowerDetailsDebugging,
),
startTimestamp: null,
startTimestamp: previous.startTimestamp ?? Date.now(),
largeImageKey: IDLE_IMAGE_KEY,
largeImageText: config[CONFIG_KEYS.LargeImageIdling],
smallImageKey: defaultSmallImageKey,
@ -57,6 +59,10 @@ export async function activity() {
};
if (window.activeTextEditor) {
if (window.activeTextEditor.document.languageId === 'Log') {
return state;
}
const largeImageKey = resolveFileIcon(window.activeTextEditor.document);
const largeImageText = config[CONFIG_KEYS.LargeImage]
.replace(REPLACE_KEYS.LanguageLowerCase, toLower(largeImageKey))
@ -75,9 +81,11 @@ export async function activity() {
largeImageKey,
largeImageText,
};
log(LogLevel.Trace, `VSCode language id: ${window.activeTextEditor.document.languageId}`);
}
log(LogLevel.Debug, JSON.stringify(state, null, 2));
log(LogLevel.Debug, `Discord Presence being sent to discord:\n${JSON.stringify(state, null, 2)}`);
return state;
}
@ -171,7 +179,7 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
git.repositories.find((repo) => repo.ui.selected)?.state.HEAD?.name ?? EMPTY,
);
} else {
raw = raw.replace(REPLACE_KEYS.GitBranch, 'Unknown');
raw = raw.replace(REPLACE_KEYS.GitBranch, UNKNOWN_GIT_BRANCH);
}
}
@ -185,7 +193,7 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
.replace('.git', '') ?? EMPTY,
);
} else {
raw = raw.replace(REPLACE_KEYS.GitRepoName, 'Unknown');
raw = raw.replace(REPLACE_KEYS.GitRepoName, UNKNOWN_GIT_REPO_NAME);
}
}

View file

@ -13,6 +13,9 @@ export const DEBUG_IMAGE_KEY = 'debug';
export const VSCODE_IMAGE_KEY = 'vscode';
export const VSCODE_INSIDERS_IMAGE_KEY = 'vscode-insiders';
export const UNKNOWN_GIT_BRANCH = 'Unknown.';
export const UNKNOWN_GIT_REPO_NAME = 'Unknown.';
export const enum REPLACE_KEYS {
Empty = '{empty}',
FileName = '{file_name}',
@ -35,17 +38,16 @@ export const enum REPLACE_KEYS {
export const enum CONFIG_KEYS {
Enabled = 'enabled',
DetailsIdling = 'details_idling',
DetailsEditing = 'details_editing',
DetailsDebugging = 'details_debugging',
LowerDetailsIdling = 'lower_details_idling',
LowerDetailsEditing = 'lower_details_editing',
LowerDetailsDebugging = 'lower_details_debugging',
LowerDetailsNoWorkspaceFound = 'lower_details_no_workspace_found',
LargeImageIdling = 'large_image_idling',
LargeImage = 'large_image',
SmallImage = 'small_image',
SuppressNotifications = 'suppress_notifications',
WorkspaceElapsedTime = 'workspace_elapsed_time',
WorkspaceExcludePatterns = 'workspace_exclude_patterns',
DetailsIdling = 'detailsIdling',
DetailsEditing = 'detailsEditing',
DetailsDebugging = 'detailsDebugging',
LowerDetailsIdling = 'lowerDetailsIdling',
LowerDetailsEditing = 'lowerDetailsEditing',
LowerDetailsDebugging = 'lowerDetailsDebugging',
LowerDetailsNoWorkspaceFound = 'lowerDetailsNoWorkspaceFound',
LargeImageIdling = 'largeImageIdling',
LargeImage = 'largeImage',
SmallImage = 'smallImage',
SuppressNotifications = 'suppressNotifications',
WorkspaceExcludePatterns = 'workspaceExcludePatterns',
}

View file

@ -9,8 +9,9 @@ import {
extensions,
debug,
} from 'vscode';
import { activity } from './activity';
import throttle from 'lodash-es/throttle';
import { activity } from './activity';
import { CLIENT_ID, CONFIG_KEYS } from './constants';
import { GitExtension } from './git';
import { log, LogLevel } from './logger';
@ -22,8 +23,13 @@ statusBarIcon.text = '$(pulse) Connecting to Discord...';
const rpc = new Client({ transport: 'ipc' });
const config = getConfig();
let state = {};
async function sendActivity() {
rpc.setActivity(await activity());
state = {
...(await activity(state)),
};
rpc.setActivity(state);
}
async function login(context: ExtensionContext) {
@ -33,9 +39,8 @@ async function login(context: ExtensionContext) {
statusBarIcon.text = '$(globe) Connected to Discord';
statusBarIcon.tooltip = 'Connected to Discord';
void sendActivity();
const onChangeActiveTextEditor = window.onDidChangeActiveTextEditor(() => sendActivity());
const onChangeTextDocument = workspace.onDidChangeTextDocument(() => sendActivity());
const onChangeTextDocument = workspace.onDidChangeTextDocument(throttle(() => sendActivity(), 1000));
const onStartDebugSession = debug.onDidStartDebugSession(() => sendActivity());
const onTerminateDebugSession = debug.onDidTerminateDebugSession(() => sendActivity());

View file

@ -5,19 +5,18 @@ import { KNOWN_EXTENSIONS, KNOWN_LANGUAGES } from './constants';
type WorkspaceExtensionConfigurationuration = WorkspaceConfiguration & {
enabled: boolean;
details_editing: string;
details_debugging: string;
details_idling: string;
lower_details_editing: string;
lower_details_debugging: string;
lower_details_idling: string;
lower_details_no_workspace_found: string;
large_image: string;
large_image_idling: string;
small_image: string;
suppress_notifications: boolean;
workspace_elapsed_time: boolean;
workspace_exclude_patterns: string[];
detailsIdling: string;
detailsEditing: string;
detailsDebugging: string;
lowerDetailsIdling: string;
lowerDetailsEditing: string;
lowerDetailsDebugging: string;
lowerDetailsNoWorkspaceFound: string;
largeImageIdling: string;
largeImage: string;
smallImage: string;
suppressNotifications: boolean;
workspaceExcludePatterns: string[];
};
export function getConfig() {