X-Git-Url: http://git.euphorik.ch/?p=euphorik.git;a=blobdiff_plain;f=js%2Fclient.js;fp=js%2Fclient.js;h=a09819b58232c19fa87c02c07f565fdd1038fad5;hp=0000000000000000000000000000000000000000;hb=deff7a2f11dca2b300b258d1e93d71e3b2e34c84;hpb=107016b49c680e6bc4ff8ae9685f7c57e46cc450 diff --git a/js/client.js b/js/client.js new file mode 100644 index 0000000..a09819b --- /dev/null +++ b/js/client.js @@ -0,0 +1,534 @@ +// coding: utf-8 +// Copyright 2008 Grégory Burri +// +// This file is part of Euphorik. +// +// Euphorik is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Euphorik is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Euphorik. If not, see . + +/*jslint laxbreak:true */ + +// les statuts possibes du client +euphorik.Client.statutType = { + // mode enregistré, peut poster des messages et modifier son profile + auth_registered : 0, + // mode identifié, peut poster des messages mais n'a pas accès au profile + auth_not_registered : 1, + // mode déconnecté, ne peut pas poster de message + deconnected : 2 +} + +/** + * Représente l'utilisateur du site. + */ +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() { + this.id = 0; + this.pseudo = euphorik.conf.pseudoDefaut; + this.login = ""; + this.password = ""; + this.email = ""; + this.css = $("link#cssPrincipale").attr("href"); + this.chatOrder = "reverse"; + this.nickFormat = "nick"; + this.viewTimes = true; + this.viewTooltips = true; + this.cookie = undefined; + + this.pagePrincipale = 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) + this.conversations = []; +} + +Client.prototype.setCss = function(css) { + if (this.css == css || css == "") { + return; + } + + this.css = css; + $("link#cssPrincipale").attr("href", this.css); + if (this.autoflush) { + this.flush(true); + } +} + +Client.prototype.pageSuivante = function(numConv) { + if (numConv < 0 && this.pagePrincipale > 1) { + this.pagePrincipale -= 1; + } else if (this.conversations[numConv].page > 1) { + this.conversations[numConv].page -= 1; + } +} + +Client.prototype.pagePrecedente = function(numConv) { + if (numConv < 0) { + this.pagePrincipale += 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) +{ + if (numConv < 0) { + if (this.pagePrincipale == 1) { + return false; + } + this.pagePrincipale = 1; + } else { + if (this.conversations[numConv].page == 1) { + return false; + } + this.conversations[numConv].page = 1; + } + return true; +} + +/** + * Ajoute une conversation à la vue de l'utilisateur. + * Le profile de l'utilisateur est directement sauvegardé sur le serveur. + * @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) { + // 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 + } +} + +Client.prototype.getJSONLoginCookie = function() +{ + return { + "header" : { "action" : "authentification", "version" : euphorik.conf.versionProtocole }, + "cookie" : this.cookie + } +} + +/** + * 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 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 +} + +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, + "email" : this.email, + "css" : this.css, + "chat_order" : this.chatOrder, + "nick_format" : this.nickFormat, + "view_times" : this.viewTimes, + "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] +} + +Client.prototype.delCookie = function() +{ + document.cookie = "cookie=; max-age=0" +} + +Client.prototype.setCookie = function() +{ + if (this.cookie == null || this.cookie == undefined) + return + + // ne fonctionne pas sous 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 +} + +Client.prototype.setStatut = function(statut) +{ + // conversation en "enum" si en "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() +} + +/** + * 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. + */ +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 + } + else + { + return this.connexion(this.getJSONEnregistrement(login, password)) + } +} + +/** + * Connexion. Réalisé de manière synchrone. + */ +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() +} + +Client.prototype.deconnexion = function() +{ + this.flush(true) + this.delCookie() + this.resetDonneesPersonnelles() + this.setStatut(euphorik.Client.statutType.deconnected) // deconnexion +} + +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"] + + // la page de la conversation principale + this.pagePrincipale = 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() + } +} + +/** + * 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") + + // 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") + } + 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) + } +} + +/** + * Met à jour l'affichage des infos bulles en fonction du profile. + */ +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() +{ + // 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") + } +} + +/** + * 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") +} + + +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 + + // 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) +}