diff --git a/js/config.js b/js/config.js index ff8f2be2..e6660bd0 100644 --- a/js/config.js +++ b/js/config.js @@ -4,7 +4,8 @@ var GOOGLE_API_KEY = "AIzaSyAeCU8CGcSkn0z9js6iocHuPBX4f_mMWkw"; var GOOGLE_SCOPES = [ "https://www.googleapis.com/auth/drive.install", "https://www.googleapis.com/auth/drive", - "https://www.googleapis.com/auth/blogger" + "https://www.googleapis.com/auth/blogger", + "https://picasaweb.google.com/data/" ]; var GOOGLE_DRIVE_APP_ID = "241271498917"; var DROPBOX_APP_KEY = "lq6mwopab8wskas"; @@ -19,9 +20,11 @@ var ASYNC_TASK_LONG_TIMEOUT = 180000; var SYNC_PERIOD = 180000; var USER_IDLE_THRESHOLD = 300000; var IMPORT_FILE_MAX_CONTENT_SIZE = 100000; +var IMPORT_IMG_MAX_CONTENT_SIZE = 10000000; var TEMPORARY_FILE_INDEX = "file.tempIndex"; var WELCOME_DOCUMENT_TITLE = "Welcome document"; var DOWNLOAD_PROXY_URL = "http://stackedit-download-proxy.herokuapp.com/"; +var PICASA_PROXY_URL = "http://stackedit-picasa-proxy.herokuapp.com/"; var WORDPRESS_CLIENT_ID = '3185'; var WORDPRESS_PROXY_URL = "http://stackedit-wordpress-proxy.herokuapp.com/"; var SSH_PROXY_URL = "http://stackedit-ssh-proxy.herokuapp.com/"; diff --git a/js/core.js b/js/core.js index 6f11e0f0..474dc332 100644 --- a/js/core.js +++ b/js/core.js @@ -260,6 +260,9 @@ define([ // Custom insert image dialog editor.hooks.set("insertImageDialog", function(callback) { core.insertLinkCallback = callback; + if(core.catchModal) { + return true; + } utils.resetModalInputs(); $("#modal-insert-image").modal(); return true; diff --git a/js/helpers/googleHelper.js b/js/helpers/googleHelper.js index a7d3041e..524c36ed 100644 --- a/js/helpers/googleHelper.js +++ b/js/helpers/googleHelper.js @@ -24,11 +24,13 @@ define([ return; } delayedFunction = function() { - connected = true; - task.chain(); + gapi.load("client,drive-realtime", function() { + connected = true; + task.chain(); + }); }; $.ajax({ - url: "https://apis.google.com/js/client.js?onload=runDelayedFunction", + url: "https://apis.google.com/js/api.js?onload=runDelayedFunction", dataType: "script", timeout: AJAX_TIMEOUT }).fail(function(jqXHR) { @@ -124,7 +126,19 @@ define([ // } var base64Data = utils.encodeBase64(content); - var multipartRequestBody = delimiter + 'Content-Type: application/json\r\n\r\n' + JSON.stringify(metadata) + delimiter + 'Content-Type: ' + contentType + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + base64Data + close_delim; + var multipartRequestBody = [ + delimiter, + 'Content-Type: application/json\r\n\r\n', + JSON.stringify(metadata), + delimiter, + 'Content-Type: ', + contentType, + '\r\n', + 'Content-Transfer-Encoding: base64\r\n', + '\r\n', + base64Data, + close_delim + ].join(""); var request = gapi.client.request({ 'path': path, @@ -167,6 +181,52 @@ define([ task.enqueue(); }; + googleHelper.uploadImg = function(name, content, albumId, callback) { + var result = undefined; + var task = new AsyncTask(); + connect(task); + authenticate(task); + task.onRun(function() { + var headers = { + "Content-Type": "image/jpeg", + "Slug": name + }; + var token = gapi.auth.getToken(); + if(token) { + headers.Authorization = "Bearer " + token.access_token; + } + + $.ajax({ + url: PICASA_PROXY_URL + "upload/" + albumId, + headers: headers, + data: content, + processData: false, + dataType: "xml", + timeout: AJAX_TIMEOUT, + type: "POST" + }).done(function(data, textStatus, jqXHR) { + result = data; + task.chain(); + }).fail(function(jqXHR) { + var error = { + code: jqXHR.status, + message: jqXHR.statusText + }; + if(error.code == 200) { + error.message = jqXHR.responseText; + } + handleError(error, task); + }); + }); + task.onSuccess(function() { + callback(undefined, result); + }); + task.onError(function(error) { + callback(error); + }); + task.enqueue(); + }; + googleHelper.checkChanges = function(lastChangeId, callback) { var changes = []; var newChangeId = lastChangeId || 0; diff --git a/js/mediaImporter.js b/js/mediaImporter.js index 2b9c77a2..11d2ccec 100644 --- a/js/mediaImporter.js +++ b/js/mediaImporter.js @@ -3,8 +3,9 @@ define([ "underscore", "classes/Provider", "core", + "extensionMgr", "providers/gplusProvider" -], function($, _, Provider, core) { +], function($, _, Provider, core, extensionMgr) { var mediaImporter = {}; @@ -33,6 +34,57 @@ define([ }); }); }); + + function handleImgImport(evt) { + evt.stopPropagation(); + evt.preventDefault(); + var files = (evt.dataTransfer || evt.target).files; + var file = _.first(files); + if(file.name.match(/.(jpe?g|png|gif|bmp)$/)) { + var reader = new FileReader(); + reader.onload = (function(importedFile) { + return function(e) { + var content = new Uint8Array(e.target.result); + providerMap["gplus"].uploadImage(file.name, content, function(error, imageLink) { + if(error) { + return; + } + // Generate an insertLinkCallback by clicking the + // pagedown button but without showing the dialog + core.catchModal = true; + $("#wmd-image-button").click(); + core.catchModal = false; + // Take the insertLinkCallback from core module + var insertLinkCallback = core.insertLinkCallback; + // Unset it to be sure core module will not call it + core.insertLinkCallback = undefined; + insertLinkCallback(imageLink || null); + }); + + // var title = importedFile.name; + // var dotPosition = title.lastIndexOf("."); + // title = dotPosition !== -1 ? title.substring(0, + // dotPosition) : title; + // var fileDesc = fileMgr.createFile(title, content); + // fileMgr.selectFile(fileDesc); + }; + })(file); + var blob = file.slice(0, IMPORT_IMG_MAX_CONTENT_SIZE); + reader.readAsArrayBuffer(blob); + } + } + + function handleDragOver(evt) { + evt.stopPropagation(); + evt.preventDefault(); + evt.dataTransfer.dropEffect = 'copy'; + } + + $('#wmd-input').each(function() { + this.addEventListener('dragover', handleDragOver, false); + this.addEventListener('drop', handleImgImport, false); + }); + }); return mediaImporter; diff --git a/js/providers/gplusProvider.js b/js/providers/gplusProvider.js index 9be1640a..8483e73e 100644 --- a/js/providers/gplusProvider.js +++ b/js/providers/gplusProvider.js @@ -23,10 +23,28 @@ define([ }); return result; } - - var importImageCallback = undefined; + var imageDoc = undefined; var importImagePreferences = utils.retrieveIgnoreError(PROVIDER_GPLUS + ".importImagePreferences"); + function showImportImgDialog() { + if(!imageDoc.thumbnails) { + extensionMgr.onError("Image " + imageDoc.name + " is not accessible."); + callback(true); + return; + } + utils.resetModalInputs(); + $("#modal-import-image img").prop("src", getThumbnailUrl(imageDoc, 128)); + utils.setInputValue("#input-import-image-title", imageDoc.name); + + // Load preferences + if(importImagePreferences) { + utils.setInputValue("#input-import-image-size", importImagePreferences.size); + } + + $("#modal-import-image").modal(); + } + + var importImageCallback = undefined; gplusProvider.importImage = function(callback) { importImageCallback = callback; googleHelper.picker(function(error, docs) { @@ -35,22 +53,28 @@ define([ return; } imageDoc = docs[0]; - if(!imageDoc.thumbnails) { - extensionMgr.onError("Image " + imageDoc.title + " is not accessible."); - callback(true); + showImportImgDialog(); + }, true); + }; + + gplusProvider.uploadImage = function(imgName, imgContent, callback) { + importImageCallback = callback; + googleHelper.uploadImg(imgName, imgContent, "default", function(error, image) { + if(error || !image) { + callback(error); return; } - utils.resetModalInputs(); - $("#modal-import-image img").prop("src", getThumbnailUrl(imageDoc, 128)); - utils.setInputValue("#input-import-image-title", imageDoc.name); - - // Load preferences - if(importImagePreferences) { - utils.setInputValue("#input-import-image-size", importImagePreferences.size); - } - - $("#modal-import-image").modal(); - }, true); + imageDoc = { + name: imgName, + thumbnails: [] + }; + $(image).find("thumbnail").each(function() { + imageDoc.thumbnails.push({ + url: $(this).attr("url") + }); + }); + showImportImgDialog(); + }); }; core.onReady(function() {