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.

339 lines
11 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. (function(){
  2. var app = angular.module("roster", []);
  3. /* Controller for Rosterlist */
  4. app.controller("RosterController", function($scope){
  5. /* Cache variables */
  6. $scope.lsJid = localStorage.getItem("username").replace("@", "at");
  7. $scope.lsRoster = localStorage.getObject($scope.lsJid + "_Roster") || {};
  8. $scope.lsGroupState = "groupState" in $scope.lsRoster ? $scope.lsRoster.groupState : {};
  9. $scope.contacts = [];
  10. $scope.groups = [];
  11. /* Dictionaries */
  12. $scope.lookupgroups = {};
  13. $scope.lookupjid = {};
  14. $scope.initContacts = function(list){
  15. document.getElementById("spinner").style.display = "block";
  16. /* Sort groups alphabetically */
  17. list.sort(groupnameCompare);
  18. $scope.contacts = list;
  19. /* Populate dictionaries */
  20. for(var i = 0; i < $scope.contacts.length; i++){
  21. $scope.lookupgroups[$scope.contacts[i].agroup] = $scope.contacts[i];
  22. /* Sort jid by presence and alphabetically */
  23. $scope.contacts[i].agroupitems.sort(jidAvalCompare);
  24. for(var j = 0; j < $scope.contacts[i].agroupitems.length; j++){
  25. $scope.lookupjid[$scope.contacts[i].agroupitems[j].ajid] = $scope.contacts[i].agroupitems[j];
  26. }
  27. }
  28. document.getElementById("spinner").style.display = "none";
  29. $scope.$apply();
  30. };
  31. $scope.initGroups = function(list){
  32. for(var i in list){
  33. if(!("rosterGroup_"+i in $scope.lsGroupState)){
  34. list[i] = true;
  35. $scope.lsGroupState["rosterGroup_" + i] = true;
  36. }
  37. else list[i] = $scope.lsGroupState["rosterGroup_" + i];
  38. }
  39. $scope.groups = list;
  40. $scope.$apply();
  41. };
  42. $scope.deleteContact = function(jid){
  43. $scope.lookupjid[jid].tombstone = true;
  44. $scope.$apply();
  45. };
  46. $scope.pushInPlace = function(element, array, comparer){
  47. if(array === $scope.contacts){
  48. dico = $scope.lookupgroups;
  49. key = "agroup";
  50. } else {
  51. dico = $scope.lookupjid;
  52. key = "ajid";
  53. }
  54. /* Put element in the right place inside array */
  55. index = locationOf(element, array, comparer);
  56. array.splice(index, 0, element);
  57. /* Update dictionary from the appropriate index */
  58. for(var i=index; i<array.length; i++){
  59. dico[array[i][key]] = array[i];
  60. }
  61. };
  62. $scope.updateContact = function(list){
  63. if($scope.contacts === null) $scope.contacts = [];
  64. /* Group change */
  65. if((list.jid in $scope.lookupjid)
  66. && !($scope.lookupjid[list.jid].ajiditems.groupname == list.groupname)){
  67. /* Kill jid from old location or whole group if it's the only jid */
  68. oldgroupname = $scope.lookupjid[list.jid].ajiditems.groupname;
  69. if($scope.lookupgroups[oldgroupname].agroupitems.length == 1){
  70. $scope.lookupgroups[oldgroupname].tombstone = true;
  71. /* Remove group from localStorage */
  72. delete $scope.lsGroupState['rosterGroup_'+oldgroupname];
  73. }
  74. else{
  75. $scope.lookupjid[list.jid].tombstone = true;
  76. }
  77. }
  78. /* New group is not in the list */
  79. if(!(list.groupname in $scope.lookupgroups)) {
  80. /* Create group */
  81. el = {
  82. 'agroup': list.groupname,
  83. 'agroupitems': [],
  84. 'tombstone': false,
  85. };
  86. $scope.pushInPlace(el, $scope.contacts, groupnameCompare);
  87. /* Reference in the localstorage for toggling */
  88. $scope.lsGroupState["rosterGroup_" + list.groupname] = true;
  89. }
  90. /* Jid is in the list and no group change */
  91. if(list.jid in $scope.lookupjid
  92. && ($scope.lookupjid[list.jid].ajiditems.groupname == list.groupname))
  93. {
  94. $scope.lookupjid[list.jid].aval = list.value;
  95. $scope.lookupjid[list.jid].atruename = list.rosterview.name;
  96. $scope.lookupjid[list.jid].ajiditems = list;
  97. $scope.lookupgroups[list.groupname].agroupitems.sort(jidAvalCompare);
  98. }
  99. else{
  100. el = {
  101. 'ajid': list.jid,
  102. 'atruename': list.rosterview.name,
  103. 'aval': list.value,
  104. 'ajiditems': list,
  105. 'tombstone': false,
  106. };
  107. $scope.pushInPlace(el, $scope.lookupgroups[list.groupname].agroupitems, jidAvalCompare);
  108. }
  109. $scope.$apply();
  110. //a new li is created, a new listener has to be created...
  111. document.getElementById(list.jid).onclick = function(){Roster.clickOnContact(this);};
  112. };
  113. this.showHideGroup = function(g){
  114. ls = $scope.lsGroupState["rosterGroup_" + g];
  115. if(ls === null){
  116. ls = $scope.lsGroupState.rosterGroup_Ungrouped;
  117. g = "Ungrouped";
  118. }
  119. ls = !ls;
  120. $scope.lsGroupState["rosterGroup_" + g] = ls;
  121. $scope.groups[g] = ls;
  122. };
  123. this.groupIsShown = function(grp){
  124. if(typeof $scope.groups[grp] != "undefined"){
  125. return $scope.groups[grp];
  126. }
  127. else return $scope.groups["Ungrouped"];
  128. };
  129. this.getContactTitle = function(c){
  130. title = accentsTidy(c.rosterview.name) + " - " + c.jid;
  131. if(c.status) title += " - " + c.status;
  132. return title;
  133. };
  134. this.getOnlineCount = function(g){
  135. count = 0;
  136. for(var i in g){
  137. if(g[i].aval < 5) count ++;
  138. }
  139. return count;
  140. };
  141. this.getContactClient = function(c){
  142. liclass = "";
  143. if(c.rosterview.client)
  144. liclass = "client " + c.rosterview.client;
  145. return liclass;
  146. };
  147. this.getJidStatusResource = function(c){
  148. lititle = c.jid;
  149. if(c.status != '') lititle += " - " + c.status;
  150. lititle += " - " + c.resource;
  151. return lititle;
  152. };
  153. this.getPresenceInactiveClient = function(c){
  154. liclass = c.rosterview.presencetxt + " " + contact.rosterview.inactive;
  155. if(c.client) liclass += " client " + c.client;
  156. return liclass;
  157. };
  158. });
  159. })();
  160. window.onunload = window.onbeforeunload = function(e){
  161. var lsjid = angular.element(roster).scope().lsJid;
  162. // Update real localstorage
  163. angular.element(roster).scope().lsRoster.groupState = angular.element(roster).scope().lsGroupState;
  164. localStorage.setObject(lsjid + "_Roster", angular.element(roster).scope().lsRoster);
  165. };
  166. /* Functions to call angular inner functions */
  167. function initContacts(tab){
  168. if(tab.length == 0)
  169. angular.element(roster).scope().contacts = null;
  170. else
  171. angular.element(roster).scope().initContacts(JSON.parse(tab));
  172. Roster.refresh();
  173. }
  174. function initGroups(tab){
  175. angular.element(roster).scope().initGroups(JSON.parse(tab));
  176. }
  177. function updateContact(tab){
  178. angular.element(roster).scope().updateContact(JSON.parse(tab));
  179. }
  180. function deleteContact(jid){
  181. angular.element(roster).scope().deleteContact(jid);
  182. }
  183. /* === PushInPlace subfunctions === */
  184. function locationOf(element, array, comparer, start, end) {
  185. if (array.length === 0)
  186. return 0;
  187. start = start || 0;
  188. end = end || array.length;
  189. var pivot = (start + end) >> 1; // >>1 = /2
  190. var c = comparer(element, array[pivot]);
  191. if ((end - start) <= 1){
  192. return (c == -1) ? pivot : pivot+1;
  193. }
  194. switch (c) {
  195. case -1: return locationOf(element, array, comparer, start, pivot);
  196. case 0: return pivot;
  197. case 1: return locationOf(element, array, comparer, pivot, end);
  198. };
  199. };
  200. /* Object comparison functions */
  201. var groupnameCompare = function(a, b) {
  202. return a.agroup.localeCompare(b.agroup);
  203. };
  204. /* Presence + alphabetical comparison */
  205. var jidAvalCompare = function(a, b) {
  206. n = a.aval - b.aval;
  207. if(n == 0){
  208. n = a.atruename.localeCompare(b.atruename);
  209. }
  210. return n ? n < 0 ? -1 : 1 : 0;
  211. };
  212. var Roster = {
  213. init : function() {
  214. var search = document.querySelector('#rostersearch');
  215. var roster = document.querySelector('#roster');
  216. var rosterlist = document.querySelector('#rosterlist');
  217. roster.onblur = function() {
  218. roster.className = roster_classback;
  219. rosterlist.className = rosterlist_classback;
  220. };
  221. search.oninput = function(event) {
  222. if(search.value.length > 0) {
  223. movim_add_class(roster, 'search');
  224. } else {
  225. movim_remove_class(roster, 'search');
  226. }
  227. // We clear the old search
  228. var selector_clear = '#rosterlist div > li.found';
  229. var li = document.querySelectorAll(selector_clear);
  230. for(i = 0; i < li.length; i++) {
  231. movim_remove_class(li.item(i), 'found');
  232. }
  233. // We select the interesting li
  234. var selector = '#rosterlist div > li[title*="' + accentsTidy(search.value) + '"]:not(.subheader)';
  235. li = document.querySelectorAll(selector);
  236. if(li != null && li.item(0) != null ){
  237. var g = li.item(0).parentNode.querySelector('.subheader');
  238. movim_add_class(g, 'found');
  239. for(i = 0; i < li.length; i++) {
  240. if(li.item(i).parentNode.firstChild != g){
  241. g = li.item(i).parentNode.querySelector('.subheader');
  242. movim_add_class(g, 'found');
  243. }
  244. movim_add_class(li.item(i), 'found');
  245. }
  246. }
  247. };
  248. },
  249. refresh: function() {
  250. var items = document.querySelectorAll('#rosterlist div > li:not(.subheader)');
  251. var i = 0;
  252. while(i < items.length)
  253. {
  254. items[i].onclick = function(){Roster.clickOnContact(this);};
  255. i++;
  256. }
  257. },
  258. reset: function(list) {
  259. for(i = 0; i < list.length; i++) {
  260. movim_remove_class(list[i], 'active');
  261. }
  262. },
  263. clearSearch: function() {
  264. var search = document.querySelector('#rostersearch');
  265. search.value = '';
  266. search.oninput();
  267. },
  268. setFound : function(jid) {
  269. document.querySelector('input[name=searchjid]').value = jid;
  270. },
  271. clickOnContact : function(e) {
  272. Contact_ajaxGetContact(e.id);
  273. /*recalculated at each click*/
  274. var it = document.querySelectorAll('#rosterlist div > li:not(.subheader)');
  275. Roster.reset(it);
  276. Roster.clearSearch();
  277. movim_add_class(e, 'active');
  278. },
  279. }
  280. MovimWebsocket.attach(function() {
  281. Roster_ajaxGetRoster();
  282. Roster.refresh();
  283. Notification.current('contacts');
  284. });
  285. movim_add_onload(function(){
  286. Roster.init();
  287. });