diff --git a/README.md b/README.md new file mode 100644 index 0000000..86d112f --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +# Snatch + +A [Sketch] plugin that upload layer to CDN directly. + +Contributions are welcome! + +## Development + +_This plugin was created using `skpm`. For a detailed explanation on how things work, checkout the [skpm Readme](https://github.com/skpm/skpm/blob/master/README.md)._ + +## Usage + +Install the dependencies + +```bash +npm install +``` + +Once the installation is done, you can run some commands inside the project folder: + +```bash +npm run build +``` + +To watch for changes: + +```bash +npm run watch +``` + +Additionally, if you wish to run the plugin every time it is built: + +```bash +npm run start +``` + +## Custom Configuration + +### Babel + +To customize Babel, you have two options: + +* You may create a [`.babelrc`](https://babeljs.io/docs/usage/babelrc) file in your project's root directory. Any settings you define here will overwrite matching config-keys within skpm preset. For example, if you pass a "presets" object, it will replace & reset all Babel presets that skpm defaults to. + +* If you'd like to modify or add to the existing Babel config, you must use a `webpack.skpm.config.js` file. Visit the [Webpack](#webpack) section for more info. + +### Webpack + +To customize webpack create `webpack.skpm.config.js` file which exports function that will change webpack's config. + +```js +/** + * Function that mutates original webpack config. + * Supports asynchronous changes when promise is returned. + * + * @param {object} config - original webpack config. + * @param {boolean} isPluginCommand - whether the config is for a plugin command or a resource + **/ +module.exports = function(config, isPluginCommand) { + /** you can change config here **/ +} +``` + +## Debugging + +To view the output of your `console.log`, you have a few different options: + +* Use the [`sketch-dev-tools`](https://github.com/skpm/sketch-dev-tools) +* Open `Console.app` and look for the sketch logs +* Look at the `~/Library/Logs/com.bohemiancoding.sketch3/Plugin Output.log` file + +Skpm provides a convenient way to do the latter: + +```bash +skpm log +``` + +The `-f` option causes `skpm log` to not stop when the end of logs is reached, but rather to wait for additional data to be appended to the input + +## Backend + +To make working on the Backend, run the [`Snatch node server`](https://github.com/ZhichengChen/snatch-server) + +[Sketch]: https://sketchapp.com/ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..b5d996b Binary files /dev/null and b/assets/icon.png differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..c4b76ae --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "snatch", + "version": "0.1.0", + "engines": { + "sketch": ">=3.0" + }, + "skpm": { + "name": "snatch", + "manifest": "src/manifest.json", + "main": "snatch.sketchplugin", + "assets": [ + "assets/**/*" + ] + }, + "scripts": { + "build": "skpm-build", + "watch": "skpm-build --watch", + "start": "skpm-build --watch --run", + "postinstall": "npm run build && skpm-link" + }, + "devDependencies": { + "@skpm/builder": "^0.5.11" + }, + "author": "Zhicheng Chen " +} diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 0000000..37ab1e7 --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,33 @@ +{ + "compatibleVersion": 3, + "name": "Snatch", + "description": "Snatch, upload layer to cdn directly, improve work efficiency.", + "author": "chenzhicheng.com", + "version": "0.1.0", + "identifier": "com.chenzhicheng.snatch", + "bundleVersion": 1, + "icon": "icon.png", + "commands": [ + { + "name": "Upload Select", + "identifier": "snaptchSelect", + "shortcut": "ctrl command p", + "script": "./snatch.js", + "handler" : "uploadSelect" + }, + { + "script" : "./snatch.js", + "handler" : "setting", + "name" : "Set Server URL", + "identifier" : "serverUrl" + } + ], + "menu": { + "title": "Snatch", + "items": [ + "snaptchSelect", + "-", + "serverUrl" + ] + } +} \ No newline at end of file diff --git a/src/snatch.js b/src/snatch.js new file mode 100644 index 0000000..b4b2f86 --- /dev/null +++ b/src/snatch.js @@ -0,0 +1,80 @@ +const Settings = require('sketch/settings'); +const UI = require('sketch/ui'); + +export function uploadSelect(context) { + onRun(context, false); +} +export function setting(e) { + onRun(context, true); +} + +function exportLayerAsBitmap(document, layer, scale) { + var slice, + result = {}, + rect = layer.absoluteRect(), + path = NSTemporaryDirectory() + layer.objectID() + '.png'; + NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()), + (slice = MSExportRequest.exportRequestsFromExportableLayer( + layer + ).firstObject()), + (slice.page = document.currentPage()), + (slice.format = 'png'), + (slice.scale = scale), + document.saveArtboardOrSlice_toFile(slice, path); + + var url = NSURL.fileURLWithPath(path), + bitmap = NSData.alloc().initWithContentsOfURL(url), + base64 = bitmap.base64EncodedStringWithOptions(0); + + NSFileManager.defaultManager().removeItemAtURL_error(url, nil); + var imgRep = NSBitmapImageRep.imageRepWithData(bitmap); + return ( + (result.bitmap = base64), + (result.width = imgRep.pixelsWide() / 4), + (result.height = imgRep.pixelsHigh() / 4), + result + ); +} + +const onRun = function(context, setting) { + const url = Settings.settingForKey('url'); + if (setting || !url) { + UI.getInputFromUser( + 'Input the server address.', + { + initialValue: url || 'https://' + }, + (err, value) => { + if (err) { + return; + } + return Settings.setSettingForKey('url', value); + } + ); + return ; + } + + const doc = context.document; + const selection = context.selection; + if (selection.count() == 0) { + doc.showMessage('Please select the layer to upload.'); + } else { + for (let i = 0; i < selection.count(); i++) { + const layer = selection[i]; + const layerName = layer.name(); + const { bitmap } = exportLayerAsBitmap(doc, layer, 1); + + fetch(url, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: { image: bitmap, name: layerName } + }) + .then(response => response.text()) + .then(text => doc.showMessage(text)) + .catch(e => doc.showMessage(e.message)); + } + } +};