mirror of https://github.com/xwiki-labs/cryptpad
Create links in the drive
This commit is contained in:
parent
d94f327756
commit
0fc2269a3a
|
@ -368,8 +368,8 @@ define([
|
|||
var mkFilePicker = function (framework, editor, evModeChange) {
|
||||
evModeChange.reg(function (mode) {
|
||||
if (MEDIA_TAG_MODES.indexOf(mode) !== -1) {
|
||||
// Embedding is endabled
|
||||
framework.setMediaTagEmbedder(function (mt) {
|
||||
// Embedding is enabled
|
||||
framework.setMediaTagEmbedder(function (mt, data) {
|
||||
editor.focus();
|
||||
editor.replaceSelection($(mt)[0].outerHTML);
|
||||
});
|
||||
|
|
|
@ -119,6 +119,7 @@ define(function() {
|
|||
file: 'cptools-file',
|
||||
fileupload: 'cptools-file-upload',
|
||||
folderupload: 'cptools-folder-upload',
|
||||
link: 'fa-link',
|
||||
pad: 'cptools-richtext',
|
||||
code: 'cptools-code',
|
||||
slide: 'cptools-slide',
|
||||
|
|
|
@ -1050,6 +1050,7 @@ define([
|
|||
var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa';
|
||||
if (type === 'fileupload') { type = 'file'; }
|
||||
if (type === 'folderupload') { type = 'file'; }
|
||||
if (type === 'link') { type = 'drive'; }
|
||||
var appClass = ' cp-icon cp-icon-color-'+type;
|
||||
$icon = $('<span>', {'class': font + ' ' + icon + appClass});
|
||||
}
|
||||
|
@ -1061,6 +1062,7 @@ define([
|
|||
if (!data) { return $icon; }
|
||||
var href = data.href || data.roHref;
|
||||
var type = data.type;
|
||||
if (data.static) { type = 'link'; }
|
||||
if (!href && !type) { return $icon; }
|
||||
|
||||
if (!type) { type = Hash.parsePadUrl(href).type; }
|
||||
|
|
|
@ -1032,10 +1032,19 @@ define([
|
|||
icon: 'fa-picture-o',
|
||||
action: function () {
|
||||
var _cfg = {
|
||||
types: ['file'],
|
||||
types: ['file', 'link'],
|
||||
where: ['root']
|
||||
};
|
||||
common.openFilePicker(_cfg, function (data) {
|
||||
// Embed links
|
||||
if (data.static) {
|
||||
var a = h('a', {
|
||||
href: data.href
|
||||
}, data.name);
|
||||
cfg.embed(a, data);
|
||||
return;
|
||||
}
|
||||
// Embed files
|
||||
if (data.type !== 'file') {
|
||||
console.log("Unexpected data type picked " + data.type);
|
||||
return;
|
||||
|
@ -3021,6 +3030,63 @@ define([
|
|||
UI.proposal(content, todo);
|
||||
};
|
||||
|
||||
UIElements.displayOpenLinkModal = function (common, data, dismiss) {
|
||||
var name = Util.fixHTML(data.title);
|
||||
var url = data.href;
|
||||
var user = data.name;
|
||||
Messages.notification_openLink = "You've received a link <b>{0}</b> from {1}:"; // XXX
|
||||
Messages.link_open = "Open URL";
|
||||
Messages.link_store = "Store link in drive";
|
||||
|
||||
var content = h('div', [
|
||||
UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])),
|
||||
h('pre', url),
|
||||
UIElements.getVerifiedFriend(common, data.curve, user)
|
||||
]);
|
||||
var clicked = false;
|
||||
var modal;
|
||||
var buttons = [{
|
||||
name: Messages.friendRequest_later,
|
||||
onClick: function () {
|
||||
if (clicked) { return true; }
|
||||
clicked = true;
|
||||
},
|
||||
keys: [27]
|
||||
}, {
|
||||
className: 'primary',
|
||||
name: Messages.link_open,
|
||||
onClick: function () {
|
||||
if (clicked) { return true; }
|
||||
clicked = true;
|
||||
common.openUnsafeURL(url);
|
||||
},
|
||||
keys: [13]
|
||||
}, {
|
||||
className: 'primary',
|
||||
name: Messages.link_store,
|
||||
onClick: function () {
|
||||
if (clicked) { return; }
|
||||
clicked = true;
|
||||
common.getSframeChannel().query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "addLink",
|
||||
data: {
|
||||
name: name,
|
||||
href: url,
|
||||
path: ['root']
|
||||
}
|
||||
}, function () {
|
||||
modal.closeModal();
|
||||
dismiss();
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keys: [[13, 'ctrl']]
|
||||
}];
|
||||
var _modal = UI.dialog.customModal(content, {buttons: buttons});
|
||||
modal = UI.openCustomModal(_modal);
|
||||
return modal;
|
||||
};
|
||||
|
||||
UIElements.displayAddOwnerModal = function (common, data) {
|
||||
var priv = common.getMetadataMgr().getPrivateData();
|
||||
var sframeChan = common.getSframeChannel();
|
||||
|
|
|
@ -42,6 +42,8 @@ define([
|
|||
Pages)
|
||||
{
|
||||
|
||||
Messages.fm_link = "Link"; // XXX
|
||||
|
||||
var APP = window.APP = {
|
||||
editable: false,
|
||||
online: false,
|
||||
|
@ -443,6 +445,11 @@ define([
|
|||
'data-icon': AppConfig.applicationsIcon.poll,
|
||||
'data-type': 'poll'
|
||||
}, Messages.button_newpoll)),
|
||||
h('li', h('a.cp-app-drive-context-newdoc.dropdown-item.cp-app-drive-context-editable', {
|
||||
'tabindex': '-1',
|
||||
'data-icon': AppConfig.applicationsIcon.link,
|
||||
'data-type': 'link'
|
||||
}, Messages.fm_link)),
|
||||
]),
|
||||
]),
|
||||
$separator.clone()[0],
|
||||
|
@ -1111,6 +1118,15 @@ define([
|
|||
var defaultInApp = ['application/pdf'];
|
||||
var openFile = function (el, isRo, app) {
|
||||
var data = manager.getFileData(el);
|
||||
|
||||
if (data.static) {
|
||||
if (data.href) {
|
||||
common.openUnsafeURL(data.href);
|
||||
manager.updateStaticAccess(el, refresh);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data || (!data.href && !data.roHref)) {
|
||||
return void logError("Missing data for the file", el, data);
|
||||
}
|
||||
|
@ -1263,6 +1279,9 @@ define([
|
|||
if ($element.is('.cp-border-color-sheet')) {
|
||||
hide.push('download');
|
||||
}
|
||||
if ($element.is('.cp-app-drive-static')) {
|
||||
hide.push('access', 'hashtag', 'properties', 'download');
|
||||
}
|
||||
if ($element.is('.cp-app-drive-element-file')) {
|
||||
// No folder in files
|
||||
hide.push('color');
|
||||
|
@ -1899,6 +1918,27 @@ define([
|
|||
|
||||
|
||||
// In list mode, display metadata from the filesData object
|
||||
var addStaticData = function (element, $element, data) {
|
||||
$element.addClass('cp-border-color-drive');
|
||||
var name = data.name;
|
||||
var $name = $('<span>', {'class': 'cp-app-drive-element-name'}).text(name);
|
||||
$element.append($name);
|
||||
if (getViewMode() === 'grid') {
|
||||
$element.attr('title', name);
|
||||
}
|
||||
|
||||
var type = Messages.fm_link;
|
||||
var $type = $('<span>', {
|
||||
'class': 'cp-app-drive-element-type cp-app-drive-element-list'
|
||||
}).text(type);
|
||||
var $adate = $('<span>', {
|
||||
'class': 'cp-app-drive-element-atime cp-app-drive-element-list'
|
||||
}).text(getDate(data.atime));
|
||||
var $cdate = $('<span>', {
|
||||
'class': 'cp-app-drive-element-ctime cp-app-drive-element-list'
|
||||
}).text(getDate(data.ctime));
|
||||
$element.append($type).append($adate).append($cdate);
|
||||
}
|
||||
var _addOwnership = function ($span, $state, data) {
|
||||
if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) {
|
||||
var $owned = $ownedIcon.clone().appendTo($state);
|
||||
|
@ -1914,6 +1954,9 @@ define([
|
|||
if (!manager.isFile(element)) { return; }
|
||||
|
||||
var data = manager.getFileData(element);
|
||||
if (data.static) {
|
||||
return addStaticData(element, $element, data);
|
||||
}
|
||||
|
||||
if (!Object.keys(data).length) {
|
||||
return true;
|
||||
|
@ -2124,7 +2167,9 @@ define([
|
|||
$icon = manager.isFolderEmpty(root[key]) ? $folderEmptyIcon.clone() : $folderIcon.clone();
|
||||
$icon.css("color", getFolderColor(path.concat(elPath)));
|
||||
}
|
||||
var classes = restrictedClass + roClass + liClass;
|
||||
|
||||
var staticClass = manager.isStaticFile(element) ? '.cp-app-drive-static' : '';
|
||||
var classes = restrictedClass + roClass + liClass + staticClass;
|
||||
var $element = $(h('li.cp-app-drive-element.cp-app-drive-element-row' + classes, {
|
||||
draggable: true
|
||||
}));
|
||||
|
@ -2460,7 +2505,6 @@ define([
|
|||
showMode(viewMode);
|
||||
|
||||
$button.click(function (e) {
|
||||
console.error(e);
|
||||
var viewMode = getViewMode();
|
||||
var newViewMode = getOppositeViewMode(viewMode);
|
||||
setViewMode(newViewMode);
|
||||
|
@ -2686,6 +2730,63 @@ define([
|
|||
});
|
||||
$input.click();
|
||||
};
|
||||
var showLinkModal = function () {
|
||||
Messages.fm_link_name = "Link name"; // XXX
|
||||
Messages.fm_link_url = "URL";
|
||||
Messages.fm_link_warning = "Warning: URL size...";
|
||||
var name, url;
|
||||
var warning = h('div.alert.alert-warning', [
|
||||
h('i.fa.fa-exclamation-triangle'),
|
||||
h('span', Messages.fm_link_warning)
|
||||
]);
|
||||
var content = h('p', [
|
||||
warning,
|
||||
h('label', {for: 'cp-app-drive-link-name'}, Messages.fm_link_name),
|
||||
name = h('input#cp-app-drive-link-name', { autocomplete: 'off' }),
|
||||
h('label', {for: 'cp-app-drive-link-url'}, Messages.fm_link_url),
|
||||
url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off' })
|
||||
]);
|
||||
var $warning = $(warning).hide();
|
||||
var $url = $(url).on('change keypress keyup keydown', function () {
|
||||
var v = $url.val().trim();
|
||||
if (v.length > 200) {
|
||||
$warning.show();
|
||||
return;
|
||||
}
|
||||
$warning.hide();
|
||||
});
|
||||
var buttons = [{
|
||||
className: 'cancel',
|
||||
name: Messages.cancelButton,
|
||||
onClick: function () {},
|
||||
keys: [27]
|
||||
}];
|
||||
buttons.push({
|
||||
className: 'primary',
|
||||
// We may want to use a new key here
|
||||
iconClass: '.fa.fa-plus',
|
||||
name: Messages.tag_add,
|
||||
onClick: function () {
|
||||
var n = $(name).val().trim();
|
||||
var u = $url.val().trim();
|
||||
if (!n || !u) { return true; }
|
||||
if (!Util.isValidURL(u)) {
|
||||
// XXX add style for invalid input? input:invalid
|
||||
UI.warn(Messages.error);
|
||||
return true;
|
||||
}
|
||||
manager.addLink(currentPath, {
|
||||
name: n,
|
||||
url: u
|
||||
}, refresh);
|
||||
},
|
||||
keys: [13]
|
||||
});
|
||||
var m = UI.dialog.customModal(content, {
|
||||
buttons: buttons
|
||||
});
|
||||
UI.openCustomModal(m);
|
||||
};
|
||||
var addNewPadHandlers = function ($block, isInRoot) {
|
||||
// Handlers
|
||||
if (isInRoot) {
|
||||
|
@ -2714,6 +2815,7 @@ define([
|
|||
}
|
||||
$block.find('a.cp-app-drive-new-fileupload, li.cp-app-drive-new-fileupload').click(showUploadFilesModal);
|
||||
$block.find('a.cp-app-drive-new-folderupload, li.cp-app-drive-new-folderupload').click(showUploadFolderModal);
|
||||
$block.find('a.cp-app-drive-new-link, li.cp-app-drive-new-link').click(showLinkModal);
|
||||
}
|
||||
$block.find('a.cp-app-drive-new-doc, li.cp-app-drive-new-doc')
|
||||
.click(function () {
|
||||
|
@ -2757,6 +2859,12 @@ define([
|
|||
});
|
||||
}
|
||||
options.push({tag: 'hr'});
|
||||
options.push({
|
||||
tag: 'a',
|
||||
attributes: {'class': 'cp-app-drive-new-link'},
|
||||
content: $('<div>').append(getIcon('link')).html() + Messages.fm_link
|
||||
});
|
||||
options.push({tag: 'hr'});
|
||||
}
|
||||
getNewPadTypes().forEach(function (type) {
|
||||
var attributes = {
|
||||
|
@ -3073,6 +3181,13 @@ define([
|
|||
$elementFolderUpload.append($('<span>', {'class': 'cp-app-drive-new-name'})
|
||||
.text(Messages.uploadFolderButton));
|
||||
}
|
||||
// Link
|
||||
var $elementFileUpload = $('<li>', {
|
||||
'class': 'cp-app-drive-new-link cp-app-drive-element-row ' +
|
||||
'cp-app-drive-element-grid'
|
||||
}).prepend(getIcon('link')).appendTo($container);
|
||||
$elementFileUpload.append($('<span>', {'class': 'cp-app-drive-new-name'})
|
||||
.text(Messages.fm_link));
|
||||
}
|
||||
// Pads
|
||||
getNewPadTypes().forEach(function (type) {
|
||||
|
@ -3479,6 +3594,7 @@ define([
|
|||
var path = paths[0];
|
||||
if (manager.isPathIn(path, [TRASH])) { return; }
|
||||
|
||||
if (!file.channel) { file.channel = id; }
|
||||
if (channels.indexOf(file.channel) !== -1) { return; }
|
||||
channels.push(file.channel);
|
||||
|
||||
|
@ -4482,8 +4598,9 @@ define([
|
|||
password: data.password
|
||||
},
|
||||
isTemplate: paths[0].path[0] === 'template',
|
||||
title: data.title,
|
||||
title: data.title || data.name,
|
||||
sharedFolder: sf,
|
||||
static: data.static ? data.href : undefined,
|
||||
common: common
|
||||
};
|
||||
if (padType === 'file') {
|
||||
|
@ -4501,6 +4618,20 @@ define([
|
|||
data = manager.getSharedFolderData(el);
|
||||
}
|
||||
if (!data) { return; }
|
||||
if (data.static) {
|
||||
sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "addLink",
|
||||
teamId: -1,
|
||||
data: {
|
||||
name: data.name,
|
||||
href: data.href,
|
||||
path: ['root']
|
||||
}
|
||||
}, function () {
|
||||
UI.log(Messages.saved);
|
||||
});
|
||||
return;
|
||||
}
|
||||
sframeChan.query('Q_STORE_IN_TEAM', {
|
||||
href: data.href || data.rohref,
|
||||
password: data.password,
|
||||
|
@ -4539,6 +4670,9 @@ define([
|
|||
}
|
||||
else if ($this.hasClass("cp-app-drive-context-newdoc")) {
|
||||
var ntype = $this.data('type') || 'pad';
|
||||
if (ntype === 'link') {
|
||||
return void showLinkModal();
|
||||
}
|
||||
var path2 = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath;
|
||||
openIn(ntype, path2, APP.team);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,11 @@ define([
|
|||
setTimeout(w);
|
||||
});
|
||||
if (res && /^http/.test(res)) {
|
||||
href = Hash.getRelativeHref(res);
|
||||
var _href = Hash.getRelativeHref(res);
|
||||
if (_href) { href = _href; }
|
||||
else {
|
||||
href = res;
|
||||
}
|
||||
setTimeout(w);
|
||||
return;
|
||||
}
|
||||
|
@ -109,6 +113,7 @@ define([
|
|||
if (mailbox.notifications && mailbox.curvePublic) {
|
||||
common.mailbox.sendTo("SHARE_PAD", {
|
||||
href: href,
|
||||
isStatic: Boolean(config.static),
|
||||
password: config.password,
|
||||
isTemplate: config.isTemplate,
|
||||
name: myName,
|
||||
|
@ -137,6 +142,20 @@ define([
|
|||
});
|
||||
return;
|
||||
}
|
||||
if (config.static) {
|
||||
common.getSframeChannel().query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "addLink",
|
||||
teamId: team.id,
|
||||
data: {
|
||||
name: title,
|
||||
href: href,
|
||||
path: ['root']
|
||||
}
|
||||
}, function () {
|
||||
UI.log(Messages.saved);
|
||||
});
|
||||
return;
|
||||
}
|
||||
sframeChan.query('Q_STORE_IN_TEAM', {
|
||||
href: href,
|
||||
password: config.password,
|
||||
|
@ -346,6 +365,9 @@ define([
|
|||
] : [
|
||||
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
|
||||
];
|
||||
|
||||
if (opts.static) { linkContent = []; }
|
||||
|
||||
linkContent.push(h('div.cp-spacer'));
|
||||
linkContent.push(UI.dialog.selectableArea('', { id: 'cp-share-link-preview', tabindex: 1, rows:3}));
|
||||
|
||||
|
@ -361,7 +383,7 @@ define([
|
|||
// warning about sharing links
|
||||
// when sharing a version hash, there is a similar warning and we want
|
||||
// to avoid alert fatigue
|
||||
if (!opts.versionHash) {
|
||||
if (!opts.versionHash && !opts.static) {
|
||||
var localStore = window.cryptpadStore;
|
||||
var dismissButton = h('span.fa.fa-times');
|
||||
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
|
||||
|
@ -405,6 +427,10 @@ define([
|
|||
var v = opts.getLinkValue({
|
||||
embed: Util.isChecked($link.find('#cp-share-embed'))
|
||||
});
|
||||
if (opts.static) {
|
||||
common.openUnsafeURL(v);
|
||||
return true;
|
||||
}
|
||||
window.open(v);
|
||||
return true;
|
||||
},
|
||||
|
@ -562,6 +588,7 @@ define([
|
|||
});
|
||||
};
|
||||
opts.getLinkValue = function (initValue, cb) {
|
||||
if (opts.static) { return opts.static; }
|
||||
var val = initValue || {};
|
||||
var edit = val.edit !== undefined ? val.edit : Util.isChecked($rights.find('#cp-share-editable-true'));
|
||||
var embed = val.embed;
|
||||
|
@ -686,7 +713,7 @@ define([
|
|||
opts.access = true; // Allow the use of the modal even if the pad is not stored
|
||||
|
||||
var hashes = opts.hashes;
|
||||
if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; }
|
||||
if (!hashes || (!hashes.editHash && !hashes.viewHash && !opts.static)) { return; }
|
||||
|
||||
var teams = getEditableTeams(common, opts);
|
||||
opts.teams = teams;
|
||||
|
@ -705,19 +732,23 @@ define([
|
|||
|
||||
var $rights = opts.$rights = getRightsHeader(common, opts);
|
||||
var resetTab = function () {
|
||||
if (opts.static) { return; }
|
||||
$rights.show();
|
||||
$rights.find('label.cp-radio').show();
|
||||
};
|
||||
var onShowEmbed = function () {
|
||||
if (opts.static) { return; }
|
||||
$rights.find('#cp-share-bar').closest('label').hide();
|
||||
$rights.find('input[type="radio"]:enabled').first().prop('checked', 'checked');
|
||||
$rights.find('input[type="radio"]').trigger('change');
|
||||
};
|
||||
var onShowContacts = function () {
|
||||
if (opts.static) { return; }
|
||||
if (!hasFriends || priv.offline) {
|
||||
$rights.hide();
|
||||
}
|
||||
};
|
||||
if (opts.static) { $rights.hide(); }
|
||||
|
||||
var contactsActive = hasFriends && !priv.offline;
|
||||
var tabs = [{
|
||||
|
@ -732,13 +763,16 @@ define([
|
|||
title: Messages.share_linkCategory,
|
||||
icon: "fa fa-link",
|
||||
active: !contactsActive,
|
||||
}, {
|
||||
getTab: getEmbedTab,
|
||||
title: Messages.share_embedCategory,
|
||||
icon: "fa fa-code",
|
||||
onShow: onShowEmbed,
|
||||
onHide: resetTab
|
||||
}];
|
||||
if (!opts.static) {
|
||||
tabs.push({
|
||||
getTab: getEmbedTab,
|
||||
title: Messages.share_embedCategory,
|
||||
icon: "fa fa-code",
|
||||
onShow: onShowEmbed,
|
||||
onHide: resetTab
|
||||
});
|
||||
}
|
||||
Modal.getModal(common, opts, tabs, function (err, modal) {
|
||||
// Hide the burn-after-reading option by default
|
||||
var $modal = $(modal);
|
||||
|
|
|
@ -92,6 +92,11 @@ define([
|
|||
(type === 'file' ? 'notification_fileShared' : // Msg.notification_fileSharedTeam
|
||||
'notification_padShared'); // Msg.notification_padSharedTeam
|
||||
|
||||
Messages.notification_linkShared = "{0} has shared a link with you: <b>{1}</b>"; // XXX
|
||||
if (msg.content.isStatic) {
|
||||
key = 'notification_linkShared'; // Msg.notification_linkShared;
|
||||
}
|
||||
|
||||
var teamNotification = /^team-/.test(data.type) && Number(data.type.slice(5));
|
||||
var teamName = '';
|
||||
if (teamNotification) {
|
||||
|
@ -109,6 +114,15 @@ define([
|
|||
return Messages._getKey(key, [name, title, teamName]);
|
||||
};
|
||||
content.handler = function() {
|
||||
if (msg.content.isStatic) {
|
||||
UIElements.displayOpenLinkModal(common, {
|
||||
curve: msg.author,
|
||||
href: msg.content.href,
|
||||
name: name,
|
||||
title: title
|
||||
}, defaultDismiss(common, data));
|
||||
return;
|
||||
}
|
||||
var obj = {
|
||||
p: msg.content.isTemplate ? ['template'] : undefined,
|
||||
t: teamNotification || undefined,
|
||||
|
|
|
@ -1306,9 +1306,14 @@ define([
|
|||
getAllStores().forEach(function (s) {
|
||||
s.manager.getSecureFilesList(where).forEach(function (obj) {
|
||||
var data = obj.data;
|
||||
if (channels.indexOf(data.channel) !== -1) { return; }
|
||||
if (channels.indexOf(data.channel || data.id) !== -1) { return; }
|
||||
var id = obj.id;
|
||||
if (data.channel) { channels.push(data.channel); }
|
||||
if (data.channel) { channels.push(data.channel || data.id); }
|
||||
// Only include static links if "link" is requested
|
||||
if (data.static) {
|
||||
if (types.indexOf('link') !== -1) { list[id] = data; }
|
||||
return;
|
||||
}
|
||||
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
|
||||
!isFiltered(parsed.type, data)) {
|
||||
|
|
|
@ -239,7 +239,7 @@ define([
|
|||
|
||||
if (isMuted(ctx, data)) { return void cb(true); }
|
||||
|
||||
var channel = Hash.hrefToHexChannelId(content.href, content.password);
|
||||
var channel = content.isStatic ? content.href : Hash.hrefToHexChannelId(content.href, content.password);
|
||||
var parsed = Hash.parsePadUrl(content.href);
|
||||
var mode = parsed.hashData && parsed.hashData.mode || 'n/a';
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ define([
|
|||
|
||||
var ROOT = exp.ROOT;
|
||||
var FILES_DATA = exp.FILES_DATA;
|
||||
var STATIC_DATA = exp.STATIC_DATA;
|
||||
var OLD_FILES_DATA = exp.OLD_FILES_DATA;
|
||||
var UNSORTED = exp.UNSORTED;
|
||||
var TRASH = exp.TRASH;
|
||||
|
@ -78,6 +79,14 @@ define([
|
|||
files[FILES_DATA][id] = data;
|
||||
cb(null, id);
|
||||
};
|
||||
exp.pushLink = function (_data, cb) {
|
||||
if (typeof cb !== "function") { cb = function () {}; }
|
||||
if (readOnly) { return void cb('EFORBIDDEN'); }
|
||||
var id = Util.createRandomInteger();
|
||||
var data = clone(_data);
|
||||
files[STATIC_DATA][id] = data;
|
||||
cb(null, id);
|
||||
};
|
||||
|
||||
exp.pushSharedFolder = function (_data, cb) {
|
||||
if (typeof cb !== "function") { cb = function () {}; }
|
||||
|
@ -136,7 +145,7 @@ define([
|
|||
|
||||
var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]);
|
||||
var toClean = [];
|
||||
exp.getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) {
|
||||
exp.getFiles([FILES_DATA, SHARED_FOLDERS, STATIC_DATA]).forEach(function (id) {
|
||||
if (filesList.indexOf(id) === -1) {
|
||||
var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
|
||||
var channelId = fd.channel;
|
||||
|
@ -146,6 +155,8 @@ define([
|
|||
if (exp.isSharedFolder(id)) {
|
||||
delete files[SHARED_FOLDERS][id];
|
||||
if (config.removeProxy) { config.removeProxy(id); }
|
||||
} else if (files[STATIC_DATA][id]) {
|
||||
delete files[STATIC_DATA][id];
|
||||
} else {
|
||||
spliceFileData(id);
|
||||
}
|
||||
|
@ -398,7 +409,7 @@ define([
|
|||
|
||||
if (!loggedIn && !config.testMode) { return; }
|
||||
id = Number(id);
|
||||
var data = files[FILES_DATA][id] || files[SHARED_FOLDERS][id];
|
||||
var data = files[FILES_DATA][id] || files[STATIC_DATA][id] || files[SHARED_FOLDERS][id];
|
||||
if (!data || typeof(data) !== "object") { return; }
|
||||
var newPath = path, parentEl;
|
||||
if (path && !Array.isArray(path)) {
|
||||
|
@ -634,7 +645,7 @@ define([
|
|||
delete element[el];
|
||||
}
|
||||
if (typeof element[el] === "number") {
|
||||
var data = files[FILES_DATA][element[el]];
|
||||
var data = files[FILES_DATA][element[el]] || files[STATIC_DATA][element[el]];
|
||||
if (!data) {
|
||||
debug("An element in ROOT doesn't have associated data", element[el], el);
|
||||
delete element[el];
|
||||
|
@ -845,6 +856,25 @@ define([
|
|||
toClean.forEach(function (id) {
|
||||
spliceFileData(id);
|
||||
});
|
||||
var sd = files[STATIC_DATA];
|
||||
var toCleanSD = [];
|
||||
for (var id in sd) {
|
||||
id = Number(id);
|
||||
var el2 = sd[id];
|
||||
if (!el2 || typeof(el2) !== "object" || !el2.href) {
|
||||
toCleanSD.push(id);
|
||||
continue;
|
||||
}
|
||||
if ((loggedIn || config.testMode) && rootFiles.indexOf(id) === -1) {
|
||||
toCleanSD.push(id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
var spliceSD = function (id) {
|
||||
if (readOnly) { return; }
|
||||
delete files[STATIC_DATA][id];
|
||||
};
|
||||
toCleanSD.forEach(spliceSD);
|
||||
};
|
||||
var fixSharedFolders = function () {
|
||||
if (sharedFolder) { return; }
|
||||
|
@ -892,6 +922,12 @@ define([
|
|||
}
|
||||
}
|
||||
};
|
||||
var fixStaticData = function () {
|
||||
if (typeof(files[STATIC_DATA]) !== "object") {
|
||||
debug("STATIC_DATA was not an object");
|
||||
files[STATIC_DATA] = {};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var fixDrive = function () {
|
||||
|
@ -900,6 +936,7 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
fixStaticData();
|
||||
fixRoot();
|
||||
fixTrashRoot();
|
||||
fixTemplate();
|
||||
|
|
|
@ -584,6 +584,24 @@ define([
|
|||
});
|
||||
});
|
||||
};
|
||||
// Add a link
|
||||
var _addLink = function (Env, data, cb) {
|
||||
data = data || {};
|
||||
var resolved = _resolvePath(Env, data.path);
|
||||
if (!resolved || !resolved.userObject) { return void cb({error: 'E_NOTFOUND'}); }
|
||||
var uo = resolved.userObject;
|
||||
var now = +new Date();
|
||||
uo.pushLink({
|
||||
name: data.name,
|
||||
href: data.href,
|
||||
atime: now,
|
||||
ctime: now
|
||||
}, function (e, id) {
|
||||
if (e) { return void cb({error: e}); }
|
||||
uo.add(id, resolved.path);
|
||||
Env.onSync(cb);
|
||||
});
|
||||
};
|
||||
|
||||
var _restoreSharedFolder = function (Env, _data, cb) {
|
||||
var fId = _data.id;
|
||||
|
@ -1019,6 +1037,14 @@ define([
|
|||
});
|
||||
|
||||
};
|
||||
|
||||
var _updateStaticAccess = function (Env, id, cb) {
|
||||
var uo = _getUserObjectFromId(Env, id);
|
||||
var sd = uo.getFileData(id, true);
|
||||
sd.atime = +new Date();
|
||||
Env.onSync(cb);
|
||||
};
|
||||
|
||||
var onCommand = function (Env, cmdData, cb) {
|
||||
var cmd = cmdData.cmd;
|
||||
var data = cmdData.data || {};
|
||||
|
@ -1031,6 +1057,8 @@ define([
|
|||
_addFolder(Env, data, cb); break;
|
||||
case 'addSharedFolder':
|
||||
_addSharedFolder(Env, data, cb); break;
|
||||
case 'addLink':
|
||||
_addLink(Env, data, cb); break;
|
||||
case 'restoreSharedFolder':
|
||||
_restoreSharedFolder(Env, data, cb); break;
|
||||
case 'convertFolderToSharedFolder':
|
||||
|
@ -1045,6 +1073,8 @@ define([
|
|||
_rename(Env, data, cb); break;
|
||||
case 'setFolderData':
|
||||
_setFolderData(Env, data, cb); break;
|
||||
case 'updateStaticAccess':
|
||||
_updateStaticAccess(Env, data, cb); break;
|
||||
default:
|
||||
cb();
|
||||
}
|
||||
|
@ -1129,8 +1159,8 @@ define([
|
|||
data: uo.getFileData(id)
|
||||
};
|
||||
}).filter(function (d) {
|
||||
if (channels.indexOf(d.data.channel) === -1) {
|
||||
channels.push(d.data.channel);
|
||||
if (channels.indexOf(d.data.channel || d.id) === -1) {
|
||||
channels.push(d.data.channel || d.id);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
@ -1383,6 +1413,16 @@ define([
|
|||
}
|
||||
}, cb);
|
||||
};
|
||||
var addLinkInner = function (Env, path, data, cb) {
|
||||
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "addLink",
|
||||
data: {
|
||||
path: path,
|
||||
name: data.name,
|
||||
href: data.url
|
||||
}
|
||||
}, cb);
|
||||
};
|
||||
var restoreSharedFolderInner = function (Env, fId, password, cb) {
|
||||
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "restoreSharedFolder",
|
||||
|
@ -1433,6 +1473,14 @@ define([
|
|||
}, cb);
|
||||
};
|
||||
|
||||
var updateStaticAccessInner = function (Env, id, cb) {
|
||||
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "updateStaticAccess",
|
||||
data: id
|
||||
}, cb);
|
||||
|
||||
};
|
||||
|
||||
/* Tools */
|
||||
|
||||
var findChannels = _findChannels;
|
||||
|
@ -1450,6 +1498,11 @@ define([
|
|||
return String(uo.getTitle(id, type));
|
||||
};
|
||||
|
||||
var isStaticFile = function (Env, id) {
|
||||
var uo = _getUserObjectFromId(Env, id);
|
||||
return uo.isStaticFile(id);
|
||||
};
|
||||
|
||||
var isReadOnlyFile = function (Env, id) {
|
||||
var uo = _getUserObjectFromId(Env, id);
|
||||
return uo.isReadOnlyFile(id);
|
||||
|
@ -1491,7 +1544,7 @@ define([
|
|||
var files = [];
|
||||
var userObjects = _getUserObjects(Env);
|
||||
userObjects.forEach(function (uo) {
|
||||
var data = uo.getFiles([UserObject.FILES_DATA]).map(function (id) {
|
||||
var data = uo.getFiles([UserObject.FILES_DATA, UserObject.STATIC_DATA]).map(function (id) {
|
||||
return [Number(id), uo.getFileData(id)];
|
||||
});
|
||||
Array.prototype.push.apply(files, data);
|
||||
|
@ -1608,17 +1661,20 @@ define([
|
|||
emptyTrash: callWithEnv(emptyTrashInner),
|
||||
addFolder: callWithEnv(addFolderInner),
|
||||
addSharedFolder: callWithEnv(addSharedFolderInner),
|
||||
addLink: callWithEnv(addLinkInner),
|
||||
restoreSharedFolder: callWithEnv(restoreSharedFolderInner),
|
||||
convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner),
|
||||
delete: callWithEnv(deleteInner),
|
||||
deleteOwned: callWithEnv(deleteOwnedInner),
|
||||
restore: callWithEnv(restoreInner),
|
||||
setFolderData: callWithEnv(setFolderDataInner),
|
||||
updateStaticAccess: callWithEnv(updateStaticAccessInner),
|
||||
// Tools
|
||||
getFileData: callWithEnv(getFileData),
|
||||
find: callWithEnv(find),
|
||||
getTitle: callWithEnv(getTitle),
|
||||
isReadOnlyFile: callWithEnv(isReadOnlyFile),
|
||||
isStaticFile: callWithEnv(isStaticFile),
|
||||
getFiles: callWithEnv(getFiles),
|
||||
search: callWithEnv(search),
|
||||
getRecentPads: callWithEnv(getRecentPads),
|
||||
|
|
|
@ -733,11 +733,20 @@ define([
|
|||
if (!common.isLoggedIn()) { return; }
|
||||
$embedButton = common.createButton('mediatag', true).click(function () {
|
||||
var cfg = {
|
||||
types: ['file'],
|
||||
types: ['file', 'link'],
|
||||
where: ['root']
|
||||
};
|
||||
if ($embedButton.data('filter')) { cfg.filter = $embedButton.data('filter'); }
|
||||
common.openFilePicker(cfg, function (data) {
|
||||
// Embed links
|
||||
if (data.static) {
|
||||
var a = h('a', {
|
||||
href: data.href
|
||||
}, data.name);
|
||||
mediaTagEmbedder($(a), data);
|
||||
return;
|
||||
}
|
||||
// Embed files
|
||||
if (data.type !== 'file') {
|
||||
console.log("Unexpected data type picked " + data.type);
|
||||
return;
|
||||
|
|
|
@ -17,6 +17,7 @@ define([
|
|||
var SHARED_FOLDERS_TEMP = module.SHARED_FOLDERS_TEMP = "sharedFoldersTemp"; // Maybe deleted or new password
|
||||
var FILES_DATA = module.FILES_DATA = Constants.storageKey;
|
||||
var OLD_FILES_DATA = module.OLD_FILES_DATA = Constants.oldStorageKey;
|
||||
var STATIC_DATA = module.STATIC_DATA = 'static';
|
||||
|
||||
// Create untitled documents when no name is given
|
||||
var getLocaleDate = function () {
|
||||
|
@ -138,6 +139,7 @@ define([
|
|||
var NEW_FILE_NAME = Messages.fm_newFile || 'New file';
|
||||
|
||||
exp.ROOT = ROOT;
|
||||
exp.STATIC_DATA = STATIC_DATA;
|
||||
exp.UNSORTED = UNSORTED;
|
||||
exp.TRASH = TRASH;
|
||||
exp.TEMPLATE = TEMPLATE;
|
||||
|
@ -236,6 +238,10 @@ define([
|
|||
return Boolean(data.roHref && !data.href);
|
||||
};
|
||||
|
||||
exp.isStaticFile = function (element) {
|
||||
return Boolean(files[STATIC_DATA] && files[STATIC_DATA][element]);
|
||||
};
|
||||
|
||||
var isFolder = exp.isFolder = function (element) {
|
||||
if (isFolderData(element)) { return false; }
|
||||
return typeof(element) === "object" || isSharedFolder(element);
|
||||
|
@ -310,6 +316,12 @@ define([
|
|||
// Get data from AllFiles (Cryptpad_RECENTPADS)
|
||||
var getFileData = exp.getFileData = function (file, editable) {
|
||||
if (!file) { return; }
|
||||
var link = (files[STATIC_DATA] || {})[file];
|
||||
if (link) {
|
||||
var _link = editable ? link : Util.clone(link);
|
||||
if (!editable) { _link.static = true; }
|
||||
return _link;
|
||||
}
|
||||
var data = files[FILES_DATA][file] || {};
|
||||
if (!editable) {
|
||||
data = JSON.parse(JSON.stringify(data));
|
||||
|
@ -344,6 +356,7 @@ define([
|
|||
return '??';
|
||||
}
|
||||
var data = getFileData(file);
|
||||
if (data.static) { return data.name; }
|
||||
if (!file || !data || !(data.href || data.roHref)) {
|
||||
error("getTitle called with a non-existing file id: ", file, data);
|
||||
return;
|
||||
|
@ -475,6 +488,11 @@ define([
|
|||
});
|
||||
return ret;
|
||||
};
|
||||
_getFiles[STATIC_DATA] = function () {
|
||||
var ret = [];
|
||||
if (!files[STATIC_DATA]) { return ret; }
|
||||
return Object.keys(files[STATIC_DATA]).map(Number).filter(Boolean);
|
||||
};
|
||||
_getFiles[FILES_DATA] = function () {
|
||||
var ret = [];
|
||||
if (!files[FILES_DATA]) { return ret; }
|
||||
|
@ -854,6 +872,7 @@ define([
|
|||
|
||||
// RENAME
|
||||
exp.rename = function (path, newName, cb) {
|
||||
cb = cb || function () {};
|
||||
if (sframeChan) {
|
||||
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||
cmd: "rename",
|
||||
|
@ -891,9 +910,15 @@ define([
|
|||
if (isSharedFolder(element)) {
|
||||
data = files[SHARED_FOLDERS][element];
|
||||
} else {
|
||||
data = files[FILES_DATA][element];
|
||||
data = files[FILES_DATA][element] || files[STATIC_DATA][element];
|
||||
}
|
||||
if (!data) { return; }
|
||||
if (files[STATIC_DATA][element]) {
|
||||
if (!newName || !newName.trim()) { return void cb(); }
|
||||
data.name = newName;
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
if (!newName || newName.trim() === "") {
|
||||
delete data.filename;
|
||||
if (typeof cb === "function") { cb(); }
|
||||
|
|
|
@ -127,6 +127,7 @@ define([
|
|||
sframeChan.event("EV_SECURE_ACTION", {
|
||||
type: parsed.type,
|
||||
password: data.password,
|
||||
static: data.static,
|
||||
href: data.url,
|
||||
name: data.name
|
||||
});
|
||||
|
@ -214,20 +215,21 @@ define([
|
|||
$container.html('');
|
||||
Object.keys(list).forEach(function (id) {
|
||||
var data = list[id];
|
||||
var name = data.filename || data.title || '?';
|
||||
var name = data.filename || data.title || data.name || '?';
|
||||
if (filter && name.toLowerCase().indexOf(filter.toLowerCase()) === -1) {
|
||||
return;
|
||||
}
|
||||
var $span = $('<span>', {
|
||||
'class': 'cp-filepicker-content-element',
|
||||
'title': name,
|
||||
'title': Util.fixHTML(name),
|
||||
}).appendTo($container);
|
||||
$span.append(UI.getFileIcon(data));
|
||||
$('<span>', {'class': 'cp-filepicker-content-element-name'}).text(name)
|
||||
.appendTo($span);
|
||||
if (data.static) { $span.attr('title', Util.fixHTML(data.href)); }
|
||||
$span.click(function () {
|
||||
if (typeof onFilePicked === "function") {
|
||||
onFilePicked({url: data.href, name: name, password: data.password});
|
||||
onFilePicked({url: data.href, name: name, static: data.static, password: data.password});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ define([
|
|||
|
||||
sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) {
|
||||
if (!teamId) { return void cb({error: 'EINVAL'}); }
|
||||
data.teamId = teamId;
|
||||
if (data.teamId !== -1) { data.teamId = teamId; }
|
||||
else { delete data.teamId; }
|
||||
Cryptpad.userObjectCommand(data, cb);
|
||||
});
|
||||
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {
|
||||
|
|
Loading…
Reference in New Issue