social_stream-presence 0.13.1 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. data/app/assets/javascripts/jquery.flexselect.sstreampresence.js +2 -2
  2. data/app/assets/javascripts/jquery.ui.chatbox.sstreampresence.js +5 -5
  3. data/app/assets/javascripts/presence.js.erb +6 -4
  4. data/app/assets/javascripts/presence_XmppClient.js.erb +1136 -996
  5. data/app/assets/javascripts/presence_audio.js.erb +74 -60
  6. data/app/assets/javascripts/presence_game.js.erb +35 -22
  7. data/app/assets/javascripts/presence_game_comunication.js.erb +22 -5
  8. data/app/assets/javascripts/presence_game_factory.js.erb +1 -1
  9. data/app/assets/javascripts/presence_game_interface.js.erb +33 -13
  10. data/app/assets/javascripts/presence_notifications.js +206 -183
  11. data/app/assets/javascripts/presence_parser.js +265 -247
  12. data/app/assets/javascripts/presence_persistence.js +199 -188
  13. data/app/assets/javascripts/presence_store.js +22 -11
  14. data/app/assets/javascripts/presence_uiManager.js.erb +553 -530
  15. data/app/assets/javascripts/presence_utilities.js +244 -219
  16. data/app/assets/javascripts/presence_videochat.js.erb +436 -409
  17. data/app/assets/javascripts/presence_windowManager.js +586 -532
  18. data/app/views/chat/_index.html.erb +7 -13
  19. data/config/locales/en.yml +2 -1
  20. data/config/locales/es.yml +2 -1
  21. data/ejabberd/ejabberd_files.zip +0 -0
  22. data/ejabberd/ejabberd_scripts/authentication_script +9 -2
  23. data/ejabberd/mod_sspresence/mod_sspresence.beam +0 -0
  24. data/lib/generators/social_stream/presence/templates/initializer.rb +4 -0
  25. data/lib/social_stream/presence/version.rb +1 -1
  26. data/lib/social_stream/presence/xmpp_server_order.rb +1 -0
  27. data/lib/social_stream-presence.rb +3 -0
  28. metadata +68 -63
@@ -2,73 +2,87 @@
2
2
  //Audio functions
3
3
  ////////////////////
4
4
 
