X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=js%2Fclient.js;h=1e872799ca8ab670f49da5d6aff9531f5f0db9ed;hp=a09819b58232c19fa87c02c07f565fdd1038fad5;hb=cb02531d4a4b217997db3fdfe2661af18c576ddd;hpb=deff7a2f11dca2b300b258d1e93d71e3b2e34c84 diff --git a/js/client.js b/js/client.js index a09819b..1e87279 100644 --- a/js/client.js +++ b/js/client.js @@ -18,106 +18,135 @@ /*jslint laxbreak:true */ -// les statuts possibes du client -euphorik.Client.statutType = { - // mode enregistré, peut poster des messages et modifier son profile +/** + * Object that represents the user. + * It carries all the user data like + * - ID + * - Nick + * - E-Mail + * - etc.. + * It can access directly to the DOM if needed. Some examples : + * - Changes the menu if the user is logged or not + * - Changes the logo if the user is an ek master + * - etc.. + * @util See util.js. + * @communication See communication.js. + */ +euphorik.Client = function(util, communication) { + this.util = util; + this.communication = communication; + + this.cookie = null; + this.regexCookie = /cookie=([^;]*)/; + + this.resetPersonalData(); + + this.setStatus(euphorik.Client.statusType.disconnected); + + // If true then each data change is flushed to the server. + // Active only for opera which doesn't support the unload event. + this.autoflush = $.browser.opera; +}; + +// The three status of a client. +euphorik.Client.statusType = { + // Authentified and registered : The user can post messages and can modify his profile. auth_registered : 0, - // mode identifié, peut poster des messages mais n'a pas accès au profile + // Authentified but not registered : The user can only post messages. auth_not_registered : 1, - // mode déconnecté, ne peut pas poster de message - deconnected : 2 -} + // Disconnected (the initial state) : The user cannot post message. + disconnected : 2 +}; /** - * Représente l'utilisateur du site. + * Reset all the local personal data. Does not erase the remote data. + * This function is used during disconnecting. */ -function Client(util) { - this.util = util; - - this.cookie = null; - this.regexCookie = /^cookie=([^;]*)/; - - // données personnels - this.resetDonneesPersonnelles(); - - this.setStatut(euphorik.Client.statutType.deconnected); - - // si true alors chaque modification du client est mémorisé sur le serveur - this.autoflush = $.browser["opera"]; -} - -Client.prototype.resetDonneesPersonnelles = function() { +euphorik.Client.prototype.resetPersonalData = function() { this.id = 0; - this.pseudo = euphorik.conf.pseudoDefaut; + this.nick = euphorik.conf.defaultNick; this.login = ""; this.password = ""; this.email = ""; - this.css = $("link#cssPrincipale").attr("href"); + this.css = $("link#mainCss").attr("href"); this.chatOrder = "reverse"; this.nickFormat = "nick"; this.viewTimes = true; this.viewTooltips = true; this.cookie = undefined; - - this.pagePrincipale = 1; + + this.mainConversationPage = 1; this.ekMaster = false; this.ostentatiousMaster = "light"; - - // les conversations, une conversation est un objet possédant les propriétés suivantes : - // - root (entier) - // - page (entier) - // - reduit (bool) + + // The user opened conversations. + // Each conversation object owns theses properties : + // - root (integer) + // - page (integer) + // - isCollapsed (bool) this.conversations = []; -} +}; -Client.prototype.setCss = function(css) { - if (this.css == css || css == "") { +/** + * Set the CSS. Dynamically change the href to the CSS in the DOM. + * @css The relative path to the CSS file, for example : + * "styles/1/euphorik.css". + */ +euphorik.Client.prototype.setCss = function(css) { + if (this.css === css || !css) { return; } this.css = css; - $("link#cssPrincipale").attr("href", this.css); + $("link#mainCss").attr("href", this.css); + if (this.autoflush) { this.flush(true); } -} +}; -Client.prototype.pageSuivante = function(numConv) { - if (numConv < 0 && this.pagePrincipale > 1) { - this.pagePrincipale -= 1; +/** + * Change the current page to the next one for the given conversation. + * @numConv The number of the conversation. + */ +euphorik.Client.prototype.nextPage = function(numConv) { + if (numConv < 0 && this.mainConversationPage > 1) { + this.mainConversationPage -= 1; } else if (this.conversations[numConv].page > 1) { this.conversations[numConv].page -= 1; } -} +}; -Client.prototype.pagePrecedente = function(numConv) { +/** + * Change the current page to the previous one for the given conversation. + * @numConv The number of the conversation. + */ +euphorik.Client.prototype.previousPage = function(numConv) { if (numConv < 0) { - this.pagePrincipale += 1; - } - else { + this.mainConversationPage += 1; + } else { this.conversations[numConv].page += 1; } -} +}; /** * Définit la première page pour la conversation donnée. * @return true si la page a changé sinon false */ -Client.prototype.goPremierePage = function(numConv) -{ +euphorik.Client.prototype.goFirstPage = function(numConv) { if (numConv < 0) { - if (this.pagePrincipale == 1) { + if (this.mainConversationPage === 1) { return false; } - this.pagePrincipale = 1; + this.mainConversationPage = 1; } else { - if (this.conversations[numConv].page == 1) { + if (this.conversations[numConv].page === 1) { return false; } this.conversations[numConv].page = 1; } return true; -} +}; /** * Ajoute une conversation à la vue de l'utilisateur. @@ -125,80 +154,62 @@ Client.prototype.goPremierePage = function(numConv) * @param racines la racine de la conversation (integer) * @return true si la conversation a été créée sinon false (par exemple si la conv existe déjà) */ -Client.prototype.ajouterConversation = function(racine) { +euphorik.Client.prototype.ajouterConversation = function(racine) { // vérification s'il elle n'existe pas déjà - for (var i = 0; i < this.conversations.length; i++) - if (this.conversations[i].root == racine) - return false - - this.conversations.push({root : racine, page : 1, reduit : false}) - if (this.autoflush) this.flush(true) - - return true -} - -Client.prototype.supprimerConversation = function(num) -{ - if (num < 0 || num >= this.conversations.length) return - - // décalage TODO : supprimer le dernier élément - for (var i = num; i < this.conversations.length - 1; i++) - this.conversations[i] = this.conversations[i+1] - this.conversations.pop() - - if (this.autoflush) this.flush(true) -} - -Client.prototype.getJSONLogin = function(login, password) -{ - return { - "header" : { "action" : "authentification", "version" : euphorik.conf.versionProtocole }, - "login" : login, - "password" : password + var existe = false; + this.conversations.each(function(i, conv) { + if (conv.root === racine) { + existe = true; + } + }); + if (existe) { + return false; } -} -Client.prototype.getJSONLoginCookie = function() -{ - return { - "header" : { "action" : "authentification", "version" : euphorik.conf.versionProtocole }, - "cookie" : this.cookie + this.conversations.push({root : racine, page : 1, isCollapsed : false}); + if (this.autoflush) { + this.flush(true); } -} -/** - * le couple (login, password) est facultatif. S'il n'est pas fournit alors il ne sera pas possible - * de s'autentifier avec (login, password). - */ -Client.prototype.getJSONEnregistrement = function(login, password) -{ - var mess = { "header" : { "action" : "register", "version" : euphorik.conf.versionProtocole }} - - if (login != undefined && password != undefined) - { - mess["login"] = login - mess["password"] = password + return true; +}; + +euphorik.Client.prototype.supprimerConversation = function(num) { + if (num < 0 || num >= this.conversations.length) { + return; } - - return mess; -} -Client.prototype.getJSONConversations = function() -{ - var conversations = new Array() - for (var i = 0; i < this.conversations.length; i++) - conversations.push({root : this.conversations[i].root, minimized : this.conversations[i].reduit}) - return conversations -} + // décalage TODO : supprimer le dernier élément + for (var i = num; i < this.conversations.length - 1; i++) { + this.conversations[i] = this.conversations[i+1]; + } + this.conversations.pop(); -Client.prototype.getJSONProfile = function() -{ + if (this.autoflush) { + this.flush(true); + } +}; + +euphorik.Client.prototype.getJSONConversations = function() { + var conversations = []; + this.conversations.each(function(i, conv) { + conversations.push({ "root" : conv.root, "minimized" : conv.isCollapsed }); + }); + return conversations; +}; + +euphorik.Client.prototype.getJSONProfile = function() { return { - "header" : { "action" : "set_profile", "version" : euphorik.conf.versionProtocole }, "cookie" : this.cookie, "login" : this.login, "password" : this.password, - "nick" : this.pseudo, + "profile" : this.getJSONProfileInfos() + }; +}; + +euphorik.Client.prototype.getJSONProfileInfos = function() { + return { + "nick" : this.nick, "email" : this.email, "css" : this.css, "chat_order" : this.chatOrder, @@ -207,328 +218,268 @@ Client.prototype.getJSONProfile = function() "view_tooltips" : this.viewTooltips, "conversations" : this.getJSONConversations(), "ostentatious_master" : this.ostentatiousMaster - } -} + }; +}; /** - * Renvoie null si pas définit. + * . */ -Client.prototype.getCookie = function() -{ - var cookie = this.regexCookie.exec(document.cookie) - if (cookie == null) this.cookie = null - else this.cookie = cookie[1] -} +euphorik.Client.prototype.getCookie = function() { + var cookie = this.regexCookie.exec(document.cookie); + if (cookie) { + this.cookie = cookie[1]; + } else { + this.cookie = undefined; + } +}; -Client.prototype.delCookie = function() -{ - document.cookie = "cookie=; max-age=0" -} +euphorik.Client.prototype.delCookie = function() { + document.cookie = "cookie=; max-age=0"; + this.cookie = undefined; +}; -Client.prototype.setCookie = function() -{ - if (this.cookie == null || this.cookie == undefined) - return - - // ne fonctionne pas sous IE.... +euphorik.Client.prototype.setCookie = function() { + if (!this.cookie) { + return; + } + + // doesn't work under IE.... /*document.cookie = "cookie=" + this.cookie + "; max-age=" + (60 * 60 * 24 * 365) */ - - document.cookie = - "cookie="+this.cookie+"; expires=" + new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 365).toUTCString() -} -Client.prototype.authentifie = function() -{ - return this.statut == euphorik.Client.statutType.auth_registered || this.statut == euphorik.Client.statutType.auth_not_registered -} + document.cookie = + "cookie="+this.cookie+"; expires=" + new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 365).toUTCString(); +}; + +euphorik.Client.prototype.authentifie = function() { + return this.statut === euphorik.Client.statusType.auth_registered || this.statut === euphorik.Client.statusType.auth_not_registered; +}; -Client.prototype.setStatut = function(statut) -{ +euphorik.Client.prototype.setStatus = function(statut) +{ // conversation en "enum" si en "string" - if (typeof(statut) == "string") - { + if (typeof(statut) === "string") { statut = - statut == "auth_registered" ? - euphorik.Client.statutType.auth_registered : - (statut == "auth_not_registered" ? euphorik.Client.statutType.auth_not_registered : euphorik.Client.statutType.deconnected) - } - - if (statut == this.statut) return - - this.statut = statut - this.majMenu() - this.majLogo() -} + statut === "auth_registered" ? + euphorik.Client.statusType.auth_registered : + (statut === "auth_not_registered" ? euphorik.Client.statusType.auth_not_registered : euphorik.Client.statusType.disconnected); + } + + if (statut === this.statut) { + return; + } + + this.statut = statut; + + this.majMenu(); + this.majLogo(); +}; /** - * Effectue la connexion vers le serveur. - * Cette fonction est bloquante tant que la connexion n'a pas été établie. - * S'il existe un cookie en local on s'authentifie directement avec lui. - * Si il n'est pas possible de s'authentifier alors on affiche un captcha anti-bot. + * Try to authentify the client with the cookie information. + * Do nothing if there is no cookie. */ -Client.prototype.connexionCookie = function() -{ - this.getCookie() - if (this.cookie == null) return false; - return this.connexion(this.getJSONLoginCookie()) -} - -Client.prototype.connexionLogin = function(login, password) -{ - return this.connexion(this.getJSONLogin(login, password)) -} - -Client.prototype.enregistrement = function(login, password) -{ - if (this.authentifie()) - { - this.login = login - this.password = password - if(this.flush()) - { - this.setStatut(euphorik.Client.statutType.auth_registered) - return true - } - return false +euphorik.Client.prototype.connectionCookie = function() { + this.getCookie(); + if (!this.cookie) { + return false; } - else - { - return this.connexion(this.getJSONEnregistrement(login, password)) + return this.connexion("authentification", { "cookie" : this.cookie }); +}; + +euphorik.Client.prototype.connexionLogin = function(login, password) { + return this.connexion("authentification", {"login" : login, "password" : password }); +}; + +euphorik.Client.prototype.enregistrement = function(login, password) { + if (this.authentifie()) { + this.login = login; + this.password = password; + if(this.flush()) { + this.setStatus(euphorik.Client.statusType.auth_registered); + return true; + } + return false; + } else { + return this.connexion("register", this.getJSONEnregistrement(login, password)); } -} +}; /** - * Connexion. Réalisé de manière synchrone. + * le couple (login, password) est facultatif. S'il n'est pas fournit alors il ne sera pas possible + * de s'autentifier avec (login, password). */ -Client.prototype.connexion = function(messageJson) -{ - var thisClient = this - jQuery.ajax( - { - async: false, - type: "POST", - url: "request", - dataType: "json", - data: this.util.jsonVersAction(messageJson), - success: - function(data) - { - if (data["reply"] == "error") - { - thisClient.util.messageDialogue(data["error_message"]) - // suppression du cookie actuel, cas où le cookie du client ne permet pas une authentification - thisClient.delCookie() - } - else - thisClient.chargerDonnees(data) - } - } - ) - return this.authentifie() -} +euphorik.Client.prototype.getJSONEnregistrement = function(login, password) { + var mess = {}; -Client.prototype.deconnexion = function() -{ - this.flush(true) - this.delCookie() - this.resetDonneesPersonnelles() - this.setStatut(euphorik.Client.statutType.deconnected) // deconnexion -} + if (login && password) { + mess.login = login; + mess.password = password; + } -Client.prototype.chargerDonnees = function(data) -{ + mess.profile = this.getJSONProfileInfos(); + + return mess; +}; + +/** + * Connexion. Réalisé de manière synchrone. + */ +euphorik.Client.prototype.connexion = function(action, messageJson) { + var thisClient = this; + + this.communication.requete( + action, + messageJson, + function(data) { + thisClient.chargerDonnees(data); + }, + function(data) { + thisClient.util.messageDialog(data.error_message); + thisClient.delCookie(); // suppression du cookie actuel, cas où le cookie du client ne permet pas une authentification + }, + false + ); + return this.authentifie(); +}; + +euphorik.Client.prototype.disconnect = function() { + this.flush(true); + this.delCookie(); + this.resetPersonalData(); + this.setStatus(euphorik.Client.statusType.disconnected); +}; + +euphorik.Client.prototype.chargerDonnees = function(data) { // la modification du statut qui suit met à jour le menu, le menu dépend (page admin) // de l'état ekMaster - this.ekMaster = data["ek_master"] != undefined ? data["ek_master"] : false - - this.setStatut(data["status"]) - - if (this.authentifie()) - { - this.cookie = data["cookie"] - this.setCookie() - - this.id = data["id"] - this.login = data["login"] - this.pseudo = data["nick"] - this.email = data["email"] - this.setCss(data["css"]) - this.chatOrder = data["chat_order"] - this.nickFormat = data["nick_format"] - this.viewTimes = data["view_times"] - this.viewTooltips = data["view_tooltips"] - this.ostentatiousMaster = data["ostentatious_master"] - + this.ekMaster = data.ek_master ? data.ek_master : false; + + this.setStatus(data.status); + + if (this.authentifie()) { + this.cookie = data.cookie; + this.setCookie(); + + this.id = data.id; + this.login = data.login; + this.nick = data.profile.nick; + this.email = data.profile.email; + this.setCss(data.profile.css); + this.chatOrder = data.profile.chat_order; + this.nickFormat = data.profile.nick_format; + this.viewTimes = data.profile.view_times; + this.viewTooltips = data.profile.view_tooltips; + this.ostentatiousMaster = data.profile.ostentatious_master; + // la page de la conversation principale - this.pagePrincipale = 1 - + this.mainConversationPage = 1; + // les conversations - this.conversations = data["conversations"] - for (var i = 0; i < this.conversations.length; i++) - this.conversations[i] = {root : this.conversations[i].root, page : 1, reduit : this.conversations[i].minimized} - - this.majBulle() - this.majCssSelectionee() - //this.majLogo() + this.conversations = data.profile.conversations; + this.conversations.map(function(conv) { + return { root : conv.root, page : 1, isCollapsed : conv.minimized }; + }); + + this.majBulle(); + this.majCssSelectionee(); } -} +}; /** * Met à jour les données personne sur serveur. * @param async de manière asynchrone ? défaut = true * @return false si le flush n'a pas pû se faire sinon true */ -Client.prototype.flush = function(async) -{ - if (async == undefined) - async = false - - if (!this.authentifie()) - return false - - var thisClient = this - var ok = true - jQuery.ajax( - { - async: async, - type: "POST", - url: "request", - dataType: "json", - data: this.util.jsonVersAction(this.getJSONProfile()), - success: - function(data) - { - if (data["reply"] == "error") - { - thisClient.util.messageDialogue(data["error_message"]) - ok = false - } - else - { - thisClient.majBulle() - } - } - } - ) - - return ok -} - -Client.prototype.majMenu = function() -{ - var displayType = "block" - - $("#menu .admin").css("display", this.ekMaster ? displayType : "none") +euphorik.Client.prototype.flush = function(async) { + async = async || false; - // met à jour le menu - if (this.statut == euphorik.Client.statutType.auth_registered) - { - $("#menu .profile").css("display", displayType).text("profile") - $("#menu .logout").css("display", displayType) - $("#menu .register").css("display", "none") + if (!this.authentifie()) { + return false; } - else if (this.statut == euphorik.Client.statutType.auth_not_registered) - { - $("#menu .profile").css("display", "none") - $("#menu .logout").css("display", displayType) - $("#menu .register").css("display", displayType) - } - else - { - $("#menu .profile").css("display", displayType).text("login") - $("#menu .logout").css("display", "none") - $("#menu .register").css("display", displayType) + + var thisClient = this; + var ok = true; + + this.communication.requete( + "set_profile", + this.getJSONProfile(), + function(data) { + thisClient.majBulle(); + }, + function(data) { + thisClient.util.messageDialog(data.error_message); + ok = false; + }, + async + ); + + return ok; +}; + +euphorik.Client.prototype.majMenu = function() { + var displayType = "block"; + + $("#menu .admin").css("display", this.ekMaster ? displayType : "none"); + + // met à jour le menu + if (this.statut === euphorik.Client.statusType.auth_registered) { + $("#menu .profile").css("display", displayType).text("profile"); + $("#menu .logout").css("display", displayType); + $("#menu .register").css("display", "none"); + } else if (this.statut === euphorik.Client.statusType.auth_not_registered) { + $("#menu .profile").css("display", "none"); + $("#menu .logout").css("display", displayType); + $("#menu .register").css("display", displayType); + } else { + $("#menu .profile").css("display", displayType).text("login"); + $("#menu .logout").css("display", "none"); + $("#menu .register").css("display", displayType); } -} +}; /** - * Met à jour l'affichage des infos bulles en fonction du profile. + * Met à jour l'affichage ou non des infos bulles en fonction du profile. */ -Client.prototype.majBulle = function() -{ - this.util.bulleActive = this.viewTooltips -} +euphorik.Client.prototype.majBulle = function() { + this.util.bulleActive = this.viewTooltips; +}; /** * Met à jour la css sélectionnée, lors du chargement des données. */ -Client.prototype.majCssSelectionee = function() -{ +euphorik.Client.prototype.majCssSelectionee = function() { // extraction du numéro de la css courante - var numCssCourante = this.css.match(/^.*?\/(\d)\/.*$/) - if (numCssCourante != null && numCssCourante[1] != undefined) - { - $("#menuCss option").removeAttr("selected") - $("#menuCss option[value=" + numCssCourante[1]+ "]").attr("selected", "selected") + var numCssCourante = this.css.match(/^.*?\/(\d)\/.*$/); + if (numCssCourante && numCssCourante[1]) { + $("#menuCss option").removeAttr("selected"); + $("#menuCss option[value=" + numCssCourante[1]+ "]").attr("selected", "selected"); } -} +}; /** * Change la "class" du logo en fonction du statut de ekMaster. */ -Client.prototype.majLogo = function() -{ - if (this.ekMaster) - $("#logo").addClass("ekMaster") - else - $("#logo").removeClass("ekMaster") -} +euphorik.Client.prototype.majLogo = function() { + if (this.ekMaster) { + $("#logo").addClass("ekMaster"); + } else { + $("#logo").removeClass("ekMaster"); + } +}; +euphorik.Client.prototype.slap = function(userId, raison) { + var thisClient = this; + this.communication.requete("slap", { "cookie" : thisClient.cookie, "user_id" : userId, "reason" : raison }); +}; -Client.prototype.slap = function(userId, raison) -{ - var thisClient = this - - jQuery.ajax({ - type: "POST", - url: "request", - dataType: "json", - data: this.util.jsonVersAction( - { - "header" : { "action" : "slap", "version" : euphorik.conf.versionProtocole }, - "cookie" : thisClient.cookie, - "user_id" : userId, - "reason" : raison - }), - success: - function(data) - { - if (data["reply"] == "error") - thisClient.util.messageDialogue(data["error_message"]) - } - }) -} - -Client.prototype.ban = function(userId, raison, minutes) -{ - var thisClient = this +euphorik.Client.prototype.ban = function(userId, raison, minutes) { + var thisClient = this; // par défaut un ban correspond à 3 jours - if (typeof(minutes) == "undefined") - minutes = euphorik.conf.tempsBan; - - jQuery.ajax({ - type: "POST", - url: "request", - dataType: "json", - data: this.util.jsonVersAction( - { - "header" : { "action" : "ban", "version" : euphorik.conf.versionProtocole }, - "cookie" : thisClient.cookie, - "duration" : minutes, - "user_id" : userId, - "reason" : raison - }), - success: - function(data) - { - if (data["reply"] == "error") - thisClient.util.messageDialogue(data["error_message"]) - } - }) -} - -Client.prototype.kick = function(userId, raison) -{ - this.ban(userId, raison, euphorik.conf.tempsKick) -} + minutes = minutes || euphorik.conf.tempsBan; + this.communication.requete("ban", { "cookie" : thisClient.cookie, "duration" : minutes, "user_id" : userId, "reason" : raison }); +}; + +euphorik.Client.prototype.kick = function(userId, raison) { + this.ban(userId, raison, euphorik.conf.tempsKick); +};