ADD Bannissement (sans le slap)
[euphorik.git] / js / pageMinichat.js
index a6ba5a6..94f6e7c 100755 (executable)
@@ -14,14 +14,13 @@ function PageMinichat(client, formateur, util)
 
 PageMinichat.prototype.contenu = function()
 {
-// <input class="captcha" name="captcha" type="text" size="12"></input>\
    return '\
-<div id="smiles"></div>\
 <form method="post" action="">\
    <p>\
       <input class="captcha" name="captcha" type="text" size="8" maxlength="8"></input>\
       <input class="pseudo" name="pseudo" type="text" size="12" maxlength="50" value="&lt;nick&gt;"></input>\
       <input class="message" name="message" type="text" size="80" maxlength="500" value=""></input>\
+      <button class="smiles"></button>\
       <button class="return"></button>\
    </p>\
 </form>\
@@ -41,8 +40,25 @@ PageMinichat.prototype.charger = function()
    \r
    this.util.setCaretToEnd(jQuery("form input.message")[0])
 
+   // les outils de bannissement (uniquement pour les ekMaster)
+   if (this.client.ekMaster)
+   {    
+      jQuery("body").append(
+         "<div id=\"outilsBan\"><img id=\"ban\" alt=\"Ban de 3 jours\" src=\"img/ban.gif\" /><img id=\"kick\" alt=\"Ban de 15min\" src=\"img/kick.gif\" /><img id=\"slap\" alt=\"Avertissement\" src=\"img/slap.gif\" /></div>"
+      )
+      jQuery("#outilsBan").hover(
+         function(){},
+         function()
+         {
+            jQuery("#outilsBan").hide()
+         }
+      )
+   }
+
+   // <smiles>
+   jQuery("body").append("<div id=\"smiles\"></div>")
    // affichage des smiles
-   jQuery("#smiles").html(this.formateur.getSmilesHTML()).children().each(
+   jQuery("#smiles").append(this.formateur.getSmilesHTML()).children().each(
       function(i)
       {
          var opacityBase = jQuery(this).css("opacity")
@@ -72,12 +88,28 @@ PageMinichat.prototype.charger = function()
          )
       }
    )
+   jQuery("form button.smiles").hover(
+      function(e)
+      {
+         var offset = jQuery(e.target).offset()
+         jQuery("#smiles").css("top", offset.top).css("left", offset.left).show()
+      },
+      function(e){}
+   )
+   jQuery("#smiles").hover(
+      function(){},
+      function(e)
+      {
+         jQuery("#smiles").hide()
+      }
+   )
+   // </smiles>
    
-   /// événements
-   jQuery("form button.return").click(
+   // événements
+   var nouveauMessage = 
       function()
-      {  \r
-         // captcha anti bot\r
+      {  
+         // captcha anti bot
          if (jQuery("form input.captcha").val() != "") return
       
          thisPage.envoyerMessage(
@@ -87,9 +119,19 @@ PageMinichat.prototype.charger = function()
             
          jQuery("form input.message")[0].focus()
       }
+      
+   jQuery("form").keypress(
+      function(e)
+      {
+         if (e.which == 13) // return
+            nouveauMessage()
+      }
    )
+   
+   jQuery("form button.return").click(nouveauMessage)
+   
    // interdiction de submiter le formulaire
-   jQuery("form").submit(function(){return false})
+   jQuery("form").submit(function(){ return false})
    
    jQuery("input.pseudo").click(
       function()
@@ -105,6 +147,9 @@ PageMinichat.prototype.decharger = function()
 {
    //alert(this.attenteCourante)
    this.messages.stopAttenteCourante()
+   
+   jQuery("body #smiles").remove()
+   jQuery("body #outilsBan").remove()
 }
 
 PageMinichat.prototype.getJSONMessage = function(pseudo, message, repondA)
@@ -180,7 +225,11 @@ PageMinichat.prototype.envoyerMessage = function(pseudo, message)
                         thisPageMinichat.messages.conversations[c].messages[m].clientARepondu = true
                   */
                }
-            }\r
+            }
+            else if (data["reply"] == "error")
+            {
+               thisPageMinichat.util.messageDialogue(data["error_message"])
+            }  \r
          }\r
       }\r
    )
@@ -210,9 +259,10 @@ function Reponse(id, pseudo, login)
   * @param pseudo
   * @param contenu
   */
