diff --git a/browser/src/control/Control.DownloadProgress.js b/browser/src/control/Control.DownloadProgress.js index d6fca618d..943aed61e 100644 --- a/browser/src/control/Control.DownloadProgress.js +++ b/browser/src/control/Control.DownloadProgress.js @@ -5,65 +5,18 @@ /* global _ $ */ L.Control.DownloadProgress = L.Control.extend({ options: { - position: 'bottomright' + snackbarTimeout: 20000 }, initialize: function (options) { L.setOptions(this, options); }, - onAdd: function () { - this._initLayout(); - return this._container; - }, - - // we really don't want mouse and other events propagating - // to the parent map - since they affect the context. - _ignoreEvents: function(elem) { - L.DomEvent.on(elem, 'mousedown mouseup mouseover mouseout mousemove', - function(e) { - L.DomEvent.stopPropagation(e); - return false; - }, this); - }, - - _initLayout: function () { - this._container = L.DomUtil.create('div', 'leaflet-control-layers'); - this._container.style.visibility = 'hidden'; - this._ignoreEvents(this._container); - - var closeButton = L.DomUtil.create('a', 'leaflet-popup-close-button download-popup', this._container); - closeButton.href = '#close'; - closeButton.innerHTML = '×'; - L.DomEvent.on(closeButton, 'click', this._onClose, this); - - var wrapper = L.DomUtil.create('div', 'leaflet-popup-content-wrapper', this._container); - var content = this._content = L.DomUtil.create('div', 'leaflet-popup-content', wrapper); - content.style.width = '100px'; - - // start download button - var startDownload = this._downloadButton = document.createElement('a'); - startDownload.href = '#start'; - startDownload.innerHTML = _('Start download'); - startDownload.style.font = '13px/11px Tahoma, Verdana, sans-serif'; - startDownload.style.alignment = 'center'; - startDownload.style.height = 20 + 'px'; - L.DomEvent.on(startDownload, 'click', this._onStartDownload, this); - - // download progress bar - this._progress = L.DomUtil.create('div', 'leaflet-paste-progress', null); - this._bar = L.DomUtil.create('span', '', this._progress); - this._value = L.DomUtil.create('span', '', this._bar); - L.DomUtil.setStyle(this._value, 'line-height', '14px'); - - // confirm button - var confirmCopy = this._confirmPasteButton = document.createElement('a'); - confirmCopy.href = '#complete'; - confirmCopy.innerHTML = _('Confirm copy to clipboard'); - confirmCopy.style.font = '13px/11px Tahoma, Verdana, sans-serif'; - confirmCopy.style.alignment = 'center'; - confirmCopy.style.height = 20 + 'px'; - L.DomEvent.on(confirmCopy, 'click', this._onConfirmCopyAction, this); + onAdd: function (map) { + this._map = map; + this._started = false; + this._complete = false; + this._closed = false; }, show: function () { @@ -73,8 +26,11 @@ L.Control.DownloadProgress = L.Control.extend({ this._started = false; this._complete = false; this._closed = false; - this._content.appendChild(this._downloadButton); - this._container.style.visibility = ''; + + var msg = _('Start download') + ' (Alt + C)'; // TODO: on Mac Alt == Option + this._map.uiManager.showSnackbar( + _('To copy outside, you have to download the content'), + msg, this._onStartDownload.bind(this), this.options.snackbarTimeout); }, isClosed: function () { @@ -88,11 +44,11 @@ L.Control.DownloadProgress = L.Control.extend({ currentStatus: function () { if (this._closed) return 'closed'; - if (this._content.contains(this._downloadButton)) + if (!this._started && !this._complete) return 'downloadButton'; - if (this._content.contains(this._progress)) + if (this._started) return 'progress'; - if (this._content.contains(this._confirmPasteButton)) + if (this._complete) return 'confirmPasteButton'; }, @@ -102,8 +58,7 @@ L.Control.DownloadProgress = L.Control.extend({ }, setValue: function (value) { - this._bar.style.width = Math.round(value) + '%'; - this._value.innerHTML = Math.round(value) + '%'; + this._map.uiManager.setSnackbarProgress(Math.round(value)); }, _setProgressCursor: function() { @@ -117,9 +72,9 @@ L.Control.DownloadProgress = L.Control.extend({ startProgressMode: function() { this._setProgressCursor(); this._started = true; + this._map.uiManager.showProgressBar( + 'Downloading clipboard content', 'Cancel', this._onClose.bind(this)); this.setValue(0); - this._content.removeChild(this._downloadButton); - this._content.appendChild(this._progress); }, _onStartDownload: function () { @@ -143,10 +98,12 @@ L.Control.DownloadProgress = L.Control.extend({ return; this._setNormalCursor(); this._complete = true; - if (this._content.contains(this._progress)) - this._content.removeChild(this._progress); - this._content.style.width = '150px'; - this._content.appendChild(this._confirmPasteButton); + this._started = false; + + var msg = _('Confirm copy to clipboard'); + // TODO: on Mac Alt == Option + this._map.uiManager.showSnackbar(msg, _('Confirm') + ' (Alt + C)', + this._onConfirmCopyAction.bind(this), this.options.snackbarTimeout); }, _onConfirmCopyAction: function () { @@ -155,16 +112,17 @@ L.Control.DownloadProgress = L.Control.extend({ }, _onClose: function () { + if (this._userAlreadyWarned()) + this._map.uiManager.closeSnackbar(); + + this._started = false; + this._complete = false; + this._closed = true; + this._setNormalCursor(); this._cancelDownload(); - if (this._content.contains(this._confirmPasteButton)) - this._content.removeChild(this._confirmPasteButton); - if (this._content.contains(this._progress)) - this._content.removeChild(this._progress); if (this._map) this._map.focus(); - this.remove(); - this._closed = true; }, _download: function () { @@ -186,7 +144,12 @@ L.Control.DownloadProgress = L.Control.extend({ // TODO: failure to parse ? ... reader.readAsText(response); }, - function(progress) { return progress/2; } + function(progress) { return progress/2; }, + function () { + that._onClose(); + that._map.uiManager.showSnackbar( + _('Download failed'), '', null,this.options.snackbarTimeout); + } ); }, diff --git a/browser/src/control/Control.UIManager.js b/browser/src/control/Control.UIManager.js index 2b951ebb3..b7a335325 100644 --- a/browser/src/control/Control.UIManager.js +++ b/browser/src/control/Control.UIManager.js @@ -917,18 +917,16 @@ L.Control.UIManager = L.Control.extend({ // Snack bar + closeSnackbar: function() { + var closeMessage = { id: 'snackbar', jsontype: 'dialog', type: 'snackbar', action: 'close' }; + app.socket._onMessage({ textMsg: 'jsdialog: ' + JSON.stringify(closeMessage) }); + }, + showSnackbar: function(label, action, callback, timeout, hasProgress) { if (!app.socket) return; - var closeJson = { - id: 'snackbar', - jsontype: 'dialog', - type: 'snackbar', - action: 'fadeout' - }; - - app.socket._onMessage({textMsg: 'jsdialog: ' + JSON.stringify(closeJson)}); + this.closeSnackbar(); var json = { id: 'snackbar', @@ -948,6 +946,7 @@ L.Control.UIManager = L.Control.extend({ ] }; + var that = this; var builderCallback = function(objectType, eventType, object, data) { window.app.console.debug('control: \'' + objectType + '\' id:\'' + object.id + '\' event: \'' + eventType + '\' state: \'' + data + '\''); @@ -955,8 +954,7 @@ L.Control.UIManager = L.Control.extend({ if (callback) callback(); - var closeMessage = { id: 'snackbar', jsontype: 'dialog', type: 'snackbar', action: 'close' }; - app.socket._onMessage({ textMsg: 'jsdialog: ' + JSON.stringify(closeMessage) }); + that.closeSnackbar(); } }; diff --git a/browser/src/map/Clipboard.js b/browser/src/map/Clipboard.js index bd6a84016..0ec1e6808 100644 --- a/browser/src/map/Clipboard.js +++ b/browser/src/map/Clipboard.js @@ -207,7 +207,7 @@ L.Clipboard = L.Class.extend({ var request = new XMLHttpRequest(); // avoid to invoke the following code if the download widget depends on user interaction - if (!that._downloadProgress || !that._downloadProgress.isVisible()) { + if (!that._downloadProgress || that._downloadProgress.isClosed()) { that._startProgress(); that._downloadProgress.startProgressMode(); } @@ -802,33 +802,31 @@ L.Clipboard = L.Class.extend({ _startProgress: function() { if (!this._downloadProgress) { this._downloadProgress = L.control.downloadProgress(); - } - if (!this._downloadProgress.isVisible()) { - this._downloadProgress.addTo(this._map); + this._map.addControl(this._downloadProgress); } this._downloadProgress.show(); }, _onDownloadOnLargeCopyPaste: function () { - if (!this._downloadProgress || this._downloadProgress.isClosed()) { - this._warnFirstLargeCopyPaste(); - this._startProgress(); - } - else if (this._downloadProgress.isStarted()) { + if (this._downloadProgress && this._downloadProgress.isStarted()) { // Need to show this only when a download is really in progress and we block it. // Otherwise, it's easier to flash the widget or something. this._warnLargeCopyPasteAlreadyStarted(); } + else { + this._warnFirstLargeCopyPaste(); + this._startProgress(); + } }, _downloadProgressStatus: function() { - if (this._downloadProgress && this._downloadProgress.isVisible()) + if (this._downloadProgress) return this._downloadProgress.currentStatus(); }, // Download button is still shown after selection changed -> user has changed their mind... _scheduleHideDownload: function(s) { - if (!this._downloadProgress || !this._downloadProgress.isVisible()) + if (!this._downloadProgress || this._downloadProgress.isClosed()) return; // If no other copy/paste things occurred then ... @@ -847,9 +845,7 @@ L.Clipboard = L.Class.extend({ clearTimeout(this._hideDownloadTimer); this._hideDownloadTimer = null; - if (!this._downloadProgress || - !this._downloadProgress.isVisible() || - this._downloadProgress.isClosed()) + if (!this._downloadProgress || this._downloadProgress.isClosed()) return; this._downloadProgress._onClose(); },