You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
516 lines
15 KiB
516 lines
15 KiB
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|
<html> |
|
<head> |
|
<style type="text/css"> |
|
@import "../../../dojo/resources/dojo.css"; |
|
@import "../../../dijit/themes/dijit.css"; |
|
@import "../../../dijit/themes/tundra/tundra.css"; |
|
|
|
html,body { |
|
width: 100%; |
|
height: 100%; |
|
overflow: none; |
|
} |
|
|
|
.dijitSplitPane{ |
|
margin: 5px; |
|
} |
|
|
|
#buddyList { |
|
cursor:pointer; |
|
} |
|
|
|
.presence { |
|
background:#525252; |
|
height: 10px; |
|
width: 10px; |
|
margin:5px; |
|
} |
|
|
|
.online, |
|
.available { |
|
background: #00AC00; |
|
} |
|
|
|
|
|
.away { |
|
background: #E20000; |
|
} |
|
|
|
|
|
.offline { |
|
background: #ccc; |
|
} |
|
|
|
</style> |
|
<title>xmpp test page</title> |
|
|
|
<script type="text/javascript" |
|
src="../../../dojo/dojo.js" data-dojo-config="isDebug:true,parseOnLoad:true"> |
|
</script> |
|
<script type="text/javascript"> |
|
|
|
dojo.require("dijit._base.popup"); |
|
dojo.require('dijit.layout.LayoutContainer'); |
|
dojo.require('dijit.layout.ContentPane'); |
|
dojo.require("dijit.layout.TabContainer"); |
|
dojo.require("dijit.form.FilteringSelect"); |
|
dojo.require("dijit.Menu"); |
|
dojo.require("dijit.Dialog"); |
|
dojo.require("dijit.Toolbar"); |
|
dojo.require("dijit.TitlePane"); |
|
dojo.require("dojox.xmpp.xmppSession"); |
|
|
|
dojo.require("dojox.xmpp.widget.ChatSession"); |
|
|
|
dojo.require("dojo.date"); |
|
dojo.require("dojo.date.locale"); |
|
dojo.require("dojo.parser"); |
|
</script> |
|
|
|
<script type="text/javascript"> |
|
|
|
|
|
//We want to know which chat instance is selected, so we can associate |
|
//the <input> area with it |
|
var selectedTab = ""; |
|
var chatTabs = {}; |
|
var chatTabContainer = null; |
|
var chatInstances = {}; |
|
|
|
/*Local copy of the user's roster*/ |
|
var roster = {}; |
|
var groups = {}; |
|
var rosterPresence = {}; |
|
var selectedJID = null; |
|
|
|
dojo.addOnLoad(function() { |
|
|
|
dijit.byId("loginDialog").show(); |
|
var buddyList = dojo.byId("buddyList"); |
|
dojo.connect(buddyList, "ondblclick",function(evt){ |
|
var target = findTargetContact(evt); |
|
if(target) { |
|
openChat(target.jid); |
|
} |
|
}); |
|
|
|
|
|
dojo.connect(buddyList, "oncontextmenu",function(evt){ |
|
selectedJID = null; |
|
var target = findTargetContact(evt); |
|
if(target) { |
|
selectedJID = target.jid; |
|
dojo.stopEvent(evt); |
|
var pop = dijit.popup.open({ |
|
popup: dijit.byId("buddyMenu"), |
|
around: target.target, |
|
onExecute: function(){ |
|
dijit.popup.close( dijit.byId("buddyMenu")); |
|
}, |
|
onCancel: function(){ |
|
dijit.popup.close( dijit.byId("buddyMenu")); |
|
} |
|
}); |
|
|
|
} |
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
function findTargetContact(evt) { |
|
var buddyList = dojo.byId("buddyList"); |
|
var jid = null; |
|
var target = evt.target; |
|
while(!jid && target != buddyList) { |
|
jid = target.getAttribute("imContactId"); |
|
if(!jid) { |
|
target = target.parentNode; |
|
} |
|
} |
|
return jid ? {jid:jid, target:target} : null; |
|
} |
|
|
|
function login() { |
|
|
|
var bindUrl = dijit.byId("bindUrl").attr("value"); |
|
var domain = dijit.byId("loginDomain").attr("value"); |
|
var jid = dijit.byId("loginJid").attr("value"); |
|
var password = dijit.byId("loginPassword").attr("value"); |
|
|
|
var useScriptSrcTransport = false; |
|
if(bindUrl.indexOf("http") == 0) { |
|
useScriptSrcTransport = true; |
|
} |
|
var options = { |
|
serviceUrl:bindUrl,// "http://other.host.local/http-bind/", |
|
hold: 1, |
|
secure: false, |
|
useScriptSrcTransport: useScriptSrcTransport, |
|
wait: 60, |
|
lang: 'en', |
|
retryCount: 2, |
|
domain: domain |
|
}; |
|
|
|
session = new dojox.xmpp.xmppSession(options); |
|
//TESTUSER |
|
|
|
//currently svc.openSession doesn't accept any params |
|
//so the iwc.userPrefs stuff above setup the user id, dont' forget it! |
|
session.open(jid, password, "test-client"); |
|
|
|
|
|
|
|
buddyList = dojo.byId("buddyList"); |
|
chatTabContainer = dijit.byId("chatTabs"); |
|
//sendInput = dojo.byId("sendInput"); |
|
|
|
//When the session becomes active, get the buddy list and populate it |
|
dojo.connect(session, "onActive", function(){ |
|
session.presenceService.publish({}); |
|
}); |
|
|
|
dojo.connect(this.session, 'onRosterAdded', buddyAdded); |
|
|
|
dojo.connect(this.session, 'onRosterChanged', function(rosterItem, previousCopy) { |
|
var presence = rosterPresence[rosterItem.id]; |
|
buddyRemoved(previousCopy); |
|
buddyAdded(rosterItem); |
|
if(presence) { |
|
updateBuddyPresence(presence); |
|
} |
|
}); |
|
dojo.connect(this.session, 'onRosterRemoved', buddyRemoved); |
|
|
|
|
|
dojo.connect(session, "onRosterUpdated", function() { |
|
for(var i=0;i<session.roster.length;i++){ |
|
var buddy = session.roster[i]; |
|
roster[buddy.jid] = buddy; |
|
if(buddy.groups.length == 0 ) { |
|
addBuddyToGroup(buddy, "buddies"); |
|
} else { |
|
for(var j= 0; j < buddy.groups.length; j++) { |
|
addBuddyToGroup(buddy, buddy.groups[j]); |
|
} |
|
} |
|
} |
|
for(groupName in groups) { |
|
createGroup(groupName); |
|
} |
|
}); |
|
|
|
|
|
|
|
//subscribe to presence notifications |
|
dojo.connect(session, 'onPresenceUpdate', updateBuddyPresence); |
|
|
|
|
|
//subscribe to onSubscriptionRequest. For this test, we'll just |
|
//automatically accept any susbscription request |
|
dojo.connect(session, "onSubscriptionRequest", function(from){ |
|
session.presenceService.approveSubscription(from); |
|
}); |
|
|
|
|
|
|
|
dojo.connect(session, "onRegisterChatInstance", function(instance, message){ |
|
|
|
//in the case of we are creating a new chat instance, defer the tab creation |
|
//until the invite has occurred and the contact's uid has been added |
|
if (instance.uid){ |
|
if(!chatInstances[instance.uid] || chatInstances[instance.uid].chatid != instance.chatid){ |
|
newMessage(instance, instance.uid, message); |
|
} |
|
chatInstances[instance.uid] = instance; |
|
} |
|
|
|
dojo.connect(instance, "onInvite", dojo.hitch(this,function(contact){ |
|
chatInstances[contact] = instance; |
|
newMessage(instance, contact, null); |
|
})); |
|
|
|
|
|
//do something when we get a new message from this chat instance |
|
dojo.connect(instance, "onNewMessage", dojo.hitch(this, function(msg){ |
|
newMessage(instance, instance.uid, msg); |
|
})); |
|
|
|
//I'm not going to wire this up for this example, but this |
|
//is the event that would signal whether a person is writing, |
|
//idle, etc (ie, the little pencil in adium) |
|
dojo.connect(instance, "setState", function(state){ |
|
console.log("IM: ", instance.uid, " is now ", state); |
|
}); |
|
}); |
|
|
|
} |
|
|
|
function createGroup(groupName) { |
|
var div = document.createElement("div"); |
|
buddyList.appendChild(div); |
|
var groupItems = groups[groupName].items; |
|
var buffer = new dojox.string.Builder(); |
|
for(var i=0;i<groupItems.length;i++){ |
|
var buddy = groupItems[i]; |
|
renderBuddy(buffer, buddy); |
|
} |
|
div.innerHTML = buffer.toString(); |
|
var titlePane = new dijit.TitlePane({title: groupName}, div); |
|
|
|
groups[groupName].container = titlePane; |
|
return titlePane; |
|
} |
|
|
|
function updateBuddyPresence(p){ |
|
rosterPresence[p.from] = p; |
|
dojo.query('div[imContactId="'+p.from+'"]', buddyList).forEach(function(contact) { |
|
contact.firstChild.className = "dijitInline presence " + p.show; |
|
}); |
|
|
|
} |
|
|
|
function buddyRemoved(buddy){ |
|
delete roster[buddy.id]; |
|
delete rosterPresence[buddy.id]; |
|
dojo.query('div[imContactId="'+buddy.id+'"]', buddyList).forEach(function(contact) { |
|
contact.parentNode.removeChild(contact); |
|
}); |
|
} |
|
|
|
function buddyAdded(buddy) { |
|
roster[buddy.id] =buddy |
|
if(buddy) { |
|
var div = null; |
|
if(buddy.groups.length == 0 ) { |
|
addBuddyToGroup(buddy, "buddies"); |
|
var container = groups["buddies"].container; |
|
if(container) { |
|
div = container.containerNode; |
|
var buffer = new dojox.string.Builder(); |
|
buffer.append(div.innerHTML); |
|
renderBuddy(buffer, buddy); |
|
div.innerHTML = buffer; |
|
} else { |
|
div = createGroup("buddies").containerNode; |
|
} |
|
|
|
} else { |
|
for(var j= 0; j < buddy.groups.length; j++) { |
|
var groupName = buddy.groups[j]; |
|
addBuddyToGroup(buddy, groupName); |
|
var container = groups[groupName].container; |
|
if(container) { |
|
div = container.containerNode; |
|
var buffer = new dojox.string.Builder(); |
|
buffer.append(div.innerHTML); |
|
renderBuddy(buffer, buddy); |
|
div.innerHTML = buffer; |
|
} else { |
|
div = createGroup(groupName).containerNode; |
|
} |
|
|
|
} |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
function renderBuddy(buffer, buddy) { |
|
buffer.append('<div imContactId="'); |
|
buffer.append(buddy.jid); |
|
buffer.append('"><div class="dijitInline presence"></div><div class="dijitInline ">'); |
|
buffer.append(buddy.name?buddy.name:buddy.jid); |
|
buffer.append('</div></div>'); |
|
} |
|
|
|
function addBuddyToGroup(buddy, groupName) { |
|
var group = groups[groupName]; |
|
if(!group) { |
|
group = {name:groupName, items: []}; |
|
groups[groupName] =group; |
|
} |
|
group.items.push(buddy); |
|
} |
|
|
|
function newMessage(instance, jid, message) { |
|
var tab = chatTabs[jid]; |
|
if(!tab) { |
|
var div = document.createElement("div"); |
|
var buddy = roster[jid]; |
|
var chatWith = jid; |
|
if(buddy && buddy.name) { |
|
chatWith = buddy.name; |
|
} |
|
tab = new dojox.xmpp.widget.ChatSession({title: jid, chatWith: chatWith, instance: instance, closable: true}, div); |
|
dojo.connect(tab, "onClose", function() { |
|
delete chatTabs[jid]; |
|
}); |
|
chatTabContainer.addChild(tab); |
|
chatTabContainer.selectChild(tab); |
|
chatTabContainer.layout(); |
|
chatTabs[jid] = tab; |
|
} |
|
tab.displayMessage(message); |
|
|
|
} |
|
|
|
function openChat(jid){ |
|
var tab = chatTabs[jid]; |
|
if(tab) { |
|
chatTabContainer.selectChild(tab); |
|
} |
|
|
|
var chatInstance = new dojox.xmpp.ChatService(); |
|
session.registerChatInstance(chatInstance); |
|
chatInstance.invite(jid); |
|
} |
|
|
|
|
|
function updatePresence(p){ |
|
//since the filtering select wants to call its onChange |
|
//at startup and the svc isn't started up yet, we just ignore it |
|
//for this test case |
|
if (session && session.presenceService) { |
|
session.presenceService.publish({show:p}); |
|
} |
|
} |
|
|
|
|
|
function addUser() { |
|
var userJID = dijit.byId("userJID").attr("value"); |
|
var userAlias = dijit.byId("userAlias").attr("value"); |
|
var userGroups = dijit.byId("userGroups").attr("value"); |
|
|
|
var groups = userGroups.split(","); |
|
session.rosterService.addRosterItem(userJID, userAlias, groups); |
|
} |
|
|
|
function showAddBuddy() { |
|
dijit.byId("userJID").setValue(""); |
|
dijit.byId("userJID").setDisabled(false); |
|
|
|
dijit.byId("userAlias").setValue(""); |
|
dijit.byId("userGroups").setValue(""); |
|
dijit.byId('addUser').show(); |
|
} |
|
|
|
function showEditBuddy() { |
|
var buddy = roster[selectedJID]; |
|
if(buddy) { |
|
dijit.byId("userJID").setValue(selectedJID); |
|
dijit.byId("userJID").setDisabled(true); |
|
|
|
dijit.byId("userAlias").setValue(buddy.name? buddy.name : ""); |
|
dijit.byId("userGroups").setValue(buddy.groups? buddy.groups.join(",") : ""); |
|
dijit.byId('addUser').show(); |
|
} |
|
} |
|
|
|
function subscribeBuddy(){ |
|
session.presenceService.subscribe(selectedJID); |
|
} |
|
|
|
|
|
function deleteBuddy(){ |
|
if(confirm("Sure you want to delete " + selectedJID + " ?")) { |
|
session.rosterService.removeRosterItem(selectedJID); |
|
} |
|
} |
|
|
|
</script> |
|
</head> |
|
|
|
<body class="tundra"> |
|
foo |
|
<div dojoType="dijit.Dialog" id="loginDialog" style="display: none; width:400px" title="Login"> |
|
<table> |
|
<tr> |
|
<td><label for="name">JID: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="loginJid" value="foo"></td> |
|
</tr> |
|
<tr> |
|
<td><label for="loc">Password: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="password" id="loginPassword" value="papajeza"></td> |
|
</tr> |
|
<tr> |
|
<td><label for="loc">Domain: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="loginDomain" value="mac"></td> |
|
</tr> |
|
<tr> |
|
<td><label for="loc">HTTP-Bind URL: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="bindUrl" value="http://127.0.0.1:7070/http-bind/"></td> |
|
</tr> |
|
<tr> |
|
<td colspan="2"><small>Note: a relative Bind URL will use the standard XHR transport and a full URL will use the cross-domain BOSH script syntax.</small></td> |
|
</tr> |
|
<tr> |
|
<td colspan="2" align="center"> |
|
<button dojoType="dijit.form.Button" onClick="login()" type="submit">Login</button></td> |
|
</tr> |
|
</table> |
|
</div> |
|
|
|
<div dojoType="dijit.Dialog" id="addUser" style="display: none" title="Add User"> |
|
<table> |
|
<tr> |
|
<td><label for="name">JID: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="userJID" value=""></td> |
|
</tr> |
|
<tr> |
|
<td><label for="name">Alias: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="userAlias" value=""></td> |
|
</tr> |
|
<tr> |
|
<td><label for="name">Groups: </label></td> |
|
<td><input dojoType="dijit.form.TextBox" type="text" id="userGroups" value=""></td> |
|
</tr> |
|
<tr> |
|
<td colspan="2" align="center"> |
|
<button dojoType="dijit.form.Button" onClick="addUser()" type="submit">Save</button> |
|
<button dojoType="dijit.form.Button" onClick="dijit.byId('addUser').hide();" type="submit">Cancel</button></td> |
|
</tr> |
|
</table> |
|
</div> |
|
<div dojoType="dijit.Menu" id="buddyMenu" style="display:none; width: 190px;"> |
|
|
|
<div dojoType="dijit.MenuItem" onClick="showEditBuddy" > |
|
Edit Buddy |
|
</div> |
|
<div dojoType="dijit.MenuItem" onClick="subscribeBuddy"> |
|
Re-request subscription |
|
</div> |
|
<div dojoType="dijit.MenuItem" onClick="deleteBuddy"> |
|
Delete |
|
</div> |
|
|
|
</div> |
|
|
|
<div dojoType="dijit.layout.LayoutContainer" style="width: 100%; height: 100%;"> |
|
<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="height: 50px; background: #999999;"> |
|
XMPP Test Client |
|
<div style="top:10px; float: right;"> |
|
Status: <select dojoType="dijit.form.FilteringSelect" id="presence" name="presence" autoComplete="false" onChange="updatePresence(arguments[0]);"> |
|
<option value="available" selected>Online</option> |
|
<option value="away">Away</option> |
|
<option value="chat">Free to Chat</option> |
|
<option value="dnd">Do Not Disturb</option> |
|
<option value="xa">Extended Away</option> |
|
</select> |
|
<button dojoType="dijit.form.Button" id="addUserButton" onClick="showAddBuddy()">Add Buddy</button> |
|
</div> |
|
</div> |
|
|
|
<div id="buddyListCP" dojoType="dijit.layout.ContentPane" layoutAlign="right" style="width: 200px; border: 1px solid #999999; overflow:auto;"> |
|
|
|
<div id="buddyList"> |
|
</div> |
|
</div> |
|
<div id="chatTabs" dojoType="dijit.layout.TabContainer" layoutAlign="client" style="border: 1px solid #999999; height:100%"></div> |
|
</div> |
|
</body> |
|
</html>
|
|
|