src/js/supportchat.js

Thu, 01 Apr 2010 16:07:16 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 01 Apr 2010 16:07:16 +0100
changeset 36
562ff07a3968
parent 34
js/supportchat.js@510ca613996a
child 37
010783d24970
permissions
-rw-r--r--

Large commit - reorganises directory structure, lots of small fixes

/* 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,'&amp;').
		replace(/>/g,'&gt;').
		replace(/</g,'&lt;').
		replace(/"/g,'&quot;');
}

function activate_links()
{
	$("[href='#support-chat']").click(display_ui);
}

$(activate_links); //FIXME (debugging)

mercurial