Merge branch 'staging' of github.com:xwiki-labs/cryptpad into teams-server-features
This commit is contained in:
@@ -462,6 +462,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
&:empty {
|
||||||
|
margin: 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.cp-share-friend {
|
.cp-share-friend {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
@@ -493,6 +497,11 @@
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.cp-ownership {
|
||||||
|
& > label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,14 @@ commands.ADD_OWNERS = function (meta, args) {
|
|||||||
throw new Error("METADATA_NONSENSE_OWNERS");
|
throw new Error("METADATA_NONSENSE_OWNERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
args.forEach(function (owner) {
|
args.forEach(function (owner) {
|
||||||
if (meta.owners.indexOf(owner) >= 0) { return; }
|
if (meta.owners.indexOf(owner) >= 0) { return; }
|
||||||
meta.owners.push(owner);
|
meta.owners.push(owner);
|
||||||
|
changed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ["RM_OWNERS", ["CrufexqXcY-z+eKJlEbNELVy5Sb7E-EAAEFI8GnEtZ0="], 1561623439989]
|
// ["RM_OWNERS", ["CrufexqXcY-z+eKJlEbNELVy5Sb7E-EAAEFI8GnEtZ0="], 1561623439989]
|
||||||
@@ -45,13 +49,24 @@ commands.RM_OWNERS = function (meta, args) {
|
|||||||
throw new Error("METADATA_NONSENSE_OWNERS");
|
throw new Error("METADATA_NONSENSE_OWNERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
// remove owners one by one
|
// remove owners one by one
|
||||||
// we assume there are no duplicates
|
// we assume there are no duplicates
|
||||||
args.forEach(function (owner) {
|
args.forEach(function (owner) {
|
||||||
var index = meta.owners.indexOf(owner);
|
var index = meta.owners.indexOf(owner);
|
||||||
if (index < 0) { return; }
|
if (index < 0) { return; }
|
||||||
|
if (meta.mailbox) {
|
||||||
|
if (typeof(meta.mailbox) === "string") {
|
||||||
|
delete meta.mailbox;
|
||||||
|
} else {
|
||||||
|
delete meta.mailbox[owner];
|
||||||
|
}
|
||||||
|
}
|
||||||
meta.owners.splice(index, 1);
|
meta.owners.splice(index, 1);
|
||||||
|
changed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ["ADD_PENDING_OWNERS", ["7eEqelGso3EBr5jHlei6av4r9w2B9XZiGGwA1EgZ-5I="], 1561623438989]
|
// ["ADD_PENDING_OWNERS", ["7eEqelGso3EBr5jHlei6av4r9w2B9XZiGGwA1EgZ-5I="], 1561623438989]
|
||||||
@@ -67,16 +82,20 @@ commands.ADD_PENDING_OWNERS = function (meta, args) {
|
|||||||
throw new Error("METADATA_NONSENSE_PENDING_OWNERS");
|
throw new Error("METADATA_NONSENSE_PENDING_OWNERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
// Add pending_owners array if it doesn't exist
|
// Add pending_owners array if it doesn't exist
|
||||||
if (!meta.pending_owners) {
|
if (!meta.pending_owners) {
|
||||||
meta.pending_owners = deduplicate(args);
|
meta.pending_owners = deduplicate(args);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
// or fill it
|
// or fill it
|
||||||
args.forEach(function (owner) {
|
args.forEach(function (owner) {
|
||||||
if (meta.pending_owners.indexOf(owner) >= 0) { return; }
|
if (meta.pending_owners.indexOf(owner) >= 0) { return; }
|
||||||
meta.pending_owners.push(owner);
|
meta.pending_owners.push(owner);
|
||||||
|
changed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ["RM_PENDING_OWNERS", ["CrufexqXcY-z+eKJlEbNELVy5Sb7E-EAAEFI8GnEtZ0="], 1561623439989]
|
// ["RM_PENDING_OWNERS", ["CrufexqXcY-z+eKJlEbNELVy5Sb7E-EAAEFI8GnEtZ0="], 1561623439989]
|
||||||
@@ -90,13 +109,17 @@ commands.RM_PENDING_OWNERS = function (meta, args) {
|
|||||||
throw new Error("METADATA_NONSENSE_PENDING_OWNERS");
|
throw new Error("METADATA_NONSENSE_PENDING_OWNERS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
// remove owners one by one
|
// remove owners one by one
|
||||||
// we assume there are no duplicates
|
// we assume there are no duplicates
|
||||||
args.forEach(function (owner) {
|
args.forEach(function (owner) {
|
||||||
var index = meta.pending_owners.indexOf(owner);
|
var index = meta.pending_owners.indexOf(owner);
|
||||||
if (index < 0) { return; }
|
if (index < 0) { return; }
|
||||||
meta.pending_owners.splice(index, 1);
|
meta.pending_owners.splice(index, 1);
|
||||||
|
changed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ["RESET_OWNERS", ["7eEqelGso3EBr5jHlei6av4r9w2B9XZiGGwA1EgZ-5I="], 1561623439989]
|
// ["RESET_OWNERS", ["7eEqelGso3EBr5jHlei6av4r9w2B9XZiGGwA1EgZ-5I="], 1561623439989]
|
||||||
@@ -112,6 +135,41 @@ commands.RESET_OWNERS = function (meta, args) {
|
|||||||
|
|
||||||
// overwrite the existing owners with the new one
|
// overwrite the existing owners with the new one
|
||||||
meta.owners = deduplicate(args);
|
meta.owners = deduplicate(args);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ["ADD_MAILBOX", {"7eEqelGso3EBr5jHlei6av4r9w2B9XZiGGwA1EgZ-5I=": mailbox, ...}, 1561623439989]
|
||||||
|
commands.ADD_MAILBOX = function (meta, args) {
|
||||||
|
// expect a new array, even if it's empty
|
||||||
|
if (!args || typeof(args) !== "object") {
|
||||||
|
throw new Error('METADATA_INVALID_MAILBOX');
|
||||||
|
}
|
||||||
|
// assume there are owners to start
|
||||||
|
if (!Array.isArray(meta.owners)) {
|
||||||
|
throw new Error("METADATA_NONSENSE_OWNERS");
|
||||||
|
}
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
|
|
||||||
|
// For each mailbox we try to add, check if the associated edPublic is an owner
|
||||||
|
// If they are, add or replace the mailbox
|
||||||
|
Object.keys(args).forEach(function (edPublic) {
|
||||||
|
if (meta.owners.indexOf(edPublic) === -1) { return; }
|
||||||
|
|
||||||
|
if (typeof(meta.mailbox) === "string") {
|
||||||
|
var str = meta.mailbox;
|
||||||
|
meta.mailbox = {};
|
||||||
|
meta.mailbox[meta.owners[0]] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure mailbox is defined
|
||||||
|
if (!meta.mailbox) { meta.mailbox = {}; }
|
||||||
|
|
||||||
|
meta.mailbox[edPublic] = args[edPublic];
|
||||||
|
changed = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.UPDATE_EXPIRATION = function () {
|
commands.UPDATE_EXPIRATION = function () {
|
||||||
@@ -127,7 +185,7 @@ var handleCommand = Meta.handleCommand = function (meta, line) {
|
|||||||
throw new Error("METADATA_UNSUPPORTED_COMMAND");
|
throw new Error("METADATA_UNSUPPORTED_COMMAND");
|
||||||
}
|
}
|
||||||
|
|
||||||
commands[command](meta, args);
|
return commands[command](meta, args);
|
||||||
};
|
};
|
||||||
Meta.commands = Object.keys(commands);
|
Meta.commands = Object.keys(commands);
|
||||||
|
|
||||||
|
|||||||
10
rpc.js
10
rpc.js
@@ -340,6 +340,7 @@ var getMetadata = function (Env, channel, cb) {
|
|||||||
value: value
|
value: value
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
// XXX global saferphore may cause issues here, a queue "per channel" is probably better
|
||||||
var metadataSem = Saferphore.create(1);
|
var metadataSem = Saferphore.create(1);
|
||||||
var setMetadata = function (Env, data, unsafeKey, cb) {
|
var setMetadata = function (Env, data, unsafeKey, cb) {
|
||||||
var channel = data.channel;
|
var channel = data.channel;
|
||||||
@@ -382,13 +383,20 @@ var setMetadata = function (Env, data, unsafeKey, cb) {
|
|||||||
|
|
||||||
// Add the new metadata line
|
// Add the new metadata line
|
||||||
var line = [command, data.value, +new Date()];
|
var line = [command, data.value, +new Date()];
|
||||||
|
var changed = false;
|
||||||
try {
|
try {
|
||||||
Meta.handleCommand(metadata, line);
|
changed = Meta.handleCommand(metadata, line);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
g();
|
g();
|
||||||
return void cb(e);
|
return void cb(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if your command is valid but it didn't result in any change to the metadata,
|
||||||
|
// call back now and don't write any "useless" line to the log
|
||||||
|
if (!changed) {
|
||||||
|
g();
|
||||||
|
return void cb(void 0, metadata);
|
||||||
|
}
|
||||||
Env.msgStore.writeMetadata(channel, JSON.stringify(line), function (e) {
|
Env.msgStore.writeMetadata(channel, JSON.stringify(line), function (e) {
|
||||||
g();
|
g();
|
||||||
if (e) {
|
if (e) {
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ define([
|
|||||||
store.messenger.updateMyData();
|
store.messenger.updateMyData();
|
||||||
}
|
}
|
||||||
var myData = createData(store.proxy);
|
var myData = createData(store.proxy);
|
||||||
|
if (store.proxy.friends) {
|
||||||
|
store.proxy.friends.me = myData;
|
||||||
|
}
|
||||||
var todo = function (friend) {
|
var todo = function (friend) {
|
||||||
if (!friend || !friend.notifications) { return; }
|
if (!friend || !friend.notifications) { return; }
|
||||||
myData.channel = friend.channel;
|
myData.channel = friend.channel;
|
||||||
|
|||||||
@@ -230,6 +230,11 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
messenger.onFriendUpdate = function (curve) {
|
||||||
|
var friend = getFriend(proxy, curve);
|
||||||
|
checkFriendData(curve, friend, friend.channel);
|
||||||
|
};
|
||||||
|
|
||||||
// Id message allows us to map a netfluxId with a public curve key
|
// Id message allows us to map a netfluxId with a public curve key
|
||||||
var onIdMessage = function (msg, sender) {
|
var onIdMessage = function (msg, sender) {
|
||||||
var channel, parsed0;
|
var channel, parsed0;
|
||||||
@@ -374,12 +379,14 @@ define([
|
|||||||
|| mySyncData.profile !== myData.profile
|
|| mySyncData.profile !== myData.profile
|
||||||
|| mySyncData.avatar !== myData.avatar) {
|
|| mySyncData.avatar !== myData.avatar) {
|
||||||
delete myData.channel;
|
delete myData.channel;
|
||||||
Object.keys(channels).forEach(function (chan) {
|
Object.keys(friends).forEach(function (curve) {
|
||||||
var channel = channels[chan];
|
var friend = friends[curve];
|
||||||
|
var chan = friend.channel;
|
||||||
|
if (friend.notifications) { return; }
|
||||||
|
if (!chan) { return; }
|
||||||
|
|
||||||
if (!channel) {
|
var channel = channels[chan];
|
||||||
return void console.error('NO_SUCH_CHANNEL');
|
if (!channel) { return; }
|
||||||
}
|
|
||||||
if (channel.readOnly) { return; }
|
if (channel.readOnly) { return; }
|
||||||
|
|
||||||
var msg = [Types.update, myData.curvePublic, +new Date(), myData];
|
var msg = [Types.update, myData.curvePublic, +new Date(), myData];
|
||||||
@@ -397,7 +404,6 @@ define([
|
|||||||
info: myData,
|
info: myData,
|
||||||
types: ['displayName', 'profile', 'avatar'],
|
types: ['displayName', 'profile', 'avatar'],
|
||||||
});
|
});
|
||||||
friends.me = myData;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -71,56 +71,22 @@ define([
|
|||||||
var getPropertiesData = function (common, cb) {
|
var getPropertiesData = function (common, cb) {
|
||||||
var data = {};
|
var data = {};
|
||||||
NThen(function (waitFor) {
|
NThen(function (waitFor) {
|
||||||
common.getPadAttribute('password', waitFor(function (err, val) {
|
|
||||||
data.password = val;
|
|
||||||
}));
|
|
||||||
}).nThen(function (waitFor) {
|
|
||||||
var base = common.getMetadataMgr().getPrivateData().origin;
|
var base = common.getMetadataMgr().getPrivateData().origin;
|
||||||
// XXX getFileData?
|
common.getPadAttribute('', waitFor(function (err, val) {
|
||||||
// XXX getPadMetadata
|
if (err || !val) {
|
||||||
common.getPadAttribute('href', waitFor(function (err, val) {
|
waitFor.abort();
|
||||||
if (!val) { return; }
|
return void cb(err || 'EEMPTY');
|
||||||
data.href = base + val;
|
}
|
||||||
}));
|
Util.extend(data, val);
|
||||||
common.getPadAttribute('roHref', waitFor(function (err, val) {
|
if (data.href) { data.href = base + data.href; }
|
||||||
if (!val) { return; }
|
if (data.roHref) { data.roHref = base + data.roHref; }
|
||||||
data.roHref = base + val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('channel', waitFor(function (err, val) {
|
|
||||||
data.channel = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('rtChannel', waitFor(function (err, val) {
|
|
||||||
data.rtChannel = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('lastVersion', waitFor(function (err, val) {
|
|
||||||
data.lastVersion = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('atime', waitFor(function (err, val) {
|
|
||||||
data.atime = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('ctime', waitFor(function (err, val) {
|
|
||||||
data.ctime = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('title', waitFor(function (err, val) {
|
|
||||||
data.title = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('tags', waitFor(function (err, val) {
|
|
||||||
data.tags = val;
|
|
||||||
}));
|
}));
|
||||||
common.getPadMetadata(null, waitFor(function (obj) {
|
common.getPadMetadata(null, waitFor(function (obj) {
|
||||||
console.log(obj);
|
|
||||||
if (obj && obj.error) { return; }
|
if (obj && obj.error) { return; }
|
||||||
data.owners = obj.owners;
|
data.owners = obj.owners;
|
||||||
data.expire = obj.expire;
|
data.expire = obj.expire;
|
||||||
data.pending_owners = obj.pending_owners;
|
data.pending_owners = obj.pending_owners;
|
||||||
}));
|
}));
|
||||||
/*
|
|
||||||
common.getPadAttribute('owners', waitFor(function (err, val) {
|
|
||||||
data.owners = val;
|
|
||||||
}));
|
|
||||||
common.getPadAttribute('expire', waitFor(function (err, val) {
|
|
||||||
data.expire = val;
|
|
||||||
}));*/
|
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
cb(void 0, data);
|
cb(void 0, data);
|
||||||
});
|
});
|
||||||
@@ -132,20 +98,20 @@ define([
|
|||||||
var user = common.getMetadataMgr().getUserData();
|
var user = common.getMetadataMgr().getUserData();
|
||||||
var edPublic = priv.edPublic;
|
var edPublic = priv.edPublic;
|
||||||
var channel = data.channel;
|
var channel = data.channel;
|
||||||
var owners = data.owners;
|
var owners = data.owners || [];
|
||||||
var pending_owners = data.pending_owners;
|
var pending_owners = data.pending_owners || [];
|
||||||
|
|
||||||
var redrawAll = function () {};
|
var redrawAll = function () {};
|
||||||
|
|
||||||
var div1 = h('div.cp-share-friends.cp-share-column');
|
var div1 = h('div.cp-share-friends.cp-share-column.cp-ownership');
|
||||||
var div2 = h('div.cp-share-friends.cp-share-column');
|
var div2 = h('div.cp-share-friends.cp-share-column.cp-ownership');
|
||||||
var $div1 = $(div1);
|
var $div1 = $(div1);
|
||||||
var $div2 = $(div2);
|
var $div2 = $(div2);
|
||||||
|
|
||||||
// Remove owner column
|
// Remove owner column
|
||||||
var drawRemove = function (pending) {
|
var drawRemove = function (pending) {
|
||||||
var _owners = {};
|
var _owners = {};
|
||||||
var o = pending ? pending_owners : owners;
|
var o = (pending ? pending_owners : owners) || [];
|
||||||
o.forEach(function (ed) {
|
o.forEach(function (ed) {
|
||||||
var f;
|
var f;
|
||||||
Object.keys(friends).some(function (c) {
|
Object.keys(friends).some(function (c) {
|
||||||
@@ -154,20 +120,25 @@ define([
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (ed === edPublic) {
|
||||||
|
f = f || user;
|
||||||
|
if (f.name) {
|
||||||
|
f.displayName = f.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
_owners[ed] = f || {
|
_owners[ed] = f || {
|
||||||
displayName: 'Unknown user: '+ ed, // XXX
|
displayName: Messages._getKey('owner_unknownUser', [ed]),
|
||||||
notifications: true,
|
notifications: true,
|
||||||
edPublic: ed,
|
edPublic: ed,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
var msg = pending ? 'Remove a pending owner:'
|
var msg = pending ? Messages.owner_removePendingText
|
||||||
: 'Remove an existing owner:'; // XXX
|
: Messages.owner_removeText;
|
||||||
var removeCol = UIElements.getFriendsList(msg, {
|
var removeCol = UIElements.getFriendsList(msg, {
|
||||||
common: common,
|
common: common,
|
||||||
friends: _owners,
|
friends: _owners,
|
||||||
noFilter: true
|
noFilter: true
|
||||||
}, function () {
|
}, function () {
|
||||||
console.log(arguments);
|
|
||||||
});
|
});
|
||||||
var $div = $(removeCol.div);
|
var $div = $(removeCol.div);
|
||||||
var others1 = removeCol.others;
|
var others1 = removeCol.others;
|
||||||
@@ -184,12 +155,13 @@ define([
|
|||||||
});
|
});
|
||||||
// When clicking on the remove button, we check the selected users.
|
// When clicking on the remove button, we check the selected users.
|
||||||
// If you try to remove yourself, we'll display an additional warning message
|
// If you try to remove yourself, we'll display an additional warning message
|
||||||
var btnMsg = pending ? 'Remove pending owners' : 'Remove owners'; // XXX
|
var btnMsg = pending ? Messages.owner_removePendingButton : Messages.owner_removeButton;
|
||||||
var removeButton = h('button.no-margin', btnMsg);
|
var removeButton = h('button.no-margin', btnMsg);
|
||||||
$(removeButton).click(function () {
|
$(removeButton).click(function () {
|
||||||
// Check selection
|
// Check selection
|
||||||
var $sel = $div.find('.cp-share-friend.cp-selected');
|
var $sel = $div.find('.cp-share-friend.cp-selected');
|
||||||
var sel = $sel.toArray();
|
var sel = $sel.toArray();
|
||||||
|
if (!sel.length) { return; }
|
||||||
var me = false;
|
var me = false;
|
||||||
var toRemove = sel.map(function (el) {
|
var toRemove = sel.map(function (el) {
|
||||||
var ed = $(el).attr('data-ed');
|
var ed = $(el).attr('data-ed');
|
||||||
@@ -197,25 +169,54 @@ define([
|
|||||||
if (ed === edPublic) { me = true; }
|
if (ed === edPublic) { me = true; }
|
||||||
return ed;
|
return ed;
|
||||||
}).filter(function (x) { return x; });
|
}).filter(function (x) { return x; });
|
||||||
// Send the command
|
NThen(function (waitFor) {
|
||||||
var send = function () {
|
var msg = me ? Messages.owner_removeMeConfirm : Messages.owner_removeConfirm;
|
||||||
|
UI.confirm(msg, waitFor(function (yes) {
|
||||||
|
if (!yes) {
|
||||||
|
waitFor.abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
// Send the command
|
||||||
sframeChan.query('Q_SET_PAD_METADATA', {
|
sframeChan.query('Q_SET_PAD_METADATA', {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
command: pending ? 'RM_PENDING_OWNERS' : 'RM_OWNERS',
|
command: pending ? 'RM_PENDING_OWNERS' : 'RM_OWNERS',
|
||||||
value: toRemove
|
value: toRemove
|
||||||
}, function (err, res) {
|
}, waitFor(function (err, res) {
|
||||||
err = err || (res && res.error);
|
err = err || (res && res.error);
|
||||||
if (err) { return void UI.warn('ERROR' + err); } // XXX
|
if (err) {
|
||||||
redrawAll();
|
waitFor.abort();
|
||||||
UI.log('DONE'); // XXX
|
redrawAll();
|
||||||
|
var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden
|
||||||
|
: Messages.error;
|
||||||
|
return void UI.warn(text);
|
||||||
|
}
|
||||||
|
UI.log(Messages.saved);
|
||||||
|
}));
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
sel.forEach(function (el) {
|
||||||
|
var friend = friends[$(el).attr('data-curve')];
|
||||||
|
if (!friend) { return; }
|
||||||
|
common.mailbox.sendTo("RM_OWNER", {
|
||||||
|
channel: channel,
|
||||||
|
title: data.title,
|
||||||
|
pending: pending,
|
||||||
|
user: {
|
||||||
|
displayName: user.name,
|
||||||
|
avatar: user.avatar,
|
||||||
|
profile: user.profile,
|
||||||
|
notifications: user.notifications,
|
||||||
|
curvePublic: user.curvePublic,
|
||||||
|
edPublic: priv.edPublic
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
channel: friend.notifications,
|
||||||
|
curvePublic: friend.curvePublic
|
||||||
|
}, waitFor());
|
||||||
});
|
});
|
||||||
};
|
}).nThen(function () {
|
||||||
var msg = me ?
|
redrawAll();
|
||||||
"Are you sure? You're going to give up on your rights, this can't be undone!" :
|
|
||||||
"Are you sure?"; // XXX
|
|
||||||
UI.confirm(msg, function (yes) {
|
|
||||||
if (!yes) { return; }
|
|
||||||
send();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$div.append(h('p', removeButton));
|
$div.append(h('p', removeButton));
|
||||||
@@ -226,16 +227,16 @@ define([
|
|||||||
var drawAdd = function () {
|
var drawAdd = function () {
|
||||||
var _friends = JSON.parse(JSON.stringify(friends));
|
var _friends = JSON.parse(JSON.stringify(friends));
|
||||||
Object.keys(_friends).forEach(function (curve) {
|
Object.keys(_friends).forEach(function (curve) {
|
||||||
if (owners.indexOf(_friends[curve].edPublic) !== -1) {
|
if (owners.indexOf(_friends[curve].edPublic) !== -1 ||
|
||||||
|
pending_owners.indexOf(_friends[curve].edPublic) !== -1) {
|
||||||
delete _friends[curve];
|
delete _friends[curve];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var addCol = UIElements.getFriendsList('Ask a friend to be an owner.', {
|
var addCol = UIElements.getFriendsList(Messages.owner_addText, {
|
||||||
common: common,
|
common: common,
|
||||||
friends: _friends
|
friends: _friends
|
||||||
}, function () {
|
}, function () {
|
||||||
// XXX onSelect...
|
//console.log(arguments);
|
||||||
console.log(arguments);
|
|
||||||
});
|
});
|
||||||
$div2 = $(addCol.div);
|
$div2 = $(addCol.div);
|
||||||
var others2 = addCol.others;
|
var others2 = addCol.others;
|
||||||
@@ -249,20 +250,20 @@ define([
|
|||||||
order = order ? 'order:'+order : '';
|
order = order ? 'order:'+order : '';
|
||||||
$(this).removeClass('cp-selected').attr('style', order);
|
$(this).removeClass('cp-selected').attr('style', order);
|
||||||
}
|
}
|
||||||
// XXX onSelect...
|
|
||||||
});
|
});
|
||||||
// When clicking on the add button, we get the selected users.
|
// When clicking on the add button, we get the selected users.
|
||||||
var addButton = h('button.no-margin', 'Add owners'); // XXX
|
var addButton = h('button.no-margin', Messages.owner_addButton);
|
||||||
$(addButton).click(function () {
|
$(addButton).click(function () {
|
||||||
// Check selection
|
// Check selection
|
||||||
var $sel = $div2.find('.cp-share-friend.cp-selected');
|
var $sel = $div2.find('.cp-share-friend.cp-selected');
|
||||||
var sel = $sel.toArray();
|
var sel = $sel.toArray();
|
||||||
|
if (!sel.length) { return; }
|
||||||
var toAdd = sel.map(function (el) {
|
var toAdd = sel.map(function (el) {
|
||||||
return friends[$(el).attr('data-curve')].edPublic;
|
return friends[$(el).attr('data-curve')].edPublic;
|
||||||
}).filter(function (x) { return x; });
|
}).filter(function (x) { return x; });
|
||||||
|
|
||||||
NThen(function (waitFor) {
|
NThen(function (waitFor) {
|
||||||
var msg = "Are you sure?"; // XXX
|
var msg = Messages.owner_addConfirm;
|
||||||
UI.confirm(msg, waitFor(function (yes) {
|
UI.confirm(msg, waitFor(function (yes) {
|
||||||
if (!yes) {
|
if (!yes) {
|
||||||
waitFor.abort();
|
waitFor.abort();
|
||||||
@@ -270,23 +271,22 @@ define([
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
console.log('koko');
|
|
||||||
// Send the command
|
// Send the command
|
||||||
sframeChan.query('Q_SET_PAD_METADATA', {
|
sframeChan.query('Q_SET_PAD_METADATA', {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
command: 'ADD_PENDING_OWNERS',
|
command: 'ADD_PENDING_OWNERS',
|
||||||
value: toAdd
|
value: toAdd
|
||||||
}, waitFor(function (err, res) {
|
}, waitFor(function (err, res) {
|
||||||
console.error(arguments);
|
|
||||||
err = err || (res && res.error);
|
err = err || (res && res.error);
|
||||||
if (err) {
|
if (err) {
|
||||||
waitFor.abort();
|
waitFor.abort();
|
||||||
return void UI.warn('ERROR' + err);
|
redrawAll();
|
||||||
} // XXX
|
var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden
|
||||||
|
: Messages.error;
|
||||||
|
return void UI.warn(text);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
console.log('okok');
|
|
||||||
// TODO send notifications
|
|
||||||
sel.forEach(function (el) {
|
sel.forEach(function (el) {
|
||||||
var friend = friends[$(el).attr('data-curve')];
|
var friend = friends[$(el).attr('data-curve')];
|
||||||
if (!friend) { return; }
|
if (!friend) { return; }
|
||||||
@@ -310,28 +310,42 @@ define([
|
|||||||
});
|
});
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
redrawAll();
|
redrawAll();
|
||||||
UI.log('DONE'); // XXX
|
UI.log(Messages.saved);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$div2.append(h('p', addButton));
|
$div2.append(h('p', addButton));
|
||||||
return $div2;
|
return $div2;
|
||||||
};
|
};
|
||||||
|
|
||||||
redrawAll = function () {
|
redrawAll = function (md) {
|
||||||
$div1.empty();
|
var todo = function (obj) {
|
||||||
$div2.empty();
|
|
||||||
common.getPadMetadata(null, function (obj) {
|
|
||||||
if (obj && obj.error) { return; }
|
if (obj && obj.error) { return; }
|
||||||
owners = obj.owners;
|
owners = obj.owners || [];
|
||||||
pending_owners = obj.pending_owners;
|
pending_owners = obj.pending_owners || [];
|
||||||
|
$div1.empty();
|
||||||
|
$div2.empty();
|
||||||
$div1.append(drawRemove(false)).append(drawRemove(true));
|
$div1.append(drawRemove(false)).append(drawRemove(true));
|
||||||
$div2.append(drawAdd());
|
$div2.append(drawAdd());
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (md) { return void todo(md); }
|
||||||
|
common.getPadMetadata({
|
||||||
|
channel: data.channel
|
||||||
|
}, todo);
|
||||||
};
|
};
|
||||||
|
|
||||||
$div1.append(drawRemove(false)).append(drawRemove(true));
|
$div1.append(drawRemove(false)).append(drawRemove(true));
|
||||||
$div2.append(drawAdd());
|
$div2.append(drawAdd());
|
||||||
|
|
||||||
|
var handler = sframeChan.on('EV_RT_METADATA', function (md) {
|
||||||
|
if (!$div1.length) {
|
||||||
|
return void handler.stop();
|
||||||
|
}
|
||||||
|
owners = md.owners || [];
|
||||||
|
pending_owners = md.pending_owners || [];
|
||||||
|
redrawAll(md);
|
||||||
|
});
|
||||||
|
|
||||||
// Create modal
|
// Create modal
|
||||||
var link = h('div.cp-share-columns', [
|
var link = h('div.cp-share-columns', [
|
||||||
div1,
|
div1,
|
||||||
@@ -341,146 +355,165 @@ define([
|
|||||||
]);
|
]);
|
||||||
var linkButtons = [{
|
var linkButtons = [{
|
||||||
className: 'cancel',
|
className: 'cancel',
|
||||||
name: 'CLOSE', // XXX existing key?
|
name: Messages.filePicker_close,
|
||||||
onClick: function () {},
|
onClick: function () {},
|
||||||
keys: [27]
|
keys: [27]
|
||||||
}];
|
}];
|
||||||
return UI.dialog.customModal(link, {buttons: linkButtons});
|
return UI.dialog.customModal(link, {buttons: linkButtons});
|
||||||
};
|
};
|
||||||
var getRightsProperties = function (common, data, cb) {
|
var getRightsProperties = function (common, data, cb) {
|
||||||
var $d = $('<div>');
|
var $div = $('<div>');
|
||||||
if (!data) { return void cb(void 0, $d); }
|
if (!data) { return void cb(void 0, $div); }
|
||||||
|
|
||||||
$('<label>', {'for': 'cp-app-prop-owners'}).text(Messages.creation_owners)
|
var draw = function () {
|
||||||
.appendTo($d);
|
var $d = $('<div>');
|
||||||
var owners = Messages.creation_noOwner;
|
$('<label>', {'for': 'cp-app-prop-owners'}).text(Messages.creation_owners)
|
||||||
var priv = common.getMetadataMgr().getPrivateData();
|
|
||||||
var edPublic = priv.edPublic;
|
|
||||||
var owned = false;
|
|
||||||
if (data.owners && data.owners.length) {
|
|
||||||
if (data.owners.indexOf(edPublic) !== -1) {
|
|
||||||
owned = true;
|
|
||||||
}
|
|
||||||
var names = [];
|
|
||||||
var strangers = 0;
|
|
||||||
data.owners.forEach(function (ed) {
|
|
||||||
// If a friend is an owner, add their name to the list
|
|
||||||
// otherwise, increment the list of strangers
|
|
||||||
if (ed === edPublic) {
|
|
||||||
names.push(Messages.yourself);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Object.keys(priv.friends || {}).some(function (c) {
|
|
||||||
var friend = priv.friends[c] || {};
|
|
||||||
if (friend.edPublic !== ed || c === 'me') { return; }
|
|
||||||
names.push(friend.displayName);
|
|
||||||
return true;
|
|
||||||
})) {
|
|
||||||
strangers++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (strangers) {
|
|
||||||
names.push(Messages._getKey('properties_unknownUser', [strangers]));
|
|
||||||
}
|
|
||||||
owners = names.join(', ');
|
|
||||||
}
|
|
||||||
$d.append(UI.dialog.selectable(owners, {
|
|
||||||
id: 'cp-app-prop-owners',
|
|
||||||
}));
|
|
||||||
if (owned) {
|
|
||||||
var manageOwners = h('button.no-margin', 'Manage owners'); // XXX
|
|
||||||
$(manageOwners).click(function () {
|
|
||||||
var modal = createOwnerModal(common, data);
|
|
||||||
UI.openCustomModal(modal, {
|
|
||||||
wide: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$d.append(h('p', manageOwners));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.noExpiration) {
|
|
||||||
var expire = Messages.creation_expireFalse;
|
|
||||||
if (data.expire && typeof (data.expire) === "number") {
|
|
||||||
expire = new Date(data.expire).toLocaleString();
|
|
||||||
}
|
|
||||||
$('<label>', {'for': 'cp-app-prop-expire'}).text(Messages.creation_expiration)
|
|
||||||
.appendTo($d);
|
.appendTo($d);
|
||||||
$d.append(UI.dialog.selectable(expire, {
|
var owners = Messages.creation_noOwner;
|
||||||
id: 'cp-app-prop-expire',
|
var priv = common.getMetadataMgr().getPrivateData();
|
||||||
}));
|
var edPublic = priv.edPublic;
|
||||||
}
|
var owned = false;
|
||||||
|
if (data.owners && data.owners.length) {
|
||||||
if (!data.noPassword) {
|
if (data.owners.indexOf(edPublic) !== -1) {
|
||||||
var hasPassword = data.password;
|
owned = true;
|
||||||
if (hasPassword) {
|
|
||||||
$('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue)
|
|
||||||
.appendTo($d);
|
|
||||||
var password = UI.passwordInput({
|
|
||||||
id: 'cp-app-prop-password',
|
|
||||||
readonly: 'readonly'
|
|
||||||
});
|
|
||||||
var $pwInput = $(password).find('.cp-password-input');
|
|
||||||
$pwInput.val(data.password).click(function () {
|
|
||||||
$pwInput[0].select();
|
|
||||||
});
|
|
||||||
$d.append(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
|
||||||
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad' && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
|
||||||
var sframeChan = common.getSframeChannel();
|
|
||||||
var changePwTitle = Messages.properties_changePassword;
|
|
||||||
var changePwConfirm = Messages.properties_confirmChange;
|
|
||||||
if (!hasPassword) {
|
|
||||||
changePwTitle = Messages.properties_addPassword;
|
|
||||||
changePwConfirm = Messages.properties_confirmNew;
|
|
||||||
}
|
}
|
||||||
$('<label>', {'for': 'cp-app-prop-change-password'})
|
var names = [];
|
||||||
.text(changePwTitle).appendTo($d);
|
var strangers = 0;
|
||||||
var newPassword = UI.passwordInput({
|
data.owners.forEach(function (ed) {
|
||||||
id: 'cp-app-prop-change-password',
|
// If a friend is an owner, add their name to the list
|
||||||
style: 'flex: 1;'
|
// otherwise, increment the list of strangers
|
||||||
});
|
if (ed === edPublic) {
|
||||||
var passwordOk = h('button', Messages.properties_changePasswordButton);
|
names.push(Messages.yourself);
|
||||||
var changePass = h('span.cp-password-container', [
|
return;
|
||||||
newPassword,
|
|
||||||
passwordOk
|
|
||||||
]);
|
|
||||||
$(passwordOk).click(function () {
|
|
||||||
var newPass = $(newPassword).find('input').val();
|
|
||||||
if (data.password === newPass ||
|
|
||||||
(!data.password && !newPass)) {
|
|
||||||
return void UI.alert(Messages.properties_passwordSame);
|
|
||||||
}
|
}
|
||||||
UI.confirm(changePwConfirm, function (yes) {
|
if (!Object.keys(priv.friends || {}).some(function (c) {
|
||||||
if (!yes) { return; }
|
var friend = priv.friends[c] || {};
|
||||||
sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
|
if (friend.edPublic !== ed || c === 'me') { return; }
|
||||||
href: data.href || data.roHref,
|
names.push(friend.displayName);
|
||||||
password: newPass
|
return true;
|
||||||
}, function (err, data) {
|
})) {
|
||||||
if (err || data.error) {
|
strangers++;
|
||||||
return void UI.alert(Messages.properties_passwordError);
|
}
|
||||||
}
|
});
|
||||||
UI.findOKButton().click();
|
if (strangers) {
|
||||||
// If we didn't have a password, we have to add the /p/
|
names.push(Messages._getKey('properties_unknownUser', [strangers]));
|
||||||
// If we had a password and we changed it to a new one, we just have to reload
|
}
|
||||||
// If we had a password and we removed it, we have to remove the /p/
|
owners = names.join(', ');
|
||||||
if (data.warning) {
|
}
|
||||||
return void UI.alert(Messages.properties_passwordWarning, function () {
|
$d.append(UI.dialog.selectable(owners, {
|
||||||
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
id: 'cp-app-prop-owners',
|
||||||
}, {force: true});
|
}));
|
||||||
}
|
if (owned) {
|
||||||
return void UI.alert(Messages.properties_passwordSuccess, function () {
|
var manageOwners = h('button.no-margin', Messages.owner_openModalButton);
|
||||||
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
$(manageOwners).click(function () {
|
||||||
}, {force: true});
|
var modal = createOwnerModal(common, data);
|
||||||
});
|
UI.openCustomModal(modal, {
|
||||||
|
wide: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$d.append(changePass);
|
$d.append(h('p', manageOwners));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
cb(void 0, $d);
|
if (!data.noExpiration) {
|
||||||
|
var expire = Messages.creation_expireFalse;
|
||||||
|
if (data.expire && typeof (data.expire) === "number") {
|
||||||
|
expire = new Date(data.expire).toLocaleString();
|
||||||
|
}
|
||||||
|
$('<label>', {'for': 'cp-app-prop-expire'}).text(Messages.creation_expiration)
|
||||||
|
.appendTo($d);
|
||||||
|
$d.append(UI.dialog.selectable(expire, {
|
||||||
|
id: 'cp-app-prop-expire',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.noPassword) {
|
||||||
|
var hasPassword = data.password;
|
||||||
|
if (hasPassword) {
|
||||||
|
$('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue)
|
||||||
|
.appendTo($d);
|
||||||
|
var password = UI.passwordInput({
|
||||||
|
id: 'cp-app-prop-password',
|
||||||
|
readonly: 'readonly'
|
||||||
|
});
|
||||||
|
var $pwInput = $(password).find('.cp-password-input');
|
||||||
|
$pwInput.val(data.password).click(function () {
|
||||||
|
$pwInput[0].select();
|
||||||
|
});
|
||||||
|
$d.append(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||||
|
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad' && parsed.type !== "sheet") { // FIXME SHEET fix password change for sheets
|
||||||
|
var sframeChan = common.getSframeChannel();
|
||||||
|
var changePwTitle = Messages.properties_changePassword;
|
||||||
|
var changePwConfirm = Messages.properties_confirmChange;
|
||||||
|
if (!hasPassword) {
|
||||||
|
changePwTitle = Messages.properties_addPassword;
|
||||||
|
changePwConfirm = Messages.properties_confirmNew;
|
||||||
|
}
|
||||||
|
$('<label>', {'for': 'cp-app-prop-change-password'})
|
||||||
|
.text(changePwTitle).appendTo($d);
|
||||||
|
var newPassword = UI.passwordInput({
|
||||||
|
id: 'cp-app-prop-change-password',
|
||||||
|
style: 'flex: 1;'
|
||||||
|
});
|
||||||
|
var passwordOk = h('button', Messages.properties_changePasswordButton);
|
||||||
|
var changePass = h('span.cp-password-container', [
|
||||||
|
newPassword,
|
||||||
|
passwordOk
|
||||||
|
]);
|
||||||
|
$(passwordOk).click(function () {
|
||||||
|
var newPass = $(newPassword).find('input').val();
|
||||||
|
if (data.password === newPass ||
|
||||||
|
(!data.password && !newPass)) {
|
||||||
|
return void UI.alert(Messages.properties_passwordSame);
|
||||||
|
}
|
||||||
|
UI.confirm(changePwConfirm, function (yes) {
|
||||||
|
if (!yes) { return; }
|
||||||
|
sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
|
||||||
|
href: data.href || data.roHref,
|
||||||
|
password: newPass
|
||||||
|
}, function (err, data) {
|
||||||
|
if (err || data.error) {
|
||||||
|
return void UI.alert(Messages.properties_passwordError);
|
||||||
|
}
|
||||||
|
UI.findOKButton().click();
|
||||||
|
// If we didn't have a password, we have to add the /p/
|
||||||
|
// If we had a password and we changed it to a new one, we just have to reload
|
||||||
|
// If we had a password and we removed it, we have to remove the /p/
|
||||||
|
if (data.warning) {
|
||||||
|
return void UI.alert(Messages.properties_passwordWarning, function () {
|
||||||
|
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
||||||
|
}, {force: true});
|
||||||
|
}
|
||||||
|
return void UI.alert(Messages.properties_passwordSuccess, function () {
|
||||||
|
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
||||||
|
}, {force: true});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$d.append(changePass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $d;
|
||||||
|
};
|
||||||
|
|
||||||
|
var sframeChan = common.getSframeChannel();
|
||||||
|
var handler = sframeChan.on('EV_RT_METADATA', function (md) {
|
||||||
|
if (!$div.length) {
|
||||||
|
handler.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
md = JSON.parse(JSON.stringify(md));
|
||||||
|
data.owners = md.owners;
|
||||||
|
data.expire = md.expire;
|
||||||
|
data.pending_owners = md.pending_owners;
|
||||||
|
$div.empty();
|
||||||
|
$div.append(draw());
|
||||||
|
});
|
||||||
|
$div.append(draw());
|
||||||
|
|
||||||
|
cb(void 0, $div);
|
||||||
};
|
};
|
||||||
var getPadProperties = function (common, data, cb) {
|
var getPadProperties = function (common, data, cb) {
|
||||||
var $d = $('<div>');
|
var $d = $('<div>');
|
||||||
@@ -567,6 +600,8 @@ define([
|
|||||||
} else {
|
} else {
|
||||||
cb(void 0, $d);
|
cb(void 0, $d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
UIElements.getProperties = function (common, data, cb) {
|
UIElements.getProperties = function (common, data, cb) {
|
||||||
var c1;
|
var c1;
|
||||||
@@ -3068,6 +3103,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var storePopupState = false;
|
var storePopupState = false;
|
||||||
|
var autoStoreModal = {};
|
||||||
UIElements.displayStorePadPopup = function (common, data) {
|
UIElements.displayStorePadPopup = function (common, data) {
|
||||||
if (storePopupState) { return; }
|
if (storePopupState) { return; }
|
||||||
storePopupState = true;
|
storePopupState = true;
|
||||||
@@ -3087,6 +3123,8 @@ define([
|
|||||||
var initialHide = data && data.autoStore && data.autoStore === -1;
|
var initialHide = data && data.autoStore && data.autoStore === -1;
|
||||||
var modal = UI.cornerPopup(text, actions, footer, {hidden: initialHide});
|
var modal = UI.cornerPopup(text, actions, footer, {hidden: initialHide});
|
||||||
|
|
||||||
|
autoStoreModal[priv.channel] = modal;
|
||||||
|
|
||||||
$(modal.popup).find('.cp-corner-footer a').click(function (e) {
|
$(modal.popup).find('.cp-corner-footer a').click(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
common.openURL('/settings/');
|
common.openURL('/settings/');
|
||||||
@@ -3094,6 +3132,7 @@ define([
|
|||||||
|
|
||||||
$(hide).click(function () {
|
$(hide).click(function () {
|
||||||
UIElements.displayCrowdfunding(common);
|
UIElements.displayCrowdfunding(common);
|
||||||
|
delete autoStoreModal[priv.channel];
|
||||||
modal.delete();
|
modal.delete();
|
||||||
});
|
});
|
||||||
var waitingForStoringCb = false;
|
var waitingForStoringCb = false;
|
||||||
@@ -3109,6 +3148,7 @@ define([
|
|||||||
}
|
}
|
||||||
return void UI.warn(Messages.autostore_error);
|
return void UI.warn(Messages.autostore_error);
|
||||||
}
|
}
|
||||||
|
delete autoStoreModal[priv.channel];
|
||||||
modal.delete();
|
modal.delete();
|
||||||
UIElements.displayCrowdfunding(common);
|
UIElements.displayCrowdfunding(common);
|
||||||
UI.log(Messages.autostore_saved);
|
UI.log(Messages.autostore_saved);
|
||||||
@@ -3286,7 +3326,6 @@ define([
|
|||||||
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
||||||
var title = Util.fixHTML(msg.content.title);
|
var title = Util.fixHTML(msg.content.title);
|
||||||
|
|
||||||
Messages.owner_add = '{0} wants you to be an owner of the pad <b>{1}</b>. Do you accept?'; //XXX
|
|
||||||
var text = Messages._getKey('owner_add', [name, title]);
|
var text = Messages._getKey('owner_add', [name, title]);
|
||||||
|
|
||||||
var link = h('a', {
|
var link = h('a', {
|
||||||
@@ -3343,13 +3382,32 @@ define([
|
|||||||
}, function (err, res) {
|
}, function (err, res) {
|
||||||
err = err || (res && res.error);
|
err = err || (res && res.error);
|
||||||
if (err) {
|
if (err) {
|
||||||
return void UI.warn('ERROR ' + err);
|
var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden
|
||||||
} // XXX
|
: Messages.error;
|
||||||
UI.log('DONE'); // XXX
|
return void UI.warn(text);
|
||||||
|
}
|
||||||
|
UI.log(Messages.saved);
|
||||||
|
|
||||||
// Send notification to the sender
|
// Send notification to the sender
|
||||||
answer(true);
|
answer(true);
|
||||||
|
|
||||||
|
var data = JSON.parse(JSON.stringify(msg.content));
|
||||||
|
data.metadata = res;
|
||||||
|
|
||||||
|
// Add the pad to your drive
|
||||||
|
// This command will also add your mailbox to the metadata log
|
||||||
|
// The callback is called when the pad is stored, independantly of the metadata command
|
||||||
|
sframeChan.query('Q_ACCEPT_OWNERSHIP', data, function (err, res) {
|
||||||
|
if (err || (res && res.error)) {
|
||||||
|
return void console.error(err | res.error);
|
||||||
|
}
|
||||||
|
UI.log(Messages.saved);
|
||||||
|
if (autoStoreModal[data.channel]) {
|
||||||
|
autoStoreModal[data.channel].delete();
|
||||||
|
delete autoStoreModal[data.channel];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Remove yourself from the pending owners
|
// Remove yourself from the pending owners
|
||||||
sframeChan.query('Q_SET_PAD_METADATA', {
|
sframeChan.query('Q_SET_PAD_METADATA', {
|
||||||
channel: msg.content.channel,
|
channel: msg.content.channel,
|
||||||
|
|||||||
@@ -757,6 +757,7 @@ define([
|
|||||||
pad.onDisconnectEvent = Util.mkEvent();
|
pad.onDisconnectEvent = Util.mkEvent();
|
||||||
pad.onConnectEvent = Util.mkEvent();
|
pad.onConnectEvent = Util.mkEvent();
|
||||||
pad.onErrorEvent = Util.mkEvent();
|
pad.onErrorEvent = Util.mkEvent();
|
||||||
|
pad.onMetadataEvent = Util.mkEvent();
|
||||||
|
|
||||||
pad.getPadMetadata = function (data, cb) {
|
pad.getPadMetadata = function (data, cb) {
|
||||||
postMessage('GET_PAD_METADATA', data, cb);
|
postMessage('GET_PAD_METADATA', data, cb);
|
||||||
@@ -1208,6 +1209,7 @@ define([
|
|||||||
PAD_DISCONNECT: common.padRpc.onDisconnectEvent.fire,
|
PAD_DISCONNECT: common.padRpc.onDisconnectEvent.fire,
|
||||||
PAD_CONNECT: common.padRpc.onConnectEvent.fire,
|
PAD_CONNECT: common.padRpc.onConnectEvent.fire,
|
||||||
PAD_ERROR: common.padRpc.onErrorEvent.fire,
|
PAD_ERROR: common.padRpc.onErrorEvent.fire,
|
||||||
|
PAD_METADATA: common.padRpc.onMetadataEvent.fire,
|
||||||
// Drive
|
// Drive
|
||||||
DRIVE_LOG: common.drive.onLog.fire,
|
DRIVE_LOG: common.drive.onLog.fire,
|
||||||
DRIVE_CHANGE: common.drive.onChange.fire,
|
DRIVE_CHANGE: common.drive.onChange.fire,
|
||||||
|
|||||||
@@ -218,7 +218,6 @@ define([
|
|||||||
// Display the notification
|
// Display the notification
|
||||||
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
||||||
var title = Util.fixHTML(msg.content.title);
|
var title = Util.fixHTML(msg.content.title);
|
||||||
Messages.owner_request = '{0} wants you to be an owner of <b>{1}</b>'; // XXX
|
|
||||||
content.getFormatText = function () {
|
content.getFormatText = function () {
|
||||||
return Messages._getKey('owner_request', [name, title]);
|
return Messages._getKey('owner_request', [name, title]);
|
||||||
};
|
};
|
||||||
@@ -241,8 +240,6 @@ define([
|
|||||||
// Display the notification
|
// Display the notification
|
||||||
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
||||||
var title = Util.fixHTML(msg.content.title);
|
var title = Util.fixHTML(msg.content.title);
|
||||||
Messages.owner_request_accepted = '{0} has accepted your offer to be an owner of <b>{1}</b>'; // XXX
|
|
||||||
Messages.owner_request_declined = '{0} has declined your offer to be an owner of <b>{1}</b>'; // XXX
|
|
||||||
var key = 'owner_request_' + (msg.content.answer ? 'accepted' : 'declined');
|
var key = 'owner_request_' + (msg.content.answer ? 'accepted' : 'declined');
|
||||||
content.getFormatText = function () {
|
content.getFormatText = function () {
|
||||||
return Messages._getKey(key, [name, title]);
|
return Messages._getKey(key, [name, title]);
|
||||||
@@ -252,6 +249,22 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handlers['RM_OWNER'] = function (common, data) {
|
||||||
|
var content = data.content;
|
||||||
|
var msg = content.msg;
|
||||||
|
|
||||||
|
// Display the notification
|
||||||
|
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous;
|
||||||
|
var title = Util.fixHTML(msg.content.title);
|
||||||
|
var key = 'owner_removed' + (msg.content.pending ? 'Pending' : '');
|
||||||
|
content.getFormatText = function () {
|
||||||
|
return Messages._getKey(key, [name, title]);
|
||||||
|
};
|
||||||
|
if (!content.archived) {
|
||||||
|
content.dismissHandler = defaultDismiss(common, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: don't forget to fixHTML everything returned by "getFormatText"
|
// NOTE: don't forget to fixHTML everything returned by "getFormatText"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1205,7 +1205,6 @@ define([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMetadataUpdate: function (metadata) {
|
onMetadataUpdate: function (metadata) {
|
||||||
console.log('onMetadataUpdate', metadata);
|
|
||||||
channel.data = metadata || {};
|
channel.data = metadata || {};
|
||||||
var allData = store.manager.findChannel(data.channel);
|
var allData = store.manager.findChannel(data.channel);
|
||||||
allData.forEach(function (obj) {
|
allData.forEach(function (obj) {
|
||||||
@@ -1214,7 +1213,7 @@ define([
|
|||||||
obj.data.expire = +metadata.expire;
|
obj.data.expire = +metadata.expire;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//channel.bcast("PAD_METADATA", metadata);
|
channel.bcast("PAD_METADATA", metadata);
|
||||||
},
|
},
|
||||||
crypto: {
|
crypto: {
|
||||||
// The encryption and decryption is done in the outer window.
|
// The encryption and decryption is done in the outer window.
|
||||||
@@ -1374,7 +1373,6 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
Store.getPadMetadata = function (clientId, data, cb) {
|
Store.getPadMetadata = function (clientId, data, cb) {
|
||||||
console.log(data);
|
|
||||||
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
|
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
|
||||||
var channel = channels[data.channel];
|
var channel = channels[data.channel];
|
||||||
if (!channel) { return void cb({ error: 'ENOTFOUND' }); }
|
if (!channel) { return void cb({ error: 'ENOTFOUND' }); }
|
||||||
@@ -1397,7 +1395,6 @@ define([
|
|||||||
cb(channel.data || {});
|
cb(channel.data || {});
|
||||||
};
|
};
|
||||||
Store.setPadMetadata = function (clientId, data, cb) {
|
Store.setPadMetadata = function (clientId, data, cb) {
|
||||||
console.log(data);
|
|
||||||
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
|
if (!data.channel) { return void cb({ error: 'ENOTFOUND'}); }
|
||||||
if (!data.command) { return void cb({ error: 'EINVAL' }); }
|
if (!data.command) { return void cb({ error: 'EINVAL' }); }
|
||||||
store.rpc.setMetadata(data, function (err, res) {
|
store.rpc.setMetadata(data, function (err, res) {
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ define([
|
|||||||
Object.keys(msg.content).forEach(function (key) {
|
Object.keys(msg.content).forEach(function (key) {
|
||||||
friend[key] = msg.content[key];
|
friend[key] = msg.content[key];
|
||||||
});
|
});
|
||||||
|
if (ctx.store.messenger) {
|
||||||
|
ctx.store.messenger.onFriendUpdate(curve, friend);
|
||||||
|
}
|
||||||
ctx.updateMetadata();
|
ctx.updateMetadata();
|
||||||
cb(true);
|
cb(true);
|
||||||
};
|
};
|
||||||
@@ -264,7 +267,6 @@ define([
|
|||||||
handlers['ADD_OWNER'] = function (ctx, box, data, cb) {
|
handlers['ADD_OWNER'] = function (ctx, box, data, cb) {
|
||||||
var msg = data.msg;
|
var msg = data.msg;
|
||||||
var content = msg.content;
|
var content = msg.content;
|
||||||
console.log(msg);
|
|
||||||
|
|
||||||
if (msg.author !== content.user.curvePublic) { return void cb(true); }
|
if (msg.author !== content.user.curvePublic) { return void cb(true); }
|
||||||
if (!content.href || !content.title || !content.channel) {
|
if (!content.href || !content.title || !content.channel) {
|
||||||
@@ -275,7 +277,10 @@ console.log(msg);
|
|||||||
var channel = content.channel;
|
var channel = content.channel;
|
||||||
|
|
||||||
if (addOwners[channel]) { return void cb(true); }
|
if (addOwners[channel]) { return void cb(true); }
|
||||||
addOwners[channel] = true;
|
addOwners[channel] = {
|
||||||
|
type: box.type,
|
||||||
|
hash: data.hash
|
||||||
|
};
|
||||||
|
|
||||||
cb(false);
|
cb(false);
|
||||||
};
|
};
|
||||||
@@ -286,6 +291,24 @@ console.log(msg);
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handlers['RM_OWNER'] = function (ctx, box, data, cb) {
|
||||||
|
var msg = data.msg;
|
||||||
|
var content = msg.content;
|
||||||
|
|
||||||
|
if (msg.author !== content.user.curvePublic) { return void cb(true); }
|
||||||
|
if (!content.channel) {
|
||||||
|
console.log('Remove invalid notification');
|
||||||
|
return void cb(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = content.channel;
|
||||||
|
|
||||||
|
if (addOwners[channel] && content.pending) {
|
||||||
|
return void cb(false, addOwners[channel]);
|
||||||
|
}
|
||||||
|
cb(false);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
add: function (ctx, box, data, cb) {
|
add: function (ctx, box, data, cb) {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -495,8 +495,8 @@ define([
|
|||||||
_addSharedFolder(Env, {
|
_addSharedFolder(Env, {
|
||||||
path: parentPath,
|
path: parentPath,
|
||||||
name: folderName,
|
name: folderName,
|
||||||
owned: data.owned, // XXX FIXME hardcoded preference
|
owned: data.owned,
|
||||||
password: data.password || '', // XXX FIXME hardcoded preference
|
password: data.password || '',
|
||||||
}, waitFor(function (id) {
|
}, waitFor(function (id) {
|
||||||
// _addSharedFolder can be an id or an error
|
// _addSharedFolder can be an id or an error
|
||||||
if (typeof(id) === 'object' && id && id.error) {
|
if (typeof(id) === 'object' && id && id.error) {
|
||||||
@@ -741,29 +741,17 @@ define([
|
|||||||
return void cb(null, Env.user.proxy[UserObject.SHARED_FOLDERS][sfId][data.attr]);
|
return void cb(null, Env.user.proxy[UserObject.SHARED_FOLDERS][sfId][data.attr]);
|
||||||
}
|
}
|
||||||
var datas = findHref(Env, data.href);
|
var datas = findHref(Env, data.href);
|
||||||
var nt = nThen;
|
|
||||||
var res = {};
|
var res = {};
|
||||||
datas.forEach(function (d) {
|
datas.forEach(function (d) {
|
||||||
nt = nt(function (waitFor) {
|
var atime = d.data.atime;
|
||||||
var atime, value;
|
|
||||||
var w = waitFor();
|
var value = data.attr ? d.data[data.attr] : JSON.parse(JSON.stringify(d.data));
|
||||||
nThen(function (waitFor2) {
|
if (!res.value || res.atime < atime) {
|
||||||
d.userObject.getPadAttribute(data.href, 'atime', waitFor2(function (err, v) {
|
res.atime = atime;
|
||||||
atime = v;
|
res.value = value;
|
||||||
}));
|
}
|
||||||
d.userObject.getPadAttribute(data.href, data.attr, waitFor2(function (err, v) {
|
|
||||||
value = v;
|
|
||||||
}));
|
|
||||||
}).nThen(function () {
|
|
||||||
if (!res.value || res.atime < atime) {
|
|
||||||
res.atime = atime;
|
|
||||||
res.value = value;
|
|
||||||
}
|
|
||||||
w();
|
|
||||||
});
|
|
||||||
}).nThen;
|
|
||||||
});
|
});
|
||||||
nt(function () { cb(null, res.value); });
|
cb(null, res.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
var getTagsList = function (Env) {
|
var getTagsList = function (Env) {
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ define([], function () {
|
|||||||
onOpen(data);
|
onOpen(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
padRpc.onMetadataEvent.reg(function (data) {
|
||||||
|
sframeChan.event('EV_RT_METADATA', data);
|
||||||
|
});
|
||||||
|
|
||||||
padRpc.onErrorEvent.reg(function (err) {
|
padRpc.onErrorEvent.reg(function (err) {
|
||||||
sframeChan.event('EV_RT_ERROR', err);
|
sframeChan.event('EV_RT_ERROR', err);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -476,6 +476,43 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sframeChan.on('Q_ACCEPT_OWNERSHIP', function (data, cb) {
|
||||||
|
var _data = {
|
||||||
|
password: data.password,
|
||||||
|
href: data.href,
|
||||||
|
channel: data.channel,
|
||||||
|
title: data.title,
|
||||||
|
owners: data.metadata.owners,
|
||||||
|
expire: data.metadata.expire,
|
||||||
|
forceSave: true
|
||||||
|
};
|
||||||
|
Cryptpad.setPadTitle(_data, function (err) {
|
||||||
|
cb({error: err});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also add your mailbox to the metadata object
|
||||||
|
var padParsed = Utils.Hash.parsePadUrl(data.href);
|
||||||
|
var padSecret = Utils.Hash.getSecrets(padParsed.type, padParsed.hash, data.password);
|
||||||
|
var padCrypto = Utils.Crypto.createEncryptor(padSecret.keys);
|
||||||
|
try {
|
||||||
|
var value = {};
|
||||||
|
value[edPublic] = padCrypto.encrypt(JSON.stringify({
|
||||||
|
notifications: notifications,
|
||||||
|
curvePublic: curvePublic
|
||||||
|
}));
|
||||||
|
var msg = {
|
||||||
|
channel: data.channel,
|
||||||
|
command: 'ADD_MAILBOX',
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
Cryptpad.setPadMetadata(msg, function (res) {
|
||||||
|
if (res.error) { console.error(res.error); }
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
return void console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_IMPORT_MEDIATAG', function (obj, cb) {
|
sframeChan.on('Q_IMPORT_MEDIATAG', function (obj, cb) {
|
||||||
var key = obj.key;
|
var key = obj.key;
|
||||||
var channel = obj.channel;
|
var channel = obj.channel;
|
||||||
@@ -986,9 +1023,17 @@ define([
|
|||||||
}, waitFor(function (obj) {
|
}, waitFor(function (obj) {
|
||||||
obj = obj || {};
|
obj = obj || {};
|
||||||
if (obj.error) { return; }
|
if (obj.error) { return; }
|
||||||
if (obj.mailbox) {
|
var mailbox;
|
||||||
|
// Get the first available mailbox (the field can be an string or an object)
|
||||||
|
// TODO maybe we should send the request to all the owners?
|
||||||
|
if (typeof (obj.mailbox) === "string") {
|
||||||
|
mailbox = obj.mailbox;
|
||||||
|
} else if (obj.mailbox && obj.owners && obj.owners.length) {
|
||||||
|
mailbox = obj.mailbox[obj.owners[0]];
|
||||||
|
}
|
||||||
|
if (mailbox) {
|
||||||
try {
|
try {
|
||||||
var dataStr = crypto.decrypt(obj.mailbox, true, true);
|
var dataStr = crypto.decrypt(mailbox, true, true);
|
||||||
var data = JSON.parse(dataStr);
|
var data = JSON.parse(dataStr);
|
||||||
if (!data.notifications || !data.curvePublic) { return; }
|
if (!data.notifications || !data.curvePublic) { return; }
|
||||||
owner = data;
|
owner = data;
|
||||||
@@ -1010,7 +1055,6 @@ define([
|
|||||||
channel: secret.channel
|
channel: secret.channel
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
console.log(data);
|
|
||||||
Cryptpad.getPadMetadata(data, cb);
|
Cryptpad.getPadMetadata(data, cb);
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_SET_PAD_METADATA', function (data, cb) {
|
sframeChan.on('Q_SET_PAD_METADATA', function (data, cb) {
|
||||||
@@ -1142,7 +1186,8 @@ define([
|
|||||||
};
|
};
|
||||||
if (data.owned) {
|
if (data.owned) {
|
||||||
rtConfig.metadata.owners = [edPublic];
|
rtConfig.metadata.owners = [edPublic];
|
||||||
rtConfig.metadata.mailbox = Utils.crypto.encrypt(JSON.stringify({
|
rtConfig.metadata.mailbox = {};
|
||||||
|
rtConfig.metadata.mailbox[edPublic] = Utils.crypto.encrypt(JSON.stringify({
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
curvePublic: curvePublic
|
curvePublic: curvePublic
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1139,5 +1139,26 @@
|
|||||||
"features_noData": "Aucune donnée personnelle requise",
|
"features_noData": "Aucune donnée personnelle requise",
|
||||||
"features_pricing": "Entre {0} et {2}€ par mois",
|
"features_pricing": "Entre {0} et {2}€ par mois",
|
||||||
"features_emailRequired": "Adresse email requise",
|
"features_emailRequired": "Adresse email requise",
|
||||||
|
"register_emailWarning0": "Il semble que vous ayez entré votre adresse email à la place du nom d'utilisateur.",
|
||||||
|
"register_emailWarning1": "Vous pouvez continuer, mais ces données ne sont pas nécessaires et ne seront pas envoyées à notre serveur.",
|
||||||
|
"register_emailWarning2": "Vous ne pourrez pas réinitialiser votre mot de passe en utilisant votre adresse email comme sur beaucoup d'autres services",
|
||||||
|
"register_emailWarning3": "Si vous souhaitez tout de même utiliser votre adresse email comme nom d'utilisateur, appuyez sur OK",
|
||||||
|
"owner_removeText": "Supprimer un propriétaire existant",
|
||||||
|
"owner_removePendingText": "Annuler une offre en attente",
|
||||||
|
"owner_addText": "Proposer à un ami d'être co-propriétaire de ce document",
|
||||||
|
"owner_unknownUser": "Utilisateur inconnu",
|
||||||
|
"owner_removeButton": "Supprimer les propriétaires sélectionnés",
|
||||||
|
"owner_removePendingButton": "Annuler les offres sélectionnées",
|
||||||
|
"owner_addButton": "Proposer la co-propriété",
|
||||||
|
"owner_removeConfirm": "Êtes-vous sûr de vouloir suppprimer les droits de propriétaire pour les utilisateurs sélectionnés ? Ils seront notifiés de cette action.",
|
||||||
|
"owner_removeMeConfirm": "Vous êtes sur le point de renoncer à vos droits de propriétaire. Vous ne serez pas en mesure d'annuler cette action. Continuer ?",
|
||||||
|
"owner_addConfirm": "Les co-propriétaires seront en mesure de changer le contenu du document et pourront supprimer vos droits de propriétaire. Continuer ?",
|
||||||
|
"owner_openModalButton": "Gérer les propriétaires",
|
||||||
|
"owner_add": "{0} souhaite que vous soyez propriétaire du pad <b>{1}</b>. Acceptez-vous ?",
|
||||||
|
"owner_request": "{0} souhaite que vous soyez propriétaire de <b>{1}</b>",
|
||||||
|
"owner_request_accepted": "{0} a accepté votre offre de devenir propriétaire de <b>{1}</b>",
|
||||||
|
"owner_request_declined": "{0} a refusé votre offre de devenir propriétaire de <b>{1}</b>",
|
||||||
|
"owner_removed": "{0} a supprimé vos droits de propriétaire de <b>{1}</b>",
|
||||||
|
"owner_removedPending": "{0} a annulé l'offre de co-propriété reçue pour <b>{1}</b>",
|
||||||
"padNotPinnedVariable": "Ce pad va expirer après {4} jours d'inactivité, {0}connectez-vous{1} ou {2}enregistrez-vous{3} pour le préserver."
|
"padNotPinnedVariable": "Ce pad va expirer après {4} jours d'inactivité, {0}connectez-vous{1} ou {2}enregistrez-vous{3} pour le préserver."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3720,7 +3720,6 @@ define([
|
|||||||
sframeChan.query('Q_GET_PAD_METADATA', {
|
sframeChan.query('Q_GET_PAD_METADATA', {
|
||||||
channel: data.channel
|
channel: data.channel
|
||||||
}, function (err, val) {
|
}, function (err, val) {
|
||||||
console.log(arguments);
|
|
||||||
if (!err && !(val && val.error)) {
|
if (!err && !(val && val.error)) {
|
||||||
data.owners = val.owners;
|
data.owners = val.owners;
|
||||||
data.expire = val.expire;
|
data.expire = val.expire;
|
||||||
|
|||||||
Reference in New Issue
Block a user