2013-04-21 00:07:27 +00:00
|
|
|
define(["jquery", "core", "dropbox-provider", "gdrive-provider", "underscore"], function($, core) {
|
2013-04-01 16:46:48 +00:00
|
|
|
var synchronizer = {};
|
2013-04-01 23:12:28 +00:00
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Create a map with providerId: providerObject
|
2013-04-20 00:14:20 +00:00
|
|
|
var providerMap = _.chain(arguments)
|
|
|
|
.map(function(argument) {
|
2013-04-20 17:40:05 +00:00
|
|
|
return argument && argument.providerId && [argument.providerId, argument];
|
2013-04-20 00:14:20 +00:00
|
|
|
}).compact().object().value();
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Used to know if user can force synchronization
|
|
|
|
var uploadPending = false;
|
2013-04-01 23:12:28 +00:00
|
|
|
|
2013-04-10 23:13:31 +00:00
|
|
|
// Allows external modules to update uploadPending flag
|
2013-04-10 18:14:59 +00:00
|
|
|
synchronizer.notifyChange = function(fileIndex) {
|
2013-04-01 23:12:28 +00:00
|
|
|
// Check that file has synchronized locations
|
2013-04-10 23:13:31 +00:00
|
|
|
if(localStorage[fileIndex + ".sync"].length !== 1) {
|
|
|
|
uploadPending = true;
|
|
|
|
synchronizer.updateSyncButton();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used to enable/disable the synchronization button
|
|
|
|
synchronizer.updateSyncButton = function() {
|
|
|
|
if(syncRunning === true || uploadPending === false || core.isOffline) {
|
|
|
|
$(".action-force-sync").addClass("disabled");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$(".action-force-sync").removeClass("disabled");
|
2013-04-01 16:46:48 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-04-10 23:13:31 +00:00
|
|
|
// Force the synchronization
|
|
|
|
synchronizer.forceSync = function() {
|
|
|
|
lastSync = 0;
|
|
|
|
synchronizer.sync();
|
|
|
|
};
|
|
|
|
|
2013-04-01 16:46:48 +00:00
|
|
|
// Recursive function to upload a single file on multiple locations
|
2013-04-10 18:14:59 +00:00
|
|
|
var uploadFileSyncIndexList = [];
|
|
|
|
var uploadContent = undefined;
|
|
|
|
var uploadContentCRC = undefined;
|
|
|
|
var uploadTitle = undefined;
|
|
|
|
var uploadTitleCRC = undefined;
|
|
|
|
function locationUp(callback) {
|
|
|
|
|
|
|
|
// No more synchronized location for this document
|
|
|
|
if (uploadFileSyncIndexList.length === 0) {
|
|
|
|
fileUp(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dequeue a synchronized location
|
2013-04-20 00:14:20 +00:00
|
|
|
var syncIndex = uploadFileSyncIndexList.pop();
|
2013-04-20 17:40:05 +00:00
|
|
|
var syncAttributes = JSON.parse(localStorage[syncIndex]);
|
|
|
|
// Use the specified provider to perform the upload
|
|
|
|
providerMap[syncAttributes.provider].syncUp(
|
|
|
|
uploadContent,
|
|
|
|
uploadContentCRC,
|
|
|
|
uploadTitle,
|
|
|
|
uploadTitleCRC,
|
|
|
|
syncAttributes,
|
|
|
|
function(error, uploadFlag) {
|
|
|
|
if(uploadFlag === true) {
|
|
|
|
// If uploadFlag is true, request another upload cycle
|
|
|
|
uploadCycle = true;
|
|
|
|
// When page is refreshed, this flag is false but should be true
|
|
|
|
uploadPending = true;
|
|
|
|
}
|
2013-04-20 00:14:20 +00:00
|
|
|
if(error) {
|
|
|
|
callback(error);
|
2013-04-07 15:22:13 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
if(uploadFlag) {
|
|
|
|
// Update syncAttributes in localStorage
|
|
|
|
localStorage[syncIndex] = JSON.stringify(syncAttributes);
|
2013-04-01 16:46:48 +00:00
|
|
|
}
|
2013-04-16 15:02:24 +00:00
|
|
|
locationUp(callback);
|
2013-04-20 17:40:05 +00:00
|
|
|
}
|
|
|
|
);
|
2013-04-01 16:46:48 +00:00
|
|
|
}
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Recursive function to upload multiple files
|
|
|
|
var uploadFileIndexList = [];
|
|
|
|
function fileUp(callback) {
|
|
|
|
|
|
|
|
// No more fileIndex to synchronize
|
|
|
|
if (uploadFileIndexList.length === 0) {
|
|
|
|
syncUp(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dequeue a fileIndex
|
|
|
|
var fileIndex = uploadFileIndexList.pop();
|
|
|
|
var fileSyncIndexes = localStorage[fileIndex + ".sync"];
|
2013-04-20 17:40:05 +00:00
|
|
|
if(fileSyncIndexes.length === 1) {
|
2013-04-10 18:14:59 +00:00
|
|
|
fileUp(callback);
|
2013-04-01 16:46:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Get document title/content
|
|
|
|
uploadContent = localStorage[fileIndex + ".content"];
|
|
|
|
uploadContentCRC = core.crc32(uploadContent);
|
|
|
|
uploadTitle = localStorage[fileIndex + ".title"];
|
|
|
|
uploadTitleCRC = core.crc32(uploadTitle);
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Parse the list of synchronized locations associated to the document
|
2013-04-20 00:14:20 +00:00
|
|
|
uploadFileSyncIndexList = _.compact(fileSyncIndexes.split(";"));
|
2013-04-10 18:14:59 +00:00
|
|
|
locationUp(callback);
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Entry point for up synchronization (upload changes)
|
2013-04-10 18:14:59 +00:00
|
|
|
var uploadCycle = false;
|
|
|
|
function syncUp(callback) {
|
|
|
|
if(uploadCycle === true) {
|
|
|
|
// New upload cycle
|
|
|
|
uploadCycle = false;
|
2013-04-20 17:40:05 +00:00
|
|
|
uploadFileIndexList = _.compact(localStorage["file.list"].split(";"));
|
2013-04-10 18:14:59 +00:00
|
|
|
fileUp(callback);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-20 17:40:05 +00:00
|
|
|
// Recursive function to download changes from multiple providers
|
|
|
|
var providerList = [];
|
|
|
|
function providerDown(callback) {
|
|
|
|
if(providerList.length === 0) {
|
2013-04-07 15:22:13 +00:00
|
|
|
callback();
|
2013-04-21 00:07:27 +00:00
|
|
|
return;
|
2013-04-07 15:22:13 +00:00
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
var provider = providerList.pop();
|
|
|
|
provider.syncDown(function(error) {
|
|
|
|
if(error) {
|
2013-04-16 15:02:24 +00:00
|
|
|
callback(error);
|
2013-04-07 15:22:13 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
providerDown(callback);
|
2013-04-07 15:22:13 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Entry point for down synchronization (download changes)
|
2013-04-01 16:46:48 +00:00
|
|
|
function syncDown(callback) {
|
2013-04-20 17:40:05 +00:00
|
|
|
providerList = _.values(providerMap);
|
|
|
|
providerDown(callback);
|
2013-04-01 16:46:48 +00:00
|
|
|
};
|
2013-04-21 00:07:27 +00:00
|
|
|
|
|
|
|
// Main entry point for synchronization
|
2013-04-01 16:46:48 +00:00
|
|
|
var syncRunning = false;
|
|
|
|
var lastSync = 0;
|
|
|
|
synchronizer.sync = function() {
|
|
|
|
// If sync is already running or timeout is not reached or offline
|
2013-04-02 18:42:47 +00:00
|
|
|
if (syncRunning || lastSync + SYNC_PERIOD > core.currentTime || core.isOffline) {
|
2013-04-01 16:46:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncRunning = true;
|
2013-04-10 18:14:59 +00:00
|
|
|
uploadCycle = true;
|
2013-04-02 18:42:47 +00:00
|
|
|
lastSync = core.currentTime;
|
2013-04-10 18:14:59 +00:00
|
|
|
synchronizer.updateSyncButton();
|
|
|
|
|
|
|
|
function isError(error) {
|
|
|
|
if(error !== undefined) {
|
2013-04-20 17:40:05 +00:00
|
|
|
console.error(error);
|
2013-04-10 18:14:59 +00:00
|
|
|
syncRunning = false;
|
|
|
|
synchronizer.updateSyncButton();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
syncDown(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncUp(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
syncRunning = false;
|
2013-04-10 18:14:59 +00:00
|
|
|
uploadPending = false;
|
2013-04-01 16:46:48 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2013-04-01 23:12:28 +00:00
|
|
|
|
2013-04-20 00:14:20 +00:00
|
|
|
// Used to populate the "Manage synchronization" dialog
|
|
|
|
var lineTemplate = ['<div class="input-prepend input-append">',
|
|
|
|
'<span class="add-on" title="<%= provider.providerName %>">',
|
|
|
|
'<i class="icon-<%= provider.providerId %>"></i></span>',
|
|
|
|
'<input class="span5" type="text" value="<%= syncDesc %>" disabled />',
|
|
|
|
'</div>'].join("");
|
|
|
|
var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>';
|
|
|
|
synchronizer.refreshManageSync = function() {
|
2013-04-21 00:07:27 +00:00
|
|
|
var fileIndex = core.fileManager.getCurrentFileIndex();
|
2013-04-20 00:14:20 +00:00
|
|
|
var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
|
|
|
|
$(".msg-no-sync, .msg-sync-list").addClass("hide");
|
|
|
|
$("#manage-sync-list .input-append").remove();
|
|
|
|
if (syncIndexList.length > 0) {
|
|
|
|
$(".msg-sync-list").removeClass("hide");
|
|
|
|
} else {
|
|
|
|
$(".msg-no-sync").removeClass("hide");
|
|
|
|
}
|
|
|
|
_.each(syncIndexList, function(syncIndex) {
|
|
|
|
var syncAttributes = JSON.parse(localStorage[syncIndex]);
|
|
|
|
var syncDesc = syncAttributes.id || syncAttributes.path;
|
|
|
|
lineElement = $(_.template(lineTemplate, {
|
|
|
|
provider: providerMap[syncAttributes.provider],
|
|
|
|
syncDesc: syncDesc
|
|
|
|
}));
|
|
|
|
lineElement.append($(removeButtonTemplate).click(function() {
|
2013-04-21 00:07:27 +00:00
|
|
|
core.fileManager.removeSync(syncIndex);
|
|
|
|
core.fileManager.updateFileTitles();
|
2013-04-20 00:14:20 +00:00
|
|
|
}));
|
|
|
|
$("#manage-sync-list").append(lineElement);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Used to enable/disable providers' synchronization
|
2013-04-20 17:40:05 +00:00
|
|
|
synchronizer.resetSyncFlags = function() {
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
provider.useSync = false;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
synchronizer.getSyncProvidersFromFile = function(fileIndex) {
|
|
|
|
var sync = localStorage[fileIndex + ".sync"];
|
|
|
|
var providerIdList = [];
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
if (sync.indexOf(";sync." + provider.providerId + ".") !== -1) {
|
|
|
|
provider.useSync = true;
|
|
|
|
providerIdList.push(provider.providerId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return providerIdList;
|
|
|
|
};
|
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
$(function() {
|
|
|
|
core.addOfflineListener(synchronizer.updateSyncButton);
|
|
|
|
core.addPeriodicCallback(synchronizer.sync);
|
2013-04-10 18:14:59 +00:00
|
|
|
|
2013-04-20 00:14:20 +00:00
|
|
|
// Init each provider
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
// Provider's import button
|
|
|
|
$(".action-sync-import-" + provider.providerId).click(function(event) {
|
|
|
|
provider.importFiles(event);
|
|
|
|
});
|
|
|
|
// Provider's export button
|
|
|
|
$(".action-sync-export-" + provider.providerId).click(function(event) {
|
2013-04-21 00:07:27 +00:00
|
|
|
var fileIndex = core.fileManager.getCurrentFileIndex();
|
2013-04-20 00:14:20 +00:00
|
|
|
var title = localStorage[fileIndex + ".title"];
|
|
|
|
var content = localStorage[fileIndex + ".content"];
|
|
|
|
provider.exportFile(event, title, content, function(error, syncIndex) {
|
|
|
|
if(error) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
localStorage[fileIndex + ".sync"] += syncIndex + ";";
|
|
|
|
synchronizer.refreshManageSync();
|
2013-04-21 00:07:27 +00:00
|
|
|
core.fileManager.updateFileTitles();
|
2013-04-20 00:14:20 +00:00
|
|
|
core.showMessage('"' + title
|
|
|
|
+ '" will now be synchronized on ' + provider.providerName + '.');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// Provider's manual sync button
|
|
|
|
$(".action-sync-manual-" + provider.providerId).click(function(event) {
|
2013-04-21 00:07:27 +00:00
|
|
|
var fileIndex = core.fileManager.getCurrentFileIndex();
|
2013-04-20 00:14:20 +00:00
|
|
|
var title = localStorage[fileIndex + ".title"];
|
|
|
|
var content = localStorage[fileIndex + ".content"];
|
|
|
|
provider.exportManual(event, title, content, function(error, syncIndex) {
|
|
|
|
if(error) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
localStorage[fileIndex + ".sync"] += syncIndex + ";";
|
|
|
|
synchronizer.refreshManageSync();
|
2013-04-21 00:07:27 +00:00
|
|
|
core.fileManager.updateFileTitles();
|
2013-04-20 00:14:20 +00:00
|
|
|
core.showMessage('"' + title
|
|
|
|
+ '" will now be synchronized on ' + provider.providerName + '.');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
synchronizer.updateSyncButton();
|
|
|
|
$(".action-force-sync").click(function() {
|
|
|
|
if(!$(this).hasClass("disabled")) {
|
|
|
|
synchronizer.forceSync();
|
|
|
|
}
|
|
|
|
});
|
2013-04-21 00:07:27 +00:00
|
|
|
});
|
2013-04-10 18:14:59 +00:00
|
|
|
|
2013-04-01 16:46:48 +00:00
|
|
|
return synchronizer;
|
2013-04-02 18:42:47 +00:00
|
|
|
});
|