ADD avancement sur l'affichage de l'élément racine (il manque la gestion des événements)
authorGreg Burri <greg.burri@gmail.com>
Fri, 27 Jun 2008 20:59:43 +0000 (20:59 +0000)
committerGreg Burri <greg.burri@gmail.com>
Fri, 27 Jun 2008 20:59:43 +0000 (20:59 +0000)
css/1/pageMinichat.css
doc/protocole3.txt
js/euphorik.js
js/pageMinichat.js
modules/erl/euphorik_protocole.erl
nbproject/private/private.xml

index e8e4181..38e0979 100755 (executable)
        width: 100%;
 }
 #page.minichat #conversations .titre {
        width: 100%;
 }
 #page.minichat #conversations .titre {
+   border-top: 1px dashed white
+}
+#page.minichat #conversations .titre .barre {
        text-align: center;
        padding-right: 8px;
        background-color: #e19671;
        color: #ffffff;
 }
        text-align: center;
        padding-right: 8px;
        background-color: #e19671;
        color: #ffffff;
 }
-#page.minichat #conversations .titre .fermer {
+#page.minichat #conversations .titre .barre .fermer {
        margin-top: 1px;
        margin-left: 5px;
        float: right;
        margin-top: 1px;
        margin-left: 5px;
        float: right;
        background-image: url(../../img/css1/fermer_conv.png);
        cursor: pointer;
 }
        background-image: url(../../img/css1/fermer_conv.png);
        cursor: pointer;
 }
-#page.minichat #conversations .titre .fermer:hover {
+#page.minichat #conversations .titre .barre .fermer:hover {
        background-image: url(../../img/css1/fermer_conv_hover.png);
 }      
        background-image: url(../../img/css1/fermer_conv_hover.png);
 }      
-#page.minichat #conversations .titre .lien {
+#page.minichat #conversations .titre .barre .lien {
        margin-top: 1px;
        float: right;
        width: 13px;
        margin-top: 1px;
        float: right;
        width: 13px;
        background-image: url(../../img/css1/copier_conv.png);
        cursor: pointer;
 }
        background-image: url(../../img/css1/copier_conv.png);
        cursor: pointer;
 }
-#page.minichat #conversations .titre .lien:hover {
+#page.minichat #conversations .titre .barre .lien:hover {
        background-image: url(../../img/css1/copier_conv_hover.png);
 }      
        background-image: url(../../img/css1/copier_conv_hover.png);
 }      
-#page.minichat #conversations .titre .next,
-#page.minichat #conversations .titre .prev {
+#page.minichat #conversations .titre .barre .next,
+#page.minichat #conversations .titre .barre .prev {
        display: none;
 }
        display: none;
 }
-#page.minichat #conversations .titre .next,
-#page.minichat #conversations .titre .prev,
-#page.minichat #conversations .titre .numPage {
+#page.minichat #conversations .titre .barre .next,
+#page.minichat #conversations .titre .barre .prev,
+#page.minichat #conversations .titre .barre .numPage {
        background-color: #841919;
        cursor: pointer;
        padding-right: 5px;
        padding-left: 5px;
 }
        background-color: #841919;
        cursor: pointer;
        padding-right: 5px;
        padding-left: 5px;
 }
-#page.minichat #conversations .titre .next:hover,
-#page.minichat #conversations .titre .prev:hover,
-#page.minichat #conversations .titre .numPage:hover {
+#page.minichat #conversations .titre .barre .next:hover,
+#page.minichat #conversations .titre .barre .prev:hover,
+#page.minichat #conversations .titre .barre .numPage:hover {
        background-color: #cb2626
 }
 
        background-color: #cb2626
 }
 
index 12b3f1f..eb661a3 100644 (file)
@@ -176,13 +176,13 @@ s -> c
 La première conversation est la principale (main).
 L'ordre des conversation est le même que celui des données de l'utilisateur.
 Le format de la date n'est pas formel.
 La première conversation est la principale (main).
 L'ordre des conversation est le même que celui des données de l'utilisateur.
 Le format de la date n'est pas formel.