-function Message(id, date, pseudo, login, contenu)
+function Message(id, auteurId, date, pseudo, login, contenu)
 {
    this.id = id
+   this.auteurId = auteurId
    this.date = date
    this.pseudo = pseudo
    this.login = login
@@ -221,6 +271,7 @@ function Message(id, date, pseudo, login, contenu)
    this.appartientAuClient = false
    this.clientARepondu = false
    this.estUneReponse = false
+   this.ekMaster = false
    
    this.systeme = false // est-ce un message 'système' ?
    
@@ -296,6 +347,7 @@ function Conversation(num, util, formateur, client)
    this.util = util
    this.formateur = formateur
    this.client = client
+   this.idDernierMessageAffiche = 0
    
    this.messages = new Array()
    this.messagesParId = new Object()
@@ -323,11 +375,11 @@ function Conversation(num, util, formateur, client)
 }
 
 /**
-  * Défini les fonctions (callback) appelées lorsque l'on change de page.
+  * Défini la page courante et s'il l'on se trouve sur la dernière page.
   * @pageCourante la page courante
   * @dernierePage true si c'est la dernière page sinon false
   */
-Conversation.prototype.eventsPage = function(pageCourante, dernierePage)
+Conversation.prototype.setPage = function(pageCourante, dernierePage)
 {
    jQuery("#conversations #" + this.getId() + " .numPage").text(pageCourante)
    jQuery("#conversations #" + this.getId() + " .next").css("display", pageCourante == 1 ? "none" : "inline")
@@ -400,40 +452,43 @@ Conversation.prototype.ajouterMessage = function(message)
       delete this.messagesParId[this.messages.shift().id]
 }
 
+/**
+  * FIXME : méthode très lourde. ne serait-ce pas mieux de virer d'un coup l'élément conversation et d'en remettre un vide ?
+  */
 Conversation.prototype.viderMessages = function()
 {
    this.messages = new Array()
+   this.idDernierMessageAffiche = 0
    jQuery("#conversations #" + this.getId() + " .message").remove()
 }
 
 /**
   * Après l'ajout d'un ou plusieurs message cette méthode est appelée afin
   * d'afficher les messages non-affichés.
+  * FIXME : méthode super lourde, à optimiser.
   * @param funClickExtract fonction (fun(numMess)) appellée lors du clic sur un bouton "extraire"
   */