5
- //Global audio variables
6
- var audio_path = '<%=image_path("chat")%>';
7
- var onMessageAudio;
8
-
9
- var html5_audiotypes=[
10
- ["mp3","audio/mpeg"],
11
- //["mp4","audio/mp4"],
12
- //["ogg","audio/ogg"],
13
- ["wav","audio/wav"]
14
- ]
15
-
16
- function initAudio(){
17
- //Init all audio files
18
- initSound("onMessageAudio");
19
- }
20
-
21
- function initSound(sound){
5
+ PRESENCE.AUDIO = (function(P,$,undefined){
6
+
7
+ //Audio variables
8
+ var audio_path = '<%=image_path("chat")%>';
9
+ var onMessageAudio;
10
+
11
+ var html5_audiotypes=[
12
+ ["mp3","audio/mpeg"],
13
+ //["mp4","audio/mp4"],
14
+ //["ogg","audio/ogg"],
15
+ ["wav","audio/wav"]
16
+ ]
17
+
18
+
19
+ var init = function(){
20
+ //Init all audio files
21
+ initSound("onMessageAudio");
22
+ }
23
+
24
+
25
+ var initSound = function(sound){
22
26
 
23
- //Check support for HTML5 audio
24
- var html5audio=document.createElement('audio')
27
+ //Check support for HTML5 audio
28
+ var html5audio=document.createElement('audio')
25
29
 
26
- if (html5audio.canPlayType){
27
- path = audio_path + "/" + sound;
28
- window[sound] = new Audio();
30
+ if (html5audio.canPlayType){
31
+ path = audio_path + "/" + sound;
32
+ window[sound] = new Audio();
29
33
 
30
- for(i=0; i<html5_audiotypes.length; i++){
31
- if (window[sound].canPlayType(html5_audiotypes[i][1])) {
32
- var source= document.createElement('source');
33
- source.type= html5_audiotypes[i][1];
34
- source.src= path + '.' + html5_audiotypes[i][0];
35
- window[sound].addEventListener('ended', endSoundListener);
36
- window[sound].appendChild(source);
37
- }
38
- }
39
- } else {
34
+ for(i=0; i<html5_audiotypes.length; i++){
35
+ if (window[sound].canPlayType(html5_audiotypes[i][1])) {
36
+ var source= document.createElement('source');
37
+ source.type= html5_audiotypes[i][1];
38
+ source.src= path + '.' + html5_audiotypes[i][0];
39
+ window[sound].addEventListener('ended', endSoundListener);
40
+ window[sound].appendChild(source);
41
+ }
42
+ }
43
+ } else {
40
44
  //Browser doesn't support HTML5 audio
45
+ }
41
46
  }
42
- }
43
47
 
44
- function endSoundListener(){ }
45
48
 
46
- function playSound(sound){
47
- if (window[sound]!=null){
48
- window[sound].play();
49
- } else {
50
- //Fallback option: When browser doesn't support HTML5 audio
51
- $('body').append('<embed src="' + audio_path + '/' + sound + '.mp3" autostart="true" hidden="true" loop="false">');
52
- }
53
- }
49
+ function endSoundListener(){ }
54
50
 
55
- function initAndPlaySound(sound){
56
- initSound(sound);
57
- playSound(sound);
58
- }
59
51
 
52
+ function playSound(sound){
53
+ if (window[sound]!=null){
54
+ window[sound].play();
55
+ } else {
56
+ //Fallback option: When browser doesn't support HTML5 audio
57
+ $('body').append('<embed src="' + audio_path + '/' + sound + '.mp3" autostart="true" hidden="true" loop="false">');
58
+ }
59
+ }
60
60
 
61
- function mustPlaySoundForChatWindow(chatBox){
62
- //Deny conditions
63
- if(userStatus == "dnd"){
64
- return false;
65
- }
66
-
67
- //Accept conditions
68
- if (!chatFocus){
69
- return true;
70
- }
71
-
72
- //Default action
73
- return false
74
- }
61
+ function initAndPlaySound(sound){
62
+ initSound(sound);
63
+ playSound(sound);
64
+ }
65
+
66
+
67
+ function mustPlaySoundForChatWindow(chatBox){
68
+ //Deny conditions
69
+ if(PRESENCE.XMPPClient.getUserStatus() == "dnd"){
70
+ return false;
71
+ }
72
+
73
+ //Accept conditions
74
+ if (!PRESENCE.UTILITIES.getChatFocus()){
75
+ return true;
76
+ }
77
+
78
+ //Default action
79
+ return false
80
+ }
81
+
82
+ return {
83
+ init : init,
84
+ mustPlaySoundForChatWindow : mustPlaySoundForChatWindow,
85
+ playSound : playSound
86
+ };
87
+
88
+ }) (PRESENCE, jQuery);
@@ -40,8 +40,12 @@ PRESENCE.GAME = (function(P,$,undefined){
40
40
  // CORE METHODS //
41
41
  /////////////////////////////////
42
42
 
43
- var init = function(myConnection){
44
- P.GAME.COMUNICATION.init(myConnection);
43
+ var init = function(){
44
+ var enable = '<%=SocialStream::Presence.games%>';
45
+ if(enable=="true"){
46
+ P.GAME.INTERFACE.enableGameFeature(true);
47
+ P.GAME.COMUNICATION.init(PRESENCE.XMPPClient.getConnection());
48
+ }
45
49
  };
46
50
 
47
51
 
@@ -56,7 +60,7 @@ PRESENCE.GAME = (function(P,$,undefined){
56
60
  var gameStatus = null;
57
61
  }
58
62
 
59
- if(! isUserConnected()){
63
+ if(! PRESENCE.XMPPClient.isUserConnected()){
60
64
  P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.offline"));
61
65
  if(gameStatus!=null){
62
66
  contactsInfo[slug].gameStatus = "disconnected";
@@ -64,8 +68,8 @@ PRESENCE.GAME = (function(P,$,undefined){
64
68
  return;
65
69
  }
66
70
 
67
- if(! isSlugChatConnected(slug)){
68
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.guestOffline", {name: getNameFromSlug(slug)}));
71
+ if(! PRESENCE.UIMANAGER.isSlugChatConnected(slug)){
72
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.guestOffline", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
69
73
  if(gameStatus!=null){
70
74
  contactsInfo[slug].gameStatus = "disconnected";
71
75
  }
@@ -142,13 +146,13 @@ PRESENCE.GAME = (function(P,$,undefined){
142
146
  contactsInfo[slug].gameStatus = "playing";
143
147
  P.GAME.INTERFACE.updateInterfaceBeforeStartGame(slug,contactsInfo[slug].game)
144
148
  } else if (response=="no"){
145
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.rejected", {name: getNameFromSlug(slug)}));
149
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.rejected", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
146
150
  contactsInfo[slug].gameStatus="disconnected";
147
151
  } else if (response=="busy"){
148
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.rejectedBusy", {name: getNameFromSlug(slug)}));
152
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.rejectedBusy", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
149
153
  contactsInfo[slug].gameStatus="disconnected";
150
154
  } else {
151
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.unknown", {name: getNameFromSlug(slug)}));
155
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.unknown", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
152
156
  contactsInfo[slug].gameStatus="disconnected";
153
157
  }
154
158
  }
@@ -157,10 +161,10 @@ PRESENCE.GAME = (function(P,$,undefined){
157
161
  if(slug in contactsInfo){
158
162
  if (status == "finish") {
159
163
  if (contactsInfo[slug].gameStatus == "pending") {
160
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.cancel", {name: getNameFromSlug(slug)}));
164
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.cancel", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
161
165
  contactsInfo[slug].gameStatus = "disconnected";
162
166
  } else if (contactsInfo[slug].gameStatus == "playing") {
163
- P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.finish", {name: getNameFromSlug(slug)}));
167
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug, I18n.t("chat.game.finish", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
164
168
  contactsInfo[slug].gameStatus = "disconnected";
165
169
  }
166
170
  }
@@ -168,6 +172,14 @@ PRESENCE.GAME = (function(P,$,undefined){
168
172
  finishGame(slug);
169
173
  }
170
174
  }
175
+
176
+ var updateLogicAfterReceivedGameRequestError = function(slug){
177
+ if(contactsInfo[slug].gameStatus!="waiting"){
178
+ return true;
179
+ }
180
+ P.GAME.INTERFACE.updateInterfaceOnInformationMessage(slug,I18n.t("chat.game.clientIssue", {name: PRESENCE.XMPPClient.getNameFromSlug(slug)}));
181
+ contactsInfo[slug].gameStatus="disconnected";
182
+ }
171
183
 
172
184
  var getPlayerNameWithId = function(slug){
173
185
  if(! slug in contactsInfo){
@@ -251,13 +263,13 @@ PRESENCE.GAME = (function(P,$,undefined){
251
263
  return;
252
264
  }
253
265
  } else {
254
- log("Warning: Missed " + game.name + " validateParams method")
266
+ PRESENCE.UTILITIES.log("Warning: Missed " + game.name + " validateParams method")
255
267
  }
256
268
 
257
269
  if(typeof PRESENCE.GAME[game.id].minimumRequirements == "function"){
258
270
  //Check requirements
259
271
  } else {
260
- log("Warning: Missed " + game.name + " minRequirements method")
272
+ PRESENCE.UTILITIES.log("Warning: Missed " + game.name + " minRequirements method")
261
273
  }
262
274
 
263
275
  //Add handler and remove previous if exits
@@ -301,16 +313,17 @@ PRESENCE.GAME = (function(P,$,undefined){
301
313
 
302
314
  return {
303
315
  init: init,
304
- game: game,
305
- player: player,
306
- startGame: startGame,
307
- finishGame: finishGame,
308
- createValidationResult: createValidationResult,
309
- requestUserToPlay: requestUserToPlay,
310
- responseUserToPlay: responseUserToPlay,
311
- updateLogicAfterReceivedGameRequest: updateLogicAfterReceivedGameRequest,
312
- updateLogicAfterReceivedGameRequestCancelation: updateLogicAfterReceivedGameRequestCancelation,
313
- updateLogicAfterReceivedGameRequestResponse: updateLogicAfterReceivedGameRequestResponse,
316
+ game : game,
317
+ player : player,
318
+ startGame : startGame,
319
+ finishGame : finishGame,
320
+ createValidationResult : createValidationResult,
321
+ requestUserToPlay : requestUserToPlay,
322
+ responseUserToPlay : responseUserToPlay,
323
+ updateLogicAfterReceivedGameRequest : updateLogicAfterReceivedGameRequest,
324
+ updateLogicAfterReceivedGameRequestCancelation : updateLogicAfterReceivedGameRequestCancelation,
325
+ updateLogicAfterReceivedGameRequestResponse : updateLogicAfterReceivedGameRequestResponse,
326
+ updateLogicAfterReceivedGameRequestError : updateLogicAfterReceivedGameRequestError,
314
327
  sendAction: sendAction,
315
328
  userDisconnected: userDisconnected
316
329
  };
@@ -10,10 +10,14 @@ PRESENCE.GAME.COMUNICATION = (function(P,$,undefined){
10
10
  //////////////////////////////////////////////
11
11
 
12
12
  var connection = null;
13
+ var iqStanzaID = new Array();
13
14
  iqStanzaID['gameRequest'] = "gameRequestID";
14
15
  iqStanzaID['gameRequestFinish'] = "gameRequestFinishID";
15
16
  iqStanzaID['gameAction'] = "gameActionID";
16
17
 
18
+ var getIQStanzaID = function(){
19
+ return iqStanzaID;
20
+ }
17
21
 
18
22
  /////////////////////////////////
19
23
  // COMUNICATION METHODS //
@@ -22,10 +26,13 @@ PRESENCE.GAME.COMUNICATION = (function(P,$,undefined){
22
26
  var init = function(myConnection){
23
27
  connection = myConnection;
24
28
  //addHandler:(callback, namespace to match, stanza name, stanza type, stanza id , stanza from, options)
25
- connection.addHandler(handleRequestGameIQStanza,null, "iq", "get",iqStanzaID['gameRequest'], null);
26
- connection.addHandler(handleIQResultFromGameRequest,null, "iq", "result",iqStanzaID['gameRequest'], null);
27
- connection.addHandler(handleIQResultFromGameRequestFinish,null, "iq", "result", iqStanzaID['gameRequestFinish'], null);
28
- connection.addHandler(handleActionIQStanza,null, "iq", "result", getIdForIqAction("gameId"), null);
29
+ if(connection){
30
+ connection.addHandler(handleRequestGameIQStanza,null, "iq", "get",iqStanzaID['gameRequest'], null);
31
+ connection.addHandler(handleIQResultFromGameRequest,null, "iq", "result",iqStanzaID['gameRequest'], null);
32
+ connection.addHandler(handleIQErrorFromGameRequest,null, "iq", "error",iqStanzaID['gameRequest'], null);
33
+ connection.addHandler(handleIQResultFromGameRequestFinish,null, "iq", "result", iqStanzaID['gameRequestFinish'], null);
34
+ connection.addHandler(handleActionIQStanza,null, "iq", "result", getIdForIqAction("gameId"), null);
35
+ }
29
36
  };
30
37
 
31
38
 
@@ -121,6 +128,7 @@ PRESENCE.GAME.COMUNICATION = (function(P,$,undefined){
121
128
 
122
129
  //RECEIVE GAME REQUEST RESPONSE
123
130
  var handleIQResultFromGameRequest = function(iq){
131
+
124
132
  var from = iq.getAttribute("from");
125
133
  var slug = from.split("@")[0];
126
134
  var queryTag = iq.getElementsByTagName('query');
@@ -134,9 +142,17 @@ PRESENCE.GAME.COMUNICATION = (function(P,$,undefined){
134
142
  return true;
135
143
  }
136
144
  }
145
+
137
146
  return true;
138
147
  }
139
148
 
149
+ //RECEIVE GAME REQUEST ERROR RESPONSE
150
+ var handleIQErrorFromGameRequest = function(iq){
151
+ var from = iq.getAttribute("from");
152
+ var slug = from.split("@")[0];
153
+ P.GAME.updateLogicAfterReceivedGameRequestError(slug)
154
+ return true;
155
+ }
140
156
 
141
157
 
142
158
  /////////////////////
@@ -374,7 +390,8 @@ PRESENCE.GAME.COMUNICATION = (function(P,$,undefined){
374
390
  sendIQStanzaWithAction: sendIQStanzaWithAction,
375
391
  handleActionIQStanza: handleActionIQStanza,
376
392
  addHandler : addHandler,
377
- removeHandler: removeHandler
393
+ removeHandler: removeHandler,
394
+ getIQStanzaID : getIQStanzaID
378
395
  };
379
396
 
380
397
  }) (PRESENCE, jQuery);
@@ -25,7 +25,7 @@ PRESENCE.GAME.FACTORY = (function(P,$,undefined){
25
25
 
26
26
  var generateGame = function(guest_slug,gameId,options){
27
27
  var player1 = new PRESENCE.GAME.player(user_slug,user_name)
28
- var player2 = new PRESENCE.GAME.player(guest_slug,getNameFromSlug(guest_slug))
28
+ var player2 = new PRESENCE.GAME.player(guest_slug,PRESENCE.XMPPClient.getNameFromSlug(guest_slug))
29
29
  var players = [player1,player2]
30
30
  var mygame = new PRESENCE.GAME.game(gameId,getGameName(gameId),players,options)
31
31
  return mygame;
@@ -12,8 +12,8 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
12
12
  //gameStatus="pending";
13
13
 
14
14
  //Show or create chatbox
15
- createBuddyChatBox(slug);
16
- var chatBox = getChatBoxForSlug(slug);
15
+ PRESENCE.WINDOW.createBuddyChatBox(slug);
16
+ var chatBox = PRESENCE.WINDOW.getChatBoxForSlug(slug);
17
17
 
18
18
  //Show invitation message
19
19
  showGameInvitation(slug,game);
@@ -22,7 +22,7 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
22
22
  hideVideoChatButton(slug);
23
23
 
24
24
  //Show gamebox
25
- toggleVideoBoxForSlug(slug,true);
25
+ PRESENCE.WINDOW.toggleVideoBoxForSlug(slug,true);
26
26
  }
27
27
 
28
28
  var updateInterfaceBeforeStartGame = function(slug,game){
@@ -31,18 +31,18 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
31
31
  parentDiv.setAttribute('id', divID);
32
32
  $(parentDiv).css('width', "100%");
33
33
  $(parentDiv).css('height', "100%");
34
- setVideoBoxContent(slug,parentDiv);
34
+ PRESENCE.WINDOW.setVideoBoxContent(slug,parentDiv);
35
35
 
36
36
  PRESENCE.GAME.startGame(slug,divID)
37
37
  }
38
38
 
39
39
  var updateInterfaceAfterFinishGame = function(slug,game){
40
- toggleVideoBoxForSlug(slug,false);
40
+ PRESENCE.WINDOW.toggleVideoBoxForSlug(slug,false);
41
41
  showVideoChatButton(slug);
42
42
  }
43
43
 
44
44
  var updateInterfaceOnInformationMessage = function(slug,msg){
45
- setVideoBoxContent(slug,"<p class=\"game-info\"> " + msg +" </p>");
45
+ PRESENCE.WINDOW.setVideoBoxContent(slug,"<p class=\"game-info\"> " + msg +" </p>");
46
46
  }
47
47
 
48
48
 
@@ -53,7 +53,7 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
53
53
 
54
54
  var pickGamesButton = function (uiElement){
55
55
  var slug = $(uiElement.element).attr("id");
56
- var videoBoxVisibility = toggleVideoBoxForSlug(slug);
56
+ var videoBoxVisibility = PRESENCE.WINDOW.toggleVideoBoxForSlug(slug);
57
57
 
58
58
  if (videoBoxVisibility) {
59
59
  hideVideoChatButton(slug);
@@ -89,7 +89,7 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
89
89
  }
90
90
  }
91
91
  var template = generateGameSelectionTemplate(slug,gameItem)
92
- setVideoBoxContent(slug,template);
92
+ PRESENCE.WINDOW.setVideoBoxContent(slug,template);
93
93
  setShowGamesButtonsFunction();
94
94
  }
95
95
 
@@ -184,10 +184,10 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
184
184
  }
185
185
 
186
186
  var showGameInvitation = function(slug,game){
187
- var title = "<p class=\"game-info\">" + I18n.t("chat.game.call", {name: getNameFromSlug(slug), game: game.name}) + " </p>";
187
+ var title = "<p class=\"game-info\">" + I18n.t("chat.game.call", {name: PRESENCE.XMPPClient.getNameFromSlug(slug), game: game.name}) + " </p>";
188
188
  var msg = title + "<p class=\"game-request\"> <a class=\"gameButton\" slug=\""+slug+"\" value=\"yes\">" + I18n.t("chat.game.accept") + "</a> -"
189
189
  + " <a class=\"gameButton\" slug=\""+slug+"\" value=\"no\">" + I18n.t("chat.game.deny") + "</a> </p>";
190
- setVideoBoxContent(slug,msg);
190
+ PRESENCE.WINDOW.setVideoBoxContent(slug,msg);
191
191
  setGameRequestButtonsFunction();
192
192
  }
193
193
 
@@ -201,24 +201,44 @@ PRESENCE.GAME.INTERFACE = (function(P,$,undefined){
201
201
  }
202
202
 
203
203
  var hideVideoChatButton = function(slug){
204
- $(getChatBoxButtonForSlug(slug,"video")).hide();
204
+ $(PRESENCE.WINDOW.getChatBoxButtonForSlug(slug,"video")).hide();
205
205
  }
206
206
 
207
207
  var showVideoChatButton = function(slug){
208
- $(getChatBoxButtonForSlug(slug,"video")).show();
208
+ $(PRESENCE.WINDOW.getChatBoxButtonForSlug(slug,"video")).show();
209
209
  }
210
210
 
211
211
  var play = function(){
212
212
  $(".chat-gamesthick").css("display","block");
213
213
  }
214
214
 
215
+ var enableGameFeature = function(enable){
216
+ //Changing chat-gamesthick CSS class by JQuery
217
+ var ss = document.styleSheets;
218
+ for (var i=0; i<ss.length; i++) {
219
+ var rules = ss[i].cssRules || ss[i].rules;
220
+ if (rules != undefined){
221
+ for (var j=0; j<rules.length; j++) {
222
+ if (rules[j].selectorText === ".chat-gamesthick") {
223
+ if(enable){
224
+ rules[j].style.display = 'block'
225
+ } else {
226
+ rules[j].style.display = 'none'
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+
215
234
  return {
216
235
  pickGamesButton: pickGamesButton,
217
236
  updateInterfaceAfterGameRequestReceived: updateInterfaceAfterGameRequestReceived,
218
237
  updateInterfaceBeforeStartGame: updateInterfaceBeforeStartGame,
219
238
  updateInterfaceAfterFinishGame: updateInterfaceAfterFinishGame,
220
239
  updateInterfaceOnInformationMessage: updateInterfaceOnInformationMessage,
221
- play: play
240
+ play: play,
241
+ enableGameFeature : enableGameFeature
222
242
  };
223
243
 
224
244
  }) (PRESENCE, jQuery);