Skip to content

Commit 6d4bc9b

Browse files
committed
feat/refactor: rewrite entire application + enhance settings/icons/usability
1 parent 80fe78d commit 6d4bc9b

18 files changed

+2003
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.eslintrc.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"root": true,
3+
"parser": "@typescript-eslint/parser",
4+
"parserOptions": {
5+
"ecmaVersion": 6,
6+
"sourceType": "module"
7+
},
8+
"plugins": ["@typescript-eslint"],
9+
"rules": {
10+
"@typescript-eslint/naming-convention": "warn",
11+
"@typescript-eslint/semi": "warn",
12+
"curly": "off",
13+
"eqeqeq": "warn",
14+
"no-throw-literal": "warn",
15+
"semi": "off"
16+
},
17+
"ignorePatterns": ["out", "dist", "**/*.d.ts"]
18+
}

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
out
2+
dist
3+
node_modules
4+
.vscode-test/
5+
*.vsix

.vscode/extensions.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
// See http://go.microsoft.com/fwlink/?LinkId=827846
3+
// for the documentation about the extensions.json format
4+
"recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher"]
5+
}

.vscode/launch.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// A launch configuration that compiles the extension and then opens it inside a new window
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
{
6+
"version": "0.2.0",
7+
"configurations": [
8+
{
9+
"name": "Run Extension",
10+
"type": "extensionHost",
11+
"request": "launch",
12+
"args": [
13+
"--extensionDevelopmentPath=${workspaceFolder}"
14+
],
15+
"outFiles": [
16+
"${workspaceFolder}/dist/**/*.js"
17+
],
18+
"preLaunchTask": "${defaultBuildTask}"
19+
},
20+
{
21+
"name": "Extension Tests",
22+
"type": "extensionHost",
23+
"request": "launch",
24+
"args": [
25+
"--extensionDevelopmentPath=${workspaceFolder}",
26+
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
27+
],
28+
"outFiles": [
29+
"${workspaceFolder}/out/**/*.js",
30+
"${workspaceFolder}/dist/**/*.js"
31+
],
32+
"preLaunchTask": "tasks: watch-tests"
33+
}
34+
]
35+
}

.vscode/settings.json

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
"files.exclude": {
4+
"out": false, // set this to true to hide the "out" folder with the compiled JS files
5+
"dist": false // set this to true to hide the "dist" folder with the compiled JS files
6+
},
7+
"search.exclude": {
8+
"out": true, // set this to false to include "out" folder in search results
9+
"dist": true // set this to false to include "dist" folder in search results
10+
},
11+
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
12+
"typescript.tsc.autoDetect": "off"
13+
}

.vscode/tasks.json

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// See https://go.microsoft.com/fwlink/?LinkId=733558
2+
// for the documentation about the tasks.json format
3+
{
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"type": "npm",
8+
"script": "watch",
9+
"problemMatcher": "$ts-webpack-watch",
10+
"isBackground": true,
11+
"presentation": {
12+
"reveal": "never",
13+
"group": "watchers"
14+
},
15+
"group": {
16+
"kind": "build",
17+
"isDefault": true
18+
}
19+
},
20+
{
21+
"type": "npm",
22+
"script": "watch-tests",
23+
"problemMatcher": "$tsc-watch",
24+
"isBackground": true,
25+
"presentation": {
26+
"reveal": "never",
27+
"group": "watchers"
28+
},
29+
"group": "build"
30+
},
31+
{
32+
"label": "tasks: watch-tests",
33+
"dependsOn": [
34+
"npm: watch",
35+
"npm: watch-tests"
36+
],
37+
"problemMatcher": []
38+
}
39+
]
40+
}

.vscodeignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.vscode/**
2+
.vscode-test/**
3+
out/**
4+
node_modules/**
5+
src/**
6+
.gitignore
7+
.yarnrc
8+
webpack.config.js
9+
vsc-extension-quickstart.md
10+
**/tsconfig.json
11+
**/.eslintrc.json
12+
**/*.map
13+
**/*.ts

.yarnrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--ignore-engines true

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Change Log
2+
3+
## [1.0.0] - 2022-12-18
4+
- Complete rewrite
5+
- New settings
6+
- Better icons

