From 0ced992b3bc3285d8043c96c62b5b2516aec2ed9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 1 May 2018 15:24:46 +0200 Subject: [PATCH 1/2] use access token to publish to gist --- package.json | 1 + src/app/panels/file-panel.js | 31 ++++++++++++---------- src/app/tabs/settings-tab.js | 21 +++++++++++++-- src/app/tabs/styles/settings-tab-styles.js | 3 +++ 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 21a2a0ac29..f32c8a452d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "exorcist": "^0.4.0", "fast-async": "6.3.1", "fast-levenshtein": "^2.0.6", + "gists": "^1.0.1", "javascript-serialize": "^1.6.1", "jquery": "^3.3.1", "js-base64": "^2.1.9", diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js index 371c435380..3ac3b56b48 100644 --- a/src/app/panels/file-panel.js +++ b/src/app/panels/file-panel.js @@ -2,8 +2,8 @@ var async = require('async') var $ = require('jquery') var yo = require('yo-yo') -var minixhr = require('minixhr') // simple and small cross-browser XMLHttpRequest (XHR) var remixLib = require('remix-lib') +var Gists = require('gists') var EventManager = remixLib.EventManager var FileExplorer = require('../files/file-explorer') var modalDialog = require('../ui/modaldialog') @@ -274,18 +274,16 @@ function filepanel (appAPI, filesProvider) { // ------------------ gist publish -------------- function publishToGist (fileProviderName) { - function cb (data) { - if (data instanceof Error) { - console.log('fail', data.message) - modalDialogCustom.alert('Failed to create gist: ' + (data || 'Unknown transport error')) + function cb (error, data) { + if (error) { + modalDialogCustom.alert('Failed to create gist: ' + error) } else { - data = JSON.parse(data) if (data.html_url) { modalDialogCustom.confirm(null, `Created a gist at ${data.html_url}. Would you like to open it in a new window?`, () => { window.open(data.html_url, '_blank') }) } else { - modalDialogCustom.alert(data.message + ' ' + data.documentation_url) + modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) } } } @@ -296,17 +294,22 @@ function filepanel (appAPI, filesProvider) { console.log(error) modalDialogCustom.alert('Failed to create gist: ' + error) } else { - var description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&gist=' - console.log(packaged) - minixhr({ - url: 'https://api.github.com/gists', - method: 'POST', - data: JSON.stringify({ + var tokenAccess = appAPI.config.get('settings/gist-access-token') + if (!tokenAccess) { + modalDialogCustom.alert('Remix requires an access token (which includes gists creation permission). Please go to the settings tab for more information.') + } else { + var description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&gist=' + var gists = new Gists({ + token: tokenAccess + }) + gists.create({ description: description, public: true, files: packaged + }, (error, result) => { + cb(error, result) }) - }, cb) + } } }) } diff --git a/src/app/tabs/settings-tab.js b/src/app/tabs/settings-tab.js index be0a0468f4..8b3bd1fbf3 100644 --- a/src/app/tabs/settings-tab.js +++ b/src/app/tabs/settings-tab.js @@ -9,6 +9,7 @@ var styleGuide = require('../ui/styles-guide/theme-chooser') var helper = require('../../lib/helper') var modal = require('../ui/modal-dialog-custom') var tooltip = require('../ui/tooltip') +var copyToClipboard = require('../ui/copy-to-clipboard') var css = require('./styles/settings-tab-styles') @@ -24,6 +25,13 @@ function SettingsTab (appAPI = {}, appEvents = {}, opts = {}) { Remix never persist any passphrase.` var warnPersonalMode = yo`` + // Gist settings + var gistAccessToken = yo`` + var token = appAPI.config.get('settings/gist-access-token') + if (token) gistAccessToken.value = token + var gistAddToken = yo` { appAPI.config.set('settings/gist-access-token', gistAccessToken.value); tooltip('Access token saved') }} value="Save" type="button">` + var gistRemoveToken = yo` { gistAccessToken.value = ''; appAPI.config.set('settings/gist-access-token', ''); tooltip('Access token removed') }} value="Remove" type="button">` + var el = yo`
@@ -48,8 +56,17 @@ function SettingsTab (appAPI = {}, appEvents = {}, opts = {}) { Enable Optimization
-
${personal}>
- Enable Personal Mode ${warnPersonalMode}> +
${personal}
+ Enable Personal Mode ${warnPersonalMode} +
+
+
+
Gist Access Token
+
Manage the access token used to publish to Gist.
+
Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only 'create gist' permission.
+ +
+
${gistAccessToken}${copyToClipboard(() => appAPI.config.get('settings/gist-access-token'))}${gistAddToken}${gistRemoveToken}
diff --git a/src/app/tabs/styles/settings-tab-styles.js b/src/app/tabs/styles/settings-tab-styles.js index 83a80fd07c..cb000b14fd 100644 --- a/src/app/tabs/styles/settings-tab-styles.js +++ b/src/app/tabs/styles/settings-tab-styles.js @@ -74,6 +74,9 @@ var css = csjs` border-radius: 2px; margin-left: 5px; } + .savegisttoken { + margin-left: 5px; + } } ` From c953633b2ab33e67532c291a2eecdd7325e73606 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 1 May 2018 16:10:00 +0200 Subject: [PATCH 2/2] Save the current gist instead of creating a new one over and over --- src/app.js | 7 ++- src/app/panels/file-panel.js | 82 +++++++++++++++++++++++------------- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/app.js b/src/app.js index 1d948b6c35..ffe04d296a 100644 --- a/src/app.js +++ b/src/app.js @@ -556,7 +556,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }) // Add files received from remote instance (i.e. another remix-ide) - function loadFiles (filesSet, fileProvider) { + function loadFiles (filesSet, fileProvider, callback) { if (!fileProvider) fileProvider = 'browser' async.each(Object.keys(filesSet), (file, callback) => { @@ -573,6 +573,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }) }, (error) => { if (!error) fileManager.switchFile() + if (callback) callback(error) }) } @@ -597,7 +598,9 @@ Please make a backup of your contracts and start using http://remix.ethereum.org modalDialogCustom.alert(`Gist load error: ${error || data.message}`) return } - loadFiles(data.files, 'gist') + loadFiles(data.files, 'gist', (errorLoadingFile) => { + if (!errorLoadingFile) filesProviders['gist'].id = gistId + }) }) }) } diff --git a/src/app/panels/file-panel.js b/src/app/panels/file-panel.js index 3ac3b56b48..cea4250d9a 100644 --- a/src/app/panels/file-panel.js +++ b/src/app/panels/file-panel.js @@ -8,6 +8,7 @@ var EventManager = remixLib.EventManager var FileExplorer = require('../files/file-explorer') var modalDialog = require('../ui/modaldialog') var modalDialogCustom = require('../ui/modal-dialog-custom') +var tooltip = require('../ui/tooltip') var QueryParams = require('../../lib/query-params') var queryParams = new QueryParams() var helper = require('../../lib/helper') @@ -80,10 +81,10 @@ function filepanel (appAPI, filesProvider) { ` : ''} - publishToGist('browser')}> + publishToGist('browser')}> - publishToGist('gist')}> + updateGist()}> @@ -273,35 +274,47 @@ function filepanel (appAPI, filesProvider) { // ------------------ gist publish -------------- + function updateGist () { + var gistId = filesProvider['gist'].id + if (!gistId) { + tooltip('no gist content is currently loaded.') + } else { + toGist('gist', gistId) + } + } + function publishToGist (fileProviderName) { - function cb (error, data) { + modalDialogCustom.confirm(null, 'Are you very sure you want to publish all your files anonymously as a public gist on github.com?', () => { + toGist(fileProviderName) + }) + } + + function toGist (fileProviderName, id) { + packageFiles(filesProvider[fileProviderName], (error, packaged) => { if (error) { + console.log(error) modalDialogCustom.alert('Failed to create gist: ' + error) } else { - if (data.html_url) { - modalDialogCustom.confirm(null, `Created a gist at ${data.html_url}. Would you like to open it in a new window?`, () => { - window.open(data.html_url, '_blank') - }) + var tokenAccess = appAPI.config.get('settings/gist-access-token') + if (!tokenAccess) { + modalDialogCustom.alert('Remix requires an access token (which includes gists creation permission). Please go to the settings tab for more information.') } else { - modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) - } - } - } - - function toGist () { - packageFiles(filesProvider[fileProviderName], (error, packaged) => { - if (error) { - console.log(error) - modalDialogCustom.alert('Failed to create gist: ' + error) - } else { - var tokenAccess = appAPI.config.get('settings/gist-access-token') - if (!tokenAccess) { - modalDialogCustom.alert('Remix requires an access token (which includes gists creation permission). Please go to the settings tab for more information.') - } else { - var description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&gist=' - var gists = new Gists({ - token: tokenAccess + var description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&gist=' + var gists = new Gists({ + token: tokenAccess + }) + if (id) { + tooltip('Saving gist (' + id + ') ...') + gists.edit({ + description: description, + public: true, + files: packaged, + id: id + }, (error, result) => { + cb(error, result) }) + } else { + tooltip('Creating a new gist ...') gists.create({ description: description, public: true, @@ -311,13 +324,24 @@ function filepanel (appAPI, filesProvider) { }) } } - }) - } - modalDialogCustom.confirm(null, 'Are you very sure you want to publish all your files anonymously as a public gist on github.com?', () => { - toGist() + } }) } + function cb (error, data) { + if (error) { + modalDialogCustom.alert('Failed to manage gist: ' + error) + } else { + if (data.html_url) { + modalDialogCustom.confirm(null, `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => { + window.open(data.html_url, '_blank') + }) + } else { + modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) + } + } + } + // ------------------ copy files -------------- function copyFiles () {