-first correpond au premier message de la conversation, vaut 'undefined' pour la conversation principale ainsi que pour les conversations vides.
+first correpond au premier message de la conversation, vaut 'null' pour la conversation principale ainsi que pour les conversations vides.
    {
       "reply" : "new_message",
       "conversations" : [
          {
             "last_page" : true | false,
    {
       "reply" : "new_message",
       "conversations" : [
          {
             "last_page" : true | false,
-            "first" : <message> | undefined,
+            "first" : <message> | null,
             "messages" : [ <message>, .. ]
          }
       ]
             "messages" : [ <message>, .. ]
          }
       ]
index 9e4d8ec..596ded4 100755 (executable)
@@ -31,7 +31,7 @@
 var conf = {
    versionProtocole : 3, // version du protcole
    nickDefaut : "<nick>",
 var conf = {
    versionProtocole : 3, // version du protcole
    nickDefaut : "<nick>",
-   nbMessageAffiche : 40, // (par page)
+   nbMessageAffiche : 10, // (par page)
    pseudoDefaut : "<nick>",
    tempsAffichageMessageDialogue : 4000, // en ms
    tempsKick : 15, // en minute
    pseudoDefaut : "<nick>",
    tempsAffichageMessageDialogue : 4000, // en ms
    tempsKick : 15, // en minute
index 2de1531..a8afb97 100755 (executable)
@@ -57,9 +57,9 @@ PageMinichat.prototype.charger = function()
    $("form input.pseudo").val(this.client.pseudo)
    
    // cet appel ne doit pas être fait avant l'appel à 'charger'
    $("form input.pseudo").val(this.client.pseudo)
    
    // cet appel ne doit pas être fait avant l'appel à 'charger'
-   this.messages = new Messages(this.client, this.formateur, this.util)
+   this.conversations = new Conversations(this.client, this.formateur, this.util)
    
    
-   this.messages.rafraichirMessages(true)
+   this.conversations.rafraichirMessages(true)
    
    this.util.setCaretToEnd($("form input.message")[0])
 
    
    this.util.setCaretToEnd($("form input.message")[0])
 
@@ -162,7 +162,7 @@ PageMinichat.prototype.charger = function()
 
 PageMinichat.prototype.decharger = function()
 {
 
 PageMinichat.prototype.decharger = function()
 {
-   this.messages.pageEvent.stopAttenteCourante()
+   this.conversations.pageEvent.stopAttenteCourante()
    
    $("body #smiles").remove()
 }
    
    $("body #smiles").remove()
 }
@@ -170,7 +170,7 @@ PageMinichat.prototype.decharger = function()
 PageMinichat.prototype.getJSONMessage = function(pseudo, message)
 {
    var repondA = []
 PageMinichat.prototype.getJSONMessage = function(pseudo, message)
 {
    var repondA = []
-   for (var id in this.messages.messagesRepond)
+   for (var id in this.conversations.messagesRepond)
       repondA.push(parseInt(id)) // FIXME : une propriété ne peut pas être de type int ?
       
    return {
       repondA.push(parseInt(id)) // FIXME : une propriété ne peut pas être de type int ?
       
    return {
@@ -235,19 +235,19 @@ PageMinichat.prototype.envoyerMessage = function(pseudo, message)
             if(data["reply"] == "ok")
             {           
                // met à jour la classe des messages auquel repond celui ci (c'est un peu de la triche) TODO : ya mieux ?
             if(data["reply"] == "ok")
             {           
                // met à jour la classe des messages auquel repond celui ci (c'est un peu de la triche) TODO : ya mieux ?
-               for (var messId in thisPageMinichat.messages.messagesRepond)
+               for (var messId in thisPageMinichat.conversations.messagesRepond)
                {
                {
-                  for (var j = 0; j < thisPageMinichat.messages.conversations.length; j++)
+                  for (var j = 0; j < thisPageMinichat.conversations.conversations.length; j++)
                   {
                   {
-                     var mess = thisPageMinichat.messages.conversations[j].messagesParId[messId]
+                     var mess = thisPageMinichat.conversations.conversations[j].messagesParId[messId]
                      if (mess != undefined)
                         mess.clientARepondu = true
                   }
                      if (mess != undefined)
                         mess.clientARepondu = true
                   }
-                  $("#conversations div#" + thisPageMinichat.messages.messagesRepond[messId].getId()).addClass("repondu")
+                  $("#conversations div#" + thisPageMinichat.conversations.messagesRepond[messId].getId()).addClass("repondu")
                }
                
                $("form input.message").val("")
                }
                
                $("form input.message").val("")
-               thisPageMinichat.messages.enleverMessagesRepond()
+               thisPageMinichat.conversations.enleverMessagesRepond()
             }
             else if (data["reply"] == "error")
             {
             }
             else if (data["reply"] == "error")
             {
@@ -282,31 +282,26 @@ function Reponse(id, pseudo, login)
 
 /**
   * Représente un message.
 
 /**
   * Représente un message.
-  * @param id (string)
-  * @param date (string)
-  * @param pseudo
-  * @param contenu
   */
   */
-function Message(client, formateur, id, auteurId, racineId, date, pseudo, login, contenu)
+function Message(client, formateur, element)
 {
    this.client = client
    this.formateur = formateur
 {
    this.client = client
    this.formateur = formateur
-   this.id = id
-   this.auteurId = auteurId
-   this.racineId = racineId
-   this.date = date
-   this.pseudo = pseudo
-   this.login = login
-   this.contenu = contenu
-   
-   this.appartientAuClient = false
-   this.clientARepondu = false
-   this.estUneReponse = false
-   this.ekMaster = false
    
    
-   this.systeme = false // est-ce un message 'système' ?
+   this.id = element["id"]
+   this.auteurId = element["user_id"]
+   this.racineId = element["root"]
+   this.date = element["date"]
+   this.pseudo = element["nick"]
+   this.login = element["login"]
+   this.contenu = element["content"]
    
    
-   this.repondA = {} // un ensemble de reponse (voir Reponse) indexé par l'id du message de la reponses
+   this.appartientAuClient = element["owner"]
+   this.clientARepondu = element["answered"]
+   this.estUneReponse = element["is_a_reply"]
+   this.systeme = element["system"] // est-ce un message 'système' ?
+   this.setRepondA(element["answer_to"]) // un ensemble de reponse (voir Reponse) indexé par l'id du message de la reponses
+   this.ekMaster = element["ek_master"]
 }
 
 /**
 }
 
 /**
@@ -425,17 +420,24 @@ Message.prototype.XHTML = function(messagePair, pre)
 
 /**
   * Représente une conversation.
 
 /**
   * Représente une conversation.
-  * @param numConv le numéro (appelé id) de la conversation
-  * @param formateur outil permettant la mise en forme du texte des messages
+  * Une conversation, au niveau XHTML, est formé de deux partie, le titre et les messages.
+  * Le titre comprend la navigation par page, un bouton pour la fermer, un bouton pour la plier, un bouton
+  * pour créer un lien ainsi que le premier message.
+  * @param conversations l'ensemble des conversations
+  * @param num le numéro de la conversation
   */
   */
-function Conversation(num, util, formateur, client)
+function Conversation(conversations, num)
 {  
 {  
-   this.num = num // peut changer au cours de la vie de la conversation
+   this.conversations = conversations
+   this.num = num // peut changer au cours de la vie de la conversation, n'est pas un id !
    this.id = Math.floor(Math.random() * 1000000).toString(36)
    this.id = Math.floor(Math.random() * 1000000).toString(36)
-   this.util = util
-   this.formateur = formateur
-   this.client = client
+   
+   this.util = this.conversations.util
+   this.formateur = this.conversations.formateur
+   this.client = this.conversations.client
+   
    this.idDernierMessageAffiche = 0
    this.idDernierMessageAffiche = 0
+   this.racine = undefined
    
    this.messages = []
    this.messagesParId = {}
    
    this.messages = []
    this.messagesParId = {}
@@ -443,12 +445,15 @@ function Conversation(num, util, formateur, client)
    this.nbMessageMax = conf.nbMessageAffiche // Le nombre de message affiché par page
 
    $("#conversations").append(
    this.nbMessageMax = conf.nbMessageAffiche // Le nombre de message affiché par page
 
    $("#conversations").append(
-      '<div id="' + this.getId() + '" class="conversation">\
-      <div class="titre">' +
-         (num == 0 ? '' : '<div class="fermer"></div><div class="lien"></div>') +
-         '<span class="next">&lt;</span><span class="numPage">1</span><span class="prev">&gt;</span>\
-         </div>\
-      </div>'
+      '<div id="' + this.getId() + '" class="conversation">' +
+      '<div class="messages"></div>' +
+      '<div class="titre">' +
+         '<div class="barre">' +
+             (num == 0 ? '' : '<div class="fermer"></div><div class="lien"></div>') +
+             '<span class="next">&lt;</span><span class="numPage">1</span><span class="prev">&gt;</span>' +
+             '</div>' +
+         '</div>' +
+      '</div>'
    )
    
    this.util.infoBulle("Aller à la première page", $("#conversations #" + this.getId() + " .numPage"))
    )
    
    this.util.infoBulle("Aller à la première page", $("#conversations #" + this.getId() + " .numPage"))
@@ -458,10 +463,31 @@ function Conversation(num, util, formateur, client)
       this.util.infoBulle("Fermer la conversation", $("#conversations #" + this.getId() + " .fermer"))   
    }
 }
       this.util.infoBulle("Fermer la conversation", $("#conversations #" + this.getId() + " .fermer"))   
    }
 }
+/**
+  * @racine un message représentant la racine de la conversation, vaut undefined pour la conversation générale
+  */
+Conversation.prototype.setRacine = function(racineElement)
+{
+   this.racine = new Message(this.client, this.formateur, racineElement)
+   this.majRacine()
+}
+
+/**
+  * Met à jour la racine, décide de l'afficher ou non.
+  * On l'affiche uniquement si le message racine n'est pas déjà affiché sur la liste des messages.
+  */
+Conversation.prototype.majRacine = function()
+{
+   if (this.racine == undefined)
+      return
+
+   if (!(this.racine.id in this.messagesParId))
+      $("#" + this.getId() + " .titre").prepend(this.racine.XHTML(true, this.getId()))
+}
 
 Conversation.prototype.enleverMiseEnEvidence = function()
 {
 
 Conversation.prototype.enleverMiseEnEvidence = function()
 {
-   $("#conversations .message").removeClass("cache")
+   $("#" + this.getId() + " .message").removeClass("cache")
 }
 
 Conversation.prototype.colorerEntetes = function()
 }
 
 Conversation.prototype.colorerEntetes = function()
@@ -574,7 +600,8 @@ Conversation.prototype.ajouterMessage = function(message)
   */
 Conversation.prototype.viderMessages = function()
 {
   */
 Conversation.prototype.viderMessages = function()
 {
-   this.messages = new Array()
+   this.messages = []
+   this.messagesParId = {}
    this.idDernierMessageAffiche = 0
    $("#conversations #" + this.getId() + " .message").remove()
 }
    this.idDernierMessageAffiche = 0
    $("#conversations #" + this.getId() + " .message").remove()
 }
@@ -588,16 +615,14 @@ Conversation.prototype.idMessageFromString = function(idString)
   * 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.
   * 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)) appelée lors du clic sur un bouton "extraire"
-  * @param funClickMessage fonction (fun(numMess)) appelée lors du clic sur un message
   */
   */
-Conversation.prototype.flush = function(funClickOuvrirConv, funClickMessage)
+Conversation.prototype.flush = function()
 {
    var thisConversation = this
 
    // est-ce que le prochain message est pair ? (permet d'alterner le style des messages)
    var messagePair = (this.idDernierMessageAffiche == 0 ? true :
 {
    var thisConversation = this
 
    // est-ce que le prochain message est pair ? (permet d'alterner le style des messages)
    var messagePair = (this.idDernierMessageAffiche == 0 ? true :
-      ($("#conversations #" + this.getId() + " div:first").attr("class").search("messagePair") == -1)
+      ($("#" + this.getId() + " .messages div:first").attr("class").search("messagePair") == -1)
    )
       
    // construction de l'XHTML des messages
    )
       
    // construction de l'XHTML des messages
@@ -610,124 +635,134 @@ Conversation.prototype.flush = function(funClickOuvrirConv, funClickMessage)
       }
    
    var DOM = $(XHTML)
       }
    
    var DOM = $(XHTML)
-   DOM.each(
-      function()
-      {      
-         $(".lienConv", this).click(
-            function(event)
-            {          
-               // FIXME : ya pas mieux ?
-               var racine = $(event.target).text()
-               funClickOuvrirConv(parseInt(idString.substring(1, racine.length - 1), 36))
-               return false
-            }
-         )         
-         
-         thisConversation.util.infoBulle("Extraction de la conversation à partir de ce message", $(".extraire", this))
-         thisConversation.util.infoBulle("Extraction de la conversation complète", $(".extraireCompletement", this))
-         
-         // l'id du message
-         var idMess = thisConversation.idMessageFromString($(this).attr("id"))
-         
-         $(this).click(
-            function(event)
-            {
-               if ($(event.target).is("a") || $(event.target).parents("#outilsBan").length > 0) return
-                              
-               // extraction d'une conversation
-               if ($(event.target).is(".extraire"))
-               {
-                  funClickOuvrirConv(idMess)
-                  return
-               }
-               
-               if ($(event.target).is(".extraireCompletement"))
-               {
-                  funClickOuvrirConv(thisConversation.messagesParId[idMess].racineId)
-                  return
-               }
-               
-               funClickMessage(thisConversation.messagesParId[idMess])
-            }
-         )
-         
-         // mise en évidence de la conversation
-         $(".entete", this).hover(
-            function()
-            {
-               thisConversation.decolorerEntetes()
-               thisConversation.afficherConversation(idMess)
-            },
-            // quand on sort de l'entête du message la mise en évidence est enlevée
-            function()
-            {
-               thisConversation.enleverMiseEnEvidence()
-               thisConversation.decolorerEntetes()
-               thisConversation.colorerEntetes()
-            }
-         )
-         
-         if (thisConversation.client.viewTimes)
-            $(".dateComplete", this).show()
-         else
-            $(".dateComplete", this).hide()
-         
-         $("a[@rel*=lightbox]", this).lightBox()
-         
-         // les outils de bannissement (uniquement pour les ekMaster)
-         if (thisConversation.client.ekMaster)
-            $(".pseudo", this).hover(
-               function(e)
-               {     
-                  var userId = parseInt($(".id", this).text())
-                  var element = $(this)
-                  var h = element.height()
-                  var offset = element.offset()
-                  thisConversation.util.outilsBan.css("top", offset.top - 2).css("left", offset.left - 2).height(h < 16 ? 16 : h).width(element.width() + 16 * 3 + 4 + 64).prependTo(this).show()
-                  $("img", thisConversation.util.outilsBan).unbind("click")
-                  $("#slap", thisConversation.util.outilsBan).click(
-                     function(e)
-                     {
-                        thisConversation.client.slap(userId, $("#outilsBan input").val())
-                        $("#outilsBan input").val("")
-                        $("#outilsBan").hide()
-                     }
-                  )
-                  $("#kick", thisConversation.util.outilsBan).click(
-                     function(e)
-                     {
-                        thisConversation.client.kick(userId, $("#outilsBan input").val())
-                        $("#outilsBan input").val("")
-                        $("#outilsBan").hide()
-                     }
-                  )
-                  $("#ban", thisConversation.util.outilsBan).click(
-                     function(e)
-                     {
-                        thisConversation.client.ban(userId, $("#outilsBan input").val())
-                        $("#outilsBan input").val("")
-                        $("#outilsBan").hide()
-                     }
-                  )
-               },
-               function(e)
-               {
-                  $("#outilsBan", this).hide()
-               }
-            )
-      }
-   )
-   DOM.prependTo("#conversations #" + this.getId())
+    
+   // pour chaque nouveau message au niveau du document on crée ses événements
+   DOM.each(function() { thisConversation.attacherEventsSurMessage(this) })
+   DOM.prependTo("#" + this.getId() + " .messages")
    
    // enlève les messages exedentaires
    
    // enlève les messages exedentaires
-   var nbMessagesAffiche = $("#conversations #" + this.getId() + " .message").size()   
+   var nbMessagesAffiche = $("#" + this.getId() + " .message").size()   
    if (nbMessagesAffiche > this.nbMessageMax)
       $("#conversations #" + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).remove()
    
    if (this.messages.length > 0)
       this.idDernierMessageAffiche = this.messages[this.messages.length-1].id
    if (nbMessagesAffiche > this.nbMessageMax)
       $("#conversations #" + this.getId() + " .message").slice(this.nbMessageMax, nbMessagesAffiche).remove()
    
    if (this.messages.length > 0)
       this.idDernierMessageAffiche = this.messages[this.messages.length-1].id
+  
+   // met à jour la racine de la conversation
+   this.majRacine()
 }
 
 }
 
+Conversation.prototype.attacherEventsSurMessage = function(element)
+{
+   // l'id du message
+   var idMess = this.idMessageFromString($(element).attr("id"))
+
+   this.util.infoBulle("Extraction de la conversation à partir de ce message", $(".extraire", this))
+   this.util.infoBulle("Extraction de la conversation complète", $(".extraireCompletement", this))
+   
+   var thisConversation = this
+   $(".lienConv", element).click(
+      function(event)
+      {          
+         // FIXME : ya pas mieux ?
+         var racine = $(event.target).text()
+         thisConversation.conversations.ouvrirConversation(parseInt(idString.substring(1, racine.length - 1), 36))
+         return false
+      }
+   )  
+       
+   $(element).click(
+      function(event)
+      {
+         if ($(event.target).is("a") || $(event.target).parents("#outilsBan").length > 0) return
+         
+          // extraction d'une conversation
+         if ($(event.target).is(".extraire"))
+         {
+            thisConversation.conversations.ouvrirConversation(idMess)
+            return
+         }
+
+         if ($(event.target).is(".extraireCompletement"))
+         {
+            thisConversation.conversations.ouvrirConversation(thisConversation.messagesParId[idMess].racineId)
+            return
+         }
+
+         // met ou enlève la mise en evidence du message
+         thisConversation.conversations.toggleMessageRepond(thisConversation.messagesParId[idMess])
+         
+         // donne le focus à la ligne de saisie
+         $("form input.message").focus()
+      }
+   )
+
+   // mise en évidence de la conversation
+   $(".entete", element).hover(
+      function()
+      {
+         thisConversation.decolorerEntetes()
+         thisConversation.afficherConversation(idMess)
+      },
+      // quand on sort de l'entête du message la mise en évidence est enlevée
+      function()
+      {
+         thisConversation.enleverMiseEnEvidence()
+         thisConversation.decolorerEntetes()
+         thisConversation.colorerEntetes()
+      }
+   )
+
+ if (thisConversation.client.viewTimes)
+    $(".dateComplete", element).show()
+ else
+    $(".dateComplete", idMess).hide()
+
+ $("a[@rel*=lightbox]", idMess).lightBox()
+
+ // les outils de bannissement (uniquement pour les ekMaster)
+ if (thisConversation.client.ekMaster)
+    $(".pseudo", idMess).hover(
+       function(e)
+       {     
+          var userId = parseInt($(".id", this).text())
+          var element = $(this)
+          var h = element.height()
+          var offset = element.offset()
+          thisConversation.util.outilsBan.css("top", offset.top - 2).css("left", offset.left - 2).height(h < 16 ? 16 : h).width(element.width() + 16 * 3 + 4 + 64).prependTo(this).show()
+          $("img", thisConversation.util.outilsBan).unbind("click")
+          $("#slap", thisConversation.util.outilsBan).click(
+             function()
+             {
+                thisConversation.client.slap(userId, $("#outilsBan input").val())
+                $("#outilsBan input").val("")
+                $("#outilsBan").hide()
+             }
+          )
+          $("#kick", thisConversation.util.outilsBan).click(
+             function()
+             {
+                thisConversation.client.kick(userId, $("#outilsBan input").val())
+                $("#outilsBan input").val("")
+                $("#outilsBan").hide()
+             }
+          )
+          $("#ban", thisConversation.util.outilsBan).click(
+             function()
+             {
+                thisConversation.client.ban(userId, $("#outilsBan input").val())
+                $("#outilsBan input").val("")
+                $("#outilsBan").hide()
+             }
+          )
+       },
+       function()
+       {
+          $("#outilsBan", this).hide()
+       }
+    )
+}
+  
 /**
   * Etablit une liste des messages à mettre en evidence et des messages à cacher.
   * Puis applique un plan diabolique.
 /**
   * Etablit une liste des messages à mettre en evidence et des messages à cacher.
   * Puis applique un plan diabolique.
@@ -783,10 +818,9 @@ Conversation.prototype.supprimer = function()
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
-  * Représente l'ensemble des messages affichés.
-  * TODO : renommer cette "classe" en 'Conversations'
+  * Représente l'ensemble des conversations affichés.
   */
   */
-function Messages(client, formateur, util)
+function Conversations(client, formateur, util)
 {
    this.client = client
    this.formateur = formateur
 {
    this.client = client
    this.formateur = formateur
@@ -806,13 +840,13 @@ function Messages(client, formateur, util)
 
 // les messages insérés dans le document XHTML on leur id prefixé par cette valeur
 // cela permet de les distinguer des "vrais" messages
 
 // les messages insérés dans le document XHTML on leur id prefixé par cette valeur
 // cela permet de les distinguer des "vrais" messages
-Messages.prototype.prefixIdMessage = "rep"
+Conversations.prototype.prefixIdMessage = "rep"
 
 /**
   * Permet de définir un message comme étant ou n'étant plus un message auquel l'utilisateur
   * répond.
   */
 
 /**
   * Permet de définir un message comme étant ou n'étant plus un message auquel l'utilisateur
   * répond.
   */
-Messages.prototype.toggleMessageRepond = function(mess)
+Conversations.prototype.toggleMessageRepond = function(mess)
 {   
    // est-ce que l'on répond déjà à ce message ? si oui alors on l'enlève de la liste
    if (mess.id in this.messagesRepond)
 {   
    // est-ce que l'on répond déjà à ce message ? si oui alors on l'enlève de la liste
    if (mess.id in this.messagesRepond)
@@ -827,7 +861,7 @@ Messages.prototype.toggleMessageRepond = function(mess)
 /**
   * Enlève tous les messages auquel l'utilisateur souhaite répond.
   */
 /**
   * Enlève tous les messages auquel l'utilisateur souhaite répond.
   */
-Messages.prototype.enleverMessagesRepond = function()
+Conversations.prototype.enleverMessagesRepond = function()
 {
    for (var messId in this.messagesRepond)
       this.enleverMessageRepond(this.messagesRepond[messId])
 {
    for (var messId in this.messagesRepond)
       this.enleverMessageRepond(this.messagesRepond[messId])
@@ -841,9 +875,9 @@ Messages.prototype.enleverMessagesRepond = function()
 /**
   * Définit un message comme n'y répondant plus.
   */
 /**
   * Définit un message comme n'y répondant plus.
   */
-Messages.prototype.enleverMessageRepond = function(mess)
+Conversations.prototype.enleverMessageRepond = function(mess)
 {
 {
-   $("#" + mess.getId()).removeClass("repondEnEvidence")
+   $(this.exprIdsPotentiels(mess)).removeClass("repondEnEvidence")
    $("#" + mess.getId(this.prefixIdMessage)).remove()
    delete this.messagesRepond[mess.id]
    this.rafraichireNombreMessagesRepond()
    $("#" + mess.getId(this.prefixIdMessage)).remove()
    delete this.messagesRepond[mess.id]
    this.rafraichireNombreMessagesRepond()
@@ -852,7 +886,7 @@ Messages.prototype.enleverMessageRepond = function(mess)
 /**
   * Définit un message comme y répondant.
   */
 /**
   * Définit un message comme y répondant.
   */
-Messages.prototype.ajouterMessageRepond = function(mess)
+Conversations.prototype.ajouterMessageRepond = function(mess)
 {
    var thisMessages = this
     
 {
    var thisMessages = this
     
@@ -870,7 +904,11 @@ Messages.prototype.ajouterMessageRepond = function(mess)
    
    $("form#posterMessage #repondA .messages").append(mess.XHTML(undefined, this.prefixIdMessage))
    this.messagesRepond[mess.id] = mess
    
    $("form#posterMessage #repondA .messages").append(mess.XHTML(undefined, this.prefixIdMessage))
    this.messagesRepond[mess.id] = mess
-   $("#" + mess.getId(this.prefixIdMessage) + ", #" + mess.getId()).addClass("repondEnEvidence")
+   
+   // ajout la classe 'repondEnEvidence' au message. comme il peut se trouver potentiellement dans
+   // chaque conversation on construit tous les id potentiels
+   $(mess.getId(this.prefixIdMessage) + ", " + this.exprIdsPotentiels(mess)).addClass("repondEnEvidence")
+   
    $("#" + mess.getId(this.prefixIdMessage)).click(
       function()
       {
    $("#" + mess.getId(this.prefixIdMessage)).click(
       function()
       {
@@ -883,14 +921,28 @@ Messages.prototype.ajouterMessageRepond = function(mess)
    this.rafraichireNombreMessagesRepond()
 }
 
    this.rafraichireNombreMessagesRepond()
 }
 
+/**
+  * Construit tous les id potentiels d'un message, renvoie par exemple :
+  * "conv9b28mess1h, conv9b2amess1h, conv9b32mess1h"
+  */
+Conversations.prototype.exprIdsPotentiels = function(mess)
+{
+   var exprMess = ""
+   for(var i = 0; i < this.conversations.length; i++)
+   {
+      exprMess += (mess != "" ? ", " : "") + "#" + mess.getId(this.conversations[i].getId())
+   }
+   return exprMess
+}
+
 /**
   * Met à jour le nombre qui indique à l'utilisateur à combien de messages il répond.
   */
 /**
   * Met à jour le nombre qui indique à l'utilisateur à combien de messages il répond.
   */
-Messages.prototype.rafraichireNombreMessagesRepond = function()
+Conversations.prototype.rafraichireNombreMessagesRepond = function()
 {
    // TODO : ya pas mieux pour trouver le nombre d'objet ?
    var nb = 0
 {
    // TODO : ya pas mieux pour trouver le nombre d'objet ?
    var nb = 0
-   for (m in this.messagesRepond)
+   for (var m in this.messagesRepond)
       nb += 1
    $("#posterMessage #repondA .nb").text(nb)
    
       nb += 1
    $("#posterMessage #repondA .nb").text(nb)
    
@@ -903,7 +955,7 @@ Messages.prototype.rafraichireNombreMessagesRepond = function()
   * Affiche les messages auquel l'utilisateur souhaite répondre au sein des messages des conversations.
   * Utilisé lorsqu'une conversation est extraite.
   */
   * Affiche les messages auquel l'utilisateur souhaite répondre au sein des messages des conversations.
   * Utilisé lorsqu'une conversation est extraite.
   */
-Messages.prototype.afficherMessagesRepondConversations = function()
+Conversations.prototype.afficherMessagesRepondConversations = function()
 {
    var expr = ""
    for(var messId in this.messagesRepond)
 {
    var expr = ""
    for(var messId in this.messagesRepond)
@@ -914,7 +966,7 @@ Messages.prototype.afficherMessagesRepondConversations = function()
 /**
   * Crée un message JSON contenant le message demandant un rafraichissement.
   */
 /**
   * Crée un message JSON contenant le message demandant un rafraichissement.
   */
-Messages.prototype.getJSONrafraichirMessages = function()
+Conversations.prototype.getJSONrafraichirMessages = function()
 {
    var mess =  {
       "message_count" : conf.nbMessageAffiche,
 {
    var mess =  {
       "message_count" : conf.nbMessageAffiche,
@@ -929,7 +981,7 @@ Messages.prototype.getJSONrafraichirMessages = function()
    return mess
 }
 
    return mess
 }
 
-Messages.prototype.getJSONConversations = function()
+Conversations.prototype.getJSONConversations = function()
 {
    var clientConv = []
    
 {
    var clientConv = []
    
@@ -952,13 +1004,16 @@ Messages.prototype.getJSONConversations = function()
   * @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
   */
   * @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)
+Conversations.prototype.ajouterMessages = function(elements, numConversation)
 {
    if (elements["messages"].length == 0)
       return this.conversations[numConversation] != undefined
 
    for (var i = 0; i < elements["messages"].length; i++)
 {
    if (elements["messages"].length == 0)
       return this.conversations[numConversation] != undefined
 
    for (var i = 0; i < elements["messages"].length; i++)
-      this.ajouterMessage(elements["messages"][i], numConversation)
+      // si une nouvelle conversation a été créée alors on lui donne la racine
+      if(this.ajouterMessage(elements["messages"][i], numConversation))
+         this.conversations[numConversation].setRacine(elements["first"])
+         
    this.flush(numConversation)
    
    // renseigne la conversation sur la page courante et si c'est la dernière
    this.flush(numConversation)
    
    // renseigne la conversation sur la page courante et si c'est la dernière
@@ -975,35 +1030,24 @@ Messages.prototype.ajouterMessages = function(elements, numConversation)
   * Les message sont données dans l'ordre de leur id.
   * @param element un element JSON représentant le message
   * @param numConversation le numéro de la conversation, 0 = principale
   * Les message sont données dans l'ordre de leur id.
   * @param element un element JSON représentant le message
   * @param numConversation le numéro de la conversation, 0 = principale
+  * @return true si une nouvelle conversation a été créée sinon false
   */
   */
-Messages.prototype.ajouterMessage = function(element, numConversation)
+Conversations.prototype.ajouterMessage = function(element, numConversation)
 {
    var thisMessages = this
 
 {
    var thisMessages = this
 
-   // pas d'utilisation de jquery pour des raisons de performance
-   var id = element["id"]
-   
+   // pas d'utilisation de jquery pour des raisons de performance      
    var message = new Message(
       this.client,
       this.formateur,
    var message = new Message(
       this.client,
       this.formateur,
-      id,      
-      element["user_id"],
-      element["root"],
-      element["date"],
-      element["nick"],
-      element["login"],
-      element["content"]
+      element
    )   
    
    )   
    
-   message.appartientAuClient = element["owner"]
-   message.clientARepondu = element["answered"]
-   message.estUneReponse = element["is_a_reply"]
-   message.systeme = element["system"] 
-   message.setRepondA(element["answer_to"])
-   message.ekMaster = element["ek_master"]
+   var nouvelleConversation = false
    
    if (this.conversations[numConversation] == null)
    {
    
    if (this.conversations[numConversation] == null)
    {
+      nouvelleConversation = true
       this.nouvelleConversation(
          numConversation,
          function(num) // fermeture de la conversation
       this.nouvelleConversation(
          numConversation,
          function(num) // fermeture de la conversation
@@ -1021,13 +1065,14 @@ Messages.prototype.ajouterMessage = function(element, numConversation)
    }
 
    this.conversations[numConversation].ajouterMessage(message)
    }
 
    this.conversations[numConversation].ajouterMessage(message)
+   return nouvelleConversation
 }
 
 }
 
-Messages.prototype.nouvelleConversation = function(num, funFermer, funLien)
+Conversations.prototype.nouvelleConversation = function(num, funFermer, funLien)
 {
    var thisMessages = this
 
 {
    var thisMessages = this
 
-   this.conversations[num] = new Conversation(num, this.util, this.formateur, this.client)   
+   this.conversations[num] = new Conversation(this, num)   
    
    if (funFermer != undefined)
       this.conversations[num].eventFermer(funFermer)
    
    if (funFermer != undefined)
       this.conversations[num].eventFermer(funFermer)
@@ -1058,7 +1103,7 @@ Messages.prototype.nouvelleConversation = function(num, funFermer, funLien)
 /**
   * Enlève une conversation.
   */
 /**
   * Enlève une conversation.
   */
-Messages.prototype.supprimerConversation = function(num)
+Conversations.prototype.supprimerConversation = function(num)
 {
    if (num <= 0 || num >= this.conversations.length) return // la numéro 0 ne peut être supprimé
    this.conversations[num].supprimer()
 {
    if (num <= 0 || num >= this.conversations.length) return // la numéro 0 ne peut être supprimé
    this.conversations[num].supprimer()
@@ -1080,7 +1125,7 @@ Messages.prototype.supprimerConversation = function(num)
 /**
   * Ajuste la largeur des conversations en fonction de leur nombre. modifie l'attribut CSS 'width'.
   */
 /**
   * Ajuste la largeur des conversations en fonction de leur nombre. modifie l'attribut CSS 'width'.
   */
-Messages.prototype.ajusterLargeurConversations = function()
+Conversations.prototype.ajusterLargeurConversations = function()
 {
    var largeurPourcent = (100 / this.conversations.length)   
    // le "- 0.01" evite que IE se chie dessus lamentablement et affiche les conversations les unes au dessus des autres
 {
    var largeurPourcent = (100 / this.conversations.length)   
    // le "- 0.01" evite que IE se chie dessus lamentablement et affiche les conversations les unes au dessus des autres
@@ -1092,7 +1137,7 @@ Messages.prototype.ajusterLargeurConversations = function()
 /**
   * Demande à toutes les conversations de se flusher (afficher les messages non-affichés).
   */
 /**
   * Demande à toutes les conversations de se flusher (afficher les messages non-affichés).
   */
-Messages.prototype.flushAll = function()
+Conversations.prototype.flushAll = function()
 {
    for (var i = 0; i < this.conversations.length; i++)
       this.flush(i)
 {
    for (var i = 0; i < this.conversations.length; i++)
       this.flush(i)
@@ -1101,27 +1146,12 @@ Messages.prototype.flushAll = function()
 /**
   * Demande à une conversation de se flusher.
   */
 /**
   * Demande à une conversation de se flusher.
   */
-Messages.prototype.flush = function(numConv)
-{
-   var thisMessages = this
-   
-   this.conversations[numConv].flush(
-      function(racine) // appelé lors d'un clic sur un lien vers une conversation
-      {
-         thisMessages.ouvrirConversation(racine)
-      },
-      // 'Mess' correspond à un objet de type 'Message'
-      function(Mess) // appelé lors d'un clic sur un message
-      {
-         // met ou enlève la mise en evidence du message
-         thisMessages.toggleMessageRepond(Mess)
-         // donne le focus à la ligne de saisie
-         $("form input.message").focus()
-      }
-   )
+Conversations.prototype.flush = function(numConv)
+{   
+   this.conversations[numConv].flush()
 }
 }
-
-Messages.prototype.ouvrirConversation = function(racine)
+  
+Conversations.prototype.ouvrirConversation = function(racine)
 {
    if (this.client.ajouterConversation(racine))
       this.rafraichirMessages(true)
 {
    if (this.client.ajouterConversation(racine))
       this.rafraichirMessages(true)
@@ -1129,7 +1159,7 @@ Messages.prototype.ouvrirConversation = function(racine)
       this.util.messageDialogue("Cette conversation est déjà ouverte")
 }
 
       this.util.messageDialogue("Cette conversation est déjà ouverte")
 }
 
-Messages.prototype.viderMessages = function()
+Conversations.prototype.viderMessages = function()
 {
    for (var i = 0; i < this.conversations.length; i++)
       this.conversations[i].viderMessages()
 {
    for (var i = 0; i < this.conversations.length; i++)
       this.conversations[i].viderMessages()
@@ -1140,7 +1170,7 @@ Messages.prototype.viderMessages = function()
   * (AJAX-Comet-style proof)
   * @param vider vide tous les messages avant d'afficher les nouveaux
   */
   * (AJAX-Comet-style proof)
   * @param vider vide tous les messages avant d'afficher les nouveaux
   */
-Messages.prototype.rafraichirMessages = function(vider)
+Conversations.prototype.rafraichirMessages = function(vider)
 {
    var thisMessages = this
    
 {
    var thisMessages = this
    
index e8c1569..dac7d03 100755 (executable)
@@ -254,14 +254,14 @@ wait_event_page_chat(User, Racines_conversations, Message_count, Last_message_id
                               {last_page, not Plus},\r
                               {first, \r
                                  if Racine =:= undefined orelse Conv =:= [] ->\r
                               {last_page, not Plus},\r
                               {first, \r
                                  if Racine =:= undefined orelse Conv =:= [] ->\r
-                                       "undefined";\r
+                                       null;\r
                                     true ->\r
                                        {Racine_id, _, _} = Racine,\r
                                        case euphorik_bd:message_by_id(Racine_id) of\r
                                           {ok, Mess} ->\r
                                              json_message(Mess, euphorik_bd:parents(Racine), User);\r
                                           _ ->\r
                                     true ->\r
                                        {Racine_id, _, _} = Racine,\r
                                        case euphorik_bd:message_by_id(Racine_id) of\r
                                           {ok, Mess} ->\r
                                              json_message(Mess, euphorik_bd:parents(Racine), User);\r
                                           _ ->\r
-                                             "undefined"\r
+                                             null\r
                                        end\r
                                  end\r
                               }, % le premier message de la conversation, peut correspondre\r
                                        end\r
                                  end\r
                               }, % le premier message de la conversation, peut correspondre\r
index 1daf207..6f22617 100644 (file)
@@ -4,8 +4,8 @@
         <file>
             <url>js/pageMinichat.js</url>
             <line>237</line>
         <file>
             <url>js/pageMinichat.js</url>
             <line>237</line>
-            <line>867</line>
-            <line>1107</line>
+            <line>908</line>
+            <line>1141</line>
         </file>
     </editor-bookmarks>
 </project-private>
         </file>
     </editor-bookmarks>
 </project-private>