Add Gaia upload progress bar

This commit is contained in:
2021-01-01 17:32:41 +01:00
parent 7585d475a7
commit 17828fe9ce

View File

@@ -434,26 +434,57 @@ class Gaia {
static get URL() { return 'https://www.gaiagps.com'; } static get URL() { return 'https://www.gaiagps.com'; }
static get API() { return Gaia.URL+'/api/objects'; } static get API() { return Gaia.URL+'/api/objects'; }
constructor($InputFile, $InputButton) { constructor() {
this.asFiles = []; this.asFiles = [];
this.aoWaypoints = []; this.aoWaypoints = [];
this.aoTracks = []; this.aoTracks = [];
this.sFolderId = ''; this.sFolderId = '';
this.asFolder = {}; this.asFolder = {};
this.sFolderName = ''; this.sFolderName = '';
this.$Feedback = $('<div>', {'style':'position:fixed;width:100%;height:25%;bottom:0;background:white;z-index:10000;border-top:1px solid #CCC;box-sizing:border-box;font-size:1.2em;overflow:auto;padding:0 1em;'}); this.progress = {current:0, total:0};
this.$InputName = $('<input>', {'type':'text', 'name':'folder_name', 'placeholder':'Folder Name', 'style': 'border-width:2px; border-color:rgba(0, 0, 0, 0.1); border-radius:4px; font-family:Inter,Helvetica Neue,Helvetica,Arial; font-size:15px; padding:8px 12px; margin-bottom:12px;'}); }
/* FIXME: adapts on GaiaGPS upgrade */
setLayout() {
let $InputButton = $('a[href="https://help.gaiagps.com/hc/en-us/articles/360052763513"]').parent().find('button');
//If the button is found (=displayed)
if($InputButton.length > 0) {
this.$InputBox = $InputButton.parent(); this.$InputBox = $InputButton.parent();
//Reboot object to remove events //Add Feedback box
this.$InputFile = $InputFile.clone().insertAfter($InputFile); this.$Feedback = ($('#ggu-feedback').length > 0)?$('#ggu-feedback'):($('<div>', {
'id':'ggu-feedback',
'style':'width:calc(100% + 64px); height:400px; margin:1em 0 0 -32px; display:inline-block; text-align:left; overflow:auto;'
}).insertAfter($InputButton));
//Add Folder Name Input next to button
this.$InputName = ($('#ggu-inputname').length > 0)?$('#ggu-inputname'):($('<input>', {
'type':'text',
'id': 'ggu-inputname',
'name':'ggu-inputname',
'placeholder':'Folder Name',
'style': 'border-width:2px; border-color:rgba(0, 0, 0, 0.1); border-radius:4px; font-family:Inter,Helvetica Neue,Helvetica,Arial; font-size:15px; padding:8px 12px; margin-bottom:12px;'
}).val('PCT').prependTo(this.$InputBox));
//Reset File Input
let $InputFile = $('input[type=file]');
this.$InputFile = $InputFile.clone()
.insertAfter($InputFile)
.attr('multiple', 'multiple')
.attr('name', 'files[]')
.change(() => { this.readInputFiles(); });
$InputFile.remove(); $InputFile.remove();
this.$InputButton = $InputButton.clone().insertAfter($InputButton); //Reset button
this.$InputButton = $InputButton.clone()
.insertAfter($InputButton)
.click(() => {this.$InputFile.click();});
$InputButton.remove(); $InputButton.remove();
this.setLayout(); //Clear all upload notifications
this.resetNotif();
}
} }
feedback(sType, sMsg) { feedback(sType, sMsg) {
@@ -464,32 +495,45 @@ class Gaia {
switch(sType) { switch(sType) {
case 'error': sColor = 'red'; break; case 'error': sColor = 'red'; break;
case 'warning': sColor = 'orange'; break; case 'warning': sColor = 'orange'; break;
case 'info': sColor = 'green'; break; case 'info': sColor = '#2D5E38'; break;
} }
this.$Feedback.append($('<p>', {'style': 'color: '+sColor+';'}).text(sFormattedMsg)); this.$Feedback.append($('<p>', {'style': 'color: '+sColor+';'}).text(sFormattedMsg));
this.$Feedback.scrollTop(this.$Feedback.prop("scrollHeight")); this.$Feedback.scrollTop(this.$Feedback.prop("scrollHeight"));
} }
//Modify Gaia DOM Interface incProgress() {
setLayout() { if(!this.progress.current) {
//Add Feedback box this.progress.$Done = $('<div>', {'style':'overflow:hidden; background:#2D5E38; color: white; text-align:right;'});
this.$Feedback.appendTo($('body')); this.progress.$Left = $('<div>', {'style':'overflow:hidden; background:white; color: #2D5E38; text-align:left;'});
this.progress.$Box = $('<div>', {'id':'ggu-progress', 'style':'margin-top:1em;'})
.append($('<div>', {'style':'display:flex; width:calc(100% + 64px); margin-left:-32px; border-radius:3px; border: 1px solid #2D5E38; box-sizing: border-box;'})
.append(this.progress.$Done)
.append(this.progress.$Left)
);
this.$Feedback.before(this.progress.$Box);
}
//Add Event on button this.progress.current++;
this.$InputButton.click(() => {this.$InputFile.click();});
//Set event on file selection if(this.progress.current < this.progress.total) {
this.$InputFile let iRatio = Math.round(this.progress.current / this.progress.total * 100);
.attr('multiple', 'multiple') let sTextDone = '', sTextLeft = '';
.attr('name', 'files[]') if(iRatio < 50) {
.change(() => {this.readInputFiles();}); sTextDone = '';
sTextLeft = '&nbsp;'+iRatio+'% ('+this.progress.current+' / '+this.progress.total+')';
//Set default Name }
this.$InputName.val('PCT').prependTo(this.$InputBox); else {
sTextDone = '('+this.progress.current+' / '+this.progress.total+') '+iRatio+'%&nbsp;';
//Clear all upload notifications sTextLeft = '';
this.resetNotif(); }
this.progress.$Done.css('flex', iRatio+' 1 0%').html(sTextDone);
this.progress.$Left.css('flex', (100 - iRatio)+' 1 0%').html(sTextLeft);
}
else {
this.progress.$Box.remove();
this.progress = {current:0, total:0};
}
} }
//Marking all upload notifications as read //Marking all upload notifications as read
@@ -524,7 +568,10 @@ class Gaia {
iCount++; iCount++;
this.feedback('info', 'Reading file "'+oFileReader.name+'" ('+iCount+'/'+this.asFiles.length+')'); this.feedback('info', 'Reading file "'+oFileReader.name+'" ('+iCount+'/'+this.asFiles.length+')');
this.parseFile(oFileReader.name, asResult.target.result); this.parseFile(oFileReader.name, asResult.target.result);
if(iCount == this.asFiles.length) this.createFolder(); if(iCount == this.asFiles.length) {
this.progress.total = this.aoTracks.length + this.aoWaypoints.length + 2; //+1: Create forlder +1: Assign objects to folder
this.createFolder();
}
}; };
})(this.asFiles[i]); })(this.asFiles[i]);
aoReaders[i].readAsText(this.asFiles[i]); aoReaders[i].readAsText(this.asFiles[i]);
@@ -581,21 +628,21 @@ class Gaia {
this.asFolder = asFolder; this.asFolder = asFolder;
this.sFolderId = asFolder.id; this.sFolderId = asFolder.id;
this.sFolderName = asFolder.properties.name; this.sFolderName = asFolder.properties.name;
this.incProgress();
this.uploadTrack(); this.uploadTrack();
}).fail(() => {
this.feedback('error', 'Folder "'+this.sFolderName+'" could not be created');
}); });
}); });
} }
//Build & Upload Track File //Build & Upload Track File
uploadTrack(iIndex, bSecondTry) { uploadTrack(iIndex) {
iIndex = iIndex || 0; iIndex = iIndex || 0;
bSecondTry = bSecondTry || false;
if(iIndex == 0) this.feedback('info', 'Uploading tracks...'); if(iIndex == 0) this.feedback('info', 'Uploading tracks...');
if(iIndex < this.aoTracks.length) { let aoTrack = this.aoTracks[iIndex];
let aoTrack = this.aoTracks[i];
this.feedback('info', 'Uploading track "'+aoTrack.name+'"'); this.feedback('info', 'Uploading track "'+aoTrack.name+'"');
//Set color //Set color
@@ -645,30 +692,39 @@ class Gaia {
url: Gaia.API+'/track/', url: Gaia.API+'/track/',
contentType: 'application/json', contentType: 'application/json',
data: sPostedData, data: sPostedData,
postedData: sPostedData,
trackName: aoTrack.name trackName: aoTrack.name
}).done(function(asTrack) { }).done(function(asTrack) {
self.aoTracks[iIndex] = asTrack; self.aoTracks[iIndex] = asTrack;
self.confirmTrack(iIndex, asTrack, this.data);
}).fail(function() {
self.feedback('error', 'Track "'+this.trackName+'" upload failed (stage 1). Retrying...');
self.uploadTrack(iIndex);
});
}
confirmTrack(iIndex, asTrack, sPostedData) {
iIndex = iIndex || 0;
var self = this;
$.ajax({ $.ajax({
url: Gaia.API+'/track/'+asTrack.features[0].id+'/', url: Gaia.API+'/track/'+asTrack.features[0].id+'/',
type: 'PUT', type: 'PUT',
contentType: 'application/json', contentType: 'application/json',
data: this.postedData, data: sPostedData,
trackName: this.trackName trackName: asTrack.features[0].properties.title
}).done(function() { }).done(function() {
self.feedback('info', 'Track "'+this.trackName+'" uploaded'); self.feedback('info', 'Track "'+this.trackName+'" uploaded');
self.uploadTrack(++iIndex); self.incProgress();
}).fail(function() { iIndex++;
self.feedback('error', 'Track "'+this.trackName+'" failed to upload. Retrying...'); if(iIndex < self.aoTracks.length) self.uploadTrack(iIndex);
self.uploadTrack(iIndex, true);
});
});
}
else { else {
self.feedback('info', 'All tracks uploaded'); self.feedback('info', 'All tracks uploaded');
self.uploadWayPoints(); self.uploadWayPoints();
} }
}).fail(function() {
self.feedback('error', 'Track "'+this.trackName+'" upload failed (stage 2). Retrying...');
self.confirmTrack(iIndex, asTrack, sPostedData);
});
} }
/* /*
@@ -694,12 +750,10 @@ class Gaia {
} }
*/ */
uploadWayPoints(iIndex, bSecondTry) { uploadWayPoints(iIndex) {
iIndex = iIndex || 0; iIndex = iIndex || 0;
bSecondTry = bSecondTry || false;
//Upload waypoints //Upload waypoints
if(iIndex < this.aoWaypoints.length) {
var sWaypointName = this.aoWaypoints[iIndex].name; var sWaypointName = this.aoWaypoints[iIndex].name;
this.feedback('info', 'Uploading waypoint '+(iIndex + 1)+'/'+this.aoWaypoints.length+' ('+sWaypointName+')'); this.feedback('info', 'Uploading waypoint '+(iIndex + 1)+'/'+this.aoWaypoints.length+' ('+sWaypointName+')');
@@ -735,28 +789,31 @@ class Gaia {
$.post({ $.post({
url: Gaia.API+'/waypoint/', url: Gaia.API+'/waypoint/',
contentType: 'application/json', contentType: 'application/json',
data: sData, data: sData
postedData: sData
}).done(function(asWaypoint) { }).done(function(asWaypoint) {
//Update local waypoint with all server info (including ID)
self.aoWaypoints[iIndex] = asWaypoint; self.aoWaypoints[iIndex] = asWaypoint;
self.confirmWayPoint(iIndex, asWaypoint, this.data);
}).fail(function(){
self.feedback('error', 'Failed to upload waypoint #'+(iIndex + 1)+' "'+sWaypointName+'" (Stage 1). Trying again...');
self.uploadWayPoints(iIndex);
});
}
confirmWayPoint(iIndex, asWaypoint, sPostedData) {
$.ajax({ $.ajax({
url: Gaia.API+'/waypoint/'+asWaypoint.properties.id+'/', url: Gaia.API+'/waypoint/'+asWaypoint.properties.id+'/',
type: 'PUT', type: 'PUT',
contentType: 'application/json', contentType: 'application/json',
data: this.postedData data: sPostedData
}).always(() => { }).done(() => {
self.uploadWayPoints(++iIndex); iIndex++;
}); this.incProgress();
}).fail(function(){ if(iIndex < this.aoWaypoints.length) this.uploadWayPoints(iIndex);
self.feedback('error', 'Failed to upload waypoint #'+(iIndex + 1)+' ('+sWaypointName+'). Trying again...');
self.uploadWayPoints(iIndex, true);
});
}
//Done uploading, assigning waypoints & tracks to folder
else this.assignElementsToFolder(); else this.assignElementsToFolder();
}).fail(() => {
this.feedback('error', 'Failed to upload waypoint #'+(iIndex + 1)+' "'+asWaypoint.properties.title+'" (Stage 2). Trying again...');
this.confirmWayPoint(iIndex, asWaypoint, sPostedData);
});
} }
assignElementsToFolder() { assignElementsToFolder() {
@@ -784,9 +841,11 @@ class Gaia {
contentType: 'application/json', contentType: 'application/json',
data: JSON.stringify(asFolder) data: JSON.stringify(asFolder)
}).done(() => { }).done(() => {
this.incProgress();
this.feedback('info', 'Done'); this.feedback('info', 'Done');
}).fail(() => { }).fail(() => {
this.feedback('error', 'WFailed to assign waypoints & tracks to folder ID "'+asFolder.id+'"'); this.feedback('warning', 'Failed to assign waypoints & tracks to folder ID "'+asFolder.id+'". Retrying...');
this.assignElementsToFolder();
}); });
} }
@@ -826,9 +885,13 @@ class Gaia {
} }
console.log('Loading GaiaGps Uploader...'); console.log('Loading GaiaGps Uploader...');
let oGaia = new Gaia();
//To be adjusted regularly /* To be adjusted on Gaia's updates */
$FileInput = $('input[type=file]');
$FileButton = $('a[href="https://help.gaiagps.com/hc/en-us/articles/360052763513"]').parent().find('button');
let oGaia = new Gaia($FileInput, $FileButton); //Side panel
$('path[d="M5 4v2h14V4H5zm0 10h4v6h6v-6h4l-7-7-7 7z"]').parent().parent().on('click', () => {
setTimeout(() => {
oGaia.setLayout();
}, 500);
});