0b77e651306cf45a225f0f860f02a1b68b1e5afa
2 // Copyright 2008 Grégory Burri
4 // This file is part of Euphorik.
6 // Euphorik is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // Euphorik is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Euphorik. If not, see <http://www.gnu.org/licenses/>.
19 /*jslint laxbreak:true */
22 * Object that represents the user.
23 * It carries all the user data like
28 * It can access directly to the DOM if needed. Some examples :
29 * - Changes the menu if the user is logged or not
30 * - Changes the logo if the user is an ek master
33 * @communication See communication.js.
35 euphorik
.Client = function(util
, communication
) {
37 this.communication
= communication
;
40 this.regexCookie
= /cookie=([^;]*)/;
42 this.resetPersonalData();
44 this.setStatus(euphorik
.Client
.statusType
.disconnected
);
46 // If true then each data change is flushed to the server.
47 // Active only for opera which doesn't support the unload event.
48 this.autoflush
= $.browser
.opera
;
51 // The three status of a client.
52 euphorik
.Client
.statusType
= {
53 // authentified and registered : The user can post messages and can modify his profile
55 // authentified but not registered : The user can only post messages
56 auth_not_registered : 1,
57 // disconnected (the initial state) : The user cannot post message
62 * Reset all the local personal data. Does not erase the remote data.
63 * This function is used during disconnecting.
65 euphorik
.Client
.prototype.resetPersonalData = function() {
67 this.nick
= euphorik
.conf
.defaultNick
;
71 this.css
= $("link#mainCss").attr("href");
72 this.chatOrder
= "reverse";
73 this.nickFormat
= "nick";
74 this.viewTimes
= true;
75 this.viewTooltips
= true;
76 this.cookie
= undefined;
78 this.mainConversationPage
= 1;
79 this.ekMaster
= false;
80 this.ostentatiousMaster
= "light";
82 // The user opened conversations.
83 // Each conversation object owns theses properties :
86 // - isCollapsed (bool)
87 this.conversations
= [];
91 * Set the CSS. Dynamically change the href to the CSS in the DOM.
92 * @css The relative path to the CSS file, for example :
93 * "styles/1/euphorik.css".
95 euphorik
.Client
.prototype.setCss = function(css
) {
96 if (this.css
=== css
|| !css
) {
101 $("link#mainCss").attr("href", this.css
);
103 if (this.autoflush
) {
109 * Change the current page to the next one for the given conversation.
110 * @numConv The number of the conversation.
112 euphorik
.Client
.prototype.nextPage = function(numConv
) {
113 if (numConv
< 0 && this.mainConversationPage
> 1) {
114 this.mainConversationPage
-= 1;
115 } else if (this.conversations
[numConv
].page
> 1) {
116 this.conversations
[numConv
].page
-= 1;
121 * Change the current page to the previous one for the given conversation.
122 * @numConv The number of the conversation.
124 euphorik
.Client
.prototype.previousPage = function(numConv
) {
126 this.mainConversationPage
+= 1;
128 this.conversations
[numConv
].page
+= 1;
133 * Définit la première page pour la conversation donnée.
134 * @return true si la page a changé sinon false
136 euphorik
.Client
.prototype.goFirstPage = function(numConv
)
139 if (this.mainConversationPage
=== 1) {
142 this.mainConversationPage
= 1;
144 if (this.conversations
[numConv
].page
=== 1) {
147 this.conversations
[numConv
].page
= 1;
153 * Ajoute une conversation à la vue de l'utilisateur.
154 * Le profile de l'utilisateur est directement sauvegardé sur le serveur.
155 * @param racines la racine de la conversation (integer)
156 * @return true si la conversation a été créée sinon false (par exemple si la conv existe déjà)
158 euphorik
.Client
.prototype.ajouterConversation = function(racine
) {
159 // vérification s'il elle n'existe pas déjà
161 this.conversations
.each(function(i
, conv
) {
162 if (conv
.root
=== racine
) {
170 this.conversations
.push({root : racine
, page : 1, isCollapsed : false});
171 if (this.autoflush
) {
178 euphorik
.Client
.prototype.supprimerConversation = function(num
) {
179 if (num
< 0 || num
>= this.conversations
.length
) {
183 // décalage TODO : supprimer le dernier élément
184 for (var i
= num
; i
< this.conversations
.length
- 1; i
++) {
185 this.conversations
[i
] = this.conversations
[i
+1];
187 this.conversations
.pop();
189 if (this.autoflush
) {
194 euphorik
.Client
.prototype.getJSONConversations = function() {
195 var conversations
= [];
196 this.conversations
.each(function(i
, conv
) {
197 conversations
.push({ "root" : conv
.root
, "minimized" : conv
.isCollapsed
});
199 return conversations
;
202 euphorik
.Client
.prototype.getJSONProfile = function() {
204 "cookie" : this.cookie
,
205 "login" : this.login
,
206 "password" : this.password
,
207 "profile" : this.getJSONProfileInfos()
211 euphorik
.Client
.prototype.getJSONProfileInfos = function() {
214 "email" : this.email
,
216 "chat_order" : this.chatOrder
,
217 "nick_format" : this.nickFormat
,
218 "view_times" : this.viewTimes
,
219 "view_tooltips" : this.viewTooltips
,
220 "conversations" : this.getJSONConversations(),
221 "ostentatious_master" : this.ostentatiousMaster
228 euphorik
.Client
.prototype.getCookie = function() {
229 var cookie
= this.regexCookie
.exec(document
.cookie
);
231 this.cookie
= cookie
[1];
233 this.cookie
= undefined;
237 euphorik
.Client
.prototype.delCookie = function() {
238 document
.cookie
= "cookie=; max-age=0";
239 this.cookie
= undefined;
242 euphorik
.Client
.prototype.setCookie = function() {
247 // doesn't work under IE....
248 /*document.cookie = "cookie=" + this.cookie + "; max-age=" + (60 * 60 * 24 * 365) */
251 "cookie="+this.cookie
+"; expires=" + new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 365).toUTCString();
254 euphorik
.Client
.prototype.authentifie = function() {
255 return this.statut
=== euphorik
.Client
.statusType
.auth_registered
|| this.statut
=== euphorik
.Client
.statusType
.auth_not_registered
;
258 euphorik
.Client
.prototype.setStatus = function(statut
)
260 // conversation en "enum" si en "string"
261 if (typeof(statut
) === "string") {
263 statut
=== "auth_registered" ?
264 euphorik
.Client
.statusType
.auth_registered :
265 (statut
=== "auth_not_registered" ? euphorik
.Client
.statusType
.auth_not_registered : euphorik
.Client
.statusType
.disconnected
);
268 if (statut
=== this.statut
) {
272 this.statut
= statut
;
279 * Try to authentify the client with the cookie information.
280 * Do nothing if there is no cookie.
282 euphorik
.Client
.prototype.connectionCookie = function() {
287 return this.connexion("authentification", { "cookie" : this.cookie
});
290 euphorik
.Client
.prototype.connexionLogin = function(login
, password
) {
291 return this.connexion("authentification", {"login" : login
, "password" : password
});
294 euphorik
.Client
.prototype.enregistrement = function(login
, password
) {
295 if (this.authentifie()) {
297 this.password
= password
;
299 this.setStatus(euphorik
.Client
.statusType
.auth_registered
);
304 return this.connexion("register", this.getJSONEnregistrement(login
, password
));
309 * le couple (login, password) est facultatif. S'il n'est pas fournit alors il ne sera pas possible
310 * de s'autentifier avec (login, password).
312 euphorik
.Client
.prototype.getJSONEnregistrement = function(login
, password
) {
315 if (login
&& password
) {
317 mess
.password
= password
;
320 mess
.profile
= this.getJSONProfileInfos();
326 * Connexion. Réalisé de manière synchrone.
328 euphorik
.Client
.prototype.connexion = function(action
, messageJson
) {
329 var thisClient
= this;
331 this.communication
.requete(
335 thisClient
.chargerDonnees(data
);
338 thisClient
.util
.messageDialog(data
.error_message
);
339 thisClient
.delCookie(); // suppression du cookie actuel, cas où le cookie du client ne permet pas une authentification
343 return this.authentifie();
346 euphorik
.Client
.prototype.disconnect = function() {
349 this.resetPersonalData();
350 this.setStatus(euphorik
.Client
.statusType
.disconnected
);
353 euphorik
.Client
.prototype.chargerDonnees = function(data
) {
354 // la modification du statut qui suit met à jour le menu, le menu dépend (page admin)
355 // de l'état ekMaster
356 this.ekMaster
= data
.ek_master
? data
.ek_master : false;
358 this.setStatus(data
.status
);
360 if (this.authentifie()) {
361 this.cookie
= data
.cookie
;
365 this.login
= data
.login
;
366 this.nick
= data
.profile
.nick
;
367 this.email
= data
.profile
.email
;
368 this.setCss(data
.profile
.css
);
369 this.chatOrder
= data
.profile
.chat_order
;
370 this.nickFormat
= data
.profile
.nick_format
;
371 this.viewTimes
= data
.profile
.view_times
;
372 this.viewTooltips
= data
.profile
.view_tooltips
;
373 this.ostentatiousMaster
= data
.profile
.ostentatious_master
;
375 // la page de la conversation principale
376 this.mainConversationPage
= 1;
379 this.conversations
= data
.profile
.conversations
;
380 this.conversations
.map(function(conv
) {
381 return { root : conv
.root
, page : 1, isCollapsed : conv
.minimized
};
385 this.majCssSelectionee();
390 * Met à jour les données personne sur serveur.
391 * @param async de manière asynchrone ? défaut = true
392 * @return false si le flush n'a pas pû se faire sinon true
394 euphorik
.Client
.prototype.flush = function(async
) {
395 async
= async
|| false;
397 if (!this.authentifie()) {
401 var thisClient
= this;
404 this.communication
.requete(
406 this.getJSONProfile(),
408 thisClient
.majBulle();
411 thisClient
.util
.messageDialog(data
.error_message
);
420 euphorik
.Client
.prototype.majMenu = function() {
421 var displayType
= "block";
423 $("#menu .admin").css("display", this.ekMaster
? displayType : "none");
425 // met à jour le menu
426 if (this.statut
=== euphorik
.Client
.statusType
.auth_registered
) {
427 $("#menu .profile").css("display", displayType
).text("profile");
428 $("#menu .logout").css("display", displayType
);
429 $("#menu .register").css("display", "none");
430 } else if (this.statut
=== euphorik
.Client
.statusType
.auth_not_registered
) {
431 $("#menu .profile").css("display", "none");
432 $("#menu .logout").css("display", displayType
);
433 $("#menu .register").css("display", displayType
);
435 $("#menu .profile").css("display", displayType
).text("login");
436 $("#menu .logout").css("display", "none");
437 $("#menu .register").css("display", displayType
);
442 * Met à jour l'affichage ou non des infos bulles en fonction du profile.
444 euphorik
.Client
.prototype.majBulle = function() {
445 this.util
.bulleActive
= this.viewTooltips
;
449 * Met à jour la css sélectionnée, lors du chargement des données.
451 euphorik
.Client
.prototype.majCssSelectionee = function() {
452 // extraction du numéro de la css courante
453 var numCssCourante
= this.css
.match(/^.*?\/(\d)\/.*$/);
454 if (numCssCourante
&& numCssCourante
[1]) {
455 $("#menuCss option").removeAttr("selected");
456 $("#menuCss option[value=" + numCssCourante
[1]+ "]").attr("selected", "selected");
461 * Change la "class" du logo en fonction du statut de ekMaster.
463 euphorik
.Client
.prototype.majLogo = function() {
465 $("#logo").addClass("ekMaster");
467 $("#logo").removeClass("ekMaster");
471 euphorik
.Client
.prototype.slap = function(userId
, raison
) {
472 var thisClient
= this;
473 this.communication
.requete("slap", { "cookie" : thisClient
.cookie
, "user_id" : userId
, "reason" : raison
});
476 euphorik
.Client
.prototype.ban = function(userId
, raison
, minutes
) {
477 var thisClient
= this;
479 // par défaut un ban correspond à 3 jours
480 minutes
= minutes
|| euphorik
.conf
.tempsBan
;
481 this.communication
.requete("ban", { "cookie" : thisClient
.cookie
, "duration" : minutes
, "user_id" : userId
, "reason" : raison
});
484 euphorik
.Client
.prototype.kick = function(userId
, raison
) {
485 this.ban(userId
, raison
, euphorik
.conf
.tempsKick
);