README.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Imperial README
2+
3+
Imperial is a hastebin alternative built with UI and user experience in mind.
4+
5+
### Connect With Us!
6+
7+
- [ImperialBin](https://imperialb.in)
8+
- [Discord](https://imperialb.in/discord)
9+
- [Github](https://imperialb.in/github)
10+
11+
## Features
12+
13+
Quickly upload text and retrieve a URL with the text!
14+
15+
![Upload Example GIF]("/assets/demo.gif")
16+
17+
## Settings
18+
19+
### Customization
20+
21+
- `API Key`: Improves features with an account, and more to come. :p
22+
- `Expiration`: An integer of days, of how long to keep the paste before expiration.
23+
- `Instant Delete`: Deletes the paste after the first view from a human.
24+
- `Image Embed`: View the code uploaded as an image, instead of text in the embed.
25+
- `Longer URLS`: Have longer URLS
26+
27+
### Keybinds
28+
29+
Windows and Linux:
30+
31+
- `Upload`: Shift + ctrl + s
32+
33+
MacOS:
34+
35+
- `Upload`: Shift + cmd + s
36+
37+
### Extension
38+
39+
- `Imperial.uploadDocument`: Uploads the selected text to Imperial and responds with a URL of your document.
40+
41+
## Requirements
42+
43+
- `imperial-node`
44+
45+
while these should come preinstalled with the extension, every system is different. If you face any troubles, try installing/resintalling these first.

assets/demo.gif

23.7 MB
Loading

package.json

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"name": "imperial-vsc",
3+
"displayName": "imperial-vsc",
4+
"description": "Use IMPERIAL in your editor!",
5+
"version": "1.0.0",
6+
"engines": {
7+
"vscode": "^1.74.0"
8+
},
9+
"categories": [
10+
"Other"
11+
],
12+
"activationEvents": [
13+
"onCommand:imperial.uploadDocument"
14+
],
15+
"main": "./dist/extension.js",
16+
"contributes": {
17+
"commands": [
18+
{
19+
"command": "imperial.uploadDocument",
20+
"title": "Upload Document",
21+
"icon": "$(save)"
22+
}
23+
],
24+
"keybindings": [
25+
{
26+
"when": "editorHasSelection",
27+
"command": "imperial.uploadDocument",
28+
"key": "ctrl+shift+s",
29+
"mac": "shift+cmd+s"
30+
}
31+
],
32+
"configuration": {
33+
"title": "Imperial",
34+
"properties": {
35+
"imperial.apiToken": {
36+
"type": "string",
37+
"default": "",
38+
"description": "API key (You need an API key for the below features and better API limit! Visit https://imperialb.in/account to get yours!)"
39+
},
40+
"imperial.longerURLs": {
41+
"type": "boolean",
42+
"default": false,
43+
"description": "32 character long URLs"
44+
},
45+
"imperial.instantDelete": {
46+
"type": "boolean",
47+
"default": false,
48+
"description": "Instantly deletes the document after being viewed"
49+
},
50+
"imperial.imageEmbed": {
51+
"type": "boolean",
52+
"default": false,
53+
"description": "Takes a snapshot of the document and embeds with OG tags"
54+
},
55+
"imperial.expiration": {
56+
"type": [
57+
"number",
58+
"null"
59+
],
60+
"default": null,
61+
"description": "When the document expires, by default it will last forever. (in days)"
62+
},
63+
"imperial.encrypted": {
64+
"type": "boolean",
65+
"default": false,
66+
"description": "Encrypts the document with AES256 with a password of your choice when provided, otherwise it will be encrypted with a cryptographically secure random password."
67+
}
68+
}
69+
},
70+
"menus": {
71+
"editor/context": [
72+
{
73+
"when": "editorHasSelection",
74+
"command": "imperial.uploadDocument",
75+
"group": "9_cutcopypaste"
76+
}
77+
],
78+
"editor/title": [
79+
{
80+
"when": "editorHasSelection",
81+
"command": "imperial.uploadDocument",
82+
"group": "navigation"
83+
}
84+
]
85+
}
86+
},
87+
"scripts": {
88+
"vscode:prepublish": "yarn run compile",
89+
"compile": "tsc -p ./",
90+
"watch": "tsc -watch -p ./",
91+
"pretest": "yarn run compile && yarn run lint",
92+
"lint": "eslint src --ext ts"
93+
},
94+
"devDependencies": {
95+
"@types/glob": "^8.0.0",
96+
"@types/mocha": "^10.0.1",
97+
"@types/node": "16.x",
98+
"@types/node-fetch": "2",
99+
"@types/vscode": "^1.74.0",
100+
"@typescript-eslint/eslint-plugin": "^5.45.0",
101+
"@typescript-eslint/parser": "^5.45.0",
102+
"@vscode/test-electron": "^2.2.0",
103+
"eslint": "^8.28.0",
104+
"glob": "^8.0.3",
105+
"mocha": "^10.1.0",
106+
"ts-loader": "^9.4.1",
107+
"typescript": "^4.9.3"
108+
},
109+
"dependencies": {
110+
"node-fetch": "2"
111+
}
112+
}

src/extension.ts

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import * as vscode from "vscode";
2+
import fetch from "node-fetch";
3+
import { Document, ImperialAPIResponse } from "./types";
4+
5+
export function activate(context: vscode.ExtensionContext) {
6+
const disposable = vscode.commands.registerCommand(
7+
"imperial.uploadDocument",
8+
async () => {
9+
const editor = vscode.window.activeTextEditor;
10+
if (!editor) return;
11+
12+
const selectedCode = editor.document.getText(editor.selection);
13+
if (selectedCode.trim().length === 0) return;
14+
15+
const config = vscode.workspace.getConfiguration("imperial");
16+
const settings: Record<string, string | boolean | null> = {
17+
apiToken: config.get("apiToken") ?? "",
18+
longerURLs: config.get("longerURLs") ?? false,
19+
shortURLs: config.get("shortURLs") ?? false,
20+
imageEmbed: config.get("imageEmbed") ?? false,
21+
expiration: config.get("expiration") ?? null,
22+
encrypted: config.get("encrypted") ?? false,
23+
};
24+
25+
const response = await fetch("https://imperial.hop.sh/v1/document", {
26+
method: "POST",
27+
headers: {
28+
// eslint-disable-next-line @typescript-eslint/naming-convention
29+
"Content-Type": "application/json",
30+
// eslint-disable-next-line @typescript-eslint/naming-convention
31+
Authorization: settings.apiToken as string,
32+
},
33+
body: JSON.stringify({
34+
content: selectedCode,
35+
settings: {
36+
longerURLS: settings.longerURLS,
37+
shortURLS: settings.shortURLS,
38+
imageEmbed: settings.imageEmbed,
39+
expiration: settings.expiration,
40+
encrypted: settings.encrypted,
41+
},
42+
}),
43+
});
44+
45+
const parsedResponse = (await response.json()) as ImperialAPIResponse<
46+
Document & { password?: string }
47+
>;
48+
49+
if (!response.ok || !parsedResponse.success || !parsedResponse.data) {
50+
vscode.window.showErrorMessage(
51+
`An error occurred: ${
52+
parsedResponse?.message ?? response.statusText ?? "Unknown error"
53+
}`
54+
);
55+
return;
56+
}
57+
58+
const selection = await vscode.window.showInformationMessage(
59+
`Uploaded to IMPERIAL!\n${parsedResponse.data.links.formatted}`,
60+
"Copy link",
61+
"Open document"
62+
);
63+
64+
const btnSelection = selection?.toLowerCase();
65+
66+
switch (btnSelection) {
67+
case "copy link":
68+
await vscode.env.clipboard.writeText(
69+
parsedResponse.data.links.formatted
70+
);
71+
break;
72+
case "open document":
73+
await vscode.commands.executeCommand(
74+
"vscode.open",
75+
vscode.Uri.parse(parsedResponse.data.links.formatted)
76+
);
77+
break;
78+
default:
79+
break;
80+
}
81+
}
82+
);
83+
84+
context.subscriptions.push(disposable);
85+
}
86+
87+
export function deactivate() {}

0 commit comments

Comments
 (0)