Commit 62f0bebc authored by Eugene Shen's avatar Eugene Shen

Fix duplication error using MappingStorage

Put MappingStorage over ERP5Storage to map the proper mappings,
by replacing its relative_url IDs with the mapping property.

Change other minor things: sort only by date_ms, not content,
rename author to sender as per the commit before the last commit,
store only the epoch time in milliseconds in messages, not Dates,
and keep only the raw nameToId in id_to_name, not chat-contact-.
parent 3f6d1dd5
...@@ -85,9 +85,14 @@ ...@@ -85,9 +85,14 @@
switch (fields.jio_type.value) { switch (fields.jio_type.value) {
case "erp5": case "erp5":
remote_sub_storage = { remote_sub_storage = {
type: "mapping",
id: ["equalSubProperty", "mapping"],
query: gadget.state.mapping_query,
sub_storage: {
type: "erp5", type: "erp5",
url: fields.erp5_url.value, url: fields.erp5_url.value,
default_view_reference: "view" default_view_reference: "jio_view"
}
}; };
break; break;
case "dav": case "dav":
......
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>958.43208.55839.34116</string> </value> <value> <string>958.44541.58107.9130</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1492099289.07</float> <float>1492188930.99</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -48,6 +48,24 @@ ...@@ -48,6 +48,24 @@
} }
/* Translate a message to a jIO and ERP5-safe unique deterministic ID.
* Parameters:
* - message: the message from which to generate an ID
* Effects: nothing
* Returns:
* - a string of the room, sender, and epoch time concatenated together,
* with all non-alphanumeric characters replaced by underscores
*/
function messageToId(message) {
// XXX should distinguish @ and . in emails
// XXX but . seems to match anything in HATEOAS queries
var concatenated_id =
message.room + "_" + message.sender + "_" + message.date_ms.toString();
return concatenated_id.replace(/\W/gi, "_");
}
/* Reset a text input. /* Reset a text input.
* Parameters: * Parameters:
* - element: the text input element to reset * - element: the text input element to reset
...@@ -62,18 +80,6 @@ ...@@ -62,18 +80,6 @@
} }
/* Get the creation epoch time of a message.
* Parameters:
* - message: the message whose creation time is desired
* Effects: nothing
* Returns: the creation time of the message, in milliseconds since 1970
*/
function getTime(message) {
return new Date(message.date_ms).getTime();
}
/* Check if two messages are the same. /* Check if two messages are the same.
* Parameters: * Parameters:
* - lhs, rhs: the two messages that may or may not be the same * - lhs, rhs: the two messages that may or may not be the same
...@@ -82,15 +88,15 @@ ...@@ -82,15 +88,15 @@
*/ */
function isSameMessage(lhs, rhs) { function isSameMessage(lhs, rhs) {
return lhs !== undefined && rhs !== undefined return lhs !== undefined && rhs !== undefined
&& lhs.name === rhs.name && lhs.content === rhs.content && lhs.sender === rhs.sender && lhs.room === rhs.room
&& lhs.room === rhs.room && getTime(lhs) === getTime(rhs); && lhs.content === rhs.content && lhs.date_ms === rhs.date_ms;
} }
/* Create a new JSON message. /* Create a new JSON message.
* Parameters: * Parameters:
* - type: the type of message, either "notification" or "message" * - type: the type of message, either "notification" or "message"
* - author: the name of the sender of the message * - sender: the name of the sender of the message
* - room: the room from where the message is sent * - room: the room from where the message is sent
* - date_ms: the epoch time at which the message is sent * - date_ms: the epoch time at which the message is sent
* - content: the content of the message * - content: the content of the message
...@@ -102,7 +108,7 @@ ...@@ -102,7 +108,7 @@
function createMessage(param_dict) { function createMessage(param_dict) {
return { return {
type: param_dict.type || "message", type: param_dict.type || "message",
author: param_dict.author, sender: param_dict.sender,
room: param_dict.room, room: param_dict.room,
date_ms: param_dict.date_ms || new Date().getTime(), date_ms: param_dict.date_ms || new Date().getTime(),
content: param_dict.content || "", content: param_dict.content || "",
...@@ -132,7 +138,7 @@ ...@@ -132,7 +138,7 @@
// Put message in the format "[3/24/2017, 11:30:52 AM] user: message" // Put message in the format "[3/24/2017, 11:30:52 AM] user: message"
chat.html = "[" + new Date(message.date_ms).toLocaleString() chat.html = "[" + new Date(message.date_ms).toLocaleString()
+ "] " + message.author + ": "; + "] " + message.sender + ": ";
// Loop through all potential URLs in the message // Loop through all potential URLs in the message
// matches[i] is the non-link content, matches[i + 1] is the actual link // matches[i] is the non-link content, matches[i + 1] is the actual link
...@@ -199,7 +205,8 @@ ...@@ -199,7 +205,8 @@
// true if the current room is a chat box, false if it is a contact panel // true if the current room is a chat box, false if it is a contact panel
is_chat: false, is_chat: false,
// a dict of room IDs to their names, i.e. {foo_bar_com: "foo@bar.com"} // a dict of room IDs to their names, i.e. {foo-bar-com: "foo@bar.com"}
// id_to_name(nameToId(x)) = nameToId(id_to_name(x)) = x
id_to_name: {}, id_to_name: {},
/* a dict of room names to the room with the following properties: /* a dict of room names to the room with the following properties:
...@@ -251,7 +258,7 @@ ...@@ -251,7 +258,7 @@
return gadget.changeState({room: param_list[0], is_chat: true}) return gadget.changeState({room: param_list[0], is_chat: true})
.push(function () { .push(function () {
gadget.deployMessage({ gadget.deployMessage({
author: gadget.state.name, sender: gadget.state.name,
room: param_list[0], room: param_list[0],
content: gadget.state.name + " has joined.", content: gadget.state.name + " has joined.",
color: "orange" color: "orange"
...@@ -502,14 +509,16 @@ ...@@ -502,14 +509,16 @@
default_jio_type: gadget.state.default_jio_type, default_jio_type: gadget.state.default_jio_type,
default_erp5_url: gadget.state.default_erp5_url, default_erp5_url: gadget.state.default_erp5_url,
default_dav_url: gadget.state.default_dav_url, default_dav_url: gadget.state.default_dav_url,
mapping_query: {
query: 'portal_type: "Text Post"',
select_list: ["sender", "room", "date_ms", "content"],
limit: [0, JIO_QUERY_MAX_LIMIT]
},
query: { query: {
query: 'portal_type: "Text Post" AND room: "' + room + '"', query: 'portal_type: "Text Post"',
limit: [0, JIO_QUERY_MAX_LIMIT], limit: [0, JIO_QUERY_MAX_LIMIT],
select_list: ["content"], select_list: ["sender", "room", "date_ms", "content"],
sort_on: [ sort_on: [["date_ms", "ascending"]]
["date_ms", "ascending"],
["content", "ascending"]
]
} }
}); });
}) })
...@@ -523,7 +532,7 @@ ...@@ -523,7 +532,7 @@
delay_refresh_index: 0, delay_refresh_index: 0,
delay_refresh_lock: false delay_refresh_lock: false
}; };
gadget.state.id_to_name["chat-contact-" + nameToId(room)] = room; gadget.state.id_to_name[nameToId(room)] = room;
return room_gadget.render(); return room_gadget.render();
}); });
}) })
...@@ -636,17 +645,17 @@ ...@@ -636,17 +645,17 @@
.declareMethod("storeArchive", function (message) { .declareMethod("storeArchive", function (message) {
var gadget = this, var gadget = this,
id = message.room + "_" + message.author id = messageToId(message);
+ "_" + getTime(message).toString();
return gadget.getDeclaredGadget("room-gadget-" + gadget.state.room) return gadget.getDeclaredGadget("room-gadget-" + gadget.state.room)
.push(function (room_gadget) { .push(function (room_gadget) {
return room_gadget.wrapJioCall("put", [id, { return room_gadget.wrapJioCall("put", [id, {
portal_type: "Text Post", portal_type: "Text Post",
parent_relative_url: "text_post_module", parent_relative_url: "text_post_module",
author: message.author, sender: message.sender,
room: message.room, room: nameToId(message.room),
date_ms: message.date_ms, date_ms: message.date_ms,
content: message.content content: message.content,
mapping: id
}]); }]);
}); });
}) })
...@@ -764,11 +773,8 @@ ...@@ -764,11 +773,8 @@
return room_gadget.wrapJioCall("allDocs", [{ return room_gadget.wrapJioCall("allDocs", [{
query: 'portal_type: "Text Post" AND room: "' + room + '"', query: 'portal_type: "Text Post" AND room: "' + room + '"',
limit: [0, JIO_QUERY_MAX_LIMIT], limit: [0, JIO_QUERY_MAX_LIMIT],
select_list: ["author", "room", "date_ms", "content"], select_list: ["sender", "room", "date_ms", "content"],
sort_on: [ sort_on: [["date_ms", "ascending"]]
["date_ms", "ascending"],
["content", "ascending"]
]
}]); }]);
}) })
.push(function (result_list) { .push(function (result_list) {
...@@ -787,12 +793,13 @@ ...@@ -787,12 +793,13 @@
j = 0; j = 0;
for (i = 0; i < result_list.data.total_rows; i += 1) { for (i = 0; i < result_list.data.total_rows; i += 1) {
message = createMessage(result_list.data.rows[i].value); message = createMessage(result_list.data.rows[i].value);
if (getTime(message) < gadget.state.room_dict[room].join_time) { message.room = gadget.state.id_to_name[message.room];
if (message.date_ms < gadget.state.room_dict[room].join_time) {
message.color = "grey"; message.color = "grey";
} }
// add old messages sent before the current message // add old messages sent before the current message
while (j < old_list.length while (j < old_list.length
&& getTime(old_list[j]) < getTime(message)) { && old_list[j].date_ms < message.date_ms) {
new_list.push(old_list[j]); new_list.push(old_list[j]);
j += 1; j += 1;
} }
...@@ -862,7 +869,7 @@ ...@@ -862,7 +869,7 @@
return gadget.changeRoom(argument); return gadget.changeRoom(argument);
} }
return gadget.deployNotification({ return gadget.deployNotification({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: "You must first add '" + argument + "' as a contact!", content: "You must first add '" + argument + "' as a contact!",
color: "red" color: "red"
...@@ -874,7 +881,7 @@ ...@@ -874,7 +881,7 @@
.push(function () { .push(function () {
if (gadget.state.room === gadget.state.name) { if (gadget.state.room === gadget.state.name) {
return gadget.deployNotification({ return gadget.deployNotification({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: "You cannot leave your own room!", content: "You cannot leave your own room!",
color: "red" color: "red"
...@@ -882,7 +889,7 @@ ...@@ -882,7 +889,7 @@
} }
delete gadget.state.room_dict[gadget.state.room]; delete gadget.state.room_dict[gadget.state.room];
return gadget.deployMessage({ return gadget.deployMessage({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: gadget.state.name + " has quit.", content: gadget.state.name + " has quit.",
color: "orange" color: "orange"
...@@ -900,7 +907,7 @@ ...@@ -900,7 +907,7 @@
case "help": case "help":
for (i = 0; i < help_list.length; i += 1) { for (i = 0; i < help_list.length; i += 1) {
promise_list.push(gadget.deployNotification({ promise_list.push(gadget.deployNotification({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: help_list[i], content: help_list[i],
color: "green" color: "green"
...@@ -910,7 +917,7 @@ ...@@ -910,7 +917,7 @@
default: default:
return gadget.deployNotification({ return gadget.deployNotification({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: "'" + argument + "' is not a valid command.", content: "'" + argument + "' is not a valid command.",
color: "red" color: "red"
...@@ -925,7 +932,8 @@ ...@@ -925,7 +932,8 @@
var gadget = this, var gadget = this,
room; room;
if (event.target.classList.contains("chat-contact")) { if (event.target.classList.contains("chat-contact")) {
room = gadget.state.id_to_name[event.target.id]; // the id in event.target.id is prefixed with "chat-contact-"
room = gadget.state.id_to_name[event.target.id.substring(13)];
gadget.state.room_dict[room].unread = false; gadget.state.room_dict[room].unread = false;
return gadget.changeState({favicon_alert: false}) return gadget.changeState({favicon_alert: false})
.push(function () { .push(function () {
...@@ -952,7 +960,7 @@ ...@@ -952,7 +960,7 @@
return gadget.parseCommand(content); return gadget.parseCommand(content);
} }
return gadget.deployMessage({ return gadget.deployMessage({
author: gadget.state.name, sender: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: content, content: content,
color: "black" color: "black"
...@@ -978,7 +986,7 @@ ...@@ -978,7 +986,7 @@
if (gadget.state.room_dict.hasOwnProperty(room) if (gadget.state.room_dict.hasOwnProperty(room)
&& gadget.state.room_dict[room].message_count > 0) { && gadget.state.room_dict[room].message_count > 0) {
promise_list.push(gadget.deployMessage({ promise_list.push(gadget.deployMessage({
author: gadget.state.name, sender: gadget.state.name,
room: room, room: room,
content: gadget.state.name + " has quit.", content: gadget.state.name + " has quit.",
color: "orange" color: "orange"
......
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>958.44293.34365.30907</string> </value> <value> <string>958.44733.2615.38656</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1492162895.42</float> <float>1492189329.87</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment