Commit 2b146ccf authored by Eugene Shen's avatar Eugene Shen

Add polling time list and fix minor bugs

Remove FastPriorityQueue because jIO already sorts everything
and gadget.state.message_list_dict[room] is always sorted,
fix the merge algorithm to not use a priority queue at all,
add POLL_DELAY_LIST to customize increasing polling intervals,
add current_refresh_dict as a mutex over refreshChat(),
and add requirements to function docstrings.
parent fdcbdb06
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */ /*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*global window, document, RSVP, rJS, Handlebars, /*global window, document, RSVP, rJS, Handlebars, promiseEventListener */
FastPriorityQueue, promiseEventListener */ (function (window, document, RSVP, rJS, Handlebars, promiseEventListener) {
(function (window, document, RSVP, rJS, Handlebars,
FastPriorityQueue, promiseEventListener) {
"use strict"; "use strict";
/* Settings required: /* Settings required:
...@@ -14,8 +12,19 @@ ...@@ -14,8 +12,19 @@
* - default_dav_url, default: "" * - default_dav_url, default: ""
*/ */
// Handlebars templates
var chat_list_template, var chat_list_template,
contact_list_template; contact_list_template,
// arbitrary limit to number of jIO text posts to return
// must include limit: [0, JIO_QUERY_MAX_LIMIT] because the default is 10
JIO_QUERY_MAX_LIMIT = 1000000000,
// list of how long to wait when polling, i.e. wait for 0.5 seconds, poll,
// then wait for 1 second, poll, etc. until always waiting for 5 minutes
POLL_DELAY_LIST = [500, 1000, 2000, 5000, 10000, 15000, 20000, 25000,
30000, 40000, 60000, 90000, 120000, 150000, 180000, 240000, 300000];
/* Check if a string ends with another string. /* Check if a string ends with another string.
...@@ -69,6 +78,19 @@ ...@@ -69,6 +78,19 @@
} }
/* Check if two messages are the same.
* Parameters:
* - lhs, rhs: the two messages that may or may not be the same
* Effects: none
* Returns: true if both messages exist and are the same, otherwise false
*/
function isSameMessage(lhs, rhs) {
return lhs !== undefined && rhs !== undefined
&& lhs.name === rhs.name && lhs.content === rhs.content
&& lhs.room === rhs.room && getTime(lhs) === getTime(rhs);
}
/* Create a new JSON message. /* Create a new JSON message.
* Parameters: * Parameters:
* - name: the name of the sender of the message * - name: the name of the sender of the message
...@@ -94,7 +116,7 @@ ...@@ -94,7 +116,7 @@
/* Translate a JSON message to an HTML chat element. /* Translate a JSON message to an HTML chat element.
* Parameters: * Parameters:
* - message: the JavaScript object to display in HTML * - message: the JavaScript object to display in HTML, from createMessage
* Effects: nothing * Effects: nothing
* Returns: a properly escaped HTML representation of the given message * Returns: a properly escaped HTML representation of the given message
*/ */
...@@ -176,11 +198,10 @@ ...@@ -176,11 +198,10 @@
// true if the room is a chat box, false if the room is a contact panel // true if the room is a chat box, false if the room is a contact panel
is_chat: false, is_chat: false,
// a dict of room IDs to the ir 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: {}, id_to_name: {},
// a dict of room names to whether each has unread messages // a dict of room names to whether each has unread messages
// i.e. {read_room: false, unread_room: true}
unread_room_dict: {}, unread_room_dict: {},
// a dict of room names to the list of messages in each, // a dict of room names to the list of messages in each,
...@@ -195,6 +216,9 @@ ...@@ -195,6 +216,9 @@
// i.e. {room: new RSVP.Queue().push(function () { return ... })} // i.e. {room: new RSVP.Queue().push(function () { return ... })}
delay_refresh_dict: {}, delay_refresh_dict: {},
// a dict of room names to whether each is currently running refreshChat
current_refresh_dict: {},
// true to use alert_icon_url, false to use default_icon_url // true to use alert_icon_url, false to use default_icon_url
favicon_alert: false, favicon_alert: false,
alert_icon_url: "https://pricespy.co.nz/favicon.ico", alert_icon_url: "https://pricespy.co.nz/favicon.ico",
...@@ -216,21 +240,37 @@ ...@@ -216,21 +240,37 @@
.declareAcquiredMethod("getSetting", "getSetting") .declareAcquiredMethod("getSetting", "getSetting")
// The following function is acquired by gadget_erp5_chat_room. /* Join a new room room.
* This function is acquired by gadget_erp5_chat_room.
* Parameters:
* - room: the name of the room to join
* Requirements:
* - room has an associated room gadget with a valid jIO storage
* Effects:
* - send a message when room is joined
*/
.allowPublicAcquisition("changeRoom", function (param_list) { .allowPublicAcquisition("joinNewRoom", function (param_list) {
var gadget = this; var gadget = this;
return gadget.changeRoom.apply(gadget, param_list); return gadget.changeState({room: param_list[0], is_chat: true})
.push(function () {
gadget.deployMessage({
name: gadget.state.name,
room: param_list[0],
content: gadget.state.name + " has joined.",
color: "orange"
});
});
}) })
/* Render everything again when the current state changes. /* Render everything again when the current state changes.
* Parameters: all properties in gadget.state * Parameters: all properties in gadget.state
* Effects: * Effects:
* - in right panel, only display the currently active room or contact
* - in right panel, set the title based on the room or contact
* - in contact list, only add styles for unread messages and current room * - in contact list, only add styles for unread messages and current room
* - set favicon depending on whether there are new unread messages * - set favicon depending on whether there are new unread messages
* - in right panel, only display the currently active room or contact
* - in right panel, set the title based on the room or contact
*/ */
.onStateChange(function (modification_dict) { .onStateChange(function (modification_dict) {
...@@ -301,34 +341,48 @@ ...@@ -301,34 +341,48 @@
chat_list_element.scrollTop = chat_list_element.scrollHeight; chat_list_element.scrollTop = chat_list_element.scrollHeight;
} }
// set update to false so that setting update to true calls onStateChange
gadget.state.update = false;
// refresh the current room // refresh the current room
if (gadget.state.refresh_chat) { if (gadget.state.refresh_chat) {
gadget.state.refresh_chat = false; gadget.state.refresh_chat = false;
gadget.delayRefresh(gadget.state.room, 5000); gadget.delayRefresh(gadget.state.room, 0);
} }
// set update to false so that setting update to true calls onStateChange
gadget.state.update = false;
}) })
// Do nothing; everything is in following declareService(), because
// clicking on Chat Box in the panel calls render() without refreshing
.declareMethod("render", function () { return; })
/* Render the gadget. /* Render the gadget.
* Parameters: * Parameters:
* - getSetting: user_email, jio_storage_description, * - getSetting: user_email, jio_storage_description,
* default_jio_type, default_erp5_url, default_dav_url * default_jio_type, default_erp5_url, default_dav_url
* Effects: * Effects:
* - update header, page_title to "OfficeJS Chat" * - update header, page_title to "OfficeJS Chat"
* - compile Handlebars templates
* - redirect if no jIO storage available * - redirect if no jIO storage available
* - create the user contact, whose name is the user name * - create the user contact, whose name is the user name
* - change to the user contact panel
*/ */
.declareMethod("render", function () { .declareService(function () {
var gadget = this, var gadget = this,
user_email; user_email;
return gadget.requireSetting( return gadget.requireSetting(
"jio_storage_description", "jio_storage_description",
"jio_configurator", "jio_configurator",
new RSVP.Queue() new RSVP.Queue()
.push(function () {
return gadget.updateHeader({page_title: "OfficeJS Chat"});
})
.push(function () {
return gadget.updateHeader({page_title: "OfficeJS Chat"});
})
.push(function () { .push(function () {
chat_list_template = Handlebars.compile( chat_list_template = Handlebars.compile(
Object.getPrototypeOf(gadget).constructor.__template_element Object.getPrototypeOf(gadget).constructor.__template_element
...@@ -342,11 +396,6 @@ ...@@ -342,11 +396,6 @@
.querySelector(".chat-title"); .querySelector(".chat-title");
gadget.state.chat_box_element = gadget.element gadget.state.chat_box_element = gadget.element
.querySelector(".chat-right-panel-chat"); .querySelector(".chat-right-panel-chat");
return gadget.updateHeader({
page_title: "OfficeJS Chat"
});
})
.push(function () {
return RSVP.all([ return RSVP.all([
gadget.getSetting("user_email"), gadget.getSetting("user_email"),
gadget.getSetting("jio_storage_description"), gadget.getSetting("jio_storage_description"),
...@@ -372,9 +421,13 @@ ...@@ -372,9 +421,13 @@
gadget.element.querySelector(".send-form input[type='text']") gadget.element.querySelector(".send-form input[type='text']")
.onfocus = function () { .onfocus = function () {
gadget.state.unread_room_dict[gadget.state.room] = false; gadget.state.unread_room_dict[gadget.state.room] = false;
return gadget.changeState({update: true}); return gadget.changeState({
refresh_chat: true,
favicon_alert: false,
update: true
});
}; };
return gadget.createContact(user_email); return gadget.createRoom(user_email);
}) })
.push(function () { .push(function () {
return gadget.changeState({room: user_email}); return gadget.changeState({room: user_email});
...@@ -383,39 +436,28 @@ ...@@ -383,39 +436,28 @@
}) })
/* Create a new contact. /* Create a new room.
* Parameters:
* - room: the name of the contact
* Effects:
* - if the name is not blank and not a duplicate, then:
* - create a new contact to be rendered in the contact list
* - create a new room gadget
*/
.declareMethod("createContact", function (room) {
var gadget = this;
if (!room.trim()) {
throw "An invisible name is not allowed! You couldn't click on it!";
}
if (gadget.state.message_list_dict.hasOwnProperty(room)) {
throw "A contact with the same name already exists!";
}
return gadget.createRoom(room);
})
/* Create a new room gadget.
* Parameters: * Parameters:
* - room: the name of the room * - room: the name of the room
* Requirements:
* - room is not blank and not already in the contact list
* Effects: * Effects:
* - declare a new gadget with scope "room-gadget-" + room * - declare a new gadget with scope "room-gadget-" + room
* - set its ID to a querySelector-safe translation of its scope * - set its ID to a querySelector-safe translation of room
* - initialize its state and render the room gadget * - initialize its state and render the room gadget
* - update the chat box gadget state dicts with the new room
* - change to the room contact panel
*/ */
.declareMethod("createRoom", function (room) { .declareMethod("createRoom", function (room) {
var gadget = this, var gadget = this,
room_gadget; room_gadget;
if (!room.trim()) {
throw "An invisible name is not allowed! You couldn't click on it!";
}
if (gadget.state.message_list_dict.hasOwnProperty(room)) {
throw "A contact with the same name already exists!";
}
return gadget.declareGadget("gadget_erp5_chat_room.html", { return gadget.declareGadget("gadget_erp5_chat_room.html", {
scope: "room-gadget-" + room scope: "room-gadget-" + room
}) })
...@@ -423,10 +465,8 @@ ...@@ -423,10 +465,8 @@
room_gadget = sub_gadget; room_gadget = sub_gadget;
room_gadget.element.setAttribute("id", room_gadget.element.setAttribute("id",
"room-gadget-" + nameToId(room)); "room-gadget-" + nameToId(room));
gadget.element.querySelector(".chat-right-panel").insertBefore(
room_gadget.element,
gadget.element.querySelector(".chat-max-height-wrapper") gadget.element.querySelector(".chat-max-height-wrapper")
); .appendChild(room_gadget.element);
return room_gadget.changeState({ return room_gadget.changeState({
room: room, room: room,
local_sub_storage: gadget.state.local_sub_storage, local_sub_storage: gadget.state.local_sub_storage,
...@@ -434,8 +474,8 @@ ...@@ -434,8 +474,8 @@
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,
query: { query: {
limit: [0, 1000000000], query: 'portal_type: "Text Post" AND room: "' + room + '"',
query: 'portal_type: "Text Post"' // AND room: "' + room + '"' limit: [0, JIO_QUERY_MAX_LIMIT]
} }
}); });
}) })
...@@ -445,6 +485,8 @@ ...@@ -445,6 +485,8 @@
.push(function () { .push(function () {
gadget.state.message_list_dict[room] = []; gadget.state.message_list_dict[room] = [];
gadget.state.message_count_dict[room] = 0; gadget.state.message_count_dict[room] = 0;
gadget.state.current_refresh_dict[room] = false;
gadget.state.delay_refresh_dict[room] = new RSVP.Queue();
gadget.state.id_to_name["chat-contact-" + nameToId(room)] = room; gadget.state.id_to_name["chat-contact-" + nameToId(room)] = room;
return gadget.changeState({room: room, is_chat: false}); return gadget.changeState({room: room, is_chat: false});
}); });
...@@ -454,44 +496,45 @@ ...@@ -454,44 +496,45 @@
/* Change to a different room. /* Change to a different room.
* Parameters: * Parameters:
* - room: the name of the room to change to * - room: the name of the room to change to
* Requirements:
* - room is already in the contact list
* Effects: * Effects:
* - hide the room gadget contact panel * - if the room is already joined, then change to the chat panel
* - show the chat box * - otherwise, change to the corresponding contact panel
* - overwrite the chat box with chats from the jIO storage
*/ */
.declareMethod("changeRoom", function (room) { .declareMethod("changeRoom", function (room) {
var gadget = this; var gadget = this;
return gadget.changeState({room: room, is_chat: true}) if (gadget.state.message_list_dict[room].length > 0) {
.push(function () { return gadget.changeState({room: room, is_chat: true});
if (gadget.state.message_list_dict[room].length === 0) {
return gadget.deployMessage({
name: gadget.state.name,
room: gadget.state.room,
content: gadget.state.name + " has joined.",
color: "orange"
});
} }
}); return gadget.changeState({room: room, is_chat: false, update: true});
}) })
/* Deploy a new message. /* Deploy a new message.
* Parameters: * Parameters:
* - param_dict: the parameters to pass to createMessage * - param_dict: the parameters to pass to createMessage
* Requirements:
* - param_dict.room is already in the contact list
* - createMessage(param_dict) creates a valid message
* Effects: * Effects:
* - create a new message * - create a new message
* - append the message to the chat
* - store the message in jIO storage * - store the message in jIO storage
* - update the chat box gadget state dicts
* - refresh the chat
*/ */
.declareMethod("deployMessage", function (param_dict) { .declareMethod("deployMessage", function (param_dict) {
var gadget = this, var gadget = this,
message = createMessage(param_dict); message = createMessage(param_dict);
gadget.state.message_list_dict[param_dict.room].push(message); gadget.state.message_list_dict[param_dict.room].push(message);
// increase so that rerreshChat() does not also call changeState()
gadget.state.message_count_dict[param_dict.room] += 1;
gadget.state.unread_room_dict[param_dict.room] = false;
return gadget.storeArchive(message) return gadget.storeArchive(message)
.push(function () { .push(function () {
return gadget.changeState({refresh_chat: true}); return gadget.changeState({refresh_chat: true, favicon_alert: false});
}); });
}) })
...@@ -499,22 +542,27 @@ ...@@ -499,22 +542,27 @@
/* Deploy a new notification. /* Deploy a new notification.
* Parameters: * Parameters:
* - param_dict: the parameters to pass to createMessage * - param_dict: the parameters to pass to createMessage
* Requirements:
* - param_dict.room is already in the contact list
* - createMessage(param_dict) creates a valid message
* Effects: * Effects:
* - create a new message * - create a new message
* - append the message to the chat * - append the message to the local message_list_dict but not jIO storage
* - refresh the chat
*/ */
.declareMethod("deployNotification", function (param_dict) { .declareMethod("deployNotification", function (param_dict) {
var gadget = this, var gadget = this;
message;
param_dict.type = "notification"; param_dict.type = "notification";
message = createMessage(param_dict); gadget.state.message_list_dict[param_dict.room]
gadget.state.message_list_dict[param_dict.room].push(message); .push(createMessage(param_dict));
return gadget.changeState({refresh_chat: true}); return gadget.changeState({refresh_chat: true});
}) })
/* Store a message in jIO storage. /* Store a message in jIO storage.
* Requirements:
* - message.room has an associated room gadget with a valid jIO storage
* Parameters: * Parameters:
* - message: the message object to store in jIO storage * - message: the message object to store in jIO storage
* Effects: store the message with all necessary properties into jIO * Effects: store the message with all necessary properties into jIO
...@@ -542,27 +590,32 @@ ...@@ -542,27 +590,32 @@
/* Refresh the chat by polling with increasing delays. /* Refresh the chat by polling with increasing delays.
* Parameters: * Parameters:
* - room: the room to refresh * - room: the room to refresh
* - delay: the time in milliseconds to wait before refreshing again * - poll_delay_index: the index in POLL_DELAY_LIST of
* the time in milliseconds to wait before refreshing again
* Requirements:
* - gadget.state.delay_refresh_dict[room] has new RSVP.Queue() in it
* Effects: * Effects:
* - call refreshChat and wait delay milliseconds before calling it again * - call refreshChat and wait a while before calling it again
*/ */
.declareMethod("delayRefresh", function (room, delay) { .declareMethod("delayRefresh", function (room, poll_delay_index) {
var gadget = this; var gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
if (poll_delay_index >= POLL_DELAY_LIST.length) {
poll_delay_index = POLL_DELAY_LIST.length - 1;
}
// do not wait for refreshChat to finish before starting the delay
return RSVP.all([ return RSVP.all([
RSVP.delay(delay), RSVP.delay(POLL_DELAY_LIST[poll_delay_index]),
gadget.refreshChat(room) gadget.refreshChat(room)
]); ]);
}) })
.push(function () { .push(function () {
if (gadget.state.delay_refresh_dict.hasOwnProperty(room)) {
gadget.state.delay_refresh_dict[room].cancel(); gadget.state.delay_refresh_dict[room].cancel();
}
gadget.state.delay_refresh_dict[room] = new RSVP.Queue() gadget.state.delay_refresh_dict[room] = new RSVP.Queue()
.push(function () { .push(function () {
return gadget.delayRefresh(room, delay + 10000); return gadget.delayRefresh(room, poll_delay_index + 1);
}); });
}); });
}) })
...@@ -571,15 +624,31 @@ ...@@ -571,15 +624,31 @@
/* Refresh the message list with chats from the jIO storage. /* Refresh the message list with chats from the jIO storage.
* Parameters: * Parameters:
* - room: the room to refresh * - room: the room to refresh
* Requirements:
* - refreshChat() is not currently being executed
* - room has an associated room gadget with a valid jIO storage
* - there are no duplicate messages in that jIO storage
* - gadget.state.message_count_dict[room] is the total number of messages
* retrieved from allDocs() the last time refreshChat() was triggered
* - gadget.state.message_list_dict[room] is a chronologically ascending
* list of the unique messages loaded in the current room
* Effects: * Effects:
* - get a sorted list of all chats in the current room from jIO storage * - get a sorted list of all chats in the current room from jIO storage
* - merge the list with the current messages in a priority queue * - merge the list with the sorted list of unique current messages
* - update the current messages with the sorted message queue * - overwrite the latter with the resulting sorted list of unique messages
*/ */
.declareMethod("refreshChat", function (room) { .declareMethod("refreshChat", function (room) {
var gadget = this, var gadget = this,
room_gadget; room_gadget;
// lock so that at most one refreshChat() is running at any time
// multiple calls to repair() results in unmanageable duplication
if (gadget.state.current_refresh_dict[room]) {
return;
}
gadget.state.current_refresh_dict[room] = true;
return gadget.getDeclaredGadget("room-gadget-" + room) return gadget.getDeclaredGadget("room-gadget-" + room)
.push(function (sub_gadget) { .push(function (sub_gadget) {
room_gadget = sub_gadget; room_gadget = sub_gadget;
...@@ -588,55 +657,61 @@ ...@@ -588,55 +657,61 @@
.push(function () { .push(function () {
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, 1000000], limit: [0, JIO_QUERY_MAX_LIMIT],
sort_on: [["date_ms", "ascending"]], select_list: ["content"],
select_list: ["content"] sort_on: [
["date_ms", "ascending"],
["content", "ascending"]
]
}]); }]);
}) })
.push(function (result_list) { .push(function (result_list) {
var i, message, new_list = [], var i, j, message, new_list = [],
old_list = gadget.state.message_list_dict[room], old_list = gadget.state.message_list_dict[room];
message_queue = new FastPriorityQueue(function (lhs, rhs) {
return getTime(lhs) < getTime(rhs);
});
// only run if there are new messages, since messages are not deleted
// calling refreshChat() after deployMessage() does nothing
// because deployMessage() already added one new message
if (result_list.data.total_rows > if (result_list.data.total_rows >
gadget.state.message_count_dict[room]) { gadget.state.message_count_dict[room]) {
gadget.state.message_count_dict[room] = result_list.data.total_rows; gadget.state.message_count_dict[room] = result_list.data.total_rows;
gadget.state.unread_room_dict[room] = true;
// merge two sorted lists of unique messages together
j = 0;
for (i = 0; i < result_list.data.total_rows; i += 1) { for (i = 0; i < result_list.data.total_rows; i += 1) {
try {
message = JSON.parse(result_list.data.rows[i].value.content); message = JSON.parse(result_list.data.rows[i].value.content);
if (message && typeof message === "object") { while (j < old_list.length
message_queue.add(message); && getTime(old_list[j]) < getTime(message)) {
} new_list.push(old_list[j]);
} catch (ignore) {} j += 1;
} }
// ignore duplicates between the lists
for (i = 0; i < old_list.length; i += 1) { while (j < old_list.length
if (!message_queue.isEmpty()) { && isSameMessage(old_list[j], message)) {
message = message_queue.poll(); j += 1;
while (getTime(old_list[i]) < getTime(message)
&& i < old_list.length) {
new_list.push(old_list[i]);
i += 1;
}
while (getTime(old_list[i]) === getTime(message)) {
i += 1;
} }
new_list.push(message); new_list.push(message);
} else {
new_list.push(old_list[i]);
} }
} while (j < old_list.length) {
while (!message_queue.isEmpty()) { new_list.push(old_list[j]);
new_list.push(message_queue.poll()); j += 1;
} }
// override the current list of messages and notify the user
gadget.state.message_list_dict[room] = new_list; gadget.state.message_list_dict[room] = new_list;
return gadget.changeState({refresh_chat: true}); gadget.state.unread_room_dict[room] = true;
return gadget.changeState({
refresh_chat: true,
favicon_alert: true
});
} }
})
// release the lock no matter what errors occur
.push(function () {
gadget.state.current_refresh_dict[room] = false;
}, function () {
gadget.state.current_refresh_dict[room] = false;
}); });
}) })
...@@ -663,16 +738,15 @@ ...@@ -663,16 +738,15 @@
]; ];
switch (command) { switch (command) {
// change to a room that has already been joined // change to the given room
case "join": case "join":
if (gadget.state.message_list_dict[argument] > 0) { if (gadget.state.message_list_dict[argument]) {
return gadget.changeRoom(argument); return gadget.changeRoom(argument);
} }
return gadget.deployNotification({ return gadget.deployNotification({
name: gadget.state.name, name: gadget.state.name,
room: gadget.state.room, room: gadget.state.room,
content: "You must first be connected to room '" content: "You must first add '" + argument + "' as a contact!",
+ argument + "' via a shared jIO storage to join it!",
color: "red" color: "red"
}); });
...@@ -727,7 +801,7 @@ ...@@ -727,7 +801,7 @@
}) })
// Call changeRoom or changeState when a chat contact is clicked. // Call changeRoom when a chat contact is clicked.
.onEvent("click", function (event) { .onEvent("click", function (event) {
var gadget = this, var gadget = this,
...@@ -735,10 +809,10 @@ ...@@ -735,10 +809,10 @@
if (event.target.classList.contains("chat-contact")) { if (event.target.classList.contains("chat-contact")) {
room = gadget.state.id_to_name[event.target.id]; room = gadget.state.id_to_name[event.target.id];
gadget.state.unread_room_dict[room] = false; gadget.state.unread_room_dict[room] = false;
if (gadget.state.message_list_dict[room] > 0) { return gadget.changeState({favicon_alert: false})
.push(function () {
return gadget.changeRoom(room); return gadget.changeRoom(room);
} });
return gadget.changeState({room: room, is_chat: false, update: true});
} }
}, false, false) }, false, false)
...@@ -753,7 +827,7 @@ ...@@ -753,7 +827,7 @@
return gadget.changeState({is_chat: false}); return gadget.changeState({is_chat: false});
case "join-form": case "join-form":
content = resetInputValue(event.target.elements.content); content = resetInputValue(event.target.elements.content);
return gadget.createContact(content); return gadget.createRoom(content);
case "send-form": case "send-form":
content = resetInputValue(event.target.elements.content); content = resetInputValue(event.target.elements.content);
if (content.indexOf("/") === 0) { if (content.indexOf("/") === 0) {
...@@ -783,7 +857,7 @@ ...@@ -783,7 +857,7 @@
var promise_list = [], room; var promise_list = [], room;
for (room in gadget.state.message_list_dict) { for (room in gadget.state.message_list_dict) {
if (gadget.state.message_list_dict.hasOwnProperty(room) if (gadget.state.message_list_dict.hasOwnProperty(room)
&& gadget.state.message_list_dict[room] > 0) { && gadget.state.message_list_dict[room].length > 0) {
promise_list.push(gadget.deployMessage({ promise_list.push(gadget.deployMessage({
name: gadget.state.name, name: gadget.state.name,
content: gadget.state.name + " has quit.", content: gadget.state.name + " has quit.",
...@@ -796,5 +870,4 @@ ...@@ -796,5 +870,4 @@
}); });
}); });
}(window, document, RSVP, rJS, Handlebars, }(window, document, RSVP, rJS, Handlebars, promiseEventListener));
FastPriorityQueue, promiseEventListener));
\ No newline at end of file
...@@ -62,7 +62,6 @@ ...@@ -62,7 +62,6 @@
/* Render the gadget. /* Render the gadget.
* Parameters: nothing
* Effects: update header, page_title to "Connect to Chat" * Effects: update header, page_title to "Connect to Chat"
*/ */
......
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