Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

One-on-one profile pane #272

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ module.exports = function(grunt) {
'libs/strophejs-plugins/muc/strophe.muc.js',
'libs/strophejs-plugins/disco/strophe.disco.js',
'libs/strophejs-plugins/caps/strophe.caps.jsonly.js',
'libs/strophejs-plugins/vcard/strophe.vcard.js',
'libs/mustache.js/mustache.js',
'libs/jquery-i18n/jquery.i18n.js',
'libs/dateformat/dateFormat.js'
Expand Down
235 changes: 177 additions & 58 deletions candy.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion candy.bundle.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions candy.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion candy.min.map

Large diffs are not rendered by default.

64 changes: 63 additions & 1 deletion libs/libs.bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion libs/libs.bundle.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions libs/libs.min.js

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ Candy.Core = (function(self, Strophe, $) {
* JID resource to use when connecting to the server.
* Specify `''` (an empty string) to request a random resource.
*/
resource: Candy.about.name
resource: Candy.about.name,
/** Boolean: useParticipantRealJid
* If set true, will direct one-on-one chats to participant's real JID rather than their MUC jid
*/
useParticipantRealJid: false
},

/** PrivateFunction: _addNamespace
Expand Down
85 changes: 82 additions & 3 deletions src/core/chatUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
*/
'use strict';

/* global Candy, Strophe */
/* global Candy, Strophe, jQuery */

/** Class: Candy.Core.ChatUser
* Chat User
*/
Candy.Core.ChatUser = function(jid, nick, affiliation, role) {
Candy.Core.ChatUser = function(jid, nick, affiliation, role, realJid) {
/** Constant: ROLE_MODERATOR
* Moderator role
*/
Expand All @@ -38,12 +38,14 @@ Candy.Core.ChatUser = function(jid, nick, affiliation, role) {
*/
this.data = {
jid: jid,
realJid: realJid || jid,
nick: Strophe.unescapeNode(nick),
affiliation: affiliation,
role: role,
privacyLists: {},
customData: {},
previousNick: undefined
previousNick: undefined,
vCard: {nickName: Strophe.unescapeNode(nick)}
};

/** Function: getJid
Expand Down Expand Up @@ -75,6 +77,22 @@ Candy.Core.ChatUser = function(jid, nick, affiliation, role) {
return Candy.Util.escapeJid(this.data.jid);
};

/** Function: getRealJid
* Gets the user's real JID, available to members of a room with appropriate permissions. Defaults to their roomJid.
*
* See:
* <Candy.Util.unescapeJid>
*
* Returns:
* (String) - real jid
*/
this.getRealJid = function() {
if(this.data.realJid) {
return Candy.Util.unescapeJid(this.data.realJid);
}
return;
};

/** Function: setJid
* Sets a user's jid
*
Expand Down Expand Up @@ -262,4 +280,65 @@ Candy.Core.ChatUser = function(jid, nick, affiliation, role) {
this.getPreviousNick = function() {
return this.data.previousNick;
};

/** Function: fetchVCard
* Requests the VCard for the user from the server
*/
this.fetchVCard = function(callback) {
var data = this.data;
Candy.Core.getConnection().vcard.get(function(stanza) {
var v = jQuery(stanza).find('vCard[xmlns="' + Strophe.NS.VCARD + '"]'),
tel = v.find('TEL'),
email = v.find('EMAIL'),
photo = v.find('PHOTO'),
org = v.find('ORG'),
adr = v.find('ADR');
data.vCard = {
nickName: v.find('NICKNAME').text(),
fullName: v.find('FN').text(),
title: v.find('TITLE').text(),
url: v.find('URL').text(),
description: v.find('DESC').text(),
tel: {
voice: tel.find('VOICE').text(),
work: tel.find('WORK').text(),
number: tel.find('NUMBER').text()
},
email: {
internet: email.find('INTERNET').text(),
pref: email.find('PREF').text(),
userID: email.find('USERID').text()
},
birthDay: v.find('BDAY').text(),
role: v.find('ROLE').text(),
photo: {
type: photo.find('TYPE').text(),
binaryValue: photo.find('BINVAL').text()
},
name: v.find('N').text(),
organisation: {
name: org.find('ORGNAME').text(),
unit: org.find('ORGUNIT').text()
},
address: {
country: adr.find('CTRY').text(),
locality: adr.find('LOCALITY').text(),
street: adr.find('STREET').text(),
region: adr.find('REGION').text(),
postCode: adr.find('PCODE').text()
}
};
callback(data.vCard);
}, this.data.jid);
};

/** Function: getVCard
* Gets the user's vcard if available.
*
* Returns:
* (String) - vcard
*/
this.getVCard = function() {
return this.data.vCard;
};
};
26 changes: 14 additions & 12 deletions src/core/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ Candy.Core.Event = (function(self, Strophe, $) {
action = 'join';
} else {
nick = Strophe.getResourceFromJid(from);
user = new Candy.Core.ChatUser(from, nick, item.attr('affiliation'), item.attr('role'));
user = new Candy.Core.ChatUser(from, nick, item.attr('affiliation'), item.attr('role'), item.attr('jid'));
// Room existed but client (myself) is not yet registered
if(room.getUser() === null && (Candy.Core.getUser().getNick() === nick || nickAssign)) {
room.setUser(user);
Expand Down Expand Up @@ -665,40 +665,41 @@ Candy.Core.Event = (function(self, Strophe, $) {
var roomJid, message, name;
if(msg.children('subject').length > 0 && msg.children('subject').text().length > 0 && msg.attr('type') === 'groupchat') {
roomJid = Candy.Util.unescapeJid(Strophe.getBareJidFromJid(msg.attr('from')));
message = { name: Strophe.getNodeFromJid(roomJid), body: msg.children('subject').text(), type: 'subject' };
message = { from: roomJid, name: Strophe.getNodeFromJid(roomJid), body: msg.children('subject').text(), type: 'subject' };
// Error messsage
} else if(msg.attr('type') === 'error') {
var error = msg.children('error');
if(error.children('text').length > 0) {
roomJid = msg.attr('from');
message = { type: 'info', body: error.children('text').text() };
message = { from: roomJid, type: 'info', body: error.children('text').text() };
}
// Chat message
} else if(msg.children('body').length > 0) {
// Private chat message
if(msg.attr('type') === 'chat' || msg.attr('type') === 'normal') {
roomJid = Candy.Util.unescapeJid(msg.attr('from'));
var bareRoomJid = Strophe.getBareJidFromJid(roomJid),
// if a 3rd-party client sends a direct message to this user (not via the room) then the username is the node and not the resource.
isNoConferenceRoomJid = !Candy.Core.getRoom(bareRoomJid);
var from = Candy.Util.unescapeJid(msg.attr('from'));
roomJid = Strophe.getBareJidFromJid(from);

name = isNoConferenceRoomJid ? Strophe.getNodeFromJid(roomJid) : Strophe.getResourceFromJid(roomJid);
message = { name: name, body: msg.children('body').text(), type: msg.attr('type'), isNoConferenceRoomJid: isNoConferenceRoomJid };
// if a 3rd-party client sends a direct message to this user (not via the room) then the username is the node and not the resource.
var isNoConferenceRoomJid = !Candy.Core.getRoom(roomJid);

name = isNoConferenceRoomJid ? Strophe.getNodeFromJid(from) : Strophe.getResourceFromJid(from);
message = { from: from, name: name, body: msg.children('body').text(), type: msg.attr('type'), isNoConferenceRoomJid: isNoConferenceRoomJid };
// Multi-user chat message
} else {
roomJid = Candy.Util.unescapeJid(Strophe.getBareJidFromJid(msg.attr('from')));
var resource = Strophe.getResourceFromJid(msg.attr('from'));
// Message from a user
if(resource) {
resource = Strophe.unescapeNode(resource);
message = { name: resource, body: msg.children('body').text(), type: msg.attr('type') };
message = { from: roomJid, name: resource, body: msg.children('body').text(), type: msg.attr('type') };
// Message from server (XEP-0045#registrar-statuscodes)
} else {
// we are not yet present in the room, let's just drop this message (issue #105)
if(!Candy.View.Pane.Chat.rooms[msg.attr('from')]) {
return true;
}
message = { name: '', body: msg.children('body').text(), type: 'info' };
message = { from: roomJid, name: '', body: msg.children('body').text(), type: 'info' };
}
}

Expand Down Expand Up @@ -761,6 +762,7 @@ Candy.Core.Event = (function(self, Strophe, $) {
* The following lists explain those parameters:
*
* Message Object Parameters:
* (String) from - The unmodified JID that the stanza came from
* (String) name - Room name
* (String) body - Message text
* (String) type - Message type ([normal, chat, groupchat])
Expand All @@ -771,7 +773,7 @@ Candy.Core.Event = (function(self, Strophe, $) {
* This flag tells if this is the case.
*
* Parameters:
* (String) roomJid - Room jid
* (String) roomJid - Room jid. For one-on-one messages, this is sanitized to the bare JID for indexing purposes.
* (Object) message - Depending on what kind of message, the object consists of different key-value pairs:
* - Room Subject: {name, body, type}
* - Error message: {type = 'info', body}
Expand Down
22 changes: 22 additions & 0 deletions src/view/observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,18 @@ Candy.View.Observer = (function(self, $) {
Candy.View.Pane.Roster.update(args.user.getJid(), args.user, args.action, args.currentUser);
Candy.View.Pane.PrivateRoom.setStatus(args.user.getJid(), args.action);
}
} else {
// Presence for a one-on-one chat
var bareJid = Strophe.getBareJidFromJid(args.from),
room = Candy.View.Pane.Chat.rooms[bareJid];
if(!room) {
return false;
}

// Reset the room's target JID
room.targetJid = bareJid;

Candy.View.Pane.Roster.update(bareJid, new Candy.Core.ChatUser(bareJid, 'foo'), 'join', Candy.Core.getUser());
}
},

Expand Down Expand Up @@ -286,6 +298,16 @@ Candy.View.Observer = (function(self, $) {
if(args.message.type === 'chat' && !Candy.View.Pane.Chat.rooms[args.roomJid]) {
Candy.View.Pane.PrivateRoom.open(args.roomJid, args.message.name, false, args.message.isNoConferenceRoomJid);
}
var room = Candy.View.Pane.Chat.rooms[args.roomJid];
if (room.targetJid === args.roomJid) {
// No messages yet received. Lock the room to this resource.
room.targetJid = args.message.from;
} else if (room.targetJid === args.message.from) {
// We're already locked to the correct resource.
} else {
// Message received from alternative resource. Release the resource lock.
room.targetJid = args.roomJid;
}
Candy.View.Pane.Message.show(args.roomJid, args.message.name, args.message.body, args.message.xhtmlMessage, args.timestamp);
}
};
Expand Down
Loading