├── .appcast.xml ├── .gitignore ├── README.md └── SelectiveUpload.sketchplugin └── Contents ├── Resources ├── SelectiveUpload.framework │ ├── Resources │ │ ├── Assets.car │ │ ├── Info.plist │ │ └── script.js │ ├── SelectiveUpload │ └── _CodeSignature │ │ └── CodeResources └── icon.png └── Sketch ├── manifest.json └── script.js /.appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **⚠️ Note: The plugin currently does not work in Sketch 71 or above.** 2 | 3 | --- 4 | 5 | # Selective Upload 6 | 7 | Exclude Artboards and Pages when uploading your Document to [Sketch](https://sketch.com) Cloud. 8 | 9 | --- 10 | 11 | With this plugin enabled, Artboards and Pages prefixed with `--` are ignored when uploading your document to Sketch Cloud. 12 | 13 | You can customize this prefix in the plugin's settings. 14 | 15 | ************************ 16 | ### ⚠️ Warning: DO NOT use Selective Upload if your original file is not backed up somewhere other than Sketch Cloud. 17 | ************************ 18 | 19 | 20 | ## Installation 21 | Download the contents of this repository, then double-click the `SelectiveUpload.sketchplugin` bundle. 22 | Or install via [Sketch Runner](https://sketchrunner.com/). 23 | 24 | # How to use 25 | 1. Simply keep this plugin enabled and your prefixed Artboards/Pages will be ignored when uploading to Sketch Cloud. 26 | 1. Customize the prefix by going to `Plugins > Selective Upload > Set Prefix`. 27 | 1. The plugin includes a few commands to help you add prefixes to multiple Artboards at once without having to rename them manually. 28 | 29 | --- 30 | 31 | Feedback or suggestions? Find me on Twitter: [@abynim](http://twitter.com/abynim) 32 | 33 | MIT License 34 | 35 | --- 36 | 37 | ## Plugs 🤓 38 | 39 | I've made more plugins for Sketch, including: 40 | 41 | [Sketch Runner](https://sketchrunner.com) - Design faster in Sketch 42 | 43 | [User Flows](https://abynim.github.io/UserFlows/) - A plugin for generating flow diagrams from Artboards in Sketch. 44 | 45 | [Lippy](https://github.com/abynim/lippy) - An interactive Lorem-ipsum generator plugin for Sketch. 46 | 47 | [Minimap](https://github.com/abynim/sketch-minimap) - A Sketch plugin to navigate large pages with ease. 48 | 49 | -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/Resources/Assets.car: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abynim/sketch-selective-upload/dbdfa8ebbb151315f76c1495ce9ebedc9cb8ad18/SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/Resources/Assets.car -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 19H2 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | SelectiveUpload 11 | CFBundleIdentifier 12 | com.abynim.SelectiveUpload 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | SelectiveUpload 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSupportedPlatforms 22 | 23 | MacOSX 24 | 25 | CFBundleVersion 26 | 65 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 12A7300 31 | DTPlatformName 32 | macosx 33 | DTPlatformVersion 34 | 10.15.6 35 | DTSDKBuild 36 | 19G68 37 | DTSDKName 38 | macosx10.15 39 | DTXcode 40 | 1201 41 | DTXcodeBuild 42 | 12A7300 43 | LSMinimumSystemVersion 44 | 10.13 45 | NSHumanReadableCopyright 46 | Copyright © 2020 Aby Nimbalkar. All rights reserved. 47 | 48 | 49 | -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/Resources/script.js: -------------------------------------------------------------------------------- 1 | var go = function(context) { 2 | try { SelectiveUpload.go(context); } 3 | catch(e) { 4 | if(Mocha.sharedRuntime().loadFrameworkWithName_inDirectory('SelectiveUpload', NSBundle.bundleWithURL(context.plugin.url()).resourceURL().path())) { 5 | SelectiveUpload.go(context); 6 | } 7 | } 8 | } 9 | 10 | const defaultsKey = "com.abynim.SelectiveUpload.prefix"; 11 | 12 | var getPrefix = function() { 13 | var currentPrefix = NSUserDefaults.standardUserDefaults().stringForKey(defaultsKey); 14 | currentPrefix = currentPrefix ? ""+currentPrefix : "--"; 15 | return currentPrefix; 16 | } 17 | 18 | var setPrefix = function(context) { 19 | var UI = require('sketch/ui'); 20 | 21 | var currentPrefix = getPrefix(); 22 | 23 | UI.getInputFromUser( 24 | "When uploading to Sketch Cloud, ignore Artboards with prefix:", 25 | { 26 | initialValue: currentPrefix, 27 | description: "(Case sensitive)" 28 | }, 29 | (err, value) => { 30 | if (err) { return } 31 | var newVal = value ? NSString.stringWithString(value) : NSString.stringWithString("--"); 32 | NSUserDefaults.standardUserDefaults().setObject_forKey(newVal, defaultsKey); 33 | } 34 | ); 35 | } 36 | 37 | var ignore = function(context) { 38 | 39 | var prefix = getPrefix(); 40 | 41 | var artboards; 42 | 43 | if(context.command.identifier().hasSuffix("Page")) { 44 | artboards = context.document.currentPage().artboards(); 45 | } else { 46 | artboards = context.selection.valueForKeyPath("@distinctUnionOfObjects.parentArtboard"); 47 | } 48 | 49 | var shouldReset = context.command.identifier().hasPrefix("reset"); 50 | 51 | var loop = artboards.objectEnumerator(); 52 | var artboard; 53 | while(artboard = loop.nextObject()) { 54 | if(shouldReset) { 55 | if(artboard.name().hasPrefix(prefix)) { 56 | var artboardName = ""+artboard.name(); 57 | artboard.setName(artboardName.substr(prefix.length)); 58 | } 59 | } 60 | else { 61 | if(!artboard.name().hasPrefix(prefix)) { 62 | artboard.setName(prefix + "" + artboard.name()); 63 | } 64 | } 65 | } 66 | 67 | } 68 | 69 | var ignorePage = function(context) { 70 | 71 | var prefix = getPrefix(); 72 | 73 | var shouldReset = context.command.identifier().hasPrefix("reset"); 74 | var currentPage = context.document.currentPage(); 75 | if(shouldReset) { 76 | if(currentPage.name().hasPrefix(prefix)) { 77 | var pageName = ""+currentPage.name(); 78 | currentPage.setName(pageName.substr(prefix.length)); 79 | } 80 | } 81 | else { 82 | if(!currentPage.name().hasPrefix(prefix)) { 83 | currentPage.setName(prefix + "" + currentPage.name()); 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/SelectiveUpload: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abynim/sketch-selective-upload/dbdfa8ebbb151315f76c1495ce9ebedc9cb8ad18/SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/SelectiveUpload -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/SelectiveUpload.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/Assets.car 8 | 9 | QvlWqWjZt39ZQ/MjpW0GLFZb/Os= 10 | 11 | Resources/Info.plist 12 | 13 | q1qiyHSLR6oApT+nliSmJqZ8buc= 14 | 15 | Resources/script.js 16 | 17 | 36L7Wdk580Qi23YnuRudH4Ar4wM= 18 | 19 | 20 | files2 21 | 22 | Resources/Assets.car 23 | 24 | hash2 25 | 26 | udquwdsEPxvcQdU+REtpjbfiqj3UkUawqQTOvzmBJOY= 27 | 28 | 29 | Resources/Info.plist 30 | 31 | hash2 32 | 33 | xpRkRJVlVwu4PE+39RtN/cN39eUXnIVC3wAlkiPIqxw= 34 | 35 | 36 | Resources/script.js 37 | 38 | hash2 39 | 40 | aaXAEp4qEOuuqmRDx5pom8+K4ARzY3kbodiYeIz87qA= 41 | 42 | 43 | 44 | rules 45 | 46 | ^Resources/ 47 | 48 | ^Resources/.*\.lproj/ 49 | 50 | optional 51 | 52 | weight 53 | 1000 54 | 55 | ^Resources/.*\.lproj/locversion.plist$ 56 | 57 | omit 58 | 59 | weight 60 | 1100 61 | 62 | ^Resources/Base\.lproj/ 63 | 64 | weight 65 | 1010 66 | 67 | ^version.plist$ 68 | 69 | 70 | rules2 71 | 72 | .*\.dSYM($|/) 73 | 74 | weight 75 | 11 76 | 77 | ^(.*/)?\.DS_Store$ 78 | 79 | omit 80 | 81 | weight 82 | 2000 83 | 84 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 85 | 86 | nested 87 | 88 | weight 89 | 10 90 | 91 | ^.* 92 | 93 | ^Info\.plist$ 94 | 95 | omit 96 | 97 | weight 98 | 20 99 | 100 | ^PkgInfo$ 101 | 102 | omit 103 | 104 | weight 105 | 20 106 | 107 | ^Resources/ 108 | 109 | weight 110 | 20 111 | 112 | ^Resources/.*\.lproj/ 113 | 114 | optional 115 | 116 | weight 117 | 1000 118 | 119 | ^Resources/.*\.lproj/locversion.plist$ 120 | 121 | omit 122 | 123 | weight 124 | 1100 125 | 126 | ^Resources/Base\.lproj/ 127 | 128 | weight 129 | 1010 130 | 131 | ^[^/]+$ 132 | 133 | nested 134 | 135 | weight 136 | 10 137 | 138 | ^embedded\.provisionprofile$ 139 | 140 | weight 141 | 20 142 | 143 | ^version\.plist$ 144 | 145 | weight 146 | 20 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abynim/sketch-selective-upload/dbdfa8ebbb151315f76c1495ce9ebedc9cb8ad18/SelectiveUpload.sketchplugin/Contents/Resources/icon.png -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands" : [ 3 | { 4 | "script" : "script.js", 5 | "handler" : "setPrefix", 6 | "shortcut" : "", 7 | "name" : "Set Prefix", 8 | "identifier" : "prefix" 9 | }, 10 | { 11 | "script" : "script.js", 12 | "handler" : "ignore", 13 | "shortcut" : "", 14 | "name" : "Exclude Selected Artboards", 15 | "identifier" : "ignoreArtboard" 16 | }, 17 | { 18 | "script" : "script.js", 19 | "handler" : "ignore", 20 | "shortcut" : "", 21 | "name" : "Exclude All Artboards in Page", 22 | "identifier" : "ignorePage" 23 | }, 24 | { 25 | "script" : "script.js", 26 | "handler" : "ignore", 27 | "shortcut" : "", 28 | "name" : "Reset Selected Artboards", 29 | "identifier" : "resetArtboard" 30 | }, 31 | { 32 | "script" : "script.js", 33 | "handler" : "ignore", 34 | "shortcut" : "", 35 | "name" : "Reset All Artboards in Page", 36 | "identifier" : "resetPage" 37 | }, 38 | { 39 | "script" : "script.js", 40 | "handler" : "ignorePage", 41 | "shortcut" : "", 42 | "name" : "Exclude Current Page", 43 | "identifier" : "ignoreCurrentPage" 44 | }, 45 | { 46 | "script" : "script.js", 47 | "handler" : "ignorePage", 48 | "shortcut" : "", 49 | "name" : "Reset Current Page", 50 | "identifier" : "resetCurrentPage" 51 | }, 52 | { 53 | "script": "script.js", 54 | "handlers": { 55 | "actions": { 56 | "Startup" : "go" 57 | } 58 | } 59 | } 60 | ], 61 | "menu": { 62 | "title" : "Selective Upload", 63 | "items": [ 64 | "ignoreArtboard", 65 | "ignorePage", 66 | "ignoreCurrentPage", 67 | "-", 68 | "resetArtboard", 69 | "resetPage", 70 | "resetCurrentPage", 71 | "-", 72 | "prefix" 73 | ] 74 | }, 75 | "identifier" : "com.abynim.SelectiveUpload", 76 | "version" : "0.2.5", 77 | "icon" : "icon.png", 78 | "description" : "Exclude artboards and pages when uploading to Sketch Cloud", 79 | "author" : "Aby Nimbalkar", 80 | "name" : "Selective Upload", 81 | "disableCocoaScriptPreprocessor" : true, 82 | "homepage" : "https://github.com/abynim/sketch-selective-upload", 83 | "appcast" : "https://raw.githubusercontent.com/abynim/sketch-selective-upload/master/.appcast.xml" 84 | } 85 | -------------------------------------------------------------------------------- /SelectiveUpload.sketchplugin/Contents/Sketch/script.js: -------------------------------------------------------------------------------- 1 | var go = function(context) { 2 | try { SelectiveUpload.go(context); } 3 | catch(e) { 4 | if(Mocha.sharedRuntime().loadFrameworkWithName_inDirectory('SelectiveUpload', NSBundle.bundleWithURL(context.plugin.url()).resourceURL().path())) { 5 | SelectiveUpload.go(context); 6 | } 7 | } 8 | } 9 | 10 | const defaultsKey = "com.abynim.SelectiveUpload.prefix"; 11 | 12 | var getPrefix = function() { 13 | var currentPrefix = NSUserDefaults.standardUserDefaults().stringForKey(defaultsKey); 14 | currentPrefix = currentPrefix ? ""+currentPrefix : "--"; 15 | return currentPrefix; 16 | } 17 | 18 | var setPrefix = function(context) { 19 | var UI = require('sketch/ui'); 20 | 21 | var currentPrefix = getPrefix(); 22 | 23 | UI.getInputFromUser( 24 | "When uploading to Sketch Cloud, ignore Artboards with prefix:", 25 | { 26 | initialValue: currentPrefix, 27 | description: "(Case sensitive)" 28 | }, 29 | (err, value) => { 30 | if (err) { return } 31 | var newVal = value ? NSString.stringWithString(value) : NSString.stringWithString("--"); 32 | NSUserDefaults.standardUserDefaults().setObject_forKey(newVal, defaultsKey); 33 | } 34 | ); 35 | } 36 | 37 | var ignore = function(context) { 38 | 39 | var prefix = getPrefix(); 40 | 41 | var artboards; 42 | 43 | if(context.command.identifier().hasSuffix("Page")) { 44 | artboards = context.document.currentPage().artboards(); 45 | } else { 46 | artboards = context.selection.valueForKeyPath("@distinctUnionOfObjects.parentArtboard"); 47 | } 48 | 49 | var shouldReset = context.command.identifier().hasPrefix("reset"); 50 | 51 | var loop = artboards.objectEnumerator(); 52 | var artboard; 53 | while(artboard = loop.nextObject()) { 54 | if(shouldReset) { 55 | if(artboard.name().hasPrefix(prefix)) { 56 | var artboardName = ""+artboard.name(); 57 | artboard.setName(artboardName.substr(prefix.length)); 58 | } 59 | } 60 | else { 61 | if(!artboard.name().hasPrefix(prefix)) { 62 | artboard.setName(prefix + "" + artboard.name()); 63 | } 64 | } 65 | } 66 | 67 | } 68 | 69 | var ignorePage = function(context) { 70 | 71 | var prefix = getPrefix(); 72 | 73 | var shouldReset = context.command.identifier().hasPrefix("reset"); 74 | var currentPage = context.document.currentPage(); 75 | if(shouldReset) { 76 | if(currentPage.name().hasPrefix(prefix)) { 77 | var pageName = ""+currentPage.name(); 78 | currentPage.setName(pageName.substr(prefix.length)); 79 | } 80 | } 81 | else { 82 | if(!currentPage.name().hasPrefix(prefix)) { 83 | currentPage.setName(prefix + "" + currentPage.name()); 84 | } 85 | } 86 | 87 | } 88 | --------------------------------------------------------------------------------