clipboard: use snackbar for interaction with user
Instead of leaflet popup we use now snackbar. - control is not removed and added again for next copy-paste but we keep single instance for all the time - added download error message - simplified close snackbar code Signed-off-by: Szymon Kłos <szymon.klos@collabora.com> Change-Id: I804a82c4f589b029a42fc2800958ff2b46b7df50
This commit is contained in:
parent
585e00a1ee
commit
689c6fa063
3 changed files with 54 additions and 97 deletions
|
@ -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);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue