Skip to content

Rewrite #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 6, 2019
27 changes: 9 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
# Polacode
<p>
<h2 align="center">Polacode — Polaroid for your code 📸</h2>
</p>

Polaroid for your code 📸.

[MarketPlace Page](https://marketplace.visualstudio.com/items?itemName=pnp.polacode)

![usage](https://github.com/octref/polacode/raw/master/demo/usage.gif)

By [Pine](https://github.com/octref) & [Peng](https://github.com/rebornix) from VS Code team.
Happy Coding!
<!-- ![usage](https://github.com/octref/polacode/raw/master/demo/usage.gif) -->
![usage](./demo/usage.gif)

## Why?

Expand All @@ -18,11 +14,10 @@ You shell out $200 for [italic cursive html attributes](https://www.typography.c

The code has to look right.

## Seriously, why not just take a screenshot?
## Tips

- I like and care about the shadow, padding & rounded corner of macOS's screenshot. I want an easy way to have those nice visuals for any selection of my snippet.
- I want to hide errors, warnings, color decorators, folding markers, line numbers, scrollbar and minimap.
- It generates something decent on Windows & Linux.
- Resize the snippet / container by dragging the lowerright corner
- Use `polacode.target`, `polacode.shadow`, `polacode.transparentBackground` and `polacode.backgroundColor` to control image appearance

## Demo

Expand All @@ -38,10 +33,6 @@ The code has to look right.

![demo3](https://raw.githubusercontent.com/octref/polacode/master/demo/3.png)

## Tip

- When running out of horizontal space, try the command `View: Toggle Editor Group Vertical/Horizontal Layout`.

## Credit

Thanks to [@tsayen](https://github.com/tsayen) for making [dom-to-image](https://github.com/tsayen/dom-to-image), which Polacode is using for generating the images.
Expand All @@ -54,7 +45,7 @@ Download button animation is made with [Vivus](https://github.com/maxwellito/viv

## Contribution

Contribution is extremely unwelcome.
Contribution is not very welcome.
Please open an issue first so I can stop you from complicating the UX.

## License
Expand Down
Binary file modified demo/usage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node"
}
}
51 changes: 47 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,61 @@
"theme": "light"
},
"icon": "icon.png",
"categories": ["Other"],
"categories": [
"Other"
],
"engines": {
"vscode": "^1.19.0"
"vscode": "^1.32.0"
},
"activationEvents": ["onCommand:polacode.activate"],
"activationEvents": [
"onCommand:polacode.activate",
"onWebviewPanel:polacode"
],
"main": "./src/extension",
"contributes": {
"commands": [
{
"command": "polacode.activate",
"title": "Polacode 📸"
}
]
],
"configuration": {
"title": "Polacode",
"properties": {
"polacode.shadow": {
"type": "string",
"description": "Shadow of the snippet node. Use any value for CSS `box-shadow`",
"default": "rgba(0, 0, 0, 0.55) 0px 20px 68px"
},
"polacode.transparentBackground": {
"type": "boolean",
"description": "Transparent background for containers",
"default": false
},
"polacode.backgroundColor": {
"type": "string",
"description": "Background color of snippet container. Use any value for CSS `background-color`",
"format": "color-hex",
"default": "#f2f2f2"
},
"polacode.target": {
"type": "string",
"description": "Shoot with or without container",
"default": "container",
"enum": [
"container",
"snippet"
],
"enumDescriptions": [
"Shoot with the container.",
"Shoot with the snippet alone. If you want transparent padding, use `container` with `\"polacode.transparentBackground\": true`"
]
}
}
}
},
"devDependencies": {
"@types/node": "^11.12.0",
"@types/vscode": "^1.32.0"
}
}
156 changes: 112 additions & 44 deletions src/extension.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,135 @@
const vscode = require('vscode')
const fs = require('fs')
const path = require('path')
const { writeFileSync } = require('fs')
const { homedir } = require('os')

const writeSerializedBlobToFile = (serializeBlob, fileName) => {
const bytes = new Uint8Array(serializeBlob.split(','))
writeFileSync(fileName, new Buffer(bytes))
fs.writeFileSync(fileName, Buffer.from(bytes))
}

const P_TITLE = 'Polacode 📸'

/**
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
const htmlPath = path.resolve(context.extensionPath, 'src/webview/index.html')
const indexUri = vscode.Uri.file(htmlPath)
const htmlPath = path.resolve(context.extensionPath, 'webview/index.html')

let lastUsedImageUri = vscode.Uri.file(path.resolve(homedir(), 'Desktop/code.png'))
vscode.commands.registerCommand('polacode.shoot', serializedBlob => {
vscode.window
.showSaveDialog({
defaultUri: lastUsedImageUri,
filters: {
Images: ['png']
}
})
.then(uri => {
if (uri) {
writeSerializedBlobToFile(serializedBlob, uri.fsPath)
lastUsedImageUri = uri
}
let panel

vscode.window.registerWebviewPanelSerializer('polacode', {
async deserializeWebviewPanel(_panel, state) {
panel = _panel
panel.webview.html = getHtmlContent(htmlPath)
panel.webview.postMessage({
type: 'restore',
innerHTML: state.innerHTML,
bgColor: context.globalState.get('polacode.bgColor', '#2e3440')
})
setupSelectionSync()
setupMessageListeners()
}
})

vscode.commands.registerCommand('polacode.activate', () => {
vscode.commands
.executeCommand('vscode.previewHtml', indexUri, 2, 'Polacode 📸', {
allowScripts: true
})
.then(() => {
const fontFamily = vscode.workspace.getConfiguration('editor').fontFamily
const bgColor = context.globalState.get('polacode.bgColor', '#2e3440')
vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', indexUri, {
type: 'init',
fontFamily,
bgColor
})
})
panel = vscode.window.createWebviewPanel('polacode', P_TITLE, 2, {
enableScripts: true,
localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'webview'))]
})

panel.webview.html = getHtmlContent(htmlPath)

setupMessageListeners()

const fontFamily = vscode.workspace.getConfiguration('editor').fontFamily
const bgColor = context.globalState.get('polacode.bgColor', '#2e3440')
panel.webview.postMessage({
type: 'init',
fontFamily,
bgColor
})

syncSettings()
})

vscode.window.onDidChangeTextEditorSelection(e => {
if (e.selections[0] && !e.selections[0].isEmpty) {
vscode.commands.executeCommand('editor.action.clipboardCopyAction')
vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', indexUri, {
type: 'update'
})
vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('polacode') || e.affectsConfiguration('editor')) {
syncSettings()
}
})

vscode.commands.registerCommand('polacode._onmessage', ({ type, data }) => {
if (type === 'updateBgColor') {
context.globalState.update('polacode.bgColor', data.bgColor)
} else if (type === 'invalidPasteContent') {
vscode.window.showInformationMessage(
'Pasted content is invalid. Only copy from VS Code and check if your shortcuts for copy/paste have conflicts.'
)
}
setupSelectionSync()

function setupMessageListeners() {
panel.webview.onDidReceiveMessage(({ type, data }) => {
switch (type) {
case 'shoot':
vscode.window
.showSaveDialog({
defaultUri: lastUsedImageUri,
filters: {
Images: ['png']
}
})
.then(uri => {
if (uri) {
writeSerializedBlobToFile(data.serializedBlob, uri.fsPath)
lastUsedImageUri = uri
}
})
break
case 'getAndUpdateCacheAndSettings':
panel.webview.postMessage({
type: 'restoreBgColor',
bgColor: context.globalState.get('polacode.bgColor', '#2e3440')
})

syncSettings()
break
case 'updateBgColor':
context.globalState.update('polacode.bgColor', data.bgColor)
break
case 'invalidPasteContent':
vscode.window.showInformationMessage(
'Pasted content is invalid. Only copy from VS Code and check if your shortcuts for copy/paste have conflicts.'
)
break
}
})
}

function syncSettings() {
const settings = vscode.workspace.getConfiguration('polacode')
const editorSettings = vscode.workspace.getConfiguration('editor')
panel.webview.postMessage({
type: 'updateSettings',
shadow: settings.get('shadow'),
transparentBackground: settings.get('transparentBackground'),
backgroundColor: settings.get('backgroundColor'),
target: settings.get('target'),
ligature: editorSettings.get('fontLigatures')
})
}

function setupSelectionSync() {
vscode.window.onDidChangeTextEditorSelection(e => {
if (e.selections[0] && !e.selections[0].isEmpty) {
vscode.commands.executeCommand('editor.action.clipboardCopyAction')
panel.postMessage({
type: 'update'
})
}
})
}
}

function getHtmlContent(htmlPath) {
const htmlContent = fs.readFileSync(htmlPath, 'utf-8')
return htmlContent.replace(/script src="([^"]*)"/g, (match, src) => {
const realSource = 'vscode-resource:' + path.resolve(htmlPath, '..', src)
return `script src="${realSource}"`
})
}

Expand Down
Loading