social_stream-presence 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,4 +2,6 @@
2
2
  //= require strophe
3
3
  //= require jquery.tools.tooltip
4
4
  //= require jquery.ui.chatbox
5
+ //= require jquery.flexselect
6
+ //= require liquidmetal
5
7
  //= require_tree .
@@ -136,7 +136,8 @@ var awayTimer;
136
136
  var timer;
137
137
  var reconnectTimer;
138
138
  var disconnectionFlag = true;
139
- var afterNewConnectionFlagFlag = false;
139
+ var afterNewConnectionFlag = false;
140
+ var afterFirstConnectionFlag = true;
140
141
  var requestContacts=false;
141
142
  var cyclesToRefresh = (refreshMinTime/timerPeriod);
142
143
 
@@ -219,8 +220,6 @@ function onConnect(status) {
219
220
 
220
221
  awayTimer = setInterval("awayTimerFunction()", awayTimerPeriod);
221
222
  timer = setInterval("timerFunction()", timerPeriod);
222
-
223
- hideAllNotifications();
224
223
  }
225
224
 
226
225
  updateChatWindow();
@@ -285,6 +284,8 @@ function onMessage(msg) {
285
284
  ///////
286
285
  function onPresence(presence) {
287
286
 
287
+ log(presence)
288
+
288
289
  //Check presence stanza type
289
290
  ptype = $(presence).attr('type');
290
291
 
@@ -332,8 +333,8 @@ function processUnavailablePresenceStanza(presence){
332
333
 
333
334
  if (slug != user_slug) {
334
335
  if (getConnectionBoxFromSlug(slug)!=null){
335
- hideConnectionBoxFromSlug(slug)
336
- showChatNotificationForSlug(slug,$(getConnectionBoxFromSlug(slug)).attr("name") + " is offline");
336
+ hideConnectionBoxFromSlug(slug);
337
+ showOfflineChatNotificationForSlug(slug);
337
338
  updateConnectedUsersOfMainChatBox();
338
339
  }
339
340
  }
@@ -1,6 +1,5 @@
1
1
  @import "colors";
2
2
 
3
-
4
3
  /* Chatbox style sheet */
5
4
 
6
5
  .ui-widget-content{
@@ -208,7 +207,10 @@ input.connectChatButton{
208
207
  padding: 2px 0 2px 0px;
209
208
  }
210
209
 
211
-
210
+ p.zero_users_connected {
211
+ text-align: center;
212
+ margin-top: 10px;
213
+ }
212
214
 
213
215
 
214
216
  /* Tooltip */
@@ -223,6 +225,7 @@ input.connectChatButton{
223
225
  color: white;
224
226
  background:transparent url(black_arrow3.png);
225
227
  text-align: center;
228
+ z-index: 10;
226
229
  }
227
230
 
228
231
 
@@ -283,7 +286,7 @@ input.connectChatButton{
283
286
  width:auto;
284
287
  min-width:170px;
285
288
  list-style:none;
286
- z-index: 1;
289
+ z-index: 2;
287
290
  }
288
291
 
289
292
  .dropdown span.value {
@@ -350,3 +353,40 @@ a.chatLink:link, a.chatLink:visited {
350
353
  a.chatImageLink:link, a.chatImageLink:visited {
351
354
  color: $main-color;
352
355
  }
356
+
357
+
358
+
359
+
360
+ /* Chosen stylesheet */
361
+
362
+ div.allContacts {
363
+ width: 100px;
364
+ display: block;
365
+ }
366
+
367
+ #search_chat_contact_flexselect {
368
+ background: url('btn/search_icon.png') 5px 50% no-repeat $secondary-color;
369
+ padding: 0 0px 0 0px;
370
+ font-size: 11px;
371
+ color: $main-color;
372
+ border: solid 1px $input-border-color;
373
+ height: 25px;
374
+ width: 122px;
375
+ padding: 0 3px 0 22px;
376
+ margin-bottom: 1px;
377
+ }
378
+
379
+ #search_chat_contact_flexselect_dropdown {
380
+ background: $secondary-color;
381
+ }
382
+
383
+ #search_chat_contact_flexselect_dropdown li {
384
+ background: $secondary-color;
385
+ font-size: 11px;
386
+ color: $main-color;
387
+ }
388
+
389
+ #search_chat_contact_flexselect_dropdown li:hover {
390
+ background: $separation-color;
391
+ }
392
+
@@ -1,4 +1,5 @@
1
1
  /*
2
2
  *= require jquery.ui.chatbox
3
+ *= require flexselect
3
4
  *= require_tree .
4
5
  */
@@ -1,7 +1,8 @@
1
1
  module XmppHelper
2
2
 
3
3
  def getChatContacts
4
- connected_users = []
4
+ connected_users = []
5
+ all_users = []
5
6
 
6
7
  #Get bidirectional contacts
7
8
  contacts = current_user.contact_actors(:type=>:user)
@@ -12,9 +13,10 @@ module XmppHelper
12
13
  if contact.user.connected
13
14
  connected_users << contact.user
14
15
  end
16
+ all_users << contact.user
15
17
  end
16
18
 
17
- return connected_users
19
+ return [connected_users,all_users]
18
20
  end
19
21
 
20
22
  end
@@ -1,44 +1,57 @@
1
- <div>
2
-
3
- <div class="block">
4
- <div class="header">
5
- <%=image_tag("btn/btn_friend.png", :class => "header_icon")%>
6
- <div class="header_text">
7
- <%=t('chat.title')%>
8
- </div>
9
- </div>
10
-
11
- <div id="status" class="dropdown">
12
- <dt><a href=""><span><%=t('chat.status.choose')%></span></a></dt>
13
- <dd>
14
- <ul id="statusList">
15
- <li><a id="available" href="#" class="option"><img class="flag" src="<%=image_path("status/available.png")%>" alt=""/> <%=t('chat.status.available')%> <span class="value">available</span></a></li>
16
- <li><a id="away" href="#" class="option"><img class="flag" src="<%=image_path("status/away.png")%>" alt=""/> <%=t('chat.status.away')%> <span class="value">away</span></a></li>
17
- <li><a id="dnd" href="#" class="option"><img class="flag" src="<%=image_path("status/dnd.png")%>" alt=""/> <%=t('chat.status.dnd')%> <span class="value">dnd</span></a></li>
18
- <li><a id="offline" href="#" class="option"><img class="flag" src="<%=image_path("status/offline.png")%>" alt=""/> <%=t('chat.status.offline')%> <span class="value">offline</span></a></li>
19
- </ul>
20
- </dd>
21
- </div>
22
-
23
- </div>
1
+ <div>
2
+ <div class="block">
3
+ <div class="header">
4
+ <%=image_tag("btn/btn_friend.png", :class => "header_icon")%>
5
+ <div class="header_text">
6
+ <%=t('chat.title')%>
7
+ </div>
8
+ </div>
9
+
10
+ <div id="status" class="dropdown">
11
+ <dt><a href=""><span><%=t('chat.status.choose')%></span></a></dt>
12
+ <dd>
13
+ <ul id="statusList">
14
+ <li><a id="available" href="#" class="option"><img class="flag" src="<%=image_path("status/available.png")%>" alt=""/> <%=t('chat.status.available')%> <span class="value">available</span></a></li>
15
+ <li><a id="away" href="#" class="option"><img class="flag" src="<%=image_path("status/away.png")%>" alt=""/> <%=t('chat.status.away')%> <span class="value">away</span></a></li>
16
+ <li><a id="dnd" href="#" class="option"><img class="flag" src="<%=image_path("status/dnd.png")%>" alt=""/> <%=t('chat.status.dnd')%> <span class="value">dnd</span></a></li>
17
+ <li><a id="offline" href="#" class="option"><img class="flag" src="<%=image_path("status/offline.png")%>" alt=""/> <%=t('chat.status.offline')%> <span class="value">offline</span></a></li>
18
+ </ul>
19
+ </dd>
20
+ </div>
21
+
22
+ </div>
24
23
 
25
- <% @contacts = getChatContacts %>
24
+ <% @contacts = getChatContacts %>
25
+ <% @online_contacts = @contacts[0] %>
26
+ <% @all_contacts = @contacts[1] %>
27
+
28
+ <div class="allContacts">
29
+ <select data-placeholder="Search Contact" id="search_chat_contact" class="flexselect">
30
+ <option value=""></option>
31
+ <% unless @all_contacts.empty? %>
32
+ <%@all_contacts.each do |contact| %>
33
+ <option value="<%=contact.slug%>"><%=contact.name%></option>
34
+ <% end %>
35
+ <% else %>
36
+ <option value="ZERO_CONTACTS"> <%=t('chat.zerocontacts')%></option>
37
+ <% end %>
38
+ </select>
39
+ </div>
26
40
 
27
- <div class="users_connected">
28
- <% unless @contacts.empty? %>
29
- <%@contacts.each do |contact| %>
30
- <div class="user_presence" name='<%=contact.name%>' slug='<%=contact.slug%>'>
31
- <a title='<%=contact.name%>' class="presence_user_link" width="28">
32
- <%=image_tag(contact.logo.url, :alt => contact.name , :size => "28x28")%>
33
- <% if contact.user.status %>
34
- <%=image_tag("status/" + contact.user.status + ".png", :class => "presence_status") %></a>
35
- <% end %>
36
- </a>
37
- </div>
38
- <%end%>
39
- <% end %>
40
- </div>
41
-
42
- </div>
43
-
44
-
41
+ <div class="users_connected">
42
+ <% if @online_contacts.empty? %>
43
+ <p class="zero_users_connected"> <%=t('chat.zerousers')%> </p>
44
+ <% else %>
45
+ <%@online_contacts.each do |contact| %>
46
+ <div class="user_presence" name='<%=contact.name%>' slug='<%=contact.slug%>'>
47
+ <a title='<%=contact.name%>' class="presence_user_link" width="28">
48
+ <%=image_tag(contact.logo.url, :alt => contact.name , :size => "28x28")%>
49
+ <% if contact.user.status %>
50
+ <%=image_tag("status/" + contact.user.status + ".png", :class => "presence_status") %></a>
51
+ <% end %>
52
+ </a>
53
+ </div>
54
+ <%end%>
55
+ <% end %>
56
+ </div>
57
+ </div>
@@ -6,6 +6,8 @@ en:
6
6
  unableconnect: "Chat Out of Service"
7
7
  title: "Chat"
8
8
  password: "Password"
9
+ zerousers: "No users connected"
10
+ zerocontacts: "No contacts found"
9
11
  status:
10
12
  choose: "Choose status"
11
13
  available: "Available"
@@ -17,4 +19,5 @@ en:
17
19
  checkbox: "Enable or disable Social Stream Chat"
18
20
  update: "Update Settings"
19
21
  notify:
20
- offline: "You are offline"
22
+ offline: "You are offline"
23
+ guestOffline: "is offline"
@@ -6,6 +6,8 @@ es:
6
6
  unableconnect: "Chat Fuera de servicio"
7
7
  title: "Chat"
8
8
  password: "Contraseña"
9
+ zerousers: "No hay contactos conectados"
10
+ zerocontacts: "No se encontró ningún contacto"
9
11
  status:
10
12
  choose: "Establecer estado"
11
13
  available: "Disponible"
@@ -18,4 +20,4 @@ es:
18
20
  update: "Guardar configuración"
19
21
  notify:
20
22
  offline: "Desconectado"
21
-
23
+ guestOffline: "está desconectado"
@@ -1,6 +1,6 @@
1
1
  class AddStatusColumnToUser < ActiveRecord::Migration
2
2
  def self.up
3
- add_column :users, :status, :string, :default => "chat"
3
+ add_column :users, :status, :string, :default => "available"
4
4
  end
5
5
 
6
6
  def self.down
@@ -1,5 +1,5 @@
1
1
  module Socialstream
2
2
  module Presence
3
- VERSION = "0.6.2"
3
+ VERSION = "0.6.3"
4
4
  end
5
5
  end
@@ -0,0 +1,265 @@
1
+ /**
2
+ * flexselect: a jQuery plugin, version: 0.3 (2011-12-17)
3
+ * @requires jQuery v1.3 or later
4
+ *
5
+ * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
6
+ * a Quicksilver-style, autocompleting, flex matching selection tool.
7
+ *
8
+ * For usage and examples, visit:
9
+ * http://rmm5t.github.com/jquery-flexselect/
10
+ *
11
+ * Licensed under the MIT:
12
+ * http://www.opensource.org/licenses/mit-license.php
13
+ *
14
+ * Copyright (c) 2009-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
15
+ */
16
+ (function($) {
17
+ $.flexselect = function(select, options) { this.init(select, options); };
18
+
19
+ $.extend($.flexselect.prototype, {
20
+ settings: {
21
+ allowMismatch: false,
22
+ selectedClass: "flexselect_selected",
23
+ dropdownClass: "flexselect_dropdown",
24
+ inputIdTransform: function(id) { return id + "_flexselect"; },
25
+ inputNameTransform: function(name) { return; },
26
+ dropdownIdTransform: function(id) { return id + "_flexselect_dropdown"; }
27
+ },
28
+ select: null,
29
+ input: null,
30
+ hidden: null,
31
+ dropdown: null,
32
+ dropdownList: null,
33
+ cache: [],
34
+ results: [],
35
+ lastAbbreviation: null,
36
+ abbreviationBeforeFocus: null,
37
+ selectedIndex: 0,
38
+ picked: false,
39
+ dropdownMouseover: false, // Workaround for poor IE behaviors
40
+
41
+ init: function(select, options) {
42
+ this.settings = $.extend({}, this.settings, options);
43
+ this.select = $(select);
44
+ this.preloadCache();
45
+ this.renderControls();
46
+ this.wire();
47
+ },
48
+
49
+ preloadCache: function() {
50
+ this.cache = this.select.children("option").map(function() {
51
+ return { name: $.trim($(this).text()), value: $(this).val(), score: 0.0 };
52
+ });
53
+ },
54
+
55
+ renderControls: function() {
56
+ var selected = this.select.children("option:selected");
57
+
58
+ this.hidden = $("<input type='hidden'/>").attr({
59
+ id: this.select.attr("id"),
60
+ name: this.select.attr("name")
61
+ }).val(selected.val());
62
+
63
+ this.input = $("<input type='text' autocomplete='off' />").attr({
64
+ id: this.settings.inputIdTransform(this.select.attr("id")),
65
+ name: this.settings.inputNameTransform(this.select.attr("name")),
66
+ accesskey: this.select.attr("accesskey"),
67
+ tabindex: this.select.attr("tabindex"),
68
+ style: this.select.attr("style")
69
+ }).addClass(this.select.attr("class")).val($.trim(selected.text()));
70
+
71
+ this.dropdown = $("<div></div>").attr({
72
+ id: this.settings.dropdownIdTransform(this.select.attr("id"))
73
+ }).addClass(this.settings.dropdownClass);
74
+ this.dropdownList = $("<ul></ul>");
75
+ this.dropdown.append(this.dropdownList);
76
+
77
+ this.select.after(this.input).after(this.hidden).remove();
78
+ $("body").append(this.dropdown);
79
+ },
80
+
81
+ wire: function() {
82
+ var self = this;
83
+
84
+ this.input.click(function() {
85
+ self.lastAbbreviation = null;
86
+ self.focus();
87
+ });
88
+
89
+ this.input.mouseup(function(event) {
90
+ // This is so Safari selection actually occurs.
91
+ event.preventDefault();
92
+ });
93
+
94
+ this.input.focus(function() {
95
+ self.abbreviationBeforeFocus = self.input.val();
96
+ self.input.select();
97
+ if (!self.picked) self.filterResults();
98
+ });
99
+
100
+ this.input.blur(function() {
101
+ if (!self.dropdownMouseover) {
102
+ self.hide();
103
+ if (!self.settings.allowMismatch && !self.picked) self.reset();
104
+ }
105
+ });
106
+
107
+ this.dropdownList.mouseover(function (event) {
108
+ if (event.target.tagName == "LI") {
109
+ var rows = self.dropdown.find("li");
110
+ self.markSelected(rows.index($(event.target)));
111
+ }
112
+ });
113
+ this.dropdownList.mouseleave(function () {
114
+ self.markSelected(-1);
115
+ });
116
+ this.dropdownList.mouseup(function (event) {
117
+ self.pickSelected();
118
+ self.focusAndHide();
119
+ });
120
+ this.dropdown.mouseover(function (event) {
121
+ self.dropdownMouseover = true;
122
+ });
123
+ this.dropdown.mouseleave(function (event) {
124
+ self.dropdownMouseover = false;
125
+ });
126
+ this.dropdown.mousedown(function (event) {
127
+ event.preventDefault();
128
+ });
129
+
130
+ this.input.keyup(function(event) {
131
+ switch (event.keyCode) {
132
+ case 13: // return
133
+ event.preventDefault();
134
+ self.pickSelected();
135
+ self.focusAndHide();
136
+ break;
137
+ case 27: // esc
138
+ event.preventDefault();
139
+ self.reset();
140
+ self.focusAndHide();
141
+ break;
142
+ default:
143
+ self.filterResults();
144
+ break;
145
+ }
146
+ });
147
+
148
+ this.input.keydown(function(event) {
149
+ switch (event.keyCode) {
150
+ case 9: // tab
151
+ self.pickSelected();
152
+ self.hide();
153
+ break;
154
+ case 33: // pgup
155
+ event.preventDefault();
156
+ self.markFirst();
157
+ break;
158
+ case 34: // pgedown
159
+ event.preventDefault();
160
+ self.markLast();
161
+ break;
162
+ case 38: // up
163
+ event.preventDefault();
164
+ self.moveSelected(-1);
165
+ break;
166
+ case 40: // down
167
+ event.preventDefault();
168
+ self.moveSelected(1);
169
+ break;
170
+ case 13: // return
171
+ case 27: // esc
172
+ event.preventDefault();
173
+ event.stopPropagation();
174
+ break;
175
+ }
176
+ });
177
+ },
178
+
179
+ filterResults: function() {
180
+ var abbreviation = this.input.val();
181
+ if (abbreviation == this.lastAbbreviation) return;
182
+
183
+ var results = [];
184
+ $.each(this.cache, function() {
185
+ this.score = LiquidMetal.score(this.name, abbreviation);
186
+ if (this.score > 0.0) results.push(this);
187
+ });
188
+ this.results = results;
189
+
190
+ this.sortResults();
191
+ this.renderDropdown();
192
+ this.markFirst();
193
+ this.lastAbbreviation = abbreviation;
194
+ this.picked = false;
195
+ },
196
+
197
+ sortResults: function() {
198
+ this.results.sort(function(a, b) { return b.score - a.score; });
199
+ },
200
+
201
+ renderDropdown: function() {
202
+ var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
203
+ var inputOffset = this.input.offset();
204
+ this.dropdown.css({
205
+ width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
206
+ top: (inputOffset.top + this.input.outerHeight()) + "px",
207
+ left: inputOffset.left + "px"
208
+ });
209
+
210
+ var list = this.dropdownList.html("");
211
+ $.each(this.results, function() {
212
+ // list.append($("<li/>").html(this.name + " <small>[" + Math.round(this.score*100)/100 + "]</small>"));
213
+ list.append($("<li/>").html(this.name));
214
+ });
215
+ this.dropdown.show();
216
+ },
217
+
218
+ markSelected: function(n) {
219
+ if (n > this.results.length) return;
220
+
221
+ var rows = this.dropdown.find("li");
222
+ rows.removeClass(this.settings.selectedClass);
223
+ this.selectedIndex = n;
224
+
225
+ if (n >= 0) $(rows[n]).addClass(this.settings.selectedClass);
226
+ },
227
+
228
+ pickSelected: function() {
229
+ var selected = this.results[this.selectedIndex];
230
+ if (selected) {
231
+ //this.input.val(selected.name);
232
+ //this.picked = true;
233
+ if(typeof changeSelectContactValue == "function"){
234
+ changeSelectContactValue(selected.name,selected.value);
235
+ }
236
+ this.hidden.val(selected.value);
237
+ } else if (this.settings.allowMismatch) {
238
+ this.hidden.val("");
239
+ } else {
240
+ this.reset();
241
+ }
242
+ this.input.val("");
243
+ },
244
+
245
+ hide: function() {
246
+ this.dropdown.hide();
247
+ this.lastAbbreviation = null;
248
+ },
249
+
250
+ moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
251
+ markFirst: function() { this.markSelected(0); },
252
+ markLast: function() { this.markSelected(this.results.length - 1); },
253
+ reset: function() { this.input.val(this.abbreviationBeforeFocus); },
254
+ focus: function() { this.input.focus(); },
255
+ focusAndHide: function() { this.hide(); //this.focus();
256
+ }
257
+ });
258
+
259
+ $.fn.flexselect = function(options) {
260
+ this.each(function() {
261
+ if (this.tagName == "SELECT") new $.flexselect(this, options);
262
+ });
263
+ return this;
264
+ };
265
+ })(jQuery);