--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/js/supportchat.js Thu Apr 01 16:07:16 2010 +0100 @@ -0,0 +1,234 @@ +/* Config */ + +var support_config = { + login_domain: "anon.localhost", + bosh_url: "/http-bind", + muc_server: "support.localhost", + team_rooms: { + "Sales": "sales@support.localhost", + "Technical": "technical@support.localhost" + }, + send_invites: true +}; + +/*** XMPP handling */ +var conn = null; + +/* Called by Strophe when status of connection changes + (from disconnected to connected, vice-versa, etc.) +*/ +function handle_connection_status(status, err) +{ + if(err) + alert("Connection error: " + err); //FIXME: Handle gracefully +} + +/* Initiate the connection to the XMPP server */ +function start_connection() +{ + conn = new Strophe.Connection(support_config.bosh_url); + var ret = true; + try + { + conn.connect(support_config.login_domain, null, handle_connection_status, 50); + } + catch(e) + { + alert("Connection error: " + e); //FIXME + ret = false; + } + return ret; +} + + +/*** UI handling */ + +/* Initial UI state */ +var ui_state = "question"; + +/* Change the UI state (question, wait, converse) */ +function set_ui_state(new_state) +{ + if(ui_state != new_state) + { + $("#support-"+ui_state).hide(); + $("#support-"+(ui_state=new_state)).show(); + } +} + +/* Handle the user submitting the question form */ +function on_question_submit() +{ + var question_type = $("#support-question-type").val(); + var question_name = $("#support-question-name").val(); + var question_text = $("#support-question-text").val(); + + var our_nick = question_name; + + set_ui_state("wait"); + + // Create our question room + var question_muc = new MUC(conn, { + // Handle room joins + joined: function (stanza, muc, nick) + { + if(nick == our_nick) + // We joined the question room, now join the team room and tell them + team_muc.join(support_config.team_rooms[question_type], our_nick); + else if(ui_state == "wait") + { + // We were waiting for an assistant, and one just joined + var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(nick) + "</span>" + " is answering your query</span><br/>\n"; + $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight); + $("#support-send-button").click(function () + { + question_muc.send_message($("#support-input").val()); + $("#support-input").val(""); + }); + set_ui_state("converse"); + } + }, + + // Handle incoming messages + message: function (stanza, muc, nick, message) + { + var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(nick) + "</span>" + ": " + htmlescape(message) + "</span><br/>\n"; + $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight); + } + }); + + // Get a unique room name from the server and then join the question MUC + conn.sendIQ($iq({to: support_config.muc_server, type: "get"}) + .c("query", { xmlns: "http://jabber.org/protocol/muc#unique" }), + function (result) // Success + { + var unique = Strophe.getText(result.getElementsByTagName("unique")[0]); + question_muc.join(unique + "@" + support_config.muc_server, our_nick); + }, + function (result) // Failure to get unique room name + { + var unique = "support-"+Math.floor(Math.random()*512); + question_muc.join(unique + "@" + support_config.muc_server, our_nick); + }); + + // Create the team MUC object (it will be joined after we join the question MUC) + var team_muc = new MUC(conn, { + joined: function (stanza, muc, nick) + { + if(nick != our_nick) + return; + + var sent = false; + for(var nick in team_muc.occupants) + { + //FIXME: Check affiliation + sent = true; + if(nick == our_nick) + continue; + else if(support_config.send_invites) + team_muc.send_invite(team_muc.jid+"/"+nick, question_text + "\n" + question_muc.jid); + else + team_muc.send_private_message(nick, question_text + "\n" + question_muc.jid); + } + if(!sent) + { + set_ui_state("offline"); + } + }, + + error: function (stanza, muc, error) + { + if(error == "conflict") + { + our_nick += "_"; + muc.join(support_config.team_rooms[question_type], our_nick); + } + else + alert("unhandled error: " + error); + } + }); +} + +function build_ui() +{ + return $(' \ + <div id="support-chat"> \ + <div id="support-question"> \ + <h2>What is the nature of your question?</h2> \ + <select id="support-question-type"> \ + <option>Sales</option> \ + <option>Technical</option> \ + </select> \ + <h2>What is your name?</h2> \ + <input id="support-question-name" type="text" /> \ + <h2>Your question:</h2> \ + <textarea id="support-question-text"></textarea><br/> \ + <input id="support-question-submit" type="submit" /> \ + </div> \ + <div id="support-wait"> \ + Please wait while we find someone to \ + answer your query... \ + <br/><br/><br/><br/> \ + <center><img src="waiting.gif" alt="Waiting" /></center> \ + </div> \ + <div id="support-converse"> \ + <div id="support-log"></div> \ + <div id="support-input-container"><textarea id="support-input" type="text" value=""></textarea></div> \ + <input id="support-send-button" type="submit" value="Send" /> \ + <div style="clear:right;"></div> \ + </div> \ + <div id="support-offline"> \ + <p>Sorry, there are no assistants available \ + to answer your question at the moment. \ + </p> \ + <div id="support-offline-form"> \ + <p>To receive a reply to your question via \ + email, please enter your email address \ + below: \ + </p> \ + <input id="support-offline-email" type="text" /> \ + <input id="support-send-button" type="submit" value="Submit" /> \ + </div> \ + <div id="support-offline-thanks"> \ + <p>Thank you. Your question has been submitted \ + and will be replied to as soon as an assistant \ + becomes available.</p> \ + </div> \ + </div> \ + </div> \ + '); +} + +function display_ui() +{ + // Display pop-up, showing question form + var ui = build_ui(); + + ui.appendTo("body"); + + if(start_connection()) + { + $("#support-question-submit").click(on_question_submit); + ui.dialog({ + title:"Live Support", + height: 400, + width: 285 + }); + } +} + +/*** Helper functions */ +function htmlescape(s) +{ + return s.replace(/&/g,'&'). + replace(/>/g,'>'). + replace(/</g,'<'). + replace(/"/g,'"'); +} + +function activate_links() +{ + $("[href='#support-chat']").click(display_ui); +} + +$(activate_links); //FIXME (debugging)