Enable drag & upload in code2 and prepare filepicker

pull/1/head
yflory 8 years ago
parent 885282ddea
commit 89b7b644f3

@ -487,10 +487,9 @@ define([
} }
//UserList.getLastName(toolbar.$userNameButton, isNew); //UserList.getLastName(toolbar.$userNameButton, isNew);
/* TODO RPC
var fmConfig = { var fmConfig = {
dropArea: $iframe.find('.CodeMirror'), dropArea: $('.CodeMirror'),
body: $iframe.find('body'), body: $('body'),
onUploaded: function (ev, data) { onUploaded: function (ev, data) {
//var cursor = editor.getCursor(); //var cursor = editor.getCursor();
//var cleanName = data.name.replace(/[\[\]]/g, ''); //var cleanName = data.name.replace(/[\[\]]/g, '');
@ -502,8 +501,7 @@ define([
editor.replaceSelection(mt); editor.replaceSelection(mt);
} }
}; };
APP.FM = Cryptpad.createFileManager(fmConfig); APP.FM = common.createFileManager(fmConfig);
*/
}; };
config.onRemote = function () { config.onRemote = function () {
@ -619,15 +617,12 @@ define([
nThen(function (waitFor) { nThen(function (waitFor) {
cmEditorAvailable(waitFor(function (cm) { cmEditorAvailable(waitFor(function (cm) {
CM = cm; CM = cm;
console.log('cm');
})); }));
$(waitFor(function () { $(waitFor(function () {
Cryptpad.addLoadingScreen(); Cryptpad.addLoadingScreen();
})); }));
SFCommon.create(waitFor(function (c) { console.log('common'); APP.common = common = c; })); SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
console.log('nThen1');
}).nThen(function (/*waitFor*/) { }).nThen(function (/*waitFor*/) {
console.log('nThen2');
CodeMirror = Cryptpad.createCodemirror(window, Cryptpad, null, CM); CodeMirror = Cryptpad.createCodemirror(window, Cryptpad, null, CM);
$('.CodeMirror').addClass('fullPage'); $('.CodeMirror').addClass('fullPage');
editor = CodeMirror.editor; editor = CodeMirror.editor;

@ -23,6 +23,85 @@ define([
} }
}; };
module.upload = function (file, noStore, common, updateProgress, onComplete, onError, onPending) {
var u8 = file.blob; // This is not a blob but a uint8array
var metadata = file.metadata;
var key = Nacl.randomBytes(32);
var next = FileCrypto.encrypt(u8, metadata, key);
var estimate = FileCrypto.computeEncryptedSize(u8.length, metadata);
var sendChunk = function (box, cb) {
var enc = Nacl.util.encodeBase64(box);
common.rpc.send.unauthenticated('UPLOAD', enc, function (e, msg) {
cb(e, msg);
});
};
var actual = 0;
var again = function (err, box) {
if (err) { throw new Error(err); }
if (box) {
actual += box.length;
var progressValue = (actual / estimate * 100);
updateProgress(progressValue);
return void sendChunk(box, function (e) {
if (e) { return console.error(e); }
next(again);
});
}
if (actual !== estimate) {
console.error('Estimated size does not match actual size');
}
// if not box then done
common.uploadComplete(function (e, id) {
if (e) { return void console.error(e); }
var uri = ['', 'blob', id.slice(0,2), id].join('/');
console.log("encrypted blob is now available as %s", uri);
var b64Key = Nacl.util.encodeBase64(key);
var hash = common.getFileHashFromKeys(id, b64Key);
var href = '/file/#' + hash;
var title = metadata.name;
if (noStore) { return void onComplete(href); }
common.renamePad(title || "", href, function (err) {
if (err) { return void console.error(err); }
onComplete(href);
});
});
};
common.uploadStatus(estimate, function (e, pending) {
if (e) {
console.error(e);
onError(e);
return;
}
if (pending) {
return void onPending(function () {
// if the user wants to cancel the pending upload to execute that one
common.uploadCancel(function (e, res) {
if (e) {
return void console.error(e);
}
console.log(res);
next(again);
});
});
}
next(again);
});
};
module.create = function (common, config) { module.create = function (common, config) {
var File = {}; var File = {};
@ -62,7 +141,8 @@ define([
}; };
var upload = function (file) { var upload = function (file) {
var blob = file.blob; var blob = file.blob; // This is not a blob but an array buffer
var u8 = new Uint8Array(blob);
var metadata = file.metadata; var metadata = file.metadata;
var id = file.id; var id = file.id;
if (queue.inProgress) { return; } if (queue.inProgress) { return; }
@ -83,58 +163,13 @@ define([
}); });
}; };
var u8 = new Uint8Array(blob); var onComplete = function (href) {
var key = Nacl.randomBytes(32);
var next = FileCrypto.encrypt(u8, metadata, key);
var estimate = FileCrypto.computeEncryptedSize(blob.byteLength, metadata);
var sendChunk = function (box, cb) {
var enc = Nacl.util.encodeBase64(box);
common.rpc.send.unauthenticated('UPLOAD', enc, function (e, msg) {
console.log(box);
cb(e, msg);
});
};
var actual = 0;
var again = function (err, box) {
if (err) { throw new Error(err); }
if (box) {
actual += box.length;
var progressValue = (actual / estimate * 100);
updateProgress(progressValue);
return void sendChunk(box, function (e) {
if (e) { return console.error(e); }
next(again);
});
}
if (actual !== estimate) {
console.error('Estimated size does not match actual size');
}
// if not box then done
common.uploadComplete(function (e, id) {
if (e) { return void console.error(e); }
var uri = ['', 'blob', id.slice(0,2), id].join('/');
console.log("encrypted blob is now available as %s", uri);
var b64Key = Nacl.util.encodeBase64(key);
var hash = common.getFileHashFromKeys(id, b64Key);
var href = '/file/#' + hash;
$link.attr('href', href) $link.attr('href', href)
.click(function (e) { .click(function (e) {
e.preventDefault(); e.preventDefault();
window.open($link.attr('href'), '_blank'); window.open($link.attr('href'), '_blank');
}); });
var title = metadata.name; var title = metadata.name;
var onComplete = function () {
common.log(Messages._getKey('upload_success', [title])); common.log(Messages._getKey('upload_success', [title]));
common.prepareFeedback('upload')(); common.prepareFeedback('upload')();
@ -147,19 +182,7 @@ define([
queue.next(); queue.next();
}; };
if (config.noStore) { return void onComplete(); } var onError = function (e) {
common.renamePad(title || "", href, function (err) {
if (err) { return void console.error(err); } // TODO
onComplete();
});
//Title.updateTitle(title || "", href);
//APP.toolbar.title.show();
});
};
common.uploadStatus(estimate, function (e, pending) {
if (e) {
queue.inProgress = false; queue.inProgress = false;
queue.next(); queue.next();
if (e === 'TOO_LARGE') { if (e === 'TOO_LARGE') {
@ -172,25 +195,19 @@ define([
} }
console.error(e); console.error(e);
return void common.alert(Messages.upload_serverError); return void common.alert(Messages.upload_serverError);
} };
if (pending) { var onPending = function (cb) {
// TODO keep this message in case of pending files in another window? common.confirm(Messages.upload_uploadPending, function (yes) {
return void common.confirm(Messages.upload_uploadPending, function (yes) {
if (!yes) { return; } if (!yes) { return; }
common.uploadCancel(function (e, res) { cb();
if (e) {
return void console.error(e);
}
console.log(res);
next(again);
});
});
}
next(again);
}); });
}; };
file.blob = u8;
module.upload(file, config.noStore, common, updateProgress, onComplete, onError, onPending);
};
var prettySize = function (bytes) { var prettySize = function (bytes) {
var kB = common.bytesToKilobytes(bytes); var kB = common.bytesToKilobytes(bytes);
if (kB < 1024) { return kB + Messages.KB; } if (kB < 1024) { return kB + Messages.KB; }

@ -723,7 +723,7 @@ define([
var proxy = store.getProxy(); var proxy = store.getProxy();
var fo = proxy.fo; var fo = proxy.fo;
var hashes = []; var hashes = [];
var list = fo.getFiles().filter(function (id) { var list = fo.getFiles([fo.ROOT]).filter(function (id) {
var href = fo.getFileData(id).href; var href = fo.getFileData(id).href;
var parsed = parsePadUrl(href); var parsed = parsePadUrl(href);
if ((parsed.type === 'file' || parsed.type === 'media') if ((parsed.type === 'file' || parsed.type === 'media')
@ -734,6 +734,26 @@ define([
}); });
return list; return list;
}; };
// Needed for the secure filepicker app
common.getSecureFilesList = function (cb) {
var store = common.getStore();
if (!store) { return void cb("Store is not ready"); }
var proxy = store.getProxy();
var fo = proxy.fo;
var list = {};
var hashes = [];
fo.getFiles([fo.ROOT]).forEach(function (id) {
var data = fo.getFileData(id);
var parsed = parsePadUrl(data.href);
if ((parsed.type === 'file' || parsed.type === 'media')
&& hashes.indexOf(parsed.hash) === -1) {
hashes.push(parsed.hash);
list[id] = data;
}
});
console.log(list);
cb (null, list);
};
var getUserChannelList = common.getUserChannelList = function () { var getUserChannelList = common.getUserChannelList = function () {
var store = common.getStore(); var store = common.getStore();
@ -953,6 +973,9 @@ define([
rpc.uploadCancel(cb); rpc.uploadCancel(cb);
}; };
common.uploadFileSecure = Files.upload;
/* Create a usage bar which keeps track of how much storage space is used /* Create a usage bar which keeps track of how much storage space is used
by your CryptDrive. The getPinnedUsage RPC is one of the heavier calls, by your CryptDrive. The getPinnedUsage RPC is one of the heavier calls,
so we throttle its usage. Clients will not update more than once per so we throttle its usage. Clients will not update more than once per
@ -1414,7 +1437,7 @@ define([
}; };
// This is duplicated in drive/main.js, it should be unified // This is duplicated in drive/main.js, it should be unified
var getFileIcon = function (data) { var getFileIcon = common.getFileIcon = function (data) {
var $icon = common.getIcon(); var $icon = common.getIcon();
if (!data) { return $icon; } if (!data) { return $icon; }

@ -0,0 +1,295 @@
define([
'jquery',
'/file/file-crypto.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, FileCrypto) {
var Nacl = window.nacl;
var module = {};
var blobToArrayBuffer = function (blob, cb) {
var reader = new FileReader();
reader.onloadend = function () {
cb(void 0, this.result);
};
reader.readAsArrayBuffer(blob);
};
var arrayBufferToString = function (AB) {
try {
return Nacl.util.encodeBase64(new Uint8Array(AB));
} catch (e) {
console.error(e);
return null;
}
};
module.create = function (common, config) {
var File = {};
var Cryptpad = common.getCryptpadCommon();
var Messages = Cryptpad.Messages;
var queue = File.queue = {
queue: [],
inProgress: false
};
var uid = function () {
return 'file-' + String(Math.random()).substring(2);
};
var $table = File.$table = $('<table>', { id: 'uploadStatus' });
var $thead = $('<tr>').appendTo($table);
$('<td>').text(Messages.upload_name).appendTo($thead);
$('<td>').text(Messages.upload_size).appendTo($thead);
$('<td>').text(Messages.upload_progress).appendTo($thead);
$('<td>').text(Messages.cancel).appendTo($thead);
var createTableContainer = function ($body) {
File.$container = $('<div>', { id: 'uploadStatusContainer' }).append($table).appendTo($body);
return File.$container;
};
var getData = function (file, href) {
var data = {};
data.name = file.metadata.name;
data.url = href;
if (file.metadata.type.slice(0,6) === 'image/') {
data.mediatag = true;
}
return data;
};
var upload = function (file) {
var blob = file.blob; // This is not a blob but an array buffer
var u8 = new Uint8Array(blob);
var metadata = file.metadata;
var id = file.id;
var dropEvent = file.dropEvent;
delete file.dropEvent;
if (queue.inProgress) { return; }
queue.inProgress = true;
var $row = $table.find('tr[id="'+id+'"]');
$row.find('.upCancel').html('-');
var $pv = $row.find('.progressValue');
var $pb = $row.find('.progressContainer');
var $pc = $row.find('.upProgress');
var $link = $row.find('.upLink');
var sframeChan = common.getSframeChannel();
var updateProgress = function (progressValue) {
$pv.text(Math.round(progressValue*100)/100 + '%');
$pb.css({
width: (progressValue/100)*$pc.width()+'px'
});
};
var onComplete = function (href) {
$link.attr('href', href)
.click(function (e) {
e.preventDefault();
window.open($link.attr('href'), '_blank');
});
var title = metadata.name;
Cryptpad.log(Messages._getKey('upload_success', [title]));
common.prepareFeedback('upload')();
if (config.onUploaded) {
var data = getData(file, href);
config.onUploaded(dropEvent, data);
}
queue.inProgress = false;
queue.next();
};
var onError = function (e) {
queue.inProgress = false;
queue.next();
if (e === 'TOO_LARGE') {
// TODO update table to say too big?
return void Cryptpad.alert(Messages.upload_tooLarge);
}
if (e === 'NOT_ENOUGH_SPACE') {
// TODO update table to say not enough space?
return void Cryptpad.alert(Messages.upload_notEnoughSpace);
}
console.error(e);
return void Cryptpad.alert(Messages.upload_serverError);
};
var onPending = function (cb) {
Cryptpad.confirm(Messages.upload_uploadPending, cb);
};
sframeChan.on('EV_FILE_UPLOAD_STATE', function (data) {
if (data.error) {
return void onError(data.error);
}
if (data.complete && data.href) {
return void onComplete(data.href);
}
if (typeof data.progress !== "undefined") {
return void updateProgress(data.progress);
}
});
sframeChan.on('Q_CANCEL_PENDING_FILE_UPLOAD', function (data, cb) {
onPending(cb);
});
file.noStore = config.noStore;
try {
file.blob = Nacl.util.encodeBase64(u8);
common.uploadFile(file, function () {
console.log('Upload started...');
});
} catch (e) {
Cryptpad.alert(Messages.upload_serverError);
}
};
var prettySize = function (bytes) {
var kB = Cryptpad.bytesToKilobytes(bytes);
if (kB < 1024) { return kB + Messages.KB; }
var mB = Cryptpad.bytesToMegabytes(bytes);
return mB + Messages.MB;
};
queue.next = function () {
if (queue.queue.length === 0) {
queue.to = window.setTimeout(function () {
if (config.keepTable) { return; }
File.$container.fadeOut();
}, 3000);
return;
}
if (queue.inProgress) { return; }
File.$container.show();
var file = queue.queue.shift();
upload(file);
};
queue.push = function (obj) {
var id = uid();
obj.id = id;
queue.queue.push(obj);
$table.show();
var estimate = FileCrypto.computeEncryptedSize(obj.blob.byteLength, obj.metadata);
var $progressBar = $('<div>', {'class':'progressContainer'});
var $progressValue = $('<span>', {'class':'progressValue'}).text(Messages.upload_pending);
var $tr = $('<tr>', {id: id}).appendTo($table);
var $cancel = $('<span>', {'class': 'cancel fa fa-times'}).click(function () {
queue.queue = queue.queue.filter(function (el) { return el.id !== id; });
$cancel.remove();
$tr.find('.upCancel').text('-');
$tr.find('.progressValue').text(Messages.upload_cancelled);
});
var $link = $('<a>', {
'class': 'upLink',
'rel': 'noopener noreferrer'
}).text(obj.metadata.name);
$('<td>').append($link).appendTo($tr);
$('<td>').text(prettySize(estimate)).appendTo($tr);
$('<td>', {'class': 'upProgress'}).append($progressBar).append($progressValue).appendTo($tr);
$('<td>', {'class': 'upCancel'}).append($cancel).appendTo($tr);
queue.next();
};
var handleFile = File.handleFile = function (file, e, thumbnail) {
var thumb;
var finish = function (arrayBuffer) {
var metadata = {
name: file.name,
type: file.type,
};
if (thumb) { metadata.thumbnail = thumb; }
queue.push({
blob: arrayBuffer,
metadata: metadata,
dropEvent: e
});
};
var processFile = function () {
blobToArrayBuffer(file, function (e, buffer) {
finish(buffer);
});
};
if (!thumbnail) { return void processFile(); }
blobToArrayBuffer(thumbnail, function (e, buffer) {
if (e) { console.error(e); }
thumb = arrayBufferToString(buffer);
processFile();
});
};
var onFileDrop = File.onFileDrop = function (file, e) {
if (!common.isLoggedIn()) {
return Cryptpad.alert(common.Messages.upload_mustLogin);
}
Array.prototype.slice.call(file).forEach(function (d) {
handleFile(d, e);
});
};
var createAreaHandlers = File.createDropArea = function ($area, $hoverArea) {
var counter = 0;
if (!$hoverArea) { $hoverArea = $area; }
if (!$area) { return; }
$hoverArea
.on('dragenter', function (e) {
e.preventDefault();
e.stopPropagation();
counter++;
$hoverArea.addClass('hovering');
})
.on('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
counter--;
if (counter <= 0) {
$hoverArea.removeClass('hovering');
}
});
$area
.on('drag dragstart dragend dragover drop dragenter dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
})
.on('drop', function (e) {
e.stopPropagation();
var dropped = e.originalEvent.dataTransfer.files;
counter = 0;
$hoverArea.removeClass('hovering');
onFileDrop(dropped, e);
});
};
var createUploader = function ($area, $hover, $body) {
if (!config.noHandlers) {
createAreaHandlers($area, null);
}
createTableContainer($body);
};
createUploader(config.dropArea, config.hoverArea, config.body);
return File;
};
return module;
});

@ -261,5 +261,59 @@ define([
return $userAdmin; return $userAdmin;
}; };
UI.createFileDialog = function (cfg) {
var common = cfg.common;
var $blockContainer = Cryptpad.createModal({
id: 'fileDialog',
$body: cfg.$body
});
var $block = $blockContainer.find('.cp-modal');
var $description = $('<p>').text(Messages.filePicker_description);
$block.append($description);
var $filter = $('<p>', {'class': 'cp-modal-form'}).appendTo($block);
var $container = $('<span>', {'class': 'fileContainer'}).appendTo($block);
var updateContainer = function () {
$container.html('');
var filter = $filter.find('.filter').val().trim();
var todo = function (err, list) {
if (err) { return void console.error(err); }
Object.keys(list).forEach(function (id) {
var data = list[id];
var name = data.title || '?';
if (filter && name.toLowerCase().indexOf(filter.toLowerCase()) === -1) {
return;
}
var $span = $('<span>', {
'class': 'element',
'title': name,
}).appendTo($container);
$span.append(Cryptpad.getFileIcon(data));
$span.append(name);
$span.click(function () {
if (typeof cfg.onSelect === "function") { cfg.onSelect(data.href); }
$blockContainer.hide();
});
});
};
common.getFilesList(todo);
};
var to;
$('<input>', {
type: 'text',
'class': 'filter',
'placeholder': Messages.filePicker_filter
}).appendTo($filter).on('keypress', function () {
if (to) { window.clearTimeout(to); }
to = window.setTimeout(updateContainer, 300);
});
//$filter.append(' '+Messages.or+' ');
/*var data = {FM: cfg.data.FM};
$filter.append(common.createButton('upload', false, data, function () {
$blockContainer.hide();
}));*/
updateContainer();
$blockContainer.show();
};
return UI; return UI;
}); });

@ -215,6 +215,38 @@ define([
}); });
sframeChan.on('Q_UPLOAD_FILE', function (data, cb) {
var sendEvent = function (data) {
sframeChan.event("EV_FILE_UPLOAD_STATE", data);
};
var updateProgress = function (progressValue) {
sendEvent({
progress: progressValue
});
};
var onComplete = function (href) {
sendEvent({
complete: true,
href: href
});
};
var onError = function (e) {
sendEvent({
error: e
});
};
var onPending = function (cb) {
sframeChan.query('Q_CANCEL_PENDING_FILE_UPLOAD', null, function (err, data) {
if (data) {
cb();
}
});
};
data.blob = Crypto.Nacl.util.decodeBase64(data.blob);
Cryptpad.uploadFileSecure(data, data.noStore, Cryptpad, updateProgress, onComplete, onError, onPending);
cb();
});
CpNfOuter.start({ CpNfOuter.start({
sframeChan: sframeChan, sframeChan: sframeChan,
channel: secret.channel, channel: secret.channel,

@ -7,12 +7,13 @@ define([
'/common/sframe-common-title.js', '/common/sframe-common-title.js',
'/common/sframe-common-interface.js', '/common/sframe-common-interface.js',
'/common/sframe-common-history.js', '/common/sframe-common-history.js',
'/common/sframe-common-file.js',
'/common/metadata-manager.js', '/common/metadata-manager.js',
'/customize/application_config.js', '/customize/application_config.js',
'/common/cryptpad-common.js', '/common/cryptpad-common.js',
'/common/common-realtime.js' '/common/common-realtime.js'
], function ($, nThen, Messages, CpNfInner, SFrameChannel, Title, UI, History, MetadataMgr, ], function ($, nThen, Messages, CpNfInner, SFrameChannel, Title, UI, History, File, MetadataMgr,
AppConfig, Cryptpad, CommonRealtime) { AppConfig, Cryptpad, CommonRealtime) {
// Chainpad Netflux Inner // Chainpad Netflux Inner
@ -36,6 +37,9 @@ define([
funcs.getCryptpadCommon = function () { funcs.getCryptpadCommon = function () {
return Cryptpad; return Cryptpad;
}; };
funcs.getSframeChannel = function () {
return ctx.sframeChan;
};
var isLoggedIn = funcs.isLoggedIn = function () { var isLoggedIn = funcs.isLoggedIn = function () {
if (!ctx.cpNfInner) { throw new Error("cpNfInner is not ready!"); } if (!ctx.cpNfInner) { throw new Error("cpNfInner is not ready!"); }
@ -51,6 +55,7 @@ define([
// UI // UI
funcs.createUserAdminMenu = UI.createUserAdminMenu; funcs.createUserAdminMenu = UI.createUserAdminMenu;
funcs.displayAvatar = UI.displayAvatar; funcs.displayAvatar = UI.displayAvatar;
funcs.createFileDialog = UI.createFileDialog;
// History // History
funcs.getHistory = function (config) { return History.create(funcs, config); }; funcs.getHistory = function (config) { return History.create(funcs, config); };
@ -118,10 +123,14 @@ define([
ctx.sframeChan.query('Q_SET_PAD_ATTRIBUTE', { ctx.sframeChan.query('Q_SET_PAD_ATTRIBUTE', {
key: key, key: key,
value: value value: value
}, function (err, data) { }, cb);
cb(); };
});
// Files
funcs.uploadFile = function (data, cb) {
ctx.sframeChan.query('Q_UPLOAD_FILE', data, cb);
}; };
funcs.createFileManager = function (config) { return File.create(funcs, config); };
// Friends // Friends
var pendingFriends = []; var pendingFriends = [];
@ -149,7 +158,7 @@ define([
url: href, url: href,
}); });
}; };
var prepareFeedback = function (key) { var prepareFeedback = funcs.prepareFeedback = function (key) {
if (typeof(key) !== 'string') { return $.noop; } if (typeof(key) !== 'string') { return $.noop; }
var type = ctx.metadataMgr.getMetadata().type; var type = ctx.metadataMgr.getMetadata().type;
@ -304,6 +313,14 @@ define([
return button; return button;
}; };
// Can, only be called by the filepicker app
funcs.getFilesList = function (cb) {
ctx.sframeChan.query('Q_GET_FILES_LIST', null, function (err, data) {
cb(err || data.error, data.data);
});
};
/* funcs.storeLinkToClipboard = function (readOnly, cb) { /* funcs.storeLinkToClipboard = function (readOnly, cb) {
ctx.sframeChan.query('Q_STORE_LINK_TO_CLIPBOARD', readOnly, function (err) { ctx.sframeChan.query('Q_STORE_LINK_TO_CLIPBOARD', readOnly, function (err) {
if (cb) { cb(err); } if (cb) { cb(err); }

@ -88,4 +88,12 @@ define({
// Get and set pad attributes stored in the drive from the inner iframe // Get and set pad attributes stored in the drive from the inner iframe
'Q_GET_PAD_ATTRIBUTE': true, 'Q_GET_PAD_ATTRIBUTE': true,
'Q_SET_PAD_ATTRIBUTE': true, 'Q_SET_PAD_ATTRIBUTE': true,
// Get all the files from the drive to display them in a file picker secure app
'Q_GET_FILES_LIST': true,
// File upload queries and events
'Q_UPLOAD_FILE': true,
'EV_FILE_UPLOAD_STATE': true,
'Q_CANCEL_PENDING_FILE_UPLOAD': true,
}); });

@ -19,6 +19,11 @@ define([
var NEW_FOLDER_NAME = Messages.fm_newFolder; var NEW_FOLDER_NAME = Messages.fm_newFolder;
var NEW_FILE_NAME = Messages.fm_newFile; var NEW_FILE_NAME = Messages.fm_newFile;
exp.ROOT = ROOT;
exp.UNSORTED = UNSORTED;
exp.TRASH = TRASH;
exp.TEMPLATE = TEMPLATE;
// Logging // Logging
var logging = function () { var logging = function () {
console.log.apply(console, arguments); console.log.apply(console, arguments);

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="no-referrer" />
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
html, body {
margin: 0px;
padding: 0px;
}
#sbox-iframe {
position:fixed;
top:0px;
left:0px;
bottom:0px;
right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
}
</style>
</head>
<body>
<iframe id="sbox-iframe">

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html style="height: 100%;">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/filepicker/inner.js" data-main="/common/sframe-boot.js?ver=1.1" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style> .loading-hidden { display: none; } </style>
</head>
<body>
</body>
</html>

@ -0,0 +1,63 @@
define([
'jquery',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/textpatcher/TextPatcher.js',
'/bower_components/chainpad-json-validator/json-ot.js',
'/common/cryptpad-common.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/customize/src/less/cryptpad.less',
'less!/customize/src/less/toolbar.less',
'less!/common/file-dialog.less',
], function (
$,
Crypto,
TextPatcher,
JsonOT,
Cryptpad,
nThen,
SFCommon)
{
var Messages = Cryptpad.Messages;
var APP = window.APP = {
Cryptpad: Cryptpad,
};
var onConnectError = function () {
Cryptpad.errorLoadingScreen(Messages.websocketError);
};
var andThen = function (common) {
//var metadataMgr = common.getMetadataMgr();
var $body = $('body');
var cfg = {
$body: $body,
common: common
};
common.createFileDialog(cfg);
Cryptpad.removeLoadingScreen();
};
var main = function () {
var common;
nThen(function (waitFor) {
$(waitFor(function () {
Cryptpad.addLoadingScreen();
}));
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (/*waitFor*/) {
Cryptpad.onError(function (info) {
if (info && info.type === "store") {
onConnectError();
}
});
andThen(common);
});
};
main();
});

@ -0,0 +1,129 @@
// Load #1, load as little as possible because we are in a race to get the loading screen up.
define([
'/bower_components/nthen/index.js',
'/api/config',
'jquery',
'/common/requireconfig.js',
], function (nThen, ApiConfig, $, RequireConfig) {
var requireConfig = RequireConfig();
// Loaded in load #2
nThen(function (waitFor) {
$(waitFor());
}).nThen(function (waitFor) {
var req = {
cfg: requireConfig,
req: [ '/common/loading.js' ],
pfx: window.location.origin
};
window.rc = requireConfig;
window.apiconf = ApiConfig;
$('#sbox-iframe').attr('src',
ApiConfig.httpSafeOrigin + '/filepicker/inner.html?' + requireConfig.urlArgs +
'#' + encodeURIComponent(JSON.stringify(req)));
// This is a cheap trick to avoid loading sframe-channel in parallel with the
// loading screen setup.
var done = waitFor();
var onMsg = function (msg) {
var data = JSON.parse(msg.data);
if (data.q !== 'READY') { return; }
window.removeEventListener('message', onMsg);
var _done = done;
done = function () { };
_done();
};
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
var Cryptpad;
var Crypto;
var Cryptget;
var sframeChan;
nThen(function (waitFor) {
// Load #2, the loading screen is up so grab whatever you need...
require([
'/common/cryptpad-common.js',
'/bower_components/chainpad-crypto/crypto.js',
'/common/cryptget.js',
'/common/sframe-channel.js',
], waitFor(function (_Cryptpad, _Crypto, _Cryptget, SFrameChannel) {
Cryptpad = _Cryptpad;
Crypto = _Crypto;
Cryptget = _Cryptget;
SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) {
sframeChan = sfc;
}));
Cryptpad.ready(waitFor());
}));
}).nThen(function () {
var proxy = Cryptpad.getProxy();
var updateMeta = function () {
//console.log('EV_METADATA_UPDATE');
var name;
nThen(function (waitFor) {
Cryptpad.getLastName(waitFor(function (err, n) {
if (err) { console.log(err); }
name = n;
}));
}).nThen(function (/*waitFor*/) {
sframeChan.event('EV_METADATA_UPDATE', {
doc: {},
user: {
name: name,
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: proxy.curvePublic,
netfluxId: Cryptpad.getNetwork().webChannels[0].myID,
},
priv: {
accountName: Cryptpad.getAccountName(),
origin: window.location.origin,
pathname: window.location.pathname,
feedbackAllowed: Cryptpad.isFeedbackAllowed(),
friends: proxy.friends || {},
settings: proxy.settings || {}
}
});
});
};
Cryptpad.onDisplayNameChanged(updateMeta);
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
proxy.on('change', 'settings', updateMeta);
Cryptpad.onError(function (info) {
console.log('error');
console.log(info);
if (info && info.type === "store") {
//onConnectError();
}
});
sframeChan.on('Q_ANON_RPC_MESSAGE', function (data, cb) {
Cryptpad.anonRpcMsg(data.msg, data.content, function (err, response) {
cb({error: err, response: response});
});
});
sframeChan.on('Q_GET_PIN_LIMIT_STATUS', function (data, cb) {
Cryptpad.isOverPinLimit(function (e, overLimit, limits) {
cb({
error: e,
overLimit: overLimit,
limits: limits
});
});
});
sframeChan.on('Q_GET_FILES_LIST', function (data, cb) {
Cryptpad.getSecureFilesList(function (err, data) {
cb({
error: err,
data: data
});
});
});
});
});
});
Loading…
Cancel
Save