PresenceService.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.xmpp.PresenceService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.xmpp.PresenceService"] = true;
  8. dojo.provide("dojox.xmpp.PresenceService");
  9. dojox.xmpp.presence = {
  10. UPDATE: 201,
  11. SUBSCRIPTION_REQUEST: 202,
  12. // SUBSCRIPTION_REQUEST_PENDING: 203,
  13. /* used when 'ask' attribute is absent on a roster item */
  14. SUBSCRIPTION_SUBSTATUS_NONE: 204,
  15. SUBSCRIPTION_NONE: 'none',
  16. SUBSCRIPTION_FROM: 'from',
  17. SUBSCRIPTION_TO: 'to',
  18. SUBSCRIPTION_BOTH: 'both',
  19. SUBSCRIPTION_REQUEST_PENDING: 'pending',
  20. STATUS_ONLINE: 'online',
  21. STATUS_AWAY: 'away',
  22. STATUS_CHAT: 'chat',
  23. STATUS_DND: 'dnd',
  24. STATUS_EXTENDED_AWAY: 'xa',
  25. STATUS_OFFLINE: 'offline',
  26. STATUS_INVISIBLE: 'invisible'
  27. }
  28. dojo.declare("dojox.xmpp.PresenceService", null, {
  29. constructor: function(xmppService){
  30. this.session= xmppService;
  31. this.isInvisible = false;
  32. this.avatarHash = null;
  33. this.presence = null;
  34. this.restrictedContactjids = {};
  35. },
  36. publish: function(presence){
  37. ////console.log("Presence::publish() ", presence);
  38. this.presence = presence;
  39. this._setPresence();
  40. },
  41. /**
  42. <presence from='juliet@capulet.com/balcony'>
  43. <x xmlns='vcard-temp:x:update'>
  44. <photo>sha1-hash-of-image</photo>
  45. </x>
  46. </presence>
  47. <presence>
  48. <x xmlns='vcard-temp:x:update'>
  49. <photo/>
  50. </x>
  51. </presence>
  52. */
  53. sendAvatarHash: function(avatarHash) {
  54. this.avatarHash = avatarHash;
  55. this._setPresence();
  56. },
  57. _setPresence: function() {
  58. var presence = this.presence;
  59. var p = {xmlns: 'jabber:client'};
  60. if (presence && presence.to){
  61. p.to = presence.to;
  62. }
  63. if (presence.show && presence.show==dojox.xmpp.presence.STATUS_OFFLINE){
  64. p.type = 'unavailable';
  65. }
  66. if (presence.show && presence.show==dojox.xmpp.presence.STATUS_INVISIBLE) {
  67. this._setInvisible();
  68. this.isInvisible = true;
  69. return;
  70. };
  71. if(this.isInvisible) {
  72. //console.log("was invisible, making visible");
  73. this._setVisible();
  74. }
  75. var req = new dojox.string.Builder(dojox.xmpp.util.createElement("presence",p, false));
  76. if (presence.show && presence.show!=dojox.xmpp.presence.STATUS_OFFLINE ) {
  77. req.append(dojox.xmpp.util.createElement("show",{},false));
  78. req.append(presence.show);
  79. req.append("</show>");
  80. }
  81. if(presence.status) {
  82. req.append(dojox.xmpp.util.createElement("status",{},false));
  83. req.append(presence.status);
  84. req.append("</status>");
  85. }
  86. if(this.avatarHash) {
  87. req.append(dojox.xmpp.util.createElement("x",{xmlns: 'vcard-temp:x:update'},false));
  88. req.append(dojox.xmpp.util.createElement("photo",{},false));
  89. req.append(this.avatarHash);
  90. req.append("</photo>");
  91. req.append("</x>");
  92. }
  93. if (presence.priority && presence.show!=dojox.xmpp.presence.STATUS_OFFLINE){
  94. if(presence.priority > 127 || presence.priority < -128){
  95. presence.priority = 5;
  96. }
  97. req.append(dojox.xmpp.util.createElement("priority",{},false));
  98. req.append(presence.priority);
  99. req.append("</priority>");
  100. }
  101. req.append("</presence>");
  102. this.session.dispatchPacket(req.toString());
  103. },
  104. /*
  105. <iq from='bilbo@tolkien.lit/shire' type='set' id='inv1'>
  106. <query xmlns='jabber:iq:privacy'>
  107. <list name='invisible'>
  108. <item action='deny' order='1'>
  109. <presence-out/>
  110. </item>
  111. </list>
  112. </query>
  113. </iq>
  114. <iq from='bilbo@tolkien.lit/shire' type='set' id='active1'>
  115. <query xmlns='jabber:iq:privacy'>
  116. <active name='invisible'/>
  117. </query>
  118. </iq>
  119. Make visible:
  120. <iq from='bilbo@tolkien.lit/shire' type='set' id='active6'>
  121. <query xmlns='jabber:iq:privacy'>
  122. <active/>
  123. </query>
  124. </iq>
  125. */
  126. toggleBlockContact: function(jid) {
  127. if(!this.restrictedContactjids[jid]) {
  128. this.restrictedContactjids[jid] = this._createRestrictedJid();
  129. }
  130. this.restrictedContactjids[jid].blocked = !this.restrictedContactjids[jid].blocked;
  131. //console.log("setting outbound block for ", jid, this.restrictedContactjids[jid]);
  132. this._updateRestricted();
  133. return this.restrictedContactjids;
  134. },
  135. toggleContactInvisiblity: function(jid) {
  136. if(!this.restrictedContactjids[jid]) {
  137. this.restrictedContactjids[jid] = this._createRestrictedJid();
  138. }
  139. this.restrictedContactjids[jid].invisible = !this.restrictedContactjids[jid].invisible;
  140. //console.log("setting outbound presence for ", jid, this.restrictedContactjids[jid]);
  141. this._updateRestricted();
  142. return this.restrictedContactjids;
  143. },
  144. _createRestrictedJid: function() {
  145. return {invisible: false, blocked:false};
  146. },
  147. _updateRestricted: function() {
  148. var props={
  149. id: this.session.getNextIqId(),
  150. from: this.session.jid + "/" + this.session.resource,
  151. type: "set"
  152. };
  153. var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
  154. req.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:privacy"},false));
  155. req.append(dojox.xmpp.util.createElement("list",{name: "iwcRestrictedContacts"},false))
  156. var count = 1;
  157. for(var jid in this.restrictedContactjids) {
  158. var item = this.restrictedContactjids[jid];
  159. //console.log("restricted ", jid, item);
  160. if(item.blocked || item.invisible) {
  161. req.append(dojox.xmpp.util.createElement("item",{value: dojox.xmpp.util.encodeJid(jid), action: "deny", order: count++},false));
  162. if(item.blocked) {
  163. req.append(dojox.xmpp.util.createElement("message",{},true));
  164. }
  165. if(item.invisible) {
  166. req.append(dojox.xmpp.util.createElement("presence-out",{},true));
  167. }
  168. req.append("</item>");
  169. } else {
  170. delete this.restrictedContactjids[jid];
  171. }
  172. }
  173. req.append("</list>");
  174. req.append("</query>");
  175. req.append("</iq>");
  176. //console.log("Restricted list: ", req.toString());
  177. var req2 = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
  178. req2.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:privacy"},false));
  179. req2.append(dojox.xmpp.util.createElement("active",{name:"iwcRestrictedContacts"},true));
  180. req2.append("</query>");
  181. req2.append("</iq>");
  182. //console.log("Activate list: ", req2.toString());
  183. this.session.dispatchPacket(req.toString());
  184. this.session.dispatchPacket(req2.toString());
  185. },
  186. _setVisible: function() {
  187. var props={
  188. id: this.session.getNextIqId(),
  189. from: this.session.jid + "/" + this.session.resource,
  190. type: "set"
  191. };
  192. var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
  193. req.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:privacy"},false));
  194. req.append(dojox.xmpp.util.createElement("active",{},true));
  195. req.append("</query>");
  196. req.append("</iq>");
  197. //console.log(req.toString());
  198. this.session.dispatchPacket(req.toString());
  199. },
  200. _setInvisible: function() {
  201. //console.log("Setting user as invisible");
  202. var props={
  203. id: this.session.getNextIqId(),
  204. from: this.session.jid + "/" + this.session.resource,
  205. type: "set"
  206. };
  207. var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
  208. req.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:privacy"},false));
  209. req.append(dojox.xmpp.util.createElement("list",{name: "invisible"},false))
  210. req.append(dojox.xmpp.util.createElement("item",{action: "deny", order: "1"},false))
  211. req.append(dojox.xmpp.util.createElement("presence-out",{},true));
  212. req.append("</item>");
  213. req.append("</list>");
  214. req.append("</query>");
  215. req.append("</iq>");
  216. props={
  217. id: this.session.getNextIqId(),
  218. from: this.session.jid + "/" + this.session.resource,
  219. type: "set"
  220. };
  221. var req2 = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
  222. req2.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:privacy"},false));
  223. req2.append(dojox.xmpp.util.createElement("active",{name:"invisible"},true));
  224. req2.append("</query>");
  225. req2.append("</iq>");
  226. //console.log(req.toString());
  227. //console.log(req2.toString());
  228. this.session.dispatchPacket(req.toString());
  229. this.session.dispatchPacket(req2.toString());
  230. },
  231. _manageSubscriptions: function(contact, type){
  232. if (!contact){return;}
  233. if (contact.indexOf('@')==-1){
  234. contact += '@' + this.session.domain;
  235. }
  236. var req = dojox.xmpp.util.createElement("presence",{to:contact,type:type},true);
  237. this.session.dispatchPacket(req);
  238. },
  239. subscribe: function(contact){
  240. this._manageSubscriptions(contact, "subscribe");
  241. },
  242. approveSubscription: function(contact){
  243. this._manageSubscriptions(contact, "subscribed");
  244. },
  245. unsubscribe: function(contact){
  246. this._manageSubscriptions(contact, "unsubscribe");
  247. },
  248. declineSubscription: function(contact){
  249. this._manageSubscriptions(contact, "unsubscribed");
  250. },
  251. cancelSubscription: function(contact){
  252. this._manageSubscriptions(contact, "unsubscribed");
  253. }
  254. });
  255. }