|
@@ -1023,6 +1023,9 @@
|
|
focus: null
|
|
focus: null
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ //Upload related
|
|
|
|
+ let uploadFileChunkSize = 1024 * 512; //512KB per chunk in low memory upload
|
|
|
|
+
|
|
//Others
|
|
//Others
|
|
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
var daysNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
|
var daysNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
|
@@ -1030,15 +1033,17 @@
|
|
var userInfo = {};
|
|
var userInfo = {};
|
|
var hardwareman = false;
|
|
var hardwareman = false;
|
|
var downloadMode = false;
|
|
var downloadMode = false;
|
|
|
|
+ var lowMemoryMode = true;
|
|
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
-
|
|
|
|
|
|
+ var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
|
|
|
|
|
//Initiation functions
|
|
//Initiation functions
|
|
initDesktopTheme();
|
|
initDesktopTheme();
|
|
initDesktopHostInfo();
|
|
initDesktopHostInfo();
|
|
initDesktopUserInfo();
|
|
initDesktopUserInfo();
|
|
initBackgroundSwitchingAnimation();
|
|
initBackgroundSwitchingAnimation();
|
|
- //initDesktopFiles(); //Will be called in initDesktopIconPreference() -> refresh()
|
|
|
|
|
|
+ //Commented for debug purpose
|
|
|
|
+ initUploadMode();
|
|
initModuleList();
|
|
initModuleList();
|
|
initDesktopIconPreference()
|
|
initDesktopIconPreference()
|
|
initUserDefinedThemeColor();
|
|
initUserDefinedThemeColor();
|
|
@@ -2884,6 +2889,7 @@
|
|
let shortenedName = filename;
|
|
let shortenedName = filename;
|
|
screenX += iconOffsetXY[0];
|
|
screenX += iconOffsetXY[0];
|
|
screenY += iconOffsetXY[1];
|
|
screenY += iconOffsetXY[1];
|
|
|
|
+
|
|
if (isDir) {
|
|
if (isDir) {
|
|
//Folder objects
|
|
//Folder objects
|
|
icon = "folder outline";
|
|
icon = "folder outline";
|
|
@@ -3249,6 +3255,7 @@
|
|
let thisFilename = files[j].name;
|
|
let thisFilename = files[j].name;
|
|
let x = parseInt(locations[j][0]);
|
|
let x = parseInt(locations[j][0]);
|
|
let y = parseInt(locations[j][1]);
|
|
let y = parseInt(locations[j][1]);
|
|
|
|
+ let uploadIconUUID = generateUploadingIcon(thisFile.name, [x,y]);
|
|
uploadFile(thisFile,function(){
|
|
uploadFile(thisFile,function(){
|
|
console.log("Uploader callback");
|
|
console.log("Uploader callback");
|
|
$.ajax({
|
|
$.ajax({
|
|
@@ -3257,10 +3264,10 @@
|
|
data: {"set": thisFilename, "x": x, "y": y},
|
|
data: {"set": thisFilename, "x": x, "y": y},
|
|
success: function(data) {
|
|
success: function(data) {
|
|
//Refresh the desktop
|
|
//Refresh the desktop
|
|
- refresh(undefined, true);
|
|
|
|
|
|
+ refresh(undefined, false);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
- });
|
|
|
|
|
|
+ }, uploadIconUUID);
|
|
|
|
|
|
}
|
|
}
|
|
}else if (sourceFilelist.length > 0 && Array.isArray(sourceFilelist)){
|
|
}else if (sourceFilelist.length > 0 && Array.isArray(sourceFilelist)){
|
|
@@ -3683,6 +3690,7 @@
|
|
return targetLocation;
|
|
return targetLocation;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //Convert location to grid index
|
|
function getGridIndexFromLocation(x,y){
|
|
function getGridIndexFromLocation(x,y){
|
|
var gridIndex = [-1,-1];
|
|
var gridIndex = [-1,-1];
|
|
for (var i = 0; i < desktopGrids.length; i++){
|
|
for (var i = 0; i < desktopGrids.length; i++){
|
|
@@ -3702,6 +3710,38 @@
|
|
return gridIndex;
|
|
return gridIndex;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //Convert grid index to location
|
|
|
|
+ function getLocationFromGridIndex(x, y){
|
|
|
|
+ var location = [-1,-1];
|
|
|
|
+
|
|
|
|
+ //Calculate the usable grid on screen
|
|
|
|
+ var iheight = 106;
|
|
|
|
+ var iwidth = 70;
|
|
|
|
+ var padding = 16;
|
|
|
|
+ if (desktopIconSize == "small") {
|
|
|
|
+ iheight = 82;
|
|
|
|
+ iwidth = 50;
|
|
|
|
+ } else if (desktopIconSize == "medium") {
|
|
|
|
+ iheight = 106;
|
|
|
|
+ iwidth = 70;
|
|
|
|
+ } else if (desktopIconSize == "big") {
|
|
|
|
+ iheight = 124;
|
|
|
|
+ iwidth = 84;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var screenHeight = window.innerHeight;
|
|
|
|
+ var screenWidth = window.innerWidth;
|
|
|
|
+
|
|
|
|
+ var vc = Math.floor((screenHeight - 20 - padding) / iheight);
|
|
|
|
+ var hc = Math.floor((screenWidth - padding) / iwidth);
|
|
|
|
+
|
|
|
|
+ //Calculate the position of this icon on the grid
|
|
|
|
+ var resultX = padding + iwidth * x + iconOffsetXY[0];
|
|
|
|
+ var resultY = padding + iheight * y + iconOffsetXY[1];
|
|
|
|
+
|
|
|
|
+ return [resultX, resultY];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
//Set allow overshoot to allow drop point to get closest grid with x / y > cursor posx /y
|
|
//Set allow overshoot to allow drop point to get closest grid with x / y > cursor posx /y
|
|
function findClosestGrid(x, y, allowOvershoot = true) {
|
|
function findClosestGrid(x, y, allowOvershoot = true) {
|
|
@@ -5198,30 +5238,205 @@
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function uploadFile(file, callback=undefined) {
|
|
|
|
- let url = 'system/file_system/upload'
|
|
|
|
- let uploadCurrentPath = "user:/Desktop/";
|
|
|
|
- let formData = new FormData();
|
|
|
|
- let xhr = new XMLHttpRequest();
|
|
|
|
- formData.append('file', file);
|
|
|
|
- formData.append('path', uploadCurrentPath);
|
|
|
|
|
|
+ //Check if this server is a low memory one
|
|
|
|
+ function initUploadMode(){
|
|
|
|
+ $.ajax({
|
|
|
|
+ url: "system/info/getRAMinfo",
|
|
|
|
+ success: function(data){
|
|
|
|
+ if (data.error !== undefined){
|
|
|
|
+ //Permission denied or other reasons that cannot access harwdare info. Use default mode
|
|
|
|
+ lowMemoryMode = true;
|
|
|
|
+ }else{
|
|
|
|
+ //Check if ramsize > 1.8 GB (2GB). If yes, switch to large memory upload mode
|
|
|
|
+ var memsize = JSON.parse(data);
|
|
|
|
+ if (parseFloat(memsize)/ 1024 / 1024 / 1024 >= 3.8){
|
|
|
|
+ console.log("[Desktop] Setting upload mode to large memory mode")
|
|
|
|
+ lowMemoryMode = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ error: function(){
|
|
|
|
+ //Hardware mode disabled. Always use low memory upload mode instead
|
|
|
|
+ lowMemoryMode = true;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
- xhr.open('POST', url, true)
|
|
|
|
- xhr.upload.addEventListener("progress", function(e) {
|
|
|
|
- console.log((e.loaded * 100.0 / e.total) || 100)
|
|
|
|
- })
|
|
|
|
|
|
+ //Generate a loading icon for this upload task
|
|
|
|
+ function generateUploadingIcon(filename, position){
|
|
|
|
+ //Get position for appending
|
|
|
|
+ var onScreenLocation = getLocationFromGridIndex(position[0], position[1]);
|
|
|
|
+ //Append to UI
|
|
|
|
+ var uploadIconUUID = Date.now();
|
|
|
|
+ $("#iconwrapper").append(`<div href="javascript:void(0);" class="${uploadIconUUID} launchIcon" type="dummy" filename="${filename}" filepath="user:/Desktop/${filename}" style="width:70px; height:106px;left:${onScreenLocation[0]}px; top:${onScreenLocation[1]}px;">
|
|
|
|
+ <span class="launchIconWrapper">
|
|
|
|
+ <img class="launchIconImage medium" src="img/desktop/files_icon/${desktopIconPack}/file upload.png" draggable="false">
|
|
|
|
+ <p class="launchIconText ${desktopIconSize}" >Uploading</p>
|
|
|
|
+ <div class="ts tiny primary progress" style="margin-top: -4px;">
|
|
|
|
+ <div class="bar" style="min-width: 0px !important; width: 0%;"></div>
|
|
|
|
+ </div>
|
|
|
|
+ </span>
|
|
|
|
+ </div>`);
|
|
|
|
+ return uploadIconUUID;
|
|
|
|
+ }
|
|
|
|
|
|
- xhr.addEventListener('readystatechange', function(e) {
|
|
|
|
- if (xhr.readyState == 4 && xhr.status == 200) {
|
|
|
|
- if (callback !== undefined){
|
|
|
|
- callback(e.target.response);
|
|
|
|
- }
|
|
|
|
|
|
+ function uploadFile(file, callback=undefined, uploadingIconUUID = undefined) {
|
|
|
|
+ if (lowMemoryMode){
|
|
|
|
+ /*
|
|
|
|
+ Low Memory Upload Mode
|
|
|
|
+ */
|
|
|
|
+ var filename = encodeURIComponent(file.name);
|
|
|
|
+ var filesize = file.size;
|
|
|
|
+
|
|
|
|
+ //Open the websocket
|
|
|
|
+ let path = "user:/Desktop";
|
|
|
|
+ let protocol = "wss://";
|
|
|
|
+ if (location.protocol !== 'https:') {
|
|
|
|
+ protocol = "ws://";
|
|
}
|
|
}
|
|
- else if (xhr.readyState == 4 && xhr.status != 200) {
|
|
|
|
- console.log("Upload failed :" + xhr.status);
|
|
|
|
|
|
+
|
|
|
|
+ var port = window.location.port;
|
|
|
|
+ if (window.location.port == ""){
|
|
|
|
+ port = "80";
|
|
}
|
|
}
|
|
- })
|
|
|
|
- xhr.send(formData);
|
|
|
|
|
|
+
|
|
|
|
+ let uploadDir = "user:/Desktop";
|
|
|
|
+
|
|
|
|
+ //Fixing Firefox path issues on or above FF48.0
|
|
|
|
+ if (isFirefox && file.webkitRelativePath != ""){
|
|
|
|
+ //Use the webkitRelativePath instead of the name, this is a folder upload
|
|
|
|
+ let pathinfo = file.webkitRelativePath.split("/");
|
|
|
|
+ pathinfo.pop();
|
|
|
|
+ let subpath = pathinfo.join("/");
|
|
|
|
+ uploadDir = uploadDir + subpath;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let socket = new WebSocket(protocol + window.location.hostname + ":" + port + "/system/file_system/lowmemUpload?filename=" + filename + "&path=" + uploadDir);
|
|
|
|
+ let currentSendingIndex = 0;
|
|
|
|
+ let chunks = Math.ceil(file.size/uploadFileChunkSize,uploadFileChunkSize);
|
|
|
|
+
|
|
|
|
+ //Define a function for sending a particular chunk
|
|
|
|
+ function sendChunk(id, uploadingIconUUID){
|
|
|
|
+ var offsetStart = id*uploadFileChunkSize;
|
|
|
|
+ var offsetEnd = id*uploadFileChunkSize + uploadFileChunkSize;
|
|
|
|
+ var thisblob = file.slice(offsetStart,offsetEnd);
|
|
|
|
+ socket.send(thisblob);
|
|
|
|
+ //console.log(id + "/" + chunks);
|
|
|
|
+
|
|
|
|
+ //Update progress to first percentage
|
|
|
|
+ var progress = id / (chunks-1) * 100.0;
|
|
|
|
+ if (progress > 100){
|
|
|
|
+ progress = 100;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (uploadingIconUUID != undefined){
|
|
|
|
+ //Update the progress on the object
|
|
|
|
+ $("." + uploadingIconUUID + ".launchIcon").find(".bar").css("width", progress + "%");
|
|
|
|
+ if (progress == 100){
|
|
|
|
+ $("." + uploadingIconUUID + ".launchIcon").find(".progress").addClass("indeterminate");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Start sending
|
|
|
|
+ socket.onopen = function(e) {
|
|
|
|
+ if (filesize < uploadFileChunkSize){
|
|
|
|
+ //This file is smaller than chunk size, set it to somwhere within 10% - 20% so it doesn't look like it is stuck
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Send the first chunk
|
|
|
|
+ sendChunk(0, uploadingIconUUID);
|
|
|
|
+ currentSendingIndex++;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ socket.onmessage = function(event) {
|
|
|
|
+ //Append to the send index
|
|
|
|
+ var incomingValue = event.data;
|
|
|
|
+
|
|
|
|
+ if (incomingValue == "next"){
|
|
|
|
+ if (currentSendingIndex == chunks + 1){
|
|
|
|
+ //Already finished
|
|
|
|
+ socket.send("done");
|
|
|
|
+ }else{
|
|
|
|
+ //Send next chunk
|
|
|
|
+ sendChunk(currentSendingIndex, uploadingIconUUID);
|
|
|
|
+ currentSendingIndex++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }else if (incomingValue == "OK"){
|
|
|
|
+ //Merge completed
|
|
|
|
+
|
|
|
|
+ }else{
|
|
|
|
+ //Try to parse it as JSON
|
|
|
|
+ try{
|
|
|
|
+ var resp = JSON.parse(incomingValue.split('\\' + '"').join("\""));
|
|
|
|
+ console.log(resp);
|
|
|
|
+ if (resp.error !== undefined){
|
|
|
|
+ //This is an error message
|
|
|
|
+ sendNotification("Upload Failed", resp.error, "remove")
|
|
|
|
+
|
|
|
|
+ //Update the progress bar to error
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }catch(ex){
|
|
|
|
+ //Something else
|
|
|
|
+ console.log(incomingValue);
|
|
|
|
+ console.log(ex);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ socket.onclose = function(event) {
|
|
|
|
+ if (callback != undefined){
|
|
|
|
+ callback();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ socket.onerror = function(error) {
|
|
|
|
+ console.log(error.message);
|
|
|
|
+ console.log("[Desktop] Unable to open WebSocket connection. Fall back to FORM POST upload mode. (Check your nginx / reverse proxy settings!!!)")
|
|
|
|
+ //Try to fallback to FORM POST upload mode
|
|
|
|
+ lowMemoryMode = false;
|
|
|
|
+ uploadFile(thisFile, callback)
|
|
|
|
+ return
|
|
|
|
+ };
|
|
|
|
+ }else{
|
|
|
|
+ let url = 'system/file_system/upload'
|
|
|
|
+ let uploadCurrentPath = "user:/Desktop/";
|
|
|
|
+ let formData = new FormData();
|
|
|
|
+ let xhr = new XMLHttpRequest();
|
|
|
|
+ formData.append('file', file);
|
|
|
|
+ formData.append('path', uploadCurrentPath);
|
|
|
|
+
|
|
|
|
+ xhr.open('POST', url, true)
|
|
|
|
+ xhr.upload.addEventListener("progress", function(e) {
|
|
|
|
+ console.log((e.loaded * 100.0 / e.total) || 100)
|
|
|
|
+ var progress = (e.loaded * 100.0 / e.total) || 100;
|
|
|
|
+ if (uploadingIconUUID != undefined){
|
|
|
|
+ //Update the progress on the object
|
|
|
|
+ $("." + uploadingIconUUID + ".launchIcon").find(".bar").css("width", progress + "%");
|
|
|
|
+ if (progress == 100){
|
|
|
|
+ $("." + uploadingIconUUID + ".launchIcon").find(".progress").addClass("indeterminate");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ xhr.addEventListener('readystatechange', function(e) {
|
|
|
|
+ if (xhr.readyState == 4 && xhr.status == 200) {
|
|
|
|
+ if (callback !== undefined){
|
|
|
|
+ callback(e.target.response);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (xhr.readyState == 4 && xhr.status != 200) {
|
|
|
|
+ console.log("Upload failed :" + xhr.status);
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ xhr.send(formData);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
function setStorage(key, value, callback = undefined) {
|
|
function setStorage(key, value, callback = undefined) {
|