-Conversation.prototype.flush = function(funClickExtract, funClickLienConv)
+Conversation.prototype.flush = function(funClickOuvrirConv)
 {
    var thisConversation = this
 
-   var idDernierMessageAffiche = jQuery("#conversations #" + this.getId() + " div:first").attr("id")
-   idDernierMessageAffiche = (idDernierMessageAffiche == undefined ? 0 : parseInt(idDernierMessageAffiche, 36))
-      
    // est-ce que le prochain message est pair ? (permet d'alterner le style des messages)
-   var messagePair = (idDernierMessageAffiche == 0 ? true :
+   var messagePair = (this.idDernierMessageAffiche == 0 ? true :
       (jQuery("#conversations #" + this.getId() + " div:first").attr("class").search("messagePair") == -1)
    )
       
    // construction de l'XHTML des messages
    var XHTML = ""
    for (var i = this.messages.length - 1; i >= 0; i--)
-      if (this.messages[i].id > idDernierMessageAffiche)
+      if (this.messages[i].id > this.idDernierMessageAffiche)
       {      
          var message = this.messages[i]
          
          // construit l'identifiant de la personne
          var identifiant = 
-            this.client.nickFormat == "nick" ? message.pseudo : 
-            (this.client.nickFormat == "login" ? message.login : message.pseudo + "(" + message.login +")" )
+            this.client.nickFormat == "nick" ? this.formateur.traitementComplet(message.pseudo) : 
+            (this.client.nickFormat == "login" ? this.formateur.traitementComplet(message.login) : 
+            this.formateur.traitementComplet(message.pseudo) + "<span class=\"login\">(" + this.formateur.traitementComplet(message.login) +")</span>" )
          
          var XHTMLrepondA = ""
          for (var id in message.repondA)
@@ -446,10 +501,11 @@ Conversation.prototype.flush = function(funClickExtract, funClickLienConv)
                (this.messages[i].clientARepondu ? " repondu" : "") +
                (this.messages[i].estUneReponse ? " reponse" : "") +
                (this.messages[i].systeme ? " systeme" : "") +
+               (this.messages[i].ekMaster ? " ekMaster" : "") +
             "\">" +
                "<div class=\"extraire\">&gt;</div>" +
                "[<span class=\"date\">" + message.date + "</span>]" +
-               "<span class=\"pseudo\">" + this.formateur.traitementComplet(identifiant) + "</span>:" +
+               "<span class=\"pseudo\" id=\"user" + message.auteurId + "\">" + identifiant + "</span>:" +
                XHTMLrepondA +
                "<span class=\"contenu\">" + (message.systeme ? this.formateur.remplacerBalisesHTML(message.contenu) : this.formateur.traitementComplet(message.contenu, message.pseudo)) + "</span>" +
             "</div>"
@@ -469,8 +525,8 @@ Conversation.prototype.flush = function(funClickExtract, funClickLienConv)
    if (nbMessagesAffiche > this.nbMessageMax)
       jQuery("#conversations #" + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).empty()
 
-   // Ajoute les événements liés à chaque message
-   jQuery("#conversations #" + this.getId() + " .message").filter(function(){return parseInt(jQuery(this).attr("id"), 36) > idDernierMessageAffiche}).each(
+   // ajoute les événements liés à chaque nouveau message
+   jQuery("#conversations #" + this.getId() + " .message").filter(function(){return parseInt(jQuery(this).attr("id"), 36) > thisConversation.idDernierMessageAffiche}).each(
       function()
       {
          jQuery(".lienConv", this).click(
@@ -478,23 +534,50 @@ Conversation.prototype.flush = function(funClickExtract, funClickLienConv)
             {          
                // FIXME : ya pas mieux ?
                var racine = jQuery(event.target).text()
-               funClickLienConv(parseInt(racine.substring(1, racine.length - 1), 36))
+               funClickOuvrirConv(parseInt(racine.substring(1, racine.length - 1), 36))
                return false
             }
          )
          
+         // les outils de bannissement (uniquement pour les ekMaster)
+         if (thisConversation.client.ekMaster)
+            jQuery(".pseudo", this).hover(
+               function(e)
+               {     
+                  var userId =  parseInt(jQuery(this).attr("id").substr(4))
+                  var element = jQuery(e.target)
+                  var h = element.height()
+                  var offset = element.offset()
+                  var outils = jQuery("#outilsBan").css("top", offset.top - 2).css("left", offset.left - 2).height(h < 16 ? 16 : h).width(element.width() + 16 * 3 + 4).show()
+                  jQuery("img", outils).unbind()
+                  jQuery("#kick", outils).click(
+                     function(e)
+                     {
+                        thisConversation.client.kick(userId)
+                     }
+                  )
+                  jQuery("#ban", outils).click(
+                     function(e)
+                     {
+                        thisConversation.client.ban(userId)
+                     }
+                  )
+               },
+               function(){}
+            )
+         
          jQuery(this).click(
             function(event)
             {
                if (jQuery(event.target).is("a")) return
                
                // l'id du message
-               idMess = jQuery(this).attr("id")
+               var idMess = jQuery(this).attr("id")
                
                // extraction d'une conversation
                if (jQuery(event.target).is(".extraire"))
                {
-                  funClickExtract(parseInt(idMess, 36))
+                  funClickOuvrirConv(parseInt(idMess, 36))
                   return
                }
             
@@ -520,6 +603,9 @@ Conversation.prototype.flush = function(funClickExtract, funClickLienConv)
          )
       }
    )
+   
+   if (this.messages.length > 0)
+      this.idDernierMessageAffiche = this.messages[this.messages.length-1].id
 }
 
 /**
@@ -573,8 +659,6 @@ function Messages(client, formateur, util)
    
    this.conversations = new Array() // les conversations, la première représente la conversation principale
    this.nouvelleConversation(0)
-
-   this.idDernierMessage = null // l'id du dernier message connu
    
    // l'objet JSONHttpRequest représentant la connexion d'attente
    this.attenteCourante = null
@@ -590,25 +674,50 @@ Messages.prototype.getJSONrafraichirMessages = function()
       "page" : "chat",
       "message_count" : conf.nbMessageAffiche,
       "main_page" : this.client.pagePrincipale,
-      "conversations" : this.client.getJSONConversations()
+      "conversations" : this.getJSONConversations()
    }
    
    if (this.client.cookie != null) mess["cookie"] = this.client.cookie;
-   if (this.idDernierMessage != null) mess["last_message_id"] = this.idDernierMessage
+   mess["last_message_id"] = this.conversations[0].idDernierMessageAffiche
+   
+   // obsolète
+   //if (this.idDernierMessage != null) mess["last_message_id"] = this.idDernierMessage
    
    return mess
 }
 
+Messages.prototype.getJSONConversations = function()
+{
+   var clientConv = this.client.getJSONConversations()
+   for (var i = 1; i < this.conversations.length; i++)
+   {
+      clientConv[i-1]["last_message_id"] = this.conversations[i].idDernierMessageAffiche
+   }
+   return clientConv
+}
+
 /**
   * Ajoute un ensemble de messages puis les affiches.
   * @param elements un tableau d'éléments JSON représentant les messages, voir protocole.txt
   * @param numConversation le numéro de la conversation auquel appartiennent les messages
+  * @return true si les messages on été ajoutés, false si la conversation n'existe pas et qu'il n'y a pas de message
   */
 Messages.prototype.ajouterMessages = function(elements, numConversation)
 {
+   if (elements["messages"].length == 0 && typeof(this.conversations[numConversation]) == "undefined")
+      return false
+
    for (var i = 0; i < elements["messages"].length; i++)
       this.ajouterMessage(elements["messages"][i], numConversation)
    this.flush(numConversation)
+   
+   // renseigne la conversation sur la page courante et si c'est la dernière
+   this.conversations[numConversation].setPage(
+      numConversation == 0 ? this.client.pagePrincipale : this.client.conversations[numConversation - 1].page,
+      elements["last_page"]
+   )
+   
+   return true
 }
 
 /**
@@ -624,11 +733,9 @@ Messages.prototype.ajouterMessage = function(element, numConversation)
    // pas d'utilisation de jquery pour des raisons de performance
    var id = element["id"]
    
-   if (this.idDernierMessage == null || id > this.idDernierMessage)
-      this.idDernierMessage = id
-   
    var message = new Message(
       id,      
+      element["user_id"],
       element["date"],
       element["nick"],
       element["login"],
@@ -640,6 +747,7 @@ Messages.prototype.ajouterMessage = function(element, numConversation)
    message.estUneReponse = element["is_a_reply"]
    message.systeme = element["system"] 
    message.setRepondA(element["answer_to"])
+   message.ekMaster = element["ek_master"]
    
    if (this.conversations[numConversation] == null)
    {
@@ -653,7 +761,7 @@ Messages.prototype.ajouterMessage = function(element, numConversation)
          {
                thisPage.util.replaceSelection(
                   jQuery("form input.message")[0],
-                  "{" + thisMessages.client.conversations[num-1].root + "}"
+                  "{" + thisMessages.client.conversations[num-1].root.toString(36) + "}"
                )
          }
       )
@@ -740,23 +848,25 @@ Messages.prototype.flush = function(numConv)
    var thisMessages = this
    
    this.conversations[numConv].flush(
-      // fonction appelée lors de la demande d'extraction d'une conversation
-      function(idMess)
-      {
-         if (thisMessages.client.ajouterConversation(idMess))
-            thisMessages.rafraichirMessages(true)
-      },
       function(racine) // appelé lorsqu'un utilisateur click sur un lien vers une conversation
       {
-         if (thisMessages.client.ajouterConversation(racine))
-            thisMessages.rafraichirMessages(true)
+         thisMessages.ouvrirConversation(racine)
       }
    )
 }
 
+Messages.prototype.ouvrirConversation = function(racine)
+{
+   if (this.client.ajouterConversation(racine))
+      this.rafraichirMessages(true)
+   else
+      this.util.messageDialogue("Cette conversation est déjà ouverte")
+}
+
 Messages.prototype.viderMessages = function()
 {
-   this.idDernierMessage = null
+   // Obsolète
+   //this.idDernierMessage = null
    
    for (var i = 0; i < this.conversations.length; i++)
       this.conversations[i].viderMessages()
@@ -786,7 +896,8 @@ Messages.prototype.rafraichirMessages = function(vider)
    this.stopAttenteCourante()
    
    if (vider)
-      this.idDernierMessage = null\r
+      for (var i = 0; i < this.conversations.length; i++)
+         this.conversations[i].idDernierMessageAffiche = 0\r
       
    dumpObj(this.getJSONrafraichirMessages())
    this.attenteCourante = jQuery.ajax({
@@ -802,19 +913,17 @@ Messages.prototype.rafraichirMessages = function(vider)
             if (vider)
                thisMessages.viderMessages()
             
-            // ajoute les messages reçu à leur conversation respective
+            // ajoute les messages reçus à leur conversation respective
             for (var numConv = 0; numConv < data["conversations"].length; numConv++)
             {
-               // ya pas de nouveaux message -> on passe à la prochaine conversation
-               if (data["conversations"][numConv]["messages"].length == 0) continue
-               
-               thisMessages.ajouterMessages(data["conversations"][numConv], numConv)
+               // ya pas de nouveaux message -> on passe à la prochaine conversation FIXME : marche pas
+               //if (data["conversations"][numConv]["messages"].length == 0) continue
                
-               // définit les événements liés à la conversation
-               thisMessages.conversations[numConv].eventsPage(
-                  numConv == 0 ? thisMessages.client.pagePrincipale : thisMessages.client.conversations[numConv - 1].page,
-                  data["conversations"][numConv]["last_page"]
-               )
+               if (! thisMessages.ajouterMessages(data["conversations"][numConv], numConv))
+               {
+                  thisMessages.util.messageDialogue("La conversation {" + thisMessages.client.conversations[numConv -1].root.toString(36) + "} n'existe pas")
+                  thisMessages.client.supprimerConversation(numConv - 1) 
+               }
             }
             
             // rappel de la fonction dans 100